diff options
-rw-r--r-- | src/libsync/syncengine.cpp | 8 | ||||
-rw-r--r-- | test/CMakeLists.txt | 1 | ||||
-rwxr-xr-x | test/scripts/txpl/t7.pl | 291 | ||||
-rw-r--r-- | test/syncenginetestutils.h | 6 | ||||
-rw-r--r-- | test/testpermissions.cpp | 306 |
5 files changed, 312 insertions, 300 deletions
diff --git a/src/libsync/syncengine.cpp b/src/libsync/syncengine.cpp index 05ad08777..41ea0320c 100644 --- a/src/libsync/syncengine.cpp +++ b/src/libsync/syncengine.cpp @@ -1532,14 +1532,6 @@ void SyncEngine::checkForPermission(SyncFileItemVector &syncItems) RemotePermissions SyncEngine::getPermissions(const QString &file) const { - static bool isTest = qEnvironmentVariableIntValue("OWNCLOUD_TEST_PERMISSIONS"); - if (isTest) { - QRegExp rx("_PERM_([^_]*)_[^/]*$"); - if (rx.indexIn(file) != -1) { - return RemotePermissions(rx.cap(1)); - } - } - // Fetch from the csync context while we still have it. ASSERT(_csync_ctx->status != CSYNC_STATUS_INIT); diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 0ee8342c9..abad72e8c 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -52,6 +52,7 @@ owncloud_add_test(UploadReset "syncenginetestutils.h") owncloud_add_test(AllFilesDeleted "syncenginetestutils.h") owncloud_add_test(Blacklist "syncenginetestutils.h") owncloud_add_test(LocalDiscovery "syncenginetestutils.h") +owncloud_add_test(Permissions "syncenginetestutils.h") owncloud_add_test(FolderWatcher "${FolderWatcher_SRC}") if( UNIX AND NOT APPLE ) diff --git a/test/scripts/txpl/t7.pl b/test/scripts/txpl/t7.pl deleted file mode 100755 index 6b68a06ef..000000000 --- a/test/scripts/txpl/t7.pl +++ /dev/null @@ -1,291 +0,0 @@ -#!/usr/bin/perl -# -# Test script for the ownCloud module of csync. -# This script requires a running ownCloud instance accessible via HTTP. -# It does quite some fancy tests and asserts the results. -# -# Copyright (C) by Klaas Freitag <freitag@owncloud.com> -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) 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 -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -# - -use lib "."; - - -use File::Copy; -use ownCloud::Test; - -use strict; - -print "Hello, this is t7, a tester for syncing of files in read only directory\n"; - -# Check if the expected rows in the DB are non-empty. Note that in some cases they might be, then we cannot use this function -# https://github.comowncloud/client/issues/2038 -sub assertCsyncJournalOk { - my $path = $_[0]; - - # FIXME: should test also remoteperm but it's not working with owncloud6 - # my $cmd = 'sqlite3 ' . $path . '._sync_*.db "SELECT count(*) from metadata where length(remotePerm) == 0 or length(fileId) == 0"'; - my $cmd = 'sqlite3 ' . $path . '._sync_*.db "SELECT count(*) from metadata where length(fileId) == 0"'; - my $result = `$cmd`; - assert($result == "0"); -} - -# IMPORTANT NOTE : -print "This test use the OWNCLOUD_TEST_PERMISSIONS environement variable and _PERM_xxx_ on filenames to set the permission. "; -print "It does not rely on real permission set on the server. This test is just for testing the propagation choices\n"; -# "It would be nice" to have a test that test with real permissions on the server - -$ENV{OWNCLOUD_TEST_PERMISSIONS} = "1"; - -initTesting(); - -printInfo( "Init" ); - -#create some files localy -my $tmpdir = "/tmp/t7/"; -mkdir($tmpdir); -createLocalFile( $tmpdir . "normalFile_PERM_WVND_.data", 100 ); -createLocalFile( $tmpdir . "cannotBeRemoved_PERM_WVN_.data", 101 ); -createLocalFile( $tmpdir . "canBeRemoved_PERM_D_.data", 102 ); -my $md5CanotBeModified = createLocalFile( $tmpdir . "canotBeModified_PERM_DVN_.data", 103 ); -createLocalFile( $tmpdir . "canBeModified_PERM_W_.data", 104 ); - -#put them in some directories -createRemoteDir( "normalDirectory_PERM_CKDNV_" ); -glob_put( "$tmpdir/*", "normalDirectory_PERM_CKDNV_" ); -createRemoteDir( "readonlyDirectory_PERM_M_" ); -glob_put( "$tmpdir/*", "readonlyDirectory_PERM_M_" ); -createRemoteDir( "readonlyDirectory_PERM_M_/subdir_PERM_CK_" ); -createRemoteDir( "readonlyDirectory_PERM_M_/subdir_PERM_CK_/subsubdir_PERM_CKDNV_" ); -glob_put( "$tmpdir/normalFile_PERM_WVND_.data", "readonlyDirectory_PERM_M_/subdir_PERM_CK_/subsubdir_PERM_CKDNV_" ); - - -csync(); -assertCsyncJournalOk(localDir()); -assertLocalAndRemoteDir( '', 0); - -system("sleep 1"); #make sure changes have different mtime - -printInfo( "Do some changes and see how they propagate" ); - -#1. remove the file than cannot be removed -# (they should be recovered) -unlink( localDir() . 'normalDirectory_PERM_CKDNV_/cannotBeRemoved_PERM_WVN_.data' ); -unlink( localDir() . 'readonlyDirectory_PERM_M_/cannotBeRemoved_PERM_WVN_.data' ); - -#2. remove the file that can be removed -# (they should properly be gone) -unlink( localDir() . 'normalDirectory_PERM_CKDNV_/canBeRemoved_PERM_D_.data' ); -unlink( localDir() . 'readonlyDirectory_PERM_M_/canBeRemoved_PERM_D_.data' ); - -#3. Edit the files that cannot be modified -# (they should be recovered, and a conflict shall be created) -system("echo 'modified' > ". localDir() . "normalDirectory_PERM_CKDNV_/canotBeModified_PERM_DVN_.data"); -system("echo 'modified_' > ". localDir() . "readonlyDirectory_PERM_M_/canotBeModified_PERM_DVN_.data"); - -#4. Edit other files -# (they should be uploaded) -system("echo '__modified' > ". localDir() . "normalDirectory_PERM_CKDNV_/canBeModified_PERM_W_.data"); -system("echo '__modified_' > ". localDir() . "readonlyDirectory_PERM_M_/canBeModified_PERM_W_.data"); - -#5. Create a new file in a read only folder -# (should be uploaded) -createLocalFile( localDir() . "normalDirectory_PERM_CKDNV_/newFile_PERM_WDNV_.data", 106 ); - -#do the sync -csync(); -assertCsyncJournalOk(localDir()); - -#1. -# File should be recovered -assert( -e localDir(). 'normalDirectory_PERM_CKDNV_/cannotBeRemoved_PERM_WVN_.data' ); -assert( -e localDir(). 'readonlyDirectory_PERM_M_/cannotBeRemoved_PERM_WVN_.data' ); - -#2. -# File should be deleted -assert( !-e localDir() . 'normalDirectory_PERM_CKDNV_/canBeRemoved_PERM_D_.data' ); -assert( !-e localDir() . 'readonlyDirectory_PERM_M_/canBeRemoved_PERM_D_.data' ); - -#3. -# File should be recovered -assert($md5CanotBeModified eq md5OfFile( localDir().'normalDirectory_PERM_CKDNV_/canotBeModified_PERM_DVN_.data' )); -assert($md5CanotBeModified eq md5OfFile( localDir().'readonlyDirectory_PERM_M_/canotBeModified_PERM_DVN_.data' )); -# and conflict created -# TODO check that the conflict file has the right content -assert( -e glob(localDir().'normalDirectory_PERM_CKDNV_/canotBeModified_PERM_DVN__conflict-*.data' ) ); -assert( -e glob(localDir().'readonlyDirectory_PERM_M_/canotBeModified_PERM_DVN__conflict-*.data' ) ); -# remove the conflicts for the next assertLocalAndRemoteDir -system("rm " . localDir().'normalDirectory_PERM_CKDNV_/canotBeModified_PERM_DVN__conflict-*.data' ); -system("rm " . localDir().'readonlyDirectory_PERM_M_/canotBeModified_PERM_DVN__conflict-*.data' ); - -#4. File should be updated, that's tested by assertLocalAndRemoteDir - -#5. -# the file should be in the server and local -assert( -e localDir() . "normalDirectory_PERM_CKDNV_/newFile_PERM_WDNV_.data" ); - -### Both side should still be the same -assertLocalAndRemoteDir( '', 0); - -# Next test - -#6. Create a new file in a read only folder -# (they should not be uploaded) -createLocalFile( localDir() . "readonlyDirectory_PERM_M_/newFile_PERM_WDNV_.data", 105 ); - -# error: can't upload to readonly -csync(1); -assertCsyncJournalOk(localDir()); - -#6. -# The file should not exist on the remote -# TODO: test that the file is NOT on the server -# but still be there -assert( -e localDir() . "readonlyDirectory_PERM_M_/newFile_PERM_WDNV_.data" ); -# remove it so assertLocalAndRemoteDir succeed. -unlink(localDir() . "readonlyDirectory_PERM_M_/newFile_PERM_WDNV_.data"); - -### Both side should still be the same -assertLocalAndRemoteDir( '', 0); - - - - -####################################################################### -printInfo( "remove the read only directory" ); -# -> It must be recovered -system("rm -r " . localDir().'readonlyDirectory_PERM_M_' ); -csync(); -assertCsyncJournalOk(localDir()); -assert( -e localDir(). 'readonlyDirectory_PERM_M_/cannotBeRemoved_PERM_WVN_.data' ); -assert( -e localDir(). 'readonlyDirectory_PERM_M_/subdir_PERM_CK_/subsubdir_PERM_CKDNV_/normalFile_PERM_WVND_.data' ); -assertLocalAndRemoteDir( '', 0); - - -####################################################################### -printInfo( "move a directory in a outside read only folder" ); -system("sqlite3 " . localDir().'._sync_*.db .dump'); - -#Missing directory should be restored -#new directory should be uploaded -system("mv " . localDir().'readonlyDirectory_PERM_M_/subdir_PERM_CK_ ' . localDir().'normalDirectory_PERM_CKDNV_/subdir_PERM_CKDNV_' ); - -csync(); -system("sqlite3 " . localDir().'._sync_*.db .dump'); -assertCsyncJournalOk(localDir()); - -# old name restored -assert( -e localDir(). 'readonlyDirectory_PERM_M_/subdir_PERM_CK_/subsubdir_PERM_CKDNV_/' ); -assert( -e localDir(). 'readonlyDirectory_PERM_M_/subdir_PERM_CK_/subsubdir_PERM_CKDNV_/normalFile_PERM_WVND_.data' ); - -# new still exist -assert( -e localDir(). 'normalDirectory_PERM_CKDNV_/subdir_PERM_CKDNV_/subsubdir_PERM_CKDNV_/normalFile_PERM_WVND_.data' ); - -assertLocalAndRemoteDir( '', 0); - - - - - -####################################################################### -printInfo( "rename a directory in a read only folder and move a directory to a read-only" ); - -# do a sync to update the database -csync(); - -#1. rename a directory in a read only folder -#Missing directory should be restored -#new directory should stay but not be uploaded -system("mv " . localDir().'readonlyDirectory_PERM_M_/subdir_PERM_CK_ ' . localDir().'readonlyDirectory_PERM_M_/newname_PERM_CK_' ); - -#2. move a directory from read to read only (move the directory from previous step) -system("mv " . localDir().'normalDirectory_PERM_CKDNV_/subdir_PERM_CKDNV_ ' . localDir().'readonlyDirectory_PERM_M_/moved_PERM_CK_' ); - -# error: can't upload to readonly! -csync(1); -assertCsyncJournalOk(localDir()); - -#1. -# old name restored -assert( -e localDir(). 'readonlyDirectory_PERM_M_/subdir_PERM_CK_/subsubdir_PERM_CKDNV_/normalFile_PERM_WVND_.data' ); - -# new still exist -assert( -e localDir(). 'readonlyDirectory_PERM_M_/newname_PERM_CK_/subsubdir_PERM_CKDNV_/normalFile_PERM_WVND_.data' ); -# but is not on server: so remove for assertLocalAndRemoteDir -system("rm -r " . localDir(). "readonlyDirectory_PERM_M_/newname_PERM_CK_"); - -#2. -# old removed -assert( ! -e localDir(). 'normalDirectory_PERM_CKDNV_/subdir_PERM_CKDNV_/' ); -# new still there -assert( -e localDir(). 'readonlyDirectory_PERM_M_/moved_PERM_CK_/subsubdir_PERM_CKDNV_/normalFile_PERM_WVND_.data' ); -#but not on server -system("rm -r " . localDir(). "readonlyDirectory_PERM_M_/moved_PERM_CK_"); - -assertLocalAndRemoteDir( '', 0); - -system("sqlite3 " . localDir().'._sync_*.db .dump'); - - -####################################################################### -printInfo( "multiple restores of a file create different conflict files" ); - -system("sleep 1"); #make sure changes have different mtime - -system("echo 'modified_1' > ". localDir() . "readonlyDirectory_PERM_M_/canotBeModified_PERM_DVN_.data"); - -#do the sync -csync(); -assertCsyncJournalOk(localDir()); - -system("sleep 1"); #make sure changes have different mtime - -system("echo 'modified_2' > ". localDir() . "readonlyDirectory_PERM_M_/canotBeModified_PERM_DVN_.data"); - -#do the sync -csync(); -assertCsyncJournalOk(localDir()); - -# there should be two conflict files -# TODO check that the conflict file has the right content -my @conflicts = glob(localDir().'readonlyDirectory_PERM_M_/canotBeModified_PERM_DVN__conflict-*.data' ); -assert( scalar @conflicts == 2 ); -# remove the conflicts for the next assertLocalAndRemoteDir -system("rm " . localDir().'readonlyDirectory_PERM_M_/canotBeModified_PERM_DVN__conflict-*.data' ); - -### Both side should still be the same -assertLocalAndRemoteDir( '', 0); - - - -cleanup(); - - - - - - - - - - - - - - - - - diff --git a/test/syncenginetestutils.h b/test/syncenginetestutils.h index e0982bd15..536521b70 100644 --- a/test/syncenginetestutils.h +++ b/test/syncenginetestutils.h @@ -289,6 +289,7 @@ public: QString name; bool isDir = true; bool isShared = false; + OCC::RemotePermissions permissions; // When uset, defaults to everything QDateTime lastModified = QDateTime::currentDateTime().addDays(-7); QString etag = generateEtag(); QByteArray fileId = generateFileId(); @@ -362,7 +363,9 @@ public: xml.writeTextElement(davUri, QStringLiteral("getlastmodified"), stringDate); xml.writeTextElement(davUri, QStringLiteral("getcontentlength"), QString::number(fileInfo.size)); xml.writeTextElement(davUri, QStringLiteral("getetag"), fileInfo.etag); - xml.writeTextElement(ocUri, QStringLiteral("permissions"), fileInfo.isShared ? QStringLiteral("SRDNVCKW") : QStringLiteral("RDNVCKW")); + xml.writeTextElement(ocUri, QStringLiteral("permissions"), !fileInfo.permissions.isNull() + ? QString(fileInfo.permissions.toString()) + : fileInfo.isShared ? QStringLiteral("SRDNVCKW") : QStringLiteral("RDNVCKW")); xml.writeTextElement(ocUri, QStringLiteral("id"), fileInfo.fileId); xml.writeTextElement(ocUri, QStringLiteral("checksums"), fileInfo.checksums); buffer.write(fileInfo.extraDavProperties); @@ -446,6 +449,7 @@ public: emit uploadProgress(fileInfo->size, fileInfo->size); setRawHeader("OC-ETag", fileInfo->etag.toLatin1()); setRawHeader("ETag", fileInfo->etag.toLatin1()); + setRawHeader("OC-FileID", fileInfo->fileId); setRawHeader("X-OC-MTime", "accepted"); // Prevents Q_ASSERT(!_runningNow) since we'll call PropagateItemJob::done twice in that case. setAttribute(QNetworkRequest::HttpStatusCodeAttribute, 200); emit metaDataChanged(); diff --git a/test/testpermissions.cpp b/test/testpermissions.cpp new file mode 100644 index 000000000..2fdd7c03a --- /dev/null +++ b/test/testpermissions.cpp @@ -0,0 +1,306 @@ +/* + * This software is in the public domain, furnished "as is", without technical + * support, and with no warranty, express or implied, as to its usefulness for + * any purpose. + * + */ + +#include <QtTest> +#include "syncenginetestutils.h" +#include <syncengine.h> +#include "common/ownsql.h" + +using namespace OCC; + +static void applyPermissionsFromName(FileInfo &info) { + static QRegularExpression rx("_PERM_([^_]*)_[^/]*$"); + auto m = rx.match(info.name); + if (m.hasMatch()) { + info.permissions = RemotePermissions(m.captured(1)); + } + + for (FileInfo &sub : info.children) + applyPermissionsFromName(sub); +} + +const FileInfo *findConflict(FileInfo &dir, const QString &filename) +{ + QFileInfo info(filename); + const FileInfo *parentDir = dir.find(info.path()); + if (!parentDir) return nullptr; + QString start = info.baseName() + " (conflicted copy"; + for (const auto &item : parentDir->children) { + if (item.name.startsWith(start)) { + return &item; + } + } + return nullptr; +} + +// Check if the expected rows in the DB are non-empty. Note that in some cases they might be, then we cannot use this function +// https://github.com/owncloud/client/issues/2038 +static void assertCsyncJournalOk(SyncJournalDb &journal) +{ + SqlDatabase db; + QVERIFY(db.openReadOnly(journal.databaseFilePath())); + SqlQuery q("SELECT count(*) from metadata where length(fileId) == 0", db); + QVERIFY(q.exec()); + QVERIFY(q.next()); + QCOMPARE(q.intValue(0), 0); +#if defined(Q_OS_WIN) // Make sure the file does not appear in the FileInfo + FileSystem::setFileHidden(journal.databaseFilePath() + "-shm", true); +#endif +} + + +class TestPermissions : public QObject +{ + Q_OBJECT + +private slots: + + void t7pl() + { + FakeFolder fakeFolder{ FileInfo() }; + QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState()); + + const int cannotBeModifiedSize = 133; + const int canBeModifiedSize = 144; + + //create some files + auto insertIn = [&](const QString &dir) { + fakeFolder.remoteModifier().insert(dir + "normalFile_PERM_WVND_.data", 100 ); + fakeFolder.remoteModifier().insert(dir + "cannotBeRemoved_PERM_WVN_.data", 101 ); + fakeFolder.remoteModifier().insert(dir + "canBeRemoved_PERM_D_.data", 102 ); + fakeFolder.remoteModifier().insert(dir + "cannotBeModified_PERM_DVN_.data", cannotBeModifiedSize , 'A'); + fakeFolder.remoteModifier().insert(dir + "canBeModified_PERM_W_.data", canBeModifiedSize ); + }; + + //put them in some directories + fakeFolder.remoteModifier().mkdir("normalDirectory_PERM_CKDNV_"); + insertIn("normalDirectory_PERM_CKDNV_/"); + fakeFolder.remoteModifier().mkdir("readonlyDirectory_PERM_M_" ); + insertIn("readonlyDirectory_PERM_M_/" ); + fakeFolder.remoteModifier().mkdir("readonlyDirectory_PERM_M_/subdir_PERM_CK_"); + fakeFolder.remoteModifier().mkdir("readonlyDirectory_PERM_M_/subdir_PERM_CK_/subsubdir_PERM_CKDNV_"); + fakeFolder.remoteModifier().insert("readonlyDirectory_PERM_M_/subdir_PERM_CK_/subsubdir_PERM_CKDNV_/normalFile_PERM_WVND_.data", 100); + applyPermissionsFromName(fakeFolder.remoteModifier()); + + QVERIFY(fakeFolder.syncOnce()); + QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState()); + assertCsyncJournalOk(fakeFolder.syncJournal()); + qInfo("Do some changes and see how they propagate"); + + //1. remove the file than cannot be removed + // (they should be recovered) + fakeFolder.localModifier().remove("normalDirectory_PERM_CKDNV_/cannotBeRemoved_PERM_WVN_.data"); + fakeFolder.localModifier().remove("readonlyDirectory_PERM_M_/cannotBeRemoved_PERM_WVN_.data"); + + //2. remove the file that can be removed + // (they should properly be gone) + auto removeReadOnly = [&] (const QString &file) { + QVERIFY(!QFileInfo(fakeFolder.localPath() + file).permission(QFile::WriteOwner)); + QFile(fakeFolder.localPath() + file).setPermissions(QFile::WriteOwner | QFile::ReadOwner); + fakeFolder.localModifier().remove(file); + }; + removeReadOnly("normalDirectory_PERM_CKDNV_/canBeRemoved_PERM_D_.data"); + removeReadOnly("readonlyDirectory_PERM_M_/canBeRemoved_PERM_D_.data"); + + //3. Edit the files that cannot be modified + // (they should be recovered, and a conflict shall be created) + auto editReadOnly = [&] (const QString &file) { + QVERIFY(!QFileInfo(fakeFolder.localPath() + file).permission(QFile::WriteOwner)); + QFile(fakeFolder.localPath() + file).setPermissions(QFile::WriteOwner | QFile::ReadOwner); + fakeFolder.localModifier().appendByte(file); + }; + editReadOnly("normalDirectory_PERM_CKDNV_/cannotBeModified_PERM_DVN_.data"); + editReadOnly("readonlyDirectory_PERM_M_/cannotBeModified_PERM_DVN_.data"); + + //4. Edit other files + // (they should be uploaded) + fakeFolder.localModifier().appendByte("normalDirectory_PERM_CKDNV_/canBeModified_PERM_W_.data"); + fakeFolder.localModifier().appendByte("readonlyDirectory_PERM_M_/canBeModified_PERM_W_.data"); + + //5. Create a new file in a read write folder + // (should be uploaded) + fakeFolder.localModifier().insert("normalDirectory_PERM_CKDNV_/newFile_PERM_WDNV_.data", 106 ); + applyPermissionsFromName(fakeFolder.remoteModifier()); + + //do the sync + QVERIFY(fakeFolder.syncOnce()); + assertCsyncJournalOk(fakeFolder.syncJournal()); + auto currentLocalState = fakeFolder.currentLocalState(); + + //1. + // File should be recovered + QVERIFY(currentLocalState.find("normalDirectory_PERM_CKDNV_/cannotBeRemoved_PERM_WVN_.data")); + QVERIFY(currentLocalState.find("readonlyDirectory_PERM_M_/cannotBeRemoved_PERM_WVN_.data")); + + //2. + // File should be deleted + QVERIFY(!currentLocalState.find("normalDirectory_PERM_CKDNV_/canBeRemoved_PERM_D_.data")); + QVERIFY(!currentLocalState.find("readonlyDirectory_PERM_M_/canBeRemoved_PERM_D_.data")); + + //3. + // File should be recovered + QCOMPARE(currentLocalState.find("normalDirectory_PERM_CKDNV_/cannotBeModified_PERM_DVN_.data")->size, cannotBeModifiedSize); + QCOMPARE(currentLocalState.find("readonlyDirectory_PERM_M_/cannotBeModified_PERM_DVN_.data")->size, cannotBeModifiedSize); + // and conflict created + auto c1 = findConflict(currentLocalState, "normalDirectory_PERM_CKDNV_/cannotBeModified_PERM_DVN_.data"); + QVERIFY(c1); + QCOMPARE(c1->size, cannotBeModifiedSize + 1); + auto c2 = findConflict(currentLocalState, "readonlyDirectory_PERM_M_/cannotBeModified_PERM_DVN_.data"); + QVERIFY(c2); + QCOMPARE(c2->size, cannotBeModifiedSize + 1); + // remove the conflicts for the next state comparison + fakeFolder.localModifier().remove(c1->path()); + fakeFolder.localModifier().remove(c2->path()); + + //4. File should be updated, that's tested by assertLocalAndRemoteDir + QCOMPARE(currentLocalState.find("normalDirectory_PERM_CKDNV_/canBeModified_PERM_W_.data")->size, canBeModifiedSize + 1); + QCOMPARE(currentLocalState.find("readonlyDirectory_PERM_M_/canBeModified_PERM_W_.data")->size, canBeModifiedSize + 1); + + //5. + // the file should be in the server and local + QVERIFY(currentLocalState.find("normalDirectory_PERM_CKDNV_/newFile_PERM_WDNV_.data")); + + // Both side should still be the same + QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState()); + + // Next test + + //6. Create a new file in a read only folder + // (they should not be uploaded) + fakeFolder.localModifier().insert("readonlyDirectory_PERM_M_/newFile_PERM_WDNV_.data", 105 ); + + applyPermissionsFromName(fakeFolder.remoteModifier()); + // error: can't upload to readonly + QVERIFY(!fakeFolder.syncOnce()); + + assertCsyncJournalOk(fakeFolder.syncJournal()); + currentLocalState = fakeFolder.currentLocalState(); + + //6. + // The file should not exist on the remote, but still be there + QVERIFY(currentLocalState.find("readonlyDirectory_PERM_M_/newFile_PERM_WDNV_.data")); + QVERIFY(!fakeFolder.currentRemoteState().find("readonlyDirectory_PERM_M_/newFile_PERM_WDNV_.data")); + // remove it so next test succeed. + fakeFolder.localModifier().remove("readonlyDirectory_PERM_M_/newFile_PERM_WDNV_.data"); + // Both side should still be the same + QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState()); + + + //###################################################################### + qInfo( "remove the read only directory" ); + // -> It must be recovered + fakeFolder.localModifier().remove("readonlyDirectory_PERM_M_"); + applyPermissionsFromName(fakeFolder.remoteModifier()); + QVERIFY(fakeFolder.syncOnce()); + assertCsyncJournalOk(fakeFolder.syncJournal()); + currentLocalState = fakeFolder.currentLocalState(); + QVERIFY(currentLocalState.find("readonlyDirectory_PERM_M_/cannotBeRemoved_PERM_WVN_.data")); + QVERIFY(currentLocalState.find("readonlyDirectory_PERM_M_/subdir_PERM_CK_/subsubdir_PERM_CKDNV_/normalFile_PERM_WVND_.data")); + QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState()); + + + //###################################################################### + qInfo( "move a directory in a outside read only folder" ); + + //Missing directory should be restored + //new directory should be uploaded + fakeFolder.localModifier().rename("readonlyDirectory_PERM_M_/subdir_PERM_CK_", "normalDirectory_PERM_CKDNV_/subdir_PERM_CKDNV_"); + applyPermissionsFromName(fakeFolder.remoteModifier()); + fakeFolder.syncOnce(); + if (fakeFolder.syncEngine().isAnotherSyncNeeded() == ImmediateFollowUp) { + QVERIFY(fakeFolder.syncOnce()); + } + assertCsyncJournalOk(fakeFolder.syncJournal()); + currentLocalState = fakeFolder.currentLocalState(); + + // old name restored + QVERIFY(currentLocalState.find("readonlyDirectory_PERM_M_/subdir_PERM_CK_/subsubdir_PERM_CKDNV_")); + QVERIFY(currentLocalState.find("readonlyDirectory_PERM_M_/subdir_PERM_CK_/subsubdir_PERM_CKDNV_/normalFile_PERM_WVND_.data")); + + // new still exist (and is uploaded) + QVERIFY(currentLocalState.find("normalDirectory_PERM_CKDNV_/subdir_PERM_CKDNV_/subsubdir_PERM_CKDNV_/normalFile_PERM_WVND_.data")); + + QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState()); + + //###################################################################### + qInfo( "rename a directory in a read only folder and move a directory to a read-only" ); + + // do a sync to update the database + applyPermissionsFromName(fakeFolder.remoteModifier()); + QVERIFY(fakeFolder.syncOnce()); + + //1. rename a directory in a read only folder + //Missing directory should be restored + //new directory should stay but not be uploaded + fakeFolder.localModifier().rename("readonlyDirectory_PERM_M_/subdir_PERM_CK_", "readonlyDirectory_PERM_M_/newname_PERM_CK_" ); + + //2. move a directory from read to read only (move the directory from previous step) + fakeFolder.localModifier().rename("normalDirectory_PERM_CKDNV_/subdir_PERM_CKDNV_", "readonlyDirectory_PERM_M_/moved_PERM_CK_" ); + + // error: can't upload to readonly! + QVERIFY(!fakeFolder.syncOnce()); + if (fakeFolder.syncEngine().isAnotherSyncNeeded() == ImmediateFollowUp) { + QVERIFY(!fakeFolder.syncOnce()); + } + assertCsyncJournalOk(fakeFolder.syncJournal()); + currentLocalState = fakeFolder.currentLocalState(); + + //1. + // old name restored + QVERIFY(currentLocalState.find("readonlyDirectory_PERM_M_/subdir_PERM_CK_/subsubdir_PERM_CKDNV_/normalFile_PERM_WVND_.data" )); + // new still exist + QVERIFY(currentLocalState.find("readonlyDirectory_PERM_M_/newname_PERM_CK_/subsubdir_PERM_CKDNV_/normalFile_PERM_WVND_.data" )); + // but is not on server: so remove it localy for the future comarison + fakeFolder.localModifier().remove("readonlyDirectory_PERM_M_/newname_PERM_CK_"); + + //2. + // old removed + QVERIFY(!currentLocalState.find("normalDirectory_PERM_CKDNV_/subdir_PERM_CKDNV_")); + // new still there + QVERIFY(currentLocalState.find("readonlyDirectory_PERM_M_/moved_PERM_CK_/subsubdir_PERM_CKDNV_/normalFile_PERM_WVND_.data" )); + //but not on server + fakeFolder.localModifier().remove("readonlyDirectory_PERM_M_/moved_PERM_CK_"); + + QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState()); + + + //###################################################################### + qInfo( "multiple restores of a file create different conflict files" ); + + editReadOnly("readonlyDirectory_PERM_M_/cannotBeModified_PERM_DVN_.data"); + fakeFolder.localModifier().setContents("readonlyDirectory_PERM_M_/cannotBeModified_PERM_DVN_.data", 's'); + //do the sync + applyPermissionsFromName(fakeFolder.remoteModifier()); + QVERIFY(fakeFolder.syncOnce()); + assertCsyncJournalOk(fakeFolder.syncJournal()); + + QThread::sleep(1); // make sure changes have different mtime + editReadOnly("readonlyDirectory_PERM_M_/cannotBeModified_PERM_DVN_.data"); + fakeFolder.localModifier().setContents("readonlyDirectory_PERM_M_/cannotBeModified_PERM_DVN_.data", 'd'); + + //do the sync + applyPermissionsFromName(fakeFolder.remoteModifier()); + QVERIFY(fakeFolder.syncOnce()); + assertCsyncJournalOk(fakeFolder.syncJournal()); + + // there should be two conflict files + currentLocalState = fakeFolder.currentLocalState(); + int count = 0; + while (auto i = findConflict(currentLocalState, "readonlyDirectory_PERM_M_/cannotBeModified_PERM_DVN_.data")) { + QVERIFY((i->contentChar == 's') || (i->contentChar == 'd')); + fakeFolder.localModifier().remove(i->path()); + currentLocalState = fakeFolder.currentLocalState(); + count++; + } + QCOMPARE(count, 2); + QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState()); + } + +}; + +QTEST_GUILESS_MAIN(TestPermissions) +#include "testpermissions.moc" |