3 namespace Doctrine\Tests\Common\Cache;
5 use Doctrine\Common\Cache\FileCache;
6 use RecursiveDirectoryIterator;
7 use RecursiveIteratorIterator;
9 abstract class BaseFileCacheTest extends CacheTest
13 protected function setUp()
16 $this->directory = sys_get_temp_dir() . '/doctrine_cache_'. uniqid();
17 } while (file_exists($this->directory));
20 protected function tearDown()
22 if ( ! is_dir($this->directory)) {
26 $iterator = new RecursiveDirectoryIterator($this->directory);
28 foreach (new RecursiveIteratorIterator($iterator, RecursiveIteratorIterator::CHILD_FIRST) as $file) {
29 if ($file->isFile()) {
30 @unlink($file->getRealPath());
31 } elseif ($file->isDir()) {
32 @rmdir($file->getRealPath());
36 @rmdir($this->directory);
39 public function testFlushAllRemovesBalancingDirectories()
41 $cache = $this->_getCacheDriver();
43 $this->assertTrue($cache->save('key1', 1));
44 $this->assertTrue($cache->save('key2', 2));
45 $this->assertTrue($cache->flushAll());
47 $iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->directory, \FilesystemIterator::SKIP_DOTS), \RecursiveIteratorIterator::CHILD_FIRST);
49 $this->assertCount(0, $iterator);
52 protected function isSharedStorage()
57 public function getPathLengthsToTest()
59 // Windows officially supports 260 bytes including null terminator
60 // 258 bytes available to use due to php bug #70943
61 // Windows officially supports 260 bytes including null terminator
62 // 259 characters is too large due to PHP bug (https://bugs.php.net/bug.php?id=70943)
63 // 260 characters is too large - null terminator is included in allowable length
72 private static function getBasePathForWindowsPathLengthTests($pathLength)
74 return FileCacheTest::getBasePathForWindowsPathLengthTests($pathLength);
79 * @param string $basePath
83 private static function getKeyAndPathFittingLength($length, $basePath)
85 $baseDirLength = strlen($basePath);
86 $extensionLength = strlen('.doctrine.cache');
87 $directoryLength = strlen(DIRECTORY_SEPARATOR . 'aa' . DIRECTORY_SEPARATOR);
88 $namespaceAndBracketLength = strlen(bin2hex("[][1]"));
93 + $namespaceAndBracketLength);
95 $key = str_repeat('a', floor($keyLength / 2));
96 $namespacedKey = '[' . $key . '][1]';
98 $keyHash = hash('sha256', $namespacedKey);
101 . DIRECTORY_SEPARATOR
102 . substr($keyHash, 0, 2)
103 . DIRECTORY_SEPARATOR
104 . bin2hex($namespacedKey)
107 $hashedKeyPath = $basePath
108 . DIRECTORY_SEPARATOR
109 . substr($keyHash, 0, 2)
110 . DIRECTORY_SEPARATOR
114 return array($key, $keyPath, $hashedKeyPath);
118 * @dataProvider getPathLengthsToTest
121 * @param bool $pathShouldBeHashed
123 public function testWindowsPathLengthLimitIsCorrectlyHandled($length, $pathShouldBeHashed)
125 $this->directory = self::getBasePathForWindowsPathLengthTests($length);
127 list($key, $keyPath, $hashedKeyPath) = self::getKeyAndPathFittingLength($length, $this->directory);
129 $this->assertEquals($length, strlen($keyPath), 'Unhashed path should be of correct length.');
131 $cacheClass = get_class($this->_getCacheDriver());
132 /* @var $cache \Doctrine\Common\Cache\FileCache */
133 $cache = new $cacheClass($this->directory, '.doctrine.cache');
135 // Trick it into thinking this is windows.
136 $reflClass = new \ReflectionClass(FileCache::class);
137 $reflProp = $reflClass->getProperty('isRunningOnWindows');
138 $reflProp->setAccessible(true);
139 $reflProp->setValue($cache, true);
140 $reflProp->setAccessible(false);
142 $value = uniqid('value', true);
144 $cache->save($key, $value);
145 $this->assertEquals($value, $cache->fetch($key));
147 if ($pathShouldBeHashed) {
148 $this->assertFileExists($hashedKeyPath, 'Path generated for key should be hashed.');
149 unlink($hashedKeyPath);
151 $this->assertFileExists($keyPath, 'Path generated for key should not be hashed.');