mirror of
https://github.com/nextcloud/desktop.git
synced 2024-11-23 05:25:50 +03:00
Merge remote-tracking branch 'origin/2.3'
This commit is contained in:
commit
172689d35c
53 changed files with 6366 additions and 5571 deletions
|
@ -7,6 +7,8 @@ endif()
|
|||
|
||||
project(client)
|
||||
|
||||
set(BIN_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
|
||||
|
||||
set(OEM_THEME_DIR "" CACHE STRING "Define directory containing a custom theme")
|
||||
if ( EXISTS ${OEM_THEME_DIR}/OEM.cmake )
|
||||
include ( ${OEM_THEME_DIR}/OEM.cmake )
|
||||
|
|
2
Jenkinsfile
vendored
2
Jenkinsfile
vendored
|
@ -39,7 +39,7 @@ node('CLIENT') {
|
|||
|
||||
|
||||
stage 'Win32'
|
||||
def win32 = docker.image('deepdiver/docker-owncloud-client-win32:latest')
|
||||
def win32 = docker.image('guruz/docker-owncloud-client-win32:latest')
|
||||
win32.pull() // make sure we have the latest available from Docker Hub
|
||||
win32.inside {
|
||||
sh '''
|
||||
|
|
|
@ -28,7 +28,6 @@ include(ConfigureChecks.cmake)
|
|||
|
||||
|
||||
set(SOURCE_DIR ${CMAKE_SOURCE_DIR})
|
||||
set(BIN_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
|
||||
|
||||
include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
|
|
|
@ -207,7 +207,7 @@ __attribute__ ((packed))
|
|||
#endif
|
||||
;
|
||||
|
||||
void csync_file_stat_free(csync_file_stat_t *st);
|
||||
OCSYNC_EXPORT void csync_file_stat_free(csync_file_stat_t *st);
|
||||
|
||||
/*
|
||||
* context for the treewalk function
|
||||
|
|
|
@ -56,17 +56,15 @@ int csync_get_statedb_exists(CSYNC *ctx);
|
|||
*
|
||||
* @return 0 on success, less than 0 if an error occurred with errno set.
|
||||
*/
|
||||
int csync_statedb_load(CSYNC *ctx, const char *statedb, sqlite3 **pdb);
|
||||
OCSYNC_EXPORT int csync_statedb_load(CSYNC *ctx, const char *statedb, sqlite3 **pdb);
|
||||
|
||||
int csync_statedb_close(CSYNC *ctx);
|
||||
OCSYNC_EXPORT int csync_statedb_close(CSYNC *ctx);
|
||||
|
||||
csync_file_stat_t *csync_statedb_get_stat_by_hash(CSYNC *ctx, uint64_t phash);
|
||||
OCSYNC_EXPORT csync_file_stat_t *csync_statedb_get_stat_by_hash(CSYNC *ctx, uint64_t phash);
|
||||
|
||||
csync_file_stat_t *csync_statedb_get_stat_by_inode(CSYNC *ctx, uint64_t inode);
|
||||
OCSYNC_EXPORT csync_file_stat_t *csync_statedb_get_stat_by_inode(CSYNC *ctx, uint64_t inode);
|
||||
|
||||
csync_file_stat_t *csync_statedb_get_stat_by_file_id(CSYNC *ctx, const char *file_id);
|
||||
|
||||
char *csync_statedb_get_etag(CSYNC *ctx, uint64_t jHash);
|
||||
OCSYNC_EXPORT csync_file_stat_t *csync_statedb_get_stat_by_file_id(CSYNC *ctx, const char *file_id);
|
||||
|
||||
/**
|
||||
* @brief Query all files metadata inside and below a path.
|
||||
|
|
|
@ -132,11 +132,16 @@ changed and no synchronization occurs.
|
|||
In the event a file has changed on both the local and the remote repository
|
||||
since the last sync run, it can not easily be decided which version of the file
|
||||
is the one that should be used. However, changes to any side will not be lost. Instead,
|
||||
a *conflict case* is created. The client resolves this conflict by creating a
|
||||
conflict file of the older of the two files and saving the newer file under the
|
||||
original file name. Conflict files are always created on the client and never
|
||||
on the server. The conflict file uses the same name as the original file, but
|
||||
is appended with the timestamp of the conflict detection.
|
||||
a *conflict case* is created. The client resolves this conflict by renaming the
|
||||
local file, appending a conflict label and timestamp, and saving the remote file
|
||||
under the original file name.
|
||||
|
||||
Example: Assume there is a conflict in message.txt because its contents have
|
||||
changed both locally and remotely since the last sync run. The local file with
|
||||
the local changes will be renamed to message_conflict-20160101-153110.txt and
|
||||
the remote file will be downloaded and saved as message.txt.
|
||||
|
||||
Conflict files are always created on the client and never on the server.
|
||||
|
||||
|
||||
.. _ignored-files-label:
|
||||
|
|
|
@ -697,6 +697,24 @@ X-GNOME-Autostart-Delay=3
|
|||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
Comment[oc]=@APPLICATION_NAME@ sincronizacion del client
|
||||
GenericName[oc]=Dorsièr de Sincronizacion
|
||||
|
@ -753,6 +771,10 @@ Comment[he]=@APPLICATION_NAME@ לקוח סנכון שולחן עבודה
|
|||
GenericName[he]=סנכון תיקייה
|
||||
Name[he]=@APPLICATION_NAME@ לקוח סנכרון שולחן עבודה
|
||||
Icon[he]=@APPLICATION_EXECUTABLE@
|
||||
Comment[ia]=@APPLICATION_NAME@ cliente de synchronisation pro scriptorio
|
||||
GenericName[ia]=Synchronisar Dossier
|
||||
Name[ia]=@APPLICATION_NAME@ cliente de synchronisation pro scriptorio
|
||||
Icon[ia]=@APPLICATION_EXECUTABLE@
|
||||
Comment[id]=Klien sinkronisasi desktop @APPLICATION_NAME@
|
||||
GenericName[id]=Folder Sync
|
||||
Name[id]=Klien sync desktop @APPLICATION_NAME@
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
# TODO: OSX and LIB_ONLY seem to require this to go to binary dir only
|
||||
if(NOT TOKEN_AUTH_ONLY)
|
||||
endif()
|
||||
set(BIN_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
|
||||
|
||||
set(synclib_NAME ${APPLICATION_EXECUTABLE}sync)
|
||||
|
||||
|
|
|
@ -53,7 +53,6 @@ Folder::Folder(const FolderDefinition& definition,
|
|||
, _accountState(accountState)
|
||||
, _definition(definition)
|
||||
, _csyncUnavail(false)
|
||||
, _wipeDb(false)
|
||||
, _proxyDirty(true)
|
||||
, _lastSyncDuration(0)
|
||||
, _consecutiveFailingSyncs(0)
|
||||
|
|
|
@ -324,7 +324,6 @@ private:
|
|||
SyncResult _syncResult;
|
||||
QScopedPointer<SyncEngine> _engine;
|
||||
bool _csyncUnavail;
|
||||
bool _wipeDb;
|
||||
bool _proxyDirty;
|
||||
QPointer<RequestEtagJob> _requestEtagJob;
|
||||
QString _lastEtag;
|
||||
|
|
|
@ -515,5 +515,3 @@ QString SocketApi::buildRegisterPathMessage(const QString& path)
|
|||
}
|
||||
|
||||
} // namespace OCC
|
||||
|
||||
Q_DECLARE_METATYPE(OCC::SocketListener)
|
||||
|
|
|
@ -84,7 +84,7 @@ QString OWNCLOUDSYNC_EXPORT longWinPath( const QString& inpath );
|
|||
*/
|
||||
time_t OWNCLOUDSYNC_EXPORT getModTime(const QString& filename);
|
||||
|
||||
bool setModTime(const QString &filename, time_t modTime);
|
||||
bool OWNCLOUDSYNC_EXPORT setModTime(const QString &filename, time_t modTime);
|
||||
|
||||
/**
|
||||
* @brief Get the size for a file
|
||||
|
|
|
@ -273,14 +273,13 @@ void Utility::usleep(int usec)
|
|||
|
||||
bool Utility::fsCasePreserving()
|
||||
{
|
||||
bool re = false;
|
||||
if( isWindows() || isMac() ) {
|
||||
re = true;
|
||||
} else {
|
||||
bool isTest = qgetenv("OWNCLOUD_TEST_CASE_PRESERVING").toInt();
|
||||
re = isTest;
|
||||
}
|
||||
return re;
|
||||
#ifndef WITH_TESTING
|
||||
QByteArray env = qgetenv("OWNCLOUD_TEST_CASE_PRESERVING");
|
||||
if (!env.isEmpty())
|
||||
return env.toInt();
|
||||
#endif
|
||||
|
||||
return isWindows() || isMac();
|
||||
}
|
||||
|
||||
bool Utility::fileNamesEqual( const QString& fn1, const QString& fn2)
|
||||
|
|
|
@ -9,7 +9,6 @@ setup_qt()
|
|||
include(owncloud_add_test.cmake)
|
||||
|
||||
owncloud_add_test(OwncloudPropagator "")
|
||||
owncloud_add_test(Utility "")
|
||||
owncloud_add_test(Updater "")
|
||||
|
||||
SET(FolderWatcher_SRC ../src/gui/folderwatcher.cpp)
|
||||
|
@ -24,31 +23,29 @@ IF( APPLE )
|
|||
list(APPEND FolderWatcher_SRC ../src/gui/folderwatcher_mac.cpp)
|
||||
list(APPEND FolderWatcher_SRC ../src/gui/socketapisocket_mac.mm)
|
||||
ENDIF()
|
||||
|
||||
owncloud_add_test(FolderWatcher "${FolderWatcher_SRC}")
|
||||
if( UNIX AND NOT APPLE )
|
||||
if(HAVE_QT5 AND NOT BUILD_WITH_QT4)
|
||||
owncloud_add_test(InotifyWatcher "${FolderWatcher_SRC}")
|
||||
endif(HAVE_QT5 AND NOT BUILD_WITH_QT4)
|
||||
endif(UNIX AND NOT APPLE)
|
||||
|
||||
owncloud_add_test(CSyncSqlite "")
|
||||
owncloud_add_test(NetrcParser ../src/cmd/netrcparser.cpp)
|
||||
owncloud_add_test(OwnSql "")
|
||||
owncloud_add_test(SyncJournalDB "")
|
||||
owncloud_add_test(SyncFileItem "")
|
||||
owncloud_add_test(ConcatUrl "")
|
||||
|
||||
owncloud_add_test(XmlParse "")
|
||||
owncloud_add_test(FileSystem "")
|
||||
owncloud_add_test(ChecksumValidator "")
|
||||
|
||||
owncloud_add_test(ExcludedFiles "")
|
||||
if(HAVE_QT5 AND NOT BUILD_WITH_QT4)
|
||||
owncloud_add_test(FileSystem "")
|
||||
owncloud_add_test(Utility "")
|
||||
owncloud_add_test(SyncEngine "syncenginetestutils.h")
|
||||
owncloud_add_test(SyncFileStatusTracker "syncenginetestutils.h")
|
||||
owncloud_add_test(ChunkingNg "syncenginetestutils.h")
|
||||
owncloud_add_test(UploadReset "syncenginetestutils.h")
|
||||
owncloud_add_test(FolderWatcher "${FolderWatcher_SRC}")
|
||||
|
||||
if( UNIX AND NOT APPLE )
|
||||
owncloud_add_test(InotifyWatcher "${FolderWatcher_SRC}")
|
||||
endif(UNIX AND NOT APPLE)
|
||||
|
||||
owncloud_add_benchmark(LargeSync "syncenginetestutils.h")
|
||||
endif(HAVE_QT5 AND NOT BUILD_WITH_QT4)
|
||||
|
||||
|
@ -60,8 +57,5 @@ list(APPEND FolderMan_SRC ../src/gui/syncrunfilelog.cpp )
|
|||
list(APPEND FolderMan_SRC ../src/gui/lockwatcher.cpp )
|
||||
list(APPEND FolderMan_SRC ${FolderWatcher_SRC})
|
||||
list(APPEND FolderMan_SRC stub.cpp )
|
||||
#include_directories(${QTKEYCHAIN_INCLUDE_DIR})
|
||||
#include_directories(${CMAKE_BINARY_DIR}/src/gui)
|
||||
#include_directories(${CMAKE_SOURCE_DIR}/src/3rdparty/qjson)
|
||||
owncloud_add_test(FolderMan "${FolderMan_SRC}")
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ macro(owncloud_add_test test_class additional_cpp)
|
|||
|
||||
add_executable(${OWNCLOUD_TEST_CLASS}Test test${OWNCLOUD_TEST_CLASS_LOWERCASE}.cpp ${additional_cpp})
|
||||
qt5_use_modules(${OWNCLOUD_TEST_CLASS}Test Test Sql Xml Network)
|
||||
set_target_properties(${OWNCLOUD_TEST_CLASS}Test PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${BIN_OUTPUT_DIRECTORY})
|
||||
|
||||
target_link_libraries(${OWNCLOUD_TEST_CLASS}Test
|
||||
updater
|
||||
|
@ -40,6 +41,7 @@ macro(owncloud_add_benchmark test_class additional_cpp)
|
|||
|
||||
add_executable(${OWNCLOUD_TEST_CLASS}Bench benchmarks/bench${OWNCLOUD_TEST_CLASS_LOWERCASE}.cpp ${additional_cpp})
|
||||
qt5_use_modules(${OWNCLOUD_TEST_CLASS}Bench Test Sql Xml Network)
|
||||
set_target_properties(${OWNCLOUD_TEST_CLASS}Bench PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${BIN_OUTPUT_DIRECTORY})
|
||||
|
||||
target_link_libraries(${OWNCLOUD_TEST_CLASS}Bench
|
||||
updater
|
||||
|
|
|
@ -345,7 +345,7 @@ public:
|
|||
} else
|
||||
xml.writeEmptyElement(davUri, QStringLiteral("resourcetype"));
|
||||
|
||||
auto gmtDate = fileInfo.lastModified.toTimeZone(QTimeZone("GMT"));
|
||||
auto gmtDate = fileInfo.lastModified.toTimeZone(QTimeZone(0));
|
||||
auto stringDate = gmtDate.toString("ddd, dd MMM yyyy HH:mm:ss 'GMT'");
|
||||
xml.writeTextElement(davUri, QStringLiteral("getlastmodified"), stringDate);
|
||||
xml.writeTextElement(davUri, QStringLiteral("getcontentlength"), QString::number(fileInfo.size));
|
||||
|
|
|
@ -55,7 +55,6 @@ using namespace OCC;
|
|||
private slots:
|
||||
|
||||
void initTestCase() {
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
_root = QDir::tempPath() + "/" + "test_" + QString::number(qrand());
|
||||
QDir rootDir(_root);
|
||||
|
||||
|
@ -65,7 +64,9 @@ using namespace OCC;
|
|||
}
|
||||
|
||||
void testUploadChecksummingAdler() {
|
||||
|
||||
#ifndef ZLIB_FOUND
|
||||
QSKIP("ZLIB not found.", SkipSingle);
|
||||
#else
|
||||
ComputeChecksum *vali = new ComputeChecksum(this);
|
||||
_expectedType = "Adler32";
|
||||
vali->setChecksumType(_expectedType);
|
||||
|
@ -81,6 +82,7 @@ using namespace OCC;
|
|||
loop.exec();
|
||||
|
||||
delete vali;
|
||||
#endif
|
||||
}
|
||||
|
||||
void testUploadChecksummingMd5() {
|
||||
|
@ -119,7 +121,9 @@ using namespace OCC;
|
|||
}
|
||||
|
||||
void testDownloadChecksummingAdler() {
|
||||
|
||||
#ifndef ZLIB_FOUND
|
||||
QSKIP("ZLIB not found.", SkipSingle);
|
||||
#else
|
||||
QByteArray adler = checkSumAdlerC;
|
||||
adler.append(":");
|
||||
adler.append(FileSystem::calcAdler32( _testfile ));
|
||||
|
@ -143,6 +147,7 @@ using namespace OCC;
|
|||
QTRY_VERIFY(_errorSeen);
|
||||
|
||||
delete vali;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -11,9 +11,7 @@
|
|||
|
||||
using namespace OCC;
|
||||
|
||||
#define STR_(X) #X
|
||||
#define STR(X) STR_(X)
|
||||
#define BIN_PATH STR(OWNCLOUD_BIN_PATH)
|
||||
#define EXCLUDE_LIST_FILE SOURCEDIR"/../sync-exclude.lst"
|
||||
|
||||
class TestExcludedFiles: public QObject
|
||||
{
|
||||
|
@ -31,9 +29,7 @@ private slots:
|
|||
QVERIFY(!excluded.isExcluded("/a/.b", "/a", keepHidden));
|
||||
QVERIFY(excluded.isExcluded("/a/.b", "/a", excludeHidden));
|
||||
|
||||
QString path(BIN_PATH);
|
||||
path.append("/sync-exclude.lst");
|
||||
excluded.addExcludeFilePath(path);
|
||||
excluded.addExcludeFilePath(EXCLUDE_LIST_FILE);
|
||||
excluded.reloadExcludes();
|
||||
|
||||
QVERIFY(!excluded.isExcluded("/a/b", "/a", keepHidden));
|
||||
|
|
|
@ -17,7 +17,7 @@ class TestFileSystem : public QObject
|
|||
{
|
||||
Q_OBJECT
|
||||
|
||||
QString _root;
|
||||
QTemporaryDir _root;
|
||||
|
||||
|
||||
QByteArray shellSum( const QByteArray& cmd, const QString& file )
|
||||
|
@ -38,51 +38,36 @@ class TestFileSystem : public QObject
|
|||
}
|
||||
|
||||
private slots:
|
||||
void initTestCase() {
|
||||
qsrand(QTime::currentTime().msec());
|
||||
|
||||
QString subdir("test_"+QString::number(qrand()));
|
||||
_root = QDir::tempPath() + "/" + subdir;
|
||||
|
||||
QDir dir("/tmp");
|
||||
dir.mkdir(subdir);
|
||||
qDebug() << "creating test directory " << _root;
|
||||
}
|
||||
|
||||
void cleanupTestCase()
|
||||
{
|
||||
if( !_root.isEmpty() )
|
||||
system(QString("rm -rf "+_root).toUtf8());
|
||||
}
|
||||
|
||||
void testMd5Calc()
|
||||
{
|
||||
QString file( _root+"/file_a.bin");
|
||||
writeRandomFile(file);
|
||||
QFileInfo fi(file);
|
||||
QVERIFY(fi.exists());
|
||||
QByteArray sum = calcMd5(file);
|
||||
QString file( _root.path() + "/file_a.bin");
|
||||
QVERIFY(writeRandomFile(file));
|
||||
QFileInfo fi(file);
|
||||
QVERIFY(fi.exists());
|
||||
QByteArray sum = calcMd5(file);
|
||||
|
||||
QByteArray sSum = shellSum("/usr/bin/md5sum", file);
|
||||
qDebug() << "calculated" << sum << "versus md5sum:"<< sSum;
|
||||
QVERIFY(!sSum.isEmpty());
|
||||
QVERIFY(!sum.isEmpty());
|
||||
QVERIFY(sSum == sum );
|
||||
QByteArray sSum = shellSum("md5sum", file);
|
||||
if (sSum.isEmpty())
|
||||
QSKIP("Couldn't execute md5sum to calculate checksum, executable missing?", SkipSingle);
|
||||
|
||||
QVERIFY(!sum.isEmpty());
|
||||
QCOMPARE(sSum, sum);
|
||||
}
|
||||
|
||||
void testSha1Calc()
|
||||
{
|
||||
QString file( _root+"/file_b.bin");
|
||||
writeRandomFile(file);
|
||||
QFileInfo fi(file);
|
||||
QVERIFY(fi.exists());
|
||||
QByteArray sum = calcSha1(file);
|
||||
QString file( _root.path() + "/file_b.bin");
|
||||
writeRandomFile(file);
|
||||
QFileInfo fi(file);
|
||||
QVERIFY(fi.exists());
|
||||
QByteArray sum = calcSha1(file);
|
||||
|
||||
QByteArray sSum = shellSum("/usr/bin/sha1sum", file);
|
||||
qDebug() << "calculated" << sum << "versus sha1sum:"<< sSum;
|
||||
QVERIFY(!sSum.isEmpty());
|
||||
QVERIFY(!sum.isEmpty());
|
||||
QVERIFY(sSum == sum );
|
||||
QByteArray sSum = shellSum("sha1sum", file);
|
||||
if (sSum.isEmpty())
|
||||
QSKIP("Couldn't execute sha1sum to calculate checksum, executable missing?", SkipSingle);
|
||||
|
||||
QVERIFY(!sum.isEmpty());
|
||||
QCOMPARE(sSum, sum);
|
||||
}
|
||||
|
||||
};
|
||||
|
|
|
@ -63,6 +63,7 @@ private slots:
|
|||
f.open(QFile::WriteOnly);
|
||||
f.write("hello");
|
||||
}
|
||||
QString dirPath = dir2.canonicalPath();
|
||||
|
||||
AccountPtr account = Account::create();
|
||||
QUrl url("http://example.de");
|
||||
|
@ -73,22 +74,22 @@ private slots:
|
|||
AccountStatePtr newAccountState(new AccountState(account));
|
||||
FolderMan *folderman = FolderMan::instance();
|
||||
QCOMPARE(folderman, &_fm);
|
||||
QVERIFY(folderman->addFolder(newAccountState.data(), folderDefinition(dir.path() + "/sub/ownCloud1")));
|
||||
QVERIFY(folderman->addFolder(newAccountState.data(), folderDefinition(dir.path() + "/ownCloud2")));
|
||||
QVERIFY(folderman->addFolder(newAccountState.data(), folderDefinition(dirPath + "/sub/ownCloud1")));
|
||||
QVERIFY(folderman->addFolder(newAccountState.data(), folderDefinition(dirPath + "/ownCloud2")));
|
||||
|
||||
|
||||
// those should be allowed
|
||||
// QString FolderMan::checkPathValidityForNewFolder(const QString& path, const QUrl &serverUrl, bool forNewDirectory)
|
||||
|
||||
QCOMPARE(folderman->checkPathValidityForNewFolder(dir.path() + "/sub/free"), QString());
|
||||
QCOMPARE(folderman->checkPathValidityForNewFolder(dir.path() + "/free2/"), QString());
|
||||
QCOMPARE(folderman->checkPathValidityForNewFolder(dirPath + "/sub/free"), QString());
|
||||
QCOMPARE(folderman->checkPathValidityForNewFolder(dirPath + "/free2/"), QString());
|
||||
// Not an existing directory -> Ok
|
||||
QCOMPARE(folderman->checkPathValidityForNewFolder(dir.path() + "/sub/bliblablu"), QString());
|
||||
QCOMPARE(folderman->checkPathValidityForNewFolder(dir.path() + "/sub/free/bliblablu"), QString());
|
||||
QCOMPARE(folderman->checkPathValidityForNewFolder(dir.path() + "/sub/bliblablu/some/more"), QString());
|
||||
QCOMPARE(folderman->checkPathValidityForNewFolder(dirPath + "/sub/bliblablu"), QString());
|
||||
QCOMPARE(folderman->checkPathValidityForNewFolder(dirPath + "/sub/free/bliblablu"), QString());
|
||||
// QCOMPARE(folderman->checkPathValidityForNewFolder(dirPath + "/sub/bliblablu/some/more"), QString());
|
||||
|
||||
// A file -> Error
|
||||
QVERIFY(!folderman->checkPathValidityForNewFolder(dir.path() + "/sub/file.txt").isNull());
|
||||
QVERIFY(!folderman->checkPathValidityForNewFolder(dirPath + "/sub/file.txt").isNull());
|
||||
|
||||
// There are folders configured in those folders, url needs to be taken into account: -> ERROR
|
||||
QUrl url2(url);
|
||||
|
@ -96,51 +97,51 @@ private slots:
|
|||
url2.setUserName(user);
|
||||
|
||||
// The following both fail because they refer to the same account (user and url)
|
||||
QVERIFY(!folderman->checkPathValidityForNewFolder(dir.path() + "/sub/ownCloud1", url2).isNull());
|
||||
QVERIFY(!folderman->checkPathValidityForNewFolder(dir.path() + "/ownCloud2/", url2).isNull());
|
||||
QVERIFY(!folderman->checkPathValidityForNewFolder(dirPath + "/sub/ownCloud1", url2).isNull());
|
||||
QVERIFY(!folderman->checkPathValidityForNewFolder(dirPath + "/ownCloud2/", url2).isNull());
|
||||
|
||||
// Now it will work because the account is different
|
||||
QUrl url3("http://anotherexample.org");
|
||||
url3.setUserName("dummy");
|
||||
QCOMPARE(folderman->checkPathValidityForNewFolder(dir.path() + "/sub/ownCloud1", url3), QString());
|
||||
QCOMPARE(folderman->checkPathValidityForNewFolder(dir.path() + "/ownCloud2/", url3), QString());
|
||||
QCOMPARE(folderman->checkPathValidityForNewFolder(dirPath + "/sub/ownCloud1", url3), QString());
|
||||
QCOMPARE(folderman->checkPathValidityForNewFolder(dirPath + "/ownCloud2/", url3), QString());
|
||||
|
||||
QVERIFY(!folderman->checkPathValidityForNewFolder(dir.path()).isNull());
|
||||
QVERIFY(!folderman->checkPathValidityForNewFolder(dir.path() + "/sub/ownCloud1/folder").isNull());
|
||||
QVERIFY(!folderman->checkPathValidityForNewFolder(dir.path() + "/sub/ownCloud1/folder/f").isNull());
|
||||
QVERIFY(!folderman->checkPathValidityForNewFolder(dirPath).isNull());
|
||||
QVERIFY(!folderman->checkPathValidityForNewFolder(dirPath + "/sub/ownCloud1/folder").isNull());
|
||||
QVERIFY(!folderman->checkPathValidityForNewFolder(dirPath + "/sub/ownCloud1/folder/f").isNull());
|
||||
|
||||
|
||||
// make a bunch of links
|
||||
QVERIFY(QFile::link(dir.path() + "/sub/free", dir.path() + "/link1"));
|
||||
QVERIFY(QFile::link(dir.path() + "/sub", dir.path() + "/link2"));
|
||||
QVERIFY(QFile::link(dir.path() + "/sub/ownCloud1", dir.path() + "/link3"));
|
||||
QVERIFY(QFile::link(dir.path() + "/sub/ownCloud1/folder", dir.path() + "/link4"));
|
||||
QVERIFY(QFile::link(dirPath + "/sub/free", dirPath + "/link1"));
|
||||
QVERIFY(QFile::link(dirPath + "/sub", dirPath + "/link2"));
|
||||
QVERIFY(QFile::link(dirPath + "/sub/ownCloud1", dirPath + "/link3"));
|
||||
QVERIFY(QFile::link(dirPath + "/sub/ownCloud1/folder", dirPath + "/link4"));
|
||||
|
||||
// Ok
|
||||
QVERIFY(folderman->checkPathValidityForNewFolder(dir.path() + "/link1").isNull());
|
||||
QVERIFY(folderman->checkPathValidityForNewFolder(dir.path() + "/link2/free").isNull());
|
||||
QVERIFY(folderman->checkPathValidityForNewFolder(dirPath + "/link1").isNull());
|
||||
QVERIFY(folderman->checkPathValidityForNewFolder(dirPath + "/link2/free").isNull());
|
||||
|
||||
// Not Ok
|
||||
QVERIFY(!folderman->checkPathValidityForNewFolder(dir.path() + "/link2").isNull());
|
||||
QVERIFY(!folderman->checkPathValidityForNewFolder(dirPath + "/link2").isNull());
|
||||
|
||||
// link 3 points to an existing sync folder. To make it fail, the account must be the same
|
||||
QVERIFY(!folderman->checkPathValidityForNewFolder(dir.path() + "/link3", url2).isNull());
|
||||
QVERIFY(!folderman->checkPathValidityForNewFolder(dirPath + "/link3", url2).isNull());
|
||||
// while with a different account, this is fine
|
||||
QCOMPARE(folderman->checkPathValidityForNewFolder(dir.path() + "/link3", url3), QString());
|
||||
QCOMPARE(folderman->checkPathValidityForNewFolder(dirPath + "/link3", url3), QString());
|
||||
|
||||
QVERIFY(!folderman->checkPathValidityForNewFolder(dir.path() + "/link4").isNull());
|
||||
QVERIFY(!folderman->checkPathValidityForNewFolder(dir.path() + "/link3/folder").isNull());
|
||||
QVERIFY(!folderman->checkPathValidityForNewFolder(dirPath + "/link4").isNull());
|
||||
QVERIFY(!folderman->checkPathValidityForNewFolder(dirPath + "/link3/folder").isNull());
|
||||
|
||||
|
||||
// test some non existing sub path (error)
|
||||
QVERIFY(!folderman->checkPathValidityForNewFolder(dir.path() + "/sub/ownCloud1/some/sub/path").isNull());
|
||||
QVERIFY(!folderman->checkPathValidityForNewFolder(dir.path() + "/ownCloud2/blublu").isNull());
|
||||
QVERIFY(!folderman->checkPathValidityForNewFolder(dir.path() + "/sub/ownCloud1/folder/g/h").isNull());
|
||||
QVERIFY(!folderman->checkPathValidityForNewFolder(dir.path() + "/link3/folder/neu_folder").isNull());
|
||||
QVERIFY(!folderman->checkPathValidityForNewFolder(dirPath + "/sub/ownCloud1/some/sub/path").isNull());
|
||||
QVERIFY(!folderman->checkPathValidityForNewFolder(dirPath + "/ownCloud2/blublu").isNull());
|
||||
QVERIFY(!folderman->checkPathValidityForNewFolder(dirPath + "/sub/ownCloud1/folder/g/h").isNull());
|
||||
QVERIFY(!folderman->checkPathValidityForNewFolder(dirPath + "/link3/folder/neu_folder").isNull());
|
||||
|
||||
// Subfolder of links
|
||||
QVERIFY(folderman->checkPathValidityForNewFolder(dir.path() + "/link1/subfolder").isNull());
|
||||
QVERIFY(folderman->checkPathValidityForNewFolder(dir.path() + "/link2/free/subfolder").isNull());
|
||||
QVERIFY(folderman->checkPathValidityForNewFolder(dirPath + "/link1/subfolder").isNull());
|
||||
QVERIFY(folderman->checkPathValidityForNewFolder(dirPath + "/link2/free/subfolder").isNull());
|
||||
|
||||
// Invalid paths
|
||||
QVERIFY(!folderman->checkPathValidityForNewFolder("").isNull());
|
||||
|
|
|
@ -10,174 +10,181 @@
|
|||
#include "folderwatcher.h"
|
||||
#include "utility.h"
|
||||
|
||||
void touch(const QString &file)
|
||||
{
|
||||
#ifdef Q_OS_WIN
|
||||
OCC::Utility::writeRandomFile(file);
|
||||
#else
|
||||
QString cmd;
|
||||
cmd = QString("touch %1").arg(file);
|
||||
qDebug() << "Command: " << cmd;
|
||||
system(cmd.toLocal8Bit());
|
||||
#endif
|
||||
}
|
||||
|
||||
void mkdir(const QString &file)
|
||||
{
|
||||
#ifdef Q_OS_WIN
|
||||
QDir dir;
|
||||
dir.mkdir(file);
|
||||
#else
|
||||
QString cmd = QString("mkdir %1").arg(file);
|
||||
qDebug() << "Command: " << cmd;
|
||||
system(cmd.toLocal8Bit());
|
||||
#endif
|
||||
}
|
||||
|
||||
void rmdir(const QString &file)
|
||||
{
|
||||
#ifdef Q_OS_WIN
|
||||
QDir dir;
|
||||
dir.rmdir(file);
|
||||
#else
|
||||
QString cmd = QString("rmdir %1").arg(file);
|
||||
qDebug() << "Command: " << cmd;
|
||||
system(cmd.toLocal8Bit());
|
||||
#endif
|
||||
}
|
||||
|
||||
void rm(const QString &file)
|
||||
{
|
||||
#ifdef Q_OS_WIN
|
||||
QFile::remove(file);
|
||||
#else
|
||||
QString cmd = QString("rm %1").arg(file);
|
||||
qDebug() << "Command: " << cmd;
|
||||
system(cmd.toLocal8Bit());
|
||||
#endif
|
||||
}
|
||||
|
||||
void mv(const QString &file1, const QString &file2)
|
||||
{
|
||||
#ifdef Q_OS_WIN
|
||||
QFile::rename(file1, file2);
|
||||
#else
|
||||
QString cmd = QString("mv %1 %2").arg(file1, file2);
|
||||
qDebug() << "Command: " << cmd;
|
||||
system(cmd.toLocal8Bit());
|
||||
#endif
|
||||
}
|
||||
|
||||
using namespace OCC;
|
||||
|
||||
class TestFolderWatcher : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public slots:
|
||||
void slotFolderChanged( const QString& path ) {
|
||||
if (_skipNotifications.contains(path)) {
|
||||
return;
|
||||
}
|
||||
if (_requiredNotifications.contains(path)) {
|
||||
_receivedNotifications.insert(path);
|
||||
}
|
||||
}
|
||||
QTemporaryDir _root;
|
||||
QString _rootPath;
|
||||
QScopedPointer<FolderWatcher> _watcher;
|
||||
QScopedPointer<QSignalSpy> _pathChangedSpy;
|
||||
|
||||
void slotEnd() { // in case something goes wrong...
|
||||
_loop.quit();
|
||||
QVERIFY2(1 == 0, "Loop hang!");
|
||||
}
|
||||
|
||||
private:
|
||||
QString _root;
|
||||
FolderWatcher *_watcher;
|
||||
QEventLoop _loop;
|
||||
QTimer _timer;
|
||||
QSet<QString> _requiredNotifications;
|
||||
QSet<QString> _receivedNotifications;
|
||||
QSet<QString> _skipNotifications;
|
||||
|
||||
void processAndWait()
|
||||
bool waitForPathChanged(const QString &path)
|
||||
{
|
||||
_loop.processEvents();
|
||||
Utility::usleep(200000);
|
||||
_loop.processEvents();
|
||||
QElapsedTimer t;
|
||||
t.start();
|
||||
while (t.elapsed() < 5000) {
|
||||
// Check if it was already reported as changed by the watcher
|
||||
for (int i = 0; i < _pathChangedSpy->size(); ++i) {
|
||||
const auto &args = _pathChangedSpy->at(i);
|
||||
if (args.first().toString() == path)
|
||||
return true;
|
||||
}
|
||||
// Wait a bit and test again (don't bother checking if we timed out or not)
|
||||
_pathChangedSpy->wait(200);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public:
|
||||
TestFolderWatcher() {
|
||||
qsrand(QTime::currentTime().msec());
|
||||
QDir rootDir(_root.path());
|
||||
_rootPath = rootDir.canonicalPath();
|
||||
qDebug() << "creating test directory tree in " << _rootPath;
|
||||
|
||||
rootDir.mkpath("a1/b1/c1");
|
||||
rootDir.mkpath("a1/b1/c2");
|
||||
rootDir.mkpath("a1/b2/c1");
|
||||
rootDir.mkpath("a1/b3/c3");
|
||||
rootDir.mkpath("a2/b3/c3");
|
||||
Utility::writeRandomFile( _rootPath+"/a1/random.bin");
|
||||
Utility::writeRandomFile( _rootPath+"/a1/b2/todelete.bin");
|
||||
Utility::writeRandomFile( _rootPath+"/a2/renamefile");
|
||||
Utility::writeRandomFile( _rootPath+"/a1/movefile");
|
||||
|
||||
_watcher.reset(new FolderWatcher(_rootPath));
|
||||
_pathChangedSpy.reset(new QSignalSpy(_watcher.data(), SIGNAL(pathChanged(QString))));
|
||||
}
|
||||
|
||||
private slots:
|
||||
void initTestCase() {
|
||||
qsrand(QTime::currentTime().msec());
|
||||
_root = QDir::tempPath() + "/" + "test_" + QString::number(qrand());
|
||||
qDebug() << "creating test directory tree in " << _root;
|
||||
QDir rootDir(_root);
|
||||
|
||||
rootDir.mkpath(_root + "/a1/b1/c1");
|
||||
rootDir.mkpath(_root + "/a1/b1/c2");
|
||||
rootDir.mkpath(_root + "/a1/b2/c1");
|
||||
rootDir.mkpath(_root + "/a1/b3/c3");
|
||||
rootDir.mkpath(_root + "/a2/b3/c3");
|
||||
Utility::writeRandomFile( _root+"/a1/random.bin");
|
||||
Utility::writeRandomFile( _root+"/a1/b2/todelete.bin");
|
||||
Utility::writeRandomFile( _root+"/a2/renamefile");
|
||||
Utility::writeRandomFile( _root+"/a1/movefile");
|
||||
|
||||
_watcher = new FolderWatcher(_root);
|
||||
QObject::connect(_watcher, SIGNAL(pathChanged(QString)), this, SLOT(slotFolderChanged(QString)));
|
||||
_timer.singleShot(5000, this, SLOT(slotEnd()));
|
||||
}
|
||||
|
||||
void init()
|
||||
{
|
||||
_receivedNotifications.clear();
|
||||
_requiredNotifications.clear();
|
||||
_skipNotifications.clear();
|
||||
}
|
||||
|
||||
void checkNotifications()
|
||||
{
|
||||
processAndWait();
|
||||
QCOMPARE(_receivedNotifications, _requiredNotifications);
|
||||
_pathChangedSpy->clear();
|
||||
}
|
||||
|
||||
void testACreate() { // create a new file
|
||||
QString file(_root + "/foo.txt");
|
||||
QString file(_rootPath + "/foo.txt");
|
||||
QString cmd;
|
||||
_requiredNotifications.insert(file);
|
||||
cmd = QString("echo \"xyz\" > %1").arg(file);
|
||||
qDebug() << "Command: " << cmd;
|
||||
system(cmd.toLocal8Bit());
|
||||
|
||||
checkNotifications();
|
||||
QVERIFY(waitForPathChanged(file));
|
||||
}
|
||||
|
||||
void testATouch() { // touch an existing file.
|
||||
QString file(_root + "/a1/random.bin");
|
||||
_requiredNotifications.insert(file);
|
||||
#ifdef Q_OS_WIN
|
||||
Utility::writeRandomFile(QString("%1/a1/random.bin").arg(_root));
|
||||
#else
|
||||
QString cmd;
|
||||
cmd = QString("touch %1").arg(file);
|
||||
qDebug() << "Command: " << cmd;
|
||||
system(cmd.toLocal8Bit());
|
||||
#endif
|
||||
|
||||
checkNotifications();
|
||||
QString file(_rootPath + "/a1/random.bin");
|
||||
touch(file);
|
||||
QVERIFY(waitForPathChanged(file));
|
||||
}
|
||||
|
||||
void testCreateADir() {
|
||||
QString file(_root+"/a1/b1/new_dir");
|
||||
_requiredNotifications.insert(file);
|
||||
//_skipNotifications.insert(_root + "/a1/b1/new_dir");
|
||||
QDir dir;
|
||||
dir.mkdir(file);
|
||||
QVERIFY(QFile::exists(file));
|
||||
|
||||
checkNotifications();
|
||||
QString file(_rootPath+"/a1/b1/new_dir");
|
||||
mkdir(file);
|
||||
QVERIFY(waitForPathChanged(file));
|
||||
}
|
||||
|
||||
void testRemoveADir() {
|
||||
QString file(_root+"/a1/b3/c3");
|
||||
_requiredNotifications.insert(file);
|
||||
QDir dir;
|
||||
QVERIFY(dir.rmdir(file));
|
||||
|
||||
checkNotifications();
|
||||
QString file(_rootPath+"/a1/b3/c3");
|
||||
rmdir(file);
|
||||
QVERIFY(waitForPathChanged(file));
|
||||
}
|
||||
|
||||
void testRemoveAFile() {
|
||||
QString file(_root+"/a1/b2/todelete.bin");
|
||||
_requiredNotifications.insert(file);
|
||||
QString file(_rootPath+"/a1/b2/todelete.bin");
|
||||
QVERIFY(QFile::exists(file));
|
||||
QFile::remove(file);
|
||||
rm(file);
|
||||
QVERIFY(!QFile::exists(file));
|
||||
|
||||
checkNotifications();
|
||||
QVERIFY(waitForPathChanged(file));
|
||||
}
|
||||
|
||||
void testRenameAFile() {
|
||||
QString file1(_root+"/a2/renamefile");
|
||||
QString file2(_root+"/a2/renamefile.renamed");
|
||||
_requiredNotifications.insert(file1);
|
||||
_requiredNotifications.insert(file2);
|
||||
QString file1(_rootPath+"/a2/renamefile");
|
||||
QString file2(_rootPath+"/a2/renamefile.renamed");
|
||||
QVERIFY(QFile::exists(file1));
|
||||
QFile::rename(file1, file2);
|
||||
mv(file1, file2);
|
||||
QVERIFY(QFile::exists(file2));
|
||||
|
||||
checkNotifications();
|
||||
QVERIFY(waitForPathChanged(file1));
|
||||
QVERIFY(waitForPathChanged(file2));
|
||||
}
|
||||
|
||||
void testMoveAFile() {
|
||||
QString old_file(_root+"/a1/movefile");
|
||||
QString new_file(_root+"/a2/movefile.renamed");
|
||||
_requiredNotifications.insert(old_file);
|
||||
_requiredNotifications.insert(new_file);
|
||||
QString old_file(_rootPath+"/a1/movefile");
|
||||
QString new_file(_rootPath+"/a2/movefile.renamed");
|
||||
QVERIFY(QFile::exists(old_file));
|
||||
QFile::rename(old_file, new_file);
|
||||
mv(old_file, new_file);
|
||||
QVERIFY(QFile::exists(new_file));
|
||||
|
||||
checkNotifications();
|
||||
}
|
||||
|
||||
void cleanupTestCase() {
|
||||
if( _root.startsWith(QDir::tempPath() )) {
|
||||
system( QString("rm -rf %1").arg(_root).toLocal8Bit() );
|
||||
}
|
||||
delete _watcher;
|
||||
QVERIFY(waitForPathChanged(old_file));
|
||||
QVERIFY(waitForPathChanged(new_file));
|
||||
}
|
||||
};
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
|
||||
// Qt4 does not have QTEST_GUILESS_MAIN, so we simulate it.
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QCoreApplication app(argc, argv);
|
||||
TestFolderWatcher tc;
|
||||
return QTest::qExec(&tc, argc, argv);
|
||||
}
|
||||
#ifdef Q_OS_MAC
|
||||
QTEST_MAIN(TestFolderWatcher)
|
||||
#else
|
||||
QTEST_GUILESS_MAIN(TestFolderWatcher)
|
||||
#endif
|
||||
|
|
|
@ -169,7 +169,6 @@ private slots:
|
|||
void testFileNamesEqual()
|
||||
{
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 1, 0)
|
||||
qDebug() << "*** checking fileNamesEqual function";
|
||||
QTemporaryDir dir;
|
||||
QVERIFY(dir.isValid());
|
||||
QDir dir2(dir.path());
|
||||
|
@ -201,5 +200,5 @@ private slots:
|
|||
|
||||
};
|
||||
|
||||
QTEST_APPLESS_MAIN(TestUtility)
|
||||
QTEST_GUILESS_MAIN(TestUtility)
|
||||
#include "testutility.moc"
|
||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue