MediaWiki  1.29.1
backupTextPassTest.php
Go to the documentation of this file.
1 <?php
2 
3 require_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->getMockBuilder( 'BaseDump' )
173  ->setMethods( [ 'prefetch' ] )
174  ->disableOriginalConstructor()
175  ->getMock();
176  $prefetchMock->expects( $this->exactly( 6 ) )
177  ->method( 'prefetch' )
178  ->will( $this->returnValueMap( $prefetchMap ) );
179 
180  // Setting up of the dump
181  $nameStub = $this->setUpStub();
182  $nameFull = $this->getNewTempFile();
183 
184  $dumper = new TextPassDumper( [ "--stub=file:" . $nameStub,
185  "--output=file:" . $nameFull ] );
186 
187  $dumper->prefetch = $prefetchMock;
188  $dumper->reporting = false;
189  $dumper->setDB( $this->db );
190 
191  // Performing the dump
192  $dumper->dump( WikiExporter::FULL, WikiExporter::TEXT );
193 
194  // Checking for correctness of the dumped data
195  $this->assertDumpStart( $nameFull );
196 
197  // Page 1
198  $this->assertPageStart( $this->pageId1, NS_MAIN, "BackupDumperTestP1" );
199  // Prefetch kicks in. This is still the SHA-1 of the original text,
200  // But the actual text (with different SHA-1) comes from prefetch.
201  $this->assertRevision( $this->revId1_1, "BackupDumperTestP1Summary1",
202  $this->textId1_1, false, "0bolhl6ol7i6x0e7yq91gxgaan39j87",
203  "Prefetch_________1Text1" );
204  $this->assertPageEnd();
205 
206  // Page 2
207  $this->assertPageStart( $this->pageId2, NS_MAIN, "BackupDumperTestP2" );
208  $this->assertRevision( $this->revId2_1, "BackupDumperTestP2Summary1",
209  $this->textId2_1, false, "jprywrymfhysqllua29tj3sc7z39dl2",
210  "BackupDumperTestP2Text1" );
211  $this->assertRevision( $this->revId2_2, "BackupDumperTestP2Summary2",
212  $this->textId2_2, false, "b7vj5ks32po5m1z1t1br4o7scdwwy95",
213  "BackupDumperTestP2Text2", $this->revId2_1 );
214  // Prefetch kicks in. This is still the SHA-1 of the original text,
215  // But the actual text (with different SHA-1) comes from prefetch.
216  $this->assertRevision( $this->revId2_3, "BackupDumperTestP2Summary3",
217  $this->textId2_3, false, "jfunqmh1ssfb8rs43r19w98k28gg56r",
218  "Prefetch_________2Text3", $this->revId2_2 );
219  $this->assertRevision( $this->revId2_4, "BackupDumperTestP2Summary4 extra",
220  $this->textId2_4, false, "6o1ciaxa6pybnqprmungwofc4lv00wv",
221  "BackupDumperTestP2Text4 some additional Text", $this->revId2_3 );
222  $this->assertPageEnd();
223 
224  // Page 3
225  // -> Page is marked deleted. Hence not visible
226 
227  // Page 4
228  $this->assertPageStart( $this->pageId4, NS_TALK, "Talk:BackupDumperTestP1" );
229  $this->assertRevision( $this->revId4_1, "Talk BackupDumperTestP1 Summary1",
230  $this->textId4_1, false, "nktofwzd0tl192k3zfepmlzxoax1lpe",
231  "TALK ABOUT BACKUPDUMPERTESTP1 TEXT1",
232  false,
233  "BackupTextPassTestModel",
234  "text/plain" );
235  $this->assertPageEnd();
236 
237  $this->assertDumpEnd();
238  }
239 
247  private function checkpointHelper( $checkpointFormat = "file" ) {
248  // Getting temporary names
249  $nameStub = $this->getNewTempFile();
250  $nameOutputDir = $this->getNewTempDirectory();
251 
252  $stderr = fopen( 'php://output', 'a' );
253  if ( $stderr === false ) {
254  $this->fail( "Could not open stream for stderr" );
255  }
256 
257  $iterations = 32; // We'll start with that many iterations of revisions
258  // in stub. Make sure that the generated volume is above the buffer size
259  // set below. Otherwise, the checkpointing does not trigger.
260  $lastDuration = 0;
261  $minDuration = 2; // We want the dump to take at least this many seconds
262  $checkpointAfter = 0.5; // Generate checkpoint after this many seconds
263 
264  // Until a dump takes at least $minDuration seconds, perform a dump and check
265  // duration. If the dump did not take long enough increase the iteration
266  // count, to generate a bigger stub file next time.
267  while ( $lastDuration < $minDuration ) {
268 
269  // Setting up the dump
270  wfRecursiveRemoveDir( $nameOutputDir );
271  $this->assertTrue( wfMkdirParents( $nameOutputDir ),
272  "Creating temporary output directory " );
273  $this->setUpStub( $nameStub, $iterations );
274  $dumper = new TextPassDumper();
275  $dumper->loadWithArgv( [ "--stub=file:" . $nameStub,
276  "--output=" . $checkpointFormat . ":" . $nameOutputDir . "/full",
277  "--maxtime=1" /*This is in minutes. Fixup is below*/,
278  "--buffersize=32768", // The default of 32 iterations fill up 32KB about twice
279  "--checkpointfile=checkpoint-%s-%s.xml.gz" ] );
280  $dumper->setDB( $this->db );
281  $dumper->maxTimeAllowed = $checkpointAfter; // Patching maxTime from 1 minute
282  $dumper->stderr = $stderr;
283 
284  // The actual dump and taking time
285  $ts_before = microtime( true );
286  $dumper->execute();
287  $ts_after = microtime( true );
288  $lastDuration = $ts_after - $ts_before;
289 
290  // Handling increasing the iteration count for the stubs
291  if ( $lastDuration < $minDuration ) {
292  $old_iterations = $iterations;
293  if ( $lastDuration > 0.2 ) {
294  // lastDuration is big enough, to allow an educated guess
295  $factor = ( $minDuration + 0.5 ) / $lastDuration;
296  if ( ( $factor > 1.1 ) && ( $factor < 100 ) ) {
297  // educated guess is reasonable
298  $iterations = (int)( $iterations * $factor );
299  }
300  }
301 
302  if ( $old_iterations == $iterations ) {
303  // Heuristics were not applied, so we just *2.
304  $iterations *= 2;
305  }
306 
307  $this->assertLessThan( 50000, $iterations,
308  "Emergency stop against infinitely increasing iteration "
309  . "count ( last duration: $lastDuration )" );
310  }
311  }
312 
313  // The dump (hopefully) did take long enough to produce more than one
314  // checkpoint file.
315  // We now check all the checkpoint files for validity.
316 
317  $files = scandir( $nameOutputDir );
318  $this->assertTrue( asort( $files ), "Sorting files in temporary directory" );
319  $fileOpened = false;
320  $lookingForPage = 1;
321  $checkpointFiles = 0;
322 
323  // Each run of the following loop body tries to handle exactly 1 /page/ (not
324  // iteration of stub content). $i is only increased after having treated page 4.
325  for ( $i = 0; $i < $iterations; ) {
326 
327  // 1. Assuring a file is opened and ready. Skipping across header if
328  // necessary.
329  if ( !$fileOpened ) {
330  $this->assertNotEmpty( $files, "No more existing dump files, "
331  . "but not yet all pages found" );
332  $fname = array_shift( $files );
333  while ( $fname == "." || $fname == ".." ) {
334  $this->assertNotEmpty( $files, "No more existing dump"
335  . " files, but not yet all pages found" );
336  $fname = array_shift( $files );
337  }
338  if ( $checkpointFormat == "gzip" ) {
339  $this->gunzip( $nameOutputDir . "/" . $fname );
340  }
341  $this->assertDumpStart( $nameOutputDir . "/" . $fname );
342  $fileOpened = true;
343  $checkpointFiles++;
344  }
345 
346  // 2. Performing a single page check
347  switch ( $lookingForPage ) {
348  case 1:
349  // Page 1
350  $this->assertPageStart( $this->pageId1 + $i * self::$numOfPages, NS_MAIN,
351  "BackupDumperTestP1" );
352  $this->assertRevision( $this->revId1_1 + $i * self::$numOfRevs, "BackupDumperTestP1Summary1",
353  $this->textId1_1, false, "0bolhl6ol7i6x0e7yq91gxgaan39j87",
354  "BackupDumperTestP1Text1" );
355  $this->assertPageEnd();
356 
357  $lookingForPage = 2;
358  break;
359 
360  case 2:
361  // Page 2
362  $this->assertPageStart( $this->pageId2 + $i * self::$numOfPages, NS_MAIN,
363  "BackupDumperTestP2" );
364  $this->assertRevision( $this->revId2_1 + $i * self::$numOfRevs, "BackupDumperTestP2Summary1",
365  $this->textId2_1, false, "jprywrymfhysqllua29tj3sc7z39dl2",
366  "BackupDumperTestP2Text1" );
367  $this->assertRevision( $this->revId2_2 + $i * self::$numOfRevs, "BackupDumperTestP2Summary2",
368  $this->textId2_2, false, "b7vj5ks32po5m1z1t1br4o7scdwwy95",
369  "BackupDumperTestP2Text2", $this->revId2_1 + $i * self::$numOfRevs );
370  $this->assertRevision( $this->revId2_3 + $i * self::$numOfRevs, "BackupDumperTestP2Summary3",
371  $this->textId2_3, false, "jfunqmh1ssfb8rs43r19w98k28gg56r",
372  "BackupDumperTestP2Text3", $this->revId2_2 + $i * self::$numOfRevs );
373  $this->assertRevision( $this->revId2_4 + $i * self::$numOfRevs,
374  "BackupDumperTestP2Summary4 extra",
375  $this->textId2_4, false, "6o1ciaxa6pybnqprmungwofc4lv00wv",
376  "BackupDumperTestP2Text4 some additional Text",
377  $this->revId2_3 + $i * self::$numOfRevs );
378  $this->assertPageEnd();
379 
380  $lookingForPage = 4;
381  break;
382 
383  case 4:
384  // Page 4
385  $this->assertPageStart( $this->pageId4 + $i * self::$numOfPages, NS_TALK,
386  "Talk:BackupDumperTestP1" );
387  $this->assertRevision( $this->revId4_1 + $i * self::$numOfRevs,
388  "Talk BackupDumperTestP1 Summary1",
389  $this->textId4_1, false, "nktofwzd0tl192k3zfepmlzxoax1lpe",
390  "TALK ABOUT BACKUPDUMPERTESTP1 TEXT1",
391  false,
392  "BackupTextPassTestModel",
393  "text/plain" );
394  $this->assertPageEnd();
395 
396  $lookingForPage = 1;
397 
398  // We dealt with the whole iteration.
399  $i++;
400  break;
401 
402  default:
403  $this->fail( "Bad setting for lookingForPage ($lookingForPage)" );
404  }
405 
406  // 3. Checking for the end of the current checkpoint file
407  if ( $this->xml->nodeType == XMLReader::END_ELEMENT
408  && $this->xml->name == "mediawiki"
409  ) {
410  $this->assertDumpEnd();
411  $fileOpened = false;
412  }
413  }
414 
415  // Assuring we completely read all files ...
416  $this->assertFalse( $fileOpened, "Currently read file still open?" );
417  $this->assertEmpty( $files, "Remaining unchecked files" );
418 
419  // ... and have dealt with more than one checkpoint file
420  $this->assertGreaterThan(
421  1,
422  $checkpointFiles,
423  "expected more than 1 checkpoint to have been created. "
424  . "Checkpoint interval is $checkpointAfter seconds, maybe your computer is too fast?"
425  );
426 
427  $this->expectETAOutput();
428  }
429 
436  function testCheckpointPlain() {
437  $this->checkpointHelper();
438  }
439 
455  function testCheckpointGzip() {
456  $this->checkHasGzip();
457  $this->checkpointHelper( "gzip" );
458  }
459 
473  private function setUpStub( $fname = null, $iterations = 1 ) {
474  if ( $fname === null ) {
475  $fname = $this->getNewTempFile();
476  }
477  $header = '<mediawiki xmlns="http://www.mediawiki.org/xml/export-0.10/" '
478  . 'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" '
479  . 'xsi:schemaLocation="http://www.mediawiki.org/xml/export-0.10/ '
480  . 'http://www.mediawiki.org/xml/export-0.10.xsd" version="0.10" xml:lang="en">
481  <siteinfo>
482  <sitename>wikisvn</sitename>
483  <base>http://localhost/wiki-svn/index.php/Main_Page</base>
484  <generator>MediaWiki 1.21alpha</generator>
485  <case>first-letter</case>
486  <namespaces>
487  <namespace key="-2" case="first-letter">Media</namespace>
488  <namespace key="-1" case="first-letter">Special</namespace>
489  <namespace key="0" case="first-letter" />
490  <namespace key="1" case="first-letter">Talk</namespace>
491  <namespace key="2" case="first-letter">User</namespace>
492  <namespace key="3" case="first-letter">User talk</namespace>
493  <namespace key="4" case="first-letter">Wikisvn</namespace>
494  <namespace key="5" case="first-letter">Wikisvn talk</namespace>
495  <namespace key="6" case="first-letter">File</namespace>
496  <namespace key="7" case="first-letter">File talk</namespace>
497  <namespace key="8" case="first-letter">MediaWiki</namespace>
498  <namespace key="9" case="first-letter">MediaWiki talk</namespace>
499  <namespace key="10" case="first-letter">Template</namespace>
500  <namespace key="11" case="first-letter">Template talk</namespace>
501  <namespace key="12" case="first-letter">Help</namespace>
502  <namespace key="13" case="first-letter">Help talk</namespace>
503  <namespace key="14" case="first-letter">Category</namespace>
504  <namespace key="15" case="first-letter">Category talk</namespace>
505  </namespaces>
506  </siteinfo>
507 ';
508  $tail = '</mediawiki>
509 ';
510 
511  $content = $header;
512  $iterations = intval( $iterations );
513  for ( $i = 0; $i < $iterations; $i++ ) {
514 
515  $page1 = ' <page>
516  <title>BackupDumperTestP1</title>
517  <ns>0</ns>
518  <id>' . ( $this->pageId1 + $i * self::$numOfPages ) . '</id>
519  <revision>
520  <id>' . ( $this->revId1_1 + $i * self::$numOfRevs ) . '</id>
521  <timestamp>2012-04-01T16:46:05Z</timestamp>
522  <contributor>
523  <ip>127.0.0.1</ip>
524  </contributor>
525  <comment>BackupDumperTestP1Summary1</comment>
526  <model>wikitext</model>
527  <format>text/x-wiki</format>
528  <text id="' . $this->textId1_1 . '" bytes="23" />
529  <sha1>0bolhl6ol7i6x0e7yq91gxgaan39j87</sha1>
530  </revision>
531  </page>
532 ';
533  $page2 = ' <page>
534  <title>BackupDumperTestP2</title>
535  <ns>0</ns>
536  <id>' . ( $this->pageId2 + $i * self::$numOfPages ) . '</id>
537  <revision>
538  <id>' . ( $this->revId2_1 + $i * self::$numOfRevs ) . '</id>
539  <timestamp>2012-04-01T16:46:05Z</timestamp>
540  <contributor>
541  <ip>127.0.0.1</ip>
542  </contributor>
543  <comment>BackupDumperTestP2Summary1</comment>
544  <model>wikitext</model>
545  <format>text/x-wiki</format>
546  <text id="' . $this->textId2_1 . '" bytes="23" />
547  <sha1>jprywrymfhysqllua29tj3sc7z39dl2</sha1>
548  </revision>
549  <revision>
550  <id>' . ( $this->revId2_2 + $i * self::$numOfRevs ) . '</id>
551  <parentid>' . ( $this->revId2_1 + $i * self::$numOfRevs ) . '</parentid>
552  <timestamp>2012-04-01T16:46:05Z</timestamp>
553  <contributor>
554  <ip>127.0.0.1</ip>
555  </contributor>
556  <comment>BackupDumperTestP2Summary2</comment>
557  <model>wikitext</model>
558  <format>text/x-wiki</format>
559  <text id="' . $this->textId2_2 . '" bytes="23" />
560  <sha1>b7vj5ks32po5m1z1t1br4o7scdwwy95</sha1>
561  </revision>
562  <revision>
563  <id>' . ( $this->revId2_3 + $i * self::$numOfRevs ) . '</id>
564  <parentid>' . ( $this->revId2_2 + $i * self::$numOfRevs ) . '</parentid>
565  <timestamp>2012-04-01T16:46:05Z</timestamp>
566  <contributor>
567  <ip>127.0.0.1</ip>
568  </contributor>
569  <comment>BackupDumperTestP2Summary3</comment>
570  <model>wikitext</model>
571  <format>text/x-wiki</format>
572  <text id="' . $this->textId2_3 . '" bytes="23" />
573  <sha1>jfunqmh1ssfb8rs43r19w98k28gg56r</sha1>
574  </revision>
575  <revision>
576  <id>' . ( $this->revId2_4 + $i * self::$numOfRevs ) . '</id>
577  <parentid>' . ( $this->revId2_3 + $i * self::$numOfRevs ) . '</parentid>
578  <timestamp>2012-04-01T16:46:05Z</timestamp>
579  <contributor>
580  <ip>127.0.0.1</ip>
581  </contributor>
582  <comment>BackupDumperTestP2Summary4 extra</comment>
583  <model>wikitext</model>
584  <format>text/x-wiki</format>
585  <text id="' . $this->textId2_4 . '" bytes="44" />
586  <sha1>6o1ciaxa6pybnqprmungwofc4lv00wv</sha1>
587  </revision>
588  </page>
589 ';
590  // page 3 not in stub
591 
592  $page4 = ' <page>
593  <title>Talk:BackupDumperTestP1</title>
594  <ns>1</ns>
595  <id>' . ( $this->pageId4 + $i * self::$numOfPages ) . '</id>
596  <revision>
597  <id>' . ( $this->revId4_1 + $i * self::$numOfRevs ) . '</id>
598  <timestamp>2012-04-01T16:46:05Z</timestamp>
599  <contributor>
600  <ip>127.0.0.1</ip>
601  </contributor>
602  <comment>Talk BackupDumperTestP1 Summary1</comment>
603  <model>BackupTextPassTestModel</model>
604  <format>text/plain</format>
605  <text id="' . $this->textId4_1 . '" bytes="35" />
606  <sha1>nktofwzd0tl192k3zfepmlzxoax1lpe</sha1>
607  </revision>
608  </page>
609 ';
610  $content .= $page1 . $page2 . $page4;
611  }
612  $content .= $tail;
613  $this->assertEquals( strlen( $content ), file_put_contents(
614  $fname, $content ), "Length of prepared stub" );
615 
616  return $fname;
617  }
618 }
619 
621 
622  public function __construct() {
623  parent::__construct( 'BackupTextPassTestModel' );
624  }
625 
626  public function exportTransform( $text, $format = null ) {
627  return strtoupper( $text );
628  }
629 
630 }
631 
647  function testBufferSizeSetting( $expected, $size, $msg ) {
648  $dumper = new TextPassDumperAccessor();
649  $dumper->loadWithArgv( [ "--buffersize=" . $size ] );
650  $dumper->execute();
651  $this->assertEquals( $expected, $dumper->getBufferSize(), $msg );
652  }
653 
659  function bufferSizeProvider() {
660  // expected, bufferSize to initialize with, message
661  return [
662  [ 512 * 1024, 512 * 1024, "Setting 512KB is not effective" ],
663  [ 8192, 8192, "Setting 8KB is not effective" ],
664  [ 4096, 2048, "Could set buffer size below lower bound" ]
665  ];
666  }
667 }
668 
687  public function getBufferSize() {
688  return $this->bufferSize;
689  }
690 
691  function dump( $history, $text = null ) {
692  return true;
693  }
694 }
TextPassDumper\$bufferSize
$bufferSize
Definition: dumpTextPass.php:54
TextPassDumperDatabaseTest\$textId1_1
$textId1_1
Definition: backupTextPassTest.php:23
Title\newFromText
static newFromText( $text, $defaultNamespace=NS_MAIN)
Create a new Title from text, such as what one would find in a link.
Definition: Title.php:265
BackupTextPassTestModelHandler\__construct
__construct()
Definition: backupTextPassTest.php:622
DumpTestCase
Base TestCase for dumps.
Definition: DumpTestCase.php:6
BackupTextPassTestModelHandler
Definition: backupTextPassTest.php:620
MediaWikiTestCase\mergeMwGlobalArrayValue
mergeMwGlobalArrayValue( $name, $values)
Merges the given values into a MW global array variable.
Definition: MediaWikiTestCase.php:766
DumpTestCase\assertPageEnd
assertPageEnd()
Asserts that the xml reader is at the page's closing element and skips to the next element.
Definition: DumpTestCase.php:314
TextPassDumperDatabaseTest\$revId2_2
$revId2_2
Definition: backupTextPassTest.php:24
wfMkdirParents
wfMkdirParents( $dir, $mode=null, $caller=null)
Make directory, and make all parent directories if they don't exist.
Definition: GlobalFunctions.php:2080
TextPassDumperDatabaseTest\$pageId3
$pageId3
Definition: backupTextPassTest.php:21
TextPassDumper\$history
$history
Definition: dumpTextPass.php:44
TextPassDumperDatabaseTest\$revId3_2
$revId3_2
Definition: backupTextPassTest.php:26
TextPassDumperDatabaseTest\$pageId2
$pageId2
Definition: backupTextPassTest.php:21
TextPassDumperDatabaseTest\testPlain
testPlain()
Definition: backupTextPassTest.php:110
TextPassDumperDatabaseTest\$textId2_2
$textId2_2
Definition: backupTextPassTest.php:24
TextPassDumperDatabaseTest\$textId2_1
$textId2_1
Definition: backupTextPassTest.php:24
$fname
if(!defined( 'MEDIAWIKI')) $fname
This file is not a valid entry point, perform no further processing unless MEDIAWIKI is defined.
Definition: Setup.php:36
TextPassDumperAccessor\dump
dump( $history, $text=null)
Definition: backupTextPassTest.php:691
TextPassDumperDatabaseTest\$revId2_3
$revId2_3
Definition: backupTextPassTest.php:25
TextPassDumperDatabaselessTest\testBufferSizeSetting
testBufferSizeSetting( $expected, $size, $msg)
Ensures that setting the buffer size is effective.
Definition: backupTextPassTest.php:647
TextPassDumperDatabaseTest\$revId3_1
$revId3_1
Definition: backupTextPassTest.php:26
TextPassDumperDatabaseTest\$pageId4
$pageId4
Definition: backupTextPassTest.php:21
TextPassDumperDatabaseTest\checkpointHelper
checkpointHelper( $checkpointFormat="file")
Ensures that checkpoint dumps are used and written, by successively increasing the stub size and dump...
Definition: backupTextPassTest.php:247
TextPassDumperAccessor
Accessor for internal state of TextPassDumper.
Definition: backupTextPassTest.php:674
DumpTestCase\assertDumpEnd
assertDumpEnd( $name="mediawiki")
Asserts that the xml reader is at the final closing tag of an xml file and closes the reader.
Definition: DumpTestCase.php:210
php
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
DumpTestCase\addRevision
addRevision(Page $page, $text, $summary, $model=CONTENT_MODEL_WIKITEXT)
Adds a revision to a page, while returning the resuting revision's id.
Definition: DumpTestCase.php:59
NS_MAIN
const NS_MAIN
Definition: Defines.php:62
TextPassDumperDatabaseTest\setUp
setUp()
Default set up function.
Definition: backupTextPassTest.php:97
TextPassDumperDatabaseTest\$pageId1
$pageId1
Definition: backupTextPassTest.php:21
MWException
MediaWiki exception.
Definition: MWException.php:26
$title
namespace and then decline to actually register it file or subcat img or subcat $title
Definition: hooks.txt:934
WikiPage\factory
static factory(Title $title)
Create a WikiPage object of the appropriate class for the given title.
Definition: WikiPage.php:120
TextPassDumperDatabaseTest\$numOfRevs
static $numOfRevs
Definition: backupTextPassTest.php:28
WikiExporter\TEXT
const TEXT
Definition: WikiExporter.php:58
TextPassDumperDatabaseTest\$textId2_3
$textId2_3
Definition: backupTextPassTest.php:25
$content
this hook is for auditing only RecentChangesLinked and Watchlist RecentChangesLinked and Watchlist Do not use this to implement individual filters if they are compatible with the ChangesListFilter and ChangesListFilterGroup structure use sub classes of those in conjunction with the ChangesListSpecialPageStructuredFilters hook This hook can be used to implement filters that do not implement that or custom behavior that is not an individual filter e g Watchlist and Watchlist you will want to construct new ChangesListBooleanFilter or ChangesListStringOptionsFilter objects When constructing you specify which group they belong to You can reuse existing or create your you must register them with $special registerFilterGroup 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:1049
MediaWikiTestCase\getNewTempFile
getNewTempFile()
Obtains a new temporary file name.
Definition: MediaWikiTestCase.php:443
$page
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:2536
TextPassDumperDatabaseTest\$revId2_4
$revId2_4
Definition: backupTextPassTest.php:25
TextPassDumperDatabaseTest\$textId2_4
$textId2_4
Definition: backupTextPassTest.php:25
DumpTestCase\assertPageStart
assertPageStart( $id, $ns, $name)
Asserts that the xml reader is at the start of a page element and skips over the first tags,...
Definition: DumpTestCase.php:300
TextPassDumperDatabaseTest\$numOfPages
static $numOfPages
Definition: backupTextPassTest.php:22
TextPassDumperDatabaseTest\testPrefetchPlain
testPrefetchPlain()
Definition: backupTextPassTest.php:164
MediaWikiTestCase\getDefaultWikitextNS
getDefaultWikitextNS()
Returns the ID of a namespace that defaults to Wikitext.
Definition: MediaWikiTestCase.php:1639
DumpTestCase\expectETAOutput
expectETAOutput()
Checks for test output consisting only of lines containing ETA announcements.
Definition: DumpTestCase.php:121
list
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
$e
div flags Integer display flags(NO_ACTION_LINK, NO_EXTRA_USER_LINKS) 'LogException' returning false will NOT prevent logging $e
Definition: hooks.txt:2122
TextPassDumperDatabaseTest\$revId2_1
$revId2_1
Definition: backupTextPassTest.php:24
$header
$header
Definition: updateCredits.php:35
TextPassDumperDatabaseTest\$revId1_1
$revId1_1
Definition: backupTextPassTest.php:23
TextContentHandler
Base content handler implementation for flat text contents.
Definition: TextContentHandler.php:31
MediaWikiLangTestCase
Base class that store and restore the Language objects.
Definition: MediaWikiLangTestCase.php:6
WikiExporter\FULL
const FULL
Definition: WikiExporter.php:49
DumpTestCase\checkHasGzip
checkHasGzip()
Skip the test if 'gzip' is not in $PATH.
Definition: DumpTestCase.php:36
TextPassDumperDatabaseTest\testCheckpointGzip
testCheckpointGzip()
tests for working checkpoint generation in gzip format work.
Definition: backupTextPassTest.php:455
DumpTestCase\assertDumpStart
assertDumpStart( $fname, $skip_siteinfo=true)
Opens an XML file to analyze and optionally skips past siteinfo.
Definition: DumpTestCase.php:193
TextPassDumperDatabaseTest\$textId3_2
$textId3_2
Definition: backupTextPassTest.php:26
TextPassDumperDatabaseTest\$textId4_1
$textId4_1
Definition: backupTextPassTest.php:27
wfRecursiveRemoveDir
wfRecursiveRemoveDir( $dir)
Remove a directory and all its content.
Definition: GlobalFunctions.php:2123
TextPassDumperAccessor\getBufferSize
getBufferSize()
Gets the bufferSize.
Definition: backupTextPassTest.php:687
TextPassDumperDatabaseTest\addDBData
addDBData()
Stub.
Definition: backupTextPassTest.php:30
DumpTestCase\gunzip
gunzip( $fname)
gunzips the given file and stores the result in the original file name
Definition: DumpTestCase.php:86
BackupTextPassTestModelHandler\exportTransform
exportTransform( $text, $format=null)
Applies transformations on export (returns the blob unchanged per default).
Definition: backupTextPassTest.php:626
NS_TALK
const NS_TALK
Definition: Defines.php:63
TextPassDumperDatabaselessTest
Tests for TextPassDumper that do not rely on the database.
Definition: backupTextPassTest.php:641
TextPassDumperDatabaseTest\$revId4_1
$revId4_1
Definition: backupTextPassTest.php:27
TextPassDumperDatabaseTest\setUpStub
setUpStub( $fname=null, $iterations=1)
Creates a stub file that is used for testing the text pass of dumps.
Definition: backupTextPassTest.php:473
TextPassDumper
Definition: dumpTextPass.php:35
TextPassDumperDatabaseTest\testCheckpointPlain
testCheckpointPlain()
Broken per T70653.
Definition: backupTextPassTest.php:436
DumpTestCase\assertRevision
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.
Definition: DumpTestCase.php:334
TextPassDumperDatabaselessTest\bufferSizeProvider
bufferSizeProvider()
Ensures that setting the buffer size is effective.
Definition: backupTextPassTest.php:659
TextPassDumperDatabaseTest
Tests for TextPassDumper that rely on the database.
Definition: backupTextPassTest.php:17
TextPassDumperDatabaseTest\$textId3_1
$textId3_1
Definition: backupTextPassTest.php:26
MediaWikiTestCase\getNewTempDirectory
getNewTempDirectory()
obtains a new temporary directory
Definition: MediaWikiTestCase.php:460