Merge pull request #20875 from owncloud/remove-changepropagator

remove old propagation logic
This commit is contained in:
Thomas Müller 2015-12-02 13:03:31 +01:00
commit 8d218bf3ef
8 changed files with 0 additions and 865 deletions

View file

@ -60,8 +60,5 @@ if (OCP\Config::getAppValue('files_external', 'allow_user_mounting', 'yes') == '
"name" => $l->t('External storage')
]);
// connecting hooks
OCP\Util::connectHook('OC_Filesystem', 'post_initMountPoints', '\OC_Mount_Config', 'initMountPointsHook');
$mountProvider = $appContainer->query('OCA\Files_External\Config\ConfigAdapter');
\OC::$server->getMountProviderCollection()->registerProvider($mountProvider);

View file

@ -74,36 +74,6 @@ class OC_Mount_Config {
return true;
}
/**
* Hook that mounts the given user's visible mount points
*
* @param array $data
*/
public static function initMountPointsHook($data) {
if ($data['user']) {
$user = \OC::$server->getUserManager()->get($data['user']);
if (!$user) {
\OC::$server->getLogger()->warning(
'Cannot init external mount points for non-existant user "' . $data['user'] . '".',
['app' => 'files_external']
);
return;
}
$userView = new \OC\Files\View('/' . $user->getUID() . '/files');
$changePropagator = new \OC\Files\Cache\ChangePropagator($userView);
$etagPropagator = new \OCA\Files_External\EtagPropagator($user, $changePropagator, \OC::$server->getConfig());
$etagPropagator->propagateDirtyMountPoints();
\OCP\Util::connectHook(
\OC\Files\Filesystem::CLASSNAME,
\OC\Files\Filesystem::signal_create_mount,
$etagPropagator, 'updateHook');
\OCP\Util::connectHook(
\OC\Files\Filesystem::CLASSNAME,
\OC\Files\Filesystem::signal_delete_mount,
$etagPropagator, 'updateHook');
}
}
/**
* Returns the mount points for the given user.
* The mount point is relative to the data directory.

View file

@ -1,141 +0,0 @@
<?php
/**
* @author Morris Jobke <hey@morrisjobke.de>
* @author Robin Appelman <icewind@owncloud.com>
* @author Vincent Petry <pvince81@owncloud.com>
*
* @copyright Copyright (c) 2015, ownCloud, Inc.
* @license AGPL-3.0
*
* This code is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program 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, version 3,
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
namespace OCA\Files_External;
use OC\Files\Filesystem;
/**
* Updates the etag of parent folders whenever a new external storage mount
* point has been created or deleted. Updates need to be triggered using
* the updateHook() method.
*
* There are two modes of operation:
* - for personal mount points, the etag is propagated directly
* - for system mount points, a dirty flag is saved in the configuration and
* the etag will be updated the next time propagateDirtyMountPoints() is called
*/
class EtagPropagator {
/**
* @var \OCP\IUser
*/
protected $user;
/**
* @var \OC\Files\Cache\ChangePropagator
*/
protected $changePropagator;
/**
* @var \OCP\IConfig
*/
protected $config;
/**
* @param \OCP\IUser $user current user, must match the propagator's
* user
* @param \OC\Files\Cache\ChangePropagator $changePropagator change propagator
* initialized with a view for $user
* @param \OCP\IConfig $config
*/
public function __construct($user, $changePropagator, $config) {
$this->user = $user;
$this->changePropagator = $changePropagator;
$this->config = $config;
}
/**
* Propagate the etag changes for all mountpoints marked as dirty and mark the mountpoints as clean
*
* @param int $time
*/
public function propagateDirtyMountPoints($time = null) {
if ($time === null) {
$time = time();
}
$mountPoints = $this->getDirtyMountPoints();
foreach ($mountPoints as $mountPoint) {
$this->changePropagator->addChange($mountPoint);
$this->config->setUserValue($this->user->getUID(), 'files_external', $mountPoint, $time);
}
if (count($mountPoints)) {
$this->changePropagator->propagateChanges($time);
}
}
/**
* Get all mountpoints we need to update the etag for
*
* @return string[]
*/
protected function getDirtyMountPoints() {
$dirty = array();
$mountPoints = $this->config->getAppKeys('files_external');
foreach ($mountPoints as $mountPoint) {
if (substr($mountPoint, 0, 1) === '/') {
$updateTime = $this->config->getAppValue('files_external', $mountPoint);
$userTime = $this->config->getUserValue($this->user->getUID(), 'files_external', $mountPoint);
if ($updateTime > $userTime) {
$dirty[] = $mountPoint;
}
}
}
return $dirty;
}
/**
* @param string $mountPoint
* @param int $time
*/
protected function markDirty($mountPoint, $time = null) {
if ($time === null) {
$time = time();
}
$this->config->setAppValue('files_external', $mountPoint, $time);
}
/**
* Update etags for mount points for known user
* For global or group mount points, updating the etag for every user is not feasible
* instead we mark the mount point as dirty and update the etag when the filesystem is loaded for the user
* For personal mount points, the change is propagated directly
*
* @param array $params hook parameters
* @param int $time update time to use when marking a mount point as dirty
*/
public function updateHook($params, $time = null) {
if ($time === null) {
$time = time();
}
$users = $params[Filesystem::signal_param_users];
$type = $params[Filesystem::signal_param_mount_type];
$mountPoint = $params[Filesystem::signal_param_path];
$mountPoint = Filesystem::normalizePath($mountPoint);
if ($type === \OC_Mount_Config::MOUNT_TYPE_GROUP or $users === 'all') {
$this->markDirty($mountPoint, $time);
} else {
$this->changePropagator->addChange($mountPoint);
$this->changePropagator->propagateChanges($time);
}
}
}

