directory = sys_get_temp_dir() . '/doctrine_cache_'. uniqid(); } while (file_exists($this->directory)); } protected function tearDown() { if ( ! is_dir($this->directory)) { return; } $iterator = new RecursiveDirectoryIterator($this->directory); foreach (new RecursiveIteratorIterator($iterator, RecursiveIteratorIterator::CHILD_FIRST) as $file) { if ($file->isFile()) { @unlink($file->getRealPath()); } elseif ($file->isDir()) { @rmdir($file->getRealPath()); } } @rmdir($this->directory); } public function testFlushAllRemovesBalancingDirectories() { $cache = $this->_getCacheDriver(); $this->assertTrue($cache->save('key1', 1)); $this->assertTrue($cache->save('key2', 2)); $this->assertTrue($cache->flushAll()); $iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->directory, \FilesystemIterator::SKIP_DOTS), \RecursiveIteratorIterator::CHILD_FIRST); $this->assertCount(0, $iterator); } protected function isSharedStorage() { return false; } public function getPathLengthsToTest() { // Windows officially supports 260 bytes including null terminator // 258 bytes available to use due to php bug #70943 // Windows officially supports 260 bytes including null terminator // 259 characters is too large due to PHP bug (https://bugs.php.net/bug.php?id=70943) // 260 characters is too large - null terminator is included in allowable length return array( array(257, false), array(258, false), array(259, true), array(260, true) ); } private static function getBasePathForWindowsPathLengthTests($pathLength) { return FileCacheTest::getBasePathForWindowsPathLengthTests($pathLength); } /** * @param int $length * @param string $basePath * * @return array */ private static function getKeyAndPathFittingLength($length, $basePath) { $baseDirLength = strlen($basePath); $extensionLength = strlen('.doctrine.cache'); $directoryLength = strlen(DIRECTORY_SEPARATOR . 'aa' . DIRECTORY_SEPARATOR); $namespaceAndBracketLength = strlen(bin2hex("[][1]")); $keyLength = $length - ($baseDirLength + $extensionLength + $directoryLength + $namespaceAndBracketLength); $key = str_repeat('a', floor($keyLength / 2)); $namespacedKey = '[' . $key . '][1]'; $keyHash = hash('sha256', $namespacedKey); $keyPath = $basePath . DIRECTORY_SEPARATOR . substr($keyHash, 0, 2) . DIRECTORY_SEPARATOR . bin2hex($namespacedKey) . '.doctrine.cache'; $hashedKeyPath = $basePath . DIRECTORY_SEPARATOR . substr($keyHash, 0, 2) . DIRECTORY_SEPARATOR . '_' . $keyHash . '.doctrine.cache'; return array($key, $keyPath, $hashedKeyPath); } /** * @dataProvider getPathLengthsToTest * * @param int $length * @param bool $pathShouldBeHashed */ public function testWindowsPathLengthLimitIsCorrectlyHandled($length, $pathShouldBeHashed) { $this->directory = self::getBasePathForWindowsPathLengthTests($length); list($key, $keyPath, $hashedKeyPath) = self::getKeyAndPathFittingLength($length, $this->directory); $this->assertEquals($length, strlen($keyPath), 'Unhashed path should be of correct length.'); $cacheClass = get_class($this->_getCacheDriver()); /* @var $cache \Doctrine\Common\Cache\FileCache */ $cache = new $cacheClass($this->directory, '.doctrine.cache'); // Trick it into thinking this is windows. $reflClass = new \ReflectionClass(FileCache::class); $reflProp = $reflClass->getProperty('isRunningOnWindows'); $reflProp->setAccessible(true); $reflProp->setValue($cache, true); $reflProp->setAccessible(false); $value = uniqid('value', true); $cache->save($key, $value); $this->assertEquals($value, $cache->fetch($key)); if ($pathShouldBeHashed) { $this->assertFileExists($hashedKeyPath, 'Path generated for key should be hashed.'); unlink($hashedKeyPath); } else { $this->assertFileExists($keyPath, 'Path generated for key should not be hashed.'); unlink($keyPath); } } }