3 namespace MediaWiki\Tests\Maintenance
;
6 use MediaWiki\MediaWikiServices
;
7 use Wikimedia\TestingAccessWrapper
;
12 class MaintenanceTest
extends MaintenanceBaseTestCase
{
15 * @see MaintenanceBaseTestCase::getMaintenanceClass
17 protected function getMaintenanceClass() {
18 return Maintenance
::class;
22 * @see MaintenanceBaseTestCase::createMaintenance
24 * Note to extension authors looking for a model to follow: This function
25 * is normally not needed in a maintenance test, it's only overridden here
26 * because Maintenance is abstract.
28 protected function createMaintenance() {
29 $className = $this->getMaintenanceClass();
30 $obj = $this->getMockForAbstractClass( $className );
32 return TestingAccessWrapper
::newFromObject( $obj );
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.
41 * @dataProvider provideOutputData
43 function testOutput( $outputs, $expected, $extraNL ) {
44 foreach ( $outputs as $data ) {
45 if ( is_array( $data ) ) {
46 list( $msg, $channel ) = $data;
51 $this->maintenance
->output( $msg, $channel );
53 $this->assertOutputPrePostShutdown( $expected, $extraNL );
56 public function provideOutputData() {
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 ],
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 ],
80 [ "foo\n", "bazChannel" ],
81 [ "bar\n", "bazChannel" ],
89 [ "foo", "bazChannel" ],
91 [ "\n", "bazChannel" ],
92 [ "ba", "bazChannel" ],
94 [ "r\n", "bazChannel" ],
101 [ "", "bazChannel" ],
102 [ "foo", "bazChannel" ],
103 [ "", "bazChannel" ],
104 [ "\nb", "bazChannel" ],
105 [ "a", "bazChannel" ],
106 [ "", "bazChannel" ],
107 [ "r\n", "bazChannel" ],
114 [ "foo", "bazChannel" ],
115 [ "bar", "bazChannel" ],
116 [ "qux", "quuxChannel" ],
117 [ "corge", "bazChannel" ],
119 "foobar\nqux\ncorge",
124 [ "foo", "bazChannel" ],
125 [ "bar\n", "bazChannel" ],
126 [ "qux\n", "quuxChannel" ],
127 [ "corge", "bazChannel" ],
129 "foobar\nqux\ncorge",
135 [ "bar", "bazChannel" ],
137 [ "quux", "bazChannel" ],
144 [ "foo", "bazChannel" ],
146 [ "qux", "bazChannel" ],
160 [ [ "foo", "", "bar" ], "foobar", false ],
161 [ [ "foo", false, "bar" ], "foobar", false ],
164 [ "qux", "quuxChannel" ],
174 [ "foo", "bazChannel" ],
175 [ "", "bazChannel" ],
176 [ "bar", "bazChannel" ],
183 [ "foo", "bazChannel" ],
184 [ false, "bazChannel" ],
185 [ "bar", "bazChannel" ],
194 * @dataProvider provideOutputChanneledData
196 function testOutputChanneled( $outputs, $expected, $extraNL ) {
197 foreach ( $outputs as $data ) {
198 if ( is_array( $data ) ) {
199 list( $msg, $channel ) = $data;
204 $this->maintenance
->outputChanneled( $msg, $channel );
206 $this->assertOutputPrePostShutdown( $expected, $extraNL );
209 public function provideOutputChanneledData() {
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 ],
219 [ "foo\nbar", "bazChannel" ]
226 [ "foo", "bazChannel" ],
227 [ "bar", "bazChannel" ],
234 [ "", "bazChannel" ],
235 [ "foo", "bazChannel" ],
236 [ "", "bazChannel" ],
237 [ "\nb", "bazChannel" ],
238 [ "a", "bazChannel" ],
239 [ "", "bazChannel" ],
240 [ "r", "bazChannel" ],
247 [ "foo", "bazChannel" ],
248 [ "bar", "bazChannel" ],
249 [ "qux", "quuxChannel" ],
250 [ "corge", "bazChannel" ],
252 "foobar\nqux\ncorge",
257 [ "foo", "bazChannel" ],
258 [ "bar", "bazChannel" ],
259 [ "qux", "quuxChannel" ],
260 [ "corge", "bazChannel" ],
262 "foobar\nqux\ncorge",
267 [ "foo", "bazChannel" ],
270 [ "corge", "bazChannel" ],
272 "foo\nbar\nqux\ncorge",
278 [ "bar", "bazChannel" ],
280 [ "quux", "bazChannel" ],
282 "foo\nbar\nqux\nquux",
287 [ "foo", "bazChannel" ],
289 [ "qux", "bazChannel" ],
292 "foo\nbar\nqux\nquux\n",
303 [ [ "foo", "", "bar" ], "foo\n\nbar\n", false ],
304 [ [ "foo", false, "bar" ], "foo\nbar\n", false ],
308 function testCleanupChanneledClean() {
309 $this->maintenance
->cleanupChanneled();
310 $this->assertOutputPrePostShutdown( "", false );
313 function testCleanupChanneledAfterOutput() {
314 $this->maintenance
->output( "foo" );
315 $this->maintenance
->cleanupChanneled();
316 $this->assertOutputPrePostShutdown( "foo", false );
319 function testCleanupChanneledAfterOutputWNullChannel() {
320 $this->maintenance
->output( "foo", null );
321 $this->maintenance
->cleanupChanneled();
322 $this->assertOutputPrePostShutdown( "foo", false );
325 function testCleanupChanneledAfterOutputWChannel() {
326 $this->maintenance
->output( "foo", "bazChannel" );
327 $this->maintenance
->cleanupChanneled();
328 $this->assertOutputPrePostShutdown( "foo\n", false );
331 function testCleanupChanneledAfterNLOutput() {
332 $this->maintenance
->output( "foo\n" );
333 $this->maintenance
->cleanupChanneled();
334 $this->assertOutputPrePostShutdown( "foo\n", false );
337 function testCleanupChanneledAfterNLOutputWNullChannel() {
338 $this->maintenance
->output( "foo\n", null );
339 $this->maintenance
->cleanupChanneled();
340 $this->assertOutputPrePostShutdown( "foo\n", false );
343 function testCleanupChanneledAfterNLOutputWChannel() {
344 $this->maintenance
->output( "foo\n", "bazChannel" );
345 $this->maintenance
->cleanupChanneled();
346 $this->assertOutputPrePostShutdown( "foo\n", false );
349 function testCleanupChanneledAfterOutputChanneledWOChannel() {
350 $this->maintenance
->outputChanneled( "foo" );
351 $this->maintenance
->cleanupChanneled();
352 $this->assertOutputPrePostShutdown( "foo\n", false );
355 function testCleanupChanneledAfterOutputChanneledWNullChannel() {
356 $this->maintenance
->outputChanneled( "foo", null );
357 $this->maintenance
->cleanupChanneled();
358 $this->assertOutputPrePostShutdown( "foo\n", false );
361 function testCleanupChanneledAfterOutputChanneledWChannel() {
362 $this->maintenance
->outputChanneled( "foo", "bazChannel" );
363 $this->maintenance
->cleanupChanneled();
364 $this->assertOutputPrePostShutdown( "foo\n", false );
367 function testMultipleMaintenanceObjectsInteractionOutput() {
368 $m2 = $this->createMaintenance();
370 $this->maintenance
->output( "foo" );
371 $m2->output( "bar" );
373 $this->assertEquals( "foobar", $this->getActualOutput(),
374 "Output before shutdown simulation (m2)" );
375 $m2->cleanupChanneled();
376 $this->assertOutputPrePostShutdown( "foobar", false );
379 function testMultipleMaintenanceObjectsInteractionOutputWNullChannel() {
380 $m2 = $this->createMaintenance();
382 $this->maintenance
->output( "foo", null );
383 $m2->output( "bar", null );
385 $this->assertEquals( "foobar", $this->getActualOutput(),
386 "Output before shutdown simulation (m2)" );
387 $m2->cleanupChanneled();
388 $this->assertOutputPrePostShutdown( "foobar", false );
391 function testMultipleMaintenanceObjectsInteractionOutputWChannel() {
392 $m2 = $this->createMaintenance();
394 $this->maintenance
->output( "foo", "bazChannel" );
395 $m2->output( "bar", "bazChannel" );
397 $this->assertEquals( "foobar", $this->getActualOutput(),
398 "Output before shutdown simulation (m2)" );
399 $m2->cleanupChanneled();
400 $this->assertOutputPrePostShutdown( "foobar\n", true );
403 function testMultipleMaintenanceObjectsInteractionOutputWNullChannelNL() {
404 $m2 = $this->createMaintenance();
406 $this->maintenance
->output( "foo\n", null );
407 $m2->output( "bar\n", null );
409 $this->assertEquals( "foo\nbar\n", $this->getActualOutput(),
410 "Output before shutdown simulation (m2)" );
411 $m2->cleanupChanneled();
412 $this->assertOutputPrePostShutdown( "foo\nbar\n", false );
415 function testMultipleMaintenanceObjectsInteractionOutputWChannelNL() {
416 $m2 = $this->createMaintenance();
418 $this->maintenance
->output( "foo\n", "bazChannel" );
419 $m2->output( "bar\n", "bazChannel" );
421 $this->assertEquals( "foobar", $this->getActualOutput(),
422 "Output before shutdown simulation (m2)" );
423 $m2->cleanupChanneled();
424 $this->assertOutputPrePostShutdown( "foobar\n", true );
427 function testMultipleMaintenanceObjectsInteractionOutputChanneled() {
428 $m2 = $this->createMaintenance();
430 $this->maintenance
->outputChanneled( "foo" );
431 $m2->outputChanneled( "bar" );
433 $this->assertEquals( "foo\nbar\n", $this->getActualOutput(),
434 "Output before shutdown simulation (m2)" );
435 $m2->cleanupChanneled();
436 $this->assertOutputPrePostShutdown( "foo\nbar\n", false );
439 function testMultipleMaintenanceObjectsInteractionOutputChanneledWNullChannel() {
440 $m2 = $this->createMaintenance();
442 $this->maintenance
->outputChanneled( "foo", null );
443 $m2->outputChanneled( "bar", null );
445 $this->assertEquals( "foo\nbar\n", $this->getActualOutput(),
446 "Output before shutdown simulation (m2)" );
447 $m2->cleanupChanneled();
448 $this->assertOutputPrePostShutdown( "foo\nbar\n", false );
451 function testMultipleMaintenanceObjectsInteractionOutputChanneledWChannel() {
452 $m2 = $this->createMaintenance();
454 $this->maintenance
->outputChanneled( "foo", "bazChannel" );
455 $m2->outputChanneled( "bar", "bazChannel" );
457 $this->assertEquals( "foobar", $this->getActualOutput(),
458 "Output before shutdown simulation (m2)" );
459 $m2->cleanupChanneled();
460 $this->assertOutputPrePostShutdown( "foobar\n", true );
463 function testMultipleMaintenanceObjectsInteractionCleanupChanneledWChannel() {
464 $m2 = $this->createMaintenance();
466 $this->maintenance
->outputChanneled( "foo", "bazChannel" );
467 $m2->outputChanneled( "bar", "bazChannel" );
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" );
478 $m2->cleanupChanneled();
479 $this->assertOutputPrePostShutdown( "foobar\n\n", false );
483 * @covers Maintenance::getConfig
485 public function testGetConfig() {
486 $this->assertInstanceOf( 'Config', $this->maintenance
->getConfig() );
488 MediaWikiServices
::getInstance()->getMainConfig(),
489 $this->maintenance
->getConfig()
494 * @covers Maintenance::setConfig
496 public function testSetConfig() {
497 $conf = $this->createMock( 'Config' );
498 $this->maintenance
->setConfig( $conf );
499 $this->assertSame( $conf, $this->maintenance
->getConfig() );
502 function testParseArgs() {
503 $m2 = $this->createMaintenance();
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' ] );
509 $this->assertEquals( [ 'this1', 'this2' ], $m2->getOption( 'multi' ) );
510 $this->assertEquals( [ [ 'multi', 'this1' ], [ 'multi', 'this2' ] ],
511 $m2->orderedOptions
);
513 $m2->cleanupChanneled();
515 $m2 = $this->createMaintenance();
517 $m2->addOption( 'multi', 'This option does stuff', false, false, false, true );
518 $m2->loadWithArgv( [ '--multi', '--multi' ] );
520 $this->assertEquals( [ 1, 1 ], $m2->getOption( 'multi' ) );
521 $this->assertEquals( [ [ 'multi', 1 ], [ 'multi', 1 ] ], $m2->orderedOptions
);
523 $m2->cleanupChanneled();
525 $m2 = $this->createMaintenance();
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' ] );
531 $this->assertEquals( 'yo', $m2->getOption( 'multi' ) );
532 $this->assertEquals( [ [ 'multi', 'yo' ] ], $m2->orderedOptions
);
534 $m2->cleanupChanneled();