From c8df27de73f845f6d1661386f06304b7c209e7d7 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Fri, 25 Oct 2013 12:33:16 +0200 Subject: Fixed quota stream to not wrap read-only fopen calls --- tests/lib/files/storage/wrapper/quota.php | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'tests/lib/files/storage') diff --git a/tests/lib/files/storage/wrapper/quota.php b/tests/lib/files/storage/wrapper/quota.php index 3702f8154f5..9b14335782f 100644 --- a/tests/lib/files/storage/wrapper/quota.php +++ b/tests/lib/files/storage/wrapper/quota.php @@ -58,4 +58,26 @@ class Quota extends \Test\Files\Storage\Storage { fclose($stream); $this->assertEquals('foobarqwe', $instance->file_get_contents('foo')); } + + public function testReturnRegularStreamOnRead(){ + $instance = $this->getLimitedStorage(9); + + // create test file first + $stream = $instance->fopen('foo', 'w+'); + fwrite($stream, 'blablacontent'); + fclose($stream); + + $stream = $instance->fopen('foo', 'r'); + $meta = stream_get_meta_data($stream); + $this->assertEquals('plainfile', $meta['wrapper_type']); + fclose($stream); + } + + public function testReturnQuotaStreamOnWrite(){ + $instance = $this->getLimitedStorage(9); + $stream = $instance->fopen('foo', 'w+'); + $meta = stream_get_meta_data($stream); + $this->assertEquals('user-space', $meta['wrapper_type']); + fclose($stream); + } } -- cgit v1.2.3 From f1e6e80eb1be9a6ef4e96e1e6c4a3e838bbd69db Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Tue, 29 Oct 2013 00:14:23 +0100 Subject: add specialized storage backend for home folders --- lib/private/files/storage/home.php | 31 +++++++++++++++++ tests/lib/files/storage/home.php | 71 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+) create mode 100644 lib/private/files/storage/home.php create mode 100644 tests/lib/files/storage/home.php (limited to 'tests/lib/files/storage') diff --git a/lib/private/files/storage/home.php b/lib/private/files/storage/home.php new file mode 100644 index 00000000000..47a76c1b840 --- /dev/null +++ b/lib/private/files/storage/home.php @@ -0,0 +1,31 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC\Files\Storage; + +/** + * Specialized version of Local storage for home directory usage + */ +class Home extends Local { + /** + * @var \OC\User\User $user + */ + protected $user; + + public function __construct($arguments) { + $this->user = $arguments['user']; + $this->datadir = $this->user->getHome(); + if (substr($this->datadir, -1) !== '/') { + $this->datadir .= '/'; + } + } + + public function getId() { + return 'home::' . $this->user->getUID(); + } +} diff --git a/tests/lib/files/storage/home.php b/tests/lib/files/storage/home.php new file mode 100644 index 00000000000..b01e07f7457 --- /dev/null +++ b/tests/lib/files/storage/home.php @@ -0,0 +1,71 @@ +. + * + */ + +namespace Test\Files\Storage; + +use OC\User\User; + +class DummyUser extends User { + private $home; + + private $uid; + + public function __construct($uid, $home) { + $this->uid = $uid; + $this->home = $home; + } + + public function getHome() { + return $this->home; + } + + public function getUID() { + return $this->uid; + } +} + +class Home extends Storage { + /** + * @var string tmpDir + */ + private $tmpDir; + + /** + * @var \OC\User\User $user + */ + private $user; + + public function setUp() { + $this->tmpDir = \OC_Helper::tmpFolder(); + $userId = uniqid('user_'); + $this->user = new DummyUser($userId, $this->tmpDir); + $this->instance = new \OC\Files\Storage\Home(array('user' => $this->user)); + } + + public function tearDown() { + \OC_Helper::rmdirr($this->tmpDir); + } + + public function testRoot() { + $this->assertEquals($this->tmpDir, $this->instance->getLocalFolder('')); + } +} -- cgit v1.2.3 From 10b2d649afde879036a00c82d2acb3fc41b70f7e Mon Sep 17 00:00:00 2001 From: Jörn Friedrich Dreyer Date: Thu, 31 Oct 2013 11:55:58 +0100 Subject: extend unit test to directories starting or ending in whitespace --- tests/lib/files/storage/storage.php | 41 +++++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 15 deletions(-) (limited to 'tests/lib/files/storage') diff --git a/tests/lib/files/storage/storage.php b/tests/lib/files/storage/storage.php index 3f339a10016..f72a5276db5 100644 --- a/tests/lib/files/storage/storage.php +++ b/tests/lib/files/storage/storage.php @@ -42,18 +42,21 @@ abstract class Storage extends \PHPUnit_Framework_TestCase { $this->assertTrue($this->instance->isUpdatable('/'), 'Root folder is not writable'); } - public function testDirectories() { - $this->assertFalse($this->instance->file_exists('/folder')); + /** + * @dataProvider directoryProvider + */ + public function testDirectories($directory) { + $this->assertFalse($this->instance->file_exists('/'.$directory)); - $this->assertTrue($this->instance->mkdir('/folder')); + $this->assertTrue($this->instance->mkdir('/'.$directory)); - $this->assertTrue($this->instance->file_exists('/folder')); - $this->assertTrue($this->instance->is_dir('/folder')); - $this->assertFalse($this->instance->is_file('/folder')); - $this->assertEquals('dir', $this->instance->filetype('/folder')); - $this->assertEquals(0, $this->instance->filesize('/folder')); - $this->assertTrue($this->instance->isReadable('/folder')); - $this->assertTrue($this->instance->isUpdatable('/folder')); + $this->assertTrue($this->instance->file_exists('/'.$directory)); + $this->assertTrue($this->instance->is_dir('/'.$directory)); + $this->assertFalse($this->instance->is_file('/'.$directory)); + $this->assertEquals('dir', $this->instance->filetype('/'.$directory)); + $this->assertEquals(0, $this->instance->filesize('/'.$directory)); + $this->assertTrue($this->instance->isReadable('/'.$directory)); + $this->assertTrue($this->instance->isUpdatable('/'.$directory)); $dh = $this->instance->opendir('/'); $content = array(); @@ -62,14 +65,14 @@ abstract class Storage extends \PHPUnit_Framework_TestCase { $content[] = $file; } } - $this->assertEquals(array('folder'), $content); + $this->assertEquals(array($directory), $content); - $this->assertFalse($this->instance->mkdir('/folder')); //cant create existing folders - $this->assertTrue($this->instance->rmdir('/folder')); + $this->assertFalse($this->instance->mkdir('/'.$directory)); //cant create existing folders + $this->assertTrue($this->instance->rmdir('/'.$directory)); - $this->assertFalse($this->instance->file_exists('/folder')); + $this->assertFalse($this->instance->file_exists('/'.$directory)); - $this->assertFalse($this->instance->rmdir('/folder')); //cant remove non existing folders + $this->assertFalse($this->instance->rmdir('/'.$directory)); //cant remove non existing folders $dh = $this->instance->opendir('/'); $content = array(); @@ -81,6 +84,14 @@ abstract class Storage extends \PHPUnit_Framework_TestCase { $this->assertEquals(array(), $content); } + public function directoryProvider() + { + return array( + array('folder'), + array(' folder'), + array('folder '), + ); + } /** * test the various uses of file_get_contents and file_put_contents */ -- cgit v1.2.3 From 34c92f665639baf6ea86a265855a2b2862755537 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Tue, 12 Nov 2013 15:46:01 +0100 Subject: Now using HomeStorage for legacy home storage ids Legacy home storage ids with the format "local://path/to/datadir/user1" are now also wrapped by the HomeStorage. --- lib/private/files/filesystem.php | 14 +++++++-- lib/private/files/storage/home.php | 14 ++++++++- tests/lib/files/filesystem.php | 64 ++++++++++++++++++++++++++++++++++++++ tests/lib/files/storage/home.php | 29 +++++++++++++++-- 4 files changed, 115 insertions(+), 6 deletions(-) (limited to 'tests/lib/files/storage') diff --git a/lib/private/files/filesystem.php b/lib/private/files/filesystem.php index e40502bbe64..899666f3e1a 100644 --- a/lib/private/files/filesystem.php +++ b/lib/private/files/filesystem.php @@ -307,10 +307,18 @@ class Filesystem { $root = \OC_User::getHome($user); $userObject = \OC_User::getManager()->get($user); - if (\OC\Files\Cache\Storage::exists('local::' . $root . '/') or is_null($userObject)) { + + if (!is_null($userObject)) { + // check for legacy home id (<= 5.0.12) + if (\OC\Files\Cache\Storage::exists('local::' . $root . '/')) { + self::mount('\OC\Files\Storage\Home', array('user' => $userObject, 'legacy' => true), $user); + } + else { + self::mount('\OC\Files\Storage\Home', array('user' => $userObject), $user); + } + } + else { self::mount('\OC\Files\Storage\Local', array('datadir' => $root), $user); - } else { - self::mount('\OC\Files\Storage\Home', array('user' => $userObject), $user); } $datadir = \OC_Config::getValue("datadirectory", \OC::$SERVERROOT . "/data"); diff --git a/lib/private/files/storage/home.php b/lib/private/files/storage/home.php index 22753519ad3..b4ceb8f4f9b 100644 --- a/lib/private/files/storage/home.php +++ b/lib/private/files/storage/home.php @@ -12,6 +12,11 @@ namespace OC\Files\Storage; * Specialized version of Local storage for home directory usage */ class Home extends Local { + /** + * @var string + */ + protected $id; + /** * @var \OC\User\User $user */ @@ -20,12 +25,19 @@ class Home extends Local { public function __construct($arguments) { $this->user = $arguments['user']; $datadir = $this->user->getHome(); + if (isset($arguments['legacy']) && $arguments['legacy']) { + // legacy home id (<= 5.0.12) + $this->id = 'local::' . $datadir . '/'; + } + else { + $this->id = 'home::' . $this->user->getUID(); + } parent::__construct(array('datadir' => $datadir)); } public function getId() { - return 'home::' . $this->user->getUID(); + return $this->id; } public function getCache($path = '') { diff --git a/tests/lib/files/filesystem.php b/tests/lib/files/filesystem.php index bef70cc725b..990e95ca595 100644 --- a/tests/lib/files/filesystem.php +++ b/tests/lib/files/filesystem.php @@ -41,9 +41,12 @@ class Filesystem extends \PHPUnit_Framework_TestCase { foreach ($this->tmpDirs as $dir) { \OC_Helper::rmdirr($dir); } + \OC\Files\Filesystem::clearMounts(); + \OC_User::setUserId(''); } public function setUp() { + \OC_User::setUserId(''); \OC\Files\Filesystem::clearMounts(); } @@ -103,6 +106,67 @@ class Filesystem extends \PHPUnit_Framework_TestCase { // \OC\Files\Filesystem::file_put_contents('/bar//foo', $fh); } + /** + * Tests that a local storage mount is used when passed user + * does not exist. + */ + public function testLocalMountWhenUserDoesNotExist() { + $datadir = \OC_Config::getValue("datadirectory", \OC::$SERVERROOT . "/data"); + $userId = uniqid('user_'); + + \OC\Files\Filesystem::initMountPoints($userId); + + $homeMount = \OC\Files\Filesystem::getStorage('/' . $userId . '/'); + + $this->assertInstanceOf('\OC\Files\Storage\Local', $homeMount); + $this->assertEquals('local::' . $datadir . '/' . $userId . '/', $homeMount->getId()); + } + + /** + * Tests that the home storage is used for the user's mount point + */ + public function testHomeMount() { + $userId = uniqid('user_'); + + \OC_User::createUser($userId, $userId); + + \OC\Files\Filesystem::initMountPoints($userId); + + $homeMount = \OC\Files\Filesystem::getStorage('/' . $userId . '/'); + + $this->assertInstanceOf('\OC\Files\Storage\Home', $homeMount); + $this->assertEquals('home::' . $userId, $homeMount->getId()); + + \OC_User::deleteUser($userId); + } + + /** + * Tests that the home storage is used in legacy mode + * for the user's mount point + */ + public function testLegacyHomeMount() { + $datadir = \OC_Config::getValue("datadirectory", \OC::$SERVERROOT . "/data"); + $userId = uniqid('user_'); + + // insert storage into DB by constructing it + // to make initMountsPoint find its existence + $localStorage = new \OC\Files\Storage\Local(array('datadir' => $datadir . '/' . $userId . '/')); + // this will trigger the insert + $cache = $localStorage->getCache(); + + \OC_User::createUser($userId, $userId); + \OC\Files\Filesystem::initMountPoints($userId); + + $homeMount = \OC\Files\Filesystem::getStorage('/' . $userId . '/'); + + $this->assertInstanceOf('\OC\Files\Storage\Home', $homeMount); + $this->assertEquals('local::' . $datadir. '/' . $userId . '/', $homeMount->getId()); + + \OC_User::deleteUser($userId); + // delete storage entry + $cache->clear(); + } + public function dummyHook($arguments) { $path = $arguments['path']; $this->assertEquals($path, \OC\Files\Filesystem::normalizePath($path)); //the path passed to the hook should already be normalized diff --git a/tests/lib/files/storage/home.php b/tests/lib/files/storage/home.php index b01e07f7457..885291e4404 100644 --- a/tests/lib/files/storage/home.php +++ b/tests/lib/files/storage/home.php @@ -56,8 +56,8 @@ class Home extends Storage { public function setUp() { $this->tmpDir = \OC_Helper::tmpFolder(); - $userId = uniqid('user_'); - $this->user = new DummyUser($userId, $this->tmpDir); + $this->userId = uniqid('user_'); + $this->user = new DummyUser($this->userId, $this->tmpDir); $this->instance = new \OC\Files\Storage\Home(array('user' => $this->user)); } @@ -65,7 +65,32 @@ class Home extends Storage { \OC_Helper::rmdirr($this->tmpDir); } + /** + * Tests that the root path matches the data dir + */ public function testRoot() { $this->assertEquals($this->tmpDir, $this->instance->getLocalFolder('')); } + + /** + * Tests that the home id is in the format home::user1 + */ + public function testId() { + $this->assertEquals('home::' . $this->userId, $this->instance->getId()); + } + + /** + * Tests that the legacy home id is in the format local::/path/to/datadir/user1/ + */ + public function testLegacyId() { + $this->instance = new \OC\Files\Storage\Home(array('user' => $this->user, 'legacy' => true)); + $this->assertEquals('local::' . $this->tmpDir . '/', $this->instance->getId()); + } + + /** + * Tests that getCache() returns an instance of HomeCache + */ + public function testGetCacheReturnsHomeCache() { + $this->assertInstanceOf('\OC\Files\Cache\HomeCache', $this->instance->getCache()); + } } -- cgit v1.2.3 From 5b6d1d79d06e404ce4a52f75393a98f52769da48 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Thu, 14 Nov 2013 18:39:39 +0100 Subject: Fixed SMB file deletion success detection Since unlink() smb4php doesn't return true on deletion success, we need to check whether the file was deleted to confirm success. Fixes #5866 --- apps/files_external/lib/smb.php | 12 ++++++++++++ tests/lib/files/storage/storage.php | 16 ++++++++++++++-- 2 files changed, 26 insertions(+), 2 deletions(-) (limited to 'tests/lib/files/storage') diff --git a/apps/files_external/lib/smb.php b/apps/files_external/lib/smb.php index c464fa9107a..5bff597fdca 100644 --- a/apps/files_external/lib/smb.php +++ b/apps/files_external/lib/smb.php @@ -81,6 +81,18 @@ class SMB extends \OC\Files\Storage\StreamWrapper{ } } + /** + * Unlinks file + * @param string @path + */ + public function unlink($path) { + unlink($this->constructUrl($path)); + clearstatcache(); + // smb4php still returns false even on success so + // check here whether file was really deleted + return !file_exists($path); + } + /** * check if a file or folder has been updated since $time * @param string $path diff --git a/tests/lib/files/storage/storage.php b/tests/lib/files/storage/storage.php index f72a5276db5..6c433e95475 100644 --- a/tests/lib/files/storage/storage.php +++ b/tests/lib/files/storage/storage.php @@ -182,8 +182,9 @@ abstract class Storage extends \PHPUnit_Framework_TestCase { $this->assertTrue($this->instance->hasUpdated('/lorem.txt', $ctimeStart - 5)); $this->assertTrue($this->instance->hasUpdated('/', $ctimeStart - 5)); - $this->assertTrue(($ctimeStart - 5) <= $mTime); - $this->assertTrue($mTime <= ($ctimeEnd + 1)); + // check that ($ctimeStart - 5) <= $mTime <= ($ctimeEnd + 1) + $this->assertGreaterThanOrEqual(($ctimeStart - 5), $mTime); + $this->assertLessThanOrEqual(($ctimeEnd + 1), $mTime); $this->assertEquals(filesize($textFile), $this->instance->filesize('/lorem.txt')); $stat = $this->instance->stat('/lorem.txt'); @@ -202,6 +203,17 @@ abstract class Storage extends \PHPUnit_Framework_TestCase { $this->assertTrue($this->instance->hasUpdated('/', $mtimeStart - 5)); } + public function testUnlink() { + $textFile = \OC::$SERVERROOT . '/tests/data/lorem.txt'; + $this->instance->file_put_contents('/lorem.txt', file_get_contents($textFile)); + + $this->assertTrue($this->instance->file_exists('/lorem.txt')); + + $this->assertTrue($this->instance->unlink('/lorem.txt')); + + $this->assertFalse($this->instance->file_exists('/lorem.txt')); + } + public function testFOpen() { $textFile = \OC::$SERVERROOT . '/tests/data/lorem.txt'; -- cgit v1.2.3 From af7118aa5db19165bcded3c860b3163488d7b6f6 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Mon, 25 Nov 2013 18:52:14 +0100 Subject: Added unit test for "overwrite file on rename/move" Also fixed "rename" unit test that was ready the result out of the wrong file. --- tests/lib/files/storage/storage.php | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'tests/lib/files/storage') diff --git a/tests/lib/files/storage/storage.php b/tests/lib/files/storage/storage.php index 6c433e95475..be534635ec9 100644 --- a/tests/lib/files/storage/storage.php +++ b/tests/lib/files/storage/storage.php @@ -139,6 +139,12 @@ abstract class Storage extends \PHPUnit_Framework_TestCase { $this->instance->rename('/source.txt', '/target2.txt'); $this->assertTrue($this->instance->file_exists('/target2.txt')); $this->assertFalse($this->instance->file_exists('/source.txt')); + $this->assertEquals(file_get_contents($textFile), $this->instance->file_get_contents('/target2.txt')); + + // move to overwrite + $this->instance->rename('/target2.txt', '/target.txt'); + $this->assertTrue($this->instance->file_exists('/target.txt')); + $this->assertFalse($this->instance->file_exists('/target2.txt')); $this->assertEquals(file_get_contents($textFile), $this->instance->file_get_contents('/target.txt')); } -- cgit v1.2.3 From c3e34676ba0a5467cadc1fd931ed659262705388 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Mon, 25 Nov 2013 18:54:58 +0100 Subject: Improved unit test for "overwrite on move" Now using a different content to make sure the file was overwritten. --- tests/lib/files/storage/storage.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'tests/lib/files/storage') diff --git a/tests/lib/files/storage/storage.php b/tests/lib/files/storage/storage.php index be534635ec9..c627395945e 100644 --- a/tests/lib/files/storage/storage.php +++ b/tests/lib/files/storage/storage.php @@ -142,10 +142,12 @@ abstract class Storage extends \PHPUnit_Framework_TestCase { $this->assertEquals(file_get_contents($textFile), $this->instance->file_get_contents('/target2.txt')); // move to overwrite - $this->instance->rename('/target2.txt', '/target.txt'); - $this->assertTrue($this->instance->file_exists('/target.txt')); + $testContents = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; + $this->instance->file_put_contents('/target3.txt', $testContents); + $this->instance->rename('/target2.txt', '/target3.txt'); + $this->assertTrue($this->instance->file_exists('/target3.txt')); $this->assertFalse($this->instance->file_exists('/target2.txt')); - $this->assertEquals(file_get_contents($textFile), $this->instance->file_get_contents('/target.txt')); + $this->assertEquals(file_get_contents($textFile), $this->instance->file_get_contents('/target3.txt')); } public function testLocal() { -- cgit v1.2.3 From 712b47757af04d6c62fd8da222aa197c23363678 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Tue, 26 Nov 2013 12:53:03 +0100 Subject: Updated unit tests for SMB - coverage for touch return value - fixed directory provider to exclude unsupported cases --- apps/files_external/tests/smb.php | 5 +++++ tests/lib/files/storage/storage.php | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'tests/lib/files/storage') diff --git a/apps/files_external/tests/smb.php b/apps/files_external/tests/smb.php index 0291f293fa6..199e35af676 100644 --- a/apps/files_external/tests/smb.php +++ b/apps/files_external/tests/smb.php @@ -29,6 +29,11 @@ class SMB extends Storage { } } + public function directoryProvider() { + // doesn't support leading/trailing spaces + return array(array('folder')); + } + public function testRenameWithSpaces() { $this->instance->mkdir('with spaces'); $result = $this->instance->rename('with spaces', 'foo bar'); diff --git a/tests/lib/files/storage/storage.php b/tests/lib/files/storage/storage.php index 6c433e95475..5b5b8556859 100644 --- a/tests/lib/files/storage/storage.php +++ b/tests/lib/files/storage/storage.php @@ -236,7 +236,8 @@ abstract class Storage extends \PHPUnit_Framework_TestCase { public function testTouchCreateFile() { $this->assertFalse($this->instance->file_exists('foo')); - $this->instance->touch('foo'); + // returns true on success + $this->assertTrue($this->instance->touch('foo')); $this->assertTrue($this->instance->file_exists('foo')); } -- cgit v1.2.3 From d69243ee5144afeed57f513b0b50f9f2dbcdd36a Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Fri, 29 Nov 2013 12:58:57 +0100 Subject: Fixed FTP and SMB to use rmdir() when deleting folders Some storages need to use different calls for deleting files or folders, usually unlink() and rmdir(). Fixes #4532 (SMB dir deletion) Fixes #5941 (FTP dir deletion) Note that the extra is_dir() should be fast because it's read from the stat cache. --- apps/files_external/lib/ftp.php | 16 ++++++++++++++++ apps/files_external/lib/smb.php | 12 +++++++++--- apps/files_external/lib/streamwrapper.php | 12 ++++++++---- tests/lib/files/storage/storage.php | 14 +++++++++++++- 4 files changed, 46 insertions(+), 8 deletions(-) (limited to 'tests/lib/files/storage') diff --git a/apps/files_external/lib/ftp.php b/apps/files_external/lib/ftp.php index 1f3ebd14b39..00bf7a189ce 100644 --- a/apps/files_external/lib/ftp.php +++ b/apps/files_external/lib/ftp.php @@ -61,6 +61,22 @@ class FTP extends \OC\Files\Storage\StreamWrapper{ $url.='://'.$this->user.':'.$this->password.'@'.$this->host.$this->root.$path; return $url; } + + /** + * Unlinks file or directory + * @param string @path + */ + public function unlink($path) { + if ($this->is_dir($path)) { + return $this->rmdir($path); + } + else { + $url = $this->constructUrl($path); + $result = unlink($url); + clearstatcache(true, $url); + return $result; + } + } public function fopen($path,$mode) { switch($mode) { case 'r': diff --git a/apps/files_external/lib/smb.php b/apps/files_external/lib/smb.php index 5bff597fdca..c5fba92ee68 100644 --- a/apps/files_external/lib/smb.php +++ b/apps/files_external/lib/smb.php @@ -82,12 +82,18 @@ class SMB extends \OC\Files\Storage\StreamWrapper{ } /** - * Unlinks file + * Unlinks file or directory * @param string @path */ public function unlink($path) { - unlink($this->constructUrl($path)); - clearstatcache(); + if ($this->is_dir($path)) { + $this->rmdir($path); + } + else { + $url = $this->constructUrl($path); + unlink($url); + clearstatcache(false, $url); + } // smb4php still returns false even on success so // check here whether file was really deleted return !file_exists($path); diff --git a/apps/files_external/lib/streamwrapper.php b/apps/files_external/lib/streamwrapper.php index 7a1991d4f04..e484325e2fb 100644 --- a/apps/files_external/lib/streamwrapper.php +++ b/apps/files_external/lib/streamwrapper.php @@ -25,8 +25,9 @@ abstract class StreamWrapper extends Common { $this->unlink($path . '/' . $file); } } - $success = rmdir($this->constructUrl($path)); - clearstatcache(); + $url = $this->constructUrl($path); + $success = rmdir($url); + clearstatcache(false, $url); return $success; } else { return false; @@ -46,8 +47,11 @@ abstract class StreamWrapper extends Common { } public function unlink($path) { - $success = unlink($this->constructUrl($path)); - clearstatcache(); + $url = $this->constructUrl($path); + $success = unlink($url); + // normally unlink() is supposed to do this implicitly, + // but doing it anyway just to be sure + clearstatcache(false, $url); return $success; } diff --git a/tests/lib/files/storage/storage.php b/tests/lib/files/storage/storage.php index 19113f52623..5a0581665a2 100644 --- a/tests/lib/files/storage/storage.php +++ b/tests/lib/files/storage/storage.php @@ -254,7 +254,19 @@ abstract class Storage extends \PHPUnit_Framework_TestCase { $this->instance->mkdir('folder/bar'); $this->instance->file_put_contents('folder/asd.txt', 'foobar'); $this->instance->file_put_contents('folder/bar/foo.txt', 'asd'); - $this->instance->rmdir('folder'); + $this->assertTrue($this->instance->rmdir('folder')); + $this->assertFalse($this->instance->file_exists('folder/asd.txt')); + $this->assertFalse($this->instance->file_exists('folder/bar/foo.txt')); + $this->assertFalse($this->instance->file_exists('folder/bar')); + $this->assertFalse($this->instance->file_exists('folder')); + } + + public function testRecursiveUnlink() { + $this->instance->mkdir('folder'); + $this->instance->mkdir('folder/bar'); + $this->instance->file_put_contents('folder/asd.txt', 'foobar'); + $this->instance->file_put_contents('folder/bar/foo.txt', 'asd'); + $this->assertTrue($this->instance->unlink('folder')); $this->assertFalse($this->instance->file_exists('folder/asd.txt')); $this->assertFalse($this->instance->file_exists('folder/bar/foo.txt')); $this->assertFalse($this->instance->file_exists('folder/bar')); -- cgit v1.2.3 From 6cf9844e9c4790342053e00e4dfaf389275e4c79 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Tue, 3 Dec 2013 14:35:53 +0100 Subject: Added unit test for the test() method This is to make sure that method isn't broken --- lib/private/files/storage/wrapper/wrapper.php | 8 ++++++++ tests/lib/files/storage/storage.php | 7 +++++++ 2 files changed, 15 insertions(+) (limited to 'tests/lib/files/storage') diff --git a/lib/private/files/storage/wrapper/wrapper.php b/lib/private/files/storage/wrapper/wrapper.php index 0336c27efa1..f9adda80314 100644 --- a/lib/private/files/storage/wrapper/wrapper.php +++ b/lib/private/files/storage/wrapper/wrapper.php @@ -424,4 +424,12 @@ class Wrapper implements \OC\Files\Storage\Storage { public function getETag($path) { return $this->storage->getETag($path); } + + /** + * Returns true + * @return true + */ + public function test() { + return $this->storage->test(); + } } diff --git a/tests/lib/files/storage/storage.php b/tests/lib/files/storage/storage.php index 5a0581665a2..182c014d999 100644 --- a/tests/lib/files/storage/storage.php +++ b/tests/lib/files/storage/storage.php @@ -42,6 +42,13 @@ abstract class Storage extends \PHPUnit_Framework_TestCase { $this->assertTrue($this->instance->isUpdatable('/'), 'Root folder is not writable'); } + /** + * Check that the test() function works + */ + public function testTestFunction() { + $this->assertTrue($this->instance->test()); + } + /** * @dataProvider directoryProvider */ -- cgit v1.2.3 From 1af7dab5358d7fd495e4382037c6e2528e2b76d5 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Sun, 19 Jan 2014 18:49:51 +0100 Subject: Fixed quota wrapper to not wrap failed fopen streams When calling fopen() on some storage types, these return false instead of throwing an exception. This fix makes sure that in case the stream wasn't opened (for example when a file doesn't exist any more) the stream isn't wrapped. Also added 'rb' as another case that doesn't need to be wrapped. Fixes #6832 --- lib/private/files/storage/wrapper/quota.php | 2 +- tests/lib/files/storage/wrapper/quota.php | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) (limited to 'tests/lib/files/storage') diff --git a/lib/private/files/storage/wrapper/quota.php b/lib/private/files/storage/wrapper/quota.php index 43016e0892f..a430e3e4617 100644 --- a/lib/private/files/storage/wrapper/quota.php +++ b/lib/private/files/storage/wrapper/quota.php @@ -95,7 +95,7 @@ class Quota extends Wrapper { public function fopen($path, $mode) { $source = $this->storage->fopen($path, $mode); $free = $this->free_space(''); - if ($free >= 0 && $mode !== 'r') { + if ($source && $free >= 0 && $mode !== 'r' && $mode !== 'rb') { return \OC\Files\Stream\Quota::wrap($source, $free); } else { return $source; diff --git a/tests/lib/files/storage/wrapper/quota.php b/tests/lib/files/storage/wrapper/quota.php index 9b14335782f..87bafb64d41 100644 --- a/tests/lib/files/storage/wrapper/quota.php +++ b/tests/lib/files/storage/wrapper/quota.php @@ -59,6 +59,20 @@ class Quota extends \Test\Files\Storage\Storage { $this->assertEquals('foobarqwe', $instance->file_get_contents('foo')); } + public function testReturnFalseWhenFopenFailed(){ + $failStorage = $this->getMock( + '\OC\Files\Storage\Local', + array('fopen'), + array(array('datadir' => $this->tmpDir))); + $failStorage->expects($this->any()) + ->method('fopen') + ->will($this->returnValue(false)); + + $instance = new \OC\Files\Storage\Wrapper\Quota(array('storage' => $failStorage, 'quota' => 1000)); + + $this->assertFalse($instance->fopen('failedfopen', 'r')); + } + public function testReturnRegularStreamOnRead(){ $instance = $this->getLimitedStorage(9); @@ -71,6 +85,11 @@ class Quota extends \Test\Files\Storage\Storage { $meta = stream_get_meta_data($stream); $this->assertEquals('plainfile', $meta['wrapper_type']); fclose($stream); + + $stream = $instance->fopen('foo', 'rb'); + $meta = stream_get_meta_data($stream); + $this->assertEquals('plainfile', $meta['wrapper_type']); + fclose($stream); } public function testReturnQuotaStreamOnWrite(){ -- cgit v1.2.3