View file

@ -1,350 +0,0 @@
<?php
/**
* @author Joas Schilling <nickvergessen@owncloud.com>
* @author Morris Jobke <hey@morrisjobke.de>
* @author Robin Appelman <icewind@owncloud.com>
*
* @copyright Copyright (c) 2015, ownCloud, Inc.
* @license AGPL-3.0
*
* This code is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program 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, version 3,
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
namespace Tests\Files_External;
use OC\Files\Filesystem;
use OC\User\User;
/**
* Class EtagPropagator
*
* @group DB
*
* @package Tests\Files_External
*/
class EtagPropagator extends \Test\TestCase {
protected function getUser() {
return new User($this->getUniqueID(), null);
}
/**
* @return \PHPUnit_Framework_MockObject_MockObject | \OC\Files\Cache\ChangePropagator
*/
protected function getChangePropagator() {
return $this->getMockBuilder('\OC\Files\Cache\ChangePropagator')
->disableOriginalConstructor()
->getMock();
}
/**
* @return \PHPUnit_Framework_MockObject_MockObject | \OCP\IConfig
*/
protected function getConfig() {
$appConfig = array();
$userConfig = array();
$mock = $this->getMockBuilder('\OCP\IConfig')
->disableOriginalConstructor()
->getMock();
$mock->expects($this->any())
->method('getAppValue')
->will($this->returnCallback(function ($appId, $key, $default = null) use (&$appConfig) {
if (isset($appConfig[$appId]) and isset($appConfig[$appId][$key])) {
return $appConfig[$appId][$key];
} else {
return $default;
}
}));
$mock->expects($this->any())
->method('setAppValue')
->will($this->returnCallback(function ($appId, $key, $value) use (&$appConfig) {
if (!isset($appConfig[$appId])) {
$appConfig[$appId] = array();
}
$appConfig[$appId][$key] = $value;
}));
$mock->expects($this->any())
->method('getAppKeys')
->will($this->returnCallback(function ($appId) use (&$appConfig) {
if (!isset($appConfig[$appId])) {
$appConfig[$appId] = array();
}
return array_keys($appConfig[$appId]);
}));
$mock->expects($this->any())
->method('getUserValue')
->will($this->returnCallback(function ($userId, $appId, $key, $default = null) use (&$userConfig) {
if (isset($userConfig[$userId]) and isset($userConfig[$userId][$appId]) and isset($userConfig[$userId][$appId][$key])) {
return $userConfig[$userId][$appId][$key];
} else {
return $default;
}
}));
$mock->expects($this->any())
->method('setUserValue')
->will($this->returnCallback(function ($userId, $appId, $key, $value) use (&$userConfig) {
if (!isset($userConfig[$userId])) {
$userConfig[$userId] = array();
}
if (!isset($userConfig[$userId][$appId])) {
$userConfig[$userId][$appId] = array();
}
$userConfig[$userId][$appId][$key] = $value;
}));
return $mock;
}
public function testSingleUserMount() {
$time = time();
$user = $this->getUser();
$config = $this->getConfig();
$changePropagator = $this->getChangePropagator();
$propagator = new \OCA\Files_External\EtagPropagator($user, $changePropagator, $config);
$changePropagator->expects($this->once())
->method('addChange')
->with('/test');
$changePropagator->expects($this->once())
->method('propagateChanges')
->with($time);
$propagator->updateHook(array(
Filesystem::signal_param_path => '/test',
Filesystem::signal_param_mount_type => \OC_Mount_Config::MOUNT_TYPE_USER,
Filesystem::signal_param_users => $user->getUID(),
), $time);
}
public function testGlobalMountNoDirectUpdate() {
$time = time();
$user = $this->getUser();
$config = $this->getConfig();
$changePropagator = $this->getChangePropagator();
$propagator = new \OCA\Files_External\EtagPropagator($user, $changePropagator, $config);
// not updated directly
$changePropagator->expects($this->never())
->method('addChange');
$changePropagator->expects($this->never())
->method('propagateChanges');
$propagator->updateHook(array(
Filesystem::signal_param_path => '/test',
Filesystem::signal_param_mount_type => \OC_Mount_Config::MOUNT_TYPE_USER,
Filesystem::signal_param_users => 'all',
), $time);
// mount point marked as dirty
$this->assertEquals(array('/test'), $config->getAppKeys('files_external'));
$this->assertEquals($time, $config->getAppValue('files_external', '/test'));
}
public function testGroupMountNoDirectUpdate() {
$time = time();
$user = $this->getUser();
$config = $this->getConfig();
$changePropagator = $this->getChangePropagator();
$propagator = new \OCA\Files_External\EtagPropagator($user, $changePropagator, $config);
// not updated directly
$changePropagator->expects($this->never())
->method('addChange');
$changePropagator->expects($this->never())
->method('propagateChanges');
$propagator->updateHook(array(
Filesystem::signal_param_path => '/test',
Filesystem::signal_param_mount_type => \OC_Mount_Config::MOUNT_TYPE_GROUP,
Filesystem::signal_param_users => 'test',
), $time);
// mount point marked as dirty
$this->assertEquals(array('/test'), $config->getAppKeys('files_external'));
$this->assertEquals($time, $config->getAppValue('files_external', '/test'));
}
public function testGlobalMountNoDirtyMountPoint() {
$time = time();
$user = $this->getUser();
$config = $this->getConfig();
$changePropagator = $this->getChangePropagator();
$propagator = new \OCA\Files_External\EtagPropagator($user, $changePropagator, $config);
$changePropagator->expects($this->never())
->method('addChange');
$changePropagator->expects($this->never())
->method('propagateChanges');
$propagator->propagateDirtyMountPoints($time);
$this->assertEquals(0, $config->getUserValue($user->getUID(), 'files_external', '/test', 0));
}
public function testGlobalMountDirtyMountPointFirstTime() {
$time = time();
$user = $this->getUser();
$config = $this->getConfig();
$changePropagator = $this->getChangePropagator();
$propagator = new \OCA\Files_External\EtagPropagator($user, $changePropagator, $config);
$config->setAppValue('files_external', '/test', $time - 10);
$changePropagator->expects($this->once())
->method('addChange')
->with('/test');
$changePropagator->expects($this->once())
->method('propagateChanges')
->with($time);
$propagator->propagateDirtyMountPoints($time);
$this->assertEquals($time, $config->getUserValue($user->getUID(), 'files_external', '/test'));
}
public function testGlobalMountNonDirtyMountPoint() {
$time = time();
$user = $this->getUser();
$config = $this->getConfig();
$changePropagator = $this->getChangePropagator();
$propagator = new \OCA\Files_External\EtagPropagator($user, $changePropagator, $config);
$config->setAppValue('files_external', '/test', $time - 10);
$config->setUserValue($user->getUID(), 'files_external', '/test', $time - 10);
$changePropagator->expects($this->never())
->method('addChange');
$changePropagator->expects($this->never())
->method('propagateChanges');
$propagator->propagateDirtyMountPoints($time);
$this->assertEquals($time - 10, $config->getUserValue($user->getUID(), 'files_external', '/test'));
}
public function testGlobalMountNonDirtyMountPointOtherUser() {
$time = time();
$user = $this->getUser();
$user2 = $this->getUser();
$config = $this->getConfig();
$changePropagator = $this->getChangePropagator();
$propagator = new \OCA\Files_External\EtagPropagator($user, $changePropagator, $config);
$config->setAppValue('files_external', '/test', $time - 10);
$config->setUserValue($user2->getUID(), 'files_external', '/test', $time - 10);
$changePropagator->expects($this->once())
->method('addChange')
->with('/test');
$changePropagator->expects($this->once())
->method('propagateChanges')
->with($time);
$propagator->propagateDirtyMountPoints($time);
$this->assertEquals($time, $config->getUserValue($user->getUID(), 'files_external', '/test'));
}
public function testGlobalMountDirtyMountPointSecondTime() {
$time = time();
$user = $this->getUser();
$config = $this->getConfig();
$changePropagator = $this->getChangePropagator();
$propagator = new \OCA\Files_External\EtagPropagator($user, $changePropagator, $config);
$config->setAppValue('files_external', '/test', $time - 10);
$config->setUserValue($user->getUID(), 'files_external', '/test', $time - 20);
$changePropagator->expects($this->once())
->method('addChange')
->with('/test');
$changePropagator->expects($this->once())
->method('propagateChanges')
->with($time);
$propagator->propagateDirtyMountPoints($time);
$this->assertEquals($time, $config->getUserValue($user->getUID(), 'files_external', '/test'));
}
public function testGlobalMountMultipleUsers() {
$time = time();
$config = $this->getConfig();
$user1 = $this->getUser();
$user2 = $this->getUser();
$user3 = $this->getUser();
$changePropagator1 = $this->getChangePropagator();
$changePropagator2 = $this->getChangePropagator();
$changePropagator3 = $this->getChangePropagator();
$propagator1 = new \OCA\Files_External\EtagPropagator($user1, $changePropagator1, $config);
$propagator2 = new \OCA\Files_External\EtagPropagator($user2, $changePropagator2, $config);
$propagator3 = new \OCA\Files_External\EtagPropagator($user3, $changePropagator3, $config);
$config->setAppValue('files_external', '/test', $time - 10);
$changePropagator1->expects($this->once())
->method('addChange')
->with('/test');
$changePropagator1->expects($this->once())
->method('propagateChanges')
->with($time);
$propagator1->propagateDirtyMountPoints($time);
$this->assertEquals($time, $config->getUserValue($user1->getUID(), 'files_external', '/test'));
$this->assertEquals(0, $config->getUserValue($user2->getUID(), 'files_external', '/test', 0));
$this->assertEquals(0, $config->getUserValue($user3->getUID(), 'files_external', '/test', 0));
$changePropagator2->expects($this->once())
->method('addChange')
->with('/test');
$changePropagator2->expects($this->once())
->method('propagateChanges')
->with($time);
$propagator2->propagateDirtyMountPoints($time);
$this->assertEquals($time, $config->getUserValue($user1->getUID(), 'files_external', '/test'));
$this->assertEquals($time, $config->getUserValue($user2->getUID(), 'files_external', '/test', 0));
$this->assertEquals(0, $config->getUserValue($user3->getUID(), 'files_external', '/test', 0));
}
public function testGlobalMountMultipleDirtyMountPoints() {
$time = time();
$user = $this->getUser();
$config = $this->getConfig();
$changePropagator = $this->getChangePropagator();
$propagator = new \OCA\Files_External\EtagPropagator($user, $changePropagator, $config);
$config->setAppValue('files_external', '/test', $time - 10);
$config->setAppValue('files_external', '/foo', $time - 50);
$config->setAppValue('files_external', '/bar', $time - 70);
$config->setUserValue($user->getUID(), 'files_external', '/foo', $time - 70);
$config->setUserValue($user->getUID(), 'files_external', '/bar', $time - 70);
$changePropagator->expects($this->exactly(2))
->method('addChange');
$changePropagator->expects($this->once())
->method('propagateChanges')
->with($time);
$propagator->propagateDirtyMountPoints($time);
$this->assertEquals($time, $config->getUserValue($user->getUID(), 'files_external', '/test'));
$this->assertEquals($time, $config->getUserValue($user->getUID(), 'files_external', '/foo'));
$this->assertEquals($time - 70, $config->getUserValue($user->getUID(), 'files_external', '/bar'));
}
}

