aboutsummaryrefslogtreecommitdiffstats
path: root/tests/phpunit/includes/objectcache/ObjectCacheFactoryIntegrationTest.php
diff options
context:
space:
mode:
Diffstat (limited to 'tests/phpunit/includes/objectcache/ObjectCacheFactoryIntegrationTest.php')
-rw-r--r--tests/phpunit/includes/objectcache/ObjectCacheFactoryIntegrationTest.php164
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 ) );
+ }
+}