MediaWiki  REL1_21
ProcessCacheLRUTest.php
Go to the documentation of this file.
00001 <?php
00002 
00012 class ProcessCacheLRUTest extends MediaWikiTestCase {
00013 
00018         function assertCacheEmpty( $cache, $msg = 'Cache should be empty' ) {
00019                 $this->assertAttributeEquals( array(), 'cache', $cache, $msg );
00020         }
00021 
00025         function fillCache( &$cache, $numEntries ) {
00026                 // Fill cache with three values
00027                 for ( $i = 1; $i <= $numEntries; $i++ ) {
00028                         $cache->set( "cache-key-$i", "prop-$i", "value-$i" );
00029                 }
00030         }
00031 
00036         function getExpectedCache( $cacheMaxEntries, $entryToFill ) {
00037                 $expected = array();
00038 
00039                 if ( $entryToFill === 0 ) {
00040                         # The cache is empty!
00041                         return array();
00042                 } elseif ( $entryToFill <= $cacheMaxEntries ) {
00043                         # Cache is not fully filled
00044                         $firstKey = 1;
00045                 } else {
00046                         # Cache overflowed
00047                         $firstKey = 1 + $entryToFill - $cacheMaxEntries;
00048                 }
00049 
00050                 $lastKey = $entryToFill;
00051 
00052                 for ( $i = $firstKey; $i <= $lastKey; $i++ ) {
00053                         $expected["cache-key-$i"] = array( "prop-$i" => "value-$i" );
00054                 }
00055                 return $expected;
00056         }
00057 
00061         function testPhpUnitArrayEquality() {
00062                 $one = array( 'A' => 1, 'B' => 2 );
00063                 $two = array( 'B' => 2, 'A' => 1 );
00064                 $this->assertEquals( $one, $two ); // ==
00065                 $this->assertNotSame( $one, $two ); // ===
00066         }
00067 
00072         function testConstructorGivenInvalidValue( $maxSize ) {
00073                 $c = new ProcessCacheLRUTestable( $maxSize );
00074         }
00075 
00079         public static function provideInvalidConstructorArg() {
00080                 return array(
00081                         array( null ),
00082                         array( array() ),
00083                         array( new stdClass() ),
00084                         array( 0 ),
00085                         array( '5' ),
00086                         array( -1 ),
00087                 );
00088         }
00089 
00090         function testAddAndGetAKey() {
00091                 $oneCache = new ProcessCacheLRUTestable( 1 );
00092                 $this->assertCacheEmpty( $oneCache );
00093 
00094                 // First set just one value
00095                 $oneCache->set( 'cache-key', 'prop1', 'value1' );
00096                 $this->assertEquals( 1, $oneCache->getEntriesCount() );
00097                 $this->assertTrue( $oneCache->has( 'cache-key', 'prop1' ) );
00098                 $this->assertEquals( 'value1', $oneCache->get( 'cache-key', 'prop1' ) );
00099         }
00100 
00101         function testDeleteOldKey() {
00102                 $oneCache = new ProcessCacheLRUTestable( 1 );
00103                 $this->assertCacheEmpty( $oneCache );
00104 
00105                 $oneCache->set( 'cache-key', 'prop1', 'value1' );
00106                 $oneCache->set( 'cache-key', 'prop1', 'value2' );
00107                 $this->assertEquals( 'value2', $oneCache->get( 'cache-key', 'prop1' ) );
00108         }
00109 
00119         function testFillingCache( $cacheMaxEntries, $entryToFill, $msg = '' ) {
00120                 $cache = new ProcessCacheLRUTestable( $cacheMaxEntries );
00121                 $this->fillCache( $cache, $entryToFill );
00122 
00123                 $this->assertSame(
00124                         $this->getExpectedCache( $cacheMaxEntries, $entryToFill ),
00125                         $cache->getCache(),
00126                         "Filling a $cacheMaxEntries entries cache with $entryToFill entries"
00127                 );
00128 
00129         }
00130 
00134         public static function provideCacheFilling() {
00135                 // ($cacheMaxEntries, $entryToFill, $msg='')
00136                 return array(
00137                         array( 1, 0 ),
00138                         array( 1, 1 ),
00139                         array( 1, 2 ), # overflow
00140                         array( 5, 33 ), # overflow
00141                 );
00142         }
00143 
00148         function testReplaceExistingKeyShouldBumpEntryToTop() {
00149                 $maxEntries = 3;
00150 
00151                 $cache = new ProcessCacheLRUTestable( $maxEntries );
00152                 // Fill cache leaving just one remaining slot
00153                 $this->fillCache( $cache, $maxEntries - 1 );
00154 
00155                 // Set an existing cache key
00156                 $cache->set( "cache-key-1", "prop-1", "new-value-for-1" );
00157 
00158                 $this->assertSame(
00159                         array(
00160                                 'cache-key-2' => array( 'prop-2' => 'value-2' ),
00161                                 'cache-key-1' => array( 'prop-1' => 'new-value-for-1' ),
00162                         ),
00163                         $cache->getCache()
00164                 );
00165         }
00166 
00167         function testRecentlyAccessedKeyStickIn() {
00168                 $cache = new ProcessCacheLRUTestable( 2 );
00169                 $cache->set( 'first', 'prop1', 'value1' );
00170                 $cache->set( 'second', 'prop2', 'value2' );
00171 
00172                 // Get first
00173                 $cache->get( 'first', 'prop1' );
00174                 // Cache a third value, should invalidate the least used one
00175                 $cache->set( 'third', 'prop3', 'value3' );
00176 
00177                 $this->assertFalse( $cache->has( 'second', 'prop2' ) );
00178         }
00179 
00186         function testReplaceExistingKeyInAFullCacheShouldBumpToTop() {
00187                 $maxEntries = 3;
00188 
00189                 $cache = new ProcessCacheLRUTestable( $maxEntries );
00190                 $this->fillCache( $cache, $maxEntries );
00191 
00192                 // Set an existing cache key
00193                 $cache->set( "cache-key-2", "prop-2", "new-value-for-2" );
00194                 $this->assertSame(
00195                         array(
00196                                 'cache-key-1' => array( 'prop-1' => 'value-1' ),
00197                                 'cache-key-3' => array( 'prop-3' => 'value-3' ),
00198                                 'cache-key-2' => array( 'prop-2' => 'new-value-for-2' ),
00199                         ),
00200                         $cache->getCache()
00201                 );
00202                 $this->assertEquals( 'new-value-for-2',
00203                         $cache->get( 'cache-key-2', 'prop-2' )
00204                 );
00205         }
00206 
00207         function testBumpExistingKeyToTop() {
00208                 $cache = new ProcessCacheLRUTestable( 3 );
00209                 $this->fillCache( $cache, 3 );
00210 
00211                 // Set the very first cache key to a new value
00212                 $cache->set( "cache-key-1", "prop-1", "new value for 1" );
00213                 $this->assertEquals(
00214                         array(
00215                                 'cache-key-2' => array( 'prop-2' => 'value-2' ),
00216                                 'cache-key-3' => array( 'prop-3' => 'value-3' ),
00217                                 'cache-key-1' => array( 'prop-1' => 'new value for 1' ),
00218                         ),
00219                         $cache->getCache()
00220                 );
00221 
00222         }
00223 
00224 }
00225 
00229 class ProcessCacheLRUTestable extends ProcessCacheLRU {
00230         public $cache = array();
00231 
00232         public function getCache() {
00233                 return $this->cache;
00234         }
00235 
00236         public function getEntriesCount() {
00237                 return count( $this->cache );
00238         }
00239 }