Aaron Schulz has uploaded a new change for review.

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

Change subject: Set the DatabaseDomain for sanity in some test classes
......................................................................

Set the DatabaseDomain for sanity in some test classes

Change-Id: I6531dc6cf89fbe7e5656354bcd4a27369f573752
---
M includes/MediaWikiServices.php
M includes/ServiceWiring.php
M includes/libs/rdbms/lbfactory/LBFactorySimple.php
M includes/libs/rdbms/loadbalancer/LoadBalancer.php
M includes/objectcache/ObjectCache.php
M tests/phpunit/MediaWikiTestCase.php
M tests/phpunit/includes/MediaWikiServicesTest.php
M tests/phpunit/includes/auth/AuthManagerTest.php
M tests/phpunit/includes/db/DatabaseMysqlBaseTest.php
M tests/phpunit/includes/db/DatabaseTestHelper.php
M tests/phpunit/includes/db/LBFactoryTest.php
M tests/phpunit/includes/installer/DatabaseUpdaterTest.php
12 files changed, 187 insertions(+), 43 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/core 
refs/changes/48/311948/1

diff --git a/includes/MediaWikiServices.php b/includes/MediaWikiServices.php
index f621867..1ec3435 100644
--- a/includes/MediaWikiServices.php
+++ b/includes/MediaWikiServices.php
@@ -582,6 +582,38 @@
 
        /**
         * @since 1.28
+        * @return \BagOStuff
+        */
+       public function getMainObjectStash() {
+               return $this->getService( 'MainObjectStash' );
+       }
+
+       /**
+        * @since 1.28
+        * @return \WANObjectCache
+        */
+       public function getMainWANObjectCache() {
+               return $this->getService( 'MainWANObjectCache' );
+       }
+
+       /**
+        * @since 1.28
+        * @return \BagOStuff
+        */
+       public function getLocalClusterObjectCache() {
+               return $this->getService( 'LocalClusterObjectCache' );
+       }
+
+       /**
+        * @since 1.28
+        * @return \BagOStuff
+        */
+       public function getLocalServerObjectCache() {
+               return $this->getService( 'LocalServerObjectCache' );
+       }
+
+       /**
+        * @since 1.28
         * @return VirtualRESTServiceClient
         */
        public function getVirtualRESTServiceClient() {
diff --git a/includes/ServiceWiring.php b/includes/ServiceWiring.php
index 8c7d802..e445974 100644
--- a/includes/ServiceWiring.php
+++ b/includes/ServiceWiring.php
@@ -210,6 +210,71 @@
                return $services->getService( '_MediaWikiTitleCodec' );
        },
 
