public function testWrite() { $textSize = strlen("dummy file data\n"); $imageSize = filesize(\OC::$SERVERROOT . '/core/img/logo.png'); $this->cache->put('foo.txt', array('mtime' => 100, 'storage_mtime' => 150)); $rootCachedData = $this->cache->get(''); $this->assertEquals(3 * $textSize + $imageSize, $rootCachedData['size']); $fooCachedData = $this->cache->get('foo.txt'); Filesystem::file_put_contents('foo.txt', 'asd'); $cachedData = $this->cache->get('foo.txt'); $this->assertEquals(3, $cachedData['size']); $this->assertInternalType('string', $fooCachedData['etag']); $this->assertInternalType('string', $cachedData['etag']); $this->assertNotSame($fooCachedData['etag'], $cachedData['etag']); $cachedData = $this->cache->get(''); $this->assertEquals(2 * $textSize + $imageSize + 3, $cachedData['size']); $this->assertInternalType('string', $rootCachedData['etag']); $this->assertInternalType('string', $cachedData['etag']); $this->assertNotSame($rootCachedData['etag'], $cachedData['etag']); $rootCachedData = $cachedData; $this->assertFalse($this->cache->inCache('bar.txt')); Filesystem::file_put_contents('bar.txt', 'asd'); $this->assertTrue($this->cache->inCache('bar.txt')); $cachedData = $this->cache->get('bar.txt'); $this->assertEquals(3, $cachedData['size']); $mtime = $cachedData['mtime']; $cachedData = $this->cache->get(''); $this->assertEquals(2 * $textSize + $imageSize + 2 * 3, $cachedData['size']); $this->assertInternalType('string', $rootCachedData['etag']); $this->assertInternalType('string', $cachedData['etag']); $this->assertNotSame($rootCachedData['etag'], $cachedData['etag']); $this->assertGreaterThanOrEqual($rootCachedData['mtime'], $mtime); }
/** * @dataProvider maskProvider * @param int $mask */ public function testGetMasked($mask) { $cache = $this->getMaskedCached($mask); $data = array('size' => 100, 'mtime' => 50, 'mimetype' => 'text/plain', 'permissions' => Constants::PERMISSION_ALL); $this->sourceCache->put('foo', $data); $result = $cache->get('foo'); $this->assertEquals($mask, $result['permissions']); $data = array('size' => 100, 'mtime' => 50, 'mimetype' => 'text/plain', 'permissions' => Constants::PERMISSION_ALL - Constants::PERMISSION_DELETE); $this->sourceCache->put('bar', $data); $result = $cache->get('bar'); $this->assertEquals($mask & ~Constants::PERMISSION_DELETE, $result['permissions']); }
function testClearKeepEntriesOutsideJail() { $file1 = 'foo/foobar'; $file2 = 'foo/foobar/asd'; $file3 = 'folder/foobar'; $data1 = array('size' => 100, 'mtime' => 50, 'mimetype' => 'httpd/unix-directory'); $this->sourceCache->put('foo', $data1); $this->sourceCache->put($file1, $data1); $this->sourceCache->put($file2, $data1); $this->sourceCache->put($file3, $data1); $this->cache->clear(); $this->assertFalse($this->cache->inCache('foobar')); $this->assertTrue($this->sourceCache->inCache('folder/foobar')); }
public function testTouch() { $rootCachedData = $this->cache->get(''); $fooCachedData = $this->cache->get('foo.txt'); Filesystem::touch('foo.txt'); $cachedData = $this->cache->get('foo.txt'); $this->assertInternalType('string', $fooCachedData['etag']); $this->assertInternalType('string', $cachedData['etag']); $this->assertGreaterThanOrEqual($fooCachedData['mtime'], $cachedData['mtime']); $cachedData = $this->cache->get(''); $this->assertInternalType('string', $rootCachedData['etag']); $this->assertInternalType('string', $cachedData['etag']); $this->assertNotSame($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'); $this->cache->put('', ['mtime' => $time - 100]); Filesystem::touch('folder/bar.txt', $time); $cachedData = $this->cache->get('folder/bar.txt'); $this->assertInternalType('string', $barCachedData['etag']); $this->assertInternalType('string', $cachedData['etag']); $this->assertNotSame($barCachedData['etag'], $cachedData['etag']); $this->assertEquals($time, $cachedData['mtime']); $cachedData = $this->cache->get('folder'); $this->assertInternalType('string', $folderCachedData['etag']); $this->assertInternalType('string', $cachedData['etag']); $this->assertNotSame($folderCachedData['etag'], $cachedData['etag']); $cachedData = $this->cache->get(''); $this->assertInternalType('string', $rootCachedData['etag']); $this->assertInternalType('string', $cachedData['etag']); $this->assertNotSame($rootCachedData['etag'], $cachedData['etag']); $this->assertEquals($time, $cachedData['mtime']); }
/** * this test shows that there is no bug if we use the normalizer */ public function testWithNormalizer() { if (!class_exists('Patchwork\\PHP\\Shim\\Normalizer')) { $this->markTestSkipped('The 3rdparty Normalizer extension is not available.'); return; } // folder name "Schön" with U+00F6 (normalized) $folderWith00F6 = "Schön"; // folder name "Schön" with U+0308 (un-normalized) $folderWith0308 = "Schön"; $data = array('size' => 100, 'mtime' => 50, 'mimetype' => 'httpd/unix-directory'); // put root folder $this->assertFalse($this->cache->get('folder')); $this->assertGreaterThan(0, $this->cache->put('folder', $data)); // put un-normalized folder $this->assertFalse($this->cache->get('folder/' . $folderWith0308)); $this->assertGreaterThan(0, $this->cache->put('folder/' . $folderWith0308, $data)); // get un-normalized folder by name $unNormalizedFolderName = $this->cache->get('folder/' . $folderWith0308); // check if folder name was normalized $this->assertEquals($folderWith00F6, $unNormalizedFolderName['name']); // put normalized folder $this->assertTrue(is_array($this->cache->get('folder/' . $folderWith00F6))); $this->assertGreaterThan(0, $this->cache->put('folder/' . $folderWith00F6, $data)); // at this point we should have only one folder named "Schön" $this->assertEquals(1, count($this->cache->getFolderContents('folder'))); }
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; $this->cache->put('folder', ['mtime' => $time - 100]); Filesystem::touch('folder/substorage/foo.txt', $time); $cachedData = $cache2->get('foo.txt'); $this->assertInternalType('string', $fooCachedData['etag']); $this->assertInternalType('string', $cachedData['etag']); $this->assertNotSame($fooCachedData['etag'], $cachedData['etag']); $this->assertEquals($time, $cachedData['mtime']); $cachedData = $cache2->get(''); $this->assertInternalType('string', $substorageCachedData['etag']); $this->assertInternalType('string', $cachedData['etag']); $this->assertNotSame($substorageCachedData['etag'], $cachedData['etag']); $cachedData = $this->cache->get('folder'); $this->assertInternalType('string', $folderCachedData['etag']); $this->assertInternalType('string', $cachedData['etag']); $this->assertNotSame($folderCachedData['etag'], $cachedData['etag']); $this->assertEquals($time, $cachedData['mtime']); }
/** * @param string $path * @param array $data */ protected function updateCache($path, $data) { \OC_Hook::emit('Scanner', 'addToCache', array('file' => $path, 'data' => $data)); $this->emit('\\OC\\Files\\Cache\\Scanner', 'updateCache', array($path, $this->storageId, $data)); if ($this->cacheActive) { $this->cache->put($path, $data); } }
/** * @param string $path * @param array $data * @param int $fileId */ protected function updateCache($path, $data, $fileId = -1) { \OC_Hook::emit('Scanner', 'addToCache', array('file' => $path, 'data' => $data)); $this->emit('\OC\Files\Cache\Scanner', 'updateCache', array($path, $this->storageId, $data)); if ($this->cacheActive) { if ($fileId !== -1) { $this->cache->update($fileId, $data); } else { $this->cache->put($path, $data); } } }
public function testNoReuseOfFileId() { $data1 = array('size' => 100, 'mtime' => 50, 'mimetype' => 'text/plain'); $this->cache->put('somefile.txt', $data1); $info = $this->cache->get('somefile.txt'); $fileId = $info['fileid']; $this->cache->remove('somefile.txt'); $data2 = array('size' => 200, 'mtime' => 100, 'mimetype' => 'text/plain'); $this->cache->put('anotherfile.txt', $data2); $info2 = $this->cache->get('anotherfile.txt'); $fileId2 = $info2['fileid']; $this->assertNotEquals($fileId, $fileId2); }
/** * Test bogus paths with leading or doubled slashes * * @dataProvider bogusPathNamesProvider */ public function testBogusPaths($bogusPath, $fixedBogusPath) { $data = array('size' => 100, 'mtime' => 50, 'mimetype' => 'httpd/unix-directory'); // put root folder $this->assertFalse($this->cache->get('')); $parentId = $this->cache->put('', $data); $this->assertGreaterThan(0, $parentId); $this->assertGreaterThan(0, $this->cache->put($bogusPath, $data)); $newData = $this->cache->get($fixedBogusPath); $this->assertNotFalse($newData); $this->assertEquals($fixedBogusPath, $newData['path']); // parent is the correct one, resolved properly (they used to not be) $this->assertEquals($parentId, $newData['parent']); $newDataFromBogus = $this->cache->get($bogusPath); // same entry $this->assertEquals($newData, $newDataFromBogus); }
public function testETagRecreation() { $this->fillTestFolders(); $this->scanner->scan('folder/bar.txt'); // manipulate etag to simulate an empty etag $this->scanner->scan('', \OC\Files\Cache\Scanner::SCAN_SHALLOW, \OC\Files\Cache\Scanner::REUSE_ETAG); $data0 = $this->cache->get('folder/bar.txt'); $this->assertInternalType('string', $data0['etag']); $data1 = $this->cache->get('folder'); $this->assertInternalType('string', $data1['etag']); $data2 = $this->cache->get(''); $this->assertInternalType('string', $data2['etag']); $data0['etag'] = ''; $this->cache->put('folder/bar.txt', $data0); // rescan $this->scanner->scan('folder/bar.txt', \OC\Files\Cache\Scanner::SCAN_SHALLOW, \OC\Files\Cache\Scanner::REUSE_ETAG); // verify cache content $newData0 = $this->cache->get('folder/bar.txt'); $this->assertInternalType('string', $newData0['etag']); $this->assertNotEmpty($newData0['etag']); }
/** * Tests that writing a file using the shared storage will propagate the file * size to the owner's parent folders. */ function testSubFolderSizePropagationToOwnerStorage() { $initialSizes = self::getOwnerDirSizes('files/container/shareddir/subdir'); $textData = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; $dataLen = strlen($textData); $this->sharedCache->put('subdir/bar.txt', array('mtime' => 10, 'storage_mtime' => 10, 'size' => $dataLen, 'mimetype' => 'text/plain')); $this->sharedStorage->file_put_contents('subdir/bar.txt', $textData); $this->sharedCache->put('subdir', array('mtime' => 10, 'storage_mtime' => 10, 'size' => $dataLen, 'mimetype' => 'text/plain')); // run the propagation code $result = $this->sharedStorage->getWatcher()->checkUpdate('subdir'); $this->assertTrue($result); // the owner's parent dirs must have increase size $newSizes = self::getOwnerDirSizes('files/container/shareddir/subdir'); $this->assertEquals($initialSizes[''] + $dataLen, $newSizes['']); $this->assertEquals($initialSizes['files'] + $dataLen, $newSizes['files']); $this->assertEquals($initialSizes['files/container'] + $dataLen, $newSizes['files/container']); $this->assertEquals($initialSizes['files/container/shareddir'] + $dataLen, $newSizes['files/container/shareddir']); $this->assertEquals($initialSizes['files/container/shareddir/subdir'] + $dataLen, $newSizes['files/container/shareddir/subdir']); // no more updates $result = $this->sharedStorage->getWatcher()->checkUpdate('subdir'); $this->assertFalse($result); }
/** * @param string $name * @dataProvider escapingProvider */ public function testEscaping($name) { $data = array('size' => 100, 'mtime' => 50, 'mimetype' => 'text/plain'); $this->cache->put($name, $data); $this->assertTrue($this->cache->inCache($name)); $retrievedData = $this->cache->get($name); foreach ($data as $key => $value) { $this->assertEquals($value, $retrievedData[$key]); } $this->cache->move($name, $name . 'asd'); $this->assertFalse($this->cache->inCache($name)); $this->assertTrue($this->cache->inCache($name . 'asd')); $this->cache->remove($name . 'asd'); $this->assertFalse($this->cache->inCache($name . 'asd')); $folderData = array('size' => 100, 'mtime' => 50, 'mimetype' => 'httpd/unix-directory'); $this->cache->put($name, $folderData); $this->cache->put('other', $folderData); $childs = ['asd', 'bar', 'foo', 'sub/folder']; $this->cache->put($name . '/sub', $folderData); $this->cache->put('other/sub', $folderData); foreach ($childs as $child) { $this->cache->put($name . '/' . $child, $data); $this->cache->put('other/' . $child, $data); $this->assertTrue($this->cache->inCache($name . '/' . $child)); } $this->cache->move($name, $name . 'asd'); foreach ($childs as $child) { $this->assertTrue($this->cache->inCache($name . 'asd/' . $child)); $this->assertTrue($this->cache->inCache('other/' . $child)); } foreach ($childs as $child) { $this->cache->remove($name . 'asd/' . $child); $this->assertFalse($this->cache->inCache($name . 'asd/' . $child)); $this->assertTrue($this->cache->inCache('other/' . $child)); } }
/** * scan all the files and folders in a folder * * @param string $path * @param bool $recursive * @param int $reuse * @return int the size of the scanned folder or -1 if the size is unknown at this stage */ public function scanChildren($path, $recursive = self::SCAN_RECURSIVE, $reuse = -1) { if ($reuse === -1) { $reuse = $recursive === self::SCAN_SHALLOW ? self::REUSE_ETAG | self::REUSE_SIZE : 0; } $this->emit('\\OC\\Files\\Cache\\Scanner', 'scanFolder', array($path, $this->storageId)); $size = 0; $childQueue = array(); $existingChildren = array(); if ($this->cache->inCache($path)) { $children = $this->cache->getFolderContents($path); foreach ($children as $child) { $existingChildren[] = $child['name']; } } $newChildren = array(); if ($this->storage->is_dir($path) && ($dh = $this->storage->opendir($path))) { $exceptionOccurred = false; \OC_DB::beginTransaction(); if (is_resource($dh)) { while (($file = readdir($dh)) !== false) { $child = $path ? $path . '/' . $file : $file; if (!Filesystem::isIgnoredDir($file)) { $newChildren[] = $file; try { $data = $this->scanFile($child, $reuse, true); if ($data) { if ($data['size'] === -1) { if ($recursive === self::SCAN_RECURSIVE) { $childQueue[] = $child; } else { $size = -1; } } else { if ($size !== -1) { $size += $data['size']; } } } } catch (\Doctrine\DBAL\DBALException $ex) { // might happen if inserting duplicate while a scanning // process is running in parallel // log and ignore \OC_Log::write('core', 'Exception while scanning file "' . $child . '": ' . $ex->getMessage(), \OC_Log::DEBUG); $exceptionOccurred = true; } } } } $removedChildren = \array_diff($existingChildren, $newChildren); foreach ($removedChildren as $childName) { $child = $path ? $path . '/' . $childName : $childName; $this->cache->remove($child); } \OC_DB::commit(); if ($exceptionOccurred) { // It might happen that the parallel scan process has already // inserted mimetypes but those weren't available yet inside the transaction // To make sure to have the updated mime types in such cases, // we reload them here $this->cache->loadMimetypes(); } foreach ($childQueue as $child) { $childSize = $this->scanChildren($child, self::SCAN_RECURSIVE, $reuse); if ($childSize === -1) { $size = -1; } else { $size += $childSize; } } $this->cache->put($path, array('size' => $size)); } $this->emit('\\OC\\Files\\Cache\\Scanner', 'postScanFolder', array($path, $this->storageId)); return $size; }
/** * store meta data for a file or folder * * @param string $file * @param array $data * * @return int file id */ public function put($file, array $data) { return $this->cache->put($file, $data); }
/** * Create dummy data in the filecache for the given storage numeric id * * @param string $storageId storage id */ private function createData($storageId) { $cache = new Cache($storageId); $cache->put('dummyfile.txt', array('size' => 5, 'mtime' => 12, 'mimetype' => 'text/plain')); }