Sfoglia il codice sorgente

Added unit tests for shared files watcher

- Added base class for sharing unit tests
- Added unit tests for shared files watched to check for folder size
  propagation
tags/list
Vincent Petry 10 anni fa
parent
commit
9f4fd0161e

+ 9
- 1
apps/files_sharing/lib/watcher.php Vedi File

@@ -38,7 +38,12 @@ class Shared_Watcher extends Watcher {

// find last parent before reaching the shared storage root,
// which is the actual shared dir from the owner
$baseDir = substr($path, 0, strpos($path, '/'));
$sepPos = strpos($path, '/');
if ($sepPos > 0) {
$baseDir = substr($path, 0, $sepPos);
} else {
$baseDir = $path;
}

// find the path relative to the data dir
$file = $this->storage->getFile($baseDir);
@@ -49,7 +54,10 @@ class Shared_Watcher extends Watcher {

// update the parent dirs' sizes in the owner's cache
$storage->getCache()->correctFolderSize(dirname($internalPath));

return true;
}
return false;
}

/**

+ 4
- 107
apps/files_sharing/tests/api.php Vedi File

@@ -20,90 +20,33 @@
*
*/

require_once __DIR__ . '/../../../lib/base.php';
require_once __DIR__ . '/base.php';

use OCA\Files\Share;

