WatcherTest.php 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. <?php
  2. /**
  3. * SPDX-FileCopyrightText: 2019-2024 Nextcloud GmbH and Nextcloud contributors
  4. * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
  5. * SPDX-License-Identifier: AGPL-3.0-only
  6. */
  7. namespace OCA\Files_Sharing\Tests;
  8. use OC\Files\Cache\Cache;
  9. use OC\Files\Storage\Storage;
  10. use OC\Files\View;
  11. use OCP\Constants;
  12. use OCP\Share\IShare;
  13. /**
  14. * Class WatcherTest
  15. *
  16. * @group DB
  17. */
  18. class WatcherTest extends TestCase {
  19. /** @var Storage */
  20. private $ownerStorage;
  21. /** @var Cache */
  22. private $ownerCache;
  23. /** @var Storage */
  24. private $sharedStorage;
  25. /** @var Cache */
  26. private $sharedCache;
  27. /** @var IShare */
  28. private $_share;
  29. protected function setUp(): void {
  30. parent::setUp();
  31. self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
  32. // prepare user1's dir structure
  33. $this->view->mkdir('container');
  34. $this->view->mkdir('container/shareddir');
  35. $this->view->mkdir('container/shareddir/subdir');
  36. [$this->ownerStorage, $internalPath] = $this->view->resolvePath('');
  37. $this->ownerCache = $this->ownerStorage->getCache();
  38. $this->ownerStorage->getScanner()->scan('');
  39. // share "shareddir" with user2
  40. $this->_share = $this->share(
  41. IShare::TYPE_USER,
  42. 'container/shareddir',
  43. self::TEST_FILES_SHARING_API_USER1,
  44. self::TEST_FILES_SHARING_API_USER2,
  45. Constants::PERMISSION_ALL
  46. );
  47. $this->_share->setStatus(IShare::STATUS_ACCEPTED);
  48. $this->shareManager->updateShare($this->_share);
  49. // login as user2
  50. self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
  51. // retrieve the shared storage
  52. $secondView = new View('/' . self::TEST_FILES_SHARING_API_USER2);
  53. [$this->sharedStorage, $internalPath] = $secondView->resolvePath('files/shareddir');
  54. $this->sharedCache = $this->sharedStorage->getCache();
  55. }
  56. protected function tearDown(): void {
  57. if ($this->sharedCache) {
  58. $this->sharedCache->clear();
  59. }
  60. self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
  61. if ($this->view) {
  62. $this->shareManager->deleteShare($this->_share);
  63. $this->view->deleteAll('container');
  64. $this->ownerCache->clear();
  65. }
  66. parent::tearDown();
  67. }
  68. /**
  69. * Tests that writing a file using the shared storage will propagate the file
  70. * size to the owner's parent folders.
  71. */
  72. public function testFolderSizePropagationToOwnerStorage(): void {
  73. $initialSizes = self::getOwnerDirSizes('files/container/shareddir');
  74. $textData = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
  75. $dataLen = strlen($textData);
  76. $this->sharedCache->put('bar.txt', ['mtime' => 10, 'storage_mtime' => 10, 'size' => $dataLen, 'mimetype' => 'text/plain']);
  77. $this->sharedStorage->file_put_contents('bar.txt', $textData);
  78. $this->sharedCache->put('', ['mtime' => 10, 'storage_mtime' => 10, 'size' => '-1', 'mimetype' => 'httpd/unix-directory']);
  79. // run the propagation code
  80. $this->sharedStorage->getWatcher()->checkUpdate('');
  81. $this->sharedStorage->getCache()->correctFolderSize('');
  82. // the owner's parent dirs must have increase size
  83. $newSizes = self::getOwnerDirSizes('files/container/shareddir');
  84. $this->assertEquals($initialSizes[''] + $dataLen, $newSizes['']);
  85. $this->assertEquals($initialSizes['files'] + $dataLen, $newSizes['files']);
  86. $this->assertEquals($initialSizes['files/container'] + $dataLen, $newSizes['files/container']);
  87. $this->assertEquals($initialSizes['files/container/shareddir'] + $dataLen, $newSizes['files/container/shareddir']);
  88. // no more updates
  89. $result = $this->sharedStorage->getWatcher()->checkUpdate('');
  90. $this->assertFalse($result);
  91. }
  92. /**
  93. * Tests that writing a file using the shared storage will propagate the file
  94. * size to the owner's parent folders.
  95. */
  96. public function testSubFolderSizePropagationToOwnerStorage(): void {
  97. $initialSizes = self::getOwnerDirSizes('files/container/shareddir/subdir');
  98. $textData = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
  99. $dataLen = strlen($textData);
  100. $this->sharedCache->put('subdir/bar.txt', ['mtime' => 10, 'storage_mtime' => 10, 'size' => $dataLen, 'mimetype' => 'text/plain']);
  101. $this->sharedStorage->file_put_contents('subdir/bar.txt', $textData);
  102. $this->sharedCache->put('subdir', ['mtime' => 10, 'storage_mtime' => 10, 'size' => $dataLen, 'mimetype' => 'text/plain']);
  103. // run the propagation code
  104. $this->sharedStorage->getWatcher()->checkUpdate('subdir');
  105. $this->sharedStorage->getCache()->correctFolderSize('subdir');
  106. // the owner's parent dirs must have increase size
  107. $newSizes = self::getOwnerDirSizes('files/container/shareddir/subdir');
  108. $this->assertEquals($initialSizes[''] + $dataLen, $newSizes['']);
  109. $this->assertEquals($initialSizes['files'] + $dataLen, $newSizes['files']);
  110. $this->assertEquals($initialSizes['files/container'] + $dataLen, $newSizes['files/container']);
  111. $this->assertEquals($initialSizes['files/container/shareddir'] + $dataLen, $newSizes['files/container/shareddir']);
  112. $this->assertEquals($initialSizes['files/container/shareddir/subdir'] + $dataLen, $newSizes['files/container/shareddir/subdir']);
  113. // no more updates
  114. $result = $this->sharedStorage->getWatcher()->checkUpdate('subdir');
  115. $this->assertFalse($result);
  116. }
  117. /**
  118. * Returns the sizes of the path and its parent dirs in a hash
  119. * where the key is the path and the value is the size.
  120. * @param string $path
  121. */
  122. public function getOwnerDirSizes($path) {
  123. $result = [];
  124. while ($path != '' && $path != '' && $path != '.') {
  125. $cachedData = $this->ownerCache->get($path);
  126. $result[$path] = $cachedData['size'];
  127. $path = dirname($path);
  128. }
  129. $cachedData = $this->ownerCache->get('');
  130. $result[''] = $cachedData['size'];
  131. return $result;
  132. }
  133. }