From 988b539dd7d1fef93219f44852208f49d928e67f Mon Sep 17 00:00:00 2001 From: Thomas Mueller Date: Mon, 10 Jun 2013 17:27:21 +0200 Subject: [PATCH 1/7] Let's just use '/' as we do almost everywhere - this change fixes two failing unit tests --- lib/autoloader.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/autoloader.php b/lib/autoloader.php index 9615838a9a..2117063909 100644 --- a/lib/autoloader.php +++ b/lib/autoloader.php @@ -96,8 +96,8 @@ class Autoloader { } else { foreach ($this->prefixPaths as $prefix => $dir) { if (0 === strpos($class, $prefix)) { - $path = str_replace('\\', DIRECTORY_SEPARATOR, $class) . '.php'; - $path = str_replace('_', DIRECTORY_SEPARATOR, $path); + $path = str_replace('\\', '/', $class) . '.php'; + $path = str_replace('_', '/', $path); $paths[] = $dir . '/' . $path; } } From 073306eaa291435a84c86dfeefe8ec4597711b69 Mon Sep 17 00:00:00 2001 From: Thomas Mueller Date: Mon, 10 Jun 2013 18:35:47 +0200 Subject: [PATCH 2/7] [Fixing Updater Unit Tests on Windows] using $internalPath within call to self::correctFolder() because $path inside of it is not processed properly due to directory separator on Windows. error logging has been added in case the given 4path is not found within self::correctFolder --- lib/files/cache/updater.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/files/cache/updater.php b/lib/files/cache/updater.php index 417a47f383..bf86596dfb 100644 --- a/lib/files/cache/updater.php +++ b/lib/files/cache/updater.php @@ -7,6 +7,7 @@ */ namespace OC\Files\Cache; +use OCP\Util; /** * listen to filesystem hooks and change the cache accordingly @@ -40,7 +41,7 @@ class Updater { $scanner = $storage->getScanner($internalPath); $scanner->scan($internalPath, Scanner::SCAN_SHALLOW); $cache->correctFolderSize($internalPath); - self::correctFolder($path, $storage->filemtime($internalPath)); + self::correctFolder($internalPath, $storage->filemtime($internalPath)); } } @@ -116,6 +117,8 @@ class Updater { if ($id !== -1) { $cache->update($id, array('mtime' => $time, 'etag' => $storage->getETag($internalPath))); self::correctFolder($parent, $time); + } else { + Util::writeLog('core', 'Path not in cache: '.$internalPath, Util::ERROR); } } } From c0b25a43752427df90c4a2e6564e8325d12ee4f4 Mon Sep 17 00:00:00 2001 From: Thomas Mueller Date: Mon, 10 Jun 2013 18:47:36 +0200 Subject: [PATCH 3/7] [Fixing Updater Unit Tests on Windows] using $internalPath within call to self::correctFolder() because $path inside of it is not processed properly due to directory separator on Windows. --- lib/files/cache/updater.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/files/cache/updater.php b/lib/files/cache/updater.php index bf86596dfb..de74f1634e 100644 --- a/lib/files/cache/updater.php +++ b/lib/files/cache/updater.php @@ -60,7 +60,7 @@ class Updater { $cache = $storage->getCache($internalPath); $cache->remove($internalPath); $cache->correctFolderSize($internalPath); - self::correctFolder($path, time()); + self::correctFolder($internalPath, time()); } } @@ -85,8 +85,8 @@ class Updater { $cache->move($internalFrom, $internalTo); $cache->correctFolderSize($internalFrom); $cache->correctFolderSize($internalTo); - self::correctFolder($from, time()); - self::correctFolder($to, time()); + self::correctFolder($internalFrom, time()); + self::correctFolder($internalTo, time()); } else { self::deleteUpdate($from); self::writeUpdate($to); From 74a170f2a5e934bca7878fc229ad04cb9cf6e543 Mon Sep 17 00:00:00 2001 From: Thomas Mueller Date: Mon, 10 Jun 2013 19:28:55 +0200 Subject: [PATCH 4/7] [Fixing unit tests in Windows] on windows open resources will be locked while the stream is open. closing the resource allows deletion below --- lib/files/view.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/files/view.php b/lib/files/view.php index e2fc8d965b..25071709fb 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -386,6 +386,12 @@ class View { $source = $this->fopen($path1 . $postFix1, 'r'); $target = $this->fopen($path2 . $postFix2, 'w'); list($count, $result) = \OC_Helper::streamCopy($source, $target); + + // close open handle - especially $source is necessary because unlink below will + // throw an exception on windows because the file is locked + fclose($source); + fclose($target); + if ($result !== false) { list($storage1, $internalPath1) = Filesystem::resolvePath($absolutePath1 . $postFix1); $storage1->unlink($internalPath1); From 2a3887a5d75b0b81344af04e02d5958cf438717d Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Wed, 12 Jun 2013 15:32:00 -0400 Subject: [PATCH 5/7] Add tests for the updater with mount points --- tests/lib/files/cache/updater.php | 128 +++++++++++++++++++++++++++++- 1 file changed, 125 insertions(+), 3 deletions(-) diff --git a/tests/lib/files/cache/updater.php b/tests/lib/files/cache/updater.php index dad3cd7e65..874a35e2c6 100644 --- a/tests/lib/files/cache/updater.php +++ b/tests/lib/files/cache/updater.php @@ -56,7 +56,7 @@ class Updater extends \PHPUnit_Framework_TestCase { \OC_Hook::connect('OC_Filesystem', 'post_write', '\OC\Files\Cache\Updater', 'writeHook'); \OC_Hook::connect('OC_Filesystem', 'post_delete', '\OC\Files\Cache\Updater', 'deleteHook'); \OC_Hook::connect('OC_Filesystem', 'post_rename', '\OC\Files\Cache\Updater', 'renameHook'); - + \OC_Hook::connect('OC_Filesystem', 'post_touch', '\OC\Files\Cache\Updater', 'touchHook'); } public function tearDown() { @@ -96,6 +96,27 @@ class Updater extends \PHPUnit_Framework_TestCase { $this->assertGreaterThanOrEqual($rootCachedData['mtime'], $mtime); } + public function testWriteWithMountPoints() { + $storage2 = new \OC\Files\Storage\Temporary(array()); + $cache2 = $storage2->getCache(); + Filesystem::mount($storage2, array(), '/' . self::$user . '/files/folder/substorage'); + $folderCachedData = $this->cache->get('folder'); + $substorageCachedData = $cache2->get(''); + Filesystem::file_put_contents('folder/substorage/foo.txt', 'asd'); + $this->assertTrue($cache2->inCache('foo.txt')); + $cachedData = $cache2->get('foo.txt'); + $this->assertEquals(3, $cachedData['size']); + $mtime = $cachedData['mtime']; + + $cachedData = $cache2->get(''); + $this->assertNotEquals($substorageCachedData['etag'], $cachedData['etag']); + $this->assertEquals($mtime, $cachedData['mtime']); + + $cachedData = $this->cache->get('folder'); + $this->assertNotEquals($folderCachedData['etag'], $cachedData['etag']); + $this->assertEquals($mtime, $cachedData['mtime']); + } + public function testDelete() { $textSize = strlen("dummy file data\n"); $imageSize = filesize(\OC::$SERVERROOT . '/core/img/logo.png'); @@ -103,7 +124,7 @@ class Updater extends \PHPUnit_Framework_TestCase { $this->assertEquals(3 * $textSize + $imageSize, $rootCachedData['size']); $this->assertTrue($this->cache->inCache('foo.txt')); - Filesystem::unlink('foo.txt', 'asd'); + Filesystem::unlink('foo.txt'); $this->assertFalse($this->cache->inCache('foo.txt')); $cachedData = $this->cache->get(''); $this->assertEquals(2 * $textSize + $imageSize, $cachedData['size']); @@ -123,6 +144,26 @@ class Updater extends \PHPUnit_Framework_TestCase { $this->assertGreaterThanOrEqual($rootCachedData['mtime'], $cachedData['mtime']); } + public function testDeleteWithMountPoints() { + $storage2 = new \OC\Files\Storage\Temporary(array()); + $cache2 = $storage2->getCache(); + Filesystem::mount($storage2, array(), '/' . self::$user . '/files/folder/substorage'); + Filesystem::file_put_contents('folder/substorage/foo.txt', 'asd'); + $this->assertTrue($cache2->inCache('foo.txt')); + $folderCachedData = $this->cache->get('folder'); + $substorageCachedData = $cache2->get(''); + Filesystem::unlink('folder/substorage/foo.txt'); + $this->assertFalse($cache2->inCache('foo.txt')); + + $cachedData = $cache2->get(''); + $this->assertNotEquals($substorageCachedData['etag'], $cachedData['etag']); + $this->assertGreaterThanOrEqual($substorageCachedData['mtime'], $cachedData['mtime']); + + $cachedData = $this->cache->get('folder'); + $this->assertNotEquals($folderCachedData['etag'], $cachedData['etag']); + $this->assertGreaterThanOrEqual($folderCachedData['mtime'], $cachedData['mtime']); + } + public function testRename() { $textSize = strlen("dummy file data\n"); $imageSize = filesize(\OC::$SERVERROOT . '/core/img/logo.png'); @@ -142,4 +183,85 @@ class Updater extends \PHPUnit_Framework_TestCase { $this->assertEquals(3 * $textSize + $imageSize, $cachedData['size']); $this->assertNotEquals($rootCachedData['etag'], $cachedData['etag']); } -} + + public function testRenameWithMountPoints() { + $storage2 = new \OC\Files\Storage\Temporary(array()); + $cache2 = $storage2->getCache(); + Filesystem::mount($storage2, array(), '/' . self::$user . '/files/folder/substorage'); + Filesystem::file_put_contents('folder/substorage/foo.txt', 'asd'); + $this->assertTrue($cache2->inCache('foo.txt')); + $folderCachedData = $this->cache->get('folder'); + $substorageCachedData = $cache2->get(''); + $fooCachedData = $cache2->get('foo.txt'); + Filesystem::rename('folder/substorage/foo.txt', 'folder/substorage/bar.txt'); + $this->assertFalse($cache2->inCache('foo.txt')); + $this->assertTrue($cache2->inCache('bar.txt')); + $cachedData = $cache2->get('bar.txt'); + $this->assertEquals($fooCachedData['fileid'], $cachedData['fileid']); + $mtime = $cachedData['mtime']; + + $cachedData = $cache2->get(''); + $this->assertNotEquals($substorageCachedData['etag'], $cachedData['etag']); + $this->assertEquals($mtime, $cachedData['mtime']); + + $cachedData = $this->cache->get('folder'); + $this->assertNotEquals($folderCachedData['etag'], $cachedData['etag']); + $this->assertEquals($mtime, $cachedData['mtime']); + } + + public function testTouch() { + $rootCachedData = $this->cache->get(''); + $fooCachedData = $this->cache->get('foo.txt'); + Filesystem::touch('foo.txt'); + $cachedData = $this->cache->get('foo.txt'); + $this->assertNotEquals($fooCachedData['etag'], $cachedData['etag']); + $this->assertGreaterThanOrEqual($fooCachedData['mtime'], $cachedData['mtime']); + + $cachedData = $this->cache->get(''); + $this->assertNotEquals($rootCachedData['etag'], $cachedData['etag']); + $this->assertGreaterThanOrEqual($rootCachedData['mtime'], $cachedData['mtime']); + $rootCachedData = $cachedData; + + $time = 1371006070; + $barCachedData = $this->cache->get('folder/bar.txt'); + $folderCachedData = $this->cache->get('folder'); + Filesystem::touch('folder/bar.txt', $time); + $cachedData = $this->cache->get('folder/bar.txt'); + $this->assertNotEquals($barCachedData['etag'], $cachedData['etag']); + $this->assertEquals($time, $cachedData['mtime']); + + $cachedData = $this->cache->get('folder'); + $this->assertNotEquals($folderCachedData['etag'], $cachedData['etag']); + $this->assertEquals($time, $cachedData['mtime']); + + $cachedData = $this->cache->get(''); + $this->assertNotEquals($rootCachedData['etag'], $cachedData['etag']); + $this->assertEquals($time, $cachedData['mtime']); + } + + public function testTouchWithMountPoints() { + $storage2 = new \OC\Files\Storage\Temporary(array()); + $cache2 = $storage2->getCache(); + Filesystem::mount($storage2, array(), '/' . self::$user . '/files/folder/substorage'); + Filesystem::file_put_contents('folder/substorage/foo.txt', 'asd'); + $this->assertTrue($cache2->inCache('foo.txt')); + $folderCachedData = $this->cache->get('folder'); + $substorageCachedData = $cache2->get(''); + $fooCachedData = $cache2->get('foo.txt'); + $cachedData = $cache2->get('foo.txt'); + $time = 1371006070; + Filesystem::touch('folder/substorage/foo.txt', $time); + $cachedData = $cache2->get('foo.txt'); + $this->assertNotEquals($fooCachedData['etag'], $cachedData['etag']); + $this->assertEquals($time, $cachedData['mtime']); + + $cachedData = $cache2->get(''); + $this->assertNotEquals($substorageCachedData['etag'], $cachedData['etag']); + $this->assertEquals($time, $cachedData['mtime']); + + $cachedData = $this->cache->get('folder'); + $this->assertNotEquals($folderCachedData['etag'], $cachedData['etag']); + $this->assertEquals($time, $cachedData['mtime']); + } + +} \ No newline at end of file From 84a8aea410053686678f8efa6ba00ac63d31133e Mon Sep 17 00:00:00 2001 From: Thomas Mueller Date: Thu, 13 Jun 2013 00:09:52 +0200 Subject: [PATCH 6/7] restore Updater functionality on non-Windows platforms --- lib/files/cache/updater.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/files/cache/updater.php b/lib/files/cache/updater.php index de74f1634e..6fee0d5845 100644 --- a/lib/files/cache/updater.php +++ b/lib/files/cache/updater.php @@ -41,7 +41,7 @@ class Updater { $scanner = $storage->getScanner($internalPath); $scanner->scan($internalPath, Scanner::SCAN_SHALLOW); $cache->correctFolderSize($internalPath); - self::correctFolder($internalPath, $storage->filemtime($internalPath)); + self::correctFolder($path, $storage->filemtime($internalPath)); } } @@ -60,7 +60,7 @@ class Updater { $cache = $storage->getCache($internalPath); $cache->remove($internalPath); $cache->correctFolderSize($internalPath); - self::correctFolder($internalPath, time()); + self::correctFolder($path, time()); } } @@ -85,8 +85,8 @@ class Updater { $cache->move($internalFrom, $internalTo); $cache->correctFolderSize($internalFrom); $cache->correctFolderSize($internalTo); - self::correctFolder($internalFrom, time()); - self::correctFolder($internalTo, time()); + self::correctFolder($from, time()); + self::correctFolder($to, time()); } else { self::deleteUpdate($from); self::writeUpdate($to); From 87521f6c6e19bb2cff21ad0792604d24a6d6403e Mon Sep 17 00:00:00 2001 From: Thomas Mueller Date: Fri, 14 Jun 2013 11:59:30 +0200 Subject: [PATCH 7/7] dirname('/test.txt') returns '\' on windows whereas on linux we get back '.' --- lib/files/cache/updater.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/files/cache/updater.php b/lib/files/cache/updater.php index 6fee0d5845..87c33a313a 100644 --- a/lib/files/cache/updater.php +++ b/lib/files/cache/updater.php @@ -103,7 +103,7 @@ class Updater { static public function correctFolder($path, $time) { if ($path !== '' && $path !== '/') { $parent = dirname($path); - if ($parent === '.') { + if ($parent === '.' || $parent === '\\') { $parent = ''; } /**