diff options
author | Vincent Petry <pvince81@owncloud.com> | 2015-06-12 18:50:49 +0200 |
---|---|---|
committer | Vincent Petry <pvince81@owncloud.com> | 2015-06-12 18:52:18 +0200 |
commit | 4497aa4c68051ff75d1587dc1b01676926dfb466 (patch) | |
tree | e298734f2f3ed0abcc19e45db284f6c1e2ca427a /tests/lib/connector | |
parent | bb0ea6336df84d391c0d972a56f27077f632948c (diff) | |
download | nextcloud-server-4497aa4c68051ff75d1587dc1b01676926dfb466.tar.gz nextcloud-server-4497aa4c68051ff75d1587dc1b01676926dfb466.zip |
Webdav PUT small file lock must be shared during hooks
Fixed code path for Webdav PUT of small files to use shared locks during
hook execution, and exclusive during the file operation
This makes it possible for versions to be copied by accessing the file
in a post_write hook.
Diffstat (limited to 'tests/lib/connector')
-rw-r--r-- | tests/lib/connector/sabre/file.php | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/tests/lib/connector/sabre/file.php b/tests/lib/connector/sabre/file.php index 6602a2df24f..834698d90cb 100644 --- a/tests/lib/connector/sabre/file.php +++ b/tests/lib/connector/sabre/file.php @@ -404,4 +404,84 @@ class File extends \Test\TestCase { $params[Filesystem::signal_param_path] ); } + + /** + * Test whether locks are set before and after the operation + */ + public function testPutLocking() { + $view = new \OC\Files\View('/' . $this->user . '/files/'); + + $path = 'test-locking.txt'; + $info = new \OC\Files\FileInfo( + '/' . $this->user . '/files/' . $path, + null, + null, + ['permissions' => \OCP\Constants::PERMISSION_ALL], + null + ); + + $file = new \OC\Connector\Sabre\File($view, $info); + + $this->assertFalse( + $this->isFileLocked($view, $path, \OCP\Lock\ILockingProvider::LOCK_SHARED), + 'File unlocked before put' + ); + $this->assertFalse( + $this->isFileLocked($view, $path, \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE), + 'File unlocked before put' + ); + + $wasLockedPre = false; + $wasLockedPost = false; + $eventHandler = $this->getMockBuilder('\stdclass') + ->setMethods(['writeCallback', 'postWriteCallback']) + ->getMock(); + + // both pre and post hooks might need access to the file, + // so only shared lock is acceptable + $eventHandler->expects($this->once()) + ->method('writeCallback') + ->will($this->returnCallback( + function() use ($view, $path, &$wasLockedPre){ + $wasLockedPre = $this->isFileLocked($view, $path, \OCP\Lock\ILockingProvider::LOCK_SHARED); + $wasLockedPre = $wasLockedPre && !$this->isFileLocked($view, $path, \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE); + } + )); + $eventHandler->expects($this->once()) + ->method('postWriteCallback') + ->will($this->returnCallback( + function() use ($view, $path, &$wasLockedPost){ + $wasLockedPost = $this->isFileLocked($view, $path, \OCP\Lock\ILockingProvider::LOCK_SHARED); + $wasLockedPost = $wasLockedPost && !$this->isFileLocked($view, $path, \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE); + } + )); + + \OCP\Util::connectHook( + Filesystem::CLASSNAME, + Filesystem::signal_write, + $eventHandler, + 'writeCallback' + ); + \OCP\Util::connectHook( + Filesystem::CLASSNAME, + Filesystem::signal_post_write, + $eventHandler, + 'postWriteCallback' + ); + + $this->assertNotEmpty($file->put($this->getStream('test data'))); + + $this->assertTrue($wasLockedPre, 'File was locked during pre-hooks'); + $this->assertTrue($wasLockedPost, 'File was locked during post-hooks'); + + $this->assertFalse( + $this->isFileLocked($view, $path, \OCP\Lock\ILockingProvider::LOCK_SHARED), + 'File unlocked after put' + ); + $this->assertFalse( + $this->isFileLocked($view, $path, \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE), + 'File unlocked after put' + ); + } + } |