PageRenderTime 46ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 1ms

/tests/ZendTest/Cache/Storage/Adapter/FilesystemTest.php

https://bitbucket.org/gencer/zf2
PHP | 327 lines | 258 code | 54 blank | 15 comment | 23 complexity | f817c33c7b6cf3bf6a14ab85a7c3ce7b MD5 | raw file
  1. <?php
  2. /**
  3. * Zend Framework (http://framework.zend.com/)
  4. *
  5. * @link http://github.com/zendframework/zf2 for the canonical source repository
  6. * @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
  7. * @license http://framework.zend.com/license/new-bsd New BSD License
  8. */
  9. namespace ZendTest\Cache\Storage\Adapter;
  10. use Zend\Cache;
  11. use Zend\Cache\Storage\Plugin\ExceptionHandler;
  12. use Zend\Cache\Storage\Plugin\PluginOptions;
  13. /**
  14. * @group Zend_Cache
  15. */
  16. class FilesystemTest extends CommonAdapterTest
  17. {
  18. protected $_tmpCacheDir;
  19. protected $_umask;
  20. public function setUp()
  21. {
  22. $this->_umask = umask();
  23. $this->_tmpCacheDir = @tempnam(sys_get_temp_dir(), 'zend_cache_test_');
  24. if (!$this->_tmpCacheDir) {
  25. $err = error_get_last();
  26. $this->fail("Can't create temporary cache directory-file: {$err['message']}");
  27. } elseif (!@unlink($this->_tmpCacheDir)) {
  28. $err = error_get_last();
  29. $this->fail("Can't remove temporary cache directory-file: {$err['message']}");
  30. } elseif (!@mkdir($this->_tmpCacheDir, 0777)) {
  31. $err = error_get_last();
  32. $this->fail("Can't create temporary cache directory: {$err['message']}");
  33. }
  34. $this->_options = new Cache\Storage\Adapter\FilesystemOptions(array(
  35. 'cache_dir' => $this->_tmpCacheDir,
  36. ));
  37. $this->_storage = new Cache\Storage\Adapter\Filesystem();
  38. $this->_storage->setOptions($this->_options);
  39. parent::setUp();
  40. }
  41. public function tearDown()
  42. {
  43. $this->_removeRecursive($this->_tmpCacheDir);
  44. if ($this->_umask != umask()) {
  45. umask($this->_umask);
  46. $this->fail("Umask wasn't reset");
  47. }
  48. parent::tearDown();
  49. }
  50. protected function _removeRecursive($dir)
  51. {
  52. if (file_exists($dir)) {
  53. $dirIt = new \DirectoryIterator($dir);
  54. foreach ($dirIt as $entry) {
  55. $fname = $entry->getFilename();
  56. if ($fname == '.' || $fname == '..') {
  57. continue;
  58. }
  59. if ($entry->isFile()) {
  60. unlink($entry->getPathname());
  61. } else {
  62. $this->_removeRecursive($entry->getPathname());
  63. }
  64. }
  65. rmdir($dir);
  66. }
  67. }
  68. public function testNormalizeCacheDir()
  69. {
  70. $cacheDir = $cacheDirExpected = realpath(sys_get_temp_dir());
  71. if (DIRECTORY_SEPARATOR != '/') {
  72. $cacheDir = str_replace(DIRECTORY_SEPARATOR, '/', $cacheDir);
  73. }
  74. $firstSlash = strpos($cacheDir, '/');
  75. $cacheDir = substr($cacheDir, 0, $firstSlash + 1)
  76. . '..//../'
  77. . substr($cacheDir, $firstSlash)
  78. . '///';
  79. $this->_options->setCacheDir($cacheDir);
  80. $cacheDir = $this->_options->getCacheDir();
  81. $this->assertEquals($cacheDirExpected, $cacheDir);
  82. }
  83. public function testSetCacheDirToSystemsTempDirWithNull()
  84. {
  85. $this->_options->setCacheDir(null);
  86. $this->assertEquals(sys_get_temp_dir(), $this->_options->getCacheDir());
  87. }
  88. public function testSetCacheDirNoDirectoryException()
  89. {
  90. $this->setExpectedException('Zend\Cache\Exception\InvalidArgumentException');
  91. $this->_options->setCacheDir(__FILE__);
  92. }
  93. public function testSetCacheDirNotWritableException()
  94. {
  95. if (substr(PHP_OS, 0, 3) == 'WIN') {
  96. $this->markTestSkipped("Not testable on windows");
  97. } else {
  98. @exec('whoami 2>&1', $out, $ret);
  99. if ($ret) {
  100. $err = error_get_last();
  101. $this->markTestSkipped("Not testable: {$err['message']}");
  102. } elseif (isset($out[0]) && $out[0] == 'root') {
  103. $this->markTestSkipped("Not testable as root");
  104. }
  105. }
  106. $this->setExpectedException('Zend\Cache\Exception\InvalidArgumentException');
  107. // create a not writable temporaty directory
  108. $testDir = tempnam(sys_get_temp_dir(), 'ZendTest');
  109. unlink($testDir); mkdir($testDir); chmod($testDir, 0557);
  110. try {
  111. $this->_options->setCacheDir($testDir);
  112. } catch (\Exception $e) {
  113. rmdir($testDir);
  114. throw $e;
  115. }
  116. }
  117. public function testSetCacheDirNotReadableException()
  118. {
  119. if (substr(PHP_OS, 0, 3) == 'WIN') {
  120. $this->markTestSkipped("Not testable on windows");
  121. } else {
  122. @exec('whoami 2>&1', $out, $ret);
  123. if ($ret) {
  124. $this->markTestSkipped("Not testable: " . implode("\n", $out));
  125. } elseif (isset($out[0]) && $out[0] == 'root') {
  126. $this->markTestSkipped("Not testable as root");
  127. }
  128. }
  129. $this->setExpectedException('Zend\Cache\Exception\InvalidArgumentException');
  130. // create a not readable temporaty directory
  131. $testDir = tempnam(sys_get_temp_dir(), 'ZendTest');
  132. unlink($testDir); mkdir($testDir); chmod($testDir, 0337);
  133. try {
  134. $this->_options->setCacheDir($testDir);
  135. } catch (\Exception $e) {
  136. rmdir($testDir);
  137. throw $e;
  138. }
  139. }
  140. public function testSetFilePermissionThrowsExceptionIfNotWritable()
  141. {
  142. $this->setExpectedException('Zend\Cache\Exception\InvalidArgumentException');
  143. $this->_options->setFilePermission(0466);
  144. }
  145. public function testSetFilePermissionThrowsExceptionIfNotReadable()
  146. {
  147. $this->setExpectedException('Zend\Cache\Exception\InvalidArgumentException');
  148. $this->_options->setFilePermission(0266);
  149. }
  150. public function testSetFilePermissionThrowsExceptionIfExecutable()
  151. {
  152. $this->setExpectedException('Zend\Cache\Exception\InvalidArgumentException');
  153. $this->_options->setFilePermission(0661);
  154. }
  155. public function testSetNoAtimeChangesAtimeOfMetadataCapability()
  156. {
  157. $capabilities = $this->_storage->getCapabilities();
  158. $this->_options->setNoAtime(false);
  159. $this->assertContains('atime', $capabilities->getSupportedMetadata());
  160. $this->_options->setNoAtime(true);
  161. $this->assertNotContains('atime', $capabilities->getSupportedMetadata());
  162. }
  163. public function testSetNoCtimeChangesCtimeOfMetadataCapability()
  164. {
  165. $capabilities = $this->_storage->getCapabilities();
  166. $this->_options->setNoCtime(false);
  167. $this->assertContains('ctime', $capabilities->getSupportedMetadata());
  168. $this->_options->setNoCtime(true);
  169. $this->assertNotContains('ctime', $capabilities->getSupportedMetadata());
  170. }
  171. public function testSetDirPermissionThrowsExceptionIfNotWritable()
  172. {
  173. $this->setExpectedException('Zend\Cache\Exception\InvalidArgumentException');
  174. $this->_options->setDirPermission(0577);
  175. }
  176. public function testSetDirPermissionThrowsExceptionIfNotReadable()
  177. {
  178. $this->setExpectedException('Zend\Cache\Exception\InvalidArgumentException');
  179. $this->_options->setDirPermission(0377);
  180. }
  181. public function testSetDirPermissionThrowsExceptionIfNotExecutable()
  182. {
  183. $this->setExpectedException('Zend\Cache\Exception\InvalidArgumentException');
  184. $this->_options->setDirPermission(0677);
  185. }
  186. public function testSetDirLevelInvalidException()
  187. {
  188. $this->setExpectedException('Zend\Cache\Exception\InvalidArgumentException');
  189. $this->_options->setDirLevel(17); // must between 0-16
  190. }
  191. public function testSetUmask()
  192. {
  193. $this->_options->setUmask(023);
  194. $this->assertSame(023, $this->_options->getUmask());
  195. $this->_options->setUmask(false);
  196. $this->assertFalse($this->_options->getUmask());
  197. }
  198. public function testSetUmaskThrowsExceptionIfNotWritable()
  199. {
  200. $this->setExpectedException('Zend\Cache\Exception\InvalidArgumentException');
  201. $this->_options->setUmask(0300);
  202. }
  203. public function testSetUmaskThrowsExceptionIfNotReadable()
  204. {
  205. $this->setExpectedException('Zend\Cache\Exception\InvalidArgumentException');
  206. $this->_options->setUmask(0200);
  207. }
  208. public function testSetUmaskThrowsExceptionIfNotExecutable()
  209. {
  210. $this->setExpectedException('Zend\Cache\Exception\InvalidArgumentException');
  211. $this->_options->setUmask(0100);
  212. }
  213. public function testGetMetadataWithCtime()
  214. {
  215. $this->_options->setNoCtime(false);
  216. $this->assertTrue($this->_storage->setItem('test', 'v'));
  217. $meta = $this->_storage->getMetadata('test');
  218. $this->assertInternalType('array', $meta);
  219. $expectedCtime = filectime($meta['filespec'] . '.dat');
  220. $this->assertEquals($expectedCtime, $meta['ctime']);
  221. }
  222. public function testGetMetadataWithAtime()
  223. {
  224. $this->_options->setNoAtime(false);
  225. $this->assertTrue($this->_storage->setItem('test', 'v'));
  226. $meta = $this->_storage->getMetadata('test');
  227. $this->assertInternalType('array', $meta);
  228. $expectedAtime = fileatime($meta['filespec'] . '.dat');
  229. $this->assertEquals($expectedAtime, $meta['atime']);
  230. }
  231. public function testClearExpiredExceptionTriggersEvent()
  232. {
  233. $this->_options->setTtl(0.1);
  234. $this->_storage->setItem('k', 'v');
  235. $dirs = glob($this->_tmpCacheDir . '/*');
  236. if (count($dirs) === 0) {
  237. $this->fail('Could not find cache dir');
  238. }
  239. chmod($dirs[0], 0500); //make directory rx, unlink should fail
  240. sleep(1); //wait for the entry to expire
  241. $plugin = new ExceptionHandler();
  242. $options = new PluginOptions(array('throw_exceptions' => false));
  243. $plugin->setOptions($options);
  244. $this->_storage->addPlugin($plugin);
  245. $this->_storage->clearExpired();
  246. chmod($dirs[0], 0700); //set dir back to writable for tearDown
  247. }
  248. public function testClearByNamespaceWithUnexpectedDirectory()
  249. {
  250. // create cache items at 2 different directory levels
  251. $this->_storage->getOptions()->setDirLevel(2);
  252. $this->_storage->setItem('a_key', 'a_value');
  253. $this->_storage->getOptions()->setDirLevel(1);
  254. $this->_storage->setItem('b_key', 'b_value');
  255. $this->_storage->clearByNamespace($this->_storage->getOptions()->getNamespace());
  256. }
  257. public function testClearByPrefixWithUnexpectedDirectory()
  258. {
  259. // create cache items at 2 different directory levels
  260. $this->_storage->getOptions()->setDirLevel(2);
  261. $this->_storage->setItem('a_key', 'a_value');
  262. $this->_storage->getOptions()->setDirLevel(1);
  263. $this->_storage->setItem('b_key', 'b_value');
  264. $glob = glob($this->_tmpCacheDir.'/*');
  265. //contrived prefix which will collide with an existing directory
  266. $prefix = substr(md5('a_key'), 2, 2);
  267. $this->_storage->clearByPrefix($prefix);
  268. }
  269. }