Merge "Update cached user ID after user is added to the database"
[lhc/web/wiklou.git] / tests / phpunit / includes / libs / objectcache / WANObjectCacheTest.php
index 54393a7..b301f28 100644 (file)
@@ -26,7 +26,7 @@ class WANObjectCacheTest extends MediaWikiTestCase {
        }
 
        /**
-        * @dataProvider provider_testSetAndGet
+        * @dataProvider provideSetAndGet
         * @covers WANObjectCache::set()
         * @covers WANObjectCache::get()
         * @param mixed $value
@@ -46,7 +46,7 @@ class WANObjectCacheTest extends MediaWikiTestCase {
                }
        }
 
-       public static function provider_testSetAndGet() {
+       public static function provideSetAndGet() {
                return array(
                        array( 14141, 3 ),
                        array( 3535.666, 3 ),
@@ -60,6 +60,9 @@ class WANObjectCacheTest extends MediaWikiTestCase {
                );
        }
 
+       /**
+        * @covers WANObjectCache::get()
+        */
        public function testGetNotExists() {
                $key = wfRandomString();
                $curTTL = null;
@@ -69,6 +72,9 @@ class WANObjectCacheTest extends MediaWikiTestCase {
                $this->assertNull( $curTTL, "Non-existing key has null current TTL" );
        }
 
+       /**
+        * @covers WANObjectCache::set()
+        */
        public function testSetOver() {
                $key = wfRandomString();
                for ( $i = 0; $i < 3; ++$i ) {
@@ -79,6 +85,9 @@ class WANObjectCacheTest extends MediaWikiTestCase {
                }
        }
 
+       /**
+        * @covers WANObjectCache::set()
+        */
        public function testStaleSet() {
                $key = wfRandomString();
                $value = wfRandomString();
@@ -89,6 +98,7 @@ class WANObjectCacheTest extends MediaWikiTestCase {
 
        /**
         * @covers WANObjectCache::getWithSetCallback()
+        * @covers WANObjectCache::doGetWithSetCallback()
         */
        public function testGetWithSetCallback() {
                $cache = $this->cache;
@@ -163,6 +173,7 @@ class WANObjectCacheTest extends MediaWikiTestCase {
 
        /**
         * @covers WANObjectCache::getWithSetCallback()
+        * @covers WANObjectCache::doGetWithSetCallback()
         */
        public function testLockTSE() {
                $cache = $this->cache;
@@ -175,7 +186,6 @@ class WANObjectCacheTest extends MediaWikiTestCase {
                        return $value;
                };
 
-               $cache->delete( $key );
                $ret = $cache->getWithSetCallback( $key, 30, $func, array( 'lockTSE' => 5 ) );
                $this->assertEquals( $value, $ret );
                $this->assertEquals( 1, $calls, 'Value was populated' );
@@ -187,6 +197,37 @@ class WANObjectCacheTest extends MediaWikiTestCase {
                $this->assertEquals( 1, $calls, 'Callback was not used' );
        }
 
+       /**
+        * @covers WANObjectCache::getWithSetCallback()
+        * @covers WANObjectCache::doGetWithSetCallback()
+        */
+       public function testLockTSESlow() {
+               $cache = $this->cache;
+               $key = wfRandomString();
+               $value = wfRandomString();
+
+               $calls = 0;
+               $func = function( $oldValue, &$ttl, &$setOpts ) use ( &$calls, $value ) {
+                       ++$calls;
+                       $setOpts['since'] = microtime( true ) - 10;
+                       return $value;
+               };
+
+               // Value should be marked as stale due to snapshot lag
+               $curTTL = null;
+               $ret = $cache->getWithSetCallback( $key, 30, $func, array( 'lockTSE' => 5 ) );
+               $this->assertEquals( $value, $ret );
+               $this->assertEquals( $value, $cache->get( $key, $curTTL ), 'Value was populated' );
+               $this->assertLessThan( 0, $curTTL, 'Value has negative curTTL' );
+               $this->assertEquals( 1, $calls, 'Value was generated' );
+
+               // Acquire a lock to verify that getWithSetCallback uses lockTSE properly
+               $this->internalCache->lock( $key, 0 );
+               $ret = $cache->getWithSetCallback( $key, 30, $func, array( 'lockTSE' => 5 ) );
+               $this->assertEquals( $value, $ret );
+               $this->assertEquals( 1, $calls, 'Callback was not used' );
+       }
+
        /**
         * @covers WANObjectCache::getMulti()
         */
@@ -250,6 +291,85 @@ class WANObjectCacheTest extends MediaWikiTestCase {
                $this->assertLessThan( 0, $curTTLs[$key2], 'Key 2 has negative current TTL' );
        }
 
+       /**
+        * @covers WANObjectCache::getMulti()
+        * @covers WANObjectCache::processCheckKeys()
+        */
+       public function testGetMultiCheckKeys() {
+               $cache = $this->cache;
+
+               $checkAll = wfRandomString();
+               $check1 = wfRandomString();
+               $check2 = wfRandomString();
+               $check3 = wfRandomString();
+               $value1 = wfRandomString();
+               $value2 = wfRandomString();
+
+               // 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.
+               foreach ( array( $checkAll, $check1, $check2 ) as $checkKey ) {
+                       $this->internalCache->set( $cache::TIME_KEY_PREFIX . $checkKey,
+                               $cache::PURGE_VAL_PREFIX . microtime( true ) - $cache::HOLDOFF_TTL, $cache::CHECK_KEY_TTL );
+               }
+
+               $cache->set( 'key1', $value1, 10 );
+               $cache->set( 'key2', $value2, 10 );
+
+               $curTTLs = array();
+               $result = $cache->getMulti( array( 'key1', 'key2', 'key3' ), $curTTLs, array(
+                       'key1' => $check1,
+                       $checkAll,
+                       'key2' => $check2,
+                       'key3' => $check3,
+               ) );
+               $this->assertEquals(
+                       array( 'key1' => $value1, 'key2' => $value2 ),
+                       $result,
+                       'Initial values'
+               );
+               $this->assertEquals(
+                       array( 'key1' => 0, 'key2' => 0 ),
+                       $curTTLs,
+                       'Initial ttls'
+               );
+
+               $cache->touchCheckKey( $check1 );
+               usleep( 100 );
+
+               $curTTLs = array();
+               $result = $cache->getMulti( array( 'key1', 'key2', 'key3' ), $curTTLs, array(
+                       'key1' => $check1,
+                       $checkAll,
+                       'key2' => $check2,
+                       'key3' => $check3,
+               ) );
+               $this->assertEquals(
+                       array( 'key1' => $value1, 'key2' => $value2 ),
+                       $result,
+                       'key1 expired by check1, but value still provided'
+               );
+               $this->assertLessThan( 0, $curTTLs['key1'], 'key1 TTL expired' );
+               $this->assertEquals( 0, $curTTLs['key2'], 'key2 still valid' );
+
+               $cache->touchCheckKey( $checkAll );
+               usleep( 100 );
+
+               $curTTLs = array();
+               $result = $cache->getMulti( array( 'key1', 'key2', 'key3' ), $curTTLs, array(
+                       'key1' => $check1,
+                       $checkAll,
+                       'key2' => $check2,
+                       'key3' => $check3,
+               ) );
+               $this->assertEquals(
+                       array( 'key1' => $value1, 'key2' => $value2 ),
+                       $result,
+                       'All keys expired by checkAll, but value still provided'
+               );
+               $this->assertLessThan( 0, $curTTLs['key1'], 'key1 expired by checkAll' );
+               $this->assertLessThan( 0, $curTTLs['key2'], 'key2 expired by checkAll' );
+       }
+
        /**
         * @covers WANObjectCache::delete()
         */
@@ -314,6 +434,40 @@ class WANObjectCacheTest extends MediaWikiTestCase {
                $this->assertEquals( $t5, $t6, 'Check key time did not change' );
        }
 
+       /**
+        * @covers WANObjectCache::getMulti()
+        */
+       public function testGetWithSeveralCheckKeys() {
+               $key = wfRandomString();
+               $tKey1 = wfRandomString();
+               $tKey2 = wfRandomString();
+               $value = 'meow';
+
+               // Two check keys are newer (given hold-off) than $key, another is older
+               $this->internalCache->set(
+                       WANObjectCache::TIME_KEY_PREFIX . $tKey2,
+                       WANObjectCache::PURGE_VAL_PREFIX . ( microtime( true ) - 3 )
+               );
+               $this->internalCache->set(
+                       WANObjectCache::TIME_KEY_PREFIX . $tKey2,
+                       WANObjectCache::PURGE_VAL_PREFIX . ( microtime( true ) - 5 )
+               );
+               $this->internalCache->set(
+                       WANObjectCache::TIME_KEY_PREFIX . $tKey1,
+                       WANObjectCache::PURGE_VAL_PREFIX . ( microtime( true ) - 30 )
+               );
+               $this->cache->set( $key, $value, 30 );
+
+               $curTTL = null;
+               $v = $this->cache->get( $key, $curTTL, array( $tKey1, $tKey2 ) );
+               $this->assertEquals( $value, $v, "Value matches" );
+               $this->assertLessThan( -5, $curTTL, "Correct CTL" );
+               $this->assertGreaterThan( -5.1, $curTTL, "Correct CTL" );
+       }
+
+       /**
+        * @covers WANObjectCache::set()
+        */
        public function testSetWithLag() {
                $value = 1;
 
@@ -333,6 +487,9 @@ class WANObjectCacheTest extends MediaWikiTestCase {
                $this->assertEquals( false, $this->cache->get( $key ), "Lagged value not written." );
        }
 
+       /**
+        * @covers WANObjectCache::set()
+        */
        public function testWritePending() {
                $value = 1;