+       'MainObjectStash' => function( MediaWikiServices $services ) {
+               $mainConfig = $services->getMainConfig();
+
+               $id = $mainConfig->get( 'MainStash' );
+               if ( !isset( $mainConfig->get( 'ObjectCaches' )[$id] ) ) {
+                       throw new UnexpectedValueException(
+                               "Cache type \"$id\" is not present in 
\$wgObjectCaches." );
+               }
+
+               return \ObjectCache::newFromParams( $mainConfig->get( 
'ObjectCaches' )[$id] );
+       },
+
+       'MainWANObjectCache' => function( MediaWikiServices $services ) {
+               $mainConfig = $services->getMainConfig();
+
+               $id = $mainConfig->get( 'MainWANCache' );
+               if ( !isset( $mainConfig->get( 'WANObjectCaches' )[$id] ) ) {
+                       throw new UnexpectedValueException(
+                               "WAN cache type \"$id\" is not present in 
\$wgWANObjectCaches." );
+               }
+
+               $params = $mainConfig->get( 'WANObjectCaches' )[$id];
+               $objectCacheId = $params['cacheId'];
+               if ( !isset( $mainConfig->get( 'ObjectCaches' )[$objectCacheId] 
) ) {
+                       throw new UnexpectedValueException(
+                               "Cache type \"$objectCacheId\" is not present 
in \$wgObjectCaches." );
+               }
+               $params['store'] = $mainConfig->get( 'ObjectCaches' 
)[$objectCacheId];
+
+               return \ObjectCache::newWANCacheFromParams( $params );
+       },
+
+       'LocalClusterObjectCache' => function( MediaWikiServices $services ) {
+               $mainConfig = $services->getMainConfig();
+
+               $id = $mainConfig->get( 'MainCacheType' );
+               if ( !isset( $mainConfig->get( 'ObjectCaches' )[$id] ) ) {
+                       throw new UnexpectedValueException(
+                               "Cache type \"$id\" is not present in 
\$wgObjectCaches." );
+               }
+
+               return \ObjectCache::newFromParams( $mainConfig->get( 
'ObjectCaches' )[$id] );
+       },
+
+       'LocalServerObjectCache' => function( MediaWikiServices $services ) {
+               $mainConfig = $services->getMainConfig();
+
+               if ( function_exists( 'apc_fetch' ) ) {
+                       $id = 'apc';
+               } elseif ( function_exists( 'xcache_get' ) && wfIniGetBool( 
'xcache.var_size' ) ) {
+                       $id = 'xcache';
+               } elseif ( function_exists( 'wincache_ucache_get' ) ) {
+                       $id = 'wincache';
+               } else {
+                       $id = CACHE_NONE;
+               }
+
+               if ( !isset( $mainConfig->get( 'ObjectCaches' )[$id] ) ) {
+                       throw new UnexpectedValueException(
+                               "Cache type \"$id\" is not present in 
\$wgObjectCaches." );
+               }
+
+               return \ObjectCache::newFromParams( $mainConfig->get( 
'ObjectCaches' )[$id] );
+       },
+
        'VirtualRESTServiceClient' => function( MediaWikiServices $services ) {
                $config = $services->getMainConfig()->get( 'VirtualRestConfig' 
);
 
diff --git a/includes/libs/rdbms/lbfactory/LBFactorySimple.php 
b/includes/libs/rdbms/lbfactory/LBFactorySimple.php
index 4ed4347..b90afe6 100644
--- a/includes/libs/rdbms/lbfactory/LBFactorySimple.php
+++ b/includes/libs/rdbms/lbfactory/LBFactorySimple.php
@@ -108,7 +108,7 @@
        /**
         * @param string $cluster
         * @param bool|string $domain
-        * @return LoadBalancer
+        * @return array
         */
        public function getExternalLB( $cluster, $domain = false ) {
                if ( !isset( $this->extLBs[$cluster] ) ) {
diff --git a/includes/libs/rdbms/loadbalancer/LoadBalancer.php 
b/includes/libs/rdbms/loadbalancer/LoadBalancer.php
index 9c07043..c030cb2 100644
--- a/includes/libs/rdbms/loadbalancer/LoadBalancer.php
+++ b/includes/libs/rdbms/loadbalancer/LoadBalancer.php
@@ -136,9 +136,10 @@
 
                $this->mReadIndex = -1;
                $this->mConns = [
-                       'local' => [],
+                       'local'       => [],
                        'foreignUsed' => [],
-                       'foreignFree' => [] ];
+                       'foreignFree' => []
+               ];
                $this->mLoads = [];
                $this->mWaitForPos = false;
                $this->mErrorConnection = false;
@@ -598,21 +599,18 @@
                        return;
                }
 
-               $dbName = $conn->getDBname();
-               $prefix = $conn->tablePrefix();
-               if ( strval( $prefix ) !== '' ) {
-                       $domain = "$dbName-$prefix";
-               } else {
-                       $domain = $dbName;
-               }
+               $domain = $conn->getDomainID();
                if ( $this->mConns['foreignUsed'][$serverIndex][$domain] !== 
$conn ) {
-                       throw new InvalidArgumentException( __METHOD__ . ": 
connection not found, has " .
-                               "the connection been freed already?" );
+                       throw new InvalidArgumentException( __METHOD__ .
+                               ": connection not found, has the connection 
been freed already?" );
                }
                $conn->setLBInfo( 'foreignPoolRefCount', --$refCount );
                if ( $refCount <= 0 ) {
                        $this->mConns['foreignFree'][$serverIndex][$domain] = 
$conn;
                        unset( 
$this->mConns['foreignUsed'][$serverIndex][$domain] );
+                       if ( !$this->mConns['foreignUsed'][$serverIndex] ) {
+                               unset( $this->mConns[ 'foreignUsed' 
][$serverIndex] ); // clean up
+                       }
                        $this->connLogger->debug( __METHOD__ . ": freed 
connection $serverIndex/$domain" );
                } else {
                        $this->connLogger->debug( __METHOD__ .
@@ -707,11 +705,10 @@
                        // Reuse a connection from another domain
                        $conn = reset( $this->mConns['foreignFree'][$i] );
                        $oldDomain = key( $this->mConns['foreignFree'][$i] );
-
                        // The empty string as a DB name means "don't care".
                        // DatabaseMysqlBase::open() already handle this on 
connection.
-                       if ( $dbName !== '' && !$conn->selectDB( $dbName ) ) {
-                               $this->mLastError = "Error selecting database 
$dbName on server " .
+                       if ( strlen( $dbName ) && !$conn->selectDB( $dbName ) ) 
{
+                               $this->mLastError = "Error selecting database 
'$dbName' on server " .
                                        $conn->getServer() . " from client host 
{$this->host}";
                                $this->mErrorConnection = $conn;
                                $conn = false;
@@ -770,7 +767,7 @@
         * @access private
         *
         * @param array $server
-        * @param bool $dbNameOverride
+        * @param string|bool $dbNameOverride Use "" to not select any database
         * @return IDatabase
         * @throws DBAccessError
         * @throws InvalidArgumentException
@@ -1473,6 +1470,17 @@
        }
 
        public function setDomainPrefix( $prefix ) {
+               if ( $this->mConns['foreignUsed'] ) {
+                       // Do not switch connections to explicit foreign 
domains unless marked as free
+                       $domains = [];
+                       foreach ( $this->mConns['foreignUsed'] as $i => 
$connsByDomain ) {
+                               $domains = array_merge( $domains, array_keys( 
$connsByDomain ) );
+                       }
+                       $domains = implode( ', ', $domains );
+                       throw new DBUnexpectedError( null,
+                               "Foreign domain connections are still in use 
($domains)." );
+               }
+
                $this->localDomain = new DatabaseDomain(
                        $this->localDomain->getDatabase(),
                        null,
diff --git a/includes/objectcache/ObjectCache.php 
b/includes/objectcache/ObjectCache.php
index ea237aa..36db15a 100644
--- a/includes/objectcache/ObjectCache.php
+++ b/includes/objectcache/ObjectCache.php
@@ -23,7 +23,6 @@
 
 use MediaWiki\Logger\LoggerFactory;
 use MediaWiki\MediaWikiServices;
-use MediaWiki\Services\ServiceDisabledException;
 
 /**
  * Functions to get cache objects
@@ -118,13 +117,20 @@
         *
         * @param string $id A key in $wgObjectCaches.
         * @return BagOStuff
-        * @throws MWException
+        * @throws UnexpectedValueException
         */
        public static function newFromId( $id ) {
                global $wgObjectCaches;
 
                if ( !isset( $wgObjectCaches[$id] ) ) {
-                       throw new MWException( "Invalid object cache type 
\"$id\" requested. " .
+                       // Always recognize these ones
+                       if ( $id === CACHE_NONE ) {
+                               return new EmptyBagOStuff();
+                       } elseif ( $id === 'hash' ) {
+                               return new HashBagOStuff();
+                       }
+
+                       throw new UnexpectedValueException( "Invalid object 
cache type \"$id\" requested. " .
                                "It is not present in \$wgObjectCaches." );
                }
 
@@ -160,7 +166,7 @@
         *  - loggroup: Alias to set 'logger' key with LoggerFactory group.
         *  - .. Other parameters passed to factory or class.
         * @return BagOStuff
-        * @throws MWException
+        * @throws UnexpectedValueException
         */
        public static function newFromParams( $params ) {
                if ( isset( $params['loggroup'] ) ) {
@@ -217,7 +223,7 @@
                        }
                        return new $class( $params );
                } else {
-                       throw new MWException( "The definition of cache type \""
+                       throw new UnexpectedValueException( "The definition of 
cache type \""
                                . print_r( $params, true ) . "\" lacks both "
                                . "factory and class parameters." );
                }
@@ -270,8 +276,9 @@
         *
         * @param int|string|array $fallback Fallback cache or parameter map 
with 'fallback'
         * @return BagOStuff
-        * @throws MWException
+        * @throws UnexpectedValueException
         * @since 1.27
+        * @deprecated Since 1.28; use 
MediaWikiServices::getLocalServerObjectCache
         */
        public static function getLocalServerInstance( $fallback = CACHE_NONE ) 
{
                if ( function_exists( 'apc_fetch' ) ) {
@@ -315,23 +322,41 @@
         * @since 1.26
         * @param string $id A key in $wgWANObjectCaches.
         * @return WANObjectCache
-        * @throws MWException
+        * @throws UnexpectedValueException
         */
        public static function newWANCacheFromId( $id ) {
-               global $wgWANObjectCaches;
+               global $wgWANObjectCaches, $wgObjectCaches;
 
                if ( !isset( $wgWANObjectCaches[$id] ) ) {
-                       throw new MWException( "Invalid object cache type 
\"$id\" requested. " .
-                               "It is not present in \$wgWANObjectCaches." );
+                       throw new UnexpectedValueException(
+                               "Cache type \"$id\" requested is not present in 
\$wgWANObjectCaches." );
                }
 
                $params = $wgWANObjectCaches[$id];
+               if ( !isset( $wgObjectCaches[$params['cacheId']] ) ) {
+                       throw new UnexpectedValueException(
+                               "Cache type \"{$params['cacheId']}\" is not 
present in \$wgObjectCaches." );
+               }
+               $params['store'] = $wgObjectCaches[$params['cacheId']];
+
+               return self::newWANCacheFromParams( $params );
+       }
+
+       /**
+        * Create a new cache object of the specified type.
+        *
+        * @since 1.28
+        * @param array $params
+        * @return WANObjectCache
+        * @throws UnexpectedValueException
+        */
+       public static function newWANCacheFromParams( array $params ) {
                foreach ( $params['channels'] as $action => $channel ) {
                        $params['relayers'][$action] = 
MediaWikiServices::getInstance()->getEventRelayerGroup()
                                ->getRelayer( $channel );
                        $params['channels'][$action] = $channel;
                }
-               $params['cache'] = self::newFromId( $params['cacheId'] );
+               $params['cache'] = self::newFromParams( $params['store'] );
                if ( isset( $params['loggroup'] ) ) {
                        $params['logger'] = LoggerFactory::getInstance( 
$params['loggroup'] );
                } else {
@@ -347,11 +372,10 @@
         *
         * @since 1.27
         * @return BagOStuff
+        * @deprecated Since 1.28 Use MediaWikiServices::getLocalClusterCache
         */
        public static function getLocalClusterInstance() {
-               global $wgMainCacheType;
-
-               return self::getInstance( $wgMainCacheType );
+               return 
MediaWikiServices::getInstance()->getLocalClusterObjectCache();
        }
 
        /**
@@ -359,11 +383,10 @@
         *
         * @since 1.26
         * @return WANObjectCache
+        * @deprecated Since 1.28 Use MediaWikiServices::getMainWANCache()
         */
        public static function getMainWANInstance() {
-               global $wgMainWANCache;
-
-               return self::getWANInstance( $wgMainWANCache );
+               return 
MediaWikiServices::getInstance()->getMainWANObjectCache();
        }
 
        /**
@@ -383,11 +406,10 @@
         *
         * @return BagOStuff
         * @since 1.26
+        * @deprecated Since 1.28 Use MediaWikiServices::getMainObjectStash
         */
        public static function getMainStashInstance() {
-               global $wgMainStash;
-
-               return self::getInstance( $wgMainStash );
+               return MediaWikiServices::getInstance()->getMainObjectStash();
        }
 
        /**
diff --git a/tests/phpunit/MediaWikiTestCase.php 
b/tests/phpunit/MediaWikiTestCase.php
index cfeb44f..446b002 100644
--- a/tests/phpunit/MediaWikiTestCase.php
+++ b/tests/phpunit/MediaWikiTestCase.php
@@ -336,6 +336,10 @@
 
                JobQueueGroup::destroySingletons();
                ObjectCache::clear();
+               $this->setService( 'MainObjectStash', new HashBagOStuff() );
+               $this->setService( 'MainWANObjectCache', new EmptyBagOStuff() 
); // sanity
+               $this->setService( 'MainWANObjectCache', 
WANObjectCache::newEmpty() );
+               $this->setService( 'LocalServerObjectCache', new 
HashBagOStuff() );
                FileBackendGroup::destroySingleton();
 
                // TODO: move global state into MediaWikiServices
@@ -483,12 +487,11 @@
                }
 
                DeferredUpdates::clearPendingUpdates();
-               ObjectCache::getMainWANInstance()->clearProcessCache();
-
+               $services = MediaWikiServices::getInstance();
+               $services->getMainWANObjectCache()->clearProcessCache();
                // XXX: reset maintenance triggers
                // Hook into period lag checks which often happen in 
long-running scripts
-               $lbFactory = 
MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
-               Maintenance::setLBFactoryTriggers( $lbFactory );
+               Maintenance::setLBFactoryTriggers( 
$services->getDBLoadBalancerFactory() );
 
                ob_start( 'MediaWikiTestCase::wfResetOutputBuffersBarrier' );
        }
@@ -535,7 +538,12 @@
                $this->restoreLoggers();
 
                if ( self::$serviceLocator && MediaWikiServices::getInstance() 
!== self::$serviceLocator ) {
+                       $lbf = 
MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
                        MediaWikiServices::forceGlobalInstance( 
self::$serviceLocator );
+                       // Carry over the LBFactory/LoadBalancer to avoid 
exhausting the max connection
+                       // limit and wasting time connecting and reconning 
again and again
+                       $this->setService( 'DBLoadBalancerFactory', $lbf );
+                       $this->setService( 'DBLoadBalancer', $lbf->getMainLB() 
);
                }
 
                // TODO: move global state into MediaWikiServices
@@ -1244,7 +1252,8 @@
                                }
 
                                if ( $truncate ) {
-                                       $db->query( 'TRUNCATE TABLE ' . 
$db->tableName( $tbl ), __METHOD__ );
+                                       $ignore = true; // ignore "table does 
not exist"
+                                       $db->query( 'TRUNCATE TABLE ' . 
$db->tableName( $tbl ), __METHOD__, $ignore );
                                } else {
                                        $db->delete( $tbl, '*', __METHOD__ );
                                }
diff --git a/tests/phpunit/includes/MediaWikiServicesTest.php 
b/tests/phpunit/includes/MediaWikiServicesTest.php
index 41f516a..66b5ac6 100644
--- a/tests/phpunit/includes/MediaWikiServicesTest.php
+++ b/tests/phpunit/includes/MediaWikiServicesTest.php
@@ -320,6 +320,10 @@
                        '_MediaWikiTitleCodec' => [ '_MediaWikiTitleCodec', 
MediaWikiTitleCodec::class ],
                        'TitleFormatter' => [ 'TitleFormatter', 
TitleFormatter::class ],
                        'TitleParser' => [ 'TitleParser', TitleParser::class ],
+                       'MainObjectStash' => [ 'MainObjectStash', 
BagOStuff::class ],
+                       'MainWANObjectCache' => [ 'MainWANObjectCache', 
WANObjectCache::class ],
+                       'LocalClusterObjectCache' => [ 
'LocalClusterObjectCache', BagOStuff::class ],
+                       'LocalServerObjectCache' => [ 'LocalServerObjectCache', 
BagOStuff::class ],
                        'VirtualRESTServiceClient' => [ 
'VirtualRESTServiceClient', VirtualRESTServiceClient::class ]
                ];
        }
diff --git a/tests/phpunit/includes/auth/AuthManagerTest.php 
b/tests/phpunit/includes/auth/AuthManagerTest.php
index f679f63..02ee226 100644
--- a/tests/phpunit/includes/auth/AuthManagerTest.php
+++ b/tests/phpunit/includes/auth/AuthManagerTest.php
@@ -2352,8 +2352,7 @@
                $wgGroupPermissions['*']['createaccount'] = true;
                $wgGroupPermissions['*']['autocreateaccount'] = false;
 
-               \ObjectCache::$instances[__METHOD__] = new \HashBagOStuff();
-               $this->setMwGlobals( [ 'wgMainCacheType' => __METHOD__ ] );
+               $this->setService( 'LocalClusterObjectCache', new 
\HashBagOStuff() );
 
                // Set up lots of mocks...
                $mocks = [];
diff --git a/tests/phpunit/includes/db/DatabaseMysqlBaseTest.php 
b/tests/phpunit/includes/db/DatabaseMysqlBaseTest.php
index f13ead4..b2cdc86 100644
--- a/tests/phpunit/includes/db/DatabaseMysqlBaseTest.php
+++ b/tests/phpunit/includes/db/DatabaseMysqlBaseTest.php
@@ -33,6 +33,7 @@
        function __construct() {
                $this->profiler = new ProfilerStub( [] );
                $this->trxProfiler = new TransactionProfiler();
+               $this->currentDomain = DatabaseDomain::newUnspecified();
        }
 
        protected function closeConnection() {
diff --git a/tests/phpunit/includes/db/DatabaseTestHelper.php 
b/tests/phpunit/includes/db/DatabaseTestHelper.php
index caa29bd..29b2bed 100644
--- a/tests/phpunit/includes/db/DatabaseTestHelper.php
+++ b/tests/phpunit/includes/db/DatabaseTestHelper.php
@@ -36,6 +36,7 @@
                $this->cliMode = isset( $opts['cliMode'] ) ? $opts['cliMode'] : 
true;
                $this->connLogger = new \Psr\Log\NullLogger();
                $this->queryLogger = new \Psr\Log\NullLogger();
+               $this->currentDomain = DatabaseDomain::newUnspecified();
        }
 
        /**
diff --git a/tests/phpunit/includes/db/LBFactoryTest.php 
b/tests/phpunit/includes/db/LBFactoryTest.php
index adf8a40..d72768d 100644
--- a/tests/phpunit/includes/db/LBFactoryTest.php
+++ b/tests/phpunit/includes/db/LBFactoryTest.php
@@ -272,6 +272,7 @@
 
                /** @var DatabaseBase $db */
                $db = $lb->getConnection( DB_MASTER, [], '' );
+               $lb->reuseConnection( $db ); // don't care
 
                $this->assertEquals(
                        '',
@@ -323,6 +324,7 @@
                $lb = $factory->getMainLB();
                /** @var DatabaseBase $db */
                $db = $lb->getConnection( DB_MASTER, [], '' );
+               $lb->reuseConnection( $db ); // don't care
 
                $this->assertEquals(
                        '',
diff --git a/tests/phpunit/includes/installer/DatabaseUpdaterTest.php 
b/tests/phpunit/includes/installer/DatabaseUpdaterTest.php
index 81c9fafa..4634239 100644
--- a/tests/phpunit/includes/installer/DatabaseUpdaterTest.php
+++ b/tests/phpunit/includes/installer/DatabaseUpdaterTest.php
@@ -21,6 +21,7 @@
        public $lastInsertData;
 
        function __construct() {
+               $this->currentDomain = DatabaseDomain::newUnspecified();
        }
 
        function clearFlag( $arg, $remember = self::REMEMBER_NOTHING ) {

-- 
To view, visit https://gerrit.wikimedia.org/r/311948
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I6531dc6cf89fbe7e5656354bcd4a27369f573752
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/core
Gerrit-Branch: master
Gerrit-Owner: Aaron Schulz <asch...@wikimedia.org>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to