diff options
Diffstat (limited to 'tests/phpunit/includes/objectcache/ObjectCacheFactoryIntegrationTest.php')
-rw-r--r-- | tests/phpunit/includes/objectcache/ObjectCacheFactoryIntegrationTest.php | 164 |
1 files changed, 164 insertions, 0 deletions
diff --git a/tests/phpunit/includes/objectcache/ObjectCacheFactoryIntegrationTest.php b/tests/phpunit/includes/objectcache/ObjectCacheFactoryIntegrationTest.php new file mode 100644 index 000000000000..4819e2617c20 --- /dev/null +++ b/tests/phpunit/includes/objectcache/ObjectCacheFactoryIntegrationTest.php @@ -0,0 +1,164 @@ +<?php + +use MediaWiki\MainConfigNames; +use Wikimedia\ObjectCache\EmptyBagOStuff; +use Wikimedia\ObjectCache\HashBagOStuff; +use Wikimedia\Rdbms\DatabaseDomain; +use Wikimedia\TestingAccessWrapper; + +/** + * @covers \ObjectCacheFactory + * @group BagOStuff + * @group Database + */ +class ObjectCacheFactoryIntegrationTest extends MediaWikiIntegrationTestCase { + + protected function setUp(): void { + $this->setCacheConfig(); + $this->setMainCache( CACHE_NONE ); + $this->overrideConfigValues( [ + MainConfigNames::MessageCacheType => CACHE_NONE, + MainConfigNames::ParserCacheType => CACHE_NONE, + ] ); + } + + protected function tearDown(): void { + ObjectCacheFactory::$localServerCacheClass = null; + } + + private function setCacheConfig( $arr = [] ) { + $defaults = [ + CACHE_NONE => [ 'class' => EmptyBagOStuff::class ], + CACHE_DB => [ 'class' => SqlBagOStuff::class ], + 'hash' => [ 'class' => HashBagOStuff::class ], + CACHE_ANYTHING => [ 'class' => HashBagOStuff::class ], + ]; + $this->overrideConfigValue( MainConfigNames::ObjectCaches, $arr + $defaults ); + // Mock ACCEL with 'hash' as being installed. + // This makes tests deterministic regardless of APC. + ObjectCacheFactory::$localServerCacheClass = 'HashBagOStuff'; + } + + public function testNewAnythingNothing() { + $ocf = $this->getServiceContainer()->getObjectCacheFactory(); + $this->assertInstanceOf( + SqlBagOStuff::class, + $ocf->getInstance( $ocf->getAnythingId() ), + 'No available types. Fallback to DB' + ); + } + + public function testNewAnythingHash() { + $this->setMainCache( CACHE_HASH ); + + $ocf = $this->getServiceContainer()->getObjectCacheFactory(); + $this->assertInstanceOf( + HashBagOStuff::class, + $ocf->getInstance( $ocf->getAnythingId() ), + 'Use an available type (hash)' + ); + } + + public function testNewAnythingAccel() { + $this->setMainCache( CACHE_ACCEL ); + + $ocf = $this->getServiceContainer()->getObjectCacheFactory(); + $this->assertInstanceOf( + HashBagOStuff::class, + $ocf->getInstance( $ocf->getAnythingId() ), + 'Use an available type (CACHE_ACCEL)' + ); + } + + public function testNewAnythingNoAccel() { + // Mock APC not being installed (T160519, T147161) + ObjectCacheFactory::$localServerCacheClass = EmptyBagOStuff::class; + $this->setMainCache( CACHE_ACCEL ); + + $ocf = $this->getServiceContainer()->getObjectCacheFactory(); + $this->assertInstanceOf( + SqlBagOStuff::class, + $ocf->getInstance( $ocf->getAnythingId() ), + 'Fallback to DB if available types fall back to Empty' + ); + } + + public function testNewAnythingNoAccelNoDb() { + $this->setCacheConfig( [ + // Mock APC not being installed (T160519, T147161) + CACHE_ACCEL => [ 'class' => EmptyBagOStuff::class ] + ] ); + $this->setMainCache( CACHE_ACCEL ); + + $this->getServiceContainer()->disableStorage(); + + $ocf = $this->getServiceContainer()->getObjectCacheFactory(); + $this->assertInstanceOf( + EmptyBagOStuff::class, + $ocf->getInstance( $ocf->getAnythingId() ), + 'Fallback to none if available types and DB are unavailable' + ); + } + + public function testNewAnythingNothingNoDb() { + $this->getServiceContainer()->disableStorage(); + + $ocf = $this->getServiceContainer()->getObjectCacheFactory(); + $this->assertInstanceOf( + EmptyBagOStuff::class, + $ocf->getInstance( $ocf->getAnythingId() ), + 'No available types or DB. Fallback to none.' + ); + } + + public function provideLocalServerKeyspace() { + $dbDomain = static function ( $dbName, $dbPrefix ) { + global $wgDBmwschema; + return ( new DatabaseDomain( $dbName, $wgDBmwschema, $dbPrefix ) )->getId(); + }; + return [ + 'default' => [ false, 'my_wiki', '', $dbDomain( 'my_wiki', '' ) ], + 'custom' => [ 'custom', 'my_wiki', '', 'custom' ], + 'prefix' => [ false, 'my_wiki', 'nl_', $dbDomain( 'my_wiki', 'nl_' ) ], + 'empty string' => [ '', 'my_wiki', 'nl_', $dbDomain( 'my_wiki', 'nl_' ) ], + ]; + } + + /** + * @dataProvider provideLocalServerKeyspace + */ + public function testLocalServerKeyspace( $cachePrefix, $dbName, $dbPrefix, $expect ) { + $this->overrideConfigValues( [ + MainConfigNames::CachePrefix => $cachePrefix, + MainConfigNames::DBname => $dbName, + MainConfigNames::DBprefix => $dbPrefix, + ] ); + // Regression against T247562 (2020), T361177 (2024). + $cache = $this->getServiceContainer()->getObjectCacheFactory()->getInstance( CACHE_ACCEL ); + $cache = TestingAccessWrapper::newFromObject( $cache ); + $this->assertSame( $expect, $cache->keyspace ); + } + + public static function provideIsDatabaseId() { + return [ + [ CACHE_DB, CACHE_NONE, true ], + [ CACHE_ANYTHING, CACHE_DB, true ], + [ CACHE_ANYTHING, 'hash', false ], + [ CACHE_ANYTHING, CACHE_ANYTHING, true ] + ]; + } + + /** + * @dataProvider provideIsDatabaseId + * @param string|int $id + * @param string|int $mainCacheType + * @param bool $expected + */ + public function testIsDatabaseId( $id, $mainCacheType, $expected ) { + $this->overrideConfigValues( [ + MainConfigNames::MainCacheType => $mainCacheType + ] ); + $ocf = $this->getServiceContainer()->getObjectCacheFactory(); + $this->assertSame( $expected, $ocf->isDatabaseId( $id ) ); + } +} |