View file

@ -1,125 +0,0 @@
<?php
/**
* @author Morris Jobke <hey@morrisjobke.de>
* @author Robin Appelman <icewind@owncloud.com>
*
* @copyright Copyright (c) 2015, ownCloud, Inc.
* @license AGPL-3.0
*
* This code is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program 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, version 3,
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
namespace OC\Files\Cache;
use OC\Files\Filesystem;
use OC\Hooks\BasicEmitter;
/**
* Propagates changes in etag and mtime up the filesystem tree
*
* @package OC\Files\Cache
*/
class ChangePropagator extends BasicEmitter {
/**
* @var string[]
*/
protected $changedFiles = array();
/**
* @var \OC\Files\View
*/
protected $view;
/**
* @param \OC\Files\View $view
*/
public function __construct(\OC\Files\View $view) {
$this->view = $view;
}
public function addChange($path) {
$this->changedFiles[] = $path;
}
public function getChanges() {
return $this->changedFiles;
}
/**
* propagate the registered changes to their parent folders
*
* @param int $time (optional) the mtime to set for the folders, if not set the current time is used
*/
public function propagateChanges($time = null) {
$changes = $this->getChanges();
$this->changedFiles = [];
if (!$time) {
$time = time();
}
foreach ($changes as $change) {
/**
* @var \OC\Files\Storage\Storage $storage
* @var string $internalPath
*/
$absolutePath = $this->view->getAbsolutePath($change);
$mount = $this->view->getMount($change);
$storage = $mount->getStorage();
$internalPath = $mount->getInternalPath($absolutePath);
if ($storage) {
$propagator = $storage->getPropagator();
$propagatedEntries = $propagator->propagateChange($internalPath, $time);
foreach ($propagatedEntries as $entry) {
$absolutePath = Filesystem::normalizePath($mount->getMountPoint() . '/' . $entry['path']);
$relativePath = $this->view->getRelativePath($absolutePath);
$this->emit('\OC\Files', 'propagate', [$relativePath, $entry]);
}
}
}
}
/**
* @return string[]
*/
public function getAllParents() {
$parents = array();
foreach ($this->getChanges() as $path) {
$parents = array_values(array_unique(array_merge($parents, $this->getParents($path))));
}
return $parents;
}
/**
* get all parent folders of $path
*
* @param string $path
* @return string[]
*/
protected function getParents($path) {
$parts = explode('/', $path);
// remove the singe file
array_pop($parts);
$result = array('/');
$resultPath = '';
foreach ($parts as $part) {
if ($part) {
$resultPath .= '/' . $part;
$result[] = $resultPath;
}
}
return $result;
}
}

View file

@ -26,8 +26,6 @@
namespace OC\Files\Utils;
use OC\Files\View;
use OC\Files\Cache\ChangePropagator;
use OC\Files\Filesystem;
use OC\ForbiddenException;
use OC\Hooks\PublicEmitter;
@ -50,11 +48,6 @@ class Scanner extends PublicEmitter {
*/
private $user;
/**
* @var \OC\Files\Cache\ChangePropagator
*/
protected $propagator;
/**
* @var \OCP\IDBConnection
*/
@ -73,7 +66,6 @@ class Scanner extends PublicEmitter {
public function __construct($user, $db, ILogger $logger) {
$this->logger = $logger;
$this->user = $user;
$this->propagator = new ChangePropagator(new View(''));
$this->db = $db;
}
@ -116,14 +108,6 @@ class Scanner extends PublicEmitter {
$scanner->listen('\OC\Files\Cache\Scanner', 'postScanFolder', function ($path) use ($mount, $emitter) {
$emitter->emit('\OC\Files\Utils\Scanner', 'postScanFolder', array($mount->getMountPoint() . $path));
});
// propagate etag and mtimes when files are changed or removed
$propagator = $this->propagator;
$propagatorListener = function ($path) use ($mount, $propagator) {
$fullPath = Filesystem::normalizePath($mount->getMountPoint() . $path);
$propagator->addChange($fullPath);
};
$scanner->listen('\OC\Files\Cache\Scanner', 'addToCache', $propagatorListener);
$scanner->listen('\OC\Files\Cache\Scanner', 'removeFromCache', $propagatorListener);
}
/**
@ -139,7 +123,6 @@ class Scanner extends PublicEmitter {
$this->attachListener($mount);
$scanner->backgroundScan();
}
$this->propagator->propagateChanges(time());
}
/**
@ -181,7 +164,6 @@ class Scanner extends PublicEmitter {
$this->db->commit();
}
}
$this->propagator->propagateChanges(time());
}
}

View file

@ -1,137 +0,0 @@
<?php
/**
* Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
namespace Test\Files\Cache;
use OC\Files\Filesystem;
use OC\Files\Storage\Temporary;
use OC\Files\View;
/**
* Class ChangePropagator
*
* @group DB
*
* @package Test\Files\Cache
*/
class ChangePropagator extends \Test\TestCase {
/**
* @var \OC\Files\Cache\ChangePropagator
*/
private $propagator;
/**
* @var \OC\Files\View
*/
private $view;
/**
* @var \OC\Files\Storage\Storage
*/
private $storage;
protected function setUp() {
parent::setUp();
$this->storage = new Temporary(array());
$root = $this->getUniqueID('/');
Filesystem::mount($this->storage, array(), $root);
$this->view = new View($root);
$this->propagator = new \OC\Files\Cache\ChangePropagator($this->view);
}
public function testGetParentsSingle() {
$this->propagator->addChange('/foo/bar/asd');
$this->assertEquals(array('/', '/foo', '/foo/bar'), $this->propagator->getAllParents());
}
public function testGetParentsMultiple() {
$this->propagator->addChange('/foo/bar/asd');
$this->propagator->addChange('/foo/qwerty');
$this->propagator->addChange('/foo/asd/bar');
$this->assertEquals(array('/', '/foo', '/foo/bar', '/foo/asd'), $this->propagator->getAllParents());
}
public function testSinglePropagate() {
$this->view->mkdir('/foo');
$this->view->mkdir('/foo/bar');
$this->view->file_put_contents('/foo/bar/sad.txt', 'qwerty');
$oldInfo1 = $this->view->getFileInfo('/');
$oldInfo2 = $this->view->getFileInfo('/foo');
$oldInfo3 = $this->view->getFileInfo('/foo/bar');
$time = time() + 50;
$this->propagator->addChange('/foo/bar/sad.txt');
$this->propagator->propagateChanges($time);
$newInfo1 = $this->view->getFileInfo('/');
$newInfo2 = $this->view->getFileInfo('/foo');
$newInfo3 = $this->view->getFileInfo('/foo/bar');
$this->assertEquals($newInfo1->getMTime(), $time);
$this->assertEquals($newInfo2->getMTime(), $time);
$this->assertEquals($newInfo3->getMTime(), $time);
$this->assertNotSame($oldInfo1->getEtag(), $newInfo1->getEtag());
$this->assertNotSame($oldInfo2->getEtag(), $newInfo2->getEtag());
$this->assertNotSame($oldInfo3->getEtag(), $newInfo3->getEtag());
}
public function testDontLowerMtime() {
$time = time();
$this->view->mkdir('/foo');
$this->view->mkdir('/foo/bar');
$cache = $this->storage->getCache();
$cache->put('', ['mtime' => $time - 50]);
$cache->put('foo', ['mtime' => $time - 150]);
$cache->put('foo/bar', ['mtime' => $time - 250]);
$this->propagator->addChange('/foo/bar/foo');
$this->propagator->propagateChanges($time - 100);
$this->assertEquals(50, $time - $cache->get('')['mtime']);
$this->assertEquals(100, $time - $cache->get('foo')['mtime']);
$this->assertEquals(100, $time - $cache->get('foo/bar')['mtime']);
}
public function testPropagateCrossStorage() {
$storage = new Temporary();
$this->view->mkdir('/foo');
Filesystem::mount($storage, [], $this->view->getAbsolutePath('/foo/submount'));
$this->view->mkdir('/foo/submount/bar');
$this->view->file_put_contents('/foo/submount/bar/sad.txt', 'qwerty');
$oldInfo1 = $this->view->getFileInfo('/');
$oldInfo2 = $this->view->getFileInfo('/foo');
$oldInfo3 = $this->view->getFileInfo('/foo/submount');
$oldInfo4 = $this->view->getFileInfo('/foo/submount/bar');
$time = time() + 50;
$this->propagator->addChange('/foo/submount/bar/sad.txt');
$this->propagator->propagateChanges($time);
$newInfo1 = $this->view->getFileInfo('/');
$newInfo2 = $this->view->getFileInfo('/foo');
$newInfo3 = $this->view->getFileInfo('/foo/submount');
$newInfo4 = $this->view->getFileInfo('/foo/submount/bar');
$this->assertEquals($newInfo1->getMTime(), $time);
$this->assertEquals($newInfo2->getMTime(), $time);
$this->assertEquals($newInfo3->getMTime(), $time);
$this->assertEquals($newInfo4->getMTime(), $time);
$this->assertNotSame($oldInfo1->getEtag(), $newInfo1->getEtag());
$this->assertNotSame($oldInfo2->getEtag(), $newInfo2->getEtag());
$this->assertNotSame($oldInfo3->getEtag(), $newInfo3->getEtag());
$this->assertNotSame($oldInfo4->getEtag(), $newInfo3->getEtag());
}
}

View file

@ -30,14 +30,6 @@ class TestScanner extends \OC\Files\Utils\Scanner {
protected function getMounts($dir) {
return $this->mounts;
}
public function getPropagator() {
return $this->propagator;
}
public function setPropagator($propagator) {
$this->propagator = $propagator;
}
}
/**
@ -144,59 +136,6 @@ class Scanner extends \Test\TestCase {
$this->assertTrue($cache->inCache('folder/bar.txt'));
}
public function testChangePropagator() {
/**
* @var \OC\Files\Cache\ChangePropagator $propagator
*/
$propagator = $this->getMock('\OC\Files\Cache\ChangePropagator', array('propagateChanges'), array(), '', false);
$storage = new Temporary(array());
$mount = new MountPoint($storage, '/foo');
Filesystem::getMountManager()->addMount($mount);
$cache = $storage->getCache();
$storage->mkdir('folder');
$storage->file_put_contents('foo.txt', 'qwerty');
$storage->file_put_contents('folder/bar.txt', 'qwerty');
$scanner = new TestScanner('', \OC::$server->getDatabaseConnection(), \OC::$server->getLogger());
$originalPropagator = $scanner->getPropagator();
$scanner->setPropagator($propagator);
$scanner->addMount($mount);
$scanner->scan('');
$changes = $propagator->getChanges();
$parents = $propagator->getAllParents();
sort($changes);
sort($parents);
$this->assertEquals(array('/foo', '/foo/folder', '/foo/folder/bar.txt', '/foo/foo.txt'), $changes);
$this->assertEquals(array('/', '/foo', '/foo/folder'), $parents);
$cache->put('foo.txt', array('storage_mtime' => time() - 50));
$propagator = $this->getMock('\OC\Files\Cache\ChangePropagator', array('propagateChanges'), array(), '', false);
$scanner->setPropagator($propagator);
$storage->file_put_contents('foo.txt', 'asdasd');
$scanner->scan('');
$changes = $propagator->getChanges();
$parents = $propagator->getAllParents();
$this->assertEquals(array('/foo/foo.txt'), $changes);
$this->assertEquals(array('/', '/foo'), $parents);
$scanner->setPropagator($originalPropagator);
$oldInfo = $cache->get('');
$cache->put('foo.txt', array('storage_mtime' => time() - 70));
$storage->file_put_contents('foo.txt', 'asdasd');
$scanner->scan('');
$newInfo = $cache->get('');
$this->assertNotEquals($oldInfo['etag'], $newInfo['etag']);
}
/**
* @return array
*/