MediaWiki REL1_32
MaintenanceTest.php
Go to the documentation of this file.
1<?php
2
4
7use Wikimedia\TestingAccessWrapper;
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}
Abstract maintenance class for quickly writing and churning out maintenance scripts with minimal effo...
MediaWikiServices is the service locator for the application scope of MediaWiki.
static getInstance()
Returns the global default instance of the top level service locator.
assertOutputPrePostShutdown( $preShutdownOutput, $expectNLAppending)
Asserts the output before and after simulating shutdown.
testOutput( $outputs, $expected, $extraNL)
provideOutputData
testOutputChanneled( $outputs, $expected, $extraNL)
provideOutputChanneledData
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
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:2055
processing should stop and the error should be shown to the user * false
Definition hooks.txt:187