+++ /dev/null
-<?php
-
-namespace Doctrine\Tests\Common\Cache;
-
-use Doctrine\Common\Cache\Cache;
-
-/**
- * @group DCOM-101
- */
-class FileCacheTest extends \Doctrine\Tests\DoctrineTestCase
-{
- /**
- * @var \Doctrine\Common\Cache\FileCache
- */
- private $driver;
-
- protected function setUp()
- {
- $this->driver = $this->getMock(
- 'Doctrine\Common\Cache\FileCache',
- array('doFetch', 'doContains', 'doSave'),
- array(), '', false
- );
- }
-
- public function testFilenameShouldCreateThePathWithOneSubDirectory()
- {
- $cache = $this->driver;
- $method = new \ReflectionMethod($cache, 'getFilename');
- $key = 'item-key';
- $expectedDir = array(
- '84',
- );
- $expectedDir = implode(DIRECTORY_SEPARATOR, $expectedDir);
-
- $method->setAccessible(true);
-
- $path = $method->invoke($cache, $key);
- $dirname = pathinfo($path, PATHINFO_DIRNAME);
-
- $this->assertEquals(DIRECTORY_SEPARATOR . $expectedDir, $dirname);
- }
-
- public function testFileExtensionCorrectlyEscaped()
- {
- $driver1 = $this->getMock(
- 'Doctrine\Common\Cache\FileCache',
- array('doFetch', 'doContains', 'doSave'),
- array(__DIR__, '.*')
- );
- $driver2 = $this->getMock(
- 'Doctrine\Common\Cache\FileCache',
- array('doFetch', 'doContains', 'doSave'),
- array(__DIR__, '.php')
- );
-
- $doGetStats = new \ReflectionMethod($driver1, 'doGetStats');
-
- $doGetStats->setAccessible(true);
-
- $stats1 = $doGetStats->invoke($driver1);
- $stats2 = $doGetStats->invoke($driver2);
-
- $this->assertSame(0, $stats1[Cache::STATS_MEMORY_USAGE]);
- $this->assertGreaterThan(0, $stats2[Cache::STATS_MEMORY_USAGE]);
- }
-
- /**
- * @group DCOM-266
- */
- public function testFileExtensionSlashCorrectlyEscaped()
- {
- $driver = $this->getMock(
- 'Doctrine\Common\Cache\FileCache',
- array('doFetch', 'doContains', 'doSave'),
- array(__DIR__ . '/../', DIRECTORY_SEPARATOR . basename(__FILE__))
- );
-
- $doGetStats = new \ReflectionMethod($driver, 'doGetStats');
-
- $doGetStats->setAccessible(true);
-
- $stats = $doGetStats->invoke($driver);
-
- $this->assertGreaterThan(0, $stats[Cache::STATS_MEMORY_USAGE]);
- }
-
- public function testNonIntUmaskThrowsInvalidArgumentException()
- {
- $this->setExpectedException('InvalidArgumentException');
-
- $this->getMock(
- 'Doctrine\Common\Cache\FileCache',
- array('doFetch', 'doContains', 'doSave'),
- array('', '', 'invalid')
- );
- }
-
- public function testGetDirectoryReturnsRealpathDirectoryString()
- {
- $directory = __DIR__ . '/../';
- $driver = $this->getMock(
- 'Doctrine\Common\Cache\FileCache',
- array('doFetch', 'doContains', 'doSave'),
- array($directory)
- );
-
- $doGetDirectory = new \ReflectionMethod($driver, 'getDirectory');
-
- $actualDirectory = $doGetDirectory->invoke($driver);
- $expectedDirectory = realpath($directory);
-
- $this->assertEquals($expectedDirectory, $actualDirectory);
- }
-
- public function testGetExtensionReturnsExtensionString()
- {
- $directory = __DIR__ . '/../';
- $extension = DIRECTORY_SEPARATOR . basename(__FILE__);
- $driver = $this->getMock(
- 'Doctrine\Common\Cache\FileCache',
- array('doFetch', 'doContains', 'doSave'),
- array($directory, $extension)
- );
-
- $doGetExtension = new \ReflectionMethod($driver, 'getExtension');
-
- $actualExtension = $doGetExtension->invoke($driver);
-
- $this->assertEquals($extension, $actualExtension);
- }
-
- const WIN_MAX_PATH_LEN = 258;
-
- public static function getBasePathForWindowsPathLengthTests($pathLength)
- {
- // Not using __DIR__ because it can get screwed up when xdebug debugger is attached.
- $basePath = realpath(sys_get_temp_dir()) . '/' . uniqid('doctrine-cache', true);
-
- /** @noinspection MkdirRaceConditionInspection */
- @mkdir($basePath);
-
- $basePath = realpath($basePath);
-
- // Test whether the desired path length is odd or even.
- $desiredPathLengthIsOdd = ($pathLength % 2) == 1;
-
- // If the cache key is not too long, the filecache codepath will add
- // a slash and bin2hex($key). The length of the added portion will be an odd number.
- // len(desired) = len(base path) + len(slash . bin2hex($key))
- // odd = even + odd
- // even = odd + odd
- $basePathLengthShouldBeOdd = !$desiredPathLengthIsOdd;
-
- $basePathLengthIsOdd = (strlen($basePath) % 2) == 1;
-
- // If the base path needs to be odd or even where it is not, we add an odd number of
- // characters as a pad. In this case, we're adding '\aa' (or '/aa' depending on platform)
- // This is all to make it so that the key we're testing would result in
- // a path that is exactly the length we want to test IF the path length limit
- // were not in place in FileCache.
- if ($basePathLengthIsOdd != $basePathLengthShouldBeOdd) {
- $basePath .= DIRECTORY_SEPARATOR . "aa";
- }
-
- return $basePath;
- }
-
- /**
- * @param int $length
- * @param string $basePath
- *
- * @return array
- */
- public static function getKeyAndPathFittingLength($length, $basePath)
- {
- $baseDirLength = strlen($basePath);
- $extensionLength = strlen('.doctrine.cache');
- $directoryLength = strlen(DIRECTORY_SEPARATOR . 'aa' . DIRECTORY_SEPARATOR);
- $keyLength = $length - ($baseDirLength + $extensionLength + $directoryLength); // - 1 because of slash
-
- $key = str_repeat('a', floor($keyLength / 2));
-
- $keyHash = hash('sha256', $key);
-
- $keyPath = $basePath
- . DIRECTORY_SEPARATOR
- . substr($keyHash, 0, 2)
- . DIRECTORY_SEPARATOR
- . bin2hex($key)
- . '.doctrine.cache';
-
- $hashedKeyPath = $basePath
- . DIRECTORY_SEPARATOR
- . substr($keyHash, 0, 2)
- . DIRECTORY_SEPARATOR
- . '_' . $keyHash
- . '.doctrine.cache';
-
- return array($key, $keyPath, $hashedKeyPath);
- }
-
- public function getPathLengthsToTest()
- {
- // 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)
- );
- }
-
- /**
- * @runInSeparateProcess
- * @dataProvider getPathLengthsToTest
- *
- * @covers \Doctrine\Common\Cache\FileCache::getFilename
- *
- * @param int $length
- * @param bool $pathShouldBeHashed
- */
- public function testWindowsPathLengthLimitationsAreCorrectlyRespected($length, $pathShouldBeHashed)
- {
- if (! defined('PHP_WINDOWS_VERSION_BUILD')) {
- define('PHP_WINDOWS_VERSION_BUILD', 'Yes, this is the "usual suspect", with the usual limitations');
- }
-
- $basePath = self::getBasePathForWindowsPathLengthTests($length);
-
- $fileCache = $this->getMockForAbstractClass(
- 'Doctrine\Common\Cache\FileCache',
- array($basePath, '.doctrine.cache')
- );
-
- list($key, $keyPath, $hashedKeyPath) = self::getKeyAndPathFittingLength($length, $basePath);
-
- $getFileName = new \ReflectionMethod($fileCache, 'getFilename');
-
- $getFileName->setAccessible(true);
-
- $this->assertEquals(
- $length,
- strlen($keyPath),
- sprintf('Path expected to be %d characters long is %d characters long', $length, strlen($keyPath))
- );
-
- if ($pathShouldBeHashed) {
- $keyPath = $hashedKeyPath;
- }
-
- if ($pathShouldBeHashed) {
- $this->assertSame(
- $hashedKeyPath,
- $getFileName->invoke($fileCache, $key),
- 'Keys should be hashed correctly if they are over the limit.'
- );
- } else {
- $this->assertSame(
- $keyPath,
- $getFileName->invoke($fileCache, $key),
- 'Keys below limit of the allowed length are used directly, unhashed'
- );
- }
- }
-}