MediaWiki  master
MaintenanceTest.php
Go to the documentation of this file.
1 <?php
2 
4 
8 
13 
17  protected function getMaintenanceClass() {
18  return Maintenance::class;
19  }
20 
28  protected function createMaintenance() {
29  $className = $this->getMaintenanceClass();
30  $obj = $this->getMockForAbstractClass( $className );
31 
32  return TestingAccessWrapper::newFromObject( $obj );
33  }
34 
35  // Although the following tests do not seem to be too consistent (compare for
36  // example the newlines within the test.*StringString tests, or the
37  // test.*Intermittent.* tests), the objective of these tests is not to describe
38  // consistent behavior, but rather currently existing behavior.
39 
43  function testOutput( $outputs, $expected, $extraNL ) {
44  foreach ( $outputs as $data ) {
45  if ( is_array( $data ) ) {
46  list( $msg, $channel ) = $data;
47  } else {
48  $msg = $data;
49  $channel = null;
50  }
51  $this->maintenance->output( $msg, $channel );
52  }
53  $this->assertOutputPrePostShutdown( $expected, $extraNL );
54  }
55 
56  public function provideOutputData() {
57  return [
58  [ [ "" ], "", false ],
59  [ [ "foo" ], "foo", false ],
60  [ [ "foo", "bar" ], "foobar", false ],
61  [ [ "foo\n" ], "foo\n", false ],
62  [ [ "foo\n\n" ], "foo\n\n", false ],
63  [ [ "foo\nbar" ], "foo\nbar", false ],
64  [ [ "foo\nbar\n" ], "foo\nbar\n", false ],
65  [ [ "foo\n", "bar\n" ], "foo\nbar\n", false ],
66  [ [ "", "foo", "", "\n", "ba", "", "r\n" ], "foo\nbar\n", false ],
67  [ [ "", "foo", "", "\nb", "a", "", "r\n" ], "foo\nbar\n", false ],
68  [ [ [ "foo", "bazChannel" ] ], "foo", true ],
69  [ [ [ "foo\n", "bazChannel" ] ], "foo", true ],
70 
71  // If this test fails, note that output takes strings with double line
72  // endings (although output's implementation in this situation calls
73  // outputChanneled with a string ending in a nl ... which is not allowed
74  // according to the documentation of outputChanneled)
75  [ [ [ "foo\n\n", "bazChannel" ] ], "foo\n", true ],
76  [ [ [ "foo\nbar", "bazChannel" ] ], "foo\nbar", true ],
77  [ [ [ "foo\nbar\n", "bazChannel" ] ], "foo\nbar", true ],
78  [
79  [
80  [ "foo\n", "bazChannel" ],
81  [ "bar\n", "bazChannel" ],
82  ],
83  "foobar",
84  true
85  ],
86  [
87  [
88  [ "", "bazChannel" ],
89  [ "foo", "bazChannel" ],
90  [ "", "bazChannel" ],
91  [ "\n", "bazChannel" ],
92  [ "ba", "bazChannel" ],
93  [ "", "bazChannel" ],
94  [ "r\n", "bazChannel" ],
95  ],
96  "foobar",
97  true
98  ],
99  [
100  [
101  [ "", "bazChannel" ],
102  [ "foo", "bazChannel" ],
103  [ "", "bazChannel" ],
104  [ "\nb", "bazChannel" ],
105  [ "a", "bazChannel" ],
106  [ "", "bazChannel" ],
107  [ "r\n", "bazChannel" ],
108  ],
109  "foo\nbar",
110  true
111  ],
112  [
113  [
114  [ "foo", "bazChannel" ],
115  [ "bar", "bazChannel" ],
116  [ "qux", "quuxChannel" ],
117  [ "corge", "bazChannel" ],
118  ],
119  "foobar\nqux\ncorge",
120  true
121  ],
122  [
123  [
124  [ "foo", "bazChannel" ],
125  [ "bar\n", "bazChannel" ],
126  [ "qux\n", "quuxChannel" ],
127  [ "corge", "bazChannel" ],
128  ],
129  "foobar\nqux\ncorge",
130  true
131  ],
132  [
133  [
134  [ "foo", null ],
135  [ "bar", "bazChannel" ],
136  [ "qux", null ],
137  [ "quux", "bazChannel" ],
138  ],
139  "foobar\nquxquux",
140  true
141  ],
142  [
143  [
144  [ "foo", "bazChannel" ],
145  [ "bar", null ],
146  [ "qux", "bazChannel" ],
147  [ "quux", null ],
148  ],
149  "foo\nbarqux\nquux",
150  false
151  ],
152  [
153  [
154  [ "foo", 1 ],
155  [ "bar", 1.0 ],
156  ],
157  "foo\nbar",
158  true
159  ],
160  [ [ "foo", "", "bar" ], "foobar", false ],
161  [ [ "foo", false, "bar" ], "foobar", false ],
162  [
163  [
164  [ "qux", "quuxChannel" ],
165  "foo",
166  false,
167  "bar"
168  ],
169  "qux\nfoobar",
170  false
171  ],
172  [
173  [
174  [ "foo", "bazChannel" ],
175  [ "", "bazChannel" ],
176  [ "bar", "bazChannel" ],
177  ],
178  "foobar",
179  true
180  ],
181  [
182  [
183  [ "foo", "bazChannel" ],
184  [ false, "bazChannel" ],
185  [ "bar", "bazChannel" ],
186  ],
187  "foobar",
188  true
189  ],
190  ];
191  }
192 
196  function testOutputChanneled( $outputs, $expected, $extraNL ) {
197  foreach ( $outputs as $data ) {
198  if ( is_array( $data ) ) {
199  list( $msg, $channel ) = $data;
200  } else {
201  $msg = $data;
202  $channel = null;
203  }
204  $this->maintenance->outputChanneled( $msg, $channel );
205  }
206  $this->assertOutputPrePostShutdown( $expected, $extraNL );
207  }
208 
209  public function provideOutputChanneledData() {
210  return [
211  [ [ "" ], "\n", false ],
212  [ [ "foo" ], "foo\n", false ],
213  [ [ "foo", "bar" ], "foo\nbar\n", false ],
214  [ [ "foo\nbar" ], "foo\nbar\n", false ],
215  [ [ "", "foo", "", "\nb", "a", "", "r" ], "\nfoo\n\n\nb\na\n\nr\n", false ],
216  [ [ [ "foo", "bazChannel" ] ], "foo", true ],
217  [
218  [
219  [ "foo\nbar", "bazChannel" ]
220  ],
221  "foo\nbar",
222  true
223  ],
224  [
225  [
226  [ "foo", "bazChannel" ],
227  [ "bar", "bazChannel" ],
228  ],
229  "foobar",
230  true
231  ],
232  [
233  [
234  [ "", "bazChannel" ],
235  [ "foo", "bazChannel" ],
236  [ "", "bazChannel" ],
237  [ "\nb", "bazChannel" ],
238  [ "a", "bazChannel" ],
239  [ "", "bazChannel" ],
240  [ "r", "bazChannel" ],
241  ],
242  "foo\nbar",
243  true
244  ],
245  [
246  [
247  [ "foo", "bazChannel" ],
248  [ "bar", "bazChannel" ],
249  [ "qux", "quuxChannel" ],
250  [ "corge", "bazChannel" ],
251  ],
252  "foobar\nqux\ncorge",
253  true
254  ],
255  [
256  [
257  [ "foo", "bazChannel" ],
258  [ "bar", "bazChannel" ],
259  [ "qux", "quuxChannel" ],
260  [ "corge", "bazChannel" ],
261  ],
262  "foobar\nqux\ncorge",
263  true
264  ],
265  [
266  [
267  [ "foo", "bazChannel" ],
268  [ "bar", null ],
269  [ "qux", null ],
270  [ "corge", "bazChannel" ],
271  ],
272  "foo\nbar\nqux\ncorge",
273  true
274  ],
275  [
276  [
277  [ "foo", null ],
278  [ "bar", "bazChannel" ],
279  [ "qux", null ],
280  [ "quux", "bazChannel" ],
281  ],
282  "foo\nbar\nqux\nquux",
283  true
284  ],
285  [
286  [
287  [ "foo", "bazChannel" ],
288  [ "bar", null ],
289  [ "qux", "bazChannel" ],
290  [ "quux", null ],
291  ],
292  "foo\nbar\nqux\nquux\n",
293  false
294  ],
295  [
296  [
297  [ "foo", 1 ],
298  [ "bar", 1.0 ],
299  ],
300  "foo\nbar",
301  true
302  ],
303  [ [ "foo", "", "bar" ], "foo\n\nbar\n", false ],
304  [ [ "foo", false, "bar" ], "foo\nbar\n", false ],
305  ];
306  }
307 
309  $this->maintenance->cleanupChanneled();
310  $this->assertOutputPrePostShutdown( "", false );
311  }
312 
314  $this->maintenance->output( "foo" );
315  $this->maintenance->cleanupChanneled();
316  $this->assertOutputPrePostShutdown( "foo", false );
317  }
318 
320  $this->maintenance->output( "foo", null );
321  $this->maintenance->cleanupChanneled();
322  $this->assertOutputPrePostShutdown( "foo", false );
323  }
324 
326  $this->maintenance->output( "foo", "bazChannel" );
327  $this->maintenance->cleanupChanneled();
328  $this->assertOutputPrePostShutdown( "foo\n", false );
329  }
330 
332  $this->maintenance->output( "foo\n" );
333  $this->maintenance->cleanupChanneled();
334  $this->assertOutputPrePostShutdown( "foo\n", false );
335  }
336 
338  $this->maintenance->output( "foo\n", null );
339  $this->maintenance->cleanupChanneled();
340  $this->assertOutputPrePostShutdown( "foo\n", false );
341  }
342 
344  $this->maintenance->output( "foo\n", "bazChannel" );
345  $this->maintenance->cleanupChanneled();
346  $this->assertOutputPrePostShutdown( "foo\n", false );
347  }
348 
350  $this->maintenance->outputChanneled( "foo" );
351  $this->maintenance->cleanupChanneled();
352  $this->assertOutputPrePostShutdown( "foo\n", false );
353  }
354 
356  $this->maintenance->outputChanneled( "foo", null );
357  $this->maintenance->cleanupChanneled();
358  $this->assertOutputPrePostShutdown( "foo\n", false );
359  }
360 
362  $this->maintenance->outputChanneled( "foo", "bazChannel" );
363  $this->maintenance->cleanupChanneled();
364  $this->assertOutputPrePostShutdown( "foo\n", false );
365  }
366 
368  $m2 = $this->createMaintenance();
369 
370  $this->maintenance->output( "foo" );
371  $m2->output( "bar" );
372 
373  $this->assertEquals( "foobar", $this->getActualOutput(),
374  "Output before shutdown simulation (m2)" );
375  $m2->cleanupChanneled();
376  $this->assertOutputPrePostShutdown( "foobar", false );
377  }
378 
380  $m2 = $this->createMaintenance();
381 
382  $this->maintenance->output( "foo", null );
383  $m2->output( "bar", null );
384 
385  $this->assertEquals( "foobar", $this->getActualOutput(),
386  "Output before shutdown simulation (m2)" );
387  $m2->cleanupChanneled();
388  $this->assertOutputPrePostShutdown( "foobar", false );
389  }
390 
392  $m2 = $this->createMaintenance();
393 
394  $this->maintenance->output( "foo", "bazChannel" );
395  $m2->output( "bar", "bazChannel" );
396 
397  $this->assertEquals( "foobar", $this->getActualOutput(),
398  "Output before shutdown simulation (m2)" );
399  $m2->cleanupChanneled();
400  $this->assertOutputPrePostShutdown( "foobar\n", true );
401  }
402 
404  $m2 = $this->createMaintenance();
405 
406  $this->maintenance->output( "foo\n", null );
407  $m2->output( "bar\n", null );
408 
409  $this->assertEquals( "foo\nbar\n", $this->getActualOutput(),
410  "Output before shutdown simulation (m2)" );
411  $m2->cleanupChanneled();
412  $this->assertOutputPrePostShutdown( "foo\nbar\n", false );
413  }
414 
416  $m2 = $this->createMaintenance();
417 
418  $this->maintenance->output( "foo\n", "bazChannel" );
419  $m2->output( "bar\n", "bazChannel" );
420 
421  $this->assertEquals( "foobar", $this->getActualOutput(),
422  "Output before shutdown simulation (m2)" );
423  $m2->cleanupChanneled();
424  $this->assertOutputPrePostShutdown( "foobar\n", true );
425  }
426 
428  $m2 = $this->createMaintenance();
429 
430  $this->maintenance->outputChanneled( "foo" );
431  $m2->outputChanneled( "bar" );
432 
433  $this->assertEquals( "foo\nbar\n", $this->getActualOutput(),
434  "Output before shutdown simulation (m2)" );
435  $m2->cleanupChanneled();
436  $this->assertOutputPrePostShutdown( "foo\nbar\n", false );
437  }
438 
440  $m2 = $this->createMaintenance();
441 
442  $this->maintenance->outputChanneled( "foo", null );
443  $m2->outputChanneled( "bar", null );
444 
445  $this->assertEquals( "foo\nbar\n", $this->getActualOutput(),
446  "Output before shutdown simulation (m2)" );
447  $m2->cleanupChanneled();
448  $this->assertOutputPrePostShutdown( "foo\nbar\n", false );
449  }
450 
452  $m2 = $this->createMaintenance();
453 
454  $this->maintenance->outputChanneled( "foo", "bazChannel" );
455  $m2->outputChanneled( "bar", "bazChannel" );
456 
457  $this->assertEquals( "foobar", $this->getActualOutput(),
458  "Output before shutdown simulation (m2)" );
459  $m2->cleanupChanneled();
460  $this->assertOutputPrePostShutdown( "foobar\n", true );
461  }
462 
464  $m2 = $this->createMaintenance();
465 
466  $this->maintenance->outputChanneled( "foo", "bazChannel" );
467  $m2->outputChanneled( "bar", "bazChannel" );
468 
469  $this->assertEquals( "foobar", $this->getActualOutput(),
470  "Output before first cleanup" );
471  $this->maintenance->cleanupChanneled();
472  $this->assertEquals( "foobar\n", $this->getActualOutput(),
473  "Output after first cleanup" );
474  $m2->cleanupChanneled();
475  $this->assertEquals( "foobar\n\n", $this->getActualOutput(),
476  "Output after second cleanup" );
477 
478  $m2->cleanupChanneled();
479  $this->assertOutputPrePostShutdown( "foobar\n\n", false );
480  }
481 
485  public function testGetConfig() {
486  $this->assertInstanceOf( 'Config', $this->maintenance->getConfig() );
487  $this->assertSame(
488  MediaWikiServices::getInstance()->getMainConfig(),
489  $this->maintenance->getConfig()
490  );
491  }
492 
496  public function testSetConfig() {
497  $conf = $this->createMock( 'Config' );
498  $this->maintenance->setConfig( $conf );
499  $this->assertSame( $conf, $this->maintenance->getConfig() );
500  }
501 
502  function testParseArgs() {
503  $m2 = $this->createMaintenance();
504 
505  // Create an option with an argument allowed to be specified multiple times
506  $m2->addOption( 'multi', 'This option does stuff', false, true, false, true );
507  $m2->loadWithArgv( [ '--multi', 'this1', '--multi', 'this2' ] );
508 
509  $this->assertEquals( [ 'this1', 'this2' ], $m2->getOption( 'multi' ) );
510  $this->assertEquals( [ [ 'multi', 'this1' ], [ 'multi', 'this2' ] ],
511  $m2->orderedOptions );
512 
513  $m2->cleanupChanneled();
514 
515  $m2 = $this->createMaintenance();
516 
517  $m2->addOption( 'multi', 'This option does stuff', false, false, false, true );
518  $m2->loadWithArgv( [ '--multi', '--multi' ] );
519 
520  $this->assertEquals( [ 1, 1 ], $m2->getOption( 'multi' ) );
521  $this->assertEquals( [ [ 'multi', 1 ], [ 'multi', 1 ] ], $m2->orderedOptions );
522 
523  $m2->cleanupChanneled();
524 
525  $m2 = $this->createMaintenance();
526 
527  // Create an option with an argument allowed to be specified multiple times
528  $m2->addOption( 'multi', 'This option doesn\'t actually support multiple occurrences' );
529  $m2->loadWithArgv( [ '--multi=yo' ] );
530 
531  $this->assertEquals( 'yo', $m2->getOption( 'multi' ) );
532  $this->assertEquals( [ [ 'multi', 'yo' ] ], $m2->orderedOptions );
533 
534  $m2->cleanupChanneled();
535  }
536 }
deferred txt A few of the database updates required by various functions here can be deferred until after the result page is displayed to the user For updating the view updating the linked to tables after a etc PHP does not yet have any way to tell the server to actually return and disconnect while still running these but it might have such a feature in the future We handle these by creating a deferred update object and putting those objects on a global list
Definition: deferred.txt:11
processing should stop and the error should be shown to the user * false
Definition: hooks.txt:187
testOutput( $outputs, $expected, $extraNL)
provideOutputData
Apache License January AND DISTRIBUTION Definitions License shall mean the terms and conditions for use
Abstract maintenance class for quickly writing and churning out maintenance scripts with minimal effo...
Definition: maintenance.txt:39
injection txt This is an overview of how MediaWiki makes use of dependency injection The design described here grew from the discussion of RFC T384 The term dependency this means that anything an object needs to operate should be injected from the the object itself should only know narrow no concrete implementation of the logic it relies on The requirement to inject everything typically results in an architecture that based on two main types of and essentially stateless service objects that use other service objects to operate on the value objects As of the beginning MediaWiki is only starting to use the DI approach Much of the code still relies on global state or direct resulting in a highly cyclical dependency MediaWikiServices
Definition: injection.txt:23
assertOutputPrePostShutdown( $preShutdownOutput, $expectNLAppending)
Asserts the output before and after simulating shutdown.
static getInstance()
Returns the global default instance of the top level service locator.
null means default in associative array with keys and values unescaped Should be merged with default with a value of false meaning to suppress the attribute in associative array with keys and values unescaped noclasses just before the function returns a value If you return true
Definition: hooks.txt:1982
this hook is for auditing only or null if authentication failed before getting that far or null if we can t even determine that When $user is not null
Definition: hooks.txt:780
This document is intended to provide useful advice for parties seeking to redistribute MediaWiki to end users It s targeted particularly at maintainers for Linux since it s been observed that distribution packages of MediaWiki often break We ve consistently had to recommend that users seeking support use official tarballs instead of their distribution s and this often solves whatever problem the user is having It would be nice if this could such as
Definition: distributors.txt:9
injection txt This is an overview of how MediaWiki makes use of dependency injection The design described here grew from the discussion of RFC T384 The term dependency this means that anything an object needs to operate should be injected from the the object itself should only know narrow no concrete implementation of the logic it relies on The requirement to inject everything typically results in an architecture that based on two main types of and essentially stateless service objects that use other service objects to operate on the value objects As of the beginning MediaWiki is only starting to use the DI approach Much of the code still relies on global state or direct resulting in a highly cyclical dependency which acts as the top level factory for services in MediaWiki which can be used to gain access to default instances of various services MediaWikiServices however also allows new services to be defined and default services to be redefined Services are defined or redefined by providing a callback the instantiator that will return a new instance of the service When it will create an instance of MediaWikiServices and populate it with the services defined in the files listed by thereby bootstrapping the DI framework Per $wgServiceWiringFiles lists includes ServiceWiring php
Definition: injection.txt:35
you have access to all of the normal MediaWiki so you can get a DB use the etc For full docs on the Maintenance class
Definition: maintenance.txt:52
testOutputChanneled( $outputs, $expected, $extraNL)
provideOutputChanneledData