PHPUnit: introduce setMainCache
The main object cache is disabled during testing. Some integration tests need it though. This provides a clean way to enable it, to replace the hacks that were used so far. Note that we may want to enable the main cache during testing soon. When that happens, this method is still useful to disable the cache in certain tests, and to set a specific cache instance. Change-Id: I04ae1bf1b6b2c8f6310acd2edf89459d01a9c870
This commit is contained in:
parent
c3d4646763
commit
bf092744c9
12 changed files with 91 additions and 30 deletions
|
|
@ -87,6 +87,7 @@ define( 'CACHE_NONE', 0 ); // Do not cache
|
|||
define( 'CACHE_DB', 1 ); // Store cache objects in the DB
|
||||
define( 'CACHE_MEMCACHED', 'memcached-php' ); // Backwards-compatability alias for Memcached
|
||||
define( 'CACHE_ACCEL', 3 ); // APC or WinCache
|
||||
define( 'CACHE_HASH', 'hash' ); // A HashBagOStuff, mostly useful for testing. Not configurable
|
||||
/** @} */
|
||||
|
||||
/** @{
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ class ObjectCache {
|
|||
// Always recognize these ones
|
||||
if ( $id === CACHE_NONE ) {
|
||||
return new EmptyBagOStuff();
|
||||
} elseif ( $id === 'hash' ) {
|
||||
} elseif ( $id === CACHE_HASH ) {
|
||||
return new HashBagOStuff();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -344,6 +344,7 @@ abstract class MediaWikiIntegrationTestCase extends PHPUnit\Framework\TestCase {
|
|||
'apc' => $hashCache,
|
||||
'apcu' => $hashCache,
|
||||
'wincache' => $hashCache,
|
||||
'UTCache' => $hashCache,
|
||||
] + $baseConfig->get( MainConfigNames::ObjectCaches );
|
||||
|
||||
// Use hash based caches
|
||||
|
|
@ -837,6 +838,45 @@ abstract class MediaWikiIntegrationTestCase extends PHPUnit\Framework\TestCase {
|
|||
$this->setMwGlobals( "wg$key", $value );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the main object cache that will be returned by ObjectCache::getLocalClusterInstance().
|
||||
*
|
||||
* Per default, the main object cache is disabled during testing (that is, the cache is an
|
||||
* EmptyBagOStuff).
|
||||
*
|
||||
* The $cache parameter support the following kinds of values:
|
||||
* - a string: refers to an entry in the ObjectCaches array, see MainConfigSchema::ObjectCaches.
|
||||
* MainCacheType will be set to this value. Use CACHE_HASH to use a HashBagOStuff.
|
||||
* - an int: refers to an entry in the ObjectCaches array, see MainConfigSchema::ObjectCaches.
|
||||
* MainCacheType will be set to this value. Use CACHE_NONE to disable caching.
|
||||
* - a BagOStuff: the object will be injected into the ObjectCache class under the name
|
||||
* 'UTCache', and MainCacheType will be set to 'UTCache'.
|
||||
*
|
||||
* @note Most entries in the ObjectCaches config setting are overwritten during testing.
|
||||
* To set the cache to anything other than CACHE_HASH, you will have to override
|
||||
* the ObjectCaches setting first.
|
||||
*
|
||||
* @note This will cause any existing service instances to be reset.
|
||||
*
|
||||
* @param string|BagOStuff $cache
|
||||
*
|
||||
* @return string|int The new value of the MainCacheType setting.
|
||||
*/
|
||||
protected function setMainCache( $cache ) {
|
||||
if ( $cache instanceof BagOStuff ) {
|
||||
// ObjectCache::$instances is reset after each test by resetNonGlobalServices().
|
||||
ObjectCache::$instances[ 'UTCache' ] = $cache;
|
||||
$cache = 'UTCache';
|
||||
}
|
||||
|
||||
if ( !is_string( $cache ) && !is_int( $cache ) ) {
|
||||
throw new InvalidArgumentException( 'Bad type of $cache parameter: ' . get_debug_type( $cache ) );
|
||||
}
|
||||
|
||||
$this->overrideConfigValue( MainConfigNames::MainCacheType, $cache );
|
||||
return $cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides a set of config settings for the duration of the current test case.
|
||||
* The original values of the config settings will be restored after the test case finishes.
|
||||
|
|
|
|||
|
|
@ -333,8 +333,8 @@ class ApiLoginTest extends ApiTestCase {
|
|||
];
|
||||
|
||||
$this->setGroupPermissions( 'sysop', 'noratelimit', false );
|
||||
$this->setMwGlobals( 'wgMainCacheType', 'hash' );
|
||||
$this->setMwGlobals( 'wgPasswordAttemptThrottle', $throttle );
|
||||
$this->setMainCache( CACHE_HASH );
|
||||
$this->overrideConfigValue( 'PasswordAttemptThrottle', $throttle );
|
||||
|
||||
list( $name, $password ) = $this->setUpForBotPassword();
|
||||
|
||||
|
|
|
|||
|
|
@ -247,9 +247,9 @@ class ApiMoveTest extends ApiTestCase {
|
|||
|
||||
$name = ucfirst( __FUNCTION__ );
|
||||
|
||||
$this->setMwGlobals( 'wgMainCacheType', 'hash' );
|
||||
$this->setMainCache( CACHE_HASH );
|
||||
|
||||
$this->mergeMwGlobalArrayValue( 'wgRateLimits',
|
||||
$this->overrideConfigValue( 'RateLimits',
|
||||
[ 'move' => [ '&can-bypass' => false, 'user' => [ 1, 60 ] ] ] );
|
||||
|
||||
$id = $this->createPage( $name );
|
||||
|
|
|
|||
|
|
@ -32,8 +32,9 @@ class ApiStashEditTest extends ApiTestCase {
|
|||
$this->getServiceContainer()->getHookContainer(),
|
||||
PageEditStash::INITIATOR_USER
|
||||
) );
|
||||
// Clear rate-limiting cache between tests
|
||||
$this->setMwGlobals( 'wgMainCacheType', 'hash' );
|
||||
|
||||
// Enable the main cache, so we have a place to store rate limit counters.
|
||||
$this->setMainCache( CACHE_HASH );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -2580,9 +2580,7 @@ class AuthManagerTest extends \MediaWikiIntegrationTestCase {
|
|||
$this->setGroupPermissions( '*', 'autocreateaccount', false );
|
||||
$this->initializeManager( true );
|
||||
|
||||
$this->mergeMwGlobalArrayValue( 'wgObjectCaches',
|
||||
[ __METHOD__ => [ 'class' => 'HashBagOStuff' ] ] );
|
||||
$this->setMwGlobals( [ 'wgMainCacheType' => __METHOD__ ] );
|
||||
$this->setMainCache( CACHE_HASH );
|
||||
|
||||
// Set up lots of mocks...
|
||||
$mocks = [];
|
||||
|
|
|
|||
|
|
@ -26,10 +26,12 @@ class SessionManagerTest extends MediaWikiIntegrationTestCase {
|
|||
private $store;
|
||||
|
||||
protected function getManager() {
|
||||
\ObjectCache::$instances['testSessionStore'] = new TestBagOStuff();
|
||||
$this->store = new TestBagOStuff();
|
||||
$cacheType = $this->setMainCache( $this->store );
|
||||
|
||||
$this->config = new \HashConfig( [
|
||||
'LanguageCode' => 'en',
|
||||
'SessionCacheType' => 'testSessionStore',
|
||||
'SessionCacheType' => $cacheType,
|
||||
'ObjectCacheSessionExpiry' => 100,
|
||||
'SessionProviders' => [
|
||||
[ 'class' => \DummySessionProvider::class ],
|
||||
|
|
@ -43,7 +45,6 @@ class SessionManagerTest extends MediaWikiIntegrationTestCase {
|
|||
|| preg_match( '/^(Persisting|Unpersisting) session (for|due to)/', $m )
|
||||
) ? null : $m;
|
||||
} );
|
||||
$this->store = new TestBagOStuff();
|
||||
|
||||
return new SessionManager( [
|
||||
'config' => $this->config,
|
||||
|
|
@ -127,7 +128,7 @@ class SessionManagerTest extends MediaWikiIntegrationTestCase {
|
|||
$manager = TestingAccessWrapper::newFromObject( new SessionManager( [
|
||||
'config' => $this->config,
|
||||
] ) );
|
||||
$this->assertSame( \ObjectCache::$instances['testSessionStore'], $manager->store );
|
||||
$this->assertSame( $this->store, $manager->store );
|
||||
|
||||
foreach ( [
|
||||
'config' => '$options[\'config\'] must be an instance of Config',
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ use MediaWiki\User\UserIdentity;
|
|||
use MediaWiki\User\UserIdentityValue;
|
||||
use MediaWikiIntegrationTestCase;
|
||||
use MWTimestamp;
|
||||
use ObjectCache;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use Wikimedia\TestingAccessWrapper;
|
||||
|
||||
|
|
@ -135,8 +134,6 @@ class RateLimiterTest extends MediaWikiIntegrationTestCase {
|
|||
* @covers \MediaWiki\Permissions\RateLimiter::limit
|
||||
*/
|
||||
public function testPingLimiterWithStaleCache() {
|
||||
global $wgMainCacheType;
|
||||
|
||||
$limits = [
|
||||
'edit' => [
|
||||
'user' => [ 1, 60 ],
|
||||
|
|
@ -147,8 +144,7 @@ class RateLimiterTest extends MediaWikiIntegrationTestCase {
|
|||
$appTime = 1600000000;
|
||||
$bag = new HashBagOStuff();
|
||||
|
||||
// TODO: make the main object cache a service we can override, T243233
|
||||
ObjectCache::$instances[$wgMainCacheType] = $bag;
|
||||
$this->setMainCache( $bag );
|
||||
|
||||
$bag->setMockTime( $bagTime ); // this is a reference!
|
||||
MWTimestamp::setFakeTime( static function () use ( &$appTime ) {
|
||||
|
|
@ -175,8 +171,6 @@ class RateLimiterTest extends MediaWikiIntegrationTestCase {
|
|||
* @covers \MediaWiki\Permissions\RateLimiter::limit
|
||||
*/
|
||||
public function testPingLimiterRate() {
|
||||
global $wgMainCacheType;
|
||||
|
||||
$limits = [
|
||||
'edit' => [
|
||||
'user' => [ 3, 60 ],
|
||||
|
|
@ -184,18 +178,17 @@ class RateLimiterTest extends MediaWikiIntegrationTestCase {
|
|||
];
|
||||
|
||||
$fakeTime = 1600000000;
|
||||
$store = new HashBagOStuff();
|
||||
$cache = new HashBagOStuff();
|
||||
|
||||
// TODO: make the main object cache a service we can override, T243233
|
||||
ObjectCache::$instances[$wgMainCacheType] = $store;
|
||||
$this->setMainCache( $cache );
|
||||
|
||||
$store->setMockTime( $fakeTime ); // this is a reference!
|
||||
$cache->setMockTime( $fakeTime ); // this is a reference!
|
||||
MWTimestamp::setFakeTime( static function () use ( &$fakeTime ) {
|
||||
return (int)$fakeTime;
|
||||
} );
|
||||
|
||||
$user = $this->newFakeUser( 'Frank', '1.2.3.4', 111 );
|
||||
$limiter = $this->newRateLimiter( $limits, [], $store );
|
||||
$limiter = $this->newRateLimiter( $limits, [], $cache );
|
||||
|
||||
// The limit is 3 per 60 second. Do 5 edits at an emulated 50 second interval.
|
||||
// They should all pass. This tests that the counter doesn't just keeps increasing
|
||||
|
|
|
|||
|
|
@ -387,7 +387,8 @@ class PageHTMLHandlerTest extends MediaWikiIntegrationTestCase {
|
|||
|
||||
public function testStashingWithRateLimitExceeded() {
|
||||
// Set the rate limit to 1 request per minute
|
||||
$this->mergeMwGlobalArrayValue( 'wgRateLimits',
|
||||
$this->overrideConfigValue(
|
||||
'RateLimits',
|
||||
[
|
||||
'stashbasehtml' => [
|
||||
'&can-bypass' => false,
|
||||
|
|
@ -395,7 +396,7 @@ class PageHTMLHandlerTest extends MediaWikiIntegrationTestCase {
|
|||
'newbie' => [ 1, 60 ]
|
||||
]
|
||||
] );
|
||||
$this->setMwGlobals( [ 'wgMainCacheType' => CACHE_ANYTHING ] );
|
||||
$this->setMainCache( CACHE_HASH );
|
||||
|
||||
$page = $this->getExistingTestPage();
|
||||
|
||||
|
|
|
|||
|
|
@ -411,7 +411,8 @@ class RevisionHTMLHandlerTest extends MediaWikiIntegrationTestCase {
|
|||
|
||||
public function testStashingWithRateLimitExceeded() {
|
||||
// Set the rate limit to 1 request per minute
|
||||
$this->mergeMwGlobalArrayValue( 'wgRateLimits',
|
||||
$this->overrideConfigValue(
|
||||
'RateLimits',
|
||||
[
|
||||
'stashbasehtml' => [
|
||||
'&can-bypass' => false,
|
||||
|
|
@ -419,7 +420,7 @@ class RevisionHTMLHandlerTest extends MediaWikiIntegrationTestCase {
|
|||
'newbie' => [ 1, 60 ]
|
||||
]
|
||||
] );
|
||||
$this->setMwGlobals( [ 'wgMainCacheType' => CACHE_ANYTHING ] );
|
||||
$this->setMainCache( CACHE_HASH );
|
||||
|
||||
$page = $this->getExistingTestPage();
|
||||
|
||||
|
|
|
|||
|
|
@ -168,6 +168,31 @@ class MediaWikiIntegrationTestCaseTest extends MediaWikiIntegrationTestCase {
|
|||
$this->assertSame( 'YYY', $config->get( MainConfigNames::JobTypeConf ) );
|
||||
}
|
||||
|
||||
public function testSetMainCache() {
|
||||
// Cache should be disabled per default during testing.
|
||||
$this->assertInstanceOf( EmptyBagOStuff::class, ObjectCache::getLocalClusterInstance() );
|
||||
|
||||
// Use HashBagOStuff.
|
||||
$this->setMainCache( CACHE_HASH );
|
||||
$cache = ObjectCache::getLocalClusterInstance();
|
||||
$this->assertInstanceOf( HashBagOStuff::class, $cache );
|
||||
|
||||
// Install different HashBagOStuff
|
||||
$cache = new HashBagOStuff();
|
||||
$name = $this->setMainCache( $cache );
|
||||
$this->assertSame( $cache, ObjectCache::getLocalClusterInstance() );
|
||||
$this->assertSame( $cache, ObjectCache::getInstance( $name ) );
|
||||
|
||||
// Our custom cache object should not replace an existing entry.
|
||||
$this->assertNotSame( $cache, ObjectCache::getInstance( CACHE_HASH ) );
|
||||
$this->setMainCache( CACHE_HASH );
|
||||
$this->assertNotSame( $cache, ObjectCache::getLocalClusterInstance() );
|
||||
|
||||
// We should be able to disable the cache.
|
||||
$this->assertSame( CACHE_NONE, $this->setMainCache( CACHE_NONE ) );
|
||||
$this->assertInstanceOf( EmptyBagOStuff::class, ObjectCache::getLocalClusterInstance() );
|
||||
}
|
||||
|
||||
public function testOverrideMwServices() {
|
||||
$initialServices = MediaWikiServices::getInstance();
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue