PageRenderTime 50ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/tests/lib/files/cache/cache.php

https://github.com/sezuan/core
PHP | 362 lines | 247 code | 70 blank | 45 comment | 2 complexity | 7f5f6fd30c564822eac78275c8245c7c MD5 | raw file
Possible License(s): AGPL-3.0, AGPL-1.0, MPL-2.0-no-copyleft-exception
  1. <?php
  2. /**
  3. * Copyright (c) 2012 Robin Appelman <icewind@owncloud.com>
  4. * This file is licensed under the Affero General Public License version 3 or
  5. * later.
  6. * See the COPYING-README file.
  7. */
  8. namespace Test\Files\Cache;
  9. use PHPUnit_Framework_MockObject_MockObject;
  10. class LongId extends \OC\Files\Storage\Temporary {
  11. public function getId() {
  12. return 'long:' . str_repeat('foo', 50) . parent::getId();
  13. }
  14. }
  15. class Cache extends \PHPUnit_Framework_TestCase {
  16. /**
  17. * @var \OC\Files\Storage\Temporary $storage;
  18. */
  19. private $storage;
  20. /**
  21. * @var \OC\Files\Storage\Temporary $storage2;
  22. */
  23. private $storage2;
  24. /**
  25. * @var \OC\Files\Cache\Cache $cache
  26. */
  27. private $cache;
  28. /**
  29. * @var \OC\Files\Cache\Cache $cache2
  30. */
  31. private $cache2;
  32. public function testSimple() {
  33. $file1 = 'foo';
  34. $file2 = 'foo/bar';
  35. $data1 = array('size' => 100, 'mtime' => 50, 'mimetype' => 'foo/folder');
  36. $data2 = array('size' => 1000, 'mtime' => 20, 'mimetype' => 'foo/file');
  37. $this->assertFalse($this->cache->inCache($file1));
  38. $this->assertEquals($this->cache->get($file1), null);
  39. $id1 = $this->cache->put($file1, $data1);
  40. $this->assertTrue($this->cache->inCache($file1));
  41. $cacheData1 = $this->cache->get($file1);
  42. foreach ($data1 as $key => $value) {
  43. $this->assertEquals($value, $cacheData1[$key]);
  44. }
  45. $this->assertEquals($cacheData1['mimepart'], 'foo');
  46. $this->assertEquals($cacheData1['fileid'], $id1);
  47. $this->assertEquals($id1, $this->cache->getId($file1));
  48. $this->assertFalse($this->cache->inCache($file2));
  49. $id2 = $this->cache->put($file2, $data2);
  50. $this->assertTrue($this->cache->inCache($file2));
  51. $cacheData2 = $this->cache->get($file2);
  52. foreach ($data2 as $key => $value) {
  53. $this->assertEquals($value, $cacheData2[$key]);
  54. }
  55. $this->assertEquals($cacheData1['fileid'], $cacheData2['parent']);
  56. $this->assertEquals($cacheData2['fileid'], $id2);
  57. $this->assertEquals($id2, $this->cache->getId($file2));
  58. $this->assertEquals($id1, $this->cache->getParentId($file2));
  59. $newSize = 1050;
  60. $newId2 = $this->cache->put($file2, array('size' => $newSize));
  61. $cacheData2 = $this->cache->get($file2);
  62. $this->assertEquals($newId2, $id2);
  63. $this->assertEquals($cacheData2['size'], $newSize);
  64. $this->assertEquals($cacheData1, $this->cache->get($file1));
  65. $this->cache->remove($file2);
  66. $this->assertFalse($this->cache->inCache($file2));
  67. $this->assertEquals($this->cache->get($file2), null);
  68. $this->assertTrue($this->cache->inCache($file1));
  69. $this->assertEquals($cacheData1, $this->cache->get($id1));
  70. }
  71. public function testPartial() {
  72. $file1 = 'foo';
  73. $this->cache->put($file1, array('size' => 10));
  74. $this->assertEquals(array('size' => 10), $this->cache->get($file1));
  75. $this->cache->put($file1, array('mtime' => 15));
  76. $this->assertEquals(array('size' => 10, 'mtime' => 15), $this->cache->get($file1));
  77. $this->cache->put($file1, array('size' => 12));
  78. $this->assertEquals(array('size' => 12, 'mtime' => 15), $this->cache->get($file1));
  79. }
  80. public function testFolder() {
  81. $file1 = 'folder';
  82. $file2 = 'folder/bar';
  83. $file3 = 'folder/foo';
  84. $data1 = array('size' => 100, 'mtime' => 50, 'mimetype' => 'httpd/unix-directory');
  85. $fileData = array();
  86. $fileData['bar'] = array('size' => 1000, 'mtime' => 20, 'mimetype' => 'foo/file');
  87. $fileData['foo'] = array('size' => 20, 'mtime' => 25, 'mimetype' => 'foo/file');
  88. $this->cache->put($file1, $data1);
  89. $this->cache->put($file2, $fileData['bar']);
  90. $this->cache->put($file3, $fileData['foo']);
  91. $content = $this->cache->getFolderContents($file1);
  92. $this->assertEquals(count($content), 2);
  93. foreach ($content as $cachedData) {
  94. $data = $fileData[$cachedData['name']];
  95. foreach ($data as $name => $value) {
  96. $this->assertEquals($value, $cachedData[$name]);
  97. }
  98. }
  99. $file4 = 'folder/unkownSize';
  100. $fileData['unkownSize'] = array('size' => -1, 'mtime' => 25, 'mimetype' => 'foo/file');
  101. $this->cache->put($file4, $fileData['unkownSize']);
  102. $this->assertEquals(-1, $this->cache->calculateFolderSize($file1));
  103. $fileData['unkownSize'] = array('size' => 5, 'mtime' => 25, 'mimetype' => 'foo/file');
  104. $this->cache->put($file4, $fileData['unkownSize']);
  105. $this->assertEquals(1025, $this->cache->calculateFolderSize($file1));
  106. $this->cache->remove('folder');
  107. $this->assertFalse($this->cache->inCache('folder/foo'));
  108. $this->assertFalse($this->cache->inCache('folder/bar'));
  109. }
  110. function testStatus() {
  111. $this->assertEquals(\OC\Files\Cache\Cache::NOT_FOUND, $this->cache->getStatus('foo'));
  112. $this->cache->put('foo', array('size' => -1));
  113. $this->assertEquals(\OC\Files\Cache\Cache::PARTIAL, $this->cache->getStatus('foo'));
  114. $this->cache->put('foo', array('size' => -1, 'mtime' => 20, 'mimetype' => 'foo/file'));
  115. $this->assertEquals(\OC\Files\Cache\Cache::SHALLOW, $this->cache->getStatus('foo'));
  116. $this->cache->put('foo', array('size' => 10));
  117. $this->assertEquals(\OC\Files\Cache\Cache::COMPLETE, $this->cache->getStatus('foo'));
  118. }
  119. function testSearch() {
  120. $file1 = 'folder';
  121. $file2 = 'folder/foobar';
  122. $file3 = 'folder/foo';
  123. $data1 = array('size' => 100, 'mtime' => 50, 'mimetype' => 'foo/folder');
  124. $fileData = array();
  125. $fileData['foobar'] = array('size' => 1000, 'mtime' => 20, 'mimetype' => 'foo/file');
  126. $fileData['foo'] = array('size' => 20, 'mtime' => 25, 'mimetype' => 'foo/file');
  127. $this->cache->put($file1, $data1);
  128. $this->cache->put($file2, $fileData['foobar']);
  129. $this->cache->put($file3, $fileData['foo']);
  130. $this->assertEquals(2, count($this->cache->search('%foo%')));
  131. $this->assertEquals(1, count($this->cache->search('foo')));
  132. $this->assertEquals(1, count($this->cache->search('%folder%')));
  133. $this->assertEquals(1, count($this->cache->search('folder%')));
  134. $this->assertEquals(3, count($this->cache->search('%')));
  135. $this->assertEquals(3, count($this->cache->searchByMime('foo')));
  136. $this->assertEquals(2, count($this->cache->searchByMime('foo/file')));
  137. }
  138. function testMove() {
  139. $file1 = 'folder';
  140. $file2 = 'folder/bar';
  141. $file3 = 'folder/foo';
  142. $file4 = 'folder/foo/1';
  143. $file5 = 'folder/foo/2';
  144. $data = array('size' => 100, 'mtime' => 50, 'mimetype' => 'foo/bar');
  145. $folderData = array('size' => 100, 'mtime' => 50, 'mimetype' => 'httpd/unix-directory');
  146. $this->cache->put($file1, $folderData);
  147. $this->cache->put($file2, $folderData);
  148. $this->cache->put($file3, $folderData);
  149. $this->cache->put($file4, $data);
  150. $this->cache->put($file5, $data);
  151. /* simulate a second user with a different storage id but the same folder structure */
  152. $this->cache2->put($file1, $folderData);
  153. $this->cache2->put($file2, $folderData);
  154. $this->cache2->put($file3, $folderData);
  155. $this->cache2->put($file4, $data);
  156. $this->cache2->put($file5, $data);
  157. $this->cache->move('folder/foo', 'folder/foobar');
  158. $this->assertFalse($this->cache->inCache('folder/foo'));
  159. $this->assertFalse($this->cache->inCache('folder/foo/1'));
  160. $this->assertFalse($this->cache->inCache('folder/foo/2'));
  161. $this->assertTrue($this->cache->inCache('folder/bar'));
  162. $this->assertTrue($this->cache->inCache('folder/foobar'));
  163. $this->assertTrue($this->cache->inCache('folder/foobar/1'));
  164. $this->assertTrue($this->cache->inCache('folder/foobar/2'));
  165. /* the folder structure of the second user must not change! */
  166. $this->assertTrue($this->cache2->inCache('folder/bar'));
  167. $this->assertTrue($this->cache2->inCache('folder/foo'));
  168. $this->assertTrue($this->cache2->inCache('folder/foo/1'));
  169. $this->assertTrue($this->cache2->inCache('folder/foo/2'));
  170. $this->assertFalse($this->cache2->inCache('folder/foobar'));
  171. $this->assertFalse($this->cache2->inCache('folder/foobar/1'));
  172. $this->assertFalse($this->cache2->inCache('folder/foobar/2'));
  173. }
  174. function testGetIncomplete() {
  175. $file1 = 'folder1';
  176. $file2 = 'folder2';
  177. $file3 = 'folder3';
  178. $file4 = 'folder4';
  179. $data = array('size' => 10, 'mtime' => 50, 'mimetype' => 'foo/bar');
  180. $this->cache->put($file1, $data);
  181. $data['size'] = -1;
  182. $this->cache->put($file2, $data);
  183. $this->cache->put($file3, $data);
  184. $data['size'] = 12;
  185. $this->cache->put($file4, $data);
  186. $this->assertEquals($file3, $this->cache->getIncomplete());
  187. }
  188. function testNonExisting() {
  189. $this->assertFalse($this->cache->get('foo.txt'));
  190. $this->assertEquals(array(), $this->cache->getFolderContents('foo'));
  191. }
  192. function testGetById() {
  193. $storageId = $this->storage->getId();
  194. $data = array('size' => 1000, 'mtime' => 20, 'mimetype' => 'foo/file');
  195. $id = $this->cache->put('foo', $data);
  196. $this->assertEquals(array($storageId, 'foo'), \OC\Files\Cache\Cache::getById($id));
  197. }
  198. function testStorageMTime() {
  199. $data = array('size' => 1000, 'mtime' => 20, 'mimetype' => 'foo/file');
  200. $this->cache->put('foo', $data);
  201. $cachedData = $this->cache->get('foo');
  202. $this->assertEquals($data['mtime'], $cachedData['storage_mtime']);//if no storage_mtime is saved, mtime should be used
  203. $this->cache->put('foo', array('storage_mtime' => 30));//when setting storage_mtime, mtime is also set
  204. $cachedData = $this->cache->get('foo');
  205. $this->assertEquals(30, $cachedData['storage_mtime']);
  206. $this->assertEquals(30, $cachedData['mtime']);
  207. $this->cache->put('foo', array('mtime' => 25));//setting mtime does not change storage_mtime
  208. $cachedData = $this->cache->get('foo');
  209. $this->assertEquals(30, $cachedData['storage_mtime']);
  210. $this->assertEquals(25, $cachedData['mtime']);
  211. }
  212. function testLongId() {
  213. $storage = new LongId(array());
  214. $cache = $storage->getCache();
  215. $storageId = $storage->getId();
  216. $data = array('size' => 1000, 'mtime' => 20, 'mimetype' => 'foo/file');
  217. $id = $cache->put('foo', $data);
  218. $this->assertEquals(array(md5($storageId), 'foo'), \OC\Files\Cache\Cache::getById($id));
  219. }
  220. /**
  221. * @brief this test show the bug resulting if we have no normalizer installed
  222. */
  223. public function testWithoutNormalizer() {
  224. // folder name "Schön" with U+00F6 (normalized)
  225. $folderWith00F6 = "\x53\x63\x68\xc3\xb6\x6e";
  226. // folder name "Schön" with U+0308 (un-normalized)
  227. $folderWith0308 = "\x53\x63\x68\x6f\xcc\x88\x6e";
  228. /**
  229. * @var \OC\Files\Cache\Cache | PHPUnit_Framework_MockObject_MockObject $cacheMock
  230. */
  231. $cacheMock = $this->getMock('\OC\Files\Cache\Cache', array('normalize'), array($this->storage), '', true);
  232. $cacheMock->expects($this->any())
  233. ->method('normalize')
  234. ->will($this->returnArgument(0));
  235. $data = array('size' => 100, 'mtime' => 50, 'mimetype' => 'httpd/unix-directory');
  236. // put root folder
  237. $this->assertFalse($cacheMock->get('folder'));
  238. $this->assertGreaterThan(0, $cacheMock->put('folder', $data));
  239. // put un-normalized folder
  240. $this->assertFalse($cacheMock->get('folder/' .$folderWith0308));
  241. $this->assertGreaterThan(0, $cacheMock->put('folder/' .$folderWith0308, $data));
  242. // get un-normalized folder by name
  243. $unNormalizedFolderName = $cacheMock->get('folder/' .$folderWith0308);
  244. // check if database layer normalized the folder name (this should not happen)
  245. $this->assertEquals($folderWith0308, $unNormalizedFolderName['name']);
  246. // put normalized folder
  247. $this->assertFalse($cacheMock->get('folder/' . $folderWith00F6));
  248. $this->assertGreaterThan(0, $cacheMock->put('folder/' .$folderWith00F6, $data));
  249. // this is our bug, we have two different hashes with the same name (Schön)
  250. $this->assertEquals(2, count($cacheMock->getFolderContents('folder')));
  251. }
  252. /**
  253. * @brief this test shows that there is no bug if we use the normalizer
  254. */
  255. public function testWithNormalizer() {
  256. if(!class_exists('Patchwork\PHP\Shim\Normalizer')) {
  257. $this->markTestSkipped('The 3rdparty Normalizer extension is not available.');
  258. return;
  259. }
  260. // folder name "Schön" with U+00F6 (normalized)
  261. $folderWith00F6 = "\x53\x63\x68\xc3\xb6\x6e";
  262. // folder name "Schön" with U+0308 (un-normalized)
  263. $folderWith0308 = "\x53\x63\x68\x6f\xcc\x88\x6e";
  264. $data = array('size' => 100, 'mtime' => 50, 'mimetype' => 'httpd/unix-directory');
  265. // put root folder
  266. $this->assertFalse($this->cache->get('folder'));
  267. $this->assertGreaterThan(0, $this->cache->put('folder', $data));
  268. // put un-normalized folder
  269. $this->assertFalse($this->cache->get('folder/' .$folderWith0308));
  270. $this->assertGreaterThan(0, $this->cache->put('folder/' .$folderWith0308, $data));
  271. // get un-normalized folder by name
  272. $unNormalizedFolderName = $this->cache->get('folder/' .$folderWith0308);
  273. // check if folder name was normalized
  274. $this->assertEquals($folderWith00F6, $unNormalizedFolderName['name']);
  275. // put normalized folder
  276. $this->assertTrue(is_array($this->cache->get('folder/' . $folderWith00F6)));
  277. $this->assertGreaterThan(0, $this->cache->put('folder/' .$folderWith00F6, $data));
  278. // at this point we should have only one folder named "Schön"
  279. $this->assertEquals(1, count($this->cache->getFolderContents('folder')));
  280. }
  281. public function tearDown() {
  282. if ($this->cache) {
  283. $this->cache->clear();
  284. }
  285. }
  286. public function setUp() {
  287. $this->storage = new \OC\Files\Storage\Temporary(array());
  288. $this->storage2 = new \OC\Files\Storage\Temporary(array());
  289. $this->cache = new \OC\Files\Cache\Cache($this->storage);
  290. $this->cache2 = new \OC\Files\Cache\Cache($this->storage2);
  291. }
  292. }