/**
* Class Test_Files_Sharing_Api
*/
class Test_Files_Sharing_Api extends \PHPUnit_Framework_TestCase {

const TEST_FILES_SHARING_API_USER1 = "test-share-user1";
const TEST_FILES_SHARING_API_USER2 = "test-share-user2";
const TEST_FILES_SHARING_API_USER3 = "test-share-user3";

public $stateFilesEncryption;
public $filename;
public $data;
/**
* @var OC_FilesystemView
*/
public $view;
public $folder;

public static function setUpBeforeClass() {
// reset backend
\OC_User::clearBackends();
\OC_User::useBackend('database');

// clear share hooks
\OC_Hook::clear('OCP\\Share');
\OC::registerShareHooks();
\OCP\Util::connectHook('OC_Filesystem', 'setup', '\OC\Files\Storage\Shared', 'setup');

// create users
self::loginHelper(\Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER1, true);
self::loginHelper(\Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER2, true);
self::loginHelper(\Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER3, true);

}
class Test_Files_Sharing_Api extends Test_Files_Sharing_Base {

function setUp() {

//login as user1
\Test_Files_Sharing_Api::loginHelper(\Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER1);

$this->data = 'foobar';
$this->view = new \OC_FilesystemView('/' . \Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER1 . '/files');
parent::setUp();

$this->folder = '/folder_share_api_test';

$this->filename = 'share-api-test.txt';

// remember files_encryption state
$this->stateFilesEncryption = \OC_App::isEnabled('files_encryption');

//we don't want to tests with app files_encryption enabled
\OC_App::disable('files_encryption');


$this->assertTrue(!\OC_App::isEnabled('files_encryption'));

// save file with content
$this->view->file_put_contents($this->filename, $this->data);
$this->view->mkdir($this->folder);
$this->view->file_put_contents($this->folder.'/'.$this->filename, $this->data);

}

function tearDown() {
$this->view->unlink($this->filename);
$this->view->deleteAll($this->folder);
// reset app files_encryption
if ($this->stateFilesEncryption) {
\OC_App::enable('files_encryption');
} else {
\OC_App::disable('files_encryption');
}
}

public static function tearDownAfterClass() {

// cleanup users
\OC_User::deleteUser(\Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER1);
\OC_User::deleteUser(\Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER2);
\OC_User::deleteUser(\Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER3);
parent::tearDown();
}

/**
@@ -548,50 +491,4 @@ class Test_Files_Sharing_Api extends \PHPUnit_Framework_TestCase {
$this->assertTrue(empty($itemsAfterDelete));

}

/**
* @param $user
* @param bool $create
* @param bool $password
*/
private static function loginHelper($user, $create = false, $password = false) {
if ($create) {
\OC_User::createUser($user, $user);
}

if ($password === false) {
$password = $user;
}

\OC_Util::tearDownFS();
\OC_User::setUserId('');
\OC\Files\Filesystem::tearDown();
\OC_Util::setupFS($user);
\OC_User::setUserId($user);

$params['uid'] = $user;
$params['password'] = $password;
}

/**
* @brief get some information from a given share
* @param int $shareID
* @return array with: item_source, share_type, share_with, item_type, permissions
*/
private function getShareFromId($shareID) {
$sql = 'SELECT `item_source`, `share_type`, `share_with`, `item_type`, `permissions` FROM `*PREFIX*share` WHERE `id` = ?';
$args = array($shareID);
$query = \OCP\DB::prepare($sql);
$result = $query->execute($args);

$share = Null;

if ($result && $result->numRows() > 0) {
$share = $result->fetchRow();
}

return $share;

}

}

+ 143
- 0
apps/files_sharing/tests/base.php Vedi File

@@ -0,0 +1,143 @@
<?php
/**
* ownCloud
*
* @author Bjoern Schiessle
* @copyright 2013 Bjoern Schiessle <schiessle@owncloud.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
* License as published by the Free Software Foundation; either
* version 3 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
*
* You should have received a copy of the GNU Affero General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
*/

require_once __DIR__ . '/../../../lib/base.php';

use OCA\Files\Share;

/**
* Class Test_Files_Sharing_Base
*
* Base class for sharing tests.
*/
class Test_Files_Sharing_Base extends \PHPUnit_Framework_TestCase {

const TEST_FILES_SHARING_API_USER1 = "test-share-user1";
const TEST_FILES_SHARING_API_USER2 = "test-share-user2";
const TEST_FILES_SHARING_API_USER3 = "test-share-user3";

public $stateFilesEncryption;
public $filename;
public $data;
/**
* @var OC_FilesystemView
*/
public $view;
public $folder;

public static function setUpBeforeClass() {
// reset backend
\OC_User::clearBackends();
\OC_User::useBackend('database');

// clear share hooks
\OC_Hook::clear('OCP\\Share');
\OC::registerShareHooks();
\OCP\Util::connectHook('OC_Filesystem', 'setup', '\OC\Files\Storage\Shared', 'setup');

// create users
self::loginHelper(self::TEST_FILES_SHARING_API_USER1, true);
self::loginHelper(self::TEST_FILES_SHARING_API_USER2, true);
self::loginHelper(self::TEST_FILES_SHARING_API_USER3, true);

}

function setUp() {

//login as user1
self::loginHelper(self::TEST_FILES_SHARING_API_USER1);

$this->data = 'foobar';
$this->view = new \OC_FilesystemView('/' . self::TEST_FILES_SHARING_API_USER1 . '/files');
// remember files_encryption state
$this->stateFilesEncryption = \OC_App::isEnabled('files_encryption');

//we don't want to tests with app files_encryption enabled
\OC_App::disable('files_encryption');


$this->assertTrue(!\OC_App::isEnabled('files_encryption'));
}

function tearDown() {
// reset app files_encryption
if ($this->stateFilesEncryption) {
\OC_App::enable('files_encryption');
} else {
\OC_App::disable('files_encryption');
}
}

public static function tearDownAfterClass() {

// cleanup users
\OC_User::deleteUser(self::TEST_FILES_SHARING_API_USER1);
\OC_User::deleteUser(self::TEST_FILES_SHARING_API_USER2);
\OC_User::deleteUser(self::TEST_FILES_SHARING_API_USER3);
}

/**
* @param $user
* @param bool $create
* @param bool $password
*/
protected static function loginHelper($user, $create = false, $password = false) {
if ($create) {
\OC_User::createUser($user, $user);
}

if ($password === false) {
$password = $user;
}

\OC_Util::tearDownFS();
\OC_User::setUserId('');
\OC\Files\Filesystem::tearDown();
\OC_Util::setupFS($user);
\OC_User::setUserId($user);

$params['uid'] = $user;
$params['password'] = $password;
}

/**
* @brief get some information from a given share
* @param int $shareID
* @return array with: item_source, share_type, share_with, item_type, permissions
*/
protected function getShareFromId($shareID) {
$sql = 'SELECT `item_source`, `share_type`, `share_with`, `item_type`, `permissions` FROM `*PREFIX*share` WHERE `id` = ?';
$args = array($shareID);
$query = \OCP\DB::prepare($sql);
$result = $query->execute($args);

$share = Null;

if ($result && $result->numRows() > 0) {
$share = $result->fetchRow();
}

return $share;

}

}

+ 161
- 0
apps/files_sharing/tests/watcher.php Vedi File

@@ -0,0 +1,161 @@
<?php
/**
* ownCloud
*
* @author Vincent Petry
* @copyright 2013 Vincent Petry <pvince81@owncloud.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
* License as published by the Free Software Foundation; either
* version 3 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
*
* You should have received a copy of the GNU Affero General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
*/
require_once __DIR__ . '/base.php';

class Test_Files_Sharing_Watcher extends Test_Files_Sharing_Base {

function setUp() {
parent::setUp();

self::loginHelper(self::TEST_FILES_SHARING_API_USER1);

// prepare user1's dir structure
$textData = "dummy file data\n";
$this->view->mkdir('container');
$this->view->mkdir('container/shareddir');
$this->view->mkdir('container/shareddir/subdir');

list($this->ownerStorage, $internalPath) = $this->view->resolvePath('');
$this->ownerCache = $this->ownerStorage->getCache();
$this->ownerStorage->getScanner()->scan('');

// share "shareddir" with user2
$fileinfo = $this->view->getFileInfo('container/shareddir');
\OCP\Share::shareItem('folder', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER,
self::TEST_FILES_SHARING_API_USER2, 31);

// login as user2
self::loginHelper(self::TEST_FILES_SHARING_API_USER2);

// retrieve the shared storage
$secondView = new \OC\Files\View('/' . self::TEST_FILES_SHARING_API_USER2);
list($this->sharedStorage, $internalPath) = $secondView->resolvePath('files/Shared/shareddir');
$this->sharedCache = $this->sharedStorage->getCache();
}

function tearDown() {
$this->sharedCache->clear();

$fileinfo = $this->view->getFileInfo('container/shareddir');
\OCP\Share::unshare('folder', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER,
self::TEST_FILES_SHARING_API_USER2);

self::loginHelper(self::TEST_FILES_SHARING_API_USER1);

$this->view->deleteAll('container');

$this->ownerCache->clear();

parent::tearDown();
}

/**
* Tests that writing a file using the shared storage will propagate the file
* size to the owner's parent folders.
*/
function testFolderSizePropagationToOwnerStorage() {
$initialSizes = self::getOwnerDirSizes('files/container/shareddir');

$textData = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$dataLen = strlen($textData);
$this->sharedCache->put('shareddir/bar.txt', array('storage_mtime' => 10));
$this->sharedStorage->file_put_contents('shareddir/bar.txt', $textData);
$this->sharedCache->put('shareddir', array('storage_mtime' => 10));

// run the propagation code
$result = $this->sharedStorage->getWatcher()->checkUpdate('shareddir');

$this->assertTrue($result);

// the owner's parent dirs must have increase size
$newSizes = self::getOwnerDirSizes('files/container/shareddir');
$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']);

// no more updates
$result = $this->sharedStorage->getWatcher()->checkUpdate('shareddir');

$this->assertFalse($result);
}

/**
* 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('shareddir/subdir/bar.txt', array('storage_mtime' => 10));
$this->sharedStorage->file_put_contents('shareddir/subdir/bar.txt', $textData);
$this->sharedCache->put('shareddir/subdir', array('storage_mtime' => 10));

// run the propagation code
$result = $this->sharedStorage->getWatcher()->checkUpdate('shareddir/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('shareddir/subdir');

$this->assertFalse($result);
}

function testNoUpdateOnRoot() {
// no updates when called for root path
$result = $this->sharedStorage->getWatcher()->checkUpdate('');

$this->assertFalse($result);

// FIXME: for some reason when running this "naked" test,
// there will be remaining nonsensical entries in the
// database with a path "test-share-user1/container/..."
}

/**
* Returns the sizes of the path and its parent dirs in a hash
* where the key is the path and the value is the size.
*/
function getOwnerDirSizes($path) {
$result = array();

while ($path != '' && $path != '' && $path != '.') {
$cachedData = $this->ownerCache->get($path);
$result[$path] = $cachedData['size'];
$path = dirname($path);
}
$cachedData = $this->ownerCache->get('');
$result[''] = $cachedData['size'];
return $result;
}
}

Loading…
Annulla
Salva