WatcherTest.php 5.5 KB

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