wiki.techinc.nl/tests/phpunit/includes/libs/ProcessCacheLRUTest.php
Timo Tijhof 9b62a6ad80 ProcessCacheLRU: Clean up doc comments and add @covers tags to tests
Change-Id: Ie7e8f4b31d89fc0bee748c03d94cb54b23ab4f83
2015-01-29 12:08:27 -08:00

265 lines
7 KiB
PHP

<?php
/**
* Test for ProcessCacheLRU class.
*
* Note that it uses the ProcessCacheLRUTestable class which extends some
* properties and methods visibility. That class is defined at the end of the
* file containing this class.
*
* @group Cache
*/
class ProcessCacheLRUTest extends PHPUnit_Framework_TestCase {
/**
* Helper to verify emptiness of a cache object.
* Compare against an array so we get the cache content difference.
*/
protected function assertCacheEmpty( $cache, $msg = 'Cache should be empty' ) {
$this->assertAttributeEquals( array(), 'cache', $cache, $msg );
}
/**
* Helper to fill a cache object passed by reference
*/
protected function fillCache( &$cache, $numEntries ) {
// Fill cache with three values
for ( $i = 1; $i <= $numEntries; $i++ ) {
$cache->set( "cache-key-$i", "prop-$i", "value-$i" );
}
}
/**
* Generates an array of what would be expected in cache for a given cache
* size and a number of entries filled in sequentially
*/
protected function getExpectedCache( $cacheMaxEntries, $entryToFill ) {
$expected = array();
if ( $entryToFill === 0 ) {
// The cache is empty!
return array();
} elseif ( $entryToFill <= $cacheMaxEntries ) {
// Cache is not fully filled
$firstKey = 1;
} else {
// Cache overflowed
$firstKey = 1 + $entryToFill - $cacheMaxEntries;
}
$lastKey = $entryToFill;
for ( $i = $firstKey; $i <= $lastKey; $i++ ) {
$expected["cache-key-$i"] = array( "prop-$i" => "value-$i" );
}
return $expected;
}
/**
* Highlight diff between assertEquals and assertNotSame
*/
public function testPhpUnitArrayEquality() {
$one = array( 'A' => 1, 'B' => 2 );
$two = array( 'B' => 2, 'A' => 1 );
// ==
$this->assertEquals( $one, $two );
// ===
$this->assertNotSame( $one, $two );
}
/**
* @dataProvider provideInvalidConstructorArg
* @expectedException UnexpectedValueException
* @covers ProcessCacheLRU::__construct
*/
public function testConstructorGivenInvalidValue( $maxSize ) {
new ProcessCacheLRUTestable( $maxSize );
}
/**
* Value which are forbidden by the constructor
*/
public static function provideInvalidConstructorArg() {
return array(
array( null ),
array( array() ),
array( new stdClass() ),
array( 0 ),
array( '5' ),
array( -1 ),
);
}
/**
* @covers ProcessCacheLRU::get
* @covers ProcessCacheLRU::set
* @covers ProcessCacheLRU::het
*/
public function testAddAndGetAKey() {
$oneCache = new ProcessCacheLRUTestable( 1 );
$this->assertCacheEmpty( $oneCache );
// First set just one value
$oneCache->set( 'cache-key', 'prop1', 'value1' );
$this->assertEquals( 1, $oneCache->getEntriesCount() );
$this->assertTrue( $oneCache->has( 'cache-key', 'prop1' ) );
$this->assertEquals( 'value1', $oneCache->get( 'cache-key', 'prop1' ) );
}
/**
* @covers ProcessCacheLRU::set
* @covers ProcessCacheLRU::get
*/
public function testDeleteOldKey() {
$oneCache = new ProcessCacheLRUTestable( 1 );
$this->assertCacheEmpty( $oneCache );
$oneCache->set( 'cache-key', 'prop1', 'value1' );
$oneCache->set( 'cache-key', 'prop1', 'value2' );
$this->assertEquals( 'value2', $oneCache->get( 'cache-key', 'prop1' ) );
}
/**
* This test that we properly overflow when filling a cache with
* a sequence of always different cache-keys. Meant to verify we correclty
* delete the older key.
*
* @covers ProcessCacheLRU::set
* @dataProvider provideCacheFilling
* @param int $cacheMaxEntries Maximum entry the created cache will hold
* @param int $entryToFill Number of entries to insert in the created cache.
*/
public function testFillingCache( $cacheMaxEntries, $entryToFill, $msg = '' ) {
$cache = new ProcessCacheLRUTestable( $cacheMaxEntries );
$this->fillCache( $cache, $entryToFill );
$this->assertSame(
$this->getExpectedCache( $cacheMaxEntries, $entryToFill ),
$cache->getCache(),
"Filling a $cacheMaxEntries entries cache with $entryToFill entries"
);
}
/**
* Provider for testFillingCache
*/
public static function provideCacheFilling() {
// ($cacheMaxEntries, $entryToFill, $msg='')
return array(
array( 1, 0 ),
array( 1, 1 ),
// overflow
array( 1, 2 ),
// overflow
array( 5, 33 ),
);
}
/**
* Create a cache with only one remaining entry then update
* the first inserted entry. Should bump it to the top.
*
* @covers ProcessCacheLRU::set
*/
public function testReplaceExistingKeyShouldBumpEntryToTop() {
$maxEntries = 3;
$cache = new ProcessCacheLRUTestable( $maxEntries );
// Fill cache leaving just one remaining slot
$this->fillCache( $cache, $maxEntries - 1 );
// Set an existing cache key
$cache->set( "cache-key-1", "prop-1", "new-value-for-1" );
$this->assertSame(
array(
'cache-key-2' => array( 'prop-2' => 'value-2' ),
'cache-key-1' => array( 'prop-1' => 'new-value-for-1' ),
),
$cache->getCache()
);
}
/**
* @covers ProcessCacheLRU::get
* @covers ProcessCacheLRU::set
* @covers ProcessCacheLRU::het
*/
public function testRecentlyAccessedKeyStickIn() {
$cache = new ProcessCacheLRUTestable( 2 );
$cache->set( 'first', 'prop1', 'value1' );
$cache->set( 'second', 'prop2', 'value2' );
// Get first
$cache->get( 'first', 'prop1' );
// Cache a third value, should invalidate the least used one
$cache->set( 'third', 'prop3', 'value3' );
$this->assertFalse( $cache->has( 'second', 'prop2' ) );
}
/**
* This first create a full cache then update the value for the 2nd
* filled entry.
* Given a cache having 1,2,3 as key, updating 2 should bump 2 to
* the top of the queue with the new value: 1,3,2* (* = updated).
*
* @covers ProcessCacheLRU::set
* @covers ProcessCacheLRU::get
*/
public function testReplaceExistingKeyInAFullCacheShouldBumpToTop() {
$maxEntries = 3;
$cache = new ProcessCacheLRUTestable( $maxEntries );
$this->fillCache( $cache, $maxEntries );
// Set an existing cache key
$cache->set( "cache-key-2", "prop-2", "new-value-for-2" );
$this->assertSame(
array(
'cache-key-1' => array( 'prop-1' => 'value-1' ),
'cache-key-3' => array( 'prop-3' => 'value-3' ),
'cache-key-2' => array( 'prop-2' => 'new-value-for-2' ),
),
$cache->getCache()
);
$this->assertEquals( 'new-value-for-2',
$cache->get( 'cache-key-2', 'prop-2' )
);
}
/**
* @covers ProcessCacheLRU::set
*/
public function testBumpExistingKeyToTop() {
$cache = new ProcessCacheLRUTestable( 3 );
$this->fillCache( $cache, 3 );
// Set the very first cache key to a new value
$cache->set( "cache-key-1", "prop-1", "new value for 1" );
$this->assertEquals(
array(
'cache-key-2' => array( 'prop-2' => 'value-2' ),
'cache-key-3' => array( 'prop-3' => 'value-3' ),
'cache-key-1' => array( 'prop-1' => 'new value for 1' ),
),
$cache->getCache()
);
}
}
/**
* Overrides some ProcessCacheLRU methods and properties accessibility.
*/
class ProcessCacheLRUTestable extends ProcessCacheLRU {
public $cache = array();
public function getCache() {
return $this->cache;
}
public function getEntriesCount() {
return count( $this->cache );
}
}