use MediaWiki\Logger\LegacySpi;
use MediaWiki\Logger\LoggerFactory;
use MediaWiki\Logger\MonologSpi;
+use MediaWiki\Logger\LogCapturingSpi;
use MediaWiki\MediaWikiServices;
use Psr\Log\LoggerInterface;
use Wikimedia\Rdbms\IDatabase;
*/
private $mwGlobalsToUnset = [];
+ /**
+ * Holds original values of ini settings to be restored
+ * in tearDown().
+ * @see setIniSettings()
+ * @var array
+ */
+ private $iniSettings = [];
+
/**
* Holds original loggers which have been replaced by setLogger()
* @var LoggerInterface[]
foreach ( $this->mwGlobalsToUnset as $value ) {
unset( $GLOBALS[$value] );
}
+ foreach ( $this->iniSettings as $name => $value ) {
+ ini_set( $name, $value );
+ }
if (
array_key_exists( 'wgExtraNamespaces', $this->mwGlobals ) ||
in_array( 'wgExtraNamespaces', $this->mwGlobalsToUnset )
}
}
+ /**
+ * Set an ini setting for the duration of the test
+ * @param string $name Name of the setting
+ * @param string $value Value to set
+ * @since 1.32
+ */
+ protected function setIniSetting( $name, $value ) {
+ $original = ini_get( $name );
+ $this->iniSettings[$name] = $original;
+ ini_set( $name, $value );
+ }
+
/**
* Must be called whenever namespaces are changed, e.g., $wgExtraNamespaces is altered.
* Otherwise old namespace data will lurk and cause bugs.
$this->loggers[$channel] = $singletons['loggers'][$channel] ?? null;
}
$singletons['loggers'][$channel] = $logger;
- } elseif ( $provider instanceof LegacySpi ) {
+ } elseif ( $provider instanceof LegacySpi || $provider instanceof LogCapturingSpi ) {
if ( !isset( $this->loggers[$channel] ) ) {
$this->loggers[$channel] = $singletons[$channel] ?? null;
}
} else {
$singletons['loggers'][$channel] = $logger;
}
- } elseif ( $provider instanceof LegacySpi ) {
+ } elseif ( $provider instanceof LegacySpi || $provider instanceof LogCapturingSpi ) {
if ( $logger === null ) {
unset( $singletons[$channel] );
} else {
$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'] );
$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 );
* @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__ );