Changeset View
Changeset View
Standalone View
Standalone View
src/infrastructure/cache/__tests__/PhutilKeyValueCacheTestCase.php
- This file was added.
| <?php | |||||
| final class PhutilKeyValueCacheTestCase extends PhutilTestCase { | |||||
| public function testInRequestCache() { | |||||
| $cache = new PhutilInRequestKeyValueCache(); | |||||
| $this->doCacheTest($cache); | |||||
| $cache->destroyCache(); | |||||
| } | |||||
| public function testInRequestCacheLimit() { | |||||
| $cache = new PhutilInRequestKeyValueCache(); | |||||
| $cache->setLimit(4); | |||||
| $cache->setKey(1, 1); | |||||
| $cache->setKey(2, 2); | |||||
| $cache->setKey(3, 3); | |||||
| $cache->setKey(4, 4); | |||||
| $this->assertEqual( | |||||
| array( | |||||
| 1 => 1, | |||||
| 2 => 2, | |||||
| 3 => 3, | |||||
| 4 => 4, | |||||
| ), | |||||
| $cache->getAllKeys()); | |||||
| $cache->setKey(5, 5); | |||||
| $this->assertEqual( | |||||
| array( | |||||
| 2 => 2, | |||||
| 3 => 3, | |||||
| 4 => 4, | |||||
| 5 => 5, | |||||
| ), | |||||
| $cache->getAllKeys()); | |||||
| } | |||||
| public function testOnDiskCache() { | |||||
| $cache = new PhutilOnDiskKeyValueCache(); | |||||
| $cache->setCacheFile(new TempFile()); | |||||
| $this->doCacheTest($cache); | |||||
| $cache->destroyCache(); | |||||
| } | |||||
| public function testAPCCache() { | |||||
| $cache = new PhutilAPCKeyValueCache(); | |||||
| if (!$cache->isAvailable()) { | |||||
| $this->assertSkipped(pht('Cache not available.')); | |||||
| } | |||||
| $this->doCacheTest($cache); | |||||
| } | |||||
| public function testDirectoryCache() { | |||||
| $cache = new PhutilDirectoryKeyValueCache(); | |||||
| $dir = Filesystem::createTemporaryDirectory(); | |||||
| $cache->setCacheDirectory($dir); | |||||
| $this->doCacheTest($cache); | |||||
| $cache->destroyCache(); | |||||
| } | |||||
| public function testDirectoryCacheSpecialDirectoryRules() { | |||||
| $cache = new PhutilDirectoryKeyValueCache(); | |||||
| $dir = Filesystem::createTemporaryDirectory(); | |||||
| $dir = $dir.'/dircache/'; | |||||
| $cache->setCacheDirectory($dir); | |||||
| $cache->setKey('a', 1); | |||||
| $this->assertEqual(true, Filesystem::pathExists($dir.'/a.cache')); | |||||
| $cache->setKey('a/b', 1); | |||||
| $this->assertEqual(true, Filesystem::pathExists($dir.'/a/')); | |||||
| $this->assertEqual(true, Filesystem::pathExists($dir.'/a/b.cache')); | |||||
| $cache->deleteKey('a/b'); | |||||
| $this->assertEqual(false, Filesystem::pathExists($dir.'/a/')); | |||||
| $this->assertEqual(false, Filesystem::pathExists($dir.'/a/b.cache')); | |||||
| $cache->destroyCache(); | |||||
| $this->assertEqual(false, Filesystem::pathExists($dir)); | |||||
| } | |||||
| public function testNamespaceCache() { | |||||
| $namespace = 'namespace'.mt_rand(); | |||||
| $in_request_cache = new PhutilInRequestKeyValueCache(); | |||||
| $cache = new PhutilKeyValueCacheNamespace($in_request_cache); | |||||
| $cache->setNamespace($namespace); | |||||
| $test_info = get_class($cache); | |||||
| $keys = array( | |||||
| 'key1' => mt_rand(), | |||||
| 'key2' => '', | |||||
| 'key3' => 'Phabricator', | |||||
| ); | |||||
| $cache->setKeys($keys); | |||||
| $cached_keys = $in_request_cache->getAllKeys(); | |||||
| foreach ($keys as $key => $value) { | |||||
| $cached_key = $namespace.':'.$key; | |||||
| $this->assertTrue( | |||||
| isset($cached_keys[$cached_key]), | |||||
| $test_info); | |||||
| $this->assertEqual( | |||||
| $value, | |||||
| $cached_keys[$cached_key], | |||||
| $test_info); | |||||
| } | |||||
| $cache->destroyCache(); | |||||
| $this->doCacheTest($cache); | |||||
| $cache->destroyCache(); | |||||
| } | |||||
| public function testCacheStack() { | |||||
| $req_cache = new PhutilInRequestKeyValueCache(); | |||||
| $disk_cache = new PhutilOnDiskKeyValueCache(); | |||||
| $disk_cache->setCacheFile(new TempFile()); | |||||
| $apc_cache = new PhutilAPCKeyValueCache(); | |||||
| $stack = array( | |||||
| $req_cache, | |||||
| $disk_cache, | |||||
| ); | |||||
| if ($apc_cache->isAvailable()) { | |||||
| $stack[] = $apc_cache; | |||||
| } | |||||
| $cache = new PhutilKeyValueCacheStack(); | |||||
| $cache->setCaches($stack); | |||||
| $this->doCacheTest($cache); | |||||
| $disk_cache->destroyCache(); | |||||
| $req_cache->destroyCache(); | |||||
| } | |||||
| private function doCacheTest(PhutilKeyValueCache $cache) { | |||||
| $key1 = 'test:'.mt_rand(); | |||||
| $key2 = 'test:'.mt_rand(); | |||||
| $default = 'cache-miss'; | |||||
| $value1 = 'cache-hit1'; | |||||
| $value2 = 'cache-hit2'; | |||||
| $test_info = get_class($cache); | |||||
| // Test that we miss correctly on missing values. | |||||
| $this->assertEqual( | |||||
| $default, | |||||
| $cache->getKey($key1, $default), | |||||
| $test_info); | |||||
| $this->assertEqual( | |||||
| array( | |||||
| ), | |||||
| $cache->getKeys(array($key1, $key2)), | |||||
| $test_info); | |||||
| // Test that we can set individual keys. | |||||
| $cache->setKey($key1, $value1); | |||||
| $this->assertEqual( | |||||
| $value1, | |||||
| $cache->getKey($key1, $default), | |||||
| $test_info); | |||||
| $this->assertEqual( | |||||
| array( | |||||
| $key1 => $value1, | |||||
| ), | |||||
| $cache->getKeys(array($key1, $key2)), | |||||
| $test_info); | |||||
| // Test that we can delete individual keys. | |||||
| $cache->deleteKey($key1); | |||||
| $this->assertEqual( | |||||
| $default, | |||||
| $cache->getKey($key1, $default), | |||||
| $test_info); | |||||
| $this->assertEqual( | |||||
| array( | |||||
| ), | |||||
| $cache->getKeys(array($key1, $key2)), | |||||
| $test_info); | |||||
| // Test that we can set multiple keys. | |||||
| $cache->setKeys( | |||||
| array( | |||||
| $key1 => $value1, | |||||
| $key2 => $value2, | |||||
| )); | |||||
| $this->assertEqual( | |||||
| $value1, | |||||
| $cache->getKey($key1, $default), | |||||
| $test_info); | |||||
| $this->assertEqual( | |||||
| array( | |||||
| $key1 => $value1, | |||||
| $key2 => $value2, | |||||
| ), | |||||
| $cache->getKeys(array($key1, $key2)), | |||||
| $test_info); | |||||
| // Test that we can delete multiple keys. | |||||
| $cache->deleteKeys(array($key1, $key2)); | |||||
| $this->assertEqual( | |||||
| $default, | |||||
| $cache->getKey($key1, $default), | |||||
| $test_info); | |||||
| $this->assertEqual( | |||||
| array( | |||||
| ), | |||||
| $cache->getKeys(array($key1, $key2)), | |||||
| $test_info); | |||||
| // NOTE: The TTL tests are necessarily slow (we must sleep() through the | |||||
| // TTLs) and do not work with APC (it does not TTL until the next request) | |||||
| // so they're disabled by default. If you're developing the cache stack, | |||||
| // it may be useful to run them. | |||||
| return; | |||||
| // Test that keys expire when they TTL. | |||||
| $cache->setKey($key1, $value1, 1); | |||||
| $cache->setKey($key2, $value2, 5); | |||||
| $this->assertEqual($value1, $cache->getKey($key1, $default)); | |||||
| $this->assertEqual($value2, $cache->getKey($key2, $default)); | |||||
| sleep(2); | |||||
| $this->assertEqual($default, $cache->getKey($key1, $default)); | |||||
| $this->assertEqual($value2, $cache->getKey($key2, $default)); | |||||
| // Test that setting a 0 TTL overwrites a nonzero TTL. | |||||
| $cache->setKey($key1, $value1, 1); | |||||
| $this->assertEqual($value1, $cache->getKey($key1, $default)); | |||||
| $cache->setKey($key1, $value1, 0); | |||||
| $this->assertEqual($value1, $cache->getKey($key1, $default)); | |||||
| sleep(2); | |||||
| $this->assertEqual($value1, $cache->getKey($key1, $default)); | |||||
| } | |||||
| } | |||||