MediaWiki REL1_28
backupTextPassTest.php
Go to the documentation of this file.
1<?php
2
3require_once __DIR__ . "/../../../maintenance/dumpTextPass.php";
4
18
19 // We'll add several pages, revision and texts. The following variables hold the
20 // corresponding ids.
22 private static $numOfPages = 4;
28 private static $numOfRevs = 8;
29
30 function addDBData() {
31 $this->tablesUsed[] = 'page';
32 $this->tablesUsed[] = 'revision';
33 $this->tablesUsed[] = 'text';
34
35 $this->mergeMwGlobalArrayValue( 'wgContentHandlers', [
36 "BackupTextPassTestModel" => "BackupTextPassTestModelHandler"
37 ] );
38
39 $ns = $this->getDefaultWikitextNS();
40
41 try {
42 // Simple page
43 $title = Title::newFromText( 'BackupDumperTestP1', $ns );
45 list( $this->revId1_1, $this->textId1_1 ) = $this->addRevision( $page,
46 "BackupDumperTestP1Text1", "BackupDumperTestP1Summary1" );
47 $this->pageId1 = $page->getId();
48
49 // Page with more than one revision
50 $title = Title::newFromText( 'BackupDumperTestP2', $ns );
52 list( $this->revId2_1, $this->textId2_1 ) = $this->addRevision( $page,
53 "BackupDumperTestP2Text1", "BackupDumperTestP2Summary1" );
54 list( $this->revId2_2, $this->textId2_2 ) = $this->addRevision( $page,
55 "BackupDumperTestP2Text2", "BackupDumperTestP2Summary2" );
56 list( $this->revId2_3, $this->textId2_3 ) = $this->addRevision( $page,
57 "BackupDumperTestP2Text3", "BackupDumperTestP2Summary3" );
58 list( $this->revId2_4, $this->textId2_4 ) = $this->addRevision( $page,
59 "BackupDumperTestP2Text4 some additional Text ",
60 "BackupDumperTestP2Summary4 extra " );
61 $this->pageId2 = $page->getId();
62
63 // Deleted page.
64 $title = Title::newFromText( 'BackupDumperTestP3', $ns );
66 list( $this->revId3_1, $this->textId3_1 ) = $this->addRevision( $page,
67 "BackupDumperTestP3Text1", "BackupDumperTestP2Summary1" );
68 list( $this->revId3_2, $this->textId3_2 ) = $this->addRevision( $page,
69 "BackupDumperTestP3Text2", "BackupDumperTestP2Summary2" );
70 $this->pageId3 = $page->getId();
71 $page->doDeleteArticle( "Testing ;)" );
72
73 // Page from non-default namespace and model.
74 // ExportTransform applies.
75
76 if ( $ns === NS_TALK ) {
77 // @todo work around this.
78 throw new MWException( "The default wikitext namespace is the talk namespace. "
79 . " We can't currently deal with that." );
80 }
81
82 $title = Title::newFromText( 'BackupDumperTestP1', NS_TALK );
84 list( $this->revId4_1, $this->textId4_1 ) = $this->addRevision( $page,
85 "Talk about BackupDumperTestP1 Text1",
86 "Talk BackupDumperTestP1 Summary1",
87 "BackupTextPassTestModel" );
88 $this->pageId4 = $page->getId();
89 } catch ( Exception $e ) {
90 // We'd love to pass $e directly. However, ... see
91 // documentation of exceptionFromAddDBData in
92 // DumpTestCase
93 $this->exceptionFromAddDBData = $e;
94 }
95 }
96
97 protected function setUp() {
98 parent::setUp();
99
100 // Since we will restrict dumping by page ranges (to allow
101 // working tests, even if the db gets prepopulated by a base
102 // class), we have to assert, that the page id are consecutively
103 // increasing
104 $this->assertEquals(
105 [ $this->pageId2, $this->pageId3, $this->pageId4 ],
106 [ $this->pageId1 + 1, $this->pageId2 + 1, $this->pageId3 + 1 ],
107 "Page ids increasing without holes" );
108 }
109
110 function testPlain() {
111 // Setting up the dump
112 $nameStub = $this->setUpStub();
113 $nameFull = $this->getNewTempFile();
114 $dumper = new TextPassDumper( [ "--stub=file:" . $nameStub,
115 "--output=file:" . $nameFull ] );
116 $dumper->reporting = false;
117 $dumper->setDB( $this->db );
118
119 // Performing the dump
120 $dumper->dump( WikiExporter::FULL, WikiExporter::TEXT );
121
122 // Checking for correctness of the dumped data
123 $this->assertDumpStart( $nameFull );
124
125 // Page 1
126 $this->assertPageStart( $this->pageId1, NS_MAIN, "BackupDumperTestP1" );
127 $this->assertRevision( $this->revId1_1, "BackupDumperTestP1Summary1",
128 $this->textId1_1, false, "0bolhl6ol7i6x0e7yq91gxgaan39j87",
129 "BackupDumperTestP1Text1" );
130 $this->assertPageEnd();
131
132 // Page 2
133 $this->assertPageStart( $this->pageId2, NS_MAIN, "BackupDumperTestP2" );
134 $this->assertRevision( $this->revId2_1, "BackupDumperTestP2Summary1",
135 $this->textId2_1, false, "jprywrymfhysqllua29tj3sc7z39dl2",
136 "BackupDumperTestP2Text1" );
137 $this->assertRevision( $this->revId2_2, "BackupDumperTestP2Summary2",
138 $this->textId2_2, false, "b7vj5ks32po5m1z1t1br4o7scdwwy95",
139 "BackupDumperTestP2Text2", $this->revId2_1 );
140 $this->assertRevision( $this->revId2_3, "BackupDumperTestP2Summary3",
141 $this->textId2_3, false, "jfunqmh1ssfb8rs43r19w98k28gg56r",
142 "BackupDumperTestP2Text3", $this->revId2_2 );
143 $this->assertRevision( $this->revId2_4, "BackupDumperTestP2Summary4 extra",
144 $this->textId2_4, false, "6o1ciaxa6pybnqprmungwofc4lv00wv",
145 "BackupDumperTestP2Text4 some additional Text", $this->revId2_3 );
146 $this->assertPageEnd();
147
148 // Page 3
149 // -> Page is marked deleted. Hence not visible
150
151 // Page 4
152 $this->assertPageStart( $this->pageId4, NS_TALK, "Talk:BackupDumperTestP1" );
153 $this->assertRevision( $this->revId4_1, "Talk BackupDumperTestP1 Summary1",
154 $this->textId4_1, false, "nktofwzd0tl192k3zfepmlzxoax1lpe",
155 "TALK ABOUT BACKUPDUMPERTESTP1 TEXT1",
156 false,
157 "BackupTextPassTestModel",
158 "text/plain" );
159 $this->assertPageEnd();
160
161 $this->assertDumpEnd();
162 }
163
164 function testPrefetchPlain() {
165 // The mapping between ids and text, for the hits of the prefetch mock
166 $prefetchMap = [
167 [ $this->pageId1, $this->revId1_1, "Prefetch_________1Text1" ],
168 [ $this->pageId2, $this->revId2_3, "Prefetch_________2Text3" ]
169 ];
170
171 // The mock itself
172 $prefetchMock = $this->getMock( 'BaseDump', [ 'prefetch' ], [], '', false );
173 $prefetchMock->expects( $this->exactly( 6 ) )
174 ->method( 'prefetch' )
175 ->will( $this->returnValueMap( $prefetchMap ) );
176
177 // Setting up of the dump
178 $nameStub = $this->setUpStub();
179 $nameFull = $this->getNewTempFile();
180
181 $dumper = new TextPassDumper( [ "--stub=file:" . $nameStub,
182 "--output=file:" . $nameFull ] );
183
184 $dumper->prefetch = $prefetchMock;
185 $dumper->reporting = false;
186 $dumper->setDB( $this->db );
187
188 // Performing the dump
189 $dumper->dump( WikiExporter::FULL, WikiExporter::TEXT );
190
191 // Checking for correctness of the dumped data
192 $this->assertDumpStart( $nameFull );
193
194 // Page 1
195 $this->assertPageStart( $this->pageId1, NS_MAIN, "BackupDumperTestP1" );
196 // Prefetch kicks in. This is still the SHA-1 of the original text,
197 // But the actual text (with different SHA-1) comes from prefetch.
198 $this->assertRevision( $this->revId1_1, "BackupDumperTestP1Summary1",
199 $this->textId1_1, false, "0bolhl6ol7i6x0e7yq91gxgaan39j87",
200 "Prefetch_________1Text1" );
201 $this->assertPageEnd();
202
203 // Page 2
204 $this->assertPageStart( $this->pageId2, NS_MAIN, "BackupDumperTestP2" );
205 $this->assertRevision( $this->revId2_1, "BackupDumperTestP2Summary1",
206 $this->textId2_1, false, "jprywrymfhysqllua29tj3sc7z39dl2",
207 "BackupDumperTestP2Text1" );
208 $this->assertRevision( $this->revId2_2, "BackupDumperTestP2Summary2",
209 $this->textId2_2, false, "b7vj5ks32po5m1z1t1br4o7scdwwy95",
210 "BackupDumperTestP2Text2", $this->revId2_1 );
211 // Prefetch kicks in. This is still the SHA-1 of the original text,
212 // But the actual text (with different SHA-1) comes from prefetch.
213 $this->assertRevision( $this->revId2_3, "BackupDumperTestP2Summary3",
214 $this->textId2_3, false, "jfunqmh1ssfb8rs43r19w98k28gg56r",
215 "Prefetch_________2Text3", $this->revId2_2 );
216 $this->assertRevision( $this->revId2_4, "BackupDumperTestP2Summary4 extra",
217 $this->textId2_4, false, "6o1ciaxa6pybnqprmungwofc4lv00wv",
218 "BackupDumperTestP2Text4 some additional Text", $this->revId2_3 );
219 $this->assertPageEnd();
220
221 // Page 3
222 // -> Page is marked deleted. Hence not visible
223
224 // Page 4
225 $this->assertPageStart( $this->pageId4, NS_TALK, "Talk:BackupDumperTestP1" );
226 $this->assertRevision( $this->revId4_1, "Talk BackupDumperTestP1 Summary1",
227 $this->textId4_1, false, "nktofwzd0tl192k3zfepmlzxoax1lpe",
228 "TALK ABOUT BACKUPDUMPERTESTP1 TEXT1",
229 false,
230 "BackupTextPassTestModel",
231 "text/plain" );
232 $this->assertPageEnd();
233
234 $this->assertDumpEnd();
235 }
236
244 private function checkpointHelper( $checkpointFormat = "file" ) {
245 // Getting temporary names
246 $nameStub = $this->getNewTempFile();
247 $nameOutputDir = $this->getNewTempDirectory();
248
249 $stderr = fopen( 'php://output', 'a' );
250 if ( $stderr === false ) {
251 $this->fail( "Could not open stream for stderr" );
252 }
253
254 $iterations = 32; // We'll start with that many iterations of revisions
255 // in stub. Make sure that the generated volume is above the buffer size
256 // set below. Otherwise, the checkpointing does not trigger.
257 $lastDuration = 0;
258 $minDuration = 2; // We want the dump to take at least this many seconds
259 $checkpointAfter = 0.5; // Generate checkpoint after this many seconds
260
261 // Until a dump takes at least $minDuration seconds, perform a dump and check
262 // duration. If the dump did not take long enough increase the iteration
263 // count, to generate a bigger stub file next time.
264 while ( $lastDuration < $minDuration ) {
265
266 // Setting up the dump
267 wfRecursiveRemoveDir( $nameOutputDir );
268 $this->assertTrue( wfMkdirParents( $nameOutputDir ),
269 "Creating temporary output directory " );
270 $this->setUpStub( $nameStub, $iterations );
271 $dumper = new TextPassDumper();
272 $dumper->loadWithArgv( [ "--stub=file:" . $nameStub,
273 "--output=" . $checkpointFormat . ":" . $nameOutputDir . "/full",
274 "--maxtime=1" /*This is in minutes. Fixup is below*/,
275 "--buffersize=32768", // The default of 32 iterations fill up 32KB about twice
276 "--checkpointfile=checkpoint-%s-%s.xml.gz" ] );
277 $dumper->setDB( $this->db );
278 $dumper->maxTimeAllowed = $checkpointAfter; // Patching maxTime from 1 minute
279 $dumper->stderr = $stderr;
280
281 // The actual dump and taking time
282 $ts_before = microtime( true );
283 $dumper->execute();
284 $ts_after = microtime( true );
285 $lastDuration = $ts_after - $ts_before;
286
287 // Handling increasing the iteration count for the stubs
288 if ( $lastDuration < $minDuration ) {
289 $old_iterations = $iterations;
290 if ( $lastDuration > 0.2 ) {
291 // lastDuration is big enough, to allow an educated guess
292 $factor = ( $minDuration + 0.5 ) / $lastDuration;
293 if ( ( $factor > 1.1 ) && ( $factor < 100 ) ) {
294 // educated guess is reasonable
295 $iterations = (int)( $iterations * $factor );
296 }
297 }
298
299 if ( $old_iterations == $iterations ) {
300 // Heuristics were not applied, so we just *2.
301 $iterations *= 2;
302 }
303
304 $this->assertLessThan( 50000, $iterations,
305 "Emergency stop against infinitely increasing iteration "
306 . "count ( last duration: $lastDuration )" );
307 }
308 }
309
310 // The dump (hopefully) did take long enough to produce more than one
311 // checkpoint file.
312 // We now check all the checkpoint files for validity.
313
314 $files = scandir( $nameOutputDir );
315 $this->assertTrue( asort( $files ), "Sorting files in temporary directory" );
316 $fileOpened = false;
317 $lookingForPage = 1;
318 $checkpointFiles = 0;
319
320 // Each run of the following loop body tries to handle exactly 1 /page/ (not
321 // iteration of stub content). $i is only increased after having treated page 4.
322 for ( $i = 0; $i < $iterations; ) {
323
324 // 1. Assuring a file is opened and ready. Skipping across header if
325 // necessary.
326 if ( !$fileOpened ) {
327 $this->assertNotEmpty( $files, "No more existing dump files, "
328 . "but not yet all pages found" );
329 $fname = array_shift( $files );
330 while ( $fname == "." || $fname == ".." ) {
331 $this->assertNotEmpty( $files, "No more existing dump"
332 . " files, but not yet all pages found" );
333 $fname = array_shift( $files );
334 }
335 if ( $checkpointFormat == "gzip" ) {
336 $this->gunzip( $nameOutputDir . "/" . $fname );
337 }
338 $this->assertDumpStart( $nameOutputDir . "/" . $fname );
339 $fileOpened = true;
340 $checkpointFiles++;
341 }
342
343 // 2. Performing a single page check
344 switch ( $lookingForPage ) {
345 case 1:
346 // Page 1
347 $this->assertPageStart( $this->pageId1 + $i * self::$numOfPages, NS_MAIN,
348 "BackupDumperTestP1" );
349 $this->assertRevision( $this->revId1_1 + $i * self::$numOfRevs, "BackupDumperTestP1Summary1",
350 $this->textId1_1, false, "0bolhl6ol7i6x0e7yq91gxgaan39j87",
351 "BackupDumperTestP1Text1" );
352 $this->assertPageEnd();
353
354 $lookingForPage = 2;
355 break;
356
357 case 2:
358 // Page 2
359 $this->assertPageStart( $this->pageId2 + $i * self::$numOfPages, NS_MAIN,
360 "BackupDumperTestP2" );
361 $this->assertRevision( $this->revId2_1 + $i * self::$numOfRevs, "BackupDumperTestP2Summary1",
362 $this->textId2_1, false, "jprywrymfhysqllua29tj3sc7z39dl2",
363 "BackupDumperTestP2Text1" );
364 $this->assertRevision( $this->revId2_2 + $i * self::$numOfRevs, "BackupDumperTestP2Summary2",
365 $this->textId2_2, false, "b7vj5ks32po5m1z1t1br4o7scdwwy95",
366 "BackupDumperTestP2Text2", $this->revId2_1 + $i * self::$numOfRevs );
367 $this->assertRevision( $this->revId2_3 + $i * self::$numOfRevs, "BackupDumperTestP2Summary3",
368 $this->textId2_3, false, "jfunqmh1ssfb8rs43r19w98k28gg56r",
369 "BackupDumperTestP2Text3", $this->revId2_2 + $i * self::$numOfRevs );
370 $this->assertRevision( $this->revId2_4 + $i * self::$numOfRevs,
371 "BackupDumperTestP2Summary4 extra",
372 $this->textId2_4, false, "6o1ciaxa6pybnqprmungwofc4lv00wv",
373 "BackupDumperTestP2Text4 some additional Text",
374 $this->revId2_3 + $i * self::$numOfRevs );
375 $this->assertPageEnd();
376
377 $lookingForPage = 4;
378 break;
379
380 case 4:
381 // Page 4
382 $this->assertPageStart( $this->pageId4 + $i * self::$numOfPages, NS_TALK,
383 "Talk:BackupDumperTestP1" );
384 $this->assertRevision( $this->revId4_1 + $i * self::$numOfRevs,
385 "Talk BackupDumperTestP1 Summary1",
386 $this->textId4_1, false, "nktofwzd0tl192k3zfepmlzxoax1lpe",
387 "TALK ABOUT BACKUPDUMPERTESTP1 TEXT1",
388 false,
389 "BackupTextPassTestModel",
390 "text/plain" );
391 $this->assertPageEnd();
392
393 $lookingForPage = 1;
394
395 // We dealt with the whole iteration.
396 $i++;
397 break;
398
399 default:
400 $this->fail( "Bad setting for lookingForPage ($lookingForPage)" );
401 }
402
403 // 3. Checking for the end of the current checkpoint file
404 if ( $this->xml->nodeType == XMLReader::END_ELEMENT
405 && $this->xml->name == "mediawiki"
406 ) {
407 $this->assertDumpEnd();
408 $fileOpened = false;
409 }
410 }
411
412 // Assuring we completely read all files ...
413 $this->assertFalse( $fileOpened, "Currently read file still open?" );
414 $this->assertEmpty( $files, "Remaining unchecked files" );
415
416 // ... and have dealt with more than one checkpoint file
417 $this->assertGreaterThan(
418 1,
419 $checkpointFiles,
420 "expected more than 1 checkpoint to have been created. "
421 . "Checkpoint interval is $checkpointAfter seconds, maybe your computer is too fast?"
422 );
423
424 $this->expectETAOutput();
425 }
426
434 $this->checkpointHelper();
435 }
436
453 $this->checkHasGzip();
454 $this->checkpointHelper( "gzip" );
455 }
456
470 private function setUpStub( $fname = null, $iterations = 1 ) {
471 if ( $fname === null ) {
472 $fname = $this->getNewTempFile();
473 }
474 $header = '<mediawiki xmlns="http://www.mediawiki.org/xml/export-0.10/" '
475 . 'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" '
476 . 'xsi:schemaLocation="http://www.mediawiki.org/xml/export-0.10/ '
477 . 'http://www.mediawiki.org/xml/export-0.10.xsd" version="0.10" xml:lang="en">
478 <siteinfo>
479 <sitename>wikisvn</sitename>
480 <base>http://localhost/wiki-svn/index.php/Main_Page</base>
481 <generator>MediaWiki 1.21alpha</generator>
482 <case>first-letter</case>
483 <namespaces>
484 <namespace key="-2" case="first-letter">Media</namespace>
485 <namespace key="-1" case="first-letter">Special</namespace>
486 <namespace key="0" case="first-letter" />
487 <namespace key="1" case="first-letter">Talk</namespace>
488 <namespace key="2" case="first-letter">User</namespace>
489 <namespace key="3" case="first-letter">User talk</namespace>
490 <namespace key="4" case="first-letter">Wikisvn</namespace>
491 <namespace key="5" case="first-letter">Wikisvn talk</namespace>
492 <namespace key="6" case="first-letter">File</namespace>
493 <namespace key="7" case="first-letter">File talk</namespace>
494 <namespace key="8" case="first-letter">MediaWiki</namespace>
495 <namespace key="9" case="first-letter">MediaWiki talk</namespace>
496 <namespace key="10" case="first-letter">Template</namespace>
497 <namespace key="11" case="first-letter">Template talk</namespace>
498 <namespace key="12" case="first-letter">Help</namespace>
499 <namespace key="13" case="first-letter">Help talk</namespace>
500 <namespace key="14" case="first-letter">Category</namespace>
501 <namespace key="15" case="first-letter">Category talk</namespace>
502 </namespaces>
503 </siteinfo>
504';
505 $tail = '</mediawiki>
506';
507
509 $iterations = intval( $iterations );
510 for ( $i = 0; $i < $iterations; $i++ ) {
511
512 $page1 = ' <page>
513 <title>BackupDumperTestP1</title>
514 <ns>0</ns>
515 <id>' . ( $this->pageId1 + $i * self::$numOfPages ) . '</id>
516 <revision>
517 <id>' . ( $this->revId1_1 + $i * self::$numOfRevs ) . '</id>
518 <timestamp>2012-04-01T16:46:05Z</timestamp>
519 <contributor>
520 <ip>127.0.0.1</ip>
521 </contributor>
522 <comment>BackupDumperTestP1Summary1</comment>
523 <model>wikitext</model>
524 <format>text/x-wiki</format>
525 <text id="' . $this->textId1_1 . '" bytes="23" />
526 <sha1>0bolhl6ol7i6x0e7yq91gxgaan39j87</sha1>
527 </revision>
528 </page>
529';
530 $page2 = ' <page>
531 <title>BackupDumperTestP2</title>
532 <ns>0</ns>
533 <id>' . ( $this->pageId2 + $i * self::$numOfPages ) . '</id>
534 <revision>
535 <id>' . ( $this->revId2_1 + $i * self::$numOfRevs ) . '</id>
536 <timestamp>2012-04-01T16:46:05Z</timestamp>
537 <contributor>
538 <ip>127.0.0.1</ip>
539 </contributor>
540 <comment>BackupDumperTestP2Summary1</comment>
541 <model>wikitext</model>
542 <format>text/x-wiki</format>
543 <text id="' . $this->textId2_1 . '" bytes="23" />
544 <sha1>jprywrymfhysqllua29tj3sc7z39dl2</sha1>
545 </revision>
546 <revision>
547 <id>' . ( $this->revId2_2 + $i * self::$numOfRevs ) . '</id>
548 <parentid>' . ( $this->revId2_1 + $i * self::$numOfRevs ) . '</parentid>
549 <timestamp>2012-04-01T16:46:05Z</timestamp>
550 <contributor>
551 <ip>127.0.0.1</ip>
552 </contributor>
553 <comment>BackupDumperTestP2Summary2</comment>
554 <model>wikitext</model>
555 <format>text/x-wiki</format>
556 <text id="' . $this->textId2_2 . '" bytes="23" />
557 <sha1>b7vj5ks32po5m1z1t1br4o7scdwwy95</sha1>
558 </revision>
559 <revision>
560 <id>' . ( $this->revId2_3 + $i * self::$numOfRevs ) . '</id>
561 <parentid>' . ( $this->revId2_2 + $i * self::$numOfRevs ) . '</parentid>
562 <timestamp>2012-04-01T16:46:05Z</timestamp>
563 <contributor>
564 <ip>127.0.0.1</ip>
565 </contributor>
566 <comment>BackupDumperTestP2Summary3</comment>
567 <model>wikitext</model>
568 <format>text/x-wiki</format>
569 <text id="' . $this->textId2_3 . '" bytes="23" />
570 <sha1>jfunqmh1ssfb8rs43r19w98k28gg56r</sha1>
571 </revision>
572 <revision>
573 <id>' . ( $this->revId2_4 + $i * self::$numOfRevs ) . '</id>
574 <parentid>' . ( $this->revId2_3 + $i * self::$numOfRevs ) . '</parentid>
575 <timestamp>2012-04-01T16:46:05Z</timestamp>
576 <contributor>
577 <ip>127.0.0.1</ip>
578 </contributor>
579 <comment>BackupDumperTestP2Summary4 extra</comment>
580 <model>wikitext</model>
581 <format>text/x-wiki</format>
582 <text id="' . $this->textId2_4 . '" bytes="44" />
583 <sha1>6o1ciaxa6pybnqprmungwofc4lv00wv</sha1>
584 </revision>
585 </page>
586';
587 // page 3 not in stub
588
589 $page4 = ' <page>
590 <title>Talk:BackupDumperTestP1</title>
591 <ns>1</ns>
592 <id>' . ( $this->pageId4 + $i * self::$numOfPages ) . '</id>
593 <revision>
594 <id>' . ( $this->revId4_1 + $i * self::$numOfRevs ) . '</id>
595 <timestamp>2012-04-01T16:46:05Z</timestamp>
596 <contributor>
597 <ip>127.0.0.1</ip>
598 </contributor>
599 <comment>Talk BackupDumperTestP1 Summary1</comment>
600 <model>BackupTextPassTestModel</model>
601 <format>text/plain</format>
602 <text id="' . $this->textId4_1 . '" bytes="35" />
603 <sha1>nktofwzd0tl192k3zfepmlzxoax1lpe</sha1>
604 </revision>
605 </page>
606';
607 $content .= $page1 . $page2 . $page4;
608 }
609 $content .= $tail;
610 $this->assertEquals( strlen( $content ), file_put_contents(
611 $fname, $content ), "Length of prepared stub" );
612
613 return $fname;
614 }
615}
616
618
619 public function __construct() {
620 parent::__construct( 'BackupTextPassTestModel' );
621 }
622
623 public function exportTransform( $text, $format = null ) {
624 return strtoupper( $text );
625 }
626
627}
628
644 function testBufferSizeSetting( $expected, $size, $msg ) {
645 $dumper = new TextPassDumperAccessor();
646 $dumper->loadWithArgv( [ "--buffersize=" . $size ] );
647 $dumper->execute();
648 $this->assertEquals( $expected, $dumper->getBufferSize(), $msg );
649 }
650
657 // expected, bufferSize to initialize with, message
658 return [
659 [ 512 * 1024, 512 * 1024, "Setting 512KB is not effective" ],
660 [ 8192, 8192, "Setting 8KB is not effective" ],
661 [ 4096, 2048, "Could set buffer size below lower bound" ]
662 ];
663 }
664}
665
684 public function getBufferSize() {
685 return $this->bufferSize;
686 }
687
688 function dump( $history, $text = null ) {
689 return true;
690 }
691}
wfRecursiveRemoveDir( $dir)
Remove a directory and all its content.
wfMkdirParents( $dir, $mode=null, $caller=null)
Make directory, and make all parent directories if they don't exist.
if(!defined( 'MEDIAWIKI')) $fname
This file is not a valid entry point, perform no further processing unless MEDIAWIKI is defined.
Definition Setup.php:36
exportTransform( $text, $format=null)
Applies transformations on export (returns the blob unchanged per default).
Base TestCase for dumps.
assertPageStart( $id, $ns, $name)
Asserts that the xml reader is at the start of a page element and skips over the first tags,...
assertDumpStart( $fname, $skip_siteinfo=true)
Opens an XML file to analyze and optionally skips past siteinfo.
expectETAOutput()
Checks for test output consisting only of lines containing ETA announcements.
assertPageEnd()
Asserts that the xml reader is at the page's closing element and skips to the next element.
assertDumpEnd( $name="mediawiki")
Asserts that the xml reader is at the final closing tag of an xml file and closes the reader.
addRevision(Page $page, $text, $summary, $model=CONTENT_MODEL_WIKITEXT)
Adds a revision to a page, while returning the resuting revision's id.
gunzip( $fname)
gunzips the given file and stores the result in the original file name
checkHasGzip()
Skip the test if 'gzip' is not in $PATH.
assertRevision( $id, $summary, $text_id, $text_bytes, $text_sha1, $text=false, $parentid=false, $model=CONTENT_MODEL_WIKITEXT, $format=CONTENT_FORMAT_WIKITEXT)
Asserts that the xml reader is at a revision and checks its representation before skipping over it.
MediaWiki exception.
Base class that store and restore the Language objects.
getDefaultWikitextNS()
Returns the ID of a namespace that defaults to Wikitext.
getNewTempFile()
Obtains a new temporary file name.
mergeMwGlobalArrayValue( $name, $values)
Merges the given values into a MW global array variable.
getNewTempDirectory()
obtains a new temporary directory
Base content handler implementation for flat text contents.
Accessor for internal state of TextPassDumper.
dump( $history, $text=null)
getBufferSize()
Gets the bufferSize.
Tests for TextPassDumper that rely on the database.
testCheckpointPlain()
Broken per T70653.
checkpointHelper( $checkpointFormat="file")
Ensures that checkpoint dumps are used and written, by successively increasing the stub size and dump...
setUpStub( $fname=null, $iterations=1)
Creates a stub file that is used for testing the text pass of dumps.
setUp()
Default set up function.
testCheckpointGzip()
tests for working checkpoint generation in gzip format work.
Tests for TextPassDumper that do not rely on the database.
testBufferSizeSetting( $expected, $size, $msg)
Ensures that setting the buffer size is effective.
bufferSizeProvider()
Ensures that setting the buffer size is effective.
static factory(Title $title)
Create a WikiPage object of the appropriate class for the given title.
Definition WikiPage.php:115
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
const NS_MAIN
Definition Defines.php:56
const NS_TALK
Definition Defines.php:57
namespace and then decline to actually register it file or subcat img or subcat $title
Definition hooks.txt:986
this hook is for auditing only RecentChangesLinked and Watchlist RecentChangesLinked and Watchlist e g Watchlist removed from all revisions and log entries to which it was applied This gives extensions a chance to take it off their books as the deletion has already been partly carried out by this point or something similar the user will be unable to create the tag set and then return false from the hook function Ensure you consume the ChangeTagAfterDelete hook to carry out custom deletion actions as context called by AbstractContent::getParserOutput May be used to override the normal model specific rendering of page content $content
Definition hooks.txt:1094
namespace are movable Hooks may change this value to override the return value of MWNamespace::isMovable(). 'NewDifferenceEngine' do that in ParserLimitReportFormat instead use this to modify the parameters of the image and a DIV can begin in one section and end in another Make sure your code can handle that case gracefully See the EditSectionClearerLink extension for an example zero but section is usually empty its values are the globals values before the output is cached $page
Definition hooks.txt:2534
returning false will NOT prevent logging $e
Definition hooks.txt:2110
$files
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:37
$header