QuotaTest.php 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  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\Storage\Wrapper;
  8. //ensure the constants are loaded
  9. use OC\Files\Cache\CacheEntry;
  10. use OC\Files\Storage\Local;
  11. \OC::$loader->load('\OC\Files\Filesystem');
  12. /**
  13. * Class QuotaTest
  14. *
  15. * @group DB
  16. *
  17. * @package Test\Files\Storage\Wrapper
  18. */
  19. class QuotaTest extends \Test\Files\Storage\Storage {
  20. /**
  21. * @var string tmpDir
  22. */
  23. private $tmpDir;
  24. protected function setUp(): void {
  25. parent::setUp();
  26. $this->tmpDir = \OC::$server->getTempManager()->getTemporaryFolder();
  27. $storage = new \OC\Files\Storage\Local(['datadir' => $this->tmpDir]);
  28. $this->instance = new \OC\Files\Storage\Wrapper\Quota(['storage' => $storage, 'quota' => 10000000]);
  29. }
  30. protected function tearDown(): void {
  31. \OC_Helper::rmdirr($this->tmpDir);
  32. parent::tearDown();
  33. }
  34. /**
  35. * @param integer $limit
  36. */
  37. protected function getLimitedStorage($limit) {
  38. $storage = new \OC\Files\Storage\Local(['datadir' => $this->tmpDir]);
  39. $storage->mkdir('files');
  40. $storage->getScanner()->scan('');
  41. return new \OC\Files\Storage\Wrapper\Quota(['storage' => $storage, 'quota' => $limit]);
  42. }
  43. public function testFilePutContentsNotEnoughSpace(): void {
  44. $instance = $this->getLimitedStorage(3);
  45. $this->assertFalse($instance->file_put_contents('files/foo', 'foobar'));
  46. }
  47. public function testCopyNotEnoughSpace(): void {
  48. $instance = $this->getLimitedStorage(9);
  49. $this->assertEquals(6, $instance->file_put_contents('files/foo', 'foobar'));
  50. $instance->getScanner()->scan('');
  51. $this->assertFalse($instance->copy('files/foo', 'files/bar'));
  52. }
  53. public function testFreeSpace(): void {
  54. $instance = $this->getLimitedStorage(9);
  55. $this->assertEquals(9, $instance->free_space(''));
  56. }
  57. public function testFreeSpaceWithUsedSpace(): void {
  58. $instance = $this->getLimitedStorage(9);
  59. $instance->getCache()->put(
  60. '', ['size' => 3]
  61. );
  62. $this->assertEquals(6, $instance->free_space(''));
  63. }
  64. public function testFreeSpaceWithUnknownDiskSpace(): void {
  65. $storage = $this->getMockBuilder(Local::class)
  66. ->setMethods(['free_space'])
  67. ->setConstructorArgs([['datadir' => $this->tmpDir]])
  68. ->getMock();
  69. $storage->expects($this->any())
  70. ->method('free_space')
  71. ->willReturn(-2);
  72. $storage->getScanner()->scan('');
  73. $instance = new \OC\Files\Storage\Wrapper\Quota(['storage' => $storage, 'quota' => 9]);
  74. $instance->getCache()->put(
  75. '', ['size' => 3]
  76. );
  77. $this->assertEquals(6, $instance->free_space(''));
  78. }
  79. public function testFreeSpaceWithUsedSpaceAndEncryption(): void {
  80. $instance = $this->getLimitedStorage(9);
  81. $instance->getCache()->put(
  82. '', ['size' => 7]
  83. );
  84. $this->assertEquals(2, $instance->free_space(''));
  85. }
  86. public function testFWriteNotEnoughSpace(): void {
  87. $instance = $this->getLimitedStorage(9);
  88. $stream = $instance->fopen('files/foo', 'w+');
  89. $this->assertEquals(6, fwrite($stream, 'foobar'));
  90. $this->assertEquals(3, fwrite($stream, 'qwerty'));
  91. fclose($stream);
  92. $this->assertEquals('foobarqwe', $instance->file_get_contents('files/foo'));
  93. }
  94. public function testStreamCopyWithEnoughSpace(): void {
  95. $instance = $this->getLimitedStorage(16);
  96. $inputStream = fopen('data://text/plain,foobarqwerty', 'r');
  97. $outputStream = $instance->fopen('files/foo', 'w+');
  98. [$count, $result] = \OC_Helper::streamCopy($inputStream, $outputStream);
  99. $this->assertEquals(12, $count);
  100. $this->assertTrue($result);
  101. fclose($inputStream);
  102. fclose($outputStream);
  103. }
  104. public function testStreamCopyNotEnoughSpace(): void {
  105. $instance = $this->getLimitedStorage(9);
  106. $inputStream = fopen('data://text/plain,foobarqwerty', 'r');
  107. $outputStream = $instance->fopen('files/foo', 'w+');
  108. [$count, $result] = \OC_Helper::streamCopy($inputStream, $outputStream);
  109. $this->assertEquals(9, $count);
  110. $this->assertFalse($result);
  111. fclose($inputStream);
  112. fclose($outputStream);
  113. }
  114. public function testReturnFalseWhenFopenFailed(): void {
  115. $failStorage = $this->getMockBuilder(Local::class)
  116. ->setMethods(['fopen'])
  117. ->setConstructorArgs([['datadir' => $this->tmpDir]])
  118. ->getMock();
  119. $failStorage->expects($this->any())
  120. ->method('fopen')
  121. ->willReturn(false);
  122. $instance = new \OC\Files\Storage\Wrapper\Quota(['storage' => $failStorage, 'quota' => 1000]);
  123. $this->assertFalse($instance->fopen('failedfopen', 'r'));
  124. }
  125. public function testReturnRegularStreamOnRead(): void {
  126. $instance = $this->getLimitedStorage(9);
  127. // create test file first
  128. $stream = $instance->fopen('files/foo', 'w+');
  129. fwrite($stream, 'blablacontent');
  130. fclose($stream);
  131. $stream = $instance->fopen('files/foo', 'r');
  132. $meta = stream_get_meta_data($stream);
  133. $this->assertEquals('plainfile', $meta['wrapper_type']);
  134. fclose($stream);
  135. $stream = $instance->fopen('files/foo', 'rb');
  136. $meta = stream_get_meta_data($stream);
  137. $this->assertEquals('plainfile', $meta['wrapper_type']);
  138. fclose($stream);
  139. }
  140. public function testReturnRegularStreamWhenOutsideFiles(): void {
  141. $instance = $this->getLimitedStorage(9);
  142. $instance->mkdir('files_other');
  143. // create test file first
  144. $stream = $instance->fopen('files_other/foo', 'w+');
  145. $meta = stream_get_meta_data($stream);
  146. $this->assertEquals('plainfile', $meta['wrapper_type']);
  147. fclose($stream);
  148. }
  149. public function testReturnQuotaStreamOnWrite(): void {
  150. $instance = $this->getLimitedStorage(9);
  151. $stream = $instance->fopen('files/foo', 'w+');
  152. $meta = stream_get_meta_data($stream);
  153. $expected_type = 'user-space';
  154. $this->assertEquals($expected_type, $meta['wrapper_type']);
  155. fclose($stream);
  156. }
  157. public function testSpaceRoot(): void {
  158. $storage = $this->getMockBuilder(Local::class)->disableOriginalConstructor()->getMock();
  159. $cache = $this->getMockBuilder('\OC\Files\Cache\Cache')->disableOriginalConstructor()->getMock();
  160. $storage->expects($this->once())
  161. ->method('getCache')
  162. ->willReturn($cache);
  163. $storage->expects($this->once())
  164. ->method('free_space')
  165. ->willReturn(2048);
  166. $cache->expects($this->once())
  167. ->method('get')
  168. ->with('files')
  169. ->willReturn(new CacheEntry(['size' => 50]));
  170. $instance = new \OC\Files\Storage\Wrapper\Quota(['storage' => $storage, 'quota' => 1024, 'root' => 'files']);
  171. $this->assertEquals(1024 - 50, $instance->free_space(''));
  172. }
  173. public function testInstanceOfStorageWrapper(): void {
  174. $this->assertTrue($this->instance->instanceOfStorage('\OC\Files\Storage\Local'));
  175. $this->assertTrue($this->instance->instanceOfStorage('\OC\Files\Storage\Wrapper\Wrapper'));
  176. $this->assertTrue($this->instance->instanceOfStorage('\OC\Files\Storage\Wrapper\Quota'));
  177. }
  178. public function testNoMkdirQuotaZero(): void {
  179. $instance = $this->getLimitedStorage(0.0);
  180. $this->assertFalse($instance->mkdir('files'));
  181. $this->assertFalse($instance->mkdir('files/foobar'));
  182. }
  183. public function testMkdirQuotaZeroTrashbin(): void {
  184. $instance = $this->getLimitedStorage(0.0);
  185. $this->assertTrue($instance->mkdir('files_trashbin'));
  186. $this->assertTrue($instance->mkdir('files_trashbin/files'));
  187. $this->assertTrue($instance->mkdir('files_versions'));
  188. $this->assertTrue($instance->mkdir('cache'));
  189. }
  190. public function testNoTouchQuotaZero(): void {
  191. $instance = $this->getLimitedStorage(0.0);
  192. $this->assertFalse($instance->touch('foobar'));
  193. }
  194. }