CacheJailTest.php 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. <?php
  2. /**
  3. * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
  4. * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
  5. * SPDX-License-Identifier: AGPL-3.0-or-later
  6. */
  7. namespace Test\Files\Cache\Wrapper;
  8. use OC\Files\Cache\Wrapper\CacheJail;
  9. use OC\Files\Search\SearchComparison;
  10. use OC\Files\Search\SearchQuery;
  11. use OC\Files\Storage\Wrapper\Jail;
  12. use OC\User\User;
  13. use OCP\EventDispatcher\IEventDispatcher;
  14. use OCP\Files\Cache\ICacheEntry;
  15. use OCP\Files\Search\ISearchComparison;
  16. use Test\Files\Cache\CacheTest;
  17. /**
  18. * Class CacheJail
  19. *
  20. * @group DB
  21. *
  22. * @package Test\Files\Cache\Wrapper
  23. */
  24. class CacheJailTest extends CacheTest {
  25. /**
  26. * @var \OC\Files\Cache\Cache $sourceCache
  27. */
  28. protected $sourceCache;
  29. protected function setUp(): void {
  30. parent::setUp();
  31. $this->storage->mkdir('jail');
  32. $this->sourceCache = $this->cache;
  33. $this->cache = new \OC\Files\Cache\Wrapper\CacheJail($this->sourceCache, 'jail');
  34. $this->cache->insert('', ['size' => 0, 'mtime' => 0, 'mimetype' => ICacheEntry::DIRECTORY_MIMETYPE]);
  35. }
  36. public function testSearchOutsideJail(): void {
  37. $this->storage->getScanner()->scan('');
  38. $file1 = 'jail/foobar';
  39. $file2 = 'folder/foobar';
  40. $data1 = ['size' => 100, 'mtime' => 50, 'mimetype' => 'foo/folder'];
  41. $this->sourceCache->insert('folder', ['size' => 0, 'mtime' => 0, 'mimetype' => ICacheEntry::DIRECTORY_MIMETYPE]);
  42. $this->sourceCache->put($file1, $data1);
  43. $this->sourceCache->put($file2, $data1);
  44. $this->assertCount(2, $this->sourceCache->search('%foobar'));
  45. $result = $this->cache->search('%foobar%');
  46. $this->assertCount(1, $result);
  47. $this->assertEquals('foobar', $result[0]['path']);
  48. $result = $this->cache->search('%foo%');
  49. $this->assertCount(1, $result);
  50. usort($result, function ($a, $b) {
  51. return $a['path'] <=> $b['path'];
  52. });
  53. $this->assertEquals('foobar', $result[0]['path']);
  54. }
  55. public function testSearchMimeOutsideJail(): void {
  56. $this->storage->getScanner()->scan('');
  57. $file1 = 'jail/foobar';
  58. $file2 = 'folder/foobar';
  59. $data1 = ['size' => 100, 'mtime' => 50, 'mimetype' => 'foo/folder'];
  60. $this->sourceCache->insert('folder', ['size' => 0, 'mtime' => 0, 'mimetype' => ICacheEntry::DIRECTORY_MIMETYPE]);
  61. $this->sourceCache->put($file1, $data1);
  62. $this->sourceCache->put($file2, $data1);
  63. $this->assertCount(2, $this->sourceCache->searchByMime('foo/folder'));
  64. $result = $this->cache->search('%foobar%');
  65. $this->assertCount(1, $result);
  66. $this->assertEquals('foobar', $result[0]['path']);
  67. }
  68. public function testSearchQueryOutsideJail(): void {
  69. $this->storage->getScanner()->scan('');
  70. $file1 = 'jail/foobar';
  71. $file2 = 'folder/foobar';
  72. $data1 = ['size' => 100, 'mtime' => 50, 'mimetype' => 'foo/folder'];
  73. $this->sourceCache->insert('folder', ['size' => 0, 'mtime' => 0, 'mimetype' => ICacheEntry::DIRECTORY_MIMETYPE]);
  74. $this->sourceCache->put($file1, $data1);
  75. $this->sourceCache->put($file2, $data1);
  76. $user = new User('foo', null, $this->createMock(IEventDispatcher::class));
  77. $query = new SearchQuery(new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'name', 'foobar'), 10, 0, [], $user);
  78. $result = $this->cache->searchQuery($query);
  79. $this->assertCount(1, $result);
  80. $this->assertEquals('foobar', $result[0]['path']);
  81. $query = new SearchQuery(new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'name', 'jail'), 10, 0, [], $user);
  82. $result = $this->cache->searchQuery($query);
  83. $this->assertCount(1, $result);
  84. $this->assertEquals('', $result[0]['path']);
  85. }
  86. public function testClearKeepEntriesOutsideJail(): void {
  87. $file1 = 'jail/foobar';
  88. $file2 = 'jail/foobar/asd';
  89. $file3 = 'folder/foobar';
  90. $data1 = ['size' => 100, 'mtime' => 50, 'mimetype' => ICacheEntry::DIRECTORY_MIMETYPE];
  91. $this->sourceCache->put('folder', $data1);
  92. $this->sourceCache->put($file1, $data1);
  93. $this->sourceCache->put($file2, $data1);
  94. $this->sourceCache->put($file3, $data1);
  95. $this->cache->clear();
  96. $this->assertFalse($this->cache->inCache('foobar'));
  97. $this->assertTrue($this->sourceCache->inCache('folder/foobar'));
  98. }
  99. public function testGetById(): void {
  100. $data1 = ['size' => 100, 'mtime' => 50, 'mimetype' => ICacheEntry::DIRECTORY_MIMETYPE];
  101. $id = $this->sourceCache->put('jail/bar', $data1);
  102. // path from jailed foo of foo/bar is bar
  103. $path = $this->cache->getPathById($id);
  104. $this->assertEquals('bar', $path);
  105. // path from jailed '' of foo/bar is foo/bar
  106. $this->cache = new \OC\Files\Cache\Wrapper\CacheJail($this->sourceCache, '');
  107. $path = $this->cache->getPathById($id);
  108. $this->assertEquals('jail/bar', $path);
  109. }
  110. public function testGetIncomplete(): void {
  111. //not supported
  112. $this->addToAssertionCount(1);
  113. }
  114. public function testMoveFromJail(): void {
  115. $folderData = ['size' => 100, 'mtime' => 50, 'mimetype' => ICacheEntry::DIRECTORY_MIMETYPE];
  116. $this->sourceCache->put('source', $folderData);
  117. $this->sourceCache->put('source/foo', $folderData);
  118. $this->sourceCache->put('source/foo/bar', $folderData);
  119. $this->sourceCache->put('target', $folderData);
  120. $jail = new CacheJail($this->sourceCache, 'source');
  121. $this->sourceCache->moveFromCache($jail, 'foo', 'target/foo');
  122. $this->assertTrue($this->sourceCache->inCache('target/foo'));
  123. $this->assertTrue($this->sourceCache->inCache('target/foo/bar'));
  124. }
  125. public function testMoveToJail(): void {
  126. $folderData = ['size' => 100, 'mtime' => 50, 'mimetype' => ICacheEntry::DIRECTORY_MIMETYPE];
  127. $this->sourceCache->put('source', $folderData);
  128. $this->sourceCache->put('source/foo', $folderData);
  129. $this->sourceCache->put('source/foo/bar', $folderData);
  130. $this->sourceCache->put('target', $folderData);
  131. $jail = new CacheJail($this->sourceCache, 'target');
  132. $jail->moveFromCache($this->sourceCache, 'source/foo', 'foo');
  133. $this->assertTrue($this->sourceCache->inCache('target/foo'));
  134. $this->assertTrue($this->sourceCache->inCache('target/foo/bar'));
  135. }
  136. public function testMoveBetweenJail(): void {
  137. $folderData = ['size' => 100, 'mtime' => 50, 'mimetype' => ICacheEntry::DIRECTORY_MIMETYPE];
  138. $this->sourceCache->put('source', $folderData);
  139. $this->sourceCache->put('source/foo', $folderData);
  140. $this->sourceCache->put('source/foo/bar', $folderData);
  141. $this->sourceCache->put('target', $folderData);
  142. $jail = new CacheJail($this->sourceCache, 'target');
  143. $sourceJail = new CacheJail($this->sourceCache, 'source');
  144. $jail->moveFromCache($sourceJail, 'foo', 'foo');
  145. $this->assertTrue($this->sourceCache->inCache('target/foo'));
  146. $this->assertTrue($this->sourceCache->inCache('target/foo/bar'));
  147. }
  148. public function testSearchNested(): void {
  149. $this->storage->getScanner()->scan('');
  150. $file1 = 'jail';
  151. $file2 = 'jail/bar';
  152. $file3 = 'jail/bar/asd';
  153. $data1 = ['size' => 100, 'mtime' => 50, 'mimetype' => 'foo/folder'];
  154. $this->sourceCache->put($file1, $data1);
  155. $this->sourceCache->put($file2, $data1);
  156. $this->sourceCache->put($file3, $data1);
  157. $nested = new \OC\Files\Cache\Wrapper\CacheJail($this->cache, 'bar');
  158. $result = $nested->search('%asd%');
  159. $this->assertCount(1, $result);
  160. $this->assertEquals('asd', $result[0]['path']);
  161. }
  162. public function testRootJail(): void {
  163. $this->storage->getScanner()->scan('');
  164. $file1 = 'jail';
  165. $file2 = 'jail/bar';
  166. $file3 = 'jail/bar/asd';
  167. $data1 = ['size' => 100, 'mtime' => 50, 'mimetype' => 'foo/folder'];
  168. $this->sourceCache->put($file1, $data1);
  169. $this->sourceCache->put($file2, $data1);
  170. $this->sourceCache->put($file3, $data1);
  171. $nested = new \OC\Files\Cache\Wrapper\CacheJail($this->sourceCache, '');
  172. $result = $nested->search('%asd%');
  173. $this->assertCount(1, $result);
  174. $this->assertEquals('jail/bar/asd', $result[0]['path']);
  175. }
  176. public function testWatcher(): void {
  177. $storage = new Jail([
  178. 'storage' => $this->storage,
  179. 'root' => 'jail'
  180. ]);
  181. $storage->getScanner()->scan('');
  182. $storage->file_put_contents('bar', 'asd');
  183. $this->assertFalse($this->cache->inCache('bar'));
  184. $storage->getWatcher()->update('bar', ['mimetype' => 'text/plain']);
  185. $this->assertTrue($this->cache->inCache('bar'));
  186. }
  187. public function testWatcherAfterInnerWatcher(): void {
  188. $storage = new Jail([
  189. 'storage' => $this->storage,
  190. 'root' => 'jail'
  191. ]);
  192. $storage->getScanner()->scan('');
  193. $storage->file_put_contents('bar', 'asd');
  194. // let the underlying storage create it's watcher first
  195. $this->storage->getWatcher();
  196. $this->assertFalse($this->cache->inCache('bar'));
  197. $storage->getWatcher()->update('bar', ['mimetype' => 'text/plain']);
  198. $this->assertTrue($this->cache->inCache('bar'));
  199. }
  200. }