use MediaWikiCoversValidator;
use PHPUnit4And6Compat;
- /** @var TimeAdjustableWANObjectCache */
+ /** @var WANObjectCache */
private $cache;
/** @var BagOStuff */
private $internalCache;
protected function setUp() {
parent::setUp();
- $this->cache = new TimeAdjustableWANObjectCache( [
- 'cache' => new TimeAdjustableHashBagOStuff(),
+ $this->cache = new WANObjectCache( [
+ 'cache' => new HashBagOStuff(),
'pool' => 'testcache-hash',
'relayer' => new EventRelayerNull( [] )
] );
$this->assertEquals( $value, $v, "Value returned" );
$this->assertEquals( 0, $wasSet, "Value not regenerated" );
- $priorTime = microtime( true ); // reference time
- $cache->setTime( $priorTime );
+ $mockWallClock = microtime( true );
+ $priorTime = $mockWallClock; // reference time
+ $cache->setMockTime( $mockWallClock );
- $cache->addTime( 1 );
+ $mockWallClock += 1;
$wasSet = 0;
$v = $cache->getWithSetCallback(
$t2 = $cache->getCheckKeyTime( $cKey2 );
$this->assertGreaterThanOrEqual( $priorTime, $t2, 'Check keys generated on miss' );
- $priorTime = $cache->addTime( 0.01 );
-
+ $mockWallClock += 0.01;
+ $priorTime = $mockWallClock; // reference time
$wasSet = 0;
$v = $cache->getWithSetCallback(
$key, 30, $func, [ 'checkKeys' => [ $cKey1, $cKey2 ] ] + $extOpts
return 'xxx' . $wasSet;
};
- $now = microtime( true ); // reference time
+ $mockWallClock = microtime( true );
+ $priorTime = $mockWallClock; // reference time
$wasSet = 0;
$key = wfRandomString();
$this->assertEquals( false, $oldValReceived, "Callback got no stale value" );
$this->assertEquals( null, $oldAsOfReceived, "Callback got no stale value" );
- $cache->addTime( 40 );
+ $mockWallClock += 40;
$v = $cache->getWithSetCallback(
$key, 30, $checkFunc, [ 'staleTTL' => 50 ] + $extOpts );
$this->assertEquals( 'xxx2', $v, "Value still returned after expired" );
$this->assertEquals( 'xxx1', $oldValReceived, "Callback got stale value" );
$this->assertNotEquals( null, $oldAsOfReceived, "Callback got stale value" );
- $cache->addTime( 260 );
+ $mockWallClock += 260;
$v = $cache->getWithSetCallback(
$key, 30, $checkFunc, [ 'staleTTL' => 50 ] + $extOpts );
$this->assertEquals( 'xxx3', $v, "Value still returned after expired" );
$this->assertEquals( false, $oldValReceived, "Callback got no stale value" );
$this->assertEquals( null, $oldAsOfReceived, "Callback got no stale value" );
+ $mockWallClock = ( $priorTime - $cache::HOLDOFF_TTL - 1 );
$wasSet = 0;
$key = wfRandomString();
$checkKey = $cache->makeKey( 'template', 'X' );
- $cache->setTime( $now - $cache::HOLDOFF_TTL - 1 );
$cache->touchCheckKey( $checkKey ); // init check key
- $cache->setTime( $now );
+ $mockWallClock = $priorTime;
$v = $cache->getWithSetCallback(
$key,
$cache::TTL_INDEFINITE,
$this->assertEquals( false, $oldValReceived, "Callback got no stale value" );
$this->assertEquals( null, $oldAsOfReceived, "Callback got no stale value" );
- $cache->addTime( $cache::TTL_HOUR ); // some time passes
+ $mockWallClock += $cache::TTL_HOUR; // some time passes
$v = $cache->getWithSetCallback(
$key,
$cache::TTL_INDEFINITE,
$this->assertEquals( 1, $wasSet, "Cached value returned" );
$cache->touchCheckKey( $checkKey ); // make key stale
- $cache->addTime( 0.01 ); // ~1 week left of grace (barely stale to avoid refreshes)
+ $mockWallClock += 0.01; // ~1 week left of grace (barely stale to avoid refreshes)
$v = $cache->getWithSetCallback(
$key,
$this->assertEquals( 1, $wasSet, "Value still returned after expired (in grace)" );
// Change of refresh increase to unity as staleness approaches graceTTL
-
- $cache->addTime( $cache::TTL_WEEK ); // 8 days of being stale
+ $mockWallClock += $cache::TTL_WEEK; // 8 days of being stale
$v = $cache->getWithSetCallback(
$key,
$cache::TTL_INDEFINITE,
$asycList[] = $callback;
};
$cache = new NearExpiringWANObjectCache( [
- 'cache' => new TimeAdjustableHashBagOStuff(),
+ 'cache' => new HashBagOStuff(),
'pool' => 'empty',
'asyncHandler' => $asyncHandler
] );
- $now = microtime( true ); // reference time
- $cache->setTime( $now );
+ $mockWallClock = microtime( true );
+ $priorTime = $mockWallClock; // reference time
+ $cache->setMockTime( $mockWallClock );
$wasSet = 0;
$key = wfRandomString();
- $checkKey = wfRandomString();
$opts = [ 'lowTTL' => 100 ];
$v = $cache->getWithSetCallback( $key, 300, $func, $opts );
$this->assertEquals( $value, $v, "Value returned" );
$this->assertEquals( 1, $wasSet, "Cached value used" );
$this->assertEquals( $v, $value, "Value cached" );
- $cache->setTime( $now + 250 );
+ $mockWallClock += 250;
$v = $cache->getWithSetCallback( $key, 300, $func, $opts );
$this->assertEquals( $value, $v, "Value returned" );
$this->assertEquals( 1, $wasSet, "Stale value used" );
$this->assertEquals( $value, $v, "New value stored" );
$cache = new PopularityRefreshingWANObjectCache( [
- 'cache' => new TimeAdjustableHashBagOStuff(),
+ 'cache' => new HashBagOStuff(),
'pool' => 'empty'
] );
- $cache->setTime( $now );
+ $mockWallClock = $priorTime;
+ $cache->setMockTime( $mockWallClock );
$wasSet = 0;
$key = wfRandomString();
$v = $cache->getWithSetCallback( $key, 60, $func, $opts );
$this->assertEquals( $value, $v, "Value returned" );
$this->assertEquals( 1, $wasSet, "Value calculated" );
- $cache->setTime( $now + 30 );
+
+ $mockWallClock += 30;
+
$v = $cache->getWithSetCallback( $key, 60, $func, $opts );
$this->assertEquals( 1, $wasSet, "Value cached" );
+ $mockWallClock = $priorTime;
$wasSet = 0;
$key = wfRandomString();
$opts = [ 'hotTTR' => 10 ];
- $cache->setTime( $now );
$v = $cache->getWithSetCallback( $key, 60, $func, $opts );
$this->assertEquals( $value, $v, "Value returned" );
$this->assertEquals( 1, $wasSet, "Value calculated" );
- $cache->setTime( $now + 30 );
+
+ $mockWallClock += 30;
+
$v = $cache->getWithSetCallback( $key, 60, $func, $opts );
$this->assertEquals( $value, $v, "Value returned" );
$this->assertEquals( 2, $wasSet, "Value re-calculated" );
$this->assertEquals( 1, $wasSet, "Value not regenerated" );
$this->assertEquals( 0, $cache->getWarmupKeyMisses(), "Keys warmed in process cache" );
- $priorTime = microtime( true ); // reference time
- $cache->setTime( $priorTime );
+ $mockWallClock = microtime( true );
+ $priorTime = $mockWallClock; // reference time
+ $cache->setMockTime( $mockWallClock );
- $cache->addTime( 1 );
+ $mockWallClock += 1;
$wasSet = 0;
$keyedIds = new ArrayIterator( [ $keyB => 'efef' ] );
$t2 = $cache->getCheckKeyTime( $cKey2 );
$this->assertGreaterThanOrEqual( $priorTime, $t2, 'Check keys generated on miss' );
- $priorTime = $cache->addTime( 0.01 );
+ $mockWallClock += 0.01;
+ $priorTime = $mockWallClock;
$value = "@43636$";
$wasSet = 0;
$keyedIds = new ArrayIterator( [ $keyC => 43636 ] );
$this->assertEquals( 1, $wasSet, "Value not regenerated" );
$this->assertEquals( 0, $cache->getWarmupKeyMisses(), "Keys warmed in process cache" );
- $priorTime = microtime( true ); // reference time
- $cache->setTime( $priorTime );
+ $mockWallClock = microtime( true );
+ $priorTime = $mockWallClock; // reference time
+ $cache->setMockTime( $mockWallClock );
- $cache->addTime( 1 );
+ $mockWallClock += 1;
$wasSet = 0;
$keyedIds = new ArrayIterator( [ $keyB => 'efef' ] );
$t2 = $cache->getCheckKeyTime( $cKey2 );
$this->assertGreaterThanOrEqual( $priorTime, $t2, 'Check keys generated on miss' );
- $priorTime = $cache->addTime( 0.01 );
+ $mockWallClock += 0.01;
+ $priorTime = $mockWallClock;
$value = "@43636$";
$wasSet = 0;
$keyedIds = new ArrayIterator( [ $keyC => 43636 ] );
$cKey1 = wfRandomString();
$cKey2 = wfRandomString();
- $priorTime = microtime( true ); // reference time
- $cache->setTime( $priorTime );
+ $mockWallClock = microtime( true );
+ $priorTime = $mockWallClock; // reference time
+ $cache->setMockTime( $mockWallClock );
- $cache->addTime( 1 );
+ $mockWallClock += 1;
$curTTLs = [];
$this->assertEquals(
$this->assertLessThanOrEqual( 0, $curTTLs[$key1], 'Key 1 has current TTL <= 0' );
$this->assertLessThanOrEqual( 0, $curTTLs[$key2], 'Key 2 has current TTL <= 0' );
- $cache->addTime( 1 );
+ $mockWallClock += 1;
$curTTLs = [];
$this->assertEquals(
$value1 = wfRandomString();
$value2 = wfRandomString();
- $cache->setTime( microtime( true ) );
+ $mockWallClock = microtime( true );
+ $cache->setMockTime( $mockWallClock );
// Fake initial check key to be set in the past. Otherwise we'd have to sleep for
// several seconds during the test to assert the behaviour.
$cache->touchCheckKey( $checkKey, WANObjectCache::HOLDOFF_NONE );
}
- $cache->addTime( 0.100 );
+ $mockWallClock += 0.100;
$cache->set( 'key1', $value1, 10 );
$cache->set( 'key2', $value2, 10 );
$this->assertGreaterThanOrEqual( 9.5, $curTTLs['key2'], 'Initial ttls' );
$this->assertLessThanOrEqual( 10.5, $curTTLs['key2'], 'Initial ttls' );
- $cache->addTime( 0.100 );
+ $mockWallClock += 0.100;
$cache->touchCheckKey( $check1 );
$curTTLs = [];
$cache = $this->cache;
$key = wfRandomString();
- $priorTime = microtime( true ); // reference time
- $cache->setTime( $priorTime );
+ $mockWallClock = microtime( true );
+ $priorTime = $mockWallClock; // reference time
+ $cache->setMockTime( $mockWallClock );
- $newTime = $cache->addTime( 0.100 );
+ $mockWallClock += 0.100;
$t0 = $cache->getCheckKeyTime( $key );
$this->assertGreaterThanOrEqual( $priorTime, $t0, 'Check key auto-created' );
- $priorTime = $newTime;
- $newTime = $cache->addTime( 0.100 );
+ $priorTime = $mockWallClock;
+ $mockWallClock += 0.100;
$cache->touchCheckKey( $key );
$t1 = $cache->getCheckKeyTime( $key );
$this->assertGreaterThanOrEqual( $priorTime, $t1, 'Check key created' );
$t2 = $cache->getCheckKeyTime( $key );
$this->assertEquals( $t1, $t2, 'Check key time did not change' );
- $cache->addTime( 0.100 );
+ $mockWallClock += 0.100;
$cache->touchCheckKey( $key );
$t3 = $cache->getCheckKeyTime( $key );
$this->assertGreaterThan( $t2, $t3, 'Check key time increased' );
$t4 = $cache->getCheckKeyTime( $key );
$this->assertEquals( $t3, $t4, 'Check key time did not change' );
- $cache->addTime( 0.100 );
+ $mockWallClock += 0.100;
$cache->resetCheckKey( $key );
$t5 = $cache->getCheckKeyTime( $key );
$this->assertGreaterThan( $t4, $t5, 'Check key time increased' );
}
}
-class TimeAdjustableHashBagOStuff extends HashBagOStuff {
- private $timeOverride = 0;
-
- public function setTime( $time ) {
- $this->timeOverride = $time;
- }
-
- protected function getCurrentTime() {
- return $this->timeOverride ?: parent::getCurrentTime();
- }
-}
-
-class TimeAdjustableWANObjectCache extends WANObjectCache {
- private $timeOverride = 0;
-
- public function setTime( $time ) {
- $this->timeOverride = $time;
- if ( $this->cache instanceof TimeAdjustableHashBagOStuff ) {
- $this->cache->setTime( $time );
- }
- }
-
- public function addTime( $time ) {
- $this->timeOverride += $time;
- if ( $this->cache instanceof TimeAdjustableHashBagOStuff ) {
- $this->cache->setTime( $this->timeOverride );
- }
-
- return $this->timeOverride;
- }
-
- protected function getCurrentTime() {
- return $this->timeOverride ?: parent::getCurrentTime();
- }
-}
-
-class NearExpiringWANObjectCache extends TimeAdjustableWANObjectCache {
+class NearExpiringWANObjectCache extends WANObjectCache {
const CLOCK_SKEW = 1;
protected function worthRefreshExpiring( $curTTL, $lowTTL ) {
}
}
-class PopularityRefreshingWANObjectCache extends TimeAdjustableWANObjectCache {
+class PopularityRefreshingWANObjectCache extends WANObjectCache {
protected function worthRefreshPopular( $asOf, $ageNew, $timeTillRefresh, $now ) {
return ( ( $now - $asOf ) > $timeTillRefresh );
}