wiki.techinc.nl/tests/phpunit/unit/includes/Settings/Source/FileSourceTest.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

65 lines
1.7 KiB
PHP

<?php
namespace MediaWiki\Tests\Unit\Settings\Source;
use MediaWiki\Settings\SettingsBuilderException;
use MediaWiki\Settings\Source\FileSource;
use MediaWiki\Settings\Source\Format\JsonFormat;
use PHPUnit\Framework\TestCase;
/**
* @covers \MediaWiki\Settings\Source\FileSource
*/
class FileSourceTest extends TestCase {
public function testLoad() {
$source = new FileSource( __DIR__ . '/fixtures/settings.json' );
$settings = $source->load();
$this->assertSame(
[ 'config' => [ 'MySetting' => 'BlaBla' ] ],
$source->load()
);
}
public function testLoadFormat() {
$source = new FileSource( __DIR__ . '/fixtures/settings.json', new JsonFormat() );
$settings = $source->load();
$this->assertSame(
[ 'config' => [ 'MySetting' => 'BlaBla' ] ],
$source->load()
);
}
public function testLoadBadFormat() {
$source = new FileSource( __DIR__ . '/fixtures/bad.json', new JsonFormat() );
$this->expectException( SettingsBuilderException::class );
$settings = $source->load();
}
public function testLoadDirectory() {
$source = new FileSource( __DIR__ . '/fixtures/dir.json' );
$this->expectException( SettingsBuilderException::class );
$settings = $source->load();
}
public function testLoadNoSuitableFormats() {
$source = new FileSource( __DIR__ . '/fixtures/settings.toml', new JsonFormat() );
$this->expectException( SettingsBuilderException::class );
$settings = $source->load();
}
public function testGetHashKey() {
$source = new FileSource( __DIR__ . '/fixtures/settings.json' );
// We can't reliably mock the filesystem stat so simply ensure the
// method returns and is non-zero in length
$this->assertNotEmpty( $source->getHashKey() );
}
}