Daniel Kinzler has uploaded a new change for review. https://gerrit.wikimedia.org/r/275596
Change subject: Avoid rebuilding database fixtures for every test run. ...................................................................... Avoid rebuilding database fixtures for every test run. This reduces the runtime of database-bound tests by about 40% (on my system, from 4:55 to 2:47). Change-Id: Iec4ed4c8419fb4ad87e6710de808863ede9998b7 --- A conf/plain/LocalSettings.mysql.php A conf/plain/LocalSettings.php M tests/phpunit/MediaWikiTestCase.php M tests/phpunit/includes/BlockTest.php M tests/phpunit/includes/db/DatabaseSqliteTest.php M tests/phpunit/includes/deferred/LinksUpdateTest.php M tests/phpunit/includes/parser/NewParserTest.php M tests/phpunit/includes/user/BotPasswordTest.php M tests/phpunit/includes/user/LocalIdLookupTest.php M tests/phpunit/maintenance/backupTextPassTest.php M tests/phpunit/maintenance/backup_LogTest.php M tests/phpunit/maintenance/backup_PageTest.php M tests/phpunit/maintenance/fetchTextTest.php 13 files changed, 165 insertions(+), 55 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/core refs/changes/96/275596/1 diff --git a/conf/plain/LocalSettings.mysql.php b/conf/plain/LocalSettings.mysql.php new file mode 100644 index 0000000..6a619b4 --- /dev/null +++ b/conf/plain/LocalSettings.mysql.php @@ -0,0 +1,32 @@ +<?php +# This file was automatically generated by the MediaWiki 1.19alpha +# installer. If you make manual changes, please keep track in case you +# need to recreate them later. +# +# See includes/DefaultSettings.php for all configurable settings +# and their default values, but don't forget to make changes in _this_ +# file, not there. +# +# Further documentation for configuration settings may be found at: +# http://www.mediawiki.org/wiki/Manual:Configuration_settings + +# Protect against web entry +if ( !defined( 'MEDIAWIKI' ) ) { + exit; +} + +## Database settings +$wgDBtype = "mysql"; +$wgDBserver = "localhost"; +$wgDBname = "wikidata_client"; +$wgDBuser = "wikidata"; +$wgDBpassword = "wikidata"; + +# MySQL specific settings +$wgDBprefix = ""; + +# MySQL table options to use during installation or update +$wgDBTableOptions = "ENGINE=MyISAM, DEFAULT CHARSET=utf8"; + +# Experimental charset support for MySQL 5.0. +$wgDBmysql5 = false; diff --git a/conf/plain/LocalSettings.php b/conf/plain/LocalSettings.php new file mode 100644 index 0000000..5d943e2 --- /dev/null +++ b/conf/plain/LocalSettings.php @@ -0,0 +1,34 @@ +<?php +# This file was automatically generated by the MediaWiki 1.20alpha +# installer. If you make manual changes, please keep track in case you +# need to recreate them later. +# +# See includes/DefaultSettings.php for all configurable settings +# and their default values, but don't forget to make changes in _this_ +# file, not there. +# +# Further documentation for configuration settings may be found at: +# http://www.mediawiki.org/wiki/Manual:Configuration_settings + +# Protect against web entry +if ( !defined( 'MEDIAWIKI' ) ) { + exit; +} + +$wgSitename = "MyWiki"; + +## The URL base path to the directory containing the wiki; +## defaults for all runtime URL paths are based off of this. +## For more information on customizing the URLs +## (like /w/index.php/Page_title to /wiki/Page_title) please see: +## http://www.mediawiki.org/wiki/Manual:Short_URL +$wgScriptPath = "/daniel/wikidata-plain"; + +$wgSecretKey = "7b5cc4c61049ee79459d392744c560e3f103f56f1850621ef8223971d6c7e213"; + +$wgLanguageCode = "de"; + +$wgSitesCacheFile = "$IP/serialized/Sites.json"; + +$wgRestrictDisplayTitle = false; + diff --git a/tests/phpunit/MediaWikiTestCase.php b/tests/phpunit/MediaWikiTestCase.php index d5192ac..b5591a5 100644 --- a/tests/phpunit/MediaWikiTestCase.php +++ b/tests/phpunit/MediaWikiTestCase.php @@ -134,13 +134,18 @@ if ( !self::$dbSetup ) { // switch to a temporary clone of the database self::setupTestDB( $this->db, $this->dbPrefix() ); + $this->addCoreDBData(); if ( ( $this->db->getType() == 'oracle' || !self::$useTemporaryTables ) && self::$reuseDB ) { $this->resetDB(); } } - $this->addCoreDBData(); - $this->addDBData(); + + if ( $this->oncePerClass() ) { + $this->addDBData(); + } + + $this->prepareDB(); $needsResetDB = true; } @@ -149,6 +154,22 @@ if ( $needsResetDB ) { $this->resetDB(); } + } + + /** + * @return boolean + */ + private function oncePerClass() { + // Remember current test class in the database connection, + //so we know when we need to run addData. + + $class = get_class( $this ); + + $first = !isset( $this->db->_hasDataForTestClass ) + || $this->db->_hasDataForTestClass !== $class; + + $this->db->_hasDataForTestClass = $class; + return $first; } /** @@ -527,10 +548,18 @@ } /** - * Stub. If a test needs to add additional data to the database, it should - * implement this method and do so + * Stub. If a test suite needs to add additional data to the database, it should + * implement this method and do so. This method is called once per test suite. * - * @since 1.18 + * Note data added by this method may be removed by resetDB() depending on + * the contents of $tablesUsed. + * + * To control the database reset between tests, override prepareDB() or resetDB(). + * + * @see prepareDB() + * @see resetDB() + * + * @since 1.27 (invocation contract changed) */ public function addDBData() { } @@ -671,27 +700,39 @@ } /** - * Empty all tables so they can be repopulated for tests + * Stub. Subclasses may override this to prepare the database. + * Called before every test run (test function or data set). + * + * @see addDBData() + * @see resetDB() + * + * @since 1.27 */ - private function resetDB() { + protected function prepareDB() { + } + + /** + * Empty all tables so they can be repopulated for tests. + * Subclasses may override this to perform additional cleanup. + * Called after every test run (test function or data set). + * + * @see addDBData() + * @see prepareDB() + * + * @since 1.27 (became available as protected method) + */ + protected function resetDB() { if ( $this->db ) { - if ( $this->db->getType() == 'oracle' ) { - if ( self::$useTemporaryTables ) { - wfGetLB()->closeAll(); - $this->db = wfGetDB( DB_MASTER ); - } else { - foreach ( $this->tablesUsed as $tbl ) { - if ( $tbl == 'interwiki' ) { - continue; - } - $this->db->query( 'TRUNCATE TABLE ' . $this->db->tableName( $tbl ), __METHOD__ ); - } + $truncate = in_array( $this->db->getType(), [ 'oracle', 'mysql' ] ); + foreach ( $this->tablesUsed as $tbl ) { + // TODO: reset interwiki and user tables to their original content. + if ( $tbl == 'interwiki' || $tbl == 'user' ) { + continue; } - } else { - foreach ( $this->tablesUsed as $tbl ) { - if ( $tbl == 'interwiki' || $tbl == 'user' ) { - continue; - } + + if ( $truncate ) { + $this->db->query( 'TRUNCATE TABLE ' . $this->db->tableName( $tbl ), __METHOD__ ); + } else { $this->db->delete( $tbl, '*', __METHOD__ ); } } @@ -1283,4 +1324,5 @@ public static function wfResetOutputBuffersBarrier( $buffer ) { return $buffer; } + } diff --git a/tests/phpunit/includes/BlockTest.php b/tests/phpunit/includes/BlockTest.php index 28192e9..25c59a8 100644 --- a/tests/phpunit/includes/BlockTest.php +++ b/tests/phpunit/includes/BlockTest.php @@ -21,8 +21,7 @@ ] ); } - function addDBData() { - + function prepareDB() { $user = User::newFromName( 'UTBlockee' ); if ( $user->getID() == 0 ) { $user->addToDatabase(); diff --git a/tests/phpunit/includes/db/DatabaseSqliteTest.php b/tests/phpunit/includes/db/DatabaseSqliteTest.php index 18de9be..80fb826 100644 --- a/tests/phpunit/includes/db/DatabaseSqliteTest.php +++ b/tests/phpunit/includes/db/DatabaseSqliteTest.php @@ -330,7 +330,7 @@ foreach ( $versions as $version ) { $versions = "upgrading from $version to $wgVersion"; - $db = $this->prepareDB( $version ); + $db = $this->prepareTestDB( $version ); $tables = $this->getTables( $db ); $this->assertEquals( $currentTables, $tables, "Different tables $versions" ); foreach ( $tables as $table ) { @@ -389,7 +389,7 @@ $this->assertTrue( $db->close(), "closing database" ); } - private function prepareDB( $version ) { + private function prepareTestDB( $version ) { static $maint = null; if ( $maint === null ) { $maint = new FakeMaintenance(); diff --git a/tests/phpunit/includes/deferred/LinksUpdateTest.php b/tests/phpunit/includes/deferred/LinksUpdateTest.php index 75af87e..cfa3e67 100644 --- a/tests/phpunit/includes/deferred/LinksUpdateTest.php +++ b/tests/phpunit/includes/deferred/LinksUpdateTest.php @@ -6,7 +6,7 @@ * ^--- make sure temporary tables are used. */ class LinksUpdateTest extends MediaWikiLangTestCase { - protected $testingPageId; + protected static $testingPageId; function __construct( $name = null, array $data = [], $dataName = '' ) { parent::__construct( $name, $data, $dataName ); @@ -47,7 +47,7 @@ public function addDBData() { $res = $this->insertPage( 'Testing' ); - $this->testingPageId = $res['id']; + self::$testingPageId = $res['id']; $this->insertPage( 'Some_other_page' ); $this->insertPage( 'Template:TestingTemplate' ); } @@ -68,7 +68,7 @@ public function testUpdate_pagelinks() { /** @var Title $t */ /** @var ParserOutput $po */ - list( $t, $po ) = $this->makeTitleAndParserOutput( "Testing", $this->testingPageId ); + list( $t, $po ) = $this->makeTitleAndParserOutput( "Testing", self::$testingPageId ); $po->addLink( Title::newFromText( "Foo" ) ); $po->addLink( Title::newFromText( "Special:Foo" ) ); // special namespace should be ignored @@ -81,7 +81,7 @@ 'pagelinks', 'pl_namespace, pl_title', - 'pl_from = ' . $this->testingPageId, + 'pl_from = ' . self::$testingPageId, [ [ NS_MAIN, 'Foo' ] ] ); $this->assertArrayEquals( [ @@ -100,7 +100,7 @@ 'pagelinks', 'pl_namespace, pl_title', - 'pl_from = ' . $this->testingPageId, + 'pl_from = ' . self::$testingPageId, [ [ NS_MAIN, 'Bar' ], [ NS_TALK, 'Bar' ], @@ -120,7 +120,7 @@ */ public function testUpdate_externallinks() { /** @var ParserOutput $po */ - list( $t, $po ) = $this->makeTitleAndParserOutput( "Testing", $this->testingPageId ); + list( $t, $po ) = $this->makeTitleAndParserOutput( "Testing", self::$testingPageId ); $po->addExternalLink( "http://testing.com/wiki/Foo" ); @@ -129,7 +129,7 @@ $po, 'externallinks', 'el_to, el_index', - 'el_from = ' . $this->testingPageId, + 'el_from = ' . self::$testingPageId, [ [ 'http://testing.com/wiki/Foo', 'http://com.testing./wiki/Foo' ], ] @@ -143,7 +143,7 @@ /** @var ParserOutput $po */ $this->setMwGlobals( 'wgCategoryCollation', 'uppercase' ); - list( $t, $po ) = $this->makeTitleAndParserOutput( "Testing", $this->testingPageId ); + list( $t, $po ) = $this->makeTitleAndParserOutput( "Testing", self::$testingPageId ); $po->addCategory( "Foo", "FOO" ); @@ -152,7 +152,7 @@ $po, 'categorylinks', 'cl_to, cl_sortkey', - 'cl_from = ' . $this->testingPageId, + 'cl_from = ' . self::$testingPageId, [ [ 'Foo', "FOO\nTESTING" ] ] ); } @@ -232,7 +232,7 @@ */ public function testUpdate_iwlinks() { /** @var ParserOutput $po */ - list( $t, $po ) = $this->makeTitleAndParserOutput( "Testing", $this->testingPageId ); + list( $t, $po ) = $this->makeTitleAndParserOutput( "Testing", self::$testingPageId ); $target = Title::makeTitleSafe( NS_MAIN, "Foo", '', 'linksupdatetest' ); $po->addInterwikiLink( $target ); @@ -242,7 +242,7 @@ $po, 'iwlinks', 'iwl_prefix, iwl_title', - 'iwl_from = ' . $this->testingPageId, + 'iwl_from = ' . self::$testingPageId, [ [ 'linksupdatetest', 'Foo' ] ] ); } @@ -252,7 +252,7 @@ */ public function testUpdate_templatelinks() { /** @var ParserOutput $po */ - list( $t, $po ) = $this->makeTitleAndParserOutput( "Testing", $this->testingPageId ); + list( $t, $po ) = $this->makeTitleAndParserOutput( "Testing", self::$testingPageId ); $po->addTemplate( Title::newFromText( "Template:Foo" ), 23, 42 ); @@ -262,7 +262,7 @@ 'templatelinks', 'tl_namespace, tl_title', - 'tl_from = ' . $this->testingPageId, + 'tl_from = ' . self::$testingPageId, [ [ NS_TEMPLATE, 'Foo' ] ] ); } @@ -272,7 +272,7 @@ */ public function testUpdate_imagelinks() { /** @var ParserOutput $po */ - list( $t, $po ) = $this->makeTitleAndParserOutput( "Testing", $this->testingPageId ); + list( $t, $po ) = $this->makeTitleAndParserOutput( "Testing", self::$testingPageId ); $po->addImage( "Foo.png" ); @@ -281,7 +281,7 @@ $po, 'imagelinks', 'il_to', - 'il_from = ' . $this->testingPageId, + 'il_from = ' . self::$testingPageId, [ [ 'Foo.png' ] ] ); } @@ -295,7 +295,7 @@ ] ); /** @var ParserOutput $po */ - list( $t, $po ) = $this->makeTitleAndParserOutput( "Testing", $this->testingPageId ); + list( $t, $po ) = $this->makeTitleAndParserOutput( "Testing", self::$testingPageId ); $po->addLanguageLink( Title::newFromText( "en:Foo" )->getFullText() ); @@ -304,7 +304,7 @@ $po, 'langlinks', 'll_lang, ll_title', - 'll_from = ' . $this->testingPageId, + 'll_from = ' . self::$testingPageId, [ [ 'En', 'Foo' ] ] ); } @@ -316,7 +316,7 @@ global $wgPagePropsHaveSortkey; /** @var ParserOutput $po */ - list( $t, $po ) = $this->makeTitleAndParserOutput( "Testing", $this->testingPageId ); + list( $t, $po ) = $this->makeTitleAndParserOutput( "Testing", self::$testingPageId ); $fields = [ 'pp_propname', 'pp_value' ]; $expected = []; @@ -349,7 +349,7 @@ } $this->assertLinksUpdate( - $t, $po, 'page_props', $fields, 'pp_page = ' . $this->testingPageId, $expected ); + $t, $po, 'page_props', $fields, 'pp_page = ' . self::$testingPageId, $expected ); } public function testUpdate_page_props_without_sortkey() { diff --git a/tests/phpunit/includes/parser/NewParserTest.php b/tests/phpunit/includes/parser/NewParserTest.php index 04d6067..31ba588 100644 --- a/tests/phpunit/includes/parser/NewParserTest.php +++ b/tests/phpunit/includes/parser/NewParserTest.php @@ -211,19 +211,22 @@ parent::tearDownAfterClass(); } + function prepareDB() { + LinkCache::singleton()->clear(); # Avoids the odd failure at creating the nullRevision + } + function addDBData() { - $this->tablesUsed[] = 'site_stats'; # disabled for performance # $this->tablesUsed[] = 'image'; # Update certain things in site_stats $this->db->insert( 'site_stats', [ 'ss_row_id' => 1, 'ss_images' => 2, 'ss_good_articles' => 1 ], - __METHOD__ + __METHOD__, + [ 'IGNORE' ] ); $user = User::newFromId( 0 ); - LinkCache::singleton()->clear(); # Avoids the odd failure at creating the nullRevision # Upload DB table entries for files. # We will upload the actual files later. Note that if anything causes LocalFile::load() diff --git a/tests/phpunit/includes/user/BotPasswordTest.php b/tests/phpunit/includes/user/BotPasswordTest.php index d3a5791..a7ae29f 100644 --- a/tests/phpunit/includes/user/BotPasswordTest.php +++ b/tests/phpunit/includes/user/BotPasswordTest.php @@ -46,7 +46,7 @@ CentralIdLookup::resetCache(); } - public function addDBData() { + public function prepareDB() { $passwordFactory = new \PasswordFactory(); $passwordFactory->init( \RequestContext::getMain()->getConfig() ); // A is unsalted MD5 (thus fast) ... we don't care about security here, this is test only diff --git a/tests/phpunit/includes/user/LocalIdLookupTest.php b/tests/phpunit/includes/user/LocalIdLookupTest.php index e2b138b..3fe2040 100644 --- a/tests/phpunit/includes/user/LocalIdLookupTest.php +++ b/tests/phpunit/includes/user/LocalIdLookupTest.php @@ -16,7 +16,7 @@ $wgGroupPermissions['local-id-lookup-test']['hideuser'] = true; } - public function addDBData() { + public function prepareDB() { for ( $i = 1; $i <= 4; $i++ ) { $user = User::newFromName( "UTLocalIdLookup$i" ); if ( $user->getId() == 0 ) { diff --git a/tests/phpunit/maintenance/backupTextPassTest.php b/tests/phpunit/maintenance/backupTextPassTest.php index e015216..472b8a5 100644 --- a/tests/phpunit/maintenance/backupTextPassTest.php +++ b/tests/phpunit/maintenance/backupTextPassTest.php @@ -27,7 +27,7 @@ private $revId4_1, $textId4_1; private static $numOfRevs = 8; - function addDBData() { + function prepareDB() { $this->tablesUsed[] = 'page'; $this->tablesUsed[] = 'revision'; $this->tablesUsed[] = 'text'; diff --git a/tests/phpunit/maintenance/backup_LogTest.php b/tests/phpunit/maintenance/backup_LogTest.php index 0b2f7fb..652600a 100644 --- a/tests/phpunit/maintenance/backup_LogTest.php +++ b/tests/phpunit/maintenance/backup_LogTest.php @@ -47,7 +47,7 @@ return $logEntry->insert(); } - function addDBData() { + function prepareDB() { $this->tablesUsed[] = 'logging'; $this->tablesUsed[] = 'user'; diff --git a/tests/phpunit/maintenance/backup_PageTest.php b/tests/phpunit/maintenance/backup_PageTest.php index 5cd8336..7902659 100644 --- a/tests/phpunit/maintenance/backup_PageTest.php +++ b/tests/phpunit/maintenance/backup_PageTest.php @@ -20,7 +20,7 @@ private $revId4_1, $textId4_1; private $namespace, $talk_namespace; - function addDBData() { + function prepareDB() { // be sure, titles created here using english namespace names $this->setMwGlobals( [ 'wgLanguageCode' => 'en', diff --git a/tests/phpunit/maintenance/fetchTextTest.php b/tests/phpunit/maintenance/fetchTextTest.php index 2e35eca..ec77a4e 100644 --- a/tests/phpunit/maintenance/fetchTextTest.php +++ b/tests/phpunit/maintenance/fetchTextTest.php @@ -123,7 +123,7 @@ throw new MWException( "Could not determine text id" ); } - function addDBData() { + function prepareDB() { $this->tablesUsed[] = 'page'; $this->tablesUsed[] = 'revision'; $this->tablesUsed[] = 'text'; -- To view, visit https://gerrit.wikimedia.org/r/275596 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Iec4ed4c8419fb4ad87e6710de808863ede9998b7 Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/core Gerrit-Branch: master Gerrit-Owner: Daniel Kinzler <[email protected]> _______________________________________________ MediaWiki-commits mailing list [email protected] https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
