Page MenuHomePhabricator

MediaWikiTestCase::setService() interferes with the database?
Closed, ResolvedPublic

Description

In https://gerrit.wikimedia.org/r/#/c/286797/, I had:

		// Since we reset the $wgContLang global, reset the TitleParser service
		$services = MediaWikiServices::getInstance();
		if ( is_callable( [ $services, 'getTitleParser' ] ) ) {
			$this->setService(
				'TitleParser',
				new MediaWikiTitleCodec(
					$langObj,
					new GenderCache(),
					$services->getMainConfig()->get( 'LocalInterwikis' )
				)
			);
		}

This caused errors like

16:50:24 1) EchoDiscussionParserTest::testGenerateEventsForRevision with data set #0 (637638133, 637637213, 'Cwobeel', 'en', array('[[User:{{{1}}}|{{<includeonly...clude>'), 'UTPage', array(array('mention', 'Cwobeel')))
16:50:24 DBQueryError: A database error has occurred. Did you forget to run maintenance/update.php after upgrading?  See: https://www.mediawiki.org/wiki/Manual:Upgrading#Run_the_update_script
16:50:24 Query: SELECT  page_id,page_namespace,page_title,page_restrictions,page_is_redirect,page_is_new,page_random,page_touched,page_links_updated,page_latest,page_len,page_content_model  FROM `unittest_page`   WHERE page_namespace = '10' AND page_title = 'U'  LIMIT 1  
16:50:24 Function: WikiPage::pageData
16:50:24 Error: 1146 Table 'jenkins_u0_mw.unittest_page' doesn't exist (127.0.0.1:3306)
16:50:24 
16:50:24 
16:50:24 /mnt/jenkins-workspace/workspace/mediawiki-extensions-hhvm/src/includes/db/Database.php:934
16:50:24 /mnt/jenkins-workspace/workspace/mediawiki-extensions-hhvm/src/includes/db/Database.php:901
16:50:24 /mnt/jenkins-workspace/workspace/mediawiki-extensions-hhvm/src/includes/db/Database.php:1234
16:50:24 /mnt/jenkins-workspace/workspace/mediawiki-extensions-hhvm/src/includes/db/Database.php:1293
16:50:24 /mnt/jenkins-workspace/workspace/mediawiki-extensions-hhvm/src/includes/page/WikiPage.php:306
16:50:24 /mnt/jenkins-workspace/workspace/mediawiki-extensions-hhvm/src/includes/page/WikiPage.php:325
16:50:24 /mnt/jenkins-workspace/workspace/mediawiki-extensions-hhvm/src/includes/page/WikiPage.php:361
16:50:24 /mnt/jenkins-workspace/workspace/mediawiki-extensions-hhvm/src/includes/page/WikiPage.php:1606
16:50:24 /mnt/jenkins-workspace/workspace/mediawiki-extensions-hhvm/src/extensions/Echo/tests/phpunit/DiscussionParserTest.php:341
16:50:24 /mnt/jenkins-workspace/workspace/mediawiki-extensions-hhvm/src/tests/phpunit/MediaWikiTestCase.php:351

(more in https://integration.wikimedia.org/ci/job/mediawiki-extensions-hhvm/61857/consoleFull)

Using:

		// Since we reset the $wgContLang global, reset the TitleParser service
		$services = MediaWikiServices::getInstance();
		if ( is_callable( [ $services, 'getTitleParser' ] ) ) {
			// TODO: All of this should use $this->setService()
			$services->resetServiceForTesting( 'TitleParser' );
			$services->redefineService( 'TitleParser', function () use ( $langObj ) {
				global $wgLocalInterwikis;
				return new MediaWikiTitleCodec(
					$langObj,
					new GenderCache(),
					$wgLocalInterwikis
				);
			} );
			// Cleanup
			$lock = new ScopedCallback( function() use ( $services ) {
				$services->resetServiceForTesting( 'TitleParser' );
			} );
		}

worked around this for now.

Probably MediaWikiTestCase::overrideMwServices() is causing issues here?

Event Timeline

@Legoktm Is this still an issue? It seems the linked patch (https://gerrit.wikimedia.org/r/286797) was merged without the described workaround. Does that mean the problem was solved? If not, which code should we change to see if the problem still exists?

Krinkle triaged this task as Medium priority.Jan 31 2018, 3:04 AM

Looking at the patch this was resolved by using the setService method in MediaWikiTestCase.

However it looks like this is still a bit hackey, after calling setglobals all that should be needed is a call to overrideServices in order to pick up the new config.

This is documented in the docs for setMwGlobals

	 * @note To allow changes to global variables to take effect on global service instances,
	 *       call overrideMwServices().

Change 407453 had a related patch set uploaded (by Addshore; owner: Addshore):
[mediawiki/extensions/Echo@master] Use overrideMwServices in DiscussionParserTest

https://gerrit.wikimedia.org/r/407453

Change 407453 merged by jenkins-bot:
[mediawiki/extensions/Echo@master] Use overrideMwServices in DiscussionParserTest

https://gerrit.wikimedia.org/r/407453

Addshore closed this task as Resolved.EditedFeb 8 2018, 11:13 PM
Addshore claimed this task.

I'm going to mark this as resolved.

For anyone that is searching for solutions and finds this ticket, after changing a global / changing globals in test cases, for example using setMwGlobals you must then call overrideServices to get a new Instance of MediaWikiServices so that any services can be constructed with your altered globals.

function testFeatureX() {
    $this->setMwGlobals ( 'globalOne', true );
    $this->overrideMwServices();
}

In a dreamy and not to distant land some sort of test template would ask you for the globals you want to set and the services you want to override and make sure that everything happens in the correct order...

function testFeatureX() {
    $this->setupTestEnvironment( [ 'globalOne' => 'foo', 'globalTwo' => true ], [ 'TitleParser' => [ $this, 'getTitleParser' ] ] );
    // Do the test
    $this->assertTrue( true );
}