Bug: T192167 Depends-On: I581e54278ac5da3f4e399e33f2c7ad468bae6b43 Change-Id: I3a21fb55db76bac51afdd399cf40ed0760e4f343
870 lines
22 KiB
PHP
870 lines
22 KiB
PHP
<?php
|
|
|
|
namespace MediaWiki\Tests\Maintenance;
|
|
|
|
use DumpBackup;
|
|
use Exception;
|
|
use MediaWiki\MediaWikiServices;
|
|
use MediaWiki\Revision\RevisionRecord;
|
|
use MediaWiki\Revision\SlotRecord;
|
|
use MediaWikiTestCase;
|
|
use MWException;
|
|
use RequestContext;
|
|
use RevisionDeleter;
|
|
use Title;
|
|
use WikiExporter;
|
|
use Wikimedia\Rdbms\IDatabase;
|
|
use Wikimedia\Rdbms\LoadBalancer;
|
|
use WikiPage;
|
|
use XmlDumpWriter;
|
|
|
|
/**
|
|
* Tests for page dumps of BackupDumper
|
|
*
|
|
* @group Database
|
|
* @group Dump
|
|
* @covers BackupDumper
|
|
*/
|
|
class BackupDumperPageTest extends DumpTestCase {
|
|
|
|
// We'll add several pages, revision and texts. The following variables hold the
|
|
// corresponding ids.
|
|
private $pageId1, $pageId2, $pageId3, $pageId4, $pageId5;
|
|
private $pageTitle1, $pageTitle2, $pageTitle3, $pageTitle4, $pageTitle5;
|
|
private $revId1_1, $textId1_1;
|
|
private $revId2_1, $textId2_1, $revId2_2, $textId2_2;
|
|
private $revId2_3, $textId2_3, $revId2_4, $textId2_4;
|
|
private $revId3_1, $textId3_1, $revId3_2, $textId3_2;
|
|
private $revId4_1, $textId4_1;
|
|
private $revId5_1, $textId5_1;
|
|
private $namespace, $talk_namespace;
|
|
|
|
/**
|
|
* @var LoadBalancer|null
|
|
*/
|
|
private $streamingLoadBalancer = null;
|
|
|
|
public function addDBData() {
|
|
// be sure, titles created here using english namespace names
|
|
$this->setContentLang( 'en' );
|
|
|
|
$this->tablesUsed[] = 'page';
|
|
$this->tablesUsed[] = 'revision';
|
|
$this->tablesUsed[] = 'ip_changes';
|
|
$this->tablesUsed[] = 'text';
|
|
|
|
try {
|
|
$this->namespace = $this->getDefaultWikitextNS();
|
|
$this->talk_namespace = NS_TALK;
|
|
|
|
if ( $this->namespace === $this->talk_namespace ) {
|
|
// @todo work around this.
|
|
throw new MWException( "The default wikitext namespace is the talk namespace. "
|
|
. " We can't currently deal with that." );
|
|
}
|
|
|
|
$this->pageTitle1 = Title::newFromText( 'BackupDumperTestP1', $this->namespace );
|
|
$page = WikiPage::factory( $this->pageTitle1 );
|
|
list( $this->revId1_1, $this->textId1_1 ) = $this->addRevision( $page,
|
|
"BackupDumperTestP1Text1", "BackupDumperTestP1Summary1" );
|
|
$this->pageId1 = $page->getId();
|
|
|
|
$this->pageTitle2 = Title::newFromText( 'BackupDumperTestP2', $this->namespace );
|
|
$page = WikiPage::factory( $this->pageTitle2 );
|
|
list( $this->revId2_1, $this->textId2_1 ) = $this->addRevision( $page,
|
|
"BackupDumperTestP2Text1", "BackupDumperTestP2Summary1" );
|
|
list( $this->revId2_2, $this->textId2_2 ) = $this->addRevision( $page,
|
|
"BackupDumperTestP2Text2", "BackupDumperTestP2Summary2" );
|
|
list( $this->revId2_3, $this->textId2_3 ) = $this->addRevision( $page,
|
|
"BackupDumperTestP2Text3", "BackupDumperTestP2Summary3" );
|
|
list( $this->revId2_4, $this->textId2_4 ) = $this->addRevision( $page,
|
|
"BackupDumperTestP2Text4 some additional Text ",
|
|
"BackupDumperTestP2Summary4 extra " );
|
|
$this->pageId2 = $page->getId();
|
|
|
|
$revDel = RevisionDeleter::createList(
|
|
'revision',
|
|
RequestContext::getMain(),
|
|
$this->pageTitle2,
|
|
[ $this->revId2_2 ]
|
|
);
|
|
$revDel->setVisibility( [
|
|
'value' => [ RevisionRecord::DELETED_TEXT => 1 ],
|
|
'comment' => 'testing!'
|
|
] );
|
|
|
|
$this->pageTitle3 = Title::newFromText( 'BackupDumperTestP3', $this->namespace );
|
|
$page = WikiPage::factory( $this->pageTitle3 );
|
|
list( $this->revId3_1, $this->textId3_1 ) = $this->addRevision( $page,
|
|
"BackupDumperTestP3Text1", "BackupDumperTestP2Summary1" );
|
|
list( $this->revId3_2, $this->textId3_2 ) = $this->addRevision( $page,
|
|
"BackupDumperTestP3Text2", "BackupDumperTestP2Summary2" );
|
|
$this->pageId3 = $page->getId();
|
|
$page->doDeleteArticle( "Testing ;)" );
|
|
|
|
$this->pageTitle4 = Title::newFromText( 'BackupDumperTestP1', $this->talk_namespace );
|
|
$page = WikiPage::factory( $this->pageTitle4 );
|
|
list( $this->revId4_1, $this->textId4_1 ) = $this->addRevision( $page,
|
|
"Talk about BackupDumperTestP1 Text1",
|
|
"Talk BackupDumperTestP1 Summary1" );
|
|
$this->pageId4 = $page->getId();
|
|
|
|
$this->pageTitle5 = Title::newFromText( 'BackupDumperTestP5' );
|
|
$page = WikiPage::factory( $this->pageTitle5 );
|
|
list( $this->revId5_1, $this->textId5_1 ) = $this->addRevision( $page,
|
|
"BackupDumperTestP5 Text1",
|
|
"BackupDumperTestP5 Summary1" );
|
|
$this->pageId5 = $page->getId();
|
|
|
|
$this->corruptRevisionData( $page->getRevision()->getRevisionRecord() );
|
|
} catch ( Exception $e ) {
|
|
// We'd love to pass $e directly. However, ... see
|
|
// documentation of exceptionFromAddDBData in
|
|
// DumpTestCase
|
|
$this->exceptionFromAddDBData = $e;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Corrupt the information about the given revision in the database.
|
|
*
|
|
* @param RevisionRecord $revision
|
|
*/
|
|
private function corruptRevisionData( RevisionRecord $revision ) {
|
|
global $wgMultiContentRevisionSchemaMigrationStage;
|
|
|
|
if ( ( $wgMultiContentRevisionSchemaMigrationStage & SCHEMA_COMPAT_WRITE_OLD ) ) {
|
|
$this->db->update(
|
|
'revision',
|
|
[ 'rev_text_id' => 0 ],
|
|
[ 'rev_id' => $revision->getId() ]
|
|
);
|
|
}
|
|
|
|
if ( ( $wgMultiContentRevisionSchemaMigrationStage & SCHEMA_COMPAT_WRITE_NEW ) ) {
|
|
$this->db->update(
|
|
'content',
|
|
[ 'content_address' => 'tt:0' ],
|
|
[ 'content_id' => $revision->getSlot( SlotRecord::MAIN )->getContentId() ]
|
|
);
|
|
}
|
|
}
|
|
|
|
protected function setUp() : void {
|
|
parent::setUp();
|
|
|
|
// Since we will restrict dumping by page ranges (to allow
|
|
// working tests, even if the db gets prepopulated by a base
|
|
// class), we have to assert, that the page id are consecutively
|
|
// increasing
|
|
$this->assertEquals(
|
|
[ $this->pageId2, $this->pageId3, $this->pageId4 ],
|
|
[ $this->pageId1 + 1, $this->pageId2 + 1, $this->pageId3 + 1 ],
|
|
"Page ids increasing without holes" );
|
|
}
|
|
|
|
public function tearDown() : void {
|
|
parent::tearDown();
|
|
|
|
if ( isset( $this->streamingLoadBalancer ) ) {
|
|
$this->streamingLoadBalancer->closeAll();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns a new database connection which is separate from the conenctions returned
|
|
* by the default LoadBalancer instance.
|
|
*
|
|
* @return IDatabase
|
|
*/
|
|
private function newStreamingDBConnection() {
|
|
// Create a *new* LoadBalancer, so no connections are shared
|
|
if ( !$this->streamingLoadBalancer ) {
|
|
$lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
|
|
|
|
$this->streamingLoadBalancer = $lbFactory->newMainLB();
|
|
}
|
|
|
|
$db = $this->streamingLoadBalancer->getConnection( DB_REPLICA );
|
|
|
|
// Make sure the DB connection has the fake table clones and the fake table prefix
|
|
MediaWikiTestCase::setupDatabaseWithTestPrefix( $db );
|
|
|
|
// Make sure the DB connection has all the test data
|
|
$this->copyTestData( $this->db, $db );
|
|
|
|
return $db;
|
|
}
|
|
|
|
/**
|
|
* @param array $argv
|
|
* @param int $startId
|
|
* @param int $endId
|
|
*
|
|
* @return DumpBackup
|
|
*/
|
|
private function newDumpBackup( $argv, $startId, $endId ) {
|
|
$dumper = new DumpBackup( $argv );
|
|
$dumper->startId = $startId;
|
|
$dumper->endId = $endId;
|
|
$dumper->reporting = false;
|
|
|
|
// NOTE: The copyTestData() method used by newStreamingDBConnection()
|
|
// doesn't work with SQLite (T217607).
|
|
// But DatabaseSqlite doesn't support streaming anyway, so just skip that part.
|
|
if ( $this->db->getType() === 'sqlite' ) {
|
|
$dumper->setDB( $this->db );
|
|
} else {
|
|
$dumper->setDB( $this->newStreamingDBConnection() );
|
|
}
|
|
|
|
return $dumper;
|
|
}
|
|
|
|
public function schemaVersionProvider() {
|
|
foreach ( XmlDumpWriter::$supportedSchemas as $schemaVersion ) {
|
|
yield [ $schemaVersion ];
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @dataProvider schemaVersionProvider
|
|
*/
|
|
public function testFullTextPlain( $schemaVersion ) {
|
|
// Preparing the dump
|
|
$fname = $this->getNewTempFile();
|
|
|
|
$dumper = $this->newDumpBackup(
|
|
[ '--full', '--quiet', '--output', 'file:' . $fname, '--schema-version', $schemaVersion ],
|
|
$this->pageId1,
|
|
$this->pageId5 + 1
|
|
);
|
|
|
|
// Performing the dump. Suppress warnings, since we want to test
|
|
// accessing broken revision data (page 5).
|
|
$this->setMwGlobals( 'wgDevelopmentWarnings', false );
|
|
$dumper->execute();
|
|
$this->setMwGlobals( 'wgDevelopmentWarnings', true );
|
|
|
|
// Checking the dumped data
|
|
$this->assertDumpSchema( $fname, $this->getXmlSchemaPath( $schemaVersion ) );
|
|
$asserter = $this->getDumpAsserter( $schemaVersion );
|
|
|
|
$asserter->assertDumpStart( $fname );
|
|
|
|
// Page 1
|
|
$asserter->assertPageStart(
|
|
$this->pageId1,
|
|
$this->namespace,
|
|
$this->pageTitle1->getPrefixedText()
|
|
);
|
|
$asserter->assertRevision(
|
|
$this->revId1_1,
|
|
"BackupDumperTestP1Summary1",
|
|
$this->textId1_1,
|
|
23,
|
|
"0bolhl6ol7i6x0e7yq91gxgaan39j87",
|
|
"BackupDumperTestP1Text1"
|
|
);
|
|
$asserter->assertPageEnd();
|
|
|
|
// Page 2
|
|
$asserter->assertPageStart(
|
|
$this->pageId2,
|
|
$this->namespace,
|
|
$this->pageTitle2->getPrefixedText()
|
|
);
|
|
$asserter->assertRevision(
|
|
$this->revId2_1,
|
|
"BackupDumperTestP2Summary1",
|
|
$this->textId2_1,
|
|
23,
|
|
"jprywrymfhysqllua29tj3sc7z39dl2",
|
|
"BackupDumperTestP2Text1"
|
|
);
|
|
$asserter->assertRevision(
|
|
$this->revId2_2,
|
|
"BackupDumperTestP2Summary2",
|
|
null, // deleted!
|
|
false, // deleted!
|
|
null, // deleted!
|
|
false, // deleted!
|
|
$this->revId2_1
|
|
);
|
|
$asserter->assertRevision(
|
|
$this->revId2_3,
|
|
"BackupDumperTestP2Summary3",
|
|
$this->textId2_3,
|
|
23,
|
|
"jfunqmh1ssfb8rs43r19w98k28gg56r",
|
|
"BackupDumperTestP2Text3",
|
|
$this->revId2_2
|
|
);
|
|
$asserter->assertRevision(
|
|
$this->revId2_4,
|
|
"BackupDumperTestP2Summary4 extra",
|
|
$this->textId2_4,
|
|
44,
|
|
"6o1ciaxa6pybnqprmungwofc4lv00wv",
|
|
"BackupDumperTestP2Text4 some additional Text",
|
|
$this->revId2_3
|
|
);
|
|
$asserter->assertPageEnd();
|
|
|
|
// Page 3
|
|
// -> Page is marked deleted. Hence not visible
|
|
|
|
// Page 4
|
|
$asserter->assertPageStart(
|
|
$this->pageId4,
|
|
$this->talk_namespace,
|
|
$this->pageTitle4->getPrefixedText()
|
|
);
|
|
$asserter->assertRevision(
|
|
$this->revId4_1,
|
|
"Talk BackupDumperTestP1 Summary1",
|
|
$this->textId4_1,
|
|
35,
|
|
"nktofwzd0tl192k3zfepmlzxoax1lpe",
|
|
"Talk about BackupDumperTestP1 Text1",
|
|
false,
|
|
CONTENT_MODEL_WIKITEXT,
|
|
CONTENT_FORMAT_WIKITEXT
|
|
);
|
|
$asserter->assertPageEnd();
|
|
|
|
// Page 5 (broken revision data)
|
|
$asserter->assertPageStart(
|
|
$this->pageId5,
|
|
$this->namespace,
|
|
$this->pageTitle5->getPrefixedText()
|
|
);
|
|
$asserter->assertRevision(
|
|
$this->revId5_1,
|
|
"BackupDumperTestP5 Summary1",
|
|
null,
|
|
24,
|
|
"d2vipufvkfs9wfruwjfj8eschxw0fbl",
|
|
false,
|
|
false,
|
|
CONTENT_MODEL_WIKITEXT,
|
|
CONTENT_FORMAT_WIKITEXT
|
|
);
|
|
$asserter->assertPageEnd();
|
|
|
|
$asserter->assertDumpEnd();
|
|
|
|
// FIXME: add multi-slot test case!
|
|
}
|
|
|
|
/**
|
|
* @dataProvider schemaVersionProvider
|
|
*/
|
|
public function testFullStubPlain( $schemaVersion ) {
|
|
// Preparing the dump
|
|
$fname = $this->getNewTempFile();
|
|
|
|
$dumper = $this->newDumpBackup(
|
|
[
|
|
'--full',
|
|
'--quiet',
|
|
'--output',
|
|
'file:' . $fname,
|
|
'--stub',
|
|
'--schema-version', $schemaVersion,
|
|
],
|
|
$this->pageId1,
|
|
$this->pageId5 + 1
|
|
);
|
|
|
|
// Performing the dump. Suppress warnings, since we want to test
|
|
// accessing broken revision data (page 5).
|
|
$this->setMwGlobals( 'wgDevelopmentWarnings', false );
|
|
$dumper->execute();
|
|
$this->setMwGlobals( 'wgDevelopmentWarnings', true );
|
|
|
|
// Checking the dumped data
|
|
$this->assertDumpSchema( $fname, $this->getXmlSchemaPath( $schemaVersion ) );
|
|
$asserter = $this->getDumpAsserter( $schemaVersion );
|
|
|
|
$asserter->assertDumpStart( $fname );
|
|
|
|
// Page 1
|
|
$asserter->assertPageStart(
|
|
$this->pageId1,
|
|
$this->namespace,
|
|
$this->pageTitle1->getPrefixedText()
|
|
);
|
|
$asserter->assertRevision(
|
|
$this->revId1_1,
|
|
"BackupDumperTestP1Summary1",
|
|
$this->textId1_1,
|
|
23,
|
|
"0bolhl6ol7i6x0e7yq91gxgaan39j87"
|
|
);
|
|
$asserter->assertPageEnd();
|
|
|
|
// Page 2
|
|
$asserter->assertPageStart(
|
|
$this->pageId2,
|
|
$this->namespace,
|
|
$this->pageTitle2->getPrefixedText()
|
|
);
|
|
$asserter->assertRevision(
|
|
$this->revId2_1,
|
|
"BackupDumperTestP2Summary1",
|
|
$this->textId2_1,
|
|
23,
|
|
"jprywrymfhysqllua29tj3sc7z39dl2"
|
|
);
|
|
$asserter->assertRevision(
|
|
$this->revId2_2,
|
|
"BackupDumperTestP2Summary2",
|
|
null, // deleted!
|
|
false, // deleted!
|
|
null, // deleted!
|
|
false, // deleted!
|
|
$this->revId2_1
|
|
);
|
|
$asserter->assertRevision(
|
|
$this->revId2_3,
|
|
"BackupDumperTestP2Summary3",
|
|
$this->textId2_3,
|
|
23,
|
|
"jfunqmh1ssfb8rs43r19w98k28gg56r",
|
|
false,
|
|
$this->revId2_2
|
|
);
|
|
$asserter->assertRevision(
|
|
$this->revId2_4,
|
|
"BackupDumperTestP2Summary4 extra",
|
|
$this->textId2_4,
|
|
44,
|
|
"6o1ciaxa6pybnqprmungwofc4lv00wv",
|
|
false,
|
|
$this->revId2_3
|
|
);
|
|
$asserter->assertPageEnd();
|
|
|
|
// Page 3
|
|
// -> Page is marked deleted. Hence not visible
|
|
|
|
// Page 4
|
|
$asserter->assertPageStart(
|
|
$this->pageId4,
|
|
$this->talk_namespace,
|
|
$this->pageTitle4->getPrefixedText()
|
|
);
|
|
$asserter->assertRevision(
|
|
$this->revId4_1,
|
|
"Talk BackupDumperTestP1 Summary1",
|
|
$this->textId4_1,
|
|
35,
|
|
"nktofwzd0tl192k3zfepmlzxoax1lpe"
|
|
);
|
|
$asserter->assertPageEnd();
|
|
|
|
// Page 5 (broken revision data)
|
|
$asserter->assertPageStart(
|
|
$this->pageId5,
|
|
$this->namespace,
|
|
$this->pageTitle5->getPrefixedText()
|
|
);
|
|
$asserter->assertRevision(
|
|
$this->revId5_1,
|
|
"BackupDumperTestP5 Summary1",
|
|
null,
|
|
24,
|
|
"d2vipufvkfs9wfruwjfj8eschxw0fbl"
|
|
);
|
|
$asserter->assertPageEnd();
|
|
|
|
$asserter->assertDumpEnd();
|
|
}
|
|
|
|
/**
|
|
* @dataProvider schemaVersionProvider
|
|
*/
|
|
public function testCurrentStubPlain( $schemaVersion ) {
|
|
// Preparing the dump
|
|
$fname = $this->getNewTempFile();
|
|
|
|
$dumper = $this->newDumpBackup(
|
|
[ '--output', 'file:' . $fname, '--schema-version', $schemaVersion ],
|
|
$this->pageId1,
|
|
$this->pageId4 + 1
|
|
);
|
|
|
|
// Performing the dump
|
|
$dumper->dump( WikiExporter::CURRENT, WikiExporter::STUB );
|
|
|
|
// Checking the dumped data
|
|
$this->assertDumpSchema( $fname, $this->getXmlSchemaPath( $schemaVersion ) );
|
|
|
|
$asserter = $this->getDumpAsserter( $schemaVersion );
|
|
$asserter->assertDumpStart( $fname );
|
|
|
|
// Page 1
|
|
$asserter->assertPageStart(
|
|
$this->pageId1,
|
|
$this->namespace,
|
|
$this->pageTitle1->getPrefixedText()
|
|
);
|
|
$asserter->assertRevision(
|
|
$this->revId1_1,
|
|
"BackupDumperTestP1Summary1",
|
|
$this->textId1_1,
|
|
23,
|
|
"0bolhl6ol7i6x0e7yq91gxgaan39j87"
|
|
);
|
|
$asserter->assertPageEnd();
|
|
|
|
// Page 2
|
|
$asserter->assertPageStart(
|
|
$this->pageId2,
|
|
$this->namespace,
|
|
$this->pageTitle2->getPrefixedText()
|
|
);
|
|
$asserter->assertRevision(
|
|
$this->revId2_4,
|
|
"BackupDumperTestP2Summary4 extra",
|
|
$this->textId2_4,
|
|
44,
|
|
"6o1ciaxa6pybnqprmungwofc4lv00wv",
|
|
false,
|
|
$this->revId2_3
|
|
);
|
|
$asserter->assertPageEnd();
|
|
|
|
// Page 3
|
|
// -> Page is marked deleted. Hence not visible
|
|
|
|
// Page 4
|
|
$asserter->assertPageStart(
|
|
$this->pageId4,
|
|
$this->talk_namespace,
|
|
$this->pageTitle4->getPrefixedText()
|
|
);
|
|
$asserter->assertRevision(
|
|
$this->revId4_1,
|
|
"Talk BackupDumperTestP1 Summary1",
|
|
$this->textId4_1,
|
|
35,
|
|
"nktofwzd0tl192k3zfepmlzxoax1lpe"
|
|
);
|
|
$asserter->assertPageEnd();
|
|
|
|
$asserter->assertDumpEnd();
|
|
}
|
|
|
|
public function testCurrentStubGzip() {
|
|
$this->checkHasGzip();
|
|
|
|
// Preparing the dump
|
|
$fname = $this->getNewTempFile();
|
|
|
|
$dumper = $this->newDumpBackup(
|
|
[ '--output', 'gzip:' . $fname ],
|
|
$this->pageId1,
|
|
$this->pageId4 + 1
|
|
);
|
|
|
|
// Performing the dump
|
|
$dumper->dump( WikiExporter::CURRENT, WikiExporter::STUB );
|
|
|
|
// Checking the dumped data
|
|
$this->gunzip( $fname );
|
|
|
|
$asserter = $this->getDumpAsserter();
|
|
$asserter->assertDumpStart( $fname );
|
|
|
|
// Page 1
|
|
$asserter->assertPageStart(
|
|
$this->pageId1,
|
|
$this->namespace,
|
|
$this->pageTitle1->getPrefixedText()
|
|
);
|
|
$asserter->assertRevision(
|
|
$this->revId1_1,
|
|
"BackupDumperTestP1Summary1",
|
|
$this->textId1_1,
|
|
23,
|
|
"0bolhl6ol7i6x0e7yq91gxgaan39j87"
|
|
);
|
|
$asserter->assertPageEnd();
|
|
|
|
// Page 2
|
|
$asserter->assertPageStart(
|
|
$this->pageId2,
|
|
$this->namespace,
|
|
$this->pageTitle2->getPrefixedText()
|
|
);
|
|
$asserter->assertRevision(
|
|
$this->revId2_4,
|
|
"BackupDumperTestP2Summary4 extra",
|
|
$this->textId2_4,
|
|
44,
|
|
"6o1ciaxa6pybnqprmungwofc4lv00wv",
|
|
false,
|
|
$this->revId2_3
|
|
);
|
|
$asserter->assertPageEnd();
|
|
|
|
// Page 3
|
|
// -> Page is marked deleted. Hence not visible
|
|
|
|
// Page 4
|
|
$asserter->assertPageStart(
|
|
$this->pageId4,
|
|
$this->talk_namespace,
|
|
$this->pageTitle4->getPrefixedText()
|
|
);
|
|
$asserter->assertRevision( $this->revId4_1, "Talk BackupDumperTestP1 Summary1",
|
|
$this->textId4_1, 35, "nktofwzd0tl192k3zfepmlzxoax1lpe" );
|
|
$asserter->assertPageEnd();
|
|
|
|
$asserter->assertDumpEnd();
|
|
}
|
|
|
|
/**
|
|
* xmldumps-backup typically performs a single dump that that writes
|
|
* out three files
|
|
* - gzipped stubs of everything (meta-history)
|
|
* - gzipped stubs of latest revisions of all pages (meta-current)
|
|
* - gzipped stubs of latest revisions of all pages of namespage 0
|
|
* (articles)
|
|
*
|
|
* We reproduce such a setup with our mini fixture, although we omit
|
|
* chunks, and all the other gimmicks of xmldumps-backup.
|
|
*
|
|
* @dataProvider schemaVersionProvider
|
|
*/
|
|
public function testXmlDumpsBackupUseCase( $schemaVersion ) {
|
|
$this->checkHasGzip();
|
|
|
|
$fnameMetaHistory = $this->getNewTempFile();
|
|
$fnameMetaCurrent = $this->getNewTempFile();
|
|
$fnameArticles = $this->getNewTempFile();
|
|
|
|
$dumper = $this->newDumpBackup(
|
|
[ "--full", "--stub", "--output=gzip:" . $fnameMetaHistory,
|
|
"--output=gzip:" . $fnameMetaCurrent, "--filter=latest",
|
|
"--output=gzip:" . $fnameArticles, "--filter=latest",
|
|
"--filter=notalk", "--filter=namespace:!NS_USER",
|
|
"--reporting=1000", '--schema-version', $schemaVersion
|
|
],
|
|
$this->pageId1,
|
|
$this->pageId4 + 1
|
|
);
|
|
$dumper->reporting = true;
|
|
|
|
// xmldumps-backup uses reporting. We will not check the exact reported
|
|
// message, as they are dependent on the processing power of the used
|
|
// computer. We only check that reporting does not crash the dumping
|
|
// and that something is reported
|
|
$dumper->stderr = fopen( 'php://output', 'a' );
|
|
if ( $dumper->stderr === false ) {
|
|
$this->fail( "Could not open stream for stderr" );
|
|
}
|
|
|
|
// Performing the dump
|
|
$dumper->dump( WikiExporter::FULL, WikiExporter::STUB );
|
|
|
|
$this->assertTrue( fclose( $dumper->stderr ), "Closing stderr handle" );
|
|
|
|
// Checking meta-history -------------------------------------------------
|
|
|
|
$this->gunzip( $fnameMetaHistory );
|
|
$this->assertDumpSchema( $fnameMetaHistory, $this->getXmlSchemaPath( $schemaVersion ) );
|
|
|
|
$asserter = $this->getDumpAsserter( $schemaVersion );
|
|
$asserter->assertDumpStart( $fnameMetaHistory );
|
|
|
|
// Page 1
|
|
$asserter->assertPageStart(
|
|
$this->pageId1,
|
|
$this->namespace,
|
|
$this->pageTitle1->getPrefixedText()
|
|
);
|
|
$asserter->assertRevision(
|
|
$this->revId1_1,
|
|
"BackupDumperTestP1Summary1",
|
|
$this->textId1_1,
|
|
23,
|
|
"0bolhl6ol7i6x0e7yq91gxgaan39j87"
|
|
);
|
|
$asserter->assertPageEnd();
|
|
|
|
// Page 2
|
|
$asserter->assertPageStart(
|
|
$this->pageId2,
|
|
$this->namespace,
|
|
$this->pageTitle2->getPrefixedText()
|
|
);
|
|
$asserter->assertRevision(
|
|
$this->revId2_1,
|
|
"BackupDumperTestP2Summary1",
|
|
$this->textId2_1,
|
|
23,
|
|
"jprywrymfhysqllua29tj3sc7z39dl2"
|
|
);
|
|
$asserter->assertRevision(
|
|
$this->revId2_2,
|
|
"BackupDumperTestP2Summary2",
|
|
null, // deleted!
|
|
false, // deleted!
|
|
null, // deleted!
|
|
false, // deleted!
|
|
$this->revId2_1
|
|
);
|
|
$asserter->assertRevision(
|
|
$this->revId2_3,
|
|
"BackupDumperTestP2Summary3",
|
|
$this->textId2_3,
|
|
23,
|
|
"jfunqmh1ssfb8rs43r19w98k28gg56r",
|
|
false,
|
|
$this->revId2_2
|
|
);
|
|
$asserter->assertRevision(
|
|
$this->revId2_4,
|
|
"BackupDumperTestP2Summary4 extra",
|
|
$this->textId2_4,
|
|
44,
|
|
"6o1ciaxa6pybnqprmungwofc4lv00wv",
|
|
false,
|
|
$this->revId2_3
|
|
);
|
|
$asserter->assertPageEnd();
|
|
|
|
// Page 3
|
|
// -> Page is marked deleted. Hence not visible
|
|
|
|
// Page 4
|
|
$asserter->assertPageStart(
|
|
$this->pageId4,
|
|
$this->talk_namespace,
|
|
$this->pageTitle4->getPrefixedText( $schemaVersion )
|
|
);
|
|
$asserter->assertRevision(
|
|
$this->revId4_1,
|
|
"Talk BackupDumperTestP1 Summary1",
|
|
$this->textId4_1,
|
|
35,
|
|
"nktofwzd0tl192k3zfepmlzxoax1lpe"
|
|
);
|
|
$asserter->assertPageEnd();
|
|
|
|
$asserter->assertDumpEnd();
|
|
|
|
// Checking meta-current -------------------------------------------------
|
|
|
|
$this->gunzip( $fnameMetaCurrent );
|
|
$this->assertDumpSchema( $fnameMetaCurrent, $this->getXmlSchemaPath( $schemaVersion ) );
|
|
|
|
$asserter = $this->getDumpAsserter( $schemaVersion );
|
|
$asserter->assertDumpStart( $fnameMetaCurrent );
|
|
|
|
// Page 1
|
|
$asserter->assertPageStart(
|
|
$this->pageId1,
|
|
$this->namespace,
|
|
$this->pageTitle1->getPrefixedText()
|
|
);
|
|
$asserter->assertRevision(
|
|
$this->revId1_1,
|
|
"BackupDumperTestP1Summary1",
|
|
$this->textId1_1,
|
|
23,
|
|
"0bolhl6ol7i6x0e7yq91gxgaan39j87"
|
|
);
|
|
$asserter->assertPageEnd();
|
|
|
|
// Page 2
|
|
$asserter->assertPageStart(
|
|
$this->pageId2,
|
|
$this->namespace,
|
|
$this->pageTitle2->getPrefixedText()
|
|
);
|
|
$asserter->assertRevision(
|
|
$this->revId2_4,
|
|
"BackupDumperTestP2Summary4 extra",
|
|
$this->textId2_4,
|
|
44,
|
|
"6o1ciaxa6pybnqprmungwofc4lv00wv",
|
|
false,
|
|
$this->revId2_3
|
|
);
|
|
$asserter->assertPageEnd();
|
|
|
|
// Page 3
|
|
// -> Page is marked deleted. Hence not visible
|
|
|
|
// Page 4
|
|
$asserter->assertPageStart(
|
|
$this->pageId4,
|
|
$this->talk_namespace,
|
|
$this->pageTitle4->getPrefixedText()
|
|
);
|
|
$asserter->assertRevision(
|
|
$this->revId4_1,
|
|
"Talk BackupDumperTestP1 Summary1",
|
|
$this->textId4_1,
|
|
35,
|
|
"nktofwzd0tl192k3zfepmlzxoax1lpe"
|
|
);
|
|
$asserter->assertPageEnd();
|
|
|
|
$asserter->assertDumpEnd();
|
|
|
|
// Checking articles -------------------------------------------------
|
|
|
|
$this->gunzip( $fnameArticles );
|
|
$this->assertDumpSchema( $fnameArticles, $this->getXmlSchemaPath( $schemaVersion ) );
|
|
|
|
$asserter = $this->getDumpAsserter( $schemaVersion );
|
|
$asserter->assertDumpStart( $fnameArticles );
|
|
|
|
// Page 1
|
|
$asserter->assertPageStart(
|
|
$this->pageId1,
|
|
$this->namespace,
|
|
$this->pageTitle1->getPrefixedText()
|
|
);
|
|
$asserter->assertRevision(
|
|
$this->revId1_1,
|
|
"BackupDumperTestP1Summary1",
|
|
$this->textId1_1,
|
|
23,
|
|
"0bolhl6ol7i6x0e7yq91gxgaan39j87"
|
|
);
|
|
$asserter->assertPageEnd();
|
|
|
|
// Page 2
|
|
$asserter->assertPageStart(
|
|
$this->pageId2,
|
|
$this->namespace,
|
|
$this->pageTitle2->getPrefixedText()
|
|
);
|
|
$asserter->assertRevision(
|
|
$this->revId2_4,
|
|
"BackupDumperTestP2Summary4 extra",
|
|
$this->textId2_4,
|
|
44,
|
|
"6o1ciaxa6pybnqprmungwofc4lv00wv",
|
|
false,
|
|
$this->revId2_3
|
|
);
|
|
$asserter->assertPageEnd();
|
|
|
|
// Page 3
|
|
// -> Page is marked deleted. Hence not visible
|
|
|
|
// Page 4
|
|
// -> Page is not in $this->namespace. Hence not visible
|
|
|
|
$asserter->assertDumpEnd();
|
|
|
|
$this->expectETAOutput();
|
|
}
|
|
}
|