From 00568af74d8b392ea9f991e3d4069cd50e030030 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Mon, 2 Mar 2015 15:25:31 +0100 Subject: Allow running the async commands from unit tests --- lib/private/command/queuebus.php | 53 ++++++++++++++++++++++++++++++++++++++++ tests/lib/testcase.php | 37 ++++++++++++++++++++++------ 2 files changed, 83 insertions(+), 7 deletions(-) create mode 100644 lib/private/command/queuebus.php diff --git a/lib/private/command/queuebus.php b/lib/private/command/queuebus.php new file mode 100644 index 00000000000..29c769e0107 --- /dev/null +++ b/lib/private/command/queuebus.php @@ -0,0 +1,53 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC\Command; + +use OCP\Command\IBus; +use OCP\Command\ICommand; + +class QueueBus implements IBus { + /** + * @var (ICommand|callable)[] + */ + private $queue; + + /** + * Schedule a command to be fired + * + * @param \OCP\Command\ICommand | callable $command + */ + public function push($command) { + $this->queue[] = $command; + } + + /** + * Require all commands using a trait to be run synchronous + * + * @param string $trait + */ + public function requireSync($trait) { + } + + /** + * @param \OCP\Command\ICommand | callable $command + */ + private function runCommand($command) { + if ($command instanceof ICommand) { + $command->handle(); + } else { + $command(); + } + } + + public function run() { + while ($command = array_shift($this->queue)) { + $this->runCommand($command); + } + } +} diff --git a/tests/lib/testcase.php b/tests/lib/testcase.php index 1ea3aa13547..2b4540120d2 100644 --- a/tests/lib/testcase.php +++ b/tests/lib/testcase.php @@ -22,9 +22,23 @@ namespace Test; +use OC\Command\QueueBus; use OCP\Security\ISecureRandom; abstract class TestCase extends \PHPUnit_Framework_TestCase { + /** + * @var \OC\Command\QueueBus + */ + private $commandBus; + + protected function setUp() { + // overwrite the command bus with one we can run ourselves + $this->commandBus = new QueueBus(); + \OC::$server->registerService('AsyncCommandBus', function(){ + return $this->commandBus; + }); + } + /** * Returns a unique identifier as uniqid() is not reliable sometimes * @@ -55,6 +69,7 @@ abstract class TestCase extends \PHPUnit_Framework_TestCase { /** * Remove all entries from the files map table + * * @param string $dataDir */ static protected function tearDownAfterClassCleanFileMapper($dataDir) { @@ -66,6 +81,7 @@ abstract class TestCase extends \PHPUnit_Framework_TestCase { /** * Remove all entries from the storages table + * * @throws \OC\DatabaseException */ static protected function tearDownAfterClassCleanStorages() { @@ -76,6 +92,7 @@ abstract class TestCase extends \PHPUnit_Framework_TestCase { /** * Remove all entries from the filecache table + * * @throws \OC\DatabaseException */ static protected function tearDownAfterClassCleanFileCache() { @@ -91,11 +108,11 @@ abstract class TestCase extends \PHPUnit_Framework_TestCase { */ static protected function tearDownAfterClassCleanStrayDataFiles($dataDir) { $knownEntries = array( - 'owncloud.log' => true, - 'owncloud.db' => true, - '.ocdata' => true, - '..' => true, - '.' => true, + 'owncloud.log' => true, + 'owncloud.db' => true, + '.ocdata' => true, + '..' => true, + '.' => true, ); if ($dh = opendir($dataDir)) { @@ -122,8 +139,7 @@ abstract class TestCase extends \PHPUnit_Framework_TestCase { $path = $dir . '/' . $file; if (is_dir($path)) { self::tearDownAfterClassCleanStrayDataUnlinkDir($path); - } - else { + } else { @unlink($path); } } @@ -169,4 +185,11 @@ abstract class TestCase extends \PHPUnit_Framework_TestCase { \OC_Util::tearDownFS(); \OC_User::setUserId(''); } + + /** + * Run all commands pushed to the bus + */ + protected function runCommands() { + $this->commandBus->run(); + } } -- cgit v1.2.3 From c80522ed63e3225ce1f1353581220c3296ed0590 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Mon, 2 Mar 2015 15:25:50 +0100 Subject: Expire files from the trash in the background --- apps/files_trashbin/command/expire.php | 55 ++++++++++++++++++++++++++++++++++ apps/files_trashbin/lib/trashbin.php | 33 ++++++++++---------- apps/files_trashbin/tests/trashbin.php | 2 ++ 3 files changed, 75 insertions(+), 15 deletions(-) create mode 100644 apps/files_trashbin/command/expire.php diff --git a/apps/files_trashbin/command/expire.php b/apps/files_trashbin/command/expire.php new file mode 100644 index 00000000000..842e061eeb9 --- /dev/null +++ b/apps/files_trashbin/command/expire.php @@ -0,0 +1,55 @@ +. + * + */ + +namespace OCA\Files_Trashbin\Command; + +use OC\Command\FileAccess; +use OCA\Files_Trashbin\Trashbin; +use OCP\Command\ICommand; + +class Expire implements ICommand { + use FileAccess; + + /** + * @var string + */ + private $user; + + /** + * @var int + */ + private $trashBinSize; + + /** + * @param string $user + * @param int $trashBinSize + */ + function __construct($user, $trashBinSize) { + $this->user = $user; + $this->trashBinSize = $trashBinSize; + } + + public function handle() { + \OC_Util::setupFS($this->user); + Trashbin::expire($this->trashBinSize, $this->user); + } +} diff --git a/apps/files_trashbin/lib/trashbin.php b/apps/files_trashbin/lib/trashbin.php index 8ce6d668d66..76395cc95d0 100644 --- a/apps/files_trashbin/lib/trashbin.php +++ b/apps/files_trashbin/lib/trashbin.php @@ -23,6 +23,7 @@ namespace OCA\Files_Trashbin; use OC\Files\Filesystem; +use OCA\Files_Trashbin\Command\Expire; class Trashbin { // how long do we keep files in the trash bin if no other value is defined in the config file (unit: days) @@ -204,13 +205,13 @@ class Trashbin { } $userTrashSize += $size; - $userTrashSize -= self::expire($userTrashSize, $user); + self::scheduleExpire($userTrashSize, $user); // if owner !== user we also need to update the owners trash size if ($owner !== $user) { $ownerTrashSize = self::getTrashbinSize($owner); $ownerTrashSize += $size; - $ownerTrashSize -= self::expire($ownerTrashSize, $owner); + self::scheduleExpire($ownerTrashSize, $owner); } return ($sizeOfAddedFiles === false) ? false : true; @@ -682,26 +683,18 @@ class Trashbin { $freeSpace = self::calculateFreeSpace($size, $user); if ($freeSpace < 0) { - self::expire($size, $user); + self::scheduleExpire($size, $user); } } /** * clean up the trash bin * - * @param int $trashbinSize current size of the trash bin + * @param int $trashBinSize current size of the trash bin * @param string $user - * @return int size of expired files */ - private static function expire($trashbinSize, $user) { - - // let the admin disable auto expire - $autoExpire = \OC_Config::getValue('trashbin_auto_expire', true); - if ($autoExpire === false) { - return 0; - } - - $availableSpace = self::calculateFreeSpace($trashbinSize, $user); + public static function expire($trashBinSize, $user) { + $availableSpace = self::calculateFreeSpace($trashBinSize, $user); $size = 0; $retention_obligation = \OC_Config::getValue('trashbin_retention_obligation', self::DEFAULT_RETENTION_OBLIGATION); @@ -718,8 +711,18 @@ class Trashbin { // delete files from trash until we meet the trash bin size limit again $size += self::deleteFiles(array_slice($dirContent, $count), $user, $availableSpace); + } - return $size; + /**@param int $trashBinSize current size of the trash bin + * @param string $user + */ + private static function scheduleExpire($trashBinSize, $user) { + // let the admin disable auto expire + $autoExpire = \OC_Config::getValue('trashbin_auto_expire', true); + if ($autoExpire === false) { + return; + } + \OC::$server->getCommandBus()->push(new Expire($user, $trashBinSize)); } /** diff --git a/apps/files_trashbin/tests/trashbin.php b/apps/files_trashbin/tests/trashbin.php index 17e38015868..8bc52cc9192 100644 --- a/apps/files_trashbin/tests/trashbin.php +++ b/apps/files_trashbin/tests/trashbin.php @@ -210,6 +210,8 @@ class Test_Trashbin extends \Test\TestCase { \OC\Files\Filesystem::unlink($folder . 'user1-4.txt'); + $this->runCommands(); + $filesInTrashUser2AfterDelete = OCA\Files_Trashbin\Helper::getTrashFiles('/', self::TEST_TRASHBIN_USER2); // user2-1.txt should have been expired -- cgit v1.2.3 From 7cb6811a7b23a2fed96bea65b9ea8aaad512e33a Mon Sep 17 00:00:00 2001 From: Thomas Müller Date: Tue, 10 Mar 2015 11:47:06 +0100 Subject: tearDown the filesystem right before setting it up again --- apps/files_trashbin/command/expire.php | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/files_trashbin/command/expire.php b/apps/files_trashbin/command/expire.php index 842e061eeb9..968608a31cb 100644 --- a/apps/files_trashbin/command/expire.php +++ b/apps/files_trashbin/command/expire.php @@ -49,6 +49,7 @@ class Expire implements ICommand { } public function handle() { + \OC_Util::tearDownFS(); \OC_Util::setupFS($this->user); Trashbin::expire($this->trashBinSize, $this->user); } -- cgit v1.2.3 From 4ffca58bc4d10ce2d7b63790813ab448c198c23f Mon Sep 17 00:00:00 2001 From: Thomas Müller Date: Tue, 10 Mar 2015 11:47:52 +0100 Subject: don't rely on \OCP\User::getUser() - it is not set properly in case of async operations --- apps/files_trashbin/lib/trashbin.php | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/apps/files_trashbin/lib/trashbin.php b/apps/files_trashbin/lib/trashbin.php index 76395cc95d0..38896821c58 100644 --- a/apps/files_trashbin/lib/trashbin.php +++ b/apps/files_trashbin/lib/trashbin.php @@ -423,7 +423,7 @@ class Trashbin { if ($view->is_dir('/files_trashbin/versions/' . $file)) { $rootView->rename(\OC\Files\Filesystem::normalizePath($user . '/files_trashbin/versions/' . $file), \OC\Files\Filesystem::normalizePath($owner . '/files_versions/' . $ownerPath)); - } else if ($versions = self::getVersionsFromTrash($versionedFile, $timestamp)) { + } else if ($versions = self::getVersionsFromTrash($versionedFile, $timestamp, $user)) { foreach ($versions as $v) { if ($timestamp) { $rootView->rename($user . '/files_trashbin/versions/' . $versionedFile . '.v' . $v . '.d' . $timestamp, $owner . '/files_versions/' . $ownerPath . '.v' . $v); @@ -527,8 +527,8 @@ class Trashbin { $file = $filename; } - $size += self::deleteVersions($view, $file, $filename, $timestamp); - $size += self::deleteEncryptionKeys($view, $file, $filename, $timestamp); + $size += self::deleteVersions($view, $file, $filename, $timestamp, $user); + $size += self::deleteEncryptionKeys($view, $file, $filename, $timestamp, $user); if ($view->is_dir('/files_trashbin/files/' . $file)) { $size += self::calculateSize(new \OC\Files\View('/' . $user . '/files_trashbin/files/' . $file)); @@ -549,14 +549,13 @@ class Trashbin { * @param $timestamp * @return int */ - private static function deleteVersions(\OC\Files\View $view, $file, $filename, $timestamp) { + private static function deleteVersions(\OC\Files\View $view, $file, $filename, $timestamp, $user) { $size = 0; if (\OCP\App::isEnabled('files_versions')) { - $user = \OCP\User::getUser(); if ($view->is_dir('files_trashbin/versions/' . $file)) { $size += self::calculateSize(new \OC\Files\view('/' . $user . '/files_trashbin/versions/' . $file)); $view->unlink('files_trashbin/versions/' . $file); - } else if ($versions = self::getVersionsFromTrash($filename, $timestamp)) { + } else if ($versions = self::getVersionsFromTrash($filename, $timestamp, $user)) { foreach ($versions as $v) { if ($timestamp) { $size += $view->filesize('/files_trashbin/versions/' . $filename . '.v' . $v . '.d' . $timestamp); @@ -578,10 +577,9 @@ class Trashbin { * @param $timestamp * @return int */ - private static function deleteEncryptionKeys(\OC\Files\View $view, $file, $filename, $timestamp) { + private static function deleteEncryptionKeys(\OC\Files\View $view, $file, $filename, $timestamp, $user) { $size = 0; if (\OCP\App::isEnabled('files_encryption')) { - $user = \OCP\User::getUser(); $keyfiles = \OC\Files\Filesystem::normalizePath('files_trashbin/keys/' . $filename); @@ -823,8 +821,8 @@ class Trashbin { * @param int $timestamp timestamp when the file was deleted * @return array */ - private static function getVersionsFromTrash($filename, $timestamp) { - $view = new \OC\Files\View('/' . \OCP\User::getUser() . '/files_trashbin/versions'); + private static function getVersionsFromTrash($filename, $timestamp, $user) { + $view = new \OC\Files\View('/' . $user . '/files_trashbin/versions'); $versions = array(); //force rescan of versions, local storage may not have updated the cache -- cgit v1.2.3