public static function resetNonServiceCaches() {
global $wgRequest, $wgJobClasses;
+ User::resetGetDefaultOptionsForTestsOnly();
foreach ( $wgJobClasses as $type => $class ) {
JobQueueGroup::singleton()->get( $type )->delete();
}
self::$useTemporaryTables = !$this->getCliArg( 'use-normal-tables' );
self::$reuseDB = $this->getCliArg( 'reuse-db' );
- $this->db = wfGetDB( DB_MASTER );
+ $lb = MediaWikiServices::getInstance()->getDBLoadBalancer();
+ $this->db = $lb->getConnection( DB_MASTER );
$this->checkDbIsSupported();
$this->tmpFiles = array_merge( $this->tmpFiles, (array)$files );
}
+ // @todo Make const when we no longer support HHVM (T192166)
+ private static $namespaceAffectingSettings = [
+ 'wgAllowImageMoving',
+ 'wgCanonicalNamespaceNames',
+ 'wgCapitalLinkOverrides',
+ 'wgCapitalLinks',
+ 'wgContentNamespaces',
+ 'wgExtensionMessagesFiles',
+ 'wgExtensionNamespaces',
+ 'wgExtraNamespaces',
+ 'wgExtraSignatureNamespaces',
+ 'wgNamespaceContentModels',
+ 'wgNamespaceProtection',
+ 'wgNamespacesWithSubpages',
+ 'wgNonincludableNamespaces',
+ 'wgRestrictionLevels',
+ ];
+
protected function tearDown() {
global $wgRequest, $wgSQLMode;
ini_set( $name, $value );
}
if (
- array_key_exists( 'wgExtraNamespaces', $this->mwGlobals ) ||
- in_array( 'wgExtraNamespaces', $this->mwGlobalsToUnset )
+ array_intersect( self::$namespaceAffectingSettings, array_keys( $this->mwGlobals ) ) ||
+ array_intersect( self::$namespaceAffectingSettings, $this->mwGlobalsToUnset )
) {
$this->resetNamespaces();
}
$GLOBALS[$key] = $value;
}
- if ( array_key_exists( 'wgExtraNamespaces', $pairs ) ) {
+ if ( array_intersect( self::$namespaceAffectingSettings, array_keys( $pairs ) ) ) {
$this->resetNamespaces();
}
}
. 'instance has been replaced by test code.' );
}
- MWNamespace::clearCaches();
Language::clearCaches();
-
- // We can't have the TitleFormatter holding on to an old Language object either
- // @todo We shouldn't need to reset all the aliases here.
- $this->localServices->resetServiceForTesting( 'TitleFormatter' );
- $this->localServices->resetServiceForTesting( 'TitleParser' );
- $this->localServices->resetServiceForTesting( '_MediaWikiTitleCodec' );
}
/**
JobQueueGroup::singleton()->get( $type )->delete();
}
+ // T219673: close any connections from code that failed to call reuseConnection()
+ // or is still holding onto a DBConnRef instance (e.g. in a singleton).
+ MediaWikiServices::getInstance()->getDBLoadBalancerFactory()->closeAll();
CloneDatabase::changePrefix( self::$oldTablePrefix );
self::$oldTablePrefix = false;
* @note this method only works when first called. Subsequent calls have no effect,
* even if using different parameters.
*
- * @param Database $db The database connection
+ * @param IMaintainableDatabase $db The database connection
* @param string $prefix The prefix to use for the new table set (aka schema).
*
* @throws MWException If the database table prefix is already $prefix
*/
- public static function setupTestDB( Database $db, $prefix ) {
+ public static function setupTestDB( IMaintainableDatabase $db, $prefix ) {
if ( self::$dbSetup ) {
return;
}
$this->ensureMockDatabaseConnection( $db );
$oldOverrides = $oldOverrides + self::$schemaOverrideDefaults;
- $originalTables = $this->listOriginalTables( $db, 'unprefixed' );
+ $originalTables = $this->listOriginalTables( $db );
// Drop tables that need to be restored or removed.
$tablesToDrop = array_merge( $oldOverrides['create'], $oldOverrides['alter'] );
if ( $tablesToRestore ) {
$this->recloneMockTables( $db, $tablesToRestore );
+
+ // Reset the restored tables, mainly for the side effect of
+ // re-calling $this->addCoreDBData() if necessary.
+ $this->resetDB( $db, $tablesToRestore );
}
}
if ( $oldOverrides['alter'] || $oldOverrides['create'] || $oldOverrides['drop'] ) {
$this->undoSchemaOverrides( $db, $oldOverrides );
+ unset( $db->_schemaOverrides );
}
// Determine new overrides.
$this->ensureMockDatabaseConnection( $db );
// Drop the tables that will be created by the schema scripts.
- $originalTables = $this->listOriginalTables( $db, 'unprefixed' );
+ $originalTables = $this->listOriginalTables( $db );
$tablesToDrop = array_intersect( $originalTables, $overrides['create'] );
if ( $tablesToDrop ) {
}
/**
- * Lists all tables in the live database schema.
+ * Lists all tables in the live database schema, without a prefix.
*
* @param IMaintainableDatabase $db
- * @param string $prefix Either 'prefixed' or 'unprefixed'
* @return array
*/
- private function listOriginalTables( IMaintainableDatabase $db, $prefix = 'prefixed' ) {
+ private function listOriginalTables( IMaintainableDatabase $db ) {
if ( !isset( $db->_originalTablePrefix ) ) {
throw new LogicException( 'No original table prefix know, cannot list tables!' );
}
$originalTables = $db->listTables( $db->_originalTablePrefix, __METHOD__ );
- if ( $prefix === 'unprefixed' ) {
- $originalPrefixRegex = '/^' . preg_quote( $db->_originalTablePrefix, '/' ) . '/';
- $originalTables = array_map(
- function ( $pt ) use ( $originalPrefixRegex ) {
- return preg_replace( $originalPrefixRegex, '', $pt );
- },
- $originalTables
- );
- }
- return $originalTables;
+ $unittestPrefixRegex = '/^' . preg_quote( $this->dbPrefix(), '/' ) . '/';
+ $originalPrefixRegex = '/^' . preg_quote( $db->_originalTablePrefix, '/' ) . '/';
+
+ $originalTables = array_filter(
+ $originalTables,
+ function ( $pt ) use ( $unittestPrefixRegex ) {
+ return !preg_match( $unittestPrefixRegex, $pt );
+ }
+ );
+
+ $originalTables = array_map(
+ function ( $pt ) use ( $originalPrefixRegex ) {
+ return preg_replace( $originalPrefixRegex, '', $pt );
+ },
+ $originalTables
+ );
+
+ return array_unique( $originalTables );
}
/**
throw new LogicException( 'No original table prefix know, cannot restore tables!' );
}
- $originalTables = $this->listOriginalTables( $db, 'unprefixed' );
+ $originalTables = $this->listOriginalTables( $db );
$tables = array_intersect( $tables, $originalTables );
$dbClone = new CloneDatabase( $db, $tables, $db->tablePrefix(), $db->_originalTablePrefix );
if ( array_intersect( $tablesUsed, $userTables ) ) {
$tablesUsed = array_unique( array_merge( $tablesUsed, $userTables ) );
TestUserRegistry::clear();
+
+ // Reset $wgUser, which is probably 127.0.0.1, as its loaded data is probably not valid
+ // @todo Should we start setting $wgUser to something nondeterministic
+ // to encourage tests to be updated to not depend on it?
+ global $wgUser;
+ $wgUser->clearInstanceCache( $wgUser->mFrom );
}
if ( array_intersect( $tablesUsed, $pageTables ) ) {
$tablesUsed = array_unique( array_merge( $tablesUsed, $pageTables ) );
* @param IDatabase $target
*/
public function copyTestData( IDatabase $source, IDatabase $target ) {
- $tables = self::listOriginalTables( $source, 'unprefixed' );
+ if ( $this->db->getType() === 'sqlite' ) {
+ // SQLite uses a non-temporary copy of the searchindex table for testing,
+ // which gets deleted and re-created when setting up the secondary connection,
+ // causing "Error 17" when trying to copy the data. See T191863#4130112.
+ throw new RuntimeException(
+ 'Setting up a secondary database connection with test data is currently not'
+ . 'with SQLite. You may want to use markTestSkippedIfDbType() to bypass this issue.'
+ );
+ }
+
+ $tables = self::listOriginalTables( $source );
foreach ( $tables as $table ) {
$res = $source->select( $table, '*', [], __METHOD__ );