wiki.techinc.nl/tests/phpunit/unit/includes/Settings/Cache/CacheInterfaceTestTrait.php
Dan Duvall d83a7bcd09 Cache loading of SettingsBuilder sources
The `SettingsBuilder` now accepts a PSR-16 cache interface with which to
store and query settings before attempting to load from each source. By
default, no cache is used, but any object that implements the
`Psr\SimpleCache\CacheInterface` may be provided to the constructor.

An explicit dependency on "psr/simple-cache" has been added to
`composer.json`. Note that this dependency already existed in vendor
albeit it as a transitive one.

An APCu based `SharedMemoryCache` adapter is provided as a canonical
PSR-16 compliant interface for production use.

Sources are now queued by the `SettingsBuilder` when calling `load()`.
If a cache interface has been provided, and the source is considered
cacheable (implements `CacheableSource`), then it is wrapped as a
`CachedSource` which will query the cache first before loading from the
wrapped source.

Cache stampedes are mitigated using probabilistic early expiry. The
implementation for this was partially based on symfony/cache-contract
source code but also from the Wikipedia article and paper referenced
therein.

See https://en.wikipedia.org/wiki/Cache_stampede#Probabilistic_early_expiration

Bug: T294748
Change-Id: I52ab3899731546876ee58265bd4a1927886746dc
2021-11-29 12:54:59 -08:00

94 lines
2.2 KiB
PHP

<?php
namespace MediaWiki\Tests\Unit\Settings\Cache;
use DateInterval;
use Psr\SimpleCache\CacheInterface;
trait CacheInterfaceTestTrait {
abstract protected function newCache(): CacheInterface;
public function testSetAndGet() {
$cache = $this->newCache();
$cache->set( 'one', 'fish1' );
$cache->set( 'two', 'fish2', 60 );
$cache->set( 'red', 'fish3', DateInterval::createFromDateString( '@60' ) );
$this->assertSame( 'fish1', $cache->get( 'one' ) );
$this->assertSame( 'fish2', $cache->get( 'two' ) );
$this->assertSame( 'fish3', $cache->get( 'red' ) );
$this->assertSame( 'fish4', $cache->get( 'blue', 'fish4' ) );
}
public function testSetAndGetMultiple() {
$cache = $this->newCache();
$cache->setMultiple(
[
'one' => 'fish1',
'two' => 'fish2',
'red' => 'fish3',
]
);
$this->assertSame(
[
'one' => 'fish1',
'two' => 'fish2',
'red' => 'fish3',
'blue' => 'fish4',
],
$cache->getMultiple( [ 'one', 'two', 'red', 'blue' ], 'fish4' )
);
}
public function testDeleteAndHas() {
$cache = $this->newCache();
$cache->set( 'red', 'fish' );
$cache->set( 'blue', 'fish' );
$cache->delete( 'red' );
$this->assertFalse( $cache->has( 'red' ) );
$this->assertTrue( $cache->has( 'blue' ) );
}
public function testDeleteMultiple() {
$cache = $this->newCache();
$cache->set( 'one', 'fish' );
$cache->set( 'two', 'fish' );
$cache->set( 'red', 'fish' );
$cache->set( 'blue', 'fish' );
$cache->deleteMultiple( [ 'two', 'red' ] );
$this->assertTrue( $cache->has( 'one' ) );
$this->assertFalse( $cache->has( 'two' ) );
$this->assertFalse( $cache->has( 'red' ) );
$this->assertTrue( $cache->has( 'blue' ) );
}
public function testClear() {
$cache = $this->newCache();
$cache->set( 'one', 'fish' );
$cache->set( 'two', 'fish' );
$cache->set( 'red', 'fish' );
$cache->set( 'blue', 'fish' );
$this->assertTrue( $cache->has( 'one' ) );
$this->assertTrue( $cache->has( 'two' ) );
$this->assertTrue( $cache->has( 'red' ) );
$this->assertTrue( $cache->has( 'blue' ) );
$cache->clear();
$this->assertFalse( $cache->has( 'one' ) );
$this->assertFalse( $cache->has( 'two' ) );
$this->assertFalse( $cache->has( 'red' ) );
$this->assertFalse( $cache->has( 'blue' ) );
}
}