PageRenderTime 43ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

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

http://github.com/zendframework/zf2
PHP | 330 lines | 262 code | 53 blank | 15 comment | 23 complexity | a3dbe6da2199c4d834f8c2f888910d2d MD5 | raw file
Possible License(s): BSD-3-Clause
  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-2015 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);
  110. mkdir($testDir);
  111. chmod($testDir, 0557);
  112. try {
  113. $this->_options->setCacheDir($testDir);
  114. } catch (\Exception $e) {
  115. rmdir($testDir);
  116. throw $e;
  117. }
  118. }
  119. public function testSetCacheDirNotReadableException()
  120. {
  121. if (substr(PHP_OS, 0, 3) == 'WIN') {
  122. $this->markTestSkipped("Not testable on windows");
  123. } else {
  124. @exec('whoami 2>&1', $out, $ret);
  125. if ($ret) {
  126. $this->markTestSkipped("Not testable: " . implode("\n", $out));
  127. } elseif (isset($out[0]) && $out[0] == 'root') {
  128. $this->markTestSkipped("Not testable as root");
  129. }
  130. }
  131. $this->setExpectedException('Zend\Cache\Exception\InvalidArgumentException');
  132. // create a not readable temporaty directory
  133. $testDir = tempnam(sys_get_temp_dir(), 'ZendTest');
  134. unlink($testDir);
  135. mkdir($testDir);
  136. chmod($testDir, 0337);
  137. try {
  138. $this->_options->setCacheDir($testDir);
  139. } catch (\Exception $e) {
  140. rmdir($testDir);
  141. throw $e;
  142. }
  143. }
  144. public function testSetFilePermissionThrowsExceptionIfNotWritable()
  145. {
  146. $this->setExpectedException('Zend\Cache\Exception\InvalidArgumentException');
  147. $this->_options->setFilePermission(0466);
  148. }
  149. public function testSetFilePermissionThrowsExceptionIfNotReadable()
  150. {
  151. $this->setExpectedException('Zend\Cache\Exception\InvalidArgumentException');
  152. $this->_options->setFilePermission(0266);
  153. }
  154. public function testSetFilePermissionThrowsExceptionIfExecutable()
  155. {
  156. $this->setExpectedException('Zend\Cache\Exception\InvalidArgumentException');
  157. $this->_options->setFilePermission(0661);
  158. }
  159. public function testSetNoAtimeChangesAtimeOfMetadataCapability()
  160. {
  161. $capabilities = $this->_storage->getCapabilities();
  162. $this->_options->setNoAtime(false);
  163. $this->assertContains('atime', $capabilities->getSupportedMetadata());
  164. $this->_options->setNoAtime(true);
  165. $this->assertNotContains('atime', $capabilities->getSupportedMetadata());
  166. }
  167. public function testSetNoCtimeChangesCtimeOfMetadataCapability()
  168. {
  169. $capabilities = $this->_storage->getCapabilities();
  170. $this->_options->setNoCtime(false);
  171. $this->assertContains('ctime', $capabilities->getSupportedMetadata());
  172. $this->_options->setNoCtime(true);
  173. $this->assertNotContains('ctime', $capabilities->getSupportedMetadata());
  174. }
  175. public function testSetDirPermissionThrowsExceptionIfNotWritable()
  176. {
  177. $this->setExpectedException('Zend\Cache\Exception\InvalidArgumentException');
  178. $this->_options->setDirPermission(0577);
  179. }
  180. public function testSetDirPermissionThrowsExceptionIfNotReadable()
  181. {
  182. $this->setExpectedException('Zend\Cache\Exception\InvalidArgumentException');
  183. $this->_options->setDirPermission(0377);
  184. }
  185. public function testSetDirPermissionThrowsExceptionIfNotExecutable()
  186. {
  187. $this->setExpectedException('Zend\Cache\Exception\InvalidArgumentException');
  188. $this->_options->setDirPermission(0677);
  189. }
  190. public function testSetDirLevelInvalidException()
  191. {
  192. $this->setExpectedException('Zend\Cache\Exception\InvalidArgumentException');
  193. $this->_options->setDirLevel(17); // must between 0-16
  194. }
  195. public function testSetUmask()
  196. {
  197. $this->_options->setUmask(023);
  198. $this->assertSame(023, $this->_options->getUmask());
  199. $this->_options->setUmask(false);
  200. $this->assertFalse($this->_options->getUmask());
  201. }
  202. public function testSetUmaskThrowsExceptionIfNotWritable()
  203. {
  204. $this->setExpectedException('Zend\Cache\Exception\InvalidArgumentException');
  205. $this->_options->setUmask(0300);
  206. }
  207. public function testSetUmaskThrowsExceptionIfNotReadable()
  208. {
  209. $this->setExpectedException('Zend\Cache\Exception\InvalidArgumentException');
  210. $this->_options->setUmask(0200);
  211. }
  212. public function testSetUmaskThrowsExceptionIfNotExecutable()
  213. {
  214. $this->setExpectedException('Zend\Cache\Exception\InvalidArgumentException');
  215. $this->_options->setUmask(0100);
  216. }
  217. public function testGetMetadataWithCtime()
  218. {
  219. $this->_options->setNoCtime(false);
  220. $this->assertTrue($this->_storage->setItem('test', 'v'));
  221. $meta = $this->_storage->getMetadata('test');
  222. $this->assertInternalType('array', $meta);
  223. $expectedCtime = filectime($meta['filespec'] . '.dat');
  224. $this->assertEquals($expectedCtime, $meta['ctime']);
  225. }
  226. public function testGetMetadataWithAtime()
  227. {
  228. $this->_options->setNoAtime(false);
  229. $this->assertTrue($this->_storage->setItem('test', 'v'));
  230. $meta = $this->_storage->getMetadata('test');
  231. $this->assertInternalType('array', $meta);
  232. $expectedAtime = fileatime($meta['filespec'] . '.dat');
  233. $this->assertEquals($expectedAtime, $meta['atime']);
  234. }
  235. public function testClearExpiredExceptionTriggersEvent()
  236. {
  237. $this->_options->setTtl(0.1);
  238. $this->_storage->setItem('k', 'v');
  239. $dirs = glob($this->_tmpCacheDir . '/*');
  240. if (count($dirs) === 0) {
  241. $this->fail('Could not find cache dir');
  242. }
  243. chmod($dirs[0], 0500); //make directory rx, unlink should fail
  244. sleep(1); //wait for the entry to expire
  245. $plugin = new ExceptionHandler();
  246. $options = new PluginOptions(array('throw_exceptions' => false));
  247. $plugin->setOptions($options);
  248. $this->_storage->addPlugin($plugin);
  249. $this->_storage->clearExpired();
  250. chmod($dirs[0], 0700); //set dir back to writable for tearDown
  251. }
  252. public function testClearByNamespaceWithUnexpectedDirectory()
  253. {
  254. // create cache items at 2 different directory levels
  255. $this->_storage->getOptions()->setDirLevel(2);
  256. $this->_storage->setItem('a_key', 'a_value');
  257. $this->_storage->getOptions()->setDirLevel(1);
  258. $this->_storage->setItem('b_key', 'b_value');
  259. $this->_storage->clearByNamespace($this->_storage->getOptions()->getNamespace());
  260. }
  261. public function testClearByPrefixWithUnexpectedDirectory()
  262. {
  263. // create cache items at 2 different directory levels
  264. $this->_storage->getOptions()->setDirLevel(2);
  265. $this->_storage->setItem('a_key', 'a_value');
  266. $this->_storage->getOptions()->setDirLevel(1);
  267. $this->_storage->setItem('b_key', 'b_value');
  268. $glob = glob($this->_tmpCacheDir.'/*');
  269. //contrived prefix which will collide with an existing directory
  270. $prefix = substr(md5('a_key'), 2, 2);
  271. $this->_storage->clearByPrefix($prefix);
  272. }
  273. }