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