51a1ed695177ce08b2ca7480434f4682dbb7edef
[lhc/web/wiklou.git] / tests / phpunit / maintenance / backup_PageTest.php
1 <?php
2
3 namespace MediaWiki\Tests\Maintenance;
4
5 use DumpBackup;
6 use Language;
7 use Title;
8 use WikiExporter;
9 use WikiPage;
10
11 /**
12 * Tests for page dumps of BackupDumper
13 *
14 * @group Database
15 * @group Dump
16 * @covers BackupDumper
17 */
18 class BackupDumperPageTest extends DumpTestCase {
19
20 // We'll add several pages, revision and texts. The following variables hold the
21 // corresponding ids.
22 private $pageId1, $pageId2, $pageId3, $pageId4;
23 private $pageTitle1, $pageTitle2, $pageTitle3, $pageTitle4;
24 private $revId1_1, $textId1_1;
25 private $revId2_1, $textId2_1, $revId2_2, $textId2_2;
26 private $revId2_3, $textId2_3, $revId2_4, $textId2_4;
27 private $revId3_1, $textId3_1, $revId3_2, $textId3_2;
28 private $revId4_1, $textId4_1;
29 private $namespace, $talk_namespace;
30
31 function addDBData() {
32 // be sure, titles created here using english namespace names
33 $this->setMwGlobals( [
34 'wgLanguageCode' => 'en',
35 'wgContLang' => Language::factory( 'en' ),
36 ] );
37
38 $this->tablesUsed[] = 'page';
39 $this->tablesUsed[] = 'revision';
40 $this->tablesUsed[] = 'ip_changes';
41 $this->tablesUsed[] = 'text';
42
43 try {
44 $this->namespace = $this->getDefaultWikitextNS();
45 $this->talk_namespace = NS_TALK;
46
47 if ( $this->namespace === $this->talk_namespace ) {
48 // @todo work around this.
49 throw new MWException( "The default wikitext namespace is the talk namespace. "
50 . " We can't currently deal with that." );
51 }
52
53 $this->pageTitle1 = Title::newFromText( 'BackupDumperTestP1', $this->namespace );
54 $page = WikiPage::factory( $this->pageTitle1 );
55 list( $this->revId1_1, $this->textId1_1 ) = $this->addRevision( $page,
56 "BackupDumperTestP1Text1", "BackupDumperTestP1Summary1" );
57 $this->pageId1 = $page->getId();
58
59 $this->pageTitle2 = Title::newFromText( 'BackupDumperTestP2', $this->namespace );
60 $page = WikiPage::factory( $this->pageTitle2 );
61 list( $this->revId2_1, $this->textId2_1 ) = $this->addRevision( $page,
62 "BackupDumperTestP2Text1", "BackupDumperTestP2Summary1" );
63 list( $this->revId2_2, $this->textId2_2 ) = $this->addRevision( $page,
64 "BackupDumperTestP2Text2", "BackupDumperTestP2Summary2" );
65 list( $this->revId2_3, $this->textId2_3 ) = $this->addRevision( $page,
66 "BackupDumperTestP2Text3", "BackupDumperTestP2Summary3" );
67 list( $this->revId2_4, $this->textId2_4 ) = $this->addRevision( $page,
68 "BackupDumperTestP2Text4 some additional Text ",
69 "BackupDumperTestP2Summary4 extra " );
70 $this->pageId2 = $page->getId();
71
72 $this->pageTitle3 = Title::newFromText( 'BackupDumperTestP3', $this->namespace );
73 $page = WikiPage::factory( $this->pageTitle3 );
74 list( $this->revId3_1, $this->textId3_1 ) = $this->addRevision( $page,
75 "BackupDumperTestP3Text1", "BackupDumperTestP2Summary1" );
76 list( $this->revId3_2, $this->textId3_2 ) = $this->addRevision( $page,
77 "BackupDumperTestP3Text2", "BackupDumperTestP2Summary2" );
78 $this->pageId3 = $page->getId();
79 $page->doDeleteArticle( "Testing ;)" );
80
81 $this->pageTitle4 = Title::newFromText( 'BackupDumperTestP1', $this->talk_namespace );
82 $page = WikiPage::factory( $this->pageTitle4 );
83 list( $this->revId4_1, $this->textId4_1 ) = $this->addRevision( $page,
84 "Talk about BackupDumperTestP1 Text1",
85 "Talk BackupDumperTestP1 Summary1" );
86 $this->pageId4 = $page->getId();
87 } catch ( Exception $e ) {
88 // We'd love to pass $e directly. However, ... see
89 // documentation of exceptionFromAddDBData in
90 // DumpTestCase
91 $this->exceptionFromAddDBData = $e;
92 }
93 }
94
95 protected function setUp() {
96 parent::setUp();
97
98 // Since we will restrict dumping by page ranges (to allow
99 // working tests, even if the db gets prepopulated by a base
100 // class), we have to assert, that the page id are consecutively
101 // increasing
102 $this->assertEquals(
103 [ $this->pageId2, $this->pageId3, $this->pageId4 ],
104 [ $this->pageId1 + 1, $this->pageId2 + 1, $this->pageId3 + 1 ],
105 "Page ids increasing without holes" );
106 }
107
108 function testFullTextPlain() {
109 // Preparing the dump
110 $fname = $this->getNewTempFile();
111
112 $dumper = new DumpBackup();
113 $dumper->loadWithArgv( [ '--full', '--quiet', '--output', 'file:' . $fname ] );
114 $dumper->startId = $this->pageId1;
115 $dumper->endId = $this->pageId4 + 1;
116 $dumper->setDB( $this->db );
117
118 // Performing the dump
119 $dumper->execute();
120
121 // Checking the dumped data
122 $this->assertDumpStart( $fname );
123
124 // Page 1
125 $this->assertPageStart( $this->pageId1, $this->namespace, $this->pageTitle1->getPrefixedText() );
126 $this->assertRevision( $this->revId1_1, "BackupDumperTestP1Summary1",
127 $this->textId1_1, 23, "0bolhl6ol7i6x0e7yq91gxgaan39j87",
128 "BackupDumperTestP1Text1" );
129 $this->assertPageEnd();
130
131 // Page 2
132 $this->assertPageStart( $this->pageId2, $this->namespace, $this->pageTitle2->getPrefixedText() );
133 $this->assertRevision( $this->revId2_1, "BackupDumperTestP2Summary1",
134 $this->textId2_1, 23, "jprywrymfhysqllua29tj3sc7z39dl2",
135 "BackupDumperTestP2Text1" );
136 $this->assertRevision( $this->revId2_2, "BackupDumperTestP2Summary2",
137 $this->textId2_2, 23, "b7vj5ks32po5m1z1t1br4o7scdwwy95",
138 "BackupDumperTestP2Text2", $this->revId2_1 );
139 $this->assertRevision( $this->revId2_3, "BackupDumperTestP2Summary3",
140 $this->textId2_3, 23, "jfunqmh1ssfb8rs43r19w98k28gg56r",
141 "BackupDumperTestP2Text3", $this->revId2_2 );
142 $this->assertRevision( $this->revId2_4, "BackupDumperTestP2Summary4 extra",
143 $this->textId2_4, 44, "6o1ciaxa6pybnqprmungwofc4lv00wv",
144 "BackupDumperTestP2Text4 some additional Text", $this->revId2_3 );
145 $this->assertPageEnd();
146
147 // Page 3
148 // -> Page is marked deleted. Hence not visible
149
150 // Page 4
151 $this->assertPageStart(
152 $this->pageId4,
153 $this->talk_namespace,
154 $this->pageTitle4->getPrefixedText()
155 );
156 $this->assertRevision( $this->revId4_1, "Talk BackupDumperTestP1 Summary1",
157 $this->textId4_1, 35, "nktofwzd0tl192k3zfepmlzxoax1lpe",
158 "Talk about BackupDumperTestP1 Text1" );
159 $this->assertPageEnd();
160
161 $this->assertDumpEnd();
162 }
163
164 function testFullStubPlain() {
165 // Preparing the dump
166 $fname = $this->getNewTempFile();
167
168 $dumper = new DumpBackup();
169 $dumper->loadWithArgv( [ '--full', '--quiet', '--output', 'file:' . $fname, '--stub' ] );
170 $dumper->startId = $this->pageId1;
171 $dumper->endId = $this->pageId4 + 1;
172 $dumper->setDB( $this->db );
173
174 // Performing the dump
175 $dumper->execute();
176
177 // Checking the dumped data
178 $this->assertDumpStart( $fname );
179
180 // Page 1
181 $this->assertPageStart( $this->pageId1, $this->namespace, $this->pageTitle1->getPrefixedText() );
182 $this->assertRevision( $this->revId1_1, "BackupDumperTestP1Summary1",
183 $this->textId1_1, 23, "0bolhl6ol7i6x0e7yq91gxgaan39j87" );
184 $this->assertPageEnd();
185
186 // Page 2
187 $this->assertPageStart( $this->pageId2, $this->namespace, $this->pageTitle2->getPrefixedText() );
188 $this->assertRevision( $this->revId2_1, "BackupDumperTestP2Summary1",
189 $this->textId2_1, 23, "jprywrymfhysqllua29tj3sc7z39dl2" );
190 $this->assertRevision( $this->revId2_2, "BackupDumperTestP2Summary2",
191 $this->textId2_2, 23, "b7vj5ks32po5m1z1t1br4o7scdwwy95", false, $this->revId2_1 );
192 $this->assertRevision( $this->revId2_3, "BackupDumperTestP2Summary3",
193 $this->textId2_3, 23, "jfunqmh1ssfb8rs43r19w98k28gg56r", false, $this->revId2_2 );
194 $this->assertRevision( $this->revId2_4, "BackupDumperTestP2Summary4 extra",
195 $this->textId2_4, 44, "6o1ciaxa6pybnqprmungwofc4lv00wv", false, $this->revId2_3 );
196 $this->assertPageEnd();
197
198 // Page 3
199 // -> Page is marked deleted. Hence not visible
200
201 // Page 4
202 $this->assertPageStart(
203 $this->pageId4,
204 $this->talk_namespace,
205 $this->pageTitle4->getPrefixedText()
206 );
207 $this->assertRevision( $this->revId4_1, "Talk BackupDumperTestP1 Summary1",
208 $this->textId4_1, 35, "nktofwzd0tl192k3zfepmlzxoax1lpe" );
209 $this->assertPageEnd();
210
211 $this->assertDumpEnd();
212 }
213
214 function testCurrentStubPlain() {
215 // Preparing the dump
216 $fname = $this->getNewTempFile();
217
218 $dumper = new DumpBackup( [ '--output', 'file:' . $fname ] );
219 $dumper->startId = $this->pageId1;
220 $dumper->endId = $this->pageId4 + 1;
221 $dumper->reporting = false;
222 $dumper->setDB( $this->db );
223
224 // Performing the dump
225 $dumper->dump( WikiExporter::CURRENT, WikiExporter::STUB );
226
227 // Checking the dumped data
228 $this->assertDumpStart( $fname );
229
230 // Page 1
231 $this->assertPageStart( $this->pageId1, $this->namespace, $this->pageTitle1->getPrefixedText() );
232 $this->assertRevision( $this->revId1_1, "BackupDumperTestP1Summary1",
233 $this->textId1_1, 23, "0bolhl6ol7i6x0e7yq91gxgaan39j87" );
234 $this->assertPageEnd();
235
236 // Page 2
237 $this->assertPageStart( $this->pageId2, $this->namespace, $this->pageTitle2->getPrefixedText() );
238 $this->assertRevision( $this->revId2_4, "BackupDumperTestP2Summary4 extra",
239 $this->textId2_4, 44, "6o1ciaxa6pybnqprmungwofc4lv00wv", false, $this->revId2_3 );
240 $this->assertPageEnd();
241
242 // Page 3
243 // -> Page is marked deleted. Hence not visible
244
245 // Page 4
246 $this->assertPageStart(
247 $this->pageId4,
248 $this->talk_namespace,
249 $this->pageTitle4->getPrefixedText()
250 );
251 $this->assertRevision( $this->revId4_1, "Talk BackupDumperTestP1 Summary1",
252 $this->textId4_1, 35, "nktofwzd0tl192k3zfepmlzxoax1lpe" );
253 $this->assertPageEnd();
254
255 $this->assertDumpEnd();
256 }
257
258 function testCurrentStubGzip() {
259 $this->checkHasGzip();
260
261 // Preparing the dump
262 $fname = $this->getNewTempFile();
263
264 $dumper = new DumpBackup( [ '--output', 'gzip:' . $fname ] );
265 $dumper->startId = $this->pageId1;
266 $dumper->endId = $this->pageId4 + 1;
267 $dumper->reporting = false;
268 $dumper->setDB( $this->db );
269
270 // Performing the dump
271 $dumper->dump( WikiExporter::CURRENT, WikiExporter::STUB );
272
273 // Checking the dumped data
274 $this->gunzip( $fname );
275 $this->assertDumpStart( $fname );
276
277 // Page 1
278 $this->assertPageStart( $this->pageId1, $this->namespace, $this->pageTitle1->getPrefixedText() );
279 $this->assertRevision( $this->revId1_1, "BackupDumperTestP1Summary1",
280 $this->textId1_1, 23, "0bolhl6ol7i6x0e7yq91gxgaan39j87" );
281 $this->assertPageEnd();
282
283 // Page 2
284 $this->assertPageStart( $this->pageId2, $this->namespace, $this->pageTitle2->getPrefixedText() );
285 $this->assertRevision( $this->revId2_4, "BackupDumperTestP2Summary4 extra",
286 $this->textId2_4, 44, "6o1ciaxa6pybnqprmungwofc4lv00wv", false, $this->revId2_3 );
287 $this->assertPageEnd();
288
289 // Page 3
290 // -> Page is marked deleted. Hence not visible
291
292 // Page 4
293 $this->assertPageStart(
294 $this->pageId4,
295 $this->talk_namespace,
296 $this->pageTitle4->getPrefixedText()
297 );
298 $this->assertRevision( $this->revId4_1, "Talk BackupDumperTestP1 Summary1",
299 $this->textId4_1, 35, "nktofwzd0tl192k3zfepmlzxoax1lpe" );
300 $this->assertPageEnd();
301
302 $this->assertDumpEnd();
303 }
304
305 /**
306 * xmldumps-backup typically performs a single dump that that writes
307 * out three files
308 * - gzipped stubs of everything (meta-history)
309 * - gzipped stubs of latest revisions of all pages (meta-current)
310 * - gzipped stubs of latest revisions of all pages of namespage 0
311 * (articles)
312 *
313 * We reproduce such a setup with our mini fixture, although we omit
314 * chunks, and all the other gimmicks of xmldumps-backup.
315 */
316 function testXmlDumpsBackupUseCase() {
317 $this->checkHasGzip();
318
319 $fnameMetaHistory = $this->getNewTempFile();
320 $fnameMetaCurrent = $this->getNewTempFile();
321 $fnameArticles = $this->getNewTempFile();
322
323 $dumper = new DumpBackup( [ "--full", "--stub", "--output=gzip:" . $fnameMetaHistory,
324 "--output=gzip:" . $fnameMetaCurrent, "--filter=latest",
325 "--output=gzip:" . $fnameArticles, "--filter=latest",
326 "--filter=notalk", "--filter=namespace:!NS_USER",
327 "--reporting=1000" ] );
328 $dumper->startId = $this->pageId1;
329 $dumper->endId = $this->pageId4 + 1;
330 $dumper->setDB( $this->db );
331
332 // xmldumps-backup uses reporting. We will not check the exact reported
333 // message, as they are dependent on the processing power of the used
334 // computer. We only check that reporting does not crash the dumping
335 // and that something is reported
336 $dumper->stderr = fopen( 'php://output', 'a' );
337 if ( $dumper->stderr === false ) {
338 $this->fail( "Could not open stream for stderr" );
339 }
340
341 // Performing the dump
342 $dumper->dump( WikiExporter::FULL, WikiExporter::STUB );
343
344 $this->assertTrue( fclose( $dumper->stderr ), "Closing stderr handle" );
345
346 // Checking meta-history -------------------------------------------------
347
348 $this->gunzip( $fnameMetaHistory );
349 $this->assertDumpStart( $fnameMetaHistory );
350
351 // Page 1
352 $this->assertPageStart( $this->pageId1, $this->namespace, $this->pageTitle1->getPrefixedText() );
353 $this->assertRevision( $this->revId1_1, "BackupDumperTestP1Summary1",
354 $this->textId1_1, 23, "0bolhl6ol7i6x0e7yq91gxgaan39j87" );
355 $this->assertPageEnd();
356
357 // Page 2
358 $this->assertPageStart( $this->pageId2, $this->namespace, $this->pageTitle2->getPrefixedText() );
359 $this->assertRevision( $this->revId2_1, "BackupDumperTestP2Summary1",
360 $this->textId2_1, 23, "jprywrymfhysqllua29tj3sc7z39dl2" );
361 $this->assertRevision( $this->revId2_2, "BackupDumperTestP2Summary2",
362 $this->textId2_2, 23, "b7vj5ks32po5m1z1t1br4o7scdwwy95", false, $this->revId2_1 );
363 $this->assertRevision( $this->revId2_3, "BackupDumperTestP2Summary3",
364 $this->textId2_3, 23, "jfunqmh1ssfb8rs43r19w98k28gg56r", false, $this->revId2_2 );
365 $this->assertRevision( $this->revId2_4, "BackupDumperTestP2Summary4 extra",
366 $this->textId2_4, 44, "6o1ciaxa6pybnqprmungwofc4lv00wv", false, $this->revId2_3 );
367 $this->assertPageEnd();
368
369 // Page 3
370 // -> Page is marked deleted. Hence not visible
371
372 // Page 4
373 $this->assertPageStart(
374 $this->pageId4,
375 $this->talk_namespace,
376 $this->pageTitle4->getPrefixedText()
377 );
378 $this->assertRevision( $this->revId4_1, "Talk BackupDumperTestP1 Summary1",
379 $this->textId4_1, 35, "nktofwzd0tl192k3zfepmlzxoax1lpe" );
380 $this->assertPageEnd();
381
382 $this->assertDumpEnd();
383
384 // Checking meta-current -------------------------------------------------
385
386 $this->gunzip( $fnameMetaCurrent );
387 $this->assertDumpStart( $fnameMetaCurrent );
388
389 // Page 1
390 $this->assertPageStart( $this->pageId1, $this->namespace, $this->pageTitle1->getPrefixedText() );
391 $this->assertRevision( $this->revId1_1, "BackupDumperTestP1Summary1",
392 $this->textId1_1, 23, "0bolhl6ol7i6x0e7yq91gxgaan39j87" );
393 $this->assertPageEnd();
394
395 // Page 2
396 $this->assertPageStart( $this->pageId2, $this->namespace, $this->pageTitle2->getPrefixedText() );
397 $this->assertRevision( $this->revId2_4, "BackupDumperTestP2Summary4 extra",
398 $this->textId2_4, 44, "6o1ciaxa6pybnqprmungwofc4lv00wv", false, $this->revId2_3 );
399 $this->assertPageEnd();
400
401 // Page 3
402 // -> Page is marked deleted. Hence not visible
403
404 // Page 4
405 $this->assertPageStart(
406 $this->pageId4,
407 $this->talk_namespace,
408 $this->pageTitle4->getPrefixedText()
409 );
410 $this->assertRevision( $this->revId4_1, "Talk BackupDumperTestP1 Summary1",
411 $this->textId4_1, 35, "nktofwzd0tl192k3zfepmlzxoax1lpe" );
412 $this->assertPageEnd();
413
414 $this->assertDumpEnd();
415
416 // Checking articles -------------------------------------------------
417
418 $this->gunzip( $fnameArticles );
419 $this->assertDumpStart( $fnameArticles );
420
421 // Page 1
422 $this->assertPageStart( $this->pageId1, $this->namespace, $this->pageTitle1->getPrefixedText() );
423 $this->assertRevision( $this->revId1_1, "BackupDumperTestP1Summary1",
424 $this->textId1_1, 23, "0bolhl6ol7i6x0e7yq91gxgaan39j87" );
425 $this->assertPageEnd();
426
427 // Page 2
428 $this->assertPageStart( $this->pageId2, $this->namespace, $this->pageTitle2->getPrefixedText() );
429 $this->assertRevision( $this->revId2_4, "BackupDumperTestP2Summary4 extra",
430 $this->textId2_4, 44, "6o1ciaxa6pybnqprmungwofc4lv00wv", false, $this->revId2_3 );
431 $this->assertPageEnd();
432
433 // Page 3
434 // -> Page is marked deleted. Hence not visible
435
436 // Page 4
437 // -> Page is not in $this->namespace. Hence not visible
438
439 $this->assertDumpEnd();
440
441 $this->expectETAOutput();
442 }
443 }