From 0ce1cf4ec55b961121f761abe07d06136b591c7e Mon Sep 17 00:00:00 2001 From: Christophe Larchier Date: Mon, 28 Oct 2024 16:47:46 +0100 Subject: [PATCH 001/178] Intermediate commit --- .../keychainmanager/keychainmanager.cpp | 2 - src/libcommon/log/sentry/sentryhandler.h | 2 +- src/libcommon/utility/utility.cpp | 2 - src/libcommonserver/log/log.h | 1 - src/libcommonserver/utility/utility.cpp | 2 - src/libcommonserver/vfs.h | 2 + .../jobs/network/abstractnetworkjob.h | 2 +- .../propagation/executor/executorworker.cpp | 2 +- src/server/updater/updaterserver.h | 2 +- src/server/updater_v2/abstractupdater.cpp | 7 +- src/server/updater_v2/abstractupdater.h | 2 +- src/server/vfs/mac/vfs_mac.h | 2 + src/server/vfs/win/CMakeLists.txt | 6 + src/server/vfs/win/vfs_win.h | 7 +- test/libcommon/CMakeLists.txt | 11 -- test/libcommonserver/CMakeLists.txt | 11 -- test/libparms/CMakeLists.txt | 11 -- test/libsyncengine/CMakeLists.txt | 11 -- test/server/CMakeLists.txt | 114 +++++++++--------- test/server/logarchiver/testlogarchiver.cpp | 4 +- test/server/updater/testabstractupdater.cpp | 3 +- test/server/updater/testupdater.cpp | 3 +- test/server/updater/testupdater.h | 2 + test/server/workers/testworkers.cpp | 81 ++++++++++--- test/server/workers/testworkers.h | 15 ++- test/test.cpp | 1 - test/test_utility/localtemporarydirectory.cpp | 4 +- test/test_utility/localtemporarydirectory.h | 2 +- test/test_utility/testhelpers.cpp | 2 +- test/test_utility/testhelpers.h | 4 +- test/testincludes.h | 2 - 31 files changed, 167 insertions(+), 155 deletions(-) diff --git a/src/libcommon/keychainmanager/keychainmanager.cpp b/src/libcommon/keychainmanager/keychainmanager.cpp index f7bb879da..fb408da41 100644 --- a/src/libcommon/keychainmanager/keychainmanager.cpp +++ b/src/libcommon/keychainmanager/keychainmanager.cpp @@ -22,8 +22,6 @@ #include -#include - #define PACKAGE "com.infomaniak.drive" #define SERVICE "desktopclient" diff --git a/src/libcommon/log/sentry/sentryhandler.h b/src/libcommon/log/sentry/sentryhandler.h index 912515c23..7f50dad3f 100644 --- a/src/libcommon/log/sentry/sentryhandler.h +++ b/src/libcommon/log/sentry/sentryhandler.h @@ -22,7 +22,7 @@ #include #include -#include "utility/types.h" +#include "libcommon/utility/types.h" #include "sentryuser.h" namespace KDC { diff --git a/src/libcommon/utility/utility.cpp b/src/libcommon/utility/utility.cpp index f99c4513d..6c5a25cdf 100644 --- a/src/libcommon/utility/utility.cpp +++ b/src/libcommon/utility/utility.cpp @@ -37,8 +37,6 @@ #include #endif -#include - #ifdef ZLIB_FOUND #include #endif diff --git a/src/libcommonserver/log/log.h b/src/libcommonserver/log/log.h index f8502d7b6..ddb704524 100644 --- a/src/libcommonserver/log/log.h +++ b/src/libcommonserver/log/log.h @@ -24,7 +24,6 @@ #include #include -#include #include "libcommon/log/sentry/sentryhandler.h" #include "libcommon/log/customlogwstream.h" diff --git a/src/libcommonserver/utility/utility.cpp b/src/libcommonserver/utility/utility.cpp index d7ef61fb9..b68c7e04c 100644 --- a/src/libcommonserver/utility/utility.cpp +++ b/src/libcommonserver/utility/utility.cpp @@ -48,8 +48,6 @@ #include #include -#include - #ifndef _WIN32 #include #endif diff --git a/src/libcommonserver/vfs.h b/src/libcommonserver/vfs.h index ad7201f94..985f5ccbf 100644 --- a/src/libcommonserver/vfs.h +++ b/src/libcommonserver/vfs.h @@ -294,6 +294,8 @@ class VfsOff : public Vfs { protected: bool startImpl(bool &installationDone, bool &activationDone, bool &connectionDone) override; void stopImpl(bool /*unregister*/) override {} + + friend class TestWorkers; }; /// Check whether the plugin for the mode is available. diff --git a/src/libsyncengine/jobs/network/abstractnetworkjob.h b/src/libsyncengine/jobs/network/abstractnetworkjob.h index d68631bab..2854cec57 100644 --- a/src/libsyncengine/jobs/network/abstractnetworkjob.h +++ b/src/libsyncengine/jobs/network/abstractnetworkjob.h @@ -18,7 +18,7 @@ #pragma once -#include "jobs/abstractjob.h" +#include "libsyncengine/jobs/abstractjob.h" #include #include diff --git a/src/libsyncengine/propagation/executor/executorworker.cpp b/src/libsyncengine/propagation/executor/executorworker.cpp index 027850c75..aaa368d3d 100644 --- a/src/libsyncengine/propagation/executor/executorworker.cpp +++ b/src/libsyncengine/propagation/executor/executorworker.cpp @@ -826,7 +826,7 @@ ExitCode ExecutorWorker::convertToPlaceholder(const SyncPath &relativeLocalPath, #ifdef __APPLE__ // VfsMac::convertToPlaceholder needs only SyncFileItem::_dehydrated syncItem.setDehydrated(!hydrated); -#elif __WIN32 +#elif _WIN32 // VfsWin::convertToPlaceholder needs only SyncFileItem::_localNodeId FileStat fileStat; IoError ioError = IoError::Success; diff --git a/src/server/updater/updaterserver.h b/src/server/updater/updaterserver.h index f9fc8377e..96996611d 100644 --- a/src/server/updater/updaterserver.h +++ b/src/server/updater/updaterserver.h @@ -18,7 +18,7 @@ #pragma once -#include "../libcommon/updater.h" +#include "libcommon/updater.h" #include #include diff --git a/src/server/updater_v2/abstractupdater.cpp b/src/server/updater_v2/abstractupdater.cpp index eea8b9f06..1ae294520 100644 --- a/src/server/updater_v2/abstractupdater.cpp +++ b/src/server/updater_v2/abstractupdater.cpp @@ -20,11 +20,10 @@ #include "abstractupdater.h" #include "db/parmsdb.h" -#include "../../libsyncengine/jobs/network/API_v2/downloadjob.h" -#include "jobs/network/getappversionjob.h" +#include "libsyncengine/jobs/network/getappversionjob.h" #include "libcommon/utility/utility.h" -#include "log/log.h" -#include "utility/utility.h" +#include "libcommonserver/utility/utility.h" +#include "libcommonserver/log/log.h" namespace KDC { diff --git a/src/server/updater_v2/abstractupdater.h b/src/server/updater_v2/abstractupdater.h index 9c3e23ae7..2060a1d8a 100644 --- a/src/server/updater_v2/abstractupdater.h +++ b/src/server/updater_v2/abstractupdater.h @@ -19,7 +19,7 @@ #pragma once -#include "jobs/network/getappversionjob.h" +#include "libsyncengine/jobs/network/getappversionjob.h" #include "utility/types.h" diff --git a/src/server/vfs/mac/vfs_mac.h b/src/server/vfs/mac/vfs_mac.h index 435248850..6ce28622c 100644 --- a/src/server/vfs/mac/vfs_mac.h +++ b/src/server/vfs/mac/vfs_mac.h @@ -97,6 +97,8 @@ class VfsMac : public Vfs { bool startImpl(bool &installationDone, bool &activationDone, bool &connectionDone) override; void stopImpl(bool unregister) override; + friend class TestWorkers; + private: LiteSyncExtConnector *_connector{nullptr}; diff --git a/src/server/vfs/win/CMakeLists.txt b/src/server/vfs/win/CMakeLists.txt index 01e188ca8..703bb736f 100644 --- a/src/server/vfs/win/CMakeLists.txt +++ b/src/server/vfs/win/CMakeLists.txt @@ -24,4 +24,10 @@ set_target_properties("${libsyncengine_NAME}_vfs_win" PROPERTIES AUTOMOC TRUE ) +# For testing: Export symbols to be able to link the library statically +GENERATE_EXPORT_HEADER("${libsyncengine_NAME}_vfs_win" + BASE_NAME "${libsyncengine_NAME}_vfs_win" + EXPORT_MACRO_NAME SYNCENGINEVFS_EXPORT + EXPORT_FILE_NAME syncenginevfslib.h +) diff --git a/src/server/vfs/win/vfs_win.h b/src/server/vfs/win/vfs_win.h index c55d8afa0..ec2b421c9 100644 --- a/src/server/vfs/win/vfs_win.h +++ b/src/server/vfs/win/vfs_win.h @@ -18,6 +18,7 @@ #pragma once +#include "server/vfs/win/syncenginevfslib.h" #include "libcommonserver/vfs.h" #include "libcommonserver/plugin.h" @@ -52,14 +53,14 @@ struct WorkerInfo { QList _threadList; }; -class VfsWin : public Vfs { +class SYNCENGINEVFS_EXPORT VfsWin : public Vfs { Q_OBJECT Q_INTERFACES(KDC::Vfs) public: WorkerInfo _workerInfo[NB_WORKERS]; - explicit VfsWin(VfsSetupParams &vfsSetupParams, QObject *parent); + explicit VfsWin(VfsSetupParams &vfsSetupParams, QObject *parent = nullptr); ~VfsWin(); void debugCbk(TraceLevel level, const wchar_t *msg); @@ -107,6 +108,8 @@ class VfsWin : public Vfs { bool startImpl(bool &installationDone, bool &activationDone, bool &connectionDone) override; void stopImpl(bool unregister) override; + friend class TestWorkers; + private: log4cplus::Logger _logger; diff --git a/test/libcommon/CMakeLists.txt b/test/libcommon/CMakeLists.txt index 2203afaa8..223cd647b 100644 --- a/test/libcommon/CMakeLists.txt +++ b/test/libcommon/CMakeLists.txt @@ -33,17 +33,6 @@ target_link_libraries(${testcommon_NAME} ${libcommonserver_NAME} ) -if (WIN32) - target_link_libraries(${testcommon_NAME} - log4cplus::log4cplusU) -elseif (APPLE) - target_link_libraries(${testcommon_NAME} - "/usr/local/lib/liblog4cplusU.dylib") -else () - target_link_libraries(${testcommon_NAME} - "/usr/local/lib/liblog4cplusU.so") -endif () - if (WIN32) target_link_libraries(${testcommon_NAME} debug diff --git a/test/libcommonserver/CMakeLists.txt b/test/libcommonserver/CMakeLists.txt index 84a7122fb..665ba0b88 100644 --- a/test/libcommonserver/CMakeLists.txt +++ b/test/libcommonserver/CMakeLists.txt @@ -47,17 +47,6 @@ target_link_libraries(${testcommonserver_NAME} ${libcommonserver_NAME} ) -if (WIN32) - target_link_libraries(${testcommonserver_NAME} - log4cplus::log4cplusU) -elseif (APPLE) - target_link_libraries(${testcommonserver_NAME} - "/usr/local/lib/liblog4cplusU.dylib") -else () - target_link_libraries(${testcommonserver_NAME} - "/usr/local/lib/liblog4cplusU.so") -endif () - if (WIN32) target_link_libraries(${testcommonserver_NAME} debug diff --git a/test/libparms/CMakeLists.txt b/test/libparms/CMakeLists.txt index 341de4955..fca3f59a1 100644 --- a/test/libparms/CMakeLists.txt +++ b/test/libparms/CMakeLists.txt @@ -34,17 +34,6 @@ target_link_libraries(${testparms_NAME} ${SQLITE3_LIBRARIES} ) -if (WIN32) - target_link_libraries(${testparms_NAME} - log4cplus::log4cplusU) -elseif(APPLE) - target_link_libraries(${testparms_NAME} - "/usr/local/lib/liblog4cplusU.dylib") -else() - target_link_libraries(${testparms_NAME} - "/usr/local/lib/liblog4cplusU.so") -endif() - if (WIN32) target_link_libraries(${testparms_NAME} debug diff --git a/test/libsyncengine/CMakeLists.txt b/test/libsyncengine/CMakeLists.txt index b99438623..319696e54 100644 --- a/test/libsyncengine/CMakeLists.txt +++ b/test/libsyncengine/CMakeLists.txt @@ -78,17 +78,6 @@ target_link_libraries(${testsyncengine_NAME} ${SQLITE3_LIBRARIES} ) -if (WIN32) - target_link_libraries(${testsyncengine_NAME} - log4cplus::log4cplusU) -elseif (APPLE) - target_link_libraries(${testsyncengine_NAME} - "/usr/local/lib/liblog4cplusU.dylib") -else () - target_link_libraries(${testsyncengine_NAME} - "/usr/local/lib/liblog4cplusU.so") -endif () - if (WIN32) target_link_libraries(${testsyncengine_NAME} debug diff --git a/test/server/CMakeLists.txt b/test/server/CMakeLists.txt index dfb3d90a4..4d1cbf440 100644 --- a/test/server/CMakeLists.txt +++ b/test/server/CMakeLists.txt @@ -1,25 +1,29 @@ project(testserver) -find_package(Qt6 REQUIRED COMPONENTS Core Gui Network Svg) -find_package(log4cplus 2.1.0 REQUIRED) +find_package(Qt6 REQUIRED COMPONENTS Network Svg) find_package(Poco 1.13.3 REQUIRED XML Net) set(CMAKE_AUTOMOC ON) set(testserver_NAME ${APPLICATION_NAME}_test_server) -set(server_srcs_path ${CMAKE_SOURCE_DIR}/src/server) + +set(server_SRCS + ../../src/libcommon/updater.h ../../src/libcommon/updater.cpp + ../../src/libcommonserver/vfs.h ../../src/libcommonserver/vfs.cpp + ../../src/libcommonserver/plugin.h ../../src/libcommonserver/plugin.cpp + ../../src/server/logarchiver.h ../../src/server/logarchiver.cpp + ../../src/server/socketapi.h ../../src/server/socketapi.cpp + ../../src/server/socketlistener.h ../../src/server/socketlistener.cpp + ../../src/server/updater/kdcupdater.h ../../src/server/updater/kdcupdater.cpp + ../../src/server/updater/updateinfo.h ../../src/server/updater/updateinfo.cpp + ../../src/server/updater/updaterserver.h ../../src/server/updater/updaterserver.cpp + ../../src/server/updater_v2/abstractupdater.h ../../src/server/updater_v2/abstractupdater.cpp +) set(testserver_SRCS - ../test.cpp ../test_utility/testhelpers.h ../test_utility/testhelpers.cpp ../test_utility/localtemporarydirectory.h ../test_utility/localtemporarydirectory.cpp - ${CMAKE_SOURCE_DIR}/src/libcommon/updater.h ${CMAKE_SOURCE_DIR}/src/libcommon/updater.cpp - ${CMAKE_SOURCE_DIR}/src/libcommonserver/plugin.h ${CMAKE_SOURCE_DIR}/src/libcommonserver/plugin.cpp - ${CMAKE_SOURCE_DIR}/src/libcommonserver/vfs.h ${CMAKE_SOURCE_DIR}/src/libcommonserver/vfs.cpp - ${server_srcs_path}/logarchiver.h ${server_srcs_path}/logarchiver.cpp - ${server_srcs_path}/updater/kdcupdater.h ${server_srcs_path}/updater/kdcupdater.cpp - ${server_srcs_path}/updater/updateinfo.h ${server_srcs_path}/updater/updateinfo.cpp - ${server_srcs_path}/updater/updaterserver.h ${server_srcs_path}/updater/updaterserver.cpp - ${server_srcs_path}/updater_v2/abstractupdater.h ${server_srcs_path}/updater_v2/abstractupdater.cpp + ../test.cpp + test.cpp logarchiver/testlogarchiver.h logarchiver/testlogarchiver.cpp updater/testupdater.h updater/testupdater.cpp @@ -29,16 +33,10 @@ set(testserver_SRCS if(APPLE) list(APPEND testserver_SRCS vfs/mac/testlitesyncextconnector.h vfs/mac/testlitesyncextconnector.cpp) - list(APPEND server_SRCS socketapisocket_mac.mm) - set_property(SOURCE socketapisocket_mac.mm APPEND_STRING PROPERTY COMPILE_FLAGS "-fobjc-arc") - - list(APPEND server_SRCS ../../extensions/MacOSX/kDriveFinderSync/kDrive/NSXPCConnection+LoginItem.m) - set_property(SOURCE ../../extensions/MacOSX/kDriveFinderSync/kDrive/NSXPCConnection+LoginItem.m APPEND_STRING PROPERTY COMPILE_FLAGS "-fobjc-arc") if(SPARKLE_FOUND) # Define this, we need to check in updater.cpp add_definitions(-DHAVE_SPARKLE) - list(APPEND testserver_SRCS ${server_srcs_path}/updater/sparkleupdater.h ${server_srcs_path}/updater/sparkleupdater_mac.mm) list(APPEND updater_DEPS ${SPARKLE_LIBRARY}) # Sparkle.framework is installed from here because macdeployqt's CopyFramework breaks on this bundle @@ -58,63 +56,50 @@ else () include_directories("/usr/local/include") endif() -add_executable(${testserver_NAME} ${testserver_SRCS}) +add_executable(${testserver_NAME} + ${server_SRCS} + ${testserver_SRCS}) set_target_properties(${testserver_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${BIN_OUTPUT_DIRECTORY}) target_link_libraries(${testserver_NAME} - Qt6::Core Qt6::Gui - Poco::XML Poco::Net + Qt6::Svg + ${libcommon_NAME} + ${libsyncengine_NAME} + updater ) -if (WIN32) - target_link_libraries(${testserver_NAME} - log4cplus::log4cplusU) -elseif (APPLE) +if (APPLE) target_link_libraries(${testserver_NAME} - "/usr/local/lib/liblog4cplusU.dylib") -else () + "${libsyncengine_NAME}_vfs_mac" + "${updater_DEPS}") +elseif (WIN32) + set(CMAKE_FIND_LIBRARY_SUFFIXES .lib) + find_library(LIBSYNCENGINE_VFS_STATIC_LIBRARY + NAMES "${libsyncengine_NAME}_vfs_win" + PATHS "${CMAKE_BINARY_DIR}/src/server/vfs/win" + NO_DEFAULT_PATH + NO_CACHE) target_link_libraries(${testserver_NAME} - "/usr/local/lib/liblog4cplusU.so") + "${LIBSYNCENGINE_VFS_STATIC_LIBRARY}") endif() if (WIN32) target_link_libraries(${testserver_NAME} - debug - "C:/Program Files (x86)/cppunit/lib/cppunitd.lib" - optimized - "C:/Program Files (x86)/cppunit/lib/cppunit.lib") + debug + "C:/Program Files (x86)/cppunit/lib/cppunitd.lib" + optimized + "C:/Program Files (x86)/cppunit/lib/cppunit.lib") elseif (APPLE) target_link_libraries(${testserver_NAME} - "/usr/local/lib/libcppunit.dylib") + "/usr/local/lib/libcppunit.dylib") else () target_link_libraries(${testserver_NAME} - "/usr/local/lib/libcppunit.so") -endif() - - -# Loaded after liblog4cplus to avoid an initialization crash -if (APPLE) - target_link_libraries(${testserver_NAME} - "${libsyncengine_NAME}_vfs_mac" - "${updater_DEPS}") -else() - target_link_libraries(${testserver_NAME} - ${libsyncengine_NAME}) + "/usr/local/lib/libcppunit.so") endif() # Install - -# VFS plugin -set(vfs_installdir "${BIN_OUTPUT_DIRECTORY}") -if (APPLE) - install(TARGETS "${libsyncengine_NAME}_vfs_mac" - LIBRARY DESTINATION "${vfs_installdir}" - RUNTIME DESTINATION "${vfs_installdir}" - ) -endif() - if (APPLE) # Default sync exclude list install(FILES ${CMAKE_SOURCE_DIR}/sync-exclude-osx.lst DESTINATION ${BIN_OUTPUT_DIRECTORY} RENAME sync-exclude.lst) @@ -122,8 +107,27 @@ if (APPLE) # Default Lite Sync app exclude list install(FILES ${CMAKE_SOURCE_DIR}/litesync-exclude.lst DESTINATION ${BIN_OUTPUT_DIRECTORY}) + #Vfs + install(TARGETS "${libsyncengine_NAME}_vfs_mac" + LIBRARY DESTINATION "${BIN_OUTPUT_DIRECTORY}" + RUNTIME DESTINATION "${BIN_OUTPUT_DIRECTORY}") + install(CODE " message(STATUS \"Fixing library paths for ${testserver_NAME}...\") execute_process(COMMAND \"install_name_tool\" -change libxxhash.0.dylib @rpath/libxxhash.0.8.2.dylib ${BIN_OUTPUT_DIRECTORY}/${testserver_NAME}) " COMPONENT RUNTIME) +elseif (WIN32) + #Vfs + set(CMAKE_FIND_LIBRARY_SUFFIXES .dll) + find_library(VFS_SHARED_LIBRARY + NAMES vfs + PATHS ${VFS_DIRECTORY} + NO_DEFAULT_PATH + NO_CACHE) + install(FILES ${VFS_SHARED_LIBRARY} + DESTINATION ${BIN_OUTPUT_DIRECTORY}) + + install(TARGETS "${libsyncengine_NAME}_vfs_win" + LIBRARY DESTINATION "${BIN_OUTPUT_DIRECTORY}" + RUNTIME DESTINATION "${BIN_OUTPUT_DIRECTORY}") endif() diff --git a/test/server/logarchiver/testlogarchiver.cpp b/test/server/logarchiver/testlogarchiver.cpp index b4f4b127a..93f33912b 100644 --- a/test/server/logarchiver/testlogarchiver.cpp +++ b/test/server/logarchiver/testlogarchiver.cpp @@ -18,11 +18,11 @@ #include "testlogarchiver.h" #include "server/logarchiver.h" +#include "libcommon/utility/utility.h" #include "libcommonserver/log/log.h" -#include "test_utility/localtemporarydirectory.h" #include "libcommonserver/io/iohelper.h" -#include "libcommon/utility/utility.h" #include "libcommonserver/db/db.h" +#include "test_utility/localtemporarydirectory.h" #include diff --git a/test/server/updater/testabstractupdater.cpp b/test/server/updater/testabstractupdater.cpp index 0a13f5385..bbcbfffb8 100644 --- a/test/server/updater/testabstractupdater.cpp +++ b/test/server/updater/testabstractupdater.cpp @@ -21,8 +21,7 @@ #include "db/parmsdb.h" #include "requests/parameterscache.h" -#include "jobs/network/getappversionjob.h" -#include "keychainmanager/keychainmanager.h" +#include "libsyncengine/jobs/network/getappversionjob.h" #include diff --git a/test/server/updater/testupdater.cpp b/test/server/updater/testupdater.cpp index 61a3e2d96..4d4f0dddb 100644 --- a/test/server/updater/testupdater.cpp +++ b/test/server/updater/testupdater.cpp @@ -17,10 +17,11 @@ */ #include "testupdater.h" -#include "libsyncengine/requests/parameterscache.h" #include "version.h" #include "libcommonserver/log/log.h" +#include "libsyncengine/requests/parameterscache.h" + #include #include diff --git a/test/server/updater/testupdater.h b/test/server/updater/testupdater.h index 5d92304e0..88fb2482c 100644 --- a/test/server/updater/testupdater.h +++ b/test/server/updater/testupdater.h @@ -23,6 +23,8 @@ #include "server/updater/sparkleupdater.h" #endif +#include + using namespace CppUnit; namespace KDC { diff --git a/test/server/workers/testworkers.cpp b/test/server/workers/testworkers.cpp index b341a6715..761eac8b0 100644 --- a/test/server/workers/testworkers.cpp +++ b/test/server/workers/testworkers.cpp @@ -19,19 +19,23 @@ #include "testworkers.h" #include "propagation/executor/executorworker.h" -#include "keychainmanager/keychainmanager.h" -#include "network/proxy.h" -#include "io/iohelper.h" +#include "libcommon/keychainmanager/keychainmanager.h" +#include "libcommonserver/network/proxy.h" +#include "libcommonserver/io/iohelper.h" #include "test_utility/testhelpers.h" +#ifdef _WIN32 +#include +#endif + namespace KDC { #if defined(__APPLE__) -std::unique_ptr TestWorkers::_vfsPtr = nullptr; -#elif defined(__WIN32) -std::unique_ptr TestWorkers::_vfsPtr = nullptr; +std::shared_ptr TestWorkers::_vfsPtr = nullptr; +#elif defined(_WIN32) +std::shared_ptr TestWorkers::_vfsPtr = nullptr; #else -std::unique_ptr TestWorkers::_vfsPtr = nullptr; +std::shared_ptr TestWorkers::_vfsPtr = nullptr; #endif bool TestWorkers::createPlaceholder(int syncDbId, const SyncPath &relativeLocalPath, const SyncFileItem &item) { @@ -96,7 +100,7 @@ void TestWorkers::setUp() { _sync = Sync(1, drive.dbId(), localPathStr, testVariables.remotePath); #if defined(__APPLE__) _sync.setVirtualFileMode(VirtualFileMode::Mac); -#elif defined(__WIN32) +#elif defined(_WIN32) _sync.setVirtualFileMode(VirtualFileMode::Win); #else _sync.setVirtualFileMode(VirtualFileMode::Off); @@ -113,7 +117,7 @@ void TestWorkers::setUp() { // Create VFS instance VfsSetupParams vfsSetupParams; vfsSetupParams._syncDbId = _sync.dbId(); -#ifdef __WIN32 +#ifdef _WIN32 vfsSetupParams._driveId = drive.driveId(); vfsSetupParams._userId = user.userId(); #endif @@ -122,11 +126,11 @@ void TestWorkers::setUp() { vfsSetupParams._logger = _logger; #if defined(__APPLE__) - _vfsPtr = std::unique_ptr(new VfsMac(vfsSetupParams)); -#elif defined(__WIN32) - _vfsPtr = std::unique_ptr(new VfsWin(vfsSetupParams)); + _vfsPtr = std::shared_ptr(new VfsMac(vfsSetupParams)); +#elif defined(_WIN32) + _vfsPtr = std::shared_ptr(new VfsWin(vfsSetupParams)); #else - _vfsPtr = std::unique_ptr(new VfsOff(vfsSetupParams)); + _vfsPtr = std::shared_ptr(new VfsOff(vfsSetupParams)); #endif // Setup SyncPal @@ -137,6 +141,27 @@ void TestWorkers::setUp() { _syncPal->setVfsCreatePlaceholderCallback(createPlaceholder); _syncPal->setVfsConvertToPlaceholderCallback(convertToPlaceholder); _syncPal->setVfsSetPinStateCallback(setPinState); + + // Setup SocketApi + std::unordered_map> syncPalMap; + syncPalMap[_sync.dbId()] = _syncPal; + std::unordered_map> vfsMap; + vfsMap[_sync.dbId()] = _vfsPtr; + _socketApi = std::make_unique(syncPalMap, vfsMap); + +#ifdef _WIN32 + // Initializes the COM library + CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED); +#endif + + // Start Vfs + bool installationDone; + bool activationDone; + bool connectionDone; + CPPUNIT_ASSERT(_vfsPtr->startImpl(installationDone, activationDone, connectionDone)); + CPPUNIT_ASSERT(installationDone); + CPPUNIT_ASSERT(activationDone); + CPPUNIT_ASSERT(connectionDone); } void TestWorkers::tearDown() { @@ -146,6 +171,8 @@ void TestWorkers::tearDown() { _syncPal->syncDb()->close(); } if (_vfsPtr) { + // Stop Vfs + _vfsPtr->stopImpl(true); _vfsPtr = nullptr; } } @@ -171,6 +198,9 @@ void TestWorkers::testCreatePlaceholder() { syncItem.setPath(relativeFolderPath); syncItem.setType(NodeType::Directory); syncItem.setDirection(SyncDirection::Down); +#ifdef _WIN32 + syncItem.setRemoteNodeId("1"); +#endif _syncPal->initProgress(syncItem); // Folder doesn't exist (normal case) @@ -179,12 +209,18 @@ void TestWorkers::testCreatePlaceholder() { CPPUNIT_ASSERT_EQUAL(exitCode, ExitCode::Ok); CPPUNIT_ASSERT_EQUAL(exitCause, ExitCause::Unknown); -#if defined(__APPLE__) || defined(__WIN32) +#ifdef __APPLE__ // Folder already exists exitCause = ExitCause::Unknown; exitCode = _syncPal->_executorWorker->createPlaceholder(relativeFolderPath, exitCause); CPPUNIT_ASSERT_EQUAL(exitCode, ExitCode::DataError); CPPUNIT_ASSERT_EQUAL(exitCause, ExitCause::InvalidSnapshot); +#elif _WIN32 + // Folder already exists + exitCause = ExitCause::Unknown; + exitCode = _syncPal->_executorWorker->createPlaceholder(relativeFolderPath, exitCause); + CPPUNIT_ASSERT_EQUAL(exitCode, ExitCode::Ok); + CPPUNIT_ASSERT_EQUAL(exitCause, ExitCause::Unknown); #endif } @@ -195,9 +231,12 @@ void TestWorkers::testCreatePlaceholder() { syncItem.setPath(relativeFilePath); syncItem.setType(NodeType::File); syncItem.setDirection(SyncDirection::Down); +#ifdef _WIN32 + syncItem.setRemoteNodeId("2"); +#endif _syncPal->initProgress(syncItem); -#if defined(__APPLE__) || defined(__WIN32) +#if defined(__APPLE__) || defined(_WIN32) // Folder access denied IoError ioError{IoError::Unknown}; CPPUNIT_ASSERT(IoHelper::setRights(_syncPal->localPath() / relativeFolderPath, false, false, false, ioError) && @@ -219,12 +258,18 @@ void TestWorkers::testCreatePlaceholder() { CPPUNIT_ASSERT_EQUAL(exitCode, ExitCode::Ok); CPPUNIT_ASSERT_EQUAL(exitCause, ExitCause::Unknown); -#if defined(__APPLE__) || defined(__WIN32) +#ifdef __APPLE__ // File already exists exitCause = ExitCause::Unknown; exitCode = _syncPal->_executorWorker->createPlaceholder(relativeFilePath, exitCause); CPPUNIT_ASSERT_EQUAL(exitCode, ExitCode::DataError); CPPUNIT_ASSERT_EQUAL(exitCause, ExitCause::InvalidSnapshot); +#elif _WIN32 + // File already exists + exitCause = ExitCause::Unknown; + exitCode = _syncPal->_executorWorker->createPlaceholder(relativeFilePath, exitCause); + CPPUNIT_ASSERT_EQUAL(exitCode, ExitCode::Ok); + CPPUNIT_ASSERT_EQUAL(exitCause, ExitCause::Unknown); #endif } } @@ -252,7 +297,7 @@ void TestWorkers::testConvertToPlaceholder() { syncItem.setDirection(SyncDirection::Down); _syncPal->initProgress(syncItem); -#if defined(__APPLE__) || defined(__WIN32) +#if defined(__APPLE__) || defined(_WIN32) // Folder doesn't exist exitCause = ExitCause::Unknown; exitCode = _syncPal->_executorWorker->convertToPlaceholder(relativeFolderPath, true, exitCause); @@ -279,7 +324,7 @@ void TestWorkers::testConvertToPlaceholder() { syncItem.setDirection(SyncDirection::Down); _syncPal->initProgress(syncItem); -#if defined(__APPLE__) || defined(__WIN32) +#if defined(__APPLE__) || defined(_WIN32) // Folder access denied IoError ioError{IoError::Unknown}; CPPUNIT_ASSERT(IoHelper::setRights(_syncPal->localPath() / relativeFolderPath, false, false, false, ioError) && diff --git a/test/server/workers/testworkers.h b/test/server/workers/testworkers.h index 34a43a73f..da895768f 100644 --- a/test/server/workers/testworkers.h +++ b/test/server/workers/testworkers.h @@ -17,16 +17,17 @@ */ #include "testincludes.h" +#include "socketapi.h" #if defined(__APPLE__) #include "server/vfs/mac/vfs_mac.h" -#elif defined(__WIN32) +#elif defined(_WIN32) #include "server/vfs/win/vfs_win.h" #else #include "libcommonserver/vfs.h" #endif -#include "propagation/executor/executorworker.h" +#include "libsyncengine/propagation/executor/executorworker.h" #include "test_utility/localtemporarydirectory.h" namespace KDC { @@ -53,12 +54,14 @@ class TestWorkers : public CppUnit::TestFixture { Sync _sync; LocalTemporaryDirectory _localTempDir{"TestExecutorWorker"}; + std::unique_ptr _socketApi; + #if defined(__APPLE__) - static std::unique_ptr _vfsPtr; -#elif defined(__WIN32) - static std::unique_ptr _vfsPtr; + static std::shared_ptr _vfsPtr; +#elif defined(_WIN32) + static std::shared_ptr _vfsPtr; #else - static std::unique_ptr _vfsPtr; + static std::shared_ptr _vfsPtr; #endif }; diff --git a/test/test.cpp b/test/test.cpp index 1e642371f..79e940869 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -27,7 +27,6 @@ int runTestSuite(const std::string &logFileName) { /* initialize random seed: */ srand(static_cast(time(NULL))); - // Disable sentry KDC::SentryHandler::init(KDC::AppType::None); // Setup log4cplus diff --git a/test/test_utility/localtemporarydirectory.cpp b/test/test_utility/localtemporarydirectory.cpp index cf73e7b34..14a9b78e2 100644 --- a/test/test_utility/localtemporarydirectory.cpp +++ b/test/test_utility/localtemporarydirectory.cpp @@ -17,8 +17,8 @@ */ #include "localtemporarydirectory.h" -#include "io/filestat.h" -#include "io/iohelper.h" +#include "libcommonserver/io/filestat.h" +#include "libcommonserver/io/iohelper.h" #include diff --git a/test/test_utility/localtemporarydirectory.h b/test/test_utility/localtemporarydirectory.h index 28ffba3be..3966dd32a 100644 --- a/test/test_utility/localtemporarydirectory.h +++ b/test/test_utility/localtemporarydirectory.h @@ -17,7 +17,7 @@ */ #pragma once -#include "utility/types.h" +#include "libcommon/utility/types.h" #include #include diff --git a/test/test_utility/testhelpers.cpp b/test/test_utility/testhelpers.cpp index a166db55f..34c36b26e 100644 --- a/test/test_utility/testhelpers.cpp +++ b/test/test_utility/testhelpers.cpp @@ -18,7 +18,7 @@ #include #include "testhelpers.h" -#include "utility/utility.h" +#include "libcommon/utility/utility.h" namespace KDC::testhelpers { diff --git a/test/test_utility/testhelpers.h b/test/test_utility/testhelpers.h index f1cf87e03..4ea30f93d 100644 --- a/test/test_utility/testhelpers.h +++ b/test/test_utility/testhelpers.h @@ -19,8 +19,8 @@ #pragma once #include "libcommon/utility/utility.h" -#include "utility/types.h" -#include "utility/utility.h" +#include "libcommon/utility/types.h" +#include "libcommonserver/utility/utility.h" #include "version.h" #include diff --git a/test/testincludes.h b/test/testincludes.h index 6a0956fd8..07c959115 100644 --- a/test/testincludes.h +++ b/test/testincludes.h @@ -33,6 +33,4 @@ #define _WINSOCKAPI_ /* Prevent inclusion of winsock.h in windows.h */ #endif -#include "libcommonserver/utility/utility.h" - int runTestSuite(const std::string &logFileName); From 574e8c93b35a4c5deb56ec170f5ef97f7e768133 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Kunz?= Date: Tue, 29 Oct 2024 11:49:47 +0100 Subject: [PATCH 002/178] KDESKTOP-1253 : Ignore items with pattern "X:" in their name on Windows --- .../platforminconsistencycheckerworker.cpp | 8 +- .../computefsoperationworker.cpp | 44 +++- .../computefsoperationworker.h | 2 + .../remotefilesystemobserverworker.cpp | 2 +- .../snapshot/snapshot.cpp | 13 +- .../file_system_observer/snapshot/snapshot.h | 3 +- .../testlocalfilesystemobserverworker.cpp | 27 +- .../file_system_observer/testsnapshot.cpp | 237 +++++++++++++----- .../file_system_observer/testsnapshot.h | 5 + 9 files changed, 246 insertions(+), 95 deletions(-) diff --git a/src/libsyncengine/reconciliation/platform_inconsistency_checker/platforminconsistencycheckerworker.cpp b/src/libsyncengine/reconciliation/platform_inconsistency_checker/platforminconsistencycheckerworker.cpp index bd288c5e4..c782eb953 100644 --- a/src/libsyncengine/reconciliation/platform_inconsistency_checker/platforminconsistencycheckerworker.cpp +++ b/src/libsyncengine/reconciliation/platform_inconsistency_checker/platforminconsistencycheckerworker.cpp @@ -40,11 +40,11 @@ void PlatformInconsistencyCheckerWorker::execute() { checkTree(ReplicaSide::Local); for (const auto &idItem: _idsToBeRemoved) { - if (!_syncPal->updateTree(ReplicaSide::Remote)->deleteNode(idItem.remoteId)) { - LOGW_SYNCPAL_WARN(_logger, L"Error in UpdateTree::deleteNode: node id=" << Utility::s2ws(idItem.remoteId.c_str())); + if (!idItem.remoteId.empty() && !_syncPal->updateTree(ReplicaSide::Remote)->deleteNode(idItem.remoteId)) { + LOGW_SYNCPAL_WARN(_logger, L"Error in UpdateTree::deleteNode: node id=" << Utility::s2ws(idItem.remoteId)); } - if (!_syncPal->updateTree(ReplicaSide::Local)->deleteNode(idItem.localId)) { - LOGW_SYNCPAL_WARN(_logger, L"Error in UpdateTree::deleteNode: node id=" << Utility::s2ws(idItem.localId.c_str())); + if (!idItem.localId.empty() && !_syncPal->updateTree(ReplicaSide::Local)->deleteNode(idItem.localId)) { + LOGW_SYNCPAL_WARN(_logger, L"Error in UpdateTree::deleteNode: node id=" << Utility::s2ws(idItem.localId)); } } diff --git a/src/libsyncengine/update_detection/file_system_observer/computefsoperationworker.cpp b/src/libsyncengine/update_detection/file_system_observer/computefsoperationworker.cpp index 1687fc544..d75a4ec70 100644 --- a/src/libsyncengine/update_detection/file_system_observer/computefsoperationworker.cpp +++ b/src/libsyncengine/update_detection/file_system_observer/computefsoperationworker.cpp @@ -29,15 +29,15 @@ namespace KDC { ComputeFSOperationWorker::ComputeFSOperationWorker(std::shared_ptr syncPal, const std::string &name, const std::string &shortName) : - ISyncWorker(syncPal, name, shortName), - _syncDb(syncPal->_syncDb), _localSnapshot(syncPal->_localSnapshot), _remoteSnapshot(syncPal->_remoteSnapshot) {} + ISyncWorker(syncPal, name, shortName), _syncDb(syncPal->_syncDb), _localSnapshot(syncPal->_localSnapshot), + _remoteSnapshot(syncPal->_remoteSnapshot) {} ComputeFSOperationWorker::ComputeFSOperationWorker(const std::shared_ptr testSyncDb, const std::shared_ptr testLocalSnapshot, const std::shared_ptr testRemoteSnapshot, const std::string &name, const std::string &shortName) : - ISyncWorker(nullptr, name, shortName, true), - _syncDb(testSyncDb), _localSnapshot(testLocalSnapshot), _remoteSnapshot(testRemoteSnapshot) {} + ISyncWorker(nullptr, name, shortName, true), _syncDb(testSyncDb), _localSnapshot(testLocalSnapshot), + _remoteSnapshot(testRemoteSnapshot) {} void ComputeFSOperationWorker::execute() { ExitCode exitCode(ExitCode::Unknown); @@ -240,7 +240,11 @@ ExitCode ComputeFSOperationWorker::inferChangeFromDbNode(const ReplicaSide side, } SyncPath snapshotPath; - if (!snapshot->path(nodeId, snapshotPath)) { + if (bool ignore = false; !snapshot->path(nodeId, snapshotPath, ignore)) { + if (ignore) { + notifyIgnoredItem(nodeId, snapshotPath, dbNode.type()); + return ExitCode::Ok; + } LOGW_SYNCPAL_WARN(_logger, L"Failed to retrieve path from snapshot for item " << SyncName2WStr(dbName).c_str() << L" (" << Utility::s2ws(nodeId).c_str() << L")"); setExitCause(ExitCause::InvalidSnapshot); @@ -467,8 +471,13 @@ ExitCode ComputeFSOperationWorker::exploreSnapshotTree(ReplicaSide side, const N } SyncPath snapshotPath; - if (!snapshot->path(nodeId, snapshotPath)) { - LOGW_SYNCPAL_WARN(_logger, L"Failed to retrieve path from snapshot for item " << Utility::s2ws(nodeId).c_str()); + if (bool ignore = false; !snapshot->path(nodeId, snapshotPath, ignore)) { + if (ignore) { + notifyIgnoredItem(nodeId, snapshotPath, type); + continue; + } + + LOG_SYNCPAL_WARN(_logger, "Failed to retrieve path from snapshot for item " << nodeId.c_str()); setExitCause(ExitCause::InvalidSnapshot); return ExitCode::DataError; } @@ -586,7 +595,13 @@ ExitCode ComputeFSOperationWorker::checkFileIntegrity(const DbNode &dbNode) { if (localSnapshotSize != remoteSnapshotSize && localSnapshotLastModified == dbNode.lastModifiedLocal().value() && localSnapshotLastModified == remoteSnapshotLastModified) { SyncPath localSnapshotPath; - if (!_syncPal->snapshot(ReplicaSide::Local, true)->path(dbNode.nodeIdLocal().value(), localSnapshotPath)) { + if (bool ignore = false; + !_syncPal->snapshot(ReplicaSide::Local, true)->path(dbNode.nodeIdLocal().value(), localSnapshotPath, ignore)) { + if (ignore) { + notifyIgnoredItem(dbNode.nodeIdLocal().value(), localSnapshotPath, dbNode.type()); + return ExitCode::Ok; + } + LOGW_SYNCPAL_WARN(_logger, L"Failed to retrieve path from snapshot for item " << SyncName2WStr(dbNode.nameLocal()).c_str() << L" (" << Utility::s2ws(dbNode.nodeIdLocal().value()).c_str() << L")"); @@ -748,7 +763,12 @@ bool ComputeFSOperationWorker::isTooBig(const std::shared_ptr re // On first sync after migration from version under 3.4.0, the DB is empty but a big folder might as been whitelisted // Therefor check also with path SyncPath relativePath; - if (remoteSnapshot->path(remoteNodeId, relativePath)) { + if (bool ignore = false; remoteSnapshot->path(remoteNodeId, relativePath, ignore)) { + if (ignore) { + notifyIgnoredItem(remoteNodeId, relativePath, remoteSnapshot->type(remoteNodeId)); + return false; + } + localNodeId = _syncPal->snapshotCopy(ReplicaSide::Local)->itemId(relativePath); if (!localNodeId.empty()) { // We already synchronize the item locally, keep it @@ -929,4 +949,10 @@ bool ComputeFSOperationWorker::pathInDeletedFolder(const SyncPath &path) { return false; } +void ComputeFSOperationWorker::notifyIgnoredItem(const NodeId &nodeId, const SyncPath &path, NodeType nodeType) { + LOGW_SYNCPAL_INFO(_logger, L"Item (or one of its descendant) has been ignored: " << Utility::formatSyncPath(path)); + Error err(_syncPal->syncDbId(), "", nodeId, nodeType, path, ConflictType::None, InconsistencyType::ReservedName); + _syncPal->addError(err); +} + } // namespace KDC diff --git a/src/libsyncengine/update_detection/file_system_observer/computefsoperationworker.h b/src/libsyncengine/update_detection/file_system_observer/computefsoperationworker.h index 7f5e4b55b..4aaaf12e3 100644 --- a/src/libsyncengine/update_detection/file_system_observer/computefsoperationworker.h +++ b/src/libsyncengine/update_detection/file_system_observer/computefsoperationworker.h @@ -77,6 +77,8 @@ class ComputeFSOperationWorker : public ISyncWorker { void logOperationGeneration(const ReplicaSide side, const FSOpPtr fsOp); + void notifyIgnoredItem(const NodeId &nodeId, const SyncPath &path, NodeType nodeType); + const std::shared_ptr _syncDb; const std::shared_ptr _localSnapshot; const std::shared_ptr _remoteSnapshot; diff --git a/src/libsyncengine/update_detection/file_system_observer/remotefilesystemobserverworker.cpp b/src/libsyncengine/update_detection/file_system_observer/remotefilesystemobserverworker.cpp index 90263deca..35377104e 100644 --- a/src/libsyncengine/update_detection/file_system_observer/remotefilesystemobserverworker.cpp +++ b/src/libsyncengine/update_detection/file_system_observer/remotefilesystemobserverworker.cpp @@ -354,7 +354,7 @@ ExitCode RemoteFileSystemObserverWorker::getItemsInDir(const NodeId &dirId, cons << SyncName2WStr(_snapshot->name(item.parentId())).c_str() << L"\""); SyncPath path; - _snapshot->path(item.parentId(), path); + _snapshot->path(item.parentId(), path, ignore); path /= item.name(); Error err(_syncPal->syncDbId(), "", item.id(), NodeType::Directory, path, ConflictType::None, InconsistencyType::None, diff --git a/src/libsyncengine/update_detection/file_system_observer/snapshot/snapshot.cpp b/src/libsyncengine/update_detection/file_system_observer/snapshot/snapshot.cpp index 23509e9e2..8f150ffba 100644 --- a/src/libsyncengine/update_detection/file_system_observer/snapshot/snapshot.cpp +++ b/src/libsyncengine/update_detection/file_system_observer/snapshot/snapshot.cpp @@ -206,8 +206,9 @@ bool Snapshot::setParentId(const NodeId &itemId, const NodeId &newParentId) { return false; } -bool Snapshot::path(const NodeId &itemId, SyncPath &path) const noexcept { +bool Snapshot::path(const NodeId &itemId, SyncPath &path, bool &ignore) const noexcept { path.clear(); + ignore = false; if (itemId.empty()) { LOG_WARN(Log::instance()->getLogger(), "Error in Snapshot::path: empty item ID argument."); @@ -235,12 +236,16 @@ bool Snapshot::path(const NodeId &itemId, SyncPath &path) const noexcept { } // Construct path - SyncPath tmp; + SyncPath tmpParentPath; while (!names.empty()) { - tmp /= names.back(); + path /= names.back(); names.pop_back(); + if (path.parent_path() != tmpParentPath) { + ignore = true; + return false; + } + tmpParentPath = path; } - path = tmp; return ok; } diff --git a/src/libsyncengine/update_detection/file_system_observer/snapshot/snapshot.h b/src/libsyncengine/update_detection/file_system_observer/snapshot/snapshot.h index a0a770a2e..9624cc307 100644 --- a/src/libsyncengine/update_detection/file_system_observer/snapshot/snapshot.h +++ b/src/libsyncengine/update_detection/file_system_observer/snapshot/snapshot.h @@ -45,7 +45,7 @@ class Snapshot : public SharedObject { NodeId itemId(const SyncPath &path) const; NodeId parentId(const NodeId &itemId) const; bool setParentId(const NodeId &itemId, const NodeId &newParentId); - bool path(const NodeId &itemId, SyncPath &path) const noexcept; + bool path(const NodeId &itemId, SyncPath &path, bool &ignore) const noexcept; SyncName name(const NodeId &itemId) const; bool setName(const NodeId &itemId, const SyncName &newName); SyncTime createdAt(const NodeId &itemId) const; @@ -84,6 +84,7 @@ class Snapshot : public SharedObject { void setValid(bool newIsValid); bool checkIntegrityRecursively(); + private: void removeChildrenRecursively(const NodeId &parentId); bool checkIntegrityRecursively(const NodeId &parentId); diff --git a/test/libsyncengine/update_detection/file_system_observer/testlocalfilesystemobserverworker.cpp b/test/libsyncengine/update_detection/file_system_observer/testlocalfilesystemobserverworker.cpp index 846d0fed9..89330895a 100644 --- a/test/libsyncengine/update_detection/file_system_observer/testlocalfilesystemobserverworker.cpp +++ b/test/libsyncengine/update_detection/file_system_observer/testlocalfilesystemobserverworker.cpp @@ -123,8 +123,9 @@ void TestLocalFileSystemObserverWorker::testLFSOWithInitialSnapshot() { const NodeId parentId = _syncPal->snapshot(ReplicaSide::Local)->parentId(id); SyncPath parentPath; - if (!parentId.empty() && _syncPal->snapshot(ReplicaSide::Local)->path(parentId, parentPath) && - parentPath.filename() == _subDirPath.filename()) { + if (bool ignore = false; !parentId.empty() && + _syncPal->snapshot(ReplicaSide::Local)->path(parentId, parentPath, ignore) && + parentPath.filename() == _subDirPath.filename()) { fileCounter++; } } @@ -149,7 +150,8 @@ void TestLocalFileSystemObserverWorker::testLFSOWithFiles() { CPPUNIT_ASSERT(_syncPal->snapshot(ReplicaSide::Local)->exists(itemId)); SyncPath testSyncPath; - CPPUNIT_ASSERT(_syncPal->snapshot(ReplicaSide::Local)->path(itemId, testSyncPath) && testSyncPath == filename); + bool ignore = false; + CPPUNIT_ASSERT(_syncPal->snapshot(ReplicaSide::Local)->path(itemId, testSyncPath, ignore) && testSyncPath == filename); } { @@ -233,17 +235,18 @@ void TestLocalFileSystemObserverWorker::testLFSOWithDuplicateFileNames() { CPPUNIT_ASSERT(_syncPal->snapshot(ReplicaSide::Local)->exists(nfcNamedItemId)); CPPUNIT_ASSERT(_syncPal->snapshot(ReplicaSide::Local)->exists(nfdNamedItemId)); SyncPath testSyncPath; + bool ignore = false; #ifdef __APPLE__ - const bool foundNfcItem = - _syncPal->snapshot(ReplicaSide::Local)->path(nfcNamedItemId, testSyncPath) && testSyncPath == makeNfcSyncName(); - const bool foundNfdItem = - _syncPal->snapshot(ReplicaSide::Local)->path(nfdNamedItemId, testSyncPath) && testSyncPath == makeNfdSyncName(); + const bool foundNfcItem = _syncPal->snapshot(ReplicaSide::Local)->path(nfcNamedItemId, testSyncPath, ignore) && + testSyncPath == makeNfcSyncName(); + const bool foundNfdItem = _syncPal->snapshot(ReplicaSide::Local)->path(nfdNamedItemId, testSyncPath, ignore) && + testSyncPath == makeNfdSyncName(); CPPUNIT_ASSERT(foundNfcItem || foundNfdItem); #else - CPPUNIT_ASSERT(_syncPal->snapshot(ReplicaSide::Local)->path(nfcNamedItemId, testSyncPath) && + CPPUNIT_ASSERT(_syncPal->snapshot(ReplicaSide::Local)->path(nfcNamedItemId, testSyncPath, ignore) && testSyncPath == makeNfcSyncName()); - CPPUNIT_ASSERT(_syncPal->snapshot(ReplicaSide::Local)->path(nfdNamedItemId, testSyncPath) && + CPPUNIT_ASSERT(_syncPal->snapshot(ReplicaSide::Local)->path(nfdNamedItemId, testSyncPath, ignore) && testSyncPath == makeNfdSyncName()); #endif } @@ -267,7 +270,8 @@ void TestLocalFileSystemObserverWorker::testLFSOWithDirs() { itemId = std::to_string(fileStat.inode); CPPUNIT_ASSERT(_syncPal->snapshot(ReplicaSide::Local)->exists(itemId)); SyncPath path; - _syncPal->snapshot(ReplicaSide::Local)->path(itemId, path); + bool ignore = false; + _syncPal->snapshot(ReplicaSide::Local)->path(itemId, path, ignore); CPPUNIT_ASSERT(path == CommonUtility::relativePath(_rootFolderPath, testAbsolutePath)); } @@ -282,7 +286,8 @@ void TestLocalFileSystemObserverWorker::testLFSOWithDirs() { Utility::msleep(1000); // Wait 1sec SyncPath path; - _syncPal->snapshot(ReplicaSide::Local)->path(itemId, path); + bool ignore = false; + _syncPal->snapshot(ReplicaSide::Local)->path(itemId, path, ignore); CPPUNIT_ASSERT(path == CommonUtility::relativePath(_rootFolderPath, destinationPath)); testAbsolutePath = destinationPath; } diff --git a/test/libsyncengine/update_detection/file_system_observer/testsnapshot.cpp b/test/libsyncengine/update_detection/file_system_observer/testsnapshot.cpp index 78f3c2450..818e813cb 100644 --- a/test/libsyncengine/update_detection/file_system_observer/testsnapshot.cpp +++ b/test/libsyncengine/update_detection/file_system_observer/testsnapshot.cpp @@ -26,12 +26,6 @@ using namespace CppUnit; namespace KDC { -void TestSnapshot::setUp() { - ParametersCache::instance(true); -} - -void TestSnapshot::tearDown() {} - /** * Tree: * @@ -45,101 +39,214 @@ void TestSnapshot::tearDown() {} * AAA */ -void TestSnapshot::testSnapshot() { - const NodeId rootNodeId = SyncDb::driveRootNode().nodeIdLocal().value(); +void TestSnapshot::setUp() { + ParametersCache::instance(true); + _rootNodeId = SyncDb::driveRootNode().nodeIdLocal().value(); const DbNode dummyRootNode(0, std::nullopt, SyncName(), SyncName(), "1", "1", std::nullopt, std::nullopt, std::nullopt, NodeType::Directory, 0, std::nullopt); - Snapshot snapshot(ReplicaSide::Local, dummyRootNode); + _snapshot = std::make_unique(ReplicaSide::Local, dummyRootNode); // Insert node A - const SnapshotItem itemA("a", rootNodeId, Str("A"), 1640995201, -1640995201, NodeType::Directory, 123, false, true, true); - snapshot.updateItem(itemA); - CPPUNIT_ASSERT(snapshot.exists("a")); - CPPUNIT_ASSERT_EQUAL(std::string("A"), SyncName2Str(snapshot.name("a"))); - CPPUNIT_ASSERT_EQUAL(NodeType::Directory, snapshot.type("a")); + const SnapshotItem itemA("a", _rootNodeId, Str("A"), testhelpers::defaultTime, testhelpers::defaultTime, NodeType::Directory, + testhelpers::defaultFileSize, false, true, true); + _snapshot->updateItem(itemA); + + // Insert node B + const SnapshotItem itemB("b", _rootNodeId, Str("B"), testhelpers::defaultTime, testhelpers::defaultTime, NodeType::Directory, + testhelpers::defaultFileSize, false, true, true); + _snapshot->updateItem(itemB); + + // Insert child nodes + const SnapshotItem itemAA("aa", "a", Str("AA"), testhelpers::defaultTime, testhelpers::defaultTime, NodeType::Directory, + testhelpers::defaultFileSize, false, true, true); + _snapshot->updateItem(itemAA); + + const SnapshotItem itemAAA("aaa", "aa", Str("AAA"), testhelpers::defaultTime, testhelpers::defaultTime, NodeType::File, + testhelpers::defaultFileSize, false, true, true); + _snapshot->updateItem(itemAAA); +} + +void TestSnapshot::tearDown() {} + +void TestSnapshot::testSnapshot() { + CPPUNIT_ASSERT(_snapshot->exists("a")); + CPPUNIT_ASSERT_EQUAL(std::string("A"), SyncName2Str(_snapshot->name("a"))); + CPPUNIT_ASSERT_EQUAL(NodeType::Directory, _snapshot->type("a")); std::unordered_set childrenIds; - snapshot.getChildrenIds(rootNodeId, childrenIds); + _snapshot->getChildrenIds(_rootNodeId, childrenIds); CPPUNIT_ASSERT(childrenIds.contains("a")); - // Update node A - snapshot.updateItem( - SnapshotItem("a", rootNodeId, Str("A*"), 1640995202, 1640995202, NodeType::Directory, 123, false, true, true)); - CPPUNIT_ASSERT_EQUAL(std::string("A*"), SyncName2Str(snapshot.name("a"))); - - // Insert node B - const SnapshotItem itemB("b", rootNodeId, Str("B"), 1640995203, 1640995203, NodeType::Directory, 123, false, true, true); - snapshot.updateItem(itemB); - CPPUNIT_ASSERT(snapshot.exists("b")); - snapshot.getChildrenIds(rootNodeId, childrenIds); + CPPUNIT_ASSERT(_snapshot->exists("b")); + _snapshot->getChildrenIds(_rootNodeId, childrenIds); CPPUNIT_ASSERT(childrenIds.contains("b")); - // Insert child nodes - const SnapshotItem itemAA("aa", "a", Str("AA"), 1640995204, 1640995204, NodeType::Directory, 123, false, true, true); - snapshot.updateItem(itemAA); - CPPUNIT_ASSERT(snapshot.exists("aa")); - snapshot.getChildrenIds("a", childrenIds); + CPPUNIT_ASSERT(_snapshot->exists("aa")); + _snapshot->getChildrenIds("a", childrenIds); CPPUNIT_ASSERT(childrenIds.contains("aa")); - const SnapshotItem itemAAA("aaa", "aa", Str("AAA"), 1640995205, 1640995205, NodeType::File, 123, false, true, true); - snapshot.updateItem(itemAAA); - CPPUNIT_ASSERT(snapshot.exists("aaa")); - snapshot.getChildrenIds("aa", childrenIds); + CPPUNIT_ASSERT(_snapshot->exists("aaa")); + _snapshot->getChildrenIds("aa", childrenIds); CPPUNIT_ASSERT(childrenIds.contains("aaa")); + // Update node A + _snapshot->updateItem(SnapshotItem("a", _rootNodeId, Str("A*"), testhelpers::defaultTime, testhelpers::defaultTime + 1, + NodeType::Directory, testhelpers::defaultFileSize, false, true, true)); + CPPUNIT_ASSERT_EQUAL(std::string("A*"), SyncName2Str(_snapshot->name("a"))); SyncPath path; - snapshot.path("aaa", path); + bool ignore = false; + _snapshot->path("aaa", path, ignore); CPPUNIT_ASSERT_EQUAL(SyncPath("A*/AA/AAA"), path); - CPPUNIT_ASSERT_EQUAL(std::string("AAA"), SyncName2Str(snapshot.name("aaa"))); - CPPUNIT_ASSERT_EQUAL(static_cast(1640995205), snapshot.lastModified("aaa")); - CPPUNIT_ASSERT_EQUAL(NodeType::File, snapshot.type("aaa")); - CPPUNIT_ASSERT(snapshot.contentChecksum("aaa").empty()); // Checksum never computed for now - CPPUNIT_ASSERT_EQUAL(NodeId("aaa"), snapshot.itemId(std::filesystem::path("A*/AA/AAA"))); + CPPUNIT_ASSERT_EQUAL(std::string("AAA"), SyncName2Str(_snapshot->name("aaa"))); + CPPUNIT_ASSERT_EQUAL(static_cast(testhelpers::defaultTime), _snapshot->lastModified("aaa")); + CPPUNIT_ASSERT_EQUAL(NodeType::File, _snapshot->type("aaa")); + CPPUNIT_ASSERT(_snapshot->contentChecksum("aaa").empty()); // Checksum never computed for now + CPPUNIT_ASSERT_EQUAL(NodeId("aaa"), _snapshot->itemId(std::filesystem::path("A*/AA/AAA"))); // Move node AA under B - snapshot.updateItem(SnapshotItem("aa", "b", Str("AA"), 1640995204, -1640995204, NodeType::Directory, 123, false, true, true)); - CPPUNIT_ASSERT(snapshot.parentId("aa") == "b"); - snapshot.getChildrenIds("b", childrenIds); + _snapshot->updateItem(SnapshotItem("aa", "b", Str("AA"), testhelpers::defaultTime, testhelpers::defaultTime, + NodeType::Directory, testhelpers::defaultFileSize, false, true, true)); + CPPUNIT_ASSERT(_snapshot->parentId("aa") == "b"); + _snapshot->getChildrenIds("b", childrenIds); CPPUNIT_ASSERT(childrenIds.contains("aa")); - snapshot.getChildrenIds("a", childrenIds); + _snapshot->getChildrenIds("a", childrenIds); CPPUNIT_ASSERT(childrenIds.empty()); // Remove node B - snapshot.removeItem("b"); - snapshot.getChildrenIds(rootNodeId, childrenIds); - CPPUNIT_ASSERT(!snapshot.exists("aaa")); - CPPUNIT_ASSERT(!snapshot.exists("aa")); - CPPUNIT_ASSERT(!snapshot.exists("b")); + _snapshot->removeItem("b"); + _snapshot->getChildrenIds(_rootNodeId, childrenIds); + CPPUNIT_ASSERT(!_snapshot->exists("aaa")); + CPPUNIT_ASSERT(!_snapshot->exists("aa")); + CPPUNIT_ASSERT(!_snapshot->exists("b")); CPPUNIT_ASSERT(!childrenIds.contains("b")); // Reset snapshot - snapshot.init(); - CPPUNIT_ASSERT_EQUAL(static_cast(1), snapshot.nbItems()); + _snapshot->init(); + CPPUNIT_ASSERT_EQUAL(static_cast(1), _snapshot->nbItems()); } void TestSnapshot::testSnapshotInsertionWithDifferentEncodings() { - const NodeId rootNodeId = *SyncDb::driveRootNode().nodeIdLocal(); - - const DbNode dummyRootNode(0, std::nullopt, Str("Local Drive"), SyncName(), "1", "1", std::nullopt, std::nullopt, - std::nullopt, NodeType::Directory, 0, std::nullopt); - Snapshot snapshot(ReplicaSide::Local, dummyRootNode); - - const SnapshotItem nfcItem("A", rootNodeId, testhelpers::makeNfcSyncName(), 1640995201, -1640995201, NodeType::Directory, 123, - false, true, true); - const SnapshotItem nfdItem("B", rootNodeId, testhelpers::makeNfdSyncName(), 1640995201, -1640995201, NodeType::Directory, 123, - false, true, true); + const SnapshotItem nfcItem("A", _rootNodeId, testhelpers::makeNfcSyncName(), testhelpers::defaultTime, + -testhelpers::defaultTime, NodeType::Directory, testhelpers::defaultFileSize, false, true, true); + const SnapshotItem nfdItem("B", _rootNodeId, testhelpers::makeNfdSyncName(), testhelpers::defaultTime, + -testhelpers::defaultTime, NodeType::Directory, testhelpers::defaultFileSize, false, true, true); { - snapshot.updateItem(nfcItem); + _snapshot->updateItem(nfcItem); SyncPath syncPath; - snapshot.path("A", syncPath); + bool ignore = false; + _snapshot->path("A", syncPath, ignore); CPPUNIT_ASSERT_EQUAL(SyncPath(testhelpers::makeNfcSyncName()), syncPath); } { - snapshot.updateItem(nfdItem); + _snapshot->updateItem(nfdItem); SyncPath syncPath; - snapshot.path("B", syncPath); + bool ignore = false; + _snapshot->path("B", syncPath, ignore); CPPUNIT_ASSERT_EQUAL(SyncPath(testhelpers::makeNfdSyncName()), syncPath); } } +void TestSnapshot::testPath() { + { + const auto id = CommonUtility::generateRandomStringAlphaNum(); + const auto name = Str("test"); + const SnapshotItem item(id, "a", name, testhelpers::defaultTime, testhelpers::defaultTime, NodeType::Directory, + testhelpers::defaultFileSize, false, true, true); + _snapshot->updateItem(item); + SyncPath path; + bool ignore = false; + CPPUNIT_ASSERT(_snapshot->path(id, path, ignore)); + CPPUNIT_ASSERT_EQUAL(SyncPath("A") / name, path); + CPPUNIT_ASSERT(!ignore); + } + + { + const auto id = CommonUtility::generateRandomStringAlphaNum(); + const auto name = Str("E:S"); + const SnapshotItem item(id, "a", name, testhelpers::defaultTime, testhelpers::defaultTime, NodeType::Directory, + testhelpers::defaultFileSize, false, true, true); + _snapshot->updateItem(item); + SyncPath path; + bool ignore = false; + // On Windows, if the file name starts with "X:" pattern, the previous element of the path are overrode + // (https://en.cppreference.com/w/cpp/filesystem/path/append) +#ifdef _WIN32 + CPPUNIT_ASSERT(!_snapshot->path(id, path, ignore)); + CPPUNIT_ASSERT(ignore); +#else + CPPUNIT_ASSERT(_snapshot->path(id, path, ignore)); + CPPUNIT_ASSERT_EQUAL(SyncPath("A") / name, path); + CPPUNIT_ASSERT(!ignore); +#endif + + const auto childId = CommonUtility::generateRandomStringAlphaNum(); + const auto childName = Str("test"); + const SnapshotItem childItem(childId, id, childName, testhelpers::defaultTime, testhelpers::defaultTime, + NodeType::Directory, testhelpers::defaultFileSize, false, true, true); + _snapshot->updateItem(childItem); +#ifdef _WIN32 + CPPUNIT_ASSERT(!_snapshot->path(childId, path, ignore)); + CPPUNIT_ASSERT(ignore); +#else + CPPUNIT_ASSERT(_snapshot->path(childId, path, ignore)); + CPPUNIT_ASSERT_EQUAL(SyncPath("A") / name / childName, path); + CPPUNIT_ASSERT(!ignore); +#endif + } + + { + const auto id = CommonUtility::generateRandomStringAlphaNum(); + const auto name = Str("a:b"); + const SnapshotItem item(id, "a", name, testhelpers::defaultTime, testhelpers::defaultTime, NodeType::Directory, + testhelpers::defaultFileSize, false, true, true); + _snapshot->updateItem(item); + SyncPath path; + bool ignore = false; + // On Windows, if the file name starts with "X:" pattern, the previous element of the path are overrode + // (https://en.cppreference.com/w/cpp/filesystem/path/append) +#ifdef _WIN32 + CPPUNIT_ASSERT(!_snapshot->path(id, path, ignore)); + CPPUNIT_ASSERT(ignore); +#else + CPPUNIT_ASSERT(_snapshot->path(id, path, ignore)); + CPPUNIT_ASSERT_EQUAL(SyncPath("A") / name, path); + CPPUNIT_ASSERT(!ignore); +#endif + } + + { + const auto id = CommonUtility::generateRandomStringAlphaNum(); + const auto name = Str("C:"); + const SnapshotItem item(id, "a", name, testhelpers::defaultTime, testhelpers::defaultTime, NodeType::Directory, + testhelpers::defaultFileSize, false, true, true); + _snapshot->updateItem(item); + + SyncPath path; + bool ignore = false; + // On Windows, if the file name starts with "X:" pattern, the previous element of the path are overrode + // (https://en.cppreference.com/w/cpp/filesystem/path/append) +#ifdef _WIN32 + CPPUNIT_ASSERT(!_snapshot->path(id, path, ignore)); + CPPUNIT_ASSERT(ignore); +#else + CPPUNIT_ASSERT(_snapshot->path(id, path, ignore)); + CPPUNIT_ASSERT_EQUAL(SyncPath("A") / name, path); + CPPUNIT_ASSERT(!ignore); +#endif + } + + { + const auto id = CommonUtility::generateRandomStringAlphaNum(); + const auto name = Str("aa:b"); + const SnapshotItem item(id, "a", name, testhelpers::defaultTime, testhelpers::defaultTime, NodeType::Directory, + testhelpers::defaultFileSize, false, true, true); + _snapshot->updateItem(item); + SyncPath path; + bool ignore = false; + CPPUNIT_ASSERT(_snapshot->path(id, path, ignore)); + CPPUNIT_ASSERT_EQUAL(SyncPath("A") / name, path); + CPPUNIT_ASSERT(!ignore); + } +} + } // namespace KDC diff --git a/test/libsyncengine/update_detection/file_system_observer/testsnapshot.h b/test/libsyncengine/update_detection/file_system_observer/testsnapshot.h index c0365b400..200a149d8 100644 --- a/test/libsyncengine/update_detection/file_system_observer/testsnapshot.h +++ b/test/libsyncengine/update_detection/file_system_observer/testsnapshot.h @@ -29,6 +29,7 @@ class TestSnapshot : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(TestSnapshot); CPPUNIT_TEST(testSnapshot); CPPUNIT_TEST(testSnapshotInsertionWithDifferentEncodings); + CPPUNIT_TEST(testPath); CPPUNIT_TEST_SUITE_END(); public: @@ -38,6 +39,10 @@ class TestSnapshot : public CppUnit::TestFixture { private: void testSnapshot(); void testSnapshotInsertionWithDifferentEncodings(); + void testPath(); + + std::unique_ptr _snapshot; + NodeId _rootNodeId; }; } // namespace KDC From 6c66776ee849ef7120694f5f3064e21c10907145 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Kunz?= Date: Wed, 30 Oct 2024 11:21:11 +0100 Subject: [PATCH 003/178] Address PR comments --- .../computefsoperationworker.cpp | 32 ++++++++----------- .../computefsoperationworker.h | 10 ++---- .../file_system_observer/testsnapshot.cpp | 9 +++--- 3 files changed, 21 insertions(+), 30 deletions(-) diff --git a/src/libsyncengine/update_detection/file_system_observer/computefsoperationworker.cpp b/src/libsyncengine/update_detection/file_system_observer/computefsoperationworker.cpp index d75a4ec70..a1494a040 100644 --- a/src/libsyncengine/update_detection/file_system_observer/computefsoperationworker.cpp +++ b/src/libsyncengine/update_detection/file_system_observer/computefsoperationworker.cpp @@ -29,15 +29,11 @@ namespace KDC { ComputeFSOperationWorker::ComputeFSOperationWorker(std::shared_ptr syncPal, const std::string &name, const std::string &shortName) : - ISyncWorker(syncPal, name, shortName), _syncDb(syncPal->_syncDb), _localSnapshot(syncPal->_localSnapshot), - _remoteSnapshot(syncPal->_remoteSnapshot) {} + ISyncWorker(syncPal, name, shortName), _syncDb(syncPal->syncDb()) {} -ComputeFSOperationWorker::ComputeFSOperationWorker(const std::shared_ptr testSyncDb, - const std::shared_ptr testLocalSnapshot, - const std::shared_ptr testRemoteSnapshot, const std::string &name, +ComputeFSOperationWorker::ComputeFSOperationWorker(const std::shared_ptr testSyncDb, const std::string &name, const std::string &shortName) : - ISyncWorker(nullptr, name, shortName, true), _syncDb(testSyncDb), _localSnapshot(testLocalSnapshot), - _remoteSnapshot(testRemoteSnapshot) {} + ISyncWorker(nullptr, name, shortName, true), _syncDb(testSyncDb) {} void ComputeFSOperationWorker::execute() { ExitCode exitCode(ExitCode::Unknown); @@ -573,30 +569,30 @@ ExitCode ComputeFSOperationWorker::checkFileIntegrity(const DbNode &dbNode) { return ExitCode::Ok; } - if (!_syncPal->snapshot(ReplicaSide::Local, true)->exists(dbNode.nodeIdLocal().value()) || - !_syncPal->snapshot(ReplicaSide::Remote, true)->exists(dbNode.nodeIdRemote().value())) { + if (!_syncPal->snapshotCopy(ReplicaSide::Local)->exists(dbNode.nodeIdLocal().value()) || + !_syncPal->snapshotCopy(ReplicaSide::Remote)->exists(dbNode.nodeIdRemote().value())) { // Ignore if item does not exist return ExitCode::Ok; } - if (const bool localSnapshotIsLink = _syncPal->snapshot(ReplicaSide::Local, true)->isLink(dbNode.nodeIdLocal().value()); + if (const bool localSnapshotIsLink = _syncPal->snapshotCopy(ReplicaSide::Local)->isLink(dbNode.nodeIdLocal().value()); localSnapshotIsLink) { // Local and remote links sizes are not always the same (macOS aliases, Windows junctions) return ExitCode::Ok; } - int64_t localSnapshotSize = _syncPal->snapshot(ReplicaSide::Local, true)->size(dbNode.nodeIdLocal().value()); - int64_t remoteSnapshotSize = _syncPal->snapshot(ReplicaSide::Remote, true)->size(dbNode.nodeIdRemote().value()); - SyncTime localSnapshotLastModified = _syncPal->snapshot(ReplicaSide::Local, true)->lastModified(dbNode.nodeIdLocal().value()); + int64_t localSnapshotSize = _syncPal->snapshotCopy(ReplicaSide::Local)->size(dbNode.nodeIdLocal().value()); + int64_t remoteSnapshotSize = _syncPal->snapshotCopy(ReplicaSide::Remote)->size(dbNode.nodeIdRemote().value()); + SyncTime localSnapshotLastModified = _syncPal->snapshotCopy(ReplicaSide::Local)->lastModified(dbNode.nodeIdLocal().value()); SyncTime remoteSnapshotLastModified = - _syncPal->snapshot(ReplicaSide::Remote, true)->lastModified(dbNode.nodeIdRemote().value()); + _syncPal->snapshotCopy(ReplicaSide::Remote)->lastModified(dbNode.nodeIdRemote().value()); // A mismatch is detected if all timestamps are equal but the sizes in snapshots differ. if (localSnapshotSize != remoteSnapshotSize && localSnapshotLastModified == dbNode.lastModifiedLocal().value() && localSnapshotLastModified == remoteSnapshotLastModified) { SyncPath localSnapshotPath; if (bool ignore = false; - !_syncPal->snapshot(ReplicaSide::Local, true)->path(dbNode.nodeIdLocal().value(), localSnapshotPath, ignore)) { + !_syncPal->snapshotCopy(ReplicaSide::Local)->path(dbNode.nodeIdLocal().value(), localSnapshotPath, ignore)) { if (ignore) { notifyIgnoredItem(dbNode.nodeIdLocal().value(), localSnapshotPath, dbNode.type()); return ExitCode::Ok; @@ -949,9 +945,9 @@ bool ComputeFSOperationWorker::pathInDeletedFolder(const SyncPath &path) { return false; } -void ComputeFSOperationWorker::notifyIgnoredItem(const NodeId &nodeId, const SyncPath &path, NodeType nodeType) { - LOGW_SYNCPAL_INFO(_logger, L"Item (or one of its descendant) has been ignored: " << Utility::formatSyncPath(path)); - Error err(_syncPal->syncDbId(), "", nodeId, nodeType, path, ConflictType::None, InconsistencyType::ReservedName); +void ComputeFSOperationWorker::notifyIgnoredItem(const NodeId &nodeId, const SyncPath &path, const NodeType nodeType) { + LOGW_SYNCPAL_INFO(_logger, L"Item (or one of its descendants) has been ignored: " << Utility::formatSyncPath(path)); + const Error err(_syncPal->syncDbId(), "", nodeId, nodeType, path, ConflictType::None, InconsistencyType::ReservedName); _syncPal->addError(err); } diff --git a/src/libsyncengine/update_detection/file_system_observer/computefsoperationworker.h b/src/libsyncengine/update_detection/file_system_observer/computefsoperationworker.h index 4aaaf12e3..c1b11985b 100644 --- a/src/libsyncengine/update_detection/file_system_observer/computefsoperationworker.h +++ b/src/libsyncengine/update_detection/file_system_observer/computefsoperationworker.h @@ -30,19 +30,15 @@ class ComputeFSOperationWorker : public ISyncWorker { /** * Constructor used for testing only * @param testSyncDb - * @param testLocalSnapshot - * @param testRemoteSnapshot * @param name * @param shortName */ - ComputeFSOperationWorker(const std::shared_ptr testSyncDb, const std::shared_ptr testLocalSnapshot, - const std::shared_ptr testRemoteSnapshot, const std::string &name, - const std::string &shortName); + ComputeFSOperationWorker(const std::shared_ptr testSyncDb, const std::string &name, const std::string &shortName); const std::unordered_map getFileSizeMismatchMap() const { return _fileSizeMismatchMap; } protected: - virtual void execute() override; + void execute() override; private: using NodeIdSet = std::unordered_set; @@ -80,8 +76,6 @@ class ComputeFSOperationWorker : public ISyncWorker { void notifyIgnoredItem(const NodeId &nodeId, const SyncPath &path, NodeType nodeType); const std::shared_ptr _syncDb; - const std::shared_ptr _localSnapshot; - const std::shared_ptr _remoteSnapshot; Sync _sync; NodeIdSet _remoteUnsyncedList; diff --git a/test/libsyncengine/update_detection/file_system_observer/testsnapshot.cpp b/test/libsyncengine/update_detection/file_system_observer/testsnapshot.cpp index 818e813cb..d45fb0dfb 100644 --- a/test/libsyncengine/update_detection/file_system_observer/testsnapshot.cpp +++ b/test/libsyncengine/update_detection/file_system_observer/testsnapshot.cpp @@ -147,6 +147,7 @@ void TestSnapshot::testSnapshotInsertionWithDifferentEncodings() { } void TestSnapshot::testPath() { + // Normal case { const auto id = CommonUtility::generateRandomStringAlphaNum(); const auto name = Str("test"); @@ -159,7 +160,7 @@ void TestSnapshot::testPath() { CPPUNIT_ASSERT_EQUAL(SyncPath("A") / name, path); CPPUNIT_ASSERT(!ignore); } - + // Item name starting by pattern "X:", should be ignored (as well as its descendants) on Windows only { const auto id = CommonUtility::generateRandomStringAlphaNum(); const auto name = Str("E:S"); @@ -193,7 +194,7 @@ void TestSnapshot::testPath() { CPPUNIT_ASSERT(!ignore); #endif } - + // Item name starting by pattern "X:", should be ignored on Windows only { const auto id = CommonUtility::generateRandomStringAlphaNum(); const auto name = Str("a:b"); @@ -213,7 +214,7 @@ void TestSnapshot::testPath() { CPPUNIT_ASSERT(!ignore); #endif } - + // Item name starting by pattern "X:", should be ignored on Windows only { const auto id = CommonUtility::generateRandomStringAlphaNum(); const auto name = Str("C:"); @@ -234,7 +235,7 @@ void TestSnapshot::testPath() { CPPUNIT_ASSERT(!ignore); #endif } - + // Item name starting with more than 1 character before `:`, should be accepted { const auto id = CommonUtility::generateRandomStringAlphaNum(); const auto name = Str("aa:b"); From 56a879c2e7218c1d2594a132fbedc8f35964f66b Mon Sep 17 00:00:00 2001 From: Christophe Larchier Date: Wed, 30 Oct 2024 15:40:01 +0100 Subject: [PATCH 004/178] Windows implementation --- .../cfapi/Vfs/cloudproviderregistrar.cpp | 9 ++++++ extensions/windows/cfapi/Vfs/placeholders.cpp | 1 + src/server/vfs/win/vfs_win.cpp | 26 +++++++++------- test/server/workers/testworkers.cpp | 31 ++++++++++--------- test/test_utility/localtemporarydirectory.cpp | 6 +++- 5 files changed, 46 insertions(+), 27 deletions(-) diff --git a/extensions/windows/cfapi/Vfs/cloudproviderregistrar.cpp b/extensions/windows/cfapi/Vfs/cloudproviderregistrar.cpp index e5b756e2b..42bd7e62e 100644 --- a/extensions/windows/cfapi/Vfs/cloudproviderregistrar.cpp +++ b/extensions/windows/cfapi/Vfs/cloudproviderregistrar.cpp @@ -87,7 +87,16 @@ std::wstring CloudProviderRegistrar::registerWithShell(ProviderInfo *providerInf winrt::StorageProviderSyncRootInfo info; info.Id(syncRootID); +#ifndef NDEBUG + // Silent WINRT_ASSERT(!is_sta()) + int reportMode = _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_DEBUG); +#endif auto folder = winrt::StorageFolder::GetFolderFromPathAsync(providerInfo->folderPath()).get(); +#ifndef NDEBUG + // Restore old report mode + _CrtSetReportMode(_CRT_ASSERT, reportMode); +#endif + info.Path(folder); info.DisplayNameResource(providerInfo->folderName()); diff --git a/extensions/windows/cfapi/Vfs/placeholders.cpp b/extensions/windows/cfapi/Vfs/placeholders.cpp index 97504c2df..1fd08dc8c 100644 --- a/extensions/windows/cfapi/Vfs/placeholders.cpp +++ b/extensions/windows/cfapi/Vfs/placeholders.cpp @@ -45,6 +45,7 @@ bool Placeholders::create(const PCWSTR fileId, const PCWSTR relativePath, const cloudEntry.FsMetadata.BasicInfo.ChangeTime = Utilities::fileTimeToLargeInteger(findData->ftLastWriteTime); if ((findData->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0) { + cloudEntry.Flags |= CF_PLACEHOLDER_CREATE_FLAG_DISABLE_ON_DEMAND_POPULATION; cloudEntry.FsMetadata.FileSize.QuadPart = 0; } else { cloudEntry.FsMetadata.FileSize.QuadPart = ((ULONGLONG) findData->nFileSizeHigh << 32) + findData->nFileSizeLow; diff --git a/src/server/vfs/win/vfs_win.cpp b/src/server/vfs/win/vfs_win.cpp index 81b86cc90..259aada4b 100644 --- a/src/server/vfs/win/vfs_win.cpp +++ b/src/server/vfs/win/vfs_win.cpp @@ -59,17 +59,21 @@ VfsWin::VfsWin(VfsSetupParams &vfsSetupParams, QObject *parent) : Vfs(vfsSetupPa return; } - // Start worker threads - for (int i = 0; i < NB_WORKERS; i++) { - for (int j = 0; j < s_nb_threads[i]; j++) { - QThread *workerThread = new QThread(); - _workerInfo[i]._threadList.append(workerThread); - Worker *worker = new Worker(this, i, j, logger()); - worker->moveToThread(workerThread); - connect(workerThread, &QThread::started, worker, &Worker::start); - connect(workerThread, &QThread::finished, worker, &QObject::deleteLater); - connect(workerThread, &QThread::finished, workerThread, &QObject::deleteLater); - workerThread->start(); + // Start hydration/dehydration workers + // !!! Disabled for testing because no QEventLoop !!! + if (qApp) { + // Start worker threads + for (int i = 0; i < NB_WORKERS; i++) { + for (int j = 0; j < s_nb_threads[i]; j++) { + QThread *workerThread = new QThread(); + _workerInfo[i]._threadList.append(workerThread); + Worker *worker = new Worker(this, i, j, logger()); + worker->moveToThread(workerThread); + connect(workerThread, &QThread::started, worker, &Worker::start); + connect(workerThread, &QThread::finished, worker, &QObject::deleteLater); + connect(workerThread, &QThread::finished, workerThread, &QObject::deleteLater); + workerThread->start(); + } } } } diff --git a/test/server/workers/testworkers.cpp b/test/server/workers/testworkers.cpp index 761eac8b0..db407b1e7 100644 --- a/test/server/workers/testworkers.cpp +++ b/test/server/workers/testworkers.cpp @@ -209,18 +209,12 @@ void TestWorkers::testCreatePlaceholder() { CPPUNIT_ASSERT_EQUAL(exitCode, ExitCode::Ok); CPPUNIT_ASSERT_EQUAL(exitCause, ExitCause::Unknown); -#ifdef __APPLE__ // Folder already exists +#if defined(__APPLE__) || defined(_WIN32) exitCause = ExitCause::Unknown; exitCode = _syncPal->_executorWorker->createPlaceholder(relativeFolderPath, exitCause); CPPUNIT_ASSERT_EQUAL(exitCode, ExitCode::DataError); CPPUNIT_ASSERT_EQUAL(exitCause, ExitCause::InvalidSnapshot); -#elif _WIN32 - // Folder already exists - exitCause = ExitCause::Unknown; - exitCode = _syncPal->_executorWorker->createPlaceholder(relativeFolderPath, exitCause); - CPPUNIT_ASSERT_EQUAL(exitCode, ExitCode::Ok); - CPPUNIT_ASSERT_EQUAL(exitCause, ExitCause::Unknown); #endif } @@ -244,8 +238,21 @@ void TestWorkers::testCreatePlaceholder() { exitCause = ExitCause::Unknown; exitCode = _syncPal->_executorWorker->createPlaceholder(relativeFilePath, exitCause); +#ifdef __APPLE__ CPPUNIT_ASSERT_EQUAL(exitCode, ExitCode::SystemError); CPPUNIT_ASSERT_EQUAL(exitCause, ExitCause::NoSearchPermission); +#else + // Strangely (bug?), the Windows api is able to create a placeholder in a folder for which the user does not have rights + CPPUNIT_ASSERT_EQUAL(exitCode, ExitCode::Ok); + CPPUNIT_ASSERT_EQUAL(exitCause, ExitCause::Unknown); + + // Remove placeholder + std::error_code ec; + std::filesystem::remove(_syncPal->localPath() / relativeFilePath); + if (ec) { + // Cannot remove file + } +#endif ioError = IoError::Unknown; CPPUNIT_ASSERT(IoHelper::setRights(_syncPal->localPath() / relativeFolderPath, true, true, true, ioError) && @@ -258,18 +265,12 @@ void TestWorkers::testCreatePlaceholder() { CPPUNIT_ASSERT_EQUAL(exitCode, ExitCode::Ok); CPPUNIT_ASSERT_EQUAL(exitCause, ExitCause::Unknown); -#ifdef __APPLE__ +#if defined(__APPLE__) || defined(_WIN32) // File already exists exitCause = ExitCause::Unknown; exitCode = _syncPal->_executorWorker->createPlaceholder(relativeFilePath, exitCause); CPPUNIT_ASSERT_EQUAL(exitCode, ExitCode::DataError); CPPUNIT_ASSERT_EQUAL(exitCause, ExitCause::InvalidSnapshot); -#elif _WIN32 - // File already exists - exitCause = ExitCause::Unknown; - exitCode = _syncPal->_executorWorker->createPlaceholder(relativeFilePath, exitCause); - CPPUNIT_ASSERT_EQUAL(exitCode, ExitCode::Ok); - CPPUNIT_ASSERT_EQUAL(exitCause, ExitCause::Unknown); #endif } } @@ -331,7 +332,7 @@ void TestWorkers::testConvertToPlaceholder() { ioError == IoError::Success); exitCause = ExitCause::Unknown; - exitCode = _syncPal->_executorWorker->createPlaceholder(relativeFilePath, exitCause); + exitCode = _syncPal->_executorWorker->convertToPlaceholder(relativeFilePath, true, exitCause); CPPUNIT_ASSERT_EQUAL(exitCode, ExitCode::SystemError); CPPUNIT_ASSERT_EQUAL(exitCause, ExitCause::NoSearchPermission); diff --git a/test/test_utility/localtemporarydirectory.cpp b/test/test_utility/localtemporarydirectory.cpp index 14a9b78e2..ad76ba9d5 100644 --- a/test/test_utility/localtemporarydirectory.cpp +++ b/test/test_utility/localtemporarydirectory.cpp @@ -51,7 +51,11 @@ LocalTemporaryDirectory::LocalTemporaryDirectory(const std::string &testType) { } LocalTemporaryDirectory::~LocalTemporaryDirectory() { - std::filesystem::remove_all(_path); + std::error_code ec; + std::filesystem::remove_all(_path, ec); + if (ec) { + // Cannot remove directory + } } From 044cf19333a17b795b7ef4711ee9e109f5c4db4d Mon Sep 17 00:00:00 2001 From: Christophe Larchier Date: Wed, 30 Oct 2024 16:10:17 +0100 Subject: [PATCH 005/178] Fix macOS build --- test/server/CMakeLists.txt | 45 ++++++++++++++++++++++++-------------- test/test.cpp | 3 ++- 2 files changed, 30 insertions(+), 18 deletions(-) diff --git a/test/server/CMakeLists.txt b/test/server/CMakeLists.txt index 4d1cbf440..abb32677c 100644 --- a/test/server/CMakeLists.txt +++ b/test/server/CMakeLists.txt @@ -19,6 +19,25 @@ set(server_SRCS ../../src/server/updater_v2/abstractupdater.h ../../src/server/updater_v2/abstractupdater.cpp ) +if(APPLE) + list(APPEND server_SRCS ../../src/server/socketapisocket_mac.mm) + set_property(SOURCE ../../src/server/socketapisocket_mac.mm APPEND_STRING PROPERTY COMPILE_FLAGS "-fobjc-arc") + + list(APPEND server_SRCS ../../extensions/MacOSX/kDriveFinderSync/kDrive/NSXPCConnection+LoginItem.m) + set_property(SOURCE ../../extensions/MacOSX/kDriveFinderSync/kDrive/NSXPCConnection+LoginItem.m APPEND_STRING PROPERTY COMPILE_FLAGS "-fobjc-arc") + + if(SPARKLE_FOUND) + # Define this, we need to check in updater.cpp + add_definitions(-DHAVE_SPARKLE) + list(APPEND updater_DEPS ${SPARKLE_LIBRARY}) + + # Sparkle.framework is installed from here because macdeployqt's CopyFramework breaks on this bundle + # as its logic is tightly tailored around Qt6 frameworks + install(DIRECTORY "${SPARKLE_LIBRARY}" + DESTINATION "${KDRIVE_OSX_BUNDLE}/Contents/Frameworks" USE_SOURCE_PERMISSIONS) + endif() +endif() + set(testserver_SRCS ../test_utility/testhelpers.h ../test_utility/testhelpers.cpp ../test_utility/localtemporarydirectory.h ../test_utility/localtemporarydirectory.cpp @@ -32,18 +51,7 @@ set(testserver_SRCS ) if(APPLE) - list(APPEND testserver_SRCS vfs/mac/testlitesyncextconnector.h vfs/mac/testlitesyncextconnector.cpp) - - if(SPARKLE_FOUND) - # Define this, we need to check in updater.cpp - add_definitions(-DHAVE_SPARKLE) - list(APPEND updater_DEPS ${SPARKLE_LIBRARY}) - - # Sparkle.framework is installed from here because macdeployqt's CopyFramework breaks on this bundle - # as its logic is tightly tailored around Qt6 frameworks - install(DIRECTORY "${SPARKLE_LIBRARY}" - DESTINATION "${KDRIVE_OSX_BUNDLE}/Contents/Frameworks" USE_SOURCE_PERMISSIONS) - endif() + list(APPEND testserver_SRCS vfs/mac/testlitesyncextconnector.h vfs/mac/testlitesyncextconnector.cpp) endif() if (WIN32) @@ -61,13 +69,11 @@ add_executable(${testserver_NAME} ${testserver_SRCS}) set_target_properties(${testserver_NAME} PROPERTIES - RUNTIME_OUTPUT_DIRECTORY ${BIN_OUTPUT_DIRECTORY}) + RUNTIME_OUTPUT_DIRECTORY ${BIN_OUTPUT_DIRECTORY}) target_link_libraries(${testserver_NAME} - Qt6::Svg - ${libcommon_NAME} - ${libsyncengine_NAME} - updater + Qt6::Svg + updater ) if (APPLE) @@ -99,6 +105,11 @@ else () "/usr/local/lib/libcppunit.so") endif() +if (APPLE) + find_library(SERVICE_MANAGEMENT_LIBRARY NAMES ServiceManagement) + target_link_libraries(${testserver_NAME} ${SERVICE_MANAGEMENT_LIBRARY}) +endif() + # Install if (APPLE) # Default sync exclude list diff --git a/test/test.cpp b/test/test.cpp index 79e940869..80a6b8242 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -18,8 +18,9 @@ #include "testincludes.h" -#include "libcommonserver/log/log.h" #include "libcommon/log/sentry/sentryhandler.h" +#include "libcommonserver/log/log.h" +#include "libcommonserver/utility/utility.h" #include From 74eb9a684a3783b55998ee00fde81a75132988a3 Mon Sep 17 00:00:00 2001 From: Christophe Larchier Date: Thu, 31 Oct 2024 16:03:45 +0100 Subject: [PATCH 006/178] Fix macOS tests --- src/server/socketapi.cpp | 19 +++++++++---------- src/server/vfs/mac/CMakeLists.txt | 8 -------- test/libsyncengine/CMakeLists.txt | 6 ------ test/server/CMakeLists.txt | 19 ++++--------------- test/server/workers/testworkers.cpp | 4 ++++ 5 files changed, 17 insertions(+), 39 deletions(-) diff --git a/src/server/socketapi.cpp b/src/server/socketapi.cpp index e89734ac2..2ebe265fd 100644 --- a/src/server/socketapi.cpp +++ b/src/server/socketapi.cpp @@ -50,9 +50,7 @@ #include #ifdef Q_OS_MAC - #include - #endif #include @@ -103,18 +101,19 @@ SocketApi::SocketApi(const std::unordered_map } else if (OldUtility::isMac()) { socketPath = SOCKETAPI_TEAM_IDENTIFIER_PREFIX APPLICATION_REV_DOMAIN ".socketApi"; #ifdef Q_OS_MAC - CFURLRef url = (CFURLRef) CFAutorelease((CFURLRef) CFBundleCopyBundleURL(CFBundleGetMainBundle())); - QString bundlePath = QUrl::fromCFURL(url).path(); - QString cmd; - // Tell Finder to use the Extension (checking it from System Preferences -> Extensions) - cmd = QString("pluginkit -v -e use -i " APPLICATION_REV_DOMAIN ".Extension"); + QString cmd = QString("pluginkit -v -e use -i " APPLICATION_REV_DOMAIN ".Extension"); system(cmd.toLocal8Bit()); // Add it again. This was needed for Mojave to trigger a load. - cmd = QString("pluginkit -v -a ") + bundlePath + "Contents/PlugIns/Extension.appex/"; - system(cmd.toLocal8Bit()); - + // TODO: Still needed? + CFURLRef url = (CFURLRef) CFAutorelease((CFURLRef) CFBundleCopyBundleURL(CFBundleGetMainBundle())); + QString appexPath = QUrl::fromCFURL(url).path() + "Contents/PlugIns/Extension.appex/"; + if (std::filesystem::exists(QStr2Path(appexPath))) { + // Bundled app (i.e. not test executable) + cmd = QString("pluginkit -v -a ") + appexPath; + system(cmd.toLocal8Bit()); + } #endif } else if (OldUtility::isLinux() || OldUtility::isBSD()) { const QString runtimeDir = QStandardPaths::writableLocation(QStandardPaths::RuntimeLocation); diff --git a/src/server/vfs/mac/CMakeLists.txt b/src/server/vfs/mac/CMakeLists.txt index ae9f261f2..c4c46e0c4 100644 --- a/src/server/vfs/mac/CMakeLists.txt +++ b/src/server/vfs/mac/CMakeLists.txt @@ -20,14 +20,6 @@ set_target_properties("${libsyncengine_NAME}_vfs_mac" AUTOMOC TRUE ) -# for being loadable when client run from build dir -set(vfs_buildoutputdir "${BIN_OUTPUT_DIRECTORY}/${KDRIVE_OSX_BUNDLE}/Contents/PlugIns/") -set_target_properties("${libsyncengine_NAME}_vfs_mac" - PROPERTIES - LIBRARY_OUTPUT_DIRECTORY ${vfs_buildoutputdir} - RUNTIME_OUTPUT_DIRECTORY ${vfs_buildoutputdir} -) - # Link find_library(SYSTEM_EXTENSION_LIBRARY NAMES SystemExtensions) target_link_libraries("${libsyncengine_NAME}_vfs_mac" diff --git a/test/libsyncengine/CMakeLists.txt b/test/libsyncengine/CMakeLists.txt index 0509c70bf..962e66661 100644 --- a/test/libsyncengine/CMakeLists.txt +++ b/test/libsyncengine/CMakeLists.txt @@ -92,12 +92,6 @@ else () endif () if (APPLE) - # Default sync exclude list - install(FILES ${CMAKE_SOURCE_DIR}/sync-exclude-osx.lst DESTINATION ${BIN_OUTPUT_DIRECTORY} RENAME sync-exclude.lst) - - # Default Lite Sync app exclude list - install(FILES ${CMAKE_SOURCE_DIR}/litesync-exclude.lst DESTINATION ${BIN_OUTPUT_DIRECTORY}) - install(CODE " message(STATUS \"Fixing library paths for ${testsyncengine_NAME}...\") execute_process(COMMAND \"install_name_tool\" -change libxxhash.0.dylib @rpath/libxxhash.0.8.2.dylib ${BIN_OUTPUT_DIRECTORY}/${testsyncengine_NAME}) diff --git a/test/server/CMakeLists.txt b/test/server/CMakeLists.txt index c81405e72..5dbb9ba60 100644 --- a/test/server/CMakeLists.txt +++ b/test/server/CMakeLists.txt @@ -32,11 +32,6 @@ if(APPLE) add_definitions(-DHAVE_SPARKLE) list(APPEND server_SRCS ${server_srcs_path}/updater/sparkleupdater.h ${server_srcs_path}/updater/sparkleupdater.mm) list(APPEND updater_DEPS ${SPARKLE_LIBRARY}) - - # Sparkle.framework is installed from here because macdeployqt's CopyFramework breaks on this bundle - # as its logic is tightly tailored around Qt6 frameworks - install(DIRECTORY "${SPARKLE_LIBRARY}" - DESTINATION "${KDRIVE_OSX_BUNDLE}/Contents/Frameworks" USE_SOURCE_PERMISSIONS) endif() elseif (WIN32) list(APPEND server_SRCS ${server_srcs_path}/updater/windowsupdater.h ${server_srcs_path}/updater/windowsupdater.cpp) @@ -118,20 +113,14 @@ endif() # Install if (APPLE) - # Default sync exclude list - install(FILES ${CMAKE_SOURCE_DIR}/sync-exclude-osx.lst DESTINATION ${BIN_OUTPUT_DIRECTORY} RENAME sync-exclude.lst) - - # Default Lite Sync app exclude list - install(FILES ${CMAKE_SOURCE_DIR}/litesync-exclude.lst DESTINATION ${BIN_OUTPUT_DIRECTORY}) - - #Vfs - install(TARGETS "${libsyncengine_NAME}_vfs_mac" - LIBRARY DESTINATION "${BIN_OUTPUT_DIRECTORY}" - RUNTIME DESTINATION "${BIN_OUTPUT_DIRECTORY}") + cmake_path(GET SPARKLE_LIBRARY PARENT_PATH USER_FRAMEWORK_PATH) install(CODE " message(STATUS \"Fixing library paths for ${testserver_NAME}...\") execute_process(COMMAND \"install_name_tool\" -change libxxhash.0.dylib @rpath/libxxhash.0.8.2.dylib ${BIN_OUTPUT_DIRECTORY}/${testserver_NAME}) + execute_process(COMMAND \"install_name_tool\" -delete_rpath ${USER_FRAMEWORK_PATH} ${BIN_OUTPUT_DIRECTORY}/${testserver_NAME}) + execute_process(COMMAND \"install_name_tool\" -add_rpath ${INSTALL_OUTPUT_DIRECTORY}/${KDRIVE_OSX_BUNDLE}/Contents/Frameworks ${BIN_OUTPUT_DIRECTORY}/${testserver_NAME}) + execute_process(COMMAND \"install_name_tool\" -add_rpath ${INSTALL_OUTPUT_DIRECTORY}/${KDRIVE_OSX_BUNDLE}/Contents/Plugins ${BIN_OUTPUT_DIRECTORY}/${testserver_NAME}) " COMPONENT RUNTIME) elseif (WIN32) #Vfs diff --git a/test/server/workers/testworkers.cpp b/test/server/workers/testworkers.cpp index 12f760687..fc5b6ea2f 100644 --- a/test/server/workers/testworkers.cpp +++ b/test/server/workers/testworkers.cpp @@ -154,6 +154,9 @@ void TestWorkers::setUp() { CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED); #endif +#if !defined(__APPLE__) + // TODO: on macOS, SIP should be deactivated and LiteSync extension signed to be able to start Vfs + // Start Vfs bool installationDone; bool activationDone; @@ -162,6 +165,7 @@ void TestWorkers::setUp() { CPPUNIT_ASSERT(installationDone); CPPUNIT_ASSERT(activationDone); CPPUNIT_ASSERT(connectionDone); +#endif } void TestWorkers::tearDown() { From 5f354103bf64d6878f78649c34d7518ccc470629 Mon Sep 17 00:00:00 2001 From: Christophe Larchier Date: Thu, 31 Oct 2024 16:42:05 +0100 Subject: [PATCH 007/178] Fix some warnings --- src/libsyncengine/jobs/network/getappversionjob.h | 3 ++- src/libsyncengine/propagation/executor/executorworker.cpp | 1 - src/server/appserver.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libsyncengine/jobs/network/getappversionjob.h b/src/libsyncengine/jobs/network/getappversionjob.h index 32e896464..70d309560 100644 --- a/src/libsyncengine/jobs/network/getappversionjob.h +++ b/src/libsyncengine/jobs/network/getappversionjob.h @@ -40,7 +40,8 @@ class GetAppVersionJob : public AbstractNetworkJob { private: std::string getSpecificUrl() override; std::string getContentType(bool &canceled) override; - void setQueryParameters(Poco::URI &, bool &canceled) override { /* no query parameters */} + void setQueryParameters(Poco::URI &, bool &) override { /* no query parameters */ + } ExitInfo setData() override { return ExitCode::Ok; } bool handleError(std::istream &is, const Poco::URI &uri) override; diff --git a/src/libsyncengine/propagation/executor/executorworker.cpp b/src/libsyncengine/propagation/executor/executorworker.cpp index f0f519f43..51705dac6 100644 --- a/src/libsyncengine/propagation/executor/executorworker.cpp +++ b/src/libsyncengine/propagation/executor/executorworker.cpp @@ -1877,7 +1877,6 @@ ExitInfo ExecutorWorker::propagateConflictToDbAndTree(SyncOpPtr syncOp, bool &pr case ConflictType::MoveMoveSource: // Name clash conflict pattern { if (syncOp->conflict().type() != ConflictType::MoveMoveSource) { - DbNodeId dbId = -1; bool localNodeFoundInDb = false; // when it's an Edit-Edit we want to delete the node NodeId effectiveNodeId = diff --git a/src/server/appserver.cpp b/src/server/appserver.cpp index 6653d596a..24885b843 100644 --- a/src/server/appserver.cpp +++ b/src/server/appserver.cpp @@ -3943,7 +3943,7 @@ void AppServer::addError(const Error &error) { } } } - for (int errorId: toBeRemovedErrorIds) { + for (int64_t errorId: toBeRemovedErrorIds) { bool found = false; if (!ParmsDb::instance()->deleteError(errorId, found)) { LOG_WARN(Log::instance()->getLogger(), "Error in ParmsDb::deleteError"); From d0de8e1aa117446fed1bb28f833271349bc5df01 Mon Sep 17 00:00:00 2001 From: Christophe Larchier Date: Mon, 4 Nov 2024 09:19:59 +0100 Subject: [PATCH 008/178] Address comments --- src/server/appserver.cpp | 2 +- test/server/workers/testworkers.cpp | 7 ++++--- test/test_utility/localtemporarydirectory.cpp | 1 + 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/server/appserver.cpp b/src/server/appserver.cpp index 24885b843..2c38d2712 100644 --- a/src/server/appserver.cpp +++ b/src/server/appserver.cpp @@ -3943,7 +3943,7 @@ void AppServer::addError(const Error &error) { } } } - for (int64_t errorId: toBeRemovedErrorIds) { + for (auto errorId: toBeRemovedErrorIds) { bool found = false; if (!ParmsDb::instance()->deleteError(errorId, found)) { LOG_WARN(Log::instance()->getLogger(), "Error in ParmsDb::deleteError"); diff --git a/test/server/workers/testworkers.cpp b/test/server/workers/testworkers.cpp index 0d6e07e30..266f80e7e 100644 --- a/test/server/workers/testworkers.cpp +++ b/test/server/workers/testworkers.cpp @@ -158,9 +158,9 @@ void TestWorkers::setUp() { // TODO: on macOS, SIP should be deactivated and LiteSync extension signed to be able to start Vfs // Start Vfs - bool installationDone; - bool activationDone; - bool connectionDone; + bool installationDone = false; + bool activationDone = false; + bool connectionDone = false; CPPUNIT_ASSERT(_vfsPtr->startImpl(installationDone, activationDone, connectionDone)); CPPUNIT_ASSERT(installationDone); CPPUNIT_ASSERT(activationDone); @@ -250,6 +250,7 @@ void TestWorkers::testCreatePlaceholder() { std::filesystem::remove(_syncPal->localPath() / relativeFilePath); if (ec) { // Cannot remove file + CPPUNIT_ASSERT(false); } #endif diff --git a/test/test_utility/localtemporarydirectory.cpp b/test/test_utility/localtemporarydirectory.cpp index ad76ba9d5..4a5c65155 100644 --- a/test/test_utility/localtemporarydirectory.cpp +++ b/test/test_utility/localtemporarydirectory.cpp @@ -55,6 +55,7 @@ LocalTemporaryDirectory::~LocalTemporaryDirectory() { std::filesystem::remove_all(_path, ec); if (ec) { // Cannot remove directory + assert(false); } } From d8a26be74cb6939c148231b05ef0945844e1ff50 Mon Sep 17 00:00:00 2001 From: Christophe Larchier Date: Mon, 4 Nov 2024 09:20:16 +0100 Subject: [PATCH 009/178] Activate tests --- test/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index f823d153e..de1a8d327 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -28,4 +28,4 @@ add_subdirectory(libcommonserver) add_subdirectory(libcommon) add_subdirectory(libparms) add_subdirectory(libsyncengine) -#add_subdirectory(server) +add_subdirectory(server) From 0e8804bc2bb58ec3915304657326df5a8f7e9601 Mon Sep 17 00:00:00 2001 From: Christophe Larchier Date: Mon, 4 Nov 2024 09:20:44 +0100 Subject: [PATCH 010/178] Fix createPlaceholder issue --- src/libsyncengine/propagation/executor/executorworker.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/libsyncengine/propagation/executor/executorworker.cpp b/src/libsyncengine/propagation/executor/executorworker.cpp index 51705dac6..2e63f73fa 100644 --- a/src/libsyncengine/propagation/executor/executorworker.cpp +++ b/src/libsyncengine/propagation/executor/executorworker.cpp @@ -745,6 +745,11 @@ ExitInfo ExecutorWorker::createPlaceholder(const SyncPath &relativeLocalPath) { return ExitCode::SystemError; } + if (ioError == IoError::AccessDenied) { + LOGW_WARN(_logger, L"Access denied to " << Path2WStr(absoluteLocalPath).c_str()); + return {ExitCode::SystemError, ExitCause::FileAccessError}; + } + if (exists) { LOGW_WARN(_logger, L"Item already exists: " << Utility::formatSyncPath(absoluteLocalPath)); return {ExitCode::DataError, ExitCause::InvalidSnapshot}; @@ -825,7 +830,7 @@ ExitInfo ExecutorWorker::processCreateOrConvertToPlaceholderError(const SyncPath if (create && exists) { return {ExitCode::SystemError, ExitCause::FileAccessError}; } else if (!create && !exists) { - return {ExitCode::DataError, ExitCause::FileAlreadyExist}; + return {ExitCode::DataError, ExitCause::InvalidSnapshot}; } if (create) { From 961b01dc3f77fa230e318a1ce46c2c10b1e6c2f6 Mon Sep 17 00:00:00 2001 From: Christophe Larchier Date: Mon, 4 Nov 2024 10:50:38 +0100 Subject: [PATCH 011/178] Fix startImpl --- src/libcommonserver/vfs.cpp | 5 ++++- src/server/vfs/mac/vfs_mac.cpp | 4 ++++ src/server/vfs/win/vfs_win.cpp | 10 +++++++++- 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/libcommonserver/vfs.cpp b/src/libcommonserver/vfs.cpp index 3027c1d6c..940d10a1a 100644 --- a/src/libcommonserver/vfs.cpp +++ b/src/libcommonserver/vfs.cpp @@ -109,7 +109,10 @@ bool VfsOff::forceStatus(const QString &path, bool isSyncing, int /*progress*/, return true; } -bool VfsOff::startImpl(bool &, bool &, bool &) { +bool VfsOff::startImpl(bool &installationDone, bool &activationDone, bool &connectionDone) { + installationDone = true; + activationDone = true; + connectionDone = true; return true; } diff --git a/src/server/vfs/mac/vfs_mac.cpp b/src/server/vfs/mac/vfs_mac.cpp index 48f85e411..b2b70e581 100644 --- a/src/server/vfs/mac/vfs_mac.cpp +++ b/src/server/vfs/mac/vfs_mac.cpp @@ -95,6 +95,10 @@ VirtualFileMode VfsMac::mode() const { } bool VfsMac::startImpl(bool &installationDone, bool &activationDone, bool &connectionDone) { + installationDone = false; + activationDone = false; + connectionDone = false; + LOG_DEBUG(logger(), "startImpl - syncDbId=" << _vfsSetupParams._syncDbId); if (!_connector) { diff --git a/src/server/vfs/win/vfs_win.cpp b/src/server/vfs/win/vfs_win.cpp index 259aada4b..0a6d49553 100644 --- a/src/server/vfs/win/vfs_win.cpp +++ b/src/server/vfs/win/vfs_win.cpp @@ -122,7 +122,11 @@ VirtualFileMode VfsWin::mode() const { return VirtualFileMode::Win; } -bool VfsWin::startImpl(bool &, bool &, bool &) { +bool VfsWin::startImpl(bool &installationDone, bool &activationDone, bool &connectionDone) { + installationDone = false; + activationDone = false; + connectionDone = false; + LOG_DEBUG(logger(), "startImpl: syncDbId=" << _vfsSetupParams._syncDbId); wchar_t clsid[39] = L""; @@ -136,6 +140,10 @@ bool VfsWin::startImpl(bool &, bool &, bool &) { _vfsSetupParams._namespaceCLSID = Utility::ws2s(std::wstring(clsid)); + installationDone = true; + activationDone = true; + connectionDone = true; + return true; } From e34b5f0146a38023b430dbc694094366c3516b75 Mon Sep 17 00:00:00 2001 From: Christophe Larchier Date: Mon, 4 Nov 2024 10:50:47 +0100 Subject: [PATCH 012/178] Fix test --- test/server/workers/testworkers.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/server/workers/testworkers.cpp b/test/server/workers/testworkers.cpp index 266f80e7e..a918e0787 100644 --- a/test/server/workers/testworkers.cpp +++ b/test/server/workers/testworkers.cpp @@ -242,7 +242,7 @@ void TestWorkers::testCreatePlaceholder() { CPPUNIT_ASSERT_EQUAL(ExitCause::FileAccessError, exitInfo.cause()); #else // Strangely (bug?), the Windows api is able to create a placeholder in a folder for which the user does not have rights - CPPUNIT_ASSERT_EQUAL(ExitCode::SystemError, exitInfo.code()); + CPPUNIT_ASSERT_EQUAL(ExitCode::Ok, exitInfo.code()); CPPUNIT_ASSERT_EQUAL(ExitCause::Unknown, exitInfo.cause()); // Remove placeholder From b63eca28f9e5a37c518e0f65d519007c05257684 Mon Sep 17 00:00:00 2001 From: Herve Eruam Date: Mon, 4 Nov 2024 15:11:47 +0100 Subject: [PATCH 013/178] Remove tmp file after a download, in case of crosslinkdevice. --- .../jobs/network/API_v2/downloadjob.cpp | 25 +++++++++---------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/src/libsyncengine/jobs/network/API_v2/downloadjob.cpp b/src/libsyncengine/jobs/network/API_v2/downloadjob.cpp index 432fc82fa..3b1963bb2 100644 --- a/src/libsyncengine/jobs/network/API_v2/downloadjob.cpp +++ b/src/libsyncengine/jobs/network/API_v2/downloadjob.cpp @@ -493,21 +493,15 @@ bool DownloadJob::createLink(const std::string &mimeType, const std::string &dat } bool DownloadJob::removeTmpFile(const SyncPath &path) { - std::error_code ec; - if (!std::filesystem::remove_all(path, ec)) { - if (ec) { - LOGW_WARN(_logger, L"Failed to remove all: " << Utility::formatStdError(path, ec).c_str()); - return false; - } - - LOGW_WARN(_logger, L"Failed to remove all: " << Utility::formatSyncPath(path).c_str()); + if (std::error_code ec; !std::filesystem::remove_all(path, ec)) { + LOGW_WARN(_logger, L"Failed to remove all: " << Utility::formatStdError(path, ec)); return false; } return true; } -bool DownloadJob::moveTmpFile(const SyncPath &path, bool &restartSync) { +bool DownloadJob::moveTmpFile(const SyncPath &tmpPath, bool &restartSync) { restartSync = false; // Move downloaded file from tmp directory to sync directory @@ -518,7 +512,7 @@ bool DownloadJob::moveTmpFile(const SyncPath &path, bool &restartSync) { while (retry) { retry = false; #endif - std::filesystem::rename(path, _localpath, ec); + std::filesystem::rename(tmpPath, _localpath, ec); #ifdef _WIN32 const bool crossDeviceLink = ec.value() == ERROR_NOT_SAME_DEVICE; #else @@ -528,10 +522,15 @@ bool DownloadJob::moveTmpFile(const SyncPath &path, bool &restartSync) { // The sync might be on a different file system than tmp folder. // In that case, try to copy the file instead. ec.clear(); - std::filesystem::copy(path, _localpath, std::filesystem::copy_options::overwrite_existing, ec); + std::filesystem::copy(tmpPath, _localpath, std::filesystem::copy_options::overwrite_existing, ec); + bool removed = removeTmpFile(tmpPath); if (ec) { - LOGW_WARN(_logger, L"Failed to copy: " << Utility::formatSyncPath(_localpath).c_str() << L", " - << Utility::formatStdError(ec).c_str()); + LOGW_WARN(_logger, + L"Failed to copy: " << Utility::formatSyncPath(_localpath) << L", " << Utility::formatStdError(ec)); + return false; + } + if (!removed) { + LOGW_WARN(_logger, L"Failed to remove: " << Utility::formatSyncPath(tmpPath)); return false; } } From e4eeb41faccee2a766555d2b4194a903a02b4eec Mon Sep 17 00:00:00 2001 From: Herve Eruam Date: Mon, 4 Nov 2024 15:16:36 +0100 Subject: [PATCH 014/178] Remove useless .c_str(). --- .../jobs/network/API_v2/downloadjob.cpp | 99 ++++++++++--------- 1 file changed, 50 insertions(+), 49 deletions(-) diff --git a/src/libsyncengine/jobs/network/API_v2/downloadjob.cpp b/src/libsyncengine/jobs/network/API_v2/downloadjob.cpp index 3b1963bb2..4b8d864c6 100644 --- a/src/libsyncengine/jobs/network/API_v2/downloadjob.cpp +++ b/src/libsyncengine/jobs/network/API_v2/downloadjob.cpp @@ -43,8 +43,9 @@ namespace KDC { DownloadJob::DownloadJob(int driveDbId, const NodeId &remoteFileId, const SyncPath &localpath, int64_t expectedSize, SyncTime creationTime, SyncTime modtime, bool isCreate) : - AbstractTokenNetworkJob(ApiType::Drive, 0, 0, driveDbId, 0, false), _remoteFileId(remoteFileId), _localpath(localpath), - _expectedSize(expectedSize), _creationTime(creationTime), _modtimeIn(modtime), _isCreate(isCreate) { + AbstractTokenNetworkJob(ApiType::Drive, 0, 0, driveDbId, 0, false), + _remoteFileId(remoteFileId), _localpath(localpath), _expectedSize(expectedSize), _creationTime(creationTime), + _modtimeIn(modtime), _isCreate(isCreate) { _httpMethod = Poco::Net::HTTPRequest::HTTP_GET; _customTimeout = 60; _trials = TRIALS; @@ -62,32 +63,32 @@ DownloadJob::~DownloadJob() { if (_responseHandlingCanceled) { if (_vfsSetPinState) { if (!_vfsSetPinState(_localpath, PinState::OnlineOnly)) { - LOGW_WARN(_logger, L"Error in vfsSetPinState: " << Utility::formatSyncPath(_localpath).c_str()); + LOGW_WARN(_logger, L"Error in vfsSetPinState: " << Utility::formatSyncPath(_localpath)); } } // TODO: usefull ? if (_vfsForceStatus) { if (!_vfsForceStatus(_localpath, false, 0, false)) { - LOGW_WARN(_logger, L"Error in vfsForceStatus: " << Utility::formatSyncPath(_localpath).c_str()); + LOGW_WARN(_logger, L"Error in vfsForceStatus: " << Utility::formatSyncPath(_localpath)); } } if (_vfsCancelHydrate) { if (!_vfsCancelHydrate(_localpath)) { - LOGW_WARN(_logger, L"Error in vfsCancelHydrate: " << Utility::formatSyncPath(_localpath).c_str()); + LOGW_WARN(_logger, L"Error in vfsCancelHydrate: " << Utility::formatSyncPath(_localpath)); } } } else { if (_vfsSetPinState) { if (!_vfsSetPinState(_localpath, _exitCode == ExitCode::Ok ? PinState::AlwaysLocal : PinState::OnlineOnly)) { - LOGW_WARN(_logger, L"Error in vfsSetPinState: " << Utility::formatSyncPath(_localpath).c_str()); + LOGW_WARN(_logger, L"Error in vfsSetPinState: " << Utility::formatSyncPath(_localpath)); } } if (_vfsForceStatus) { if (!_vfsForceStatus(_localpath, false, 0, _exitCode == ExitCode::Ok)) { - LOGW_WARN(_logger, L"Error in vfsForceStatus: " << Utility::formatSyncPath(_localpath).c_str()); + LOGW_WARN(_logger, L"Error in vfsForceStatus: " << Utility::formatSyncPath(_localpath)); } } } @@ -110,15 +111,15 @@ bool DownloadJob::canRun() { bool exists; IoError ioError = IoError::Success; if (!IoHelper::checkIfPathExists(_localpath, exists, ioError)) { - LOGW_WARN(_logger, L"Error in IoHelper::checkIfPathExists: " << Utility::formatIoError(_localpath, ioError).c_str()); + LOGW_WARN(_logger, L"Error in IoHelper::checkIfPathExists: " << Utility::formatIoError(_localpath, ioError)); _exitCode = ExitCode::SystemError; _exitCause = ExitCause::FileAccessError; return false; } if (_isCreate && exists) { - LOGW_DEBUG(_logger, L"Item: " << Utility::formatSyncPath(_localpath).c_str() - << L" already exist. Aborting current sync and restart."); + LOGW_DEBUG(_logger, + L"Item: " << Utility::formatSyncPath(_localpath) << L" already exist. Aborting current sync and restart."); _exitCode = ExitCode::NeedRestart; _exitCause = ExitCause::UnexpectedFileSystemEvent; return false; @@ -134,29 +135,29 @@ void DownloadJob::runJob() noexcept { FileStat filestat; IoError ioError = IoError::Success; if (!IoHelper::getFileStat(_localpath, &filestat, ioError)) { - LOGW_WARN(_logger, L"Error in IoHelper::getFileStat: " << Utility::formatIoError(_localpath, ioError).c_str()); + LOGW_WARN(_logger, L"Error in IoHelper::getFileStat: " << Utility::formatIoError(_localpath, ioError)); return; } if (ioError == IoError::NoSuchFileOrDirectory) { - LOGW_WARN(_logger, L"Item does not exist anymore: " << Utility::formatSyncPath(_localpath).c_str()); + LOGW_WARN(_logger, L"Item does not exist anymore: " << Utility::formatSyncPath(_localpath)); return; } else if (ioError == IoError::AccessDenied) { - LOGW_WARN(_logger, L"Item misses search permission: " << Utility::formatSyncPath(_localpath).c_str()); + LOGW_WARN(_logger, L"Item misses search permission: " << Utility::formatSyncPath(_localpath)); return; } std::string error; if (!_vfsUpdateMetadata(_localpath, filestat.creationTime, filestat.modtime, _expectedSize, std::to_string(filestat.inode), error)) { - LOGW_WARN(_logger, L"Update metadata failed: " << Utility::formatSyncPath(_localpath).c_str()); + LOGW_WARN(_logger, L"Update metadata failed: " << Utility::formatSyncPath(_localpath)); return; } } if (_vfsForceStatus) { if (!_vfsForceStatus(_localpath, true, 0, false)) { - LOGW_WARN(_logger, L"Error in vfsForceStatus: " << Utility::formatSyncPath(_localpath).c_str()); + LOGW_WARN(_logger, L"Error in vfsForceStatus: " << Utility::formatSyncPath(_localpath)); return; } } @@ -209,7 +210,7 @@ bool DownloadJob::handleResponse(std::istream &is) { SyncPath tmpPath; IoError ioError = IoError::Success; if (!IoHelper::tempDirectoryPath(tmpPath, ioError)) { - LOGW_WARN(_logger, L"Failed to get temporary directory path: " << Utility::formatIoError(tmpPath, ioError).c_str()); + LOGW_WARN(_logger, L"Failed to get temporary directory tmpPath: " << Utility::formatIoError(tmpPath, ioError)); _exitCode = ExitCode::SystemError; _exitCause = ExitCause::Unknown; return false; @@ -219,7 +220,7 @@ bool DownloadJob::handleResponse(std::istream &is) { std::ofstream output(tmpPath.native().c_str(), std::ios::binary); if (!output) { - LOGW_WARN(_logger, L"Failed to create file: " << Utility::formatSyncPath(tmpPath).c_str()); + LOGW_WARN(_logger, L"Failed to create file: " << Utility::formatSyncPath(tmpPath)); _exitCode = ExitCode::SystemError; _exitCause = Utility::enoughSpace(tmpPath) ? ExitCause::FileAccessError : ExitCause::NotEnoughDiskSpace; return false; @@ -303,11 +304,11 @@ bool DownloadJob::handleResponse(std::istream &is) { if (elapsed_seconds.count() > NOTIFICATION_DELAY || done) { // Update fetch status if (!_vfsUpdateFetchStatus(tmpPath, _localpath, getProgress(), fetchCanceled, fetchFinished)) { - LOGW_WARN(_logger, L"Error in vfsUpdateFetchStatus: " << Utility::formatSyncPath(_localpath).c_str()); + LOGW_WARN(_logger, L"Error in vfsUpdateFetchStatus: " << Utility::formatSyncPath(_localpath)); fetchError = true; break; } else if (fetchCanceled) { - LOGW_WARN(_logger, L"Update fetch status canceled: " << Utility::formatSyncPath(_localpath).c_str()); + LOGW_WARN(_logger, L"Update fetch status canceled: " << Utility::formatSyncPath(_localpath)); break; } fileProgressTimer = std::chrono::steady_clock::now(); @@ -330,12 +331,12 @@ bool DownloadJob::handleResponse(std::istream &is) { if (_vfsUpdateFetchStatus && !fetchFinished) { // Update fetch status if (!_vfsUpdateFetchStatus(tmpPath, _localpath, getProgress(), fetchCanceled, fetchFinished)) { - LOGW_WARN(_logger, L"Error in vfsUpdateFetchStatus: " << Utility::formatSyncPath(_localpath).c_str()); + LOGW_WARN(_logger, L"Error in vfsUpdateFetchStatus: " << Utility::formatSyncPath(_localpath)); fetchError = true; } else if (fetchCanceled) { - LOGW_WARN(_logger, L"Update fetch status canceled: " << Utility::formatSyncPath(_localpath).c_str()); + LOGW_WARN(_logger, L"Update fetch status canceled: " << Utility::formatSyncPath(_localpath)); } else if (!fetchFinished) { - LOGW_WARN(_logger, L"Update fetch status not terminated: " << Utility::formatSyncPath(_localpath).c_str()); + LOGW_WARN(_logger, L"Update fetch status not terminated: " << Utility::formatSyncPath(_localpath)); } _responseHandlingCanceled = fetchCanceled || fetchError || (!fetchFinished); @@ -343,7 +344,7 @@ bool DownloadJob::handleResponse(std::istream &is) { // Replace file by tmp one bool replaceError = false; if (!moveTmpFile(tmpPath, restartSync)) { - LOGW_WARN(_logger, L"Failed to replace file by tmp one: " << Utility::formatSyncPath(tmpPath).c_str()); + LOGW_WARN(_logger, L"Failed to replace file by tmp one: " << Utility::formatSyncPath(tmpPath)); replaceError = true; } @@ -356,7 +357,7 @@ bool DownloadJob::handleResponse(std::istream &is) { // Remove tmp file if (!removeTmpFile(tmpPath)) { - LOGW_WARN(_logger, L"Failed to remove tmp file: " << Utility::formatSyncPath(tmpPath).c_str()); + LOGW_WARN(_logger, L"Failed to remove tmp file: " << Utility::formatSyncPath(tmpPath)); } if (isAborted() || fetchCanceled) { @@ -381,12 +382,12 @@ bool DownloadJob::handleResponse(std::istream &is) { bool exists = false; if (!Utility::setFileDates(_localpath, std::make_optional(_creationTime), std::make_optional(_modtimeIn), isLink, exists)) { - LOGW_WARN(_logger, L"Error in Utility::setFileDates: " << Utility::formatSyncPath(_localpath).c_str()); + LOGW_WARN(_logger, L"Error in Utility::setFileDates: " << Utility::formatSyncPath(_localpath)); // Do nothing (remote file will be updated during the next sync) SentryHandler::instance()->captureMessage(SentryLevel::Warning, "DownloadJob::handleResponse", "Unable to set file dates"); } else if (!exists) { - LOGW_INFO(_logger, L"Item does not exist anymore. Restarting sync: " << Utility::formatSyncPath(_localpath).c_str()); + LOGW_INFO(_logger, L"Item does not exist anymore. Restarting sync: " << Utility::formatSyncPath(_localpath)); _exitCode = ExitCode::DataError; _exitCause = ExitCause::InvalidSnapshot; return false; @@ -397,19 +398,19 @@ bool DownloadJob::handleResponse(std::istream &is) { FileStat filestat; IoError ioError = IoError::Success; if (!IoHelper::getFileStat(_localpath, &filestat, ioError)) { - LOGW_WARN(_logger, L"Error in IoHelper::getFileStat: " << Utility::formatIoError(_localpath, ioError).c_str()); + LOGW_WARN(_logger, L"Error in IoHelper::getFileStat: " << Utility::formatIoError(_localpath, ioError)); _exitCode = ExitCode::SystemError; _exitCause = ExitCause::Unknown; return false; } if (ioError == IoError::NoSuchFileOrDirectory) { - LOGW_WARN(_logger, L"Item does not exist anymore: " << Utility::formatSyncPath(_localpath).c_str()); + LOGW_WARN(_logger, L"Item does not exist anymore: " << Utility::formatSyncPath(_localpath)); _exitCode = ExitCode::DataError; _exitCause = ExitCause::InvalidSnapshot; return false; } else if (ioError == IoError::AccessDenied) { - LOGW_WARN(_logger, L"Item misses search permission: " << Utility::formatSyncPath(_localpath).c_str()); + LOGW_WARN(_logger, L"Item misses search permission: " << Utility::formatSyncPath(_localpath)); _exitCode = ExitCode::SystemError; _exitCause = ExitCause::FileAccessError; return false; @@ -430,56 +431,56 @@ bool DownloadJob::createLink(const std::string &mimeType, const std::string &dat // Create symlink const auto targetPath = Str2Path(data); if (targetPath == _localpath) { - LOGW_DEBUG(_logger, L"Cannot create symlink on itself: " << Utility::formatSyncPath(_localpath).c_str()); + LOGW_DEBUG(_logger, L"Cannot create symlink on itself: " << Utility::formatSyncPath(_localpath)); return false; } - LOGW_DEBUG(_logger, L"Create symlink: " << Utility::formatSyncPath(targetPath).c_str() << L", " - << Utility::formatSyncPath(_localpath).c_str()); + LOGW_DEBUG(_logger, + L"Create symlink: " << Utility::formatSyncPath(targetPath) << L", " << Utility::formatSyncPath(_localpath)); bool isFolder = mimeType == mimeTypeSymlinkFolder; IoError ioError = IoError::Success; if (!IoHelper::createSymlink(targetPath, _localpath, isFolder, ioError)) { - LOGW_WARN(_logger, L"Failed to create symlink: " << Utility::formatIoError(targetPath, ioError).c_str()); + LOGW_WARN(_logger, L"Failed to create symlink: " << Utility::formatIoError(targetPath, ioError)); return false; } } else if (mimeType == mimeTypeHardlink) { // Unreachable code const auto targetPath = Str2Path(data); if (targetPath == _localpath) { - LOGW_DEBUG(_logger, L"Cannot create hardlink on itself: " << Utility::formatSyncPath(_localpath).c_str()); + LOGW_DEBUG(_logger, L"Cannot create hardlink on itself: " << Utility::formatSyncPath(_localpath)); return false; } - LOGW_DEBUG(_logger, L"Create hardlink: target " << Utility::formatSyncPath(targetPath).c_str() << L", " - << Utility::formatSyncPath(_localpath).c_str()); + LOGW_DEBUG(_logger, L"Create hardlink: target " << Utility::formatSyncPath(targetPath) << L", " + << Utility::formatSyncPath(_localpath)); std::error_code ec; std::filesystem::create_hard_link(targetPath, _localpath, ec); if (ec) { - LOGW_WARN(_logger, L"Failed to create hardlink: target " << Utility::formatSyncPath(targetPath).c_str() << L", " - << Utility::formatSyncPath(_localpath).c_str() << L", " - << Utility::formatStdError(ec).c_str()); + LOGW_WARN(_logger, L"Failed to create hardlink: target " << Utility::formatSyncPath(targetPath) << L", " + << Utility::formatSyncPath(_localpath) << L", " + << Utility::formatStdError(ec)); return false; } } else if (mimeType == mimeTypeJunction) { #if defined(_WIN32) - LOGW_DEBUG(_logger, L"Create junction: " << Utility::formatSyncPath(_localpath).c_str()); + LOGW_DEBUG(_logger, L"Create junction: " << Utility::formatSyncPath(_localpath)); IoError ioError = IoError::Success; if (!IoHelper::createJunction(data, _localpath, ioError)) { - LOGW_WARN(_logger, L"Failed to create junction: " << Utility::formatIoError(_localpath, ioError).c_str()); + LOGW_WARN(_logger, L"Failed to create junction: " << Utility::formatIoError(_localpath, ioError)); return false; } #endif } else if (mimeType == mimeTypeFinderAlias) { #if defined(__APPLE__) - LOGW_DEBUG(_logger, L"Create alias: " << Utility::formatSyncPath(_localpath).c_str()); + LOGW_DEBUG(_logger, L"Create alias: " << Utility::formatSyncPath(_localpath)); IoError ioError = IoError::Success; if (!IoHelper::createAlias(data, _localpath, ioError)) { const std::wstring message = Utility::s2ws(IoHelper::ioError2StdString(ioError)); - LOGW_WARN(_logger, L"Failed to create alias: " << Utility::formatIoError(_localpath, ioError).c_str()); + LOGW_WARN(_logger, L"Failed to create alias: " << Utility::formatIoError(_localpath, ioError)); return false; } @@ -540,10 +541,10 @@ bool DownloadJob::moveTmpFile(const SyncPath &tmpPath, bool &restartSync) { // Retry retry = true; Utility::msleep(10); - LOGW_DEBUG(_logger, L"Retrying to move downloaded file: " << Utility::formatSyncPath(_localpath).c_str()); + LOGW_DEBUG(_logger, L"Retrying to move downloaded file: " << Utility::formatSyncPath(_localpath)); counter--; } else { - LOGW_WARN(_logger, L"Failed to rename: " << Utility::formatStdError(_localpath, ec).c_str()); + LOGW_WARN(_logger, L"Failed to rename: " << Utility::formatStdError(_localpath, ec)); return false; } } @@ -556,8 +557,8 @@ bool DownloadJob::moveTmpFile(const SyncPath &tmpPath, bool &restartSync) { bool exists = false; IoError ioError = IoError::Success; if (!IoHelper::checkIfPathExists(_localpath.parent_path(), exists, ioError)) { - LOGW_WARN(_logger, L"Error in IoHelper::checkIfPathExists: " - << Utility::formatIoError(_localpath.parent_path(), ioError).c_str()); + LOGW_WARN(_logger, + L"Error in IoHelper::checkIfPathExists: " << Utility::formatIoError(_localpath.parent_path(), ioError)); _exitCode = ExitCode::SystemError; _exitCause = ExitCause::Unknown; return false; @@ -570,12 +571,12 @@ bool DownloadJob::moveTmpFile(const SyncPath &tmpPath, bool &restartSync) { } if (!exists) { - LOGW_INFO(_logger, L"Parent of item does not exist anymore: " << Utility::formatStdError(_localpath, ec).c_str()); + LOGW_INFO(_logger, L"Parent of item does not exist anymore: " << Utility::formatStdError(_localpath, ec)); restartSync = true; return true; } - LOGW_WARN(_logger, L"Failed to rename: " << Utility::formatStdError(_localpath, ec).c_str()); + LOGW_WARN(_logger, L"Failed to rename: " << Utility::formatStdError(_localpath, ec)); return false; } #ifdef _WIN32 From 653924f421e908ef021f225706dd1349c5d52ab5 Mon Sep 17 00:00:00 2001 From: Christophe Larchier Date: Tue, 5 Nov 2024 08:36:01 +0100 Subject: [PATCH 015/178] Fix build-ci script --- infomaniak-build-tools/macos/build-ci.sh | 31 +++++++++--------------- 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/infomaniak-build-tools/macos/build-ci.sh b/infomaniak-build-tools/macos/build-ci.sh index 26247e6a3..a9e7f1187 100644 --- a/infomaniak-build-tools/macos/build-ci.sh +++ b/infomaniak-build-tools/macos/build-ci.sh @@ -40,15 +40,17 @@ export PATH=$QTDIR/bin:$PATH # Set Infomaniak Theme KDRIVE_DIR="$SRCDIR/infomaniak" -# Path to Sparkle installation -SPARKLE_DIR="$HOME/Library/Frameworks" +# Set build dir +BUILDDIR="$PWD/build-macos/client" + +# Set install dir +INSTALLDIR="$PWD/build-macos/client/install" -# Prepare directory +# Create install dir if needed mkdir -p build-macos/client -mkdir -p build-macos/install -INSTALLDIR="$PWD/build-macos/install" -BUILDDIR="$PWD/build-macos/client" +mkdir -p build-macos/client/install +# Backup the existing .app if there is one if [ -d "$INSTALLDIR/$APPNAME-old.app" ]; then rm -rf "$INSTALLDIR/$APPNAME-old.app" fi @@ -57,40 +59,31 @@ if [ -d "$INSTALLDIR/$APPNAME.app" ]; then cp -a "$INSTALLDIR/$APPNAME.app" "$INSTALLDIR/$APPNAME-old.app" fi -pushd "$BUILDDIR" - +# Prepare additional cmake arguments if [ -z "$KDRIVE_VERSION_BUILD" ]; then KDRIVE_VERSION_BUILD="$(date +%Y%m%d)" fi -# Prepare cmake arguments CMAKE_PARAMS=(-DKDRIVE_VERSION_BUILD="$KDRIVE_VERSION_BUILD") if [ -n "$TEAM_IDENTIFIER" -a -n "$SIGN_IDENTITY" ]; then CMAKE_PARAMS+=(-DSOCKETAPI_TEAM_IDENTIFIER_PREFIX="$TEAM_IDENTIFIER.") fi -if [ -n "$APPLICATION_SERVER_URL" ]; then - CMAKE_PARAMS+=(-DAPPLICATION_SERVER_URL="$APPLICATION_SERVER_URL") -fi +# Configure +pushd "$BUILDDIR" # Configure infomaniakdrive cmake \ -DCMAKE_OSX_DEPLOYMENT_TARGET="$MACOSX_DEPLOYMENT_TARGET" \ -DCMAKE_INSTALL_PREFIX="$INSTALLDIR" \ -DCMAKE_BUILD_TYPE=Release \ - -DSPARKLE_LIBRARY="$SPARKLE_DIR/Sparkle.framework" \ - -DOPENSSL_ROOT_DIR="/usr/local/" \ - -DOPENSSL_INCLUDE_DIR="/usr/local/include/" \ - -DOPENSSL_CRYPTO_LIBRARY="/usr/local/lib/libcrypto.dylib" \ - -DOPENSSL_SSL_LIBRARY="/usr/local/lib/libssl.dylib" \ -DKDRIVE_THEME_DIR="$KDRIVE_DIR" \ - -DQTDIR="$QTDIR" \ -DBUILD_UNIT_TESTS=1 \ "${CMAKE_PARAMS[@]}" \ "$SRCDIR" # Build kDrive sources -make -j6 install +make -j6 all install popd From aff4539b2c5d60659a82c077192b5898a9cf26a2 Mon Sep 17 00:00:00 2001 From: Christophe Larchier Date: Tue, 5 Nov 2024 10:50:23 +0100 Subject: [PATCH 016/178] Merge develop --- .../cfapi/FileExplorerExtensionPackage/Package.appxmanifest | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extensions/windows/cfapi/FileExplorerExtensionPackage/Package.appxmanifest b/extensions/windows/cfapi/FileExplorerExtensionPackage/Package.appxmanifest index 24cb610c2..c0dab27bc 100644 --- a/extensions/windows/cfapi/FileExplorerExtensionPackage/Package.appxmanifest +++ b/extensions/windows/cfapi/FileExplorerExtensionPackage/Package.appxmanifest @@ -12,8 +12,8 @@ + Publisher="CN=Infomaniak Network SA, O=Infomaniak Network SA, S=Genève, C=CH, OID.2.5.4.15=Private Organization, OID.1.3.6.1.4.1.311.60.2.1.3=CH, SERIALNUMBER=CHE-103.167.648" + Version="3.6.7.0" /> kDrive Windows Explorer Extension Package From 9668aefc745a0ab7b03879bd5b495b168f587371 Mon Sep 17 00:00:00 2001 From: Christophe Larchier Date: Tue, 5 Nov 2024 11:32:51 +0100 Subject: [PATCH 017/178] Build Windows extension on CI --- .github/workflows/windows.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 09907c7ea..70e655dbd 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -55,7 +55,7 @@ jobs: set COVFILE=%cd%\src\test.cov call "cov01.exe" -1 - powershell ./infomaniak-build-tools/windows/build-drive.ps1 -ci + powershell ./infomaniak-build-tools/windows/build-drive.ps1 -ci -ext shell: cmd - name: Execute tests From 4ea039c722e34ef5063ba9fe5161e486a18bbe37 Mon Sep 17 00:00:00 2001 From: Christophe Larchier Date: Tue, 5 Nov 2024 12:03:07 +0100 Subject: [PATCH 018/178] Revert "Build Windows extension on CI" This reverts commit 9668aefc745a0ab7b03879bd5b495b168f587371. --- .github/workflows/windows.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 70e655dbd..09907c7ea 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -55,7 +55,7 @@ jobs: set COVFILE=%cd%\src\test.cov call "cov01.exe" -1 - powershell ./infomaniak-build-tools/windows/build-drive.ps1 -ci -ext + powershell ./infomaniak-build-tools/windows/build-drive.ps1 -ci shell: cmd - name: Execute tests From a38dee098e1d2bfbb04dd7e4bcb21441018cbcdf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Kunz?= Date: Tue, 5 Nov 2024 13:31:53 +0100 Subject: [PATCH 019/178] KDESKTOP-1345 - release notes first draft --- infomaniak-build-tools/kDrive-template.html | 30 ++++++++---- .../kDrive-3.6.7.20241105-linux-de.html | 44 ++++++++++++++++++ .../kDrive-3.6.7.20241105-linux-en.html | 44 ++++++++++++++++++ .../kDrive-3.6.7.20241105-linux-es.html | 44 ++++++++++++++++++ .../kDrive-3.6.7.20241105-linux-fr.html | 44 ++++++++++++++++++ .../kDrive-3.6.7.20241105-linux-it.html | 44 ++++++++++++++++++ .../kDrive-3.6.7.20241105-macos-de.html | 44 ++++++++++++++++++ .../kDrive-3.6.7.20241105-macos-en.html | 44 ++++++++++++++++++ .../kDrive-3.6.7.20241105-macos-es.html | 44 ++++++++++++++++++ .../kDrive-3.6.7.20241105-macos-fr.html | 44 ++++++++++++++++++ .../kDrive-3.6.7.20241105-macos-it.html | 44 ++++++++++++++++++ .../kDrive-3.6.7.20241105-win-de.html | 46 +++++++++++++++++++ .../kDrive-3.6.7.20241105-win-en.html | 46 +++++++++++++++++++ .../kDrive-3.6.7.20241105-win-es.html | 46 +++++++++++++++++++ .../kDrive-3.6.7.20241105-win-fr.html | 46 +++++++++++++++++++ .../kDrive-3.6.7.20241105-win-it.html | 46 +++++++++++++++++++ 16 files changed, 690 insertions(+), 10 deletions(-) create mode 100644 release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-linux-de.html create mode 100644 release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-linux-en.html create mode 100644 release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-linux-es.html create mode 100644 release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-linux-fr.html create mode 100644 release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-linux-it.html create mode 100644 release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-macos-de.html create mode 100644 release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-macos-en.html create mode 100644 release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-macos-es.html create mode 100644 release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-macos-fr.html create mode 100644 release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-macos-it.html create mode 100644 release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-win-de.html create mode 100644 release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-win-en.html create mode 100644 release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-win-es.html create mode 100644 release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-win-fr.html create mode 100644 release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-win-it.html diff --git a/infomaniak-build-tools/kDrive-template.html b/infomaniak-build-tools/kDrive-template.html index a32fd4f46..3d9c6fb15 100644 --- a/infomaniak-build-tools/kDrive-template.html +++ b/infomaniak-build-tools/kDrive-template.html @@ -19,18 +19,28 @@ -

Release notes - kDrive 3.6.6

+

Release notes - kDrive 3.6.7

+

New features

+
    +
  • Change the update mechanism to allow progressive delivery of new version
  • +

Bug fixes

    -
  • Fixed a sync issue occurring on files whose name contains a special character
  • -
  • Corrected behaviour in the event of disconnection
  • -
  • Fixed issue where an empty file list is retrieved in case of poor network connection
  • -
  • Fixed an issue causing many conflicting files when using specific software
  • -
  • Fixed a sync issue generating infinite loop
  • -
  • Windows - Code optimization to reduce duration of steps 1 and 2
  • -
  • macOS - Fixed unwanted popup message on session logout
  • -
  • Fixed several crashes related to logging
  • -
  • Fixed several crashes related to sync pausing
  • +
  • Fixed new file wrongly downloaded in LiteSync mode
  • +
  • Fixed missing share links entries in contextual menu
  • +
  • Consolidation of error management during the propagation step
  • +
  • Do not block application startup if local sync folder is missing
  • +
  • Add "*.tmp" files to default exclusion templates
  • +
  • Fixed wrongly blacklisted files
  • +
  • Fixed broken sync on FAT systems
  • +
  • Fixed startup issue in case of unknown proxy type
  • +
  • Fixed migration issues
  • +
  • Fixed status in case of abort during upload
  • +
  • Exclude files/folders with name length above 255 characters
  • +
  • Win - Fixed issue on symkinks and junctions
  • +
  • Fixed CSV parsing error leading to incomplete remote snapshot
  • +
  • Improve handling of access denied errors
  • +
  • Win - Improve error handling if a move to trash operation fails
\ No newline at end of file diff --git a/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-linux-de.html b/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-linux-de.html new file mode 100644 index 000000000..e7c5a2524 --- /dev/null +++ b/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-linux-de.html @@ -0,0 +1,44 @@ + + + + + +

Versionshinweise - kDrive 3.6.7

+

Neue Funktionen

+
    +
  • Änderung des Aktualisierungsmechanismus, um die schrittweise Bereitstellung neuer Versionen zu ermöglichen
  • +
+

Fehlerbehebungen

+
    +
  • Neue Datei wurde im LiteSync-Modus fälschlicherweise heruntergeladen
  • +
  • Fehlende Einträge für Freigabelinks im Kontextmenü behoben
  • +
  • Konsolidierung des Fehlermanagements während der Ausbreitungsphase
  • +
  • Start der Anwendung nicht blockieren, wenn der lokale Synchronisierungsordner fehlt
  • +
  • Hinzufügen von "*.tmp"-Dateien zu Standard-Ausschlussvorlagen
  • +
  • Falsch auf die schwarze Liste gesetzte Dateien korrigiert
  • +
  • Fehlerhafte Synchronisierung auf FAT-Systemen behoben
  • +
  • Startproblem im Falle eines unbekannten Proxy-Typs behoben
  • +
  • Behobene Migrationsprobleme
  • +
  • Status bei Abbruch während des Uploads korrigiert
  • +
  • Dateien/Ordner mit einer Namenslänge von mehr als 255 Zeichen ausschließen
  • +
  • Fehler bei der CSV-Analyse behoben, der zu einem unvollständigen Remote-Snapshot führte
  • +
  • Verbesserte Behandlung von Fehlern bei verweigertem Zugriff
  • +
+ + \ No newline at end of file diff --git a/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-linux-en.html b/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-linux-en.html new file mode 100644 index 000000000..1199df78d --- /dev/null +++ b/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-linux-en.html @@ -0,0 +1,44 @@ + + + + + +

Release notes - kDrive 3.6.7

+

New features

+
    +
  • Change the update mechanism to allow progressive delivery of new version
  • +
+

Bug fixes

+
    +
  • Fixed new file wrongly downloaded in LiteSync mode
  • +
  • Fixed missing share links entries in contextual menu
  • +
  • Consolidation of error management during the propagation step
  • +
  • Do not block application startup if local sync folder is missing
  • +
  • Add "*.tmp" files to default exclusion templates
  • +
  • Fixed wrongly blacklisted files
  • +
  • Fixed broken sync on FAT systems
  • +
  • Fixed startup issue in case of unknown proxy type
  • +
  • Fixed migration issues
  • +
  • Fixed status in case of abort during upload
  • +
  • Exclude files/folders with name length above 255 characters
  • +
  • Fixed CSV parsing error leading to incomplete remote snapshot
  • +
  • Improve handling of access denied errors
  • +
+ + \ No newline at end of file diff --git a/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-linux-es.html b/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-linux-es.html new file mode 100644 index 000000000..a11f4885a --- /dev/null +++ b/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-linux-es.html @@ -0,0 +1,44 @@ + + + + + +

Notas de la versión - kDrive 3.6.7

+

Novedades

+
    +
  • Cambiar el mecanismo de actualización para permitir la entrega progresiva de la nueva versión
  • +
+

Corrección de errores

+
    +
  • Corregido el error de descarga de un nuevo archivo en el modo LiteSync
  • +
  • Se ha corregido la falta de entradas de enlaces compartidos en el menú contextual.
  • +
  • Consolidación de la gestión de errores durante la etapa de propagación
  • +
  • No bloquear el inicio de la aplicación si falta la carpeta de sincronización local
  • +
  • Añadir archivos "*.tmp" a las plantillas de exclusión por defecto
  • +
  • Corrección de archivos incluidos erróneamente en la lista negra
  • +
  • Corregida la sincronización rota en sistemas FAT
  • +
  • Se ha corregido un problema de inicio en caso de tipo de proxy desconocido.
  • +
  • Solucionados los problemas de migración
  • +
  • Corregido el estado en caso de aborto durante la carga
  • +
  • Excluir archivos/carpetas cuyo nombre tenga más de 255 caracteres
  • +
  • Se ha corregido un error de análisis CSV que provocaba una instantánea remota incompleta.
  • +
  • Mejorar la gestión de los errores de acceso denegado
  • +
+ + \ No newline at end of file diff --git a/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-linux-fr.html b/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-linux-fr.html new file mode 100644 index 000000000..50ff70ef9 --- /dev/null +++ b/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-linux-fr.html @@ -0,0 +1,44 @@ + + + + + +

Notes de version - kDrive 3.6.7

+

Nouvelles fonctionnalités

+
    +
  • Modifier le mécanisme de mise à jour pour permettre la livraison progressive de la nouvelle version
  • +
+

Correction de bugs

+
    +
  • Correction d'un nouveau fichier mal téléchargé en mode LiteSync
  • +
  • Correction de l'absence de liens de partage dans le menu contextuel
  • +
  • Consolidation de la gestion des erreurs lors de l'étape de propagation
  • +
  • Ne pas bloquer le démarrage de l'application si le dossier de synchronisation local est manquant
  • +
  • Ajouter les fichiers "*.tmp" aux modèles d'exclusion par défaut
  • +
  • Correction des fichiers mis sur liste noire à tort
  • +
  • Correction de la synchronisation interrompue sur les systèmes FAT
  • +
  • Correction du problème de démarrage en cas de type de proxy inconnu
  • +
  • Correction des problèmes de migration
  • +
  • Correction de l'état en cas d'interruption du téléchargement
  • +
  • Exclure les fichiers/dossiers dont le nom comporte plus de 255 caractères.
  • +
  • Correction d'une erreur d'analyse CSV entraînant un instantané à distance incomplet
  • +
  • Amélioration de la gestion des erreurs de refus d'accès
  • +
+ + \ No newline at end of file diff --git a/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-linux-it.html b/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-linux-it.html new file mode 100644 index 000000000..3a59e94bf --- /dev/null +++ b/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-linux-it.html @@ -0,0 +1,44 @@ + + + + + +

Note di rilascio - kDrive 3.6.7

+

Nuove caratteristiche

+
    +
  • Modificare il meccanismo di aggiornamento per consentire la consegna progressiva della nuova versione.
  • +
+

Correzioni di bug

+
    +
  • Corretto il nuovo file scaricato erroneamente in modalità LiteSync
  • +
  • Correzione delle voci mancanti dei link di condivisione nel menu contestuale
  • +
  • Consolidamento della gestione degli errori durante la fase di propagazione
  • +
  • Non bloccare l'avvio dell'applicazione se manca la cartella di sincronizzazione locale
  • +
  • Aggiungere i file "*.tmp" ai modelli di esclusione predefiniti
  • +
  • Corretti i file erroneamente inseriti nella lista nera
  • +
  • Corretta la sincronizzazione interrotta sui sistemi FAT
  • +
  • Corretto il problema di avvio in caso di tipo di proxy sconosciuto
  • +
  • Problemi di migrazione corretti
  • +
  • Corretto lo stato in caso di interruzione del caricamento
  • +
  • Escludete i file/cartelle con nomi di lunghezza superiore a 255 caratteri.
  • +
  • Corretto l'errore di parsing CSV che portava a un'istantanea remota incompleta.
  • +
  • Migliorare la gestione degli errori di accesso negato
  • +
+ + \ No newline at end of file diff --git a/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-macos-de.html b/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-macos-de.html new file mode 100644 index 000000000..e7c5a2524 --- /dev/null +++ b/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-macos-de.html @@ -0,0 +1,44 @@ + + + + + +

Versionshinweise - kDrive 3.6.7

+

Neue Funktionen

+
    +
  • Änderung des Aktualisierungsmechanismus, um die schrittweise Bereitstellung neuer Versionen zu ermöglichen
  • +
+

Fehlerbehebungen

+
    +
  • Neue Datei wurde im LiteSync-Modus fälschlicherweise heruntergeladen
  • +
  • Fehlende Einträge für Freigabelinks im Kontextmenü behoben
  • +
  • Konsolidierung des Fehlermanagements während der Ausbreitungsphase
  • +
  • Start der Anwendung nicht blockieren, wenn der lokale Synchronisierungsordner fehlt
  • +
  • Hinzufügen von "*.tmp"-Dateien zu Standard-Ausschlussvorlagen
  • +
  • Falsch auf die schwarze Liste gesetzte Dateien korrigiert
  • +
  • Fehlerhafte Synchronisierung auf FAT-Systemen behoben
  • +
  • Startproblem im Falle eines unbekannten Proxy-Typs behoben
  • +
  • Behobene Migrationsprobleme
  • +
  • Status bei Abbruch während des Uploads korrigiert
  • +
  • Dateien/Ordner mit einer Namenslänge von mehr als 255 Zeichen ausschließen
  • +
  • Fehler bei der CSV-Analyse behoben, der zu einem unvollständigen Remote-Snapshot führte
  • +
  • Verbesserte Behandlung von Fehlern bei verweigertem Zugriff
  • +
+ + \ No newline at end of file diff --git a/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-macos-en.html b/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-macos-en.html new file mode 100644 index 000000000..1199df78d --- /dev/null +++ b/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-macos-en.html @@ -0,0 +1,44 @@ + + + + + +

Release notes - kDrive 3.6.7

+

New features

+
    +
  • Change the update mechanism to allow progressive delivery of new version
  • +
+

Bug fixes

+
    +
  • Fixed new file wrongly downloaded in LiteSync mode
  • +
  • Fixed missing share links entries in contextual menu
  • +
  • Consolidation of error management during the propagation step
  • +
  • Do not block application startup if local sync folder is missing
  • +
  • Add "*.tmp" files to default exclusion templates
  • +
  • Fixed wrongly blacklisted files
  • +
  • Fixed broken sync on FAT systems
  • +
  • Fixed startup issue in case of unknown proxy type
  • +
  • Fixed migration issues
  • +
  • Fixed status in case of abort during upload
  • +
  • Exclude files/folders with name length above 255 characters
  • +
  • Fixed CSV parsing error leading to incomplete remote snapshot
  • +
  • Improve handling of access denied errors
  • +
+ + \ No newline at end of file diff --git a/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-macos-es.html b/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-macos-es.html new file mode 100644 index 000000000..a11f4885a --- /dev/null +++ b/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-macos-es.html @@ -0,0 +1,44 @@ + + + + + +

Notas de la versión - kDrive 3.6.7

+

Novedades

+
    +
  • Cambiar el mecanismo de actualización para permitir la entrega progresiva de la nueva versión
  • +
+

Corrección de errores

+
    +
  • Corregido el error de descarga de un nuevo archivo en el modo LiteSync
  • +
  • Se ha corregido la falta de entradas de enlaces compartidos en el menú contextual.
  • +
  • Consolidación de la gestión de errores durante la etapa de propagación
  • +
  • No bloquear el inicio de la aplicación si falta la carpeta de sincronización local
  • +
  • Añadir archivos "*.tmp" a las plantillas de exclusión por defecto
  • +
  • Corrección de archivos incluidos erróneamente en la lista negra
  • +
  • Corregida la sincronización rota en sistemas FAT
  • +
  • Se ha corregido un problema de inicio en caso de tipo de proxy desconocido.
  • +
  • Solucionados los problemas de migración
  • +
  • Corregido el estado en caso de aborto durante la carga
  • +
  • Excluir archivos/carpetas cuyo nombre tenga más de 255 caracteres
  • +
  • Se ha corregido un error de análisis CSV que provocaba una instantánea remota incompleta.
  • +
  • Mejorar la gestión de los errores de acceso denegado
  • +
+ + \ No newline at end of file diff --git a/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-macos-fr.html b/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-macos-fr.html new file mode 100644 index 000000000..50ff70ef9 --- /dev/null +++ b/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-macos-fr.html @@ -0,0 +1,44 @@ + + + + + +

Notes de version - kDrive 3.6.7

+

Nouvelles fonctionnalités

+
    +
  • Modifier le mécanisme de mise à jour pour permettre la livraison progressive de la nouvelle version
  • +
+

Correction de bugs

+
    +
  • Correction d'un nouveau fichier mal téléchargé en mode LiteSync
  • +
  • Correction de l'absence de liens de partage dans le menu contextuel
  • +
  • Consolidation de la gestion des erreurs lors de l'étape de propagation
  • +
  • Ne pas bloquer le démarrage de l'application si le dossier de synchronisation local est manquant
  • +
  • Ajouter les fichiers "*.tmp" aux modèles d'exclusion par défaut
  • +
  • Correction des fichiers mis sur liste noire à tort
  • +
  • Correction de la synchronisation interrompue sur les systèmes FAT
  • +
  • Correction du problème de démarrage en cas de type de proxy inconnu
  • +
  • Correction des problèmes de migration
  • +
  • Correction de l'état en cas d'interruption du téléchargement
  • +
  • Exclure les fichiers/dossiers dont le nom comporte plus de 255 caractères.
  • +
  • Correction d'une erreur d'analyse CSV entraînant un instantané à distance incomplet
  • +
  • Amélioration de la gestion des erreurs de refus d'accès
  • +
+ + \ No newline at end of file diff --git a/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-macos-it.html b/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-macos-it.html new file mode 100644 index 000000000..3a59e94bf --- /dev/null +++ b/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-macos-it.html @@ -0,0 +1,44 @@ + + + + + +

Note di rilascio - kDrive 3.6.7

+

Nuove caratteristiche

+
    +
  • Modificare il meccanismo di aggiornamento per consentire la consegna progressiva della nuova versione.
  • +
+

Correzioni di bug

+
    +
  • Corretto il nuovo file scaricato erroneamente in modalità LiteSync
  • +
  • Correzione delle voci mancanti dei link di condivisione nel menu contestuale
  • +
  • Consolidamento della gestione degli errori durante la fase di propagazione
  • +
  • Non bloccare l'avvio dell'applicazione se manca la cartella di sincronizzazione locale
  • +
  • Aggiungere i file "*.tmp" ai modelli di esclusione predefiniti
  • +
  • Corretti i file erroneamente inseriti nella lista nera
  • +
  • Corretta la sincronizzazione interrotta sui sistemi FAT
  • +
  • Corretto il problema di avvio in caso di tipo di proxy sconosciuto
  • +
  • Problemi di migrazione corretti
  • +
  • Corretto lo stato in caso di interruzione del caricamento
  • +
  • Escludete i file/cartelle con nomi di lunghezza superiore a 255 caratteri.
  • +
  • Corretto l'errore di parsing CSV che portava a un'istantanea remota incompleta.
  • +
  • Migliorare la gestione degli errori di accesso negato
  • +
+ + \ No newline at end of file diff --git a/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-win-de.html b/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-win-de.html new file mode 100644 index 000000000..ae8878484 --- /dev/null +++ b/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-win-de.html @@ -0,0 +1,46 @@ + + + + + +

Versionshinweise - kDrive 3.6.7

+

Neue Funktionen

+
    +
  • Änderung des Aktualisierungsmechanismus, um die schrittweise Bereitstellung neuer Versionen zu ermöglichen
  • +
+

Fehlerbehebungen

+
    +
  • Neue Datei wurde im LiteSync-Modus fälschlicherweise heruntergeladen
  • +
  • Fehlende Einträge für Freigabelinks im Kontextmenü behoben
  • +
  • Konsolidierung des Fehlermanagements während der Ausbreitungsphase
  • +
  • Start der Anwendung nicht blockieren, wenn der lokale Synchronisierungsordner fehlt
  • +
  • Hinzufügen von "*.tmp"-Dateien zu Standard-Ausschlussvorlagen
  • +
  • Falsch auf die schwarze Liste gesetzte Dateien korrigiert
  • +
  • Fehlerhafte Synchronisierung auf FAT-Systemen behoben
  • +
  • Startproblem im Falle eines unbekannten Proxy-Typs behoben
  • +
  • Behobene Migrationsprobleme
  • +
  • Status bei Abbruch während des Uploads korrigiert
  • +
  • Dateien/Ordner mit einer Namenslänge von mehr als 255 Zeichen ausschließen
  • +
  • Problem mit Symkinks und Abzweigungen behoben
  • +
  • Fehler bei der CSV-Analyse behoben, der zu einem unvollständigen Remote-Snapshot führte
  • +
  • Verbesserte Behandlung von Fehlern bei verweigertem Zugriff
  • +
  • Verbesserte Fehlerbehandlung bei fehlgeschlagenem Verschieben in den Papierkorb
  • +
+ + \ No newline at end of file diff --git a/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-win-en.html b/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-win-en.html new file mode 100644 index 000000000..e56c42f06 --- /dev/null +++ b/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-win-en.html @@ -0,0 +1,46 @@ + + + + + +

Release notes - kDrive 3.6.7

+

New features

+
    +
  • Change the update mechanism to allow progressive delivery of new version
  • +
+

Bug fixes

+
    +
  • Fixed new file wrongly downloaded in LiteSync mode
  • +
  • Fixed missing share links entries in contextual menu
  • +
  • Consolidation of error management during the propagation step
  • +
  • Do not block application startup if local sync folder is missing
  • +
  • Add "*.tmp" files to default exclusion templates
  • +
  • Fixed wrongly blacklisted files
  • +
  • Fixed broken sync on FAT systems
  • +
  • Fixed startup issue in case of unknown proxy type
  • +
  • Fixed migration issues
  • +
  • Fixed status in case of abort during upload
  • +
  • Exclude files/folders with name length above 255 characters
  • +
  • Fixed issue on symkinks and junctions
  • +
  • Fixed CSV parsing error leading to incomplete remote snapshot
  • +
  • Improve handling of access denied errors
  • +
  • Improve error handling if a move to trash operation fails
  • +
+ + \ No newline at end of file diff --git a/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-win-es.html b/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-win-es.html new file mode 100644 index 000000000..d4795f005 --- /dev/null +++ b/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-win-es.html @@ -0,0 +1,46 @@ + + + + + +

Notas de la versión - kDrive 3.6.7

+

Novedades

+
    +
  • Cambiar el mecanismo de actualización para permitir la entrega progresiva de la nueva versión
  • +
+

Corrección de errores

+
    +
  • Corregido el error de descarga de un nuevo archivo en el modo LiteSync
  • +
  • Se ha corregido la falta de entradas de enlaces compartidos en el menú contextual.
  • +
  • Consolidación de la gestión de errores durante la etapa de propagación
  • +
  • No bloquear el inicio de la aplicación si falta la carpeta de sincronización local
  • +
  • Añadir archivos "*.tmp" a las plantillas de exclusión por defecto
  • +
  • Corrección de archivos incluidos erróneamente en la lista negra
  • +
  • Corregida la sincronización rota en sistemas FAT
  • +
  • Se ha corregido un problema de inicio en caso de tipo de proxy desconocido.
  • +
  • Solucionados los problemas de migración
  • +
  • Corregido el estado en caso de aborto durante la carga
  • +
  • Excluir archivos/carpetas cuyo nombre tenga más de 255 caracteres
  • +
  • Se ha solucionado un problema con los enlaces simbólicos y los cruces.
  • +
  • Se ha corregido un error de análisis CSV que provocaba una instantánea remota incompleta.
  • +
  • Mejorar la gestión de los errores de acceso denegado
  • +
  • Mejorar la gestión de errores si falla una operación de mover a la papelera
  • +
+ + \ No newline at end of file diff --git a/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-win-fr.html b/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-win-fr.html new file mode 100644 index 000000000..1a737d865 --- /dev/null +++ b/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-win-fr.html @@ -0,0 +1,46 @@ + + + + + +

Notes de version - kDrive 3.6.7

+

Nouvelles fonctionnalités

+
    +
  • Modifier le mécanisme de mise à jour pour permettre la livraison progressive de la nouvelle version
  • +
+

Correction de bugs

+
    +
  • Correction d'un nouveau fichier mal téléchargé en mode LiteSync
  • +
  • Correction de l'absence de liens de partage dans le menu contextuel
  • +
  • Consolidation de la gestion des erreurs lors de l'étape de propagation
  • +
  • Ne pas bloquer le démarrage de l'application si le dossier de synchronisation local est manquant
  • +
  • Ajouter les fichiers "*.tmp" aux modèles d'exclusion par défaut
  • +
  • Correction des fichiers mis sur liste noire à tort
  • +
  • Correction de la synchronisation interrompue sur les systèmes FAT
  • +
  • Correction du problème de démarrage en cas de type de proxy inconnu
  • +
  • Correction des problèmes de migration
  • +
  • Correction de l'état en cas d'interruption du téléchargement
  • +
  • Exclure les fichiers/dossiers dont le nom comporte plus de 255 caractères.
  • +
  • Correction d'un problème sur les liens et les jonctions de systèmes
  • +
  • Correction d'une erreur d'analyse CSV entraînant un instantané à distance incomplet
  • +
  • Amélioration de la gestion des erreurs de refus d'accès
  • +
  • Amélioration de la gestion des erreurs en cas d'échec d'une opération de déplacement vers la corbeille
  • +
+ + \ No newline at end of file diff --git a/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-win-it.html b/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-win-it.html new file mode 100644 index 000000000..594f9c577 --- /dev/null +++ b/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-win-it.html @@ -0,0 +1,46 @@ + + + + + +

Note di rilascio - kDrive 3.6.7

+

Nuove caratteristiche

+
    +
  • Modificare il meccanismo di aggiornamento per consentire la consegna progressiva della nuova versione.
  • +
+

Correzioni di bug

+
    +
  • Corretto il nuovo file scaricato erroneamente in modalità LiteSync
  • +
  • Correzione delle voci mancanti dei link di condivisione nel menu contestuale
  • +
  • Consolidamento della gestione degli errori durante la fase di propagazione
  • +
  • Non bloccare l'avvio dell'applicazione se manca la cartella di sincronizzazione locale
  • +
  • Aggiungere i file "*.tmp" ai modelli di esclusione predefiniti
  • +
  • Corretti i file erroneamente inseriti nella lista nera
  • +
  • Corretta la sincronizzazione interrotta sui sistemi FAT
  • +
  • Corretto il problema di avvio in caso di tipo di proxy sconosciuto
  • +
  • Problemi di migrazione corretti
  • +
  • Corretto lo stato in caso di interruzione del caricamento
  • +
  • Escludete i file/cartelle con nomi di lunghezza superiore a 255 caratteri.
  • +
  • Corretto il problema dei collegamenti simbolici e delle giunzioni
  • +
  • Corretto l'errore di parsing CSV che portava a un'istantanea remota incompleta.
  • +
  • Migliorare la gestione degli errori di accesso negato
  • +
  • Migliorare la gestione degli errori se un'operazione di spostamento nel cestino fallisce
  • +
+ + \ No newline at end of file From 5c38bfe91cac10e42afef0a89770360495a5f887 Mon Sep 17 00:00:00 2001 From: Christophe Larchier Date: Tue, 5 Nov 2024 14:18:41 +0100 Subject: [PATCH 020/178] Fix Windows build --- test/server/CMakeLists.txt | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/test/server/CMakeLists.txt b/test/server/CMakeLists.txt index 5dbb9ba60..c559cd14e 100644 --- a/test/server/CMakeLists.txt +++ b/test/server/CMakeLists.txt @@ -101,14 +101,8 @@ if (APPLE) "${libsyncengine_NAME}_vfs_mac" "${updater_DEPS}") elseif (WIN32) - set(CMAKE_FIND_LIBRARY_SUFFIXES .lib) - find_library(LIBSYNCENGINE_VFS_STATIC_LIBRARY - NAMES "${libsyncengine_NAME}_vfs_win" - PATHS "${CMAKE_BINARY_DIR}/src/server/vfs/win" - NO_DEFAULT_PATH - NO_CACHE) target_link_libraries(${testserver_NAME} - "${LIBSYNCENGINE_VFS_STATIC_LIBRARY}") + "${CMAKE_INSTALL_PREFIX}/src/server/vfs/win/${libsyncengine_NAME}_vfs_win.lib") endif() # Install From ee84a9ed3e8c9765067d576481598f818eb5669c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Kunz?= Date: Tue, 5 Nov 2024 14:30:59 +0100 Subject: [PATCH 021/178] KDESKTOP-1345 - Address PR comments --- infomaniak-build-tools/kDrive-template.html | 9 ++++----- .../kDrive-3.6.7.20241105-linux-de.html | 6 +++--- .../kDrive-3.6.7.20241105-linux-en.html | 8 ++++---- .../kDrive-3.6.7.20241105-linux-es.html | 8 ++++---- .../kDrive-3.6.7.20241105-linux-fr.html | 6 +++--- .../kDrive-3.6.7.20241105-linux-it.html | 8 ++++---- .../kDrive-3.6.7.20241105-macos-de.html | 6 +++--- .../kDrive-3.6.7.20241105-macos-en.html | 8 ++++---- .../kDrive-3.6.7.20241105-macos-es.html | 8 ++++---- .../kDrive-3.6.7.20241105-macos-fr.html | 6 +++--- .../kDrive-3.6.7.20241105-macos-it.html | 8 ++++---- .../kDrive-3.6.7.20241105-win-de.html | 7 +++---- .../kDrive-3.6.7.20241105-win-en.html | 9 ++++----- .../kDrive-3.6.7.20241105-win-es.html | 9 ++++----- .../kDrive-3.6.7.20241105-win-fr.html | 7 +++---- .../kDrive-3.6.7.20241105-win-it.html | 9 ++++----- 16 files changed, 58 insertions(+), 64 deletions(-) diff --git a/infomaniak-build-tools/kDrive-template.html b/infomaniak-build-tools/kDrive-template.html index 3d9c6fb15..fb4d69d3e 100644 --- a/infomaniak-build-tools/kDrive-template.html +++ b/infomaniak-build-tools/kDrive-template.html @@ -22,7 +22,7 @@

Release notes - kDrive 3.6.7

New features

    -
  • Change the update mechanism to allow progressive delivery of new version
  • +
  • Change the update mechanism to allow progressive delivery of a new version

Bug fixes

    @@ -30,17 +30,16 @@

    Bug fixes

  • Fixed missing share links entries in contextual menu
  • Consolidation of error management during the propagation step
  • Do not block application startup if local sync folder is missing
  • -
  • Add "*.tmp" files to default exclusion templates
  • +
  • Added "*.tmp" files to default exclusion templates
  • Fixed wrongly blacklisted files
  • Fixed broken sync on FAT systems
  • Fixed startup issue in case of unknown proxy type
  • Fixed migration issues
  • Fixed status in case of abort during upload
  • -
  • Exclude files/folders with name length above 255 characters
  • +
  • Exclude files and folders with name length above 255 characters
  • Win - Fixed issue on symkinks and junctions
  • Fixed CSV parsing error leading to incomplete remote snapshot
  • -
  • Improve handling of access denied errors
  • -
  • Win - Improve error handling if a move to trash operation fails
  • +
  • Improved handling of access denied errors
\ No newline at end of file diff --git a/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-linux-de.html b/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-linux-de.html index e7c5a2524..6c2277ccc 100644 --- a/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-linux-de.html +++ b/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-linux-de.html @@ -22,7 +22,7 @@

Versionshinweise - kDrive 3.6.7

Neue Funktionen

    -
  • Änderung des Aktualisierungsmechanismus, um die schrittweise Bereitstellung neuer Versionen zu ermöglichen
  • +
  • Änderung des Aktualisierungsmechanismus, um die schrittweise Bereitstellung einer neuen Version zu ermöglichen

Fehlerbehebungen

    @@ -30,13 +30,13 @@

    Fehlerbehebungen

  • Fehlende Einträge für Freigabelinks im Kontextmenü behoben
  • Konsolidierung des Fehlermanagements während der Ausbreitungsphase
  • Start der Anwendung nicht blockieren, wenn der lokale Synchronisierungsordner fehlt
  • -
  • Hinzufügen von "*.tmp"-Dateien zu Standard-Ausschlussvorlagen
  • +
  • *.tmp"-Dateien zu Standard-Ausschlussvorlagen hinzugefügt
  • Falsch auf die schwarze Liste gesetzte Dateien korrigiert
  • Fehlerhafte Synchronisierung auf FAT-Systemen behoben
  • Startproblem im Falle eines unbekannten Proxy-Typs behoben
  • Behobene Migrationsprobleme
  • Status bei Abbruch während des Uploads korrigiert
  • -
  • Dateien/Ordner mit einer Namenslänge von mehr als 255 Zeichen ausschließen
  • +
  • Ausschließen von Dateien und Ordnern mit einer Namenslänge von mehr als 255 Zeichen
  • Fehler bei der CSV-Analyse behoben, der zu einem unvollständigen Remote-Snapshot führte
  • Verbesserte Behandlung von Fehlern bei verweigertem Zugriff
diff --git a/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-linux-en.html b/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-linux-en.html index 1199df78d..122e7014a 100644 --- a/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-linux-en.html +++ b/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-linux-en.html @@ -22,7 +22,7 @@

Release notes - kDrive 3.6.7

New features

    -
  • Change the update mechanism to allow progressive delivery of new version
  • +
  • Change the update mechanism to allow progressive delivery of a new version

Bug fixes

    @@ -30,15 +30,15 @@

    Bug fixes

  • Fixed missing share links entries in contextual menu
  • Consolidation of error management during the propagation step
  • Do not block application startup if local sync folder is missing
  • -
  • Add "*.tmp" files to default exclusion templates
  • +
  • Added "*.tmp" files to default exclusion templates
  • Fixed wrongly blacklisted files
  • Fixed broken sync on FAT systems
  • Fixed startup issue in case of unknown proxy type
  • Fixed migration issues
  • Fixed status in case of abort during upload
  • -
  • Exclude files/folders with name length above 255 characters
  • +
  • Exclude files and folders with name length above 255 characters
  • Fixed CSV parsing error leading to incomplete remote snapshot
  • -
  • Improve handling of access denied errors
  • +
  • Improved handling of access denied errors
\ No newline at end of file diff --git a/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-linux-es.html b/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-linux-es.html index a11f4885a..b2ede6ad7 100644 --- a/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-linux-es.html +++ b/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-linux-es.html @@ -22,7 +22,7 @@

Notas de la versión - kDrive 3.6.7

Novedades

    -
  • Cambiar el mecanismo de actualización para permitir la entrega progresiva de la nueva versión
  • +
  • Cambiar el mecanismo de actualización para permitir la entrega progresiva de una nueva versión

Corrección de errores

    @@ -30,15 +30,15 @@

    Corrección de errores

  • Se ha corregido la falta de entradas de enlaces compartidos en el menú contextual.
  • Consolidación de la gestión de errores durante la etapa de propagación
  • No bloquear el inicio de la aplicación si falta la carpeta de sincronización local
  • -
  • Añadir archivos "*.tmp" a las plantillas de exclusión por defecto
  • +
  • Añadidos los archivos "*.tmp" a las plantillas de exclusión por defecto
  • Corrección de archivos incluidos erróneamente en la lista negra
  • Corregida la sincronización rota en sistemas FAT
  • Se ha corregido un problema de inicio en caso de tipo de proxy desconocido.
  • Solucionados los problemas de migración
  • Corregido el estado en caso de aborto durante la carga
  • -
  • Excluir archivos/carpetas cuyo nombre tenga más de 255 caracteres
  • +
  • Excluir archivos y carpetas cuyo nombre tenga más de 255 caracteres
  • Se ha corregido un error de análisis CSV que provocaba una instantánea remota incompleta.
  • -
  • Mejorar la gestión de los errores de acceso denegado
  • +
  • Mejora de la gestión de los errores de acceso denegado
\ No newline at end of file diff --git a/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-linux-fr.html b/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-linux-fr.html index 50ff70ef9..adf5c75ba 100644 --- a/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-linux-fr.html +++ b/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-linux-fr.html @@ -22,7 +22,7 @@

Notes de version - kDrive 3.6.7

Nouvelles fonctionnalités

    -
  • Modifier le mécanisme de mise à jour pour permettre la livraison progressive de la nouvelle version
  • +
  • Modifier le mécanisme de mise à jour pour permettre la livraison progressive d'une nouvelle version

Correction de bugs

    @@ -30,13 +30,13 @@

    Correction de bugs

  • Correction de l'absence de liens de partage dans le menu contextuel
  • Consolidation de la gestion des erreurs lors de l'étape de propagation
  • Ne pas bloquer le démarrage de l'application si le dossier de synchronisation local est manquant
  • -
  • Ajouter les fichiers "*.tmp" aux modèles d'exclusion par défaut
  • +
  • Ajout des fichiers "*.tmp" aux modèles d'exclusion par défaut
  • Correction des fichiers mis sur liste noire à tort
  • Correction de la synchronisation interrompue sur les systèmes FAT
  • Correction du problème de démarrage en cas de type de proxy inconnu
  • Correction des problèmes de migration
  • Correction de l'état en cas d'interruption du téléchargement
  • -
  • Exclure les fichiers/dossiers dont le nom comporte plus de 255 caractères.
  • +
  • Exclure les fichiers et les dossiers dont le nom comporte plus de 255 caractères.
  • Correction d'une erreur d'analyse CSV entraînant un instantané à distance incomplet
  • Amélioration de la gestion des erreurs de refus d'accès
diff --git a/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-linux-it.html b/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-linux-it.html index 3a59e94bf..fa7082646 100644 --- a/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-linux-it.html +++ b/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-linux-it.html @@ -22,7 +22,7 @@

Note di rilascio - kDrive 3.6.7

Nuove caratteristiche

    -
  • Modificare il meccanismo di aggiornamento per consentire la consegna progressiva della nuova versione.
  • +
  • Modificare il meccanismo di aggiornamento per consentire la consegna progressiva di una nuova versione.

Correzioni di bug

    @@ -30,15 +30,15 @@

    Correzioni di bug

  • Correzione delle voci mancanti dei link di condivisione nel menu contestuale
  • Consolidamento della gestione degli errori durante la fase di propagazione
  • Non bloccare l'avvio dell'applicazione se manca la cartella di sincronizzazione locale
  • -
  • Aggiungere i file "*.tmp" ai modelli di esclusione predefiniti
  • +
  • Aggiunti i file "*.tmp" ai modelli di esclusione predefiniti
  • Corretti i file erroneamente inseriti nella lista nera
  • Corretta la sincronizzazione interrotta sui sistemi FAT
  • Corretto il problema di avvio in caso di tipo di proxy sconosciuto
  • Problemi di migrazione corretti
  • Corretto lo stato in caso di interruzione del caricamento
  • -
  • Escludete i file/cartelle con nomi di lunghezza superiore a 255 caratteri.
  • +
  • Escludere i file e le cartelle con nomi di lunghezza superiore a 255 caratteri.
  • Corretto l'errore di parsing CSV che portava a un'istantanea remota incompleta.
  • -
  • Migliorare la gestione degli errori di accesso negato
  • +
  • Gestione migliorata degli errori di accesso negato
\ No newline at end of file diff --git a/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-macos-de.html b/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-macos-de.html index e7c5a2524..6c2277ccc 100644 --- a/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-macos-de.html +++ b/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-macos-de.html @@ -22,7 +22,7 @@

Versionshinweise - kDrive 3.6.7

Neue Funktionen

    -
  • Änderung des Aktualisierungsmechanismus, um die schrittweise Bereitstellung neuer Versionen zu ermöglichen
  • +
  • Änderung des Aktualisierungsmechanismus, um die schrittweise Bereitstellung einer neuen Version zu ermöglichen

Fehlerbehebungen

    @@ -30,13 +30,13 @@

    Fehlerbehebungen

  • Fehlende Einträge für Freigabelinks im Kontextmenü behoben
  • Konsolidierung des Fehlermanagements während der Ausbreitungsphase
  • Start der Anwendung nicht blockieren, wenn der lokale Synchronisierungsordner fehlt
  • -
  • Hinzufügen von "*.tmp"-Dateien zu Standard-Ausschlussvorlagen
  • +
  • *.tmp"-Dateien zu Standard-Ausschlussvorlagen hinzugefügt
  • Falsch auf die schwarze Liste gesetzte Dateien korrigiert
  • Fehlerhafte Synchronisierung auf FAT-Systemen behoben
  • Startproblem im Falle eines unbekannten Proxy-Typs behoben
  • Behobene Migrationsprobleme
  • Status bei Abbruch während des Uploads korrigiert
  • -
  • Dateien/Ordner mit einer Namenslänge von mehr als 255 Zeichen ausschließen
  • +
  • Ausschließen von Dateien und Ordnern mit einer Namenslänge von mehr als 255 Zeichen
  • Fehler bei der CSV-Analyse behoben, der zu einem unvollständigen Remote-Snapshot führte
  • Verbesserte Behandlung von Fehlern bei verweigertem Zugriff
diff --git a/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-macos-en.html b/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-macos-en.html index 1199df78d..122e7014a 100644 --- a/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-macos-en.html +++ b/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-macos-en.html @@ -22,7 +22,7 @@

Release notes - kDrive 3.6.7

New features

    -
  • Change the update mechanism to allow progressive delivery of new version
  • +
  • Change the update mechanism to allow progressive delivery of a new version

Bug fixes

    @@ -30,15 +30,15 @@

    Bug fixes

  • Fixed missing share links entries in contextual menu
  • Consolidation of error management during the propagation step
  • Do not block application startup if local sync folder is missing
  • -
  • Add "*.tmp" files to default exclusion templates
  • +
  • Added "*.tmp" files to default exclusion templates
  • Fixed wrongly blacklisted files
  • Fixed broken sync on FAT systems
  • Fixed startup issue in case of unknown proxy type
  • Fixed migration issues
  • Fixed status in case of abort during upload
  • -
  • Exclude files/folders with name length above 255 characters
  • +
  • Exclude files and folders with name length above 255 characters
  • Fixed CSV parsing error leading to incomplete remote snapshot
  • -
  • Improve handling of access denied errors
  • +
  • Improved handling of access denied errors
\ No newline at end of file diff --git a/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-macos-es.html b/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-macos-es.html index a11f4885a..b2ede6ad7 100644 --- a/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-macos-es.html +++ b/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-macos-es.html @@ -22,7 +22,7 @@

Notas de la versión - kDrive 3.6.7

Novedades

    -
  • Cambiar el mecanismo de actualización para permitir la entrega progresiva de la nueva versión
  • +
  • Cambiar el mecanismo de actualización para permitir la entrega progresiva de una nueva versión

Corrección de errores

    @@ -30,15 +30,15 @@

    Corrección de errores

  • Se ha corregido la falta de entradas de enlaces compartidos en el menú contextual.
  • Consolidación de la gestión de errores durante la etapa de propagación
  • No bloquear el inicio de la aplicación si falta la carpeta de sincronización local
  • -
  • Añadir archivos "*.tmp" a las plantillas de exclusión por defecto
  • +
  • Añadidos los archivos "*.tmp" a las plantillas de exclusión por defecto
  • Corrección de archivos incluidos erróneamente en la lista negra
  • Corregida la sincronización rota en sistemas FAT
  • Se ha corregido un problema de inicio en caso de tipo de proxy desconocido.
  • Solucionados los problemas de migración
  • Corregido el estado en caso de aborto durante la carga
  • -
  • Excluir archivos/carpetas cuyo nombre tenga más de 255 caracteres
  • +
  • Excluir archivos y carpetas cuyo nombre tenga más de 255 caracteres
  • Se ha corregido un error de análisis CSV que provocaba una instantánea remota incompleta.
  • -
  • Mejorar la gestión de los errores de acceso denegado
  • +
  • Mejora de la gestión de los errores de acceso denegado
\ No newline at end of file diff --git a/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-macos-fr.html b/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-macos-fr.html index 50ff70ef9..adf5c75ba 100644 --- a/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-macos-fr.html +++ b/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-macos-fr.html @@ -22,7 +22,7 @@

Notes de version - kDrive 3.6.7

Nouvelles fonctionnalités

    -
  • Modifier le mécanisme de mise à jour pour permettre la livraison progressive de la nouvelle version
  • +
  • Modifier le mécanisme de mise à jour pour permettre la livraison progressive d'une nouvelle version

Correction de bugs

    @@ -30,13 +30,13 @@

    Correction de bugs

  • Correction de l'absence de liens de partage dans le menu contextuel
  • Consolidation de la gestion des erreurs lors de l'étape de propagation
  • Ne pas bloquer le démarrage de l'application si le dossier de synchronisation local est manquant
  • -
  • Ajouter les fichiers "*.tmp" aux modèles d'exclusion par défaut
  • +
  • Ajout des fichiers "*.tmp" aux modèles d'exclusion par défaut
  • Correction des fichiers mis sur liste noire à tort
  • Correction de la synchronisation interrompue sur les systèmes FAT
  • Correction du problème de démarrage en cas de type de proxy inconnu
  • Correction des problèmes de migration
  • Correction de l'état en cas d'interruption du téléchargement
  • -
  • Exclure les fichiers/dossiers dont le nom comporte plus de 255 caractères.
  • +
  • Exclure les fichiers et les dossiers dont le nom comporte plus de 255 caractères.
  • Correction d'une erreur d'analyse CSV entraînant un instantané à distance incomplet
  • Amélioration de la gestion des erreurs de refus d'accès
diff --git a/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-macos-it.html b/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-macos-it.html index 3a59e94bf..fa7082646 100644 --- a/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-macos-it.html +++ b/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-macos-it.html @@ -22,7 +22,7 @@

Note di rilascio - kDrive 3.6.7

Nuove caratteristiche

    -
  • Modificare il meccanismo di aggiornamento per consentire la consegna progressiva della nuova versione.
  • +
  • Modificare il meccanismo di aggiornamento per consentire la consegna progressiva di una nuova versione.

Correzioni di bug

    @@ -30,15 +30,15 @@

    Correzioni di bug

  • Correzione delle voci mancanti dei link di condivisione nel menu contestuale
  • Consolidamento della gestione degli errori durante la fase di propagazione
  • Non bloccare l'avvio dell'applicazione se manca la cartella di sincronizzazione locale
  • -
  • Aggiungere i file "*.tmp" ai modelli di esclusione predefiniti
  • +
  • Aggiunti i file "*.tmp" ai modelli di esclusione predefiniti
  • Corretti i file erroneamente inseriti nella lista nera
  • Corretta la sincronizzazione interrotta sui sistemi FAT
  • Corretto il problema di avvio in caso di tipo di proxy sconosciuto
  • Problemi di migrazione corretti
  • Corretto lo stato in caso di interruzione del caricamento
  • -
  • Escludete i file/cartelle con nomi di lunghezza superiore a 255 caratteri.
  • +
  • Escludere i file e le cartelle con nomi di lunghezza superiore a 255 caratteri.
  • Corretto l'errore di parsing CSV che portava a un'istantanea remota incompleta.
  • -
  • Migliorare la gestione degli errori di accesso negato
  • +
  • Gestione migliorata degli errori di accesso negato
\ No newline at end of file diff --git a/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-win-de.html b/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-win-de.html index ae8878484..0e5b63b9b 100644 --- a/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-win-de.html +++ b/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-win-de.html @@ -22,7 +22,7 @@

Versionshinweise - kDrive 3.6.7

Neue Funktionen

    -
  • Änderung des Aktualisierungsmechanismus, um die schrittweise Bereitstellung neuer Versionen zu ermöglichen
  • +
  • Änderung des Aktualisierungsmechanismus, um die schrittweise Bereitstellung einer neuen Version zu ermöglichen

Fehlerbehebungen

    @@ -30,17 +30,16 @@

    Fehlerbehebungen

  • Fehlende Einträge für Freigabelinks im Kontextmenü behoben
  • Konsolidierung des Fehlermanagements während der Ausbreitungsphase
  • Start der Anwendung nicht blockieren, wenn der lokale Synchronisierungsordner fehlt
  • -
  • Hinzufügen von "*.tmp"-Dateien zu Standard-Ausschlussvorlagen
  • +
  • *.tmp"-Dateien zu Standard-Ausschlussvorlagen hinzugefügt
  • Falsch auf die schwarze Liste gesetzte Dateien korrigiert
  • Fehlerhafte Synchronisierung auf FAT-Systemen behoben
  • Startproblem im Falle eines unbekannten Proxy-Typs behoben
  • Behobene Migrationsprobleme
  • Status bei Abbruch während des Uploads korrigiert
  • -
  • Dateien/Ordner mit einer Namenslänge von mehr als 255 Zeichen ausschließen
  • +
  • Ausschließen von Dateien und Ordnern mit einer Namenslänge von mehr als 255 Zeichen
  • Problem mit Symkinks und Abzweigungen behoben
  • Fehler bei der CSV-Analyse behoben, der zu einem unvollständigen Remote-Snapshot führte
  • Verbesserte Behandlung von Fehlern bei verweigertem Zugriff
  • -
  • Verbesserte Fehlerbehandlung bei fehlgeschlagenem Verschieben in den Papierkorb
\ No newline at end of file diff --git a/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-win-en.html b/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-win-en.html index e56c42f06..92290b222 100644 --- a/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-win-en.html +++ b/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-win-en.html @@ -22,7 +22,7 @@

Release notes - kDrive 3.6.7

New features

    -
  • Change the update mechanism to allow progressive delivery of new version
  • +
  • Change the update mechanism to allow progressive delivery of a new version

Bug fixes

    @@ -30,17 +30,16 @@

    Bug fixes

  • Fixed missing share links entries in contextual menu
  • Consolidation of error management during the propagation step
  • Do not block application startup if local sync folder is missing
  • -
  • Add "*.tmp" files to default exclusion templates
  • +
  • Added "*.tmp" files to default exclusion templates
  • Fixed wrongly blacklisted files
  • Fixed broken sync on FAT systems
  • Fixed startup issue in case of unknown proxy type
  • Fixed migration issues
  • Fixed status in case of abort during upload
  • -
  • Exclude files/folders with name length above 255 characters
  • +
  • Exclude files and folders with name length above 255 characters
  • Fixed issue on symkinks and junctions
  • Fixed CSV parsing error leading to incomplete remote snapshot
  • -
  • Improve handling of access denied errors
  • -
  • Improve error handling if a move to trash operation fails
  • +
  • Improved handling of access denied errors
\ No newline at end of file diff --git a/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-win-es.html b/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-win-es.html index d4795f005..5022129f7 100644 --- a/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-win-es.html +++ b/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-win-es.html @@ -22,7 +22,7 @@

Notas de la versión - kDrive 3.6.7

Novedades

    -
  • Cambiar el mecanismo de actualización para permitir la entrega progresiva de la nueva versión
  • +
  • Cambiar el mecanismo de actualización para permitir la entrega progresiva de una nueva versión

Corrección de errores

    @@ -30,17 +30,16 @@

    Corrección de errores

  • Se ha corregido la falta de entradas de enlaces compartidos en el menú contextual.
  • Consolidación de la gestión de errores durante la etapa de propagación
  • No bloquear el inicio de la aplicación si falta la carpeta de sincronización local
  • -
  • Añadir archivos "*.tmp" a las plantillas de exclusión por defecto
  • +
  • Añadidos los archivos "*.tmp" a las plantillas de exclusión por defecto
  • Corrección de archivos incluidos erróneamente en la lista negra
  • Corregida la sincronización rota en sistemas FAT
  • Se ha corregido un problema de inicio en caso de tipo de proxy desconocido.
  • Solucionados los problemas de migración
  • Corregido el estado en caso de aborto durante la carga
  • -
  • Excluir archivos/carpetas cuyo nombre tenga más de 255 caracteres
  • +
  • Excluir archivos y carpetas cuyo nombre tenga más de 255 caracteres
  • Se ha solucionado un problema con los enlaces simbólicos y los cruces.
  • Se ha corregido un error de análisis CSV que provocaba una instantánea remota incompleta.
  • -
  • Mejorar la gestión de los errores de acceso denegado
  • -
  • Mejorar la gestión de errores si falla una operación de mover a la papelera
  • +
  • Mejora de la gestión de los errores de acceso denegado
\ No newline at end of file diff --git a/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-win-fr.html b/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-win-fr.html index 1a737d865..6aca9264b 100644 --- a/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-win-fr.html +++ b/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-win-fr.html @@ -22,7 +22,7 @@

Notes de version - kDrive 3.6.7

Nouvelles fonctionnalités

    -
  • Modifier le mécanisme de mise à jour pour permettre la livraison progressive de la nouvelle version
  • +
  • Modifier le mécanisme de mise à jour pour permettre la livraison progressive d'une nouvelle version

Correction de bugs

    @@ -30,17 +30,16 @@

    Correction de bugs

  • Correction de l'absence de liens de partage dans le menu contextuel
  • Consolidation de la gestion des erreurs lors de l'étape de propagation
  • Ne pas bloquer le démarrage de l'application si le dossier de synchronisation local est manquant
  • -
  • Ajouter les fichiers "*.tmp" aux modèles d'exclusion par défaut
  • +
  • Ajout des fichiers "*.tmp" aux modèles d'exclusion par défaut
  • Correction des fichiers mis sur liste noire à tort
  • Correction de la synchronisation interrompue sur les systèmes FAT
  • Correction du problème de démarrage en cas de type de proxy inconnu
  • Correction des problèmes de migration
  • Correction de l'état en cas d'interruption du téléchargement
  • -
  • Exclure les fichiers/dossiers dont le nom comporte plus de 255 caractères.
  • +
  • Exclure les fichiers et les dossiers dont le nom comporte plus de 255 caractères.
  • Correction d'un problème sur les liens et les jonctions de systèmes
  • Correction d'une erreur d'analyse CSV entraînant un instantané à distance incomplet
  • Amélioration de la gestion des erreurs de refus d'accès
  • -
  • Amélioration de la gestion des erreurs en cas d'échec d'une opération de déplacement vers la corbeille
\ No newline at end of file diff --git a/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-win-it.html b/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-win-it.html index 594f9c577..fd5946fae 100644 --- a/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-win-it.html +++ b/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-win-it.html @@ -22,7 +22,7 @@

Note di rilascio - kDrive 3.6.7

Nuove caratteristiche

    -
  • Modificare il meccanismo di aggiornamento per consentire la consegna progressiva della nuova versione.
  • +
  • Modificare il meccanismo di aggiornamento per consentire la consegna progressiva di una nuova versione.

Correzioni di bug

    @@ -30,17 +30,16 @@

    Correzioni di bug

  • Correzione delle voci mancanti dei link di condivisione nel menu contestuale
  • Consolidamento della gestione degli errori durante la fase di propagazione
  • Non bloccare l'avvio dell'applicazione se manca la cartella di sincronizzazione locale
  • -
  • Aggiungere i file "*.tmp" ai modelli di esclusione predefiniti
  • +
  • Aggiunti i file "*.tmp" ai modelli di esclusione predefiniti
  • Corretti i file erroneamente inseriti nella lista nera
  • Corretta la sincronizzazione interrotta sui sistemi FAT
  • Corretto il problema di avvio in caso di tipo di proxy sconosciuto
  • Problemi di migrazione corretti
  • Corretto lo stato in caso di interruzione del caricamento
  • -
  • Escludete i file/cartelle con nomi di lunghezza superiore a 255 caratteri.
  • +
  • Escludere i file e le cartelle con nomi di lunghezza superiore a 255 caratteri.
  • Corretto il problema dei collegamenti simbolici e delle giunzioni
  • Corretto l'errore di parsing CSV che portava a un'istantanea remota incompleta.
  • -
  • Migliorare la gestione degli errori di accesso negato
  • -
  • Migliorare la gestione degli errori se un'operazione di spostamento nel cestino fallisce
  • +
  • Gestione migliorata degli errori di accesso negato
\ No newline at end of file From 4b92475538045697d7962ae286d923a9f8883cab Mon Sep 17 00:00:00 2001 From: Christophe Larchier Date: Tue, 5 Nov 2024 14:47:18 +0100 Subject: [PATCH 022/178] Fix Windows build --- test/server/CMakeLists.txt | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/test/server/CMakeLists.txt b/test/server/CMakeLists.txt index c559cd14e..1a5c64045 100644 --- a/test/server/CMakeLists.txt +++ b/test/server/CMakeLists.txt @@ -116,18 +116,4 @@ if (APPLE) execute_process(COMMAND \"install_name_tool\" -add_rpath ${INSTALL_OUTPUT_DIRECTORY}/${KDRIVE_OSX_BUNDLE}/Contents/Frameworks ${BIN_OUTPUT_DIRECTORY}/${testserver_NAME}) execute_process(COMMAND \"install_name_tool\" -add_rpath ${INSTALL_OUTPUT_DIRECTORY}/${KDRIVE_OSX_BUNDLE}/Contents/Plugins ${BIN_OUTPUT_DIRECTORY}/${testserver_NAME}) " COMPONENT RUNTIME) -elseif (WIN32) - #Vfs - set(CMAKE_FIND_LIBRARY_SUFFIXES .dll) - find_library(VFS_SHARED_LIBRARY - NAMES vfs - PATHS ${VFS_DIRECTORY} - NO_DEFAULT_PATH - NO_CACHE) - install(FILES ${VFS_SHARED_LIBRARY} - DESTINATION ${BIN_OUTPUT_DIRECTORY}) - - install(TARGETS "${libsyncengine_NAME}_vfs_win" - LIBRARY DESTINATION "${BIN_OUTPUT_DIRECTORY}" - RUNTIME DESTINATION "${BIN_OUTPUT_DIRECTORY}") endif() From 72d21a4b43f338168a606cd426e789bef572c100 Mon Sep 17 00:00:00 2001 From: Christophe Larchier Date: Tue, 5 Nov 2024 16:07:09 +0100 Subject: [PATCH 023/178] Fix Windows build --- src/server/vfs/win/CMakeLists.txt | 24 ++++++++++-------------- test/server/CMakeLists.txt | 2 +- 2 files changed, 11 insertions(+), 15 deletions(-) diff --git a/src/server/vfs/win/CMakeLists.txt b/src/server/vfs/win/CMakeLists.txt index 703bb736f..a7dc82fdf 100644 --- a/src/server/vfs/win/CMakeLists.txt +++ b/src/server/vfs/win/CMakeLists.txt @@ -1,6 +1,6 @@ find_package(Qt6) -add_library("${libsyncengine_NAME}_vfs_win" SHARED +set(libsyncengine_vfs_win_SRCS vfs_win.h vfs_win.cpp ../../../libcommonserver/vfs.h ../../../libcommonserver/vfs.cpp ../../../libcommonserver/plugin.h ../../../libcommonserver/plugin.cpp @@ -8,13 +8,8 @@ add_library("${libsyncengine_NAME}_vfs_win" SHARED ../../../common/filesystembase.h ../../../common/filesystembase.cpp ) -set(CMAKE_FIND_LIBRARY_SUFFIXES .lib) -find_library(VFS_STATIC_LIBRARY NAMES vfs PATHS ${VFS_DIRECTORY} NO_DEFAULT_PATH) - -target_link_libraries("${libsyncengine_NAME}_vfs_win" - ${libsyncengine_NAME} - ${VFS_STATIC_LIBRARY} - Qt6::Core +add_library("${libsyncengine_NAME}_vfs_win" SHARED + ${libsyncengine_vfs_win_SRCS} ) set_target_properties("${libsyncengine_NAME}_vfs_win" PROPERTIES @@ -24,10 +19,11 @@ set_target_properties("${libsyncengine_NAME}_vfs_win" PROPERTIES AUTOMOC TRUE ) -# For testing: Export symbols to be able to link the library statically -GENERATE_EXPORT_HEADER("${libsyncengine_NAME}_vfs_win" - BASE_NAME "${libsyncengine_NAME}_vfs_win" - EXPORT_MACRO_NAME SYNCENGINEVFS_EXPORT - EXPORT_FILE_NAME syncenginevfslib.h -) +set(CMAKE_FIND_LIBRARY_SUFFIXES .lib) +find_library(VFS_STATIC_LIBRARY NAMES vfs PATHS ${VFS_DIRECTORY} NO_DEFAULT_PATH) +target_link_libraries("${libsyncengine_NAME}_vfs_win" + ${libsyncengine_NAME} + ${VFS_STATIC_LIBRARY} + Qt6::Core +) diff --git a/test/server/CMakeLists.txt b/test/server/CMakeLists.txt index 1a5c64045..596db3937 100644 --- a/test/server/CMakeLists.txt +++ b/test/server/CMakeLists.txt @@ -102,7 +102,7 @@ if (APPLE) "${updater_DEPS}") elseif (WIN32) target_link_libraries(${testserver_NAME} - "${CMAKE_INSTALL_PREFIX}/src/server/vfs/win/${libsyncengine_NAME}_vfs_win.lib") + "${libsyncengine_NAME}_vfs_win") endif() # Install From 833630167388aeb6f07f2258ed1701e82f77e111 Mon Sep 17 00:00:00 2001 From: Christophe Larchier Date: Wed, 6 Nov 2024 08:33:56 +0100 Subject: [PATCH 024/178] Fix build --- src/server/vfs/win/CMakeLists.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/server/vfs/win/CMakeLists.txt b/src/server/vfs/win/CMakeLists.txt index a7dc82fdf..c268b189f 100644 --- a/src/server/vfs/win/CMakeLists.txt +++ b/src/server/vfs/win/CMakeLists.txt @@ -27,3 +27,10 @@ target_link_libraries("${libsyncengine_NAME}_vfs_win" ${VFS_STATIC_LIBRARY} Qt6::Core ) + +generate_export_header("${libsyncengine_NAME}_vfs_win" + BASE_NAME "${libsyncengine_NAME}_vfs_win" + EXPORT_MACRO_NAME SYNCENGINEVFS_EXPORT + EXPORT_FILE_NAME syncenginevfslib.h +) + From 71eabdd87cacd50c8cc35079064550d75dd4c940 Mon Sep 17 00:00:00 2001 From: Christophe Larchier Date: Wed, 6 Nov 2024 11:43:05 +0100 Subject: [PATCH 025/178] Add logs --- extensions/windows/cfapi/Common/utilities.cpp | 2 ++ extensions/windows/cfapi/Vfs/cloudprovider.cpp | 1 + extensions/windows/cfapi/Vfs/cloudproviderregistrar.cpp | 1 + 3 files changed, 4 insertions(+) diff --git a/extensions/windows/cfapi/Common/utilities.cpp b/extensions/windows/cfapi/Common/utilities.cpp index 964f338e7..dc4e2a7a1 100644 --- a/extensions/windows/cfapi/Common/utilities.cpp +++ b/extensions/windows/cfapi/Common/utilities.cpp @@ -143,6 +143,7 @@ void Utilities::initPipeName(const wchar_t *appName) { wchar_t userName[DEFAULT_BUFLEN]; GetUserName(userName, &len); s_pipeName = std::wstring(L"\\\\.\\pipe\\") + std::wstring(appName) + L"-" + std::wstring(userName, len); + TRACE_DEBUG(L"Init pipe: name = %ls", s_pipeName.c_str()); } bool Utilities::connectToPipeServer() { @@ -157,6 +158,7 @@ bool Utilities::connectToPipeServer() { return false; } + TRACE_DEBUG(L"Open pipe: name = %ls", s_pipeName.c_str()); while (true) { s_pipe = CreateFile(s_pipeName.data(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); if (s_pipe != INVALID_HANDLE_VALUE) { diff --git a/extensions/windows/cfapi/Vfs/cloudprovider.cpp b/extensions/windows/cfapi/Vfs/cloudprovider.cpp index d0510a1d3..ff9016d6d 100644 --- a/extensions/windows/cfapi/Vfs/cloudprovider.cpp +++ b/extensions/windows/cfapi/Vfs/cloudprovider.cpp @@ -90,6 +90,7 @@ bool CloudProvider::start(wchar_t *namespaceCLSID, DWORD *namespaceCLSIDSize) { TRACE_ERROR(L"Error in CloudProviderRegistrar::registerWithShell!"); return false; } + TRACE_DEBUG(L"CloudProviderRegistrar::registerWithShell done: syncRootID = %ls", _synRootID.c_str()); // Hook up callback methods for transferring files between client and server TRACE_DEBUG(L"Calling connectSyncRootTransferCallbacks"); diff --git a/extensions/windows/cfapi/Vfs/cloudproviderregistrar.cpp b/extensions/windows/cfapi/Vfs/cloudproviderregistrar.cpp index 42bd7e62e..ac340f95b 100644 --- a/extensions/windows/cfapi/Vfs/cloudproviderregistrar.cpp +++ b/extensions/windows/cfapi/Vfs/cloudproviderregistrar.cpp @@ -187,6 +187,7 @@ std::wstring CloudProviderRegistrar::registerWithShell(ProviderInfo *providerInf bool CloudProviderRegistrar::unregister(std::wstring syncRootID) { try { + TRACE_DEBUG(L"StorageProviderSyncRootManager::Unregister: syncRootID = %ls", syncRootID.c_str()); winrt::StorageProviderSyncRootManager::Unregister(syncRootID); } catch (winrt::hresult_error const &ex) { TRACE_ERROR(L"WinRT error caught : hr %08x - %s!", static_cast(winrt::to_hresult()), ex.message().c_str()); From 469e2f105b70c598ad49f48550d0b73e2f76c054 Mon Sep 17 00:00:00 2001 From: Christophe Larchier Date: Wed, 6 Nov 2024 11:43:23 +0100 Subject: [PATCH 026/178] Fix memory leak --- extensions/windows/cfapi/Vfs/dllmain.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/extensions/windows/cfapi/Vfs/dllmain.cpp b/extensions/windows/cfapi/Vfs/dllmain.cpp index c00f01cf9..34175baab 100644 --- a/extensions/windows/cfapi/Vfs/dllmain.cpp +++ b/extensions/windows/cfapi/Vfs/dllmain.cpp @@ -81,6 +81,7 @@ DLL_EXP int __cdecl vfsStart(const wchar_t *driveId, const wchar_t *userId, cons if (s_cloudProviders.size() == 0) { if (!Utilities::connectToPipeServer()) { TRACE_ERROR(L"Error in connectToPipeServer!"); + delete cloudProvider; return E_ABORT; } } From 65427aad4b25b0a423a8a2ffded22bafe2f5835f Mon Sep 17 00:00:00 2001 From: Christophe Larchier Date: Wed, 6 Nov 2024 16:39:44 +0100 Subject: [PATCH 027/178] Fix pipe name on the CI --- src/libcommonserver/utility/utility.cpp | 4 ++++ src/libcommonserver/utility/utility.h | 1 + src/libcommonserver/utility/utility_linux.cpp | 4 ++++ src/libcommonserver/utility/utility_mac.cpp | 5 +++++ src/libcommonserver/utility/utility_win.cpp | 9 +++++++++ src/server/socketapi.cpp | 5 ++--- test/libcommonserver/utility/testutility.cpp | 17 +++++++++++++++++ test/libcommonserver/utility/testutility.h | 2 ++ 8 files changed, 44 insertions(+), 3 deletions(-) diff --git a/src/libcommonserver/utility/utility.cpp b/src/libcommonserver/utility/utility.cpp index ed480c908..98ffda46a 100644 --- a/src/libcommonserver/utility/utility.cpp +++ b/src/libcommonserver/utility/utility.cpp @@ -909,4 +909,8 @@ SyncPath Utility::sharedFolderName() { return Str2SyncName(SHARED_FOLDER); } +std::string Utility::userName() { + return userName_private(); +} + } // namespace KDC diff --git a/src/libcommonserver/utility/utility.h b/src/libcommonserver/utility/utility.h index 6ea2c2a40..0c4735661 100644 --- a/src/libcommonserver/utility/utility.h +++ b/src/libcommonserver/utility/utility.h @@ -182,6 +182,7 @@ struct COMMONSERVER_EXPORT Utility { static SyncPath commonDocumentsFolderName(); static SyncPath sharedFolderName(); + static std::string userName(); private: static log4cplus::Logger _logger; diff --git a/src/libcommonserver/utility/utility_linux.cpp b/src/libcommonserver/utility/utility_linux.cpp index f8ea851f2..401adb9c4 100644 --- a/src/libcommonserver/utility/utility_linux.cpp +++ b/src/libcommonserver/utility/utility_linux.cpp @@ -261,4 +261,8 @@ static bool setFileDates_private(const KDC::SyncPath &filePath, std::optional modificationDate, bool symlink, bool &exists) { return KDC::setFileDates(filePath, creationDate, modificationDate, symlink, exists); } + +static std::string userName_private() { + return std::string(std::getenv("USER"); +} + } // namespace KDC diff --git a/src/libcommonserver/utility/utility_win.cpp b/src/libcommonserver/utility/utility_win.cpp index e3d6483b6..efac69e41 100644 --- a/src/libcommonserver/utility/utility_win.cpp +++ b/src/libcommonserver/utility/utility_win.cpp @@ -45,6 +45,8 @@ #include #include +#define USERNAME_BUFLEN 4096 + namespace KDC { static bool moveItemToTrash_private(const SyncPath &itemPath) { @@ -283,4 +285,11 @@ static bool cpuUsageByProcess_private(double &percent) { return true; } +static std::string userName_private() { + DWORD len = USERNAME_BUFLEN; + wchar_t userName[USERNAME_BUFLEN]; + GetUserName(userName, &len); + return Utility::ws2s(std::wstring(userName)); +} + } // namespace KDC diff --git a/src/server/socketapi.cpp b/src/server/socketapi.cpp index 2ebe265fd..f0283cbdf 100644 --- a/src/server/socketapi.cpp +++ b/src/server/socketapi.cpp @@ -49,7 +49,7 @@ #include #include -#ifdef Q_OS_MAC +#ifdef __APPLE__ #include #endif @@ -96,8 +96,7 @@ SocketApi::SocketApi(const std::unordered_map QString socketPath; if (OldUtility::isWindows()) { - socketPath = QString("\\\\.\\pipe\\") + QString(APPLICATION_SHORTNAME) + QString("-") + - QString::fromLocal8Bit(qgetenv("USERNAME")); + socketPath = QString("\\\\.\\pipe\\%1-%2").arg(APPLICATION_SHORTNAME, Utility::userName().c_str()); } else if (OldUtility::isMac()) { socketPath = SOCKETAPI_TEAM_IDENTIFIER_PREFIX APPLICATION_REV_DOMAIN ".socketApi"; #ifdef Q_OS_MAC diff --git a/test/libcommonserver/utility/testutility.cpp b/test/libcommonserver/utility/testutility.cpp index 73b7a20e3..61a105654 100644 --- a/test/libcommonserver/utility/testutility.cpp +++ b/test/libcommonserver/utility/testutility.cpp @@ -482,4 +482,21 @@ void TestUtility::testIsSameOrParentPath() { CPPUNIT_ASSERT(Utility::isDescendantOrEqual("a/b/c", "a")); } +void TestUtility::testUserName() { + CPPUNIT_ASSERT(!Utility::userName().empty()); + +#ifdef _WIN32 + std::filesystem::path homeDir(std::string(std::getenv("USERPROFILE"))); + if (homeDir.empty()) { + // When the tests are run by the CI ("Github Actions Runner" process), the user is "SYSTEM" and has no home directory + CPPUNIT_ASSERT_EQUAL(std::string("SYSTEM"), Utility::userName()); + } else { + CPPUNIT_ASSERT_EQUAL(SyncName2Str(homeDir.filename()), Utility::userName()); + } +#else + std::filesystem::path homeDir(std::string(std::getenv("HOME"))); + CPPUNIT_ASSERT_EQUAL(homeDir.filename(), Utility::userName()); +#endif +} + } // namespace KDC diff --git a/test/libcommonserver/utility/testutility.h b/test/libcommonserver/utility/testutility.h index 37b85d564..d8d666709 100644 --- a/test/libcommonserver/utility/testutility.h +++ b/test/libcommonserver/utility/testutility.h @@ -61,6 +61,7 @@ class TestUtility : public CppUnit::TestFixture { CPPUNIT_TEST(testNormalizedSyncName); CPPUNIT_TEST(testNormalizedSyncPath); CPPUNIT_TEST(testIsSameOrParentPath); + CPPUNIT_TEST(testUserName); CPPUNIT_TEST_SUITE_END(); public: @@ -106,6 +107,7 @@ class TestUtility : public CppUnit::TestFixture { void testNormalizedSyncName(); void testNormalizedSyncPath(); void testIsSameOrParentPath(); + void testUserName(); private: std::unique_ptr _testObj; From 1d739785368f7a7be2c9d24a2b1a337bba41e353 Mon Sep 17 00:00:00 2001 From: Christophe Larchier Date: Wed, 6 Nov 2024 16:47:31 +0100 Subject: [PATCH 028/178] Fix build --- src/libcommonserver/utility/utility_mac.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcommonserver/utility/utility_mac.cpp b/src/libcommonserver/utility/utility_mac.cpp index f1b41eb48..0eb3ea025 100644 --- a/src/libcommonserver/utility/utility_mac.cpp +++ b/src/libcommonserver/utility/utility_mac.cpp @@ -176,7 +176,7 @@ static bool setFileDates_private(const KDC::SyncPath &filePath, std::optional Date: Wed, 6 Nov 2024 16:53:56 +0100 Subject: [PATCH 029/178] Fix Linux & macOS build --- test/libcommonserver/utility/testutility.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/libcommonserver/utility/testutility.cpp b/test/libcommonserver/utility/testutility.cpp index 61a105654..aedc6effd 100644 --- a/test/libcommonserver/utility/testutility.cpp +++ b/test/libcommonserver/utility/testutility.cpp @@ -491,11 +491,11 @@ void TestUtility::testUserName() { // When the tests are run by the CI ("Github Actions Runner" process), the user is "SYSTEM" and has no home directory CPPUNIT_ASSERT_EQUAL(std::string("SYSTEM"), Utility::userName()); } else { - CPPUNIT_ASSERT_EQUAL(SyncName2Str(homeDir.filename()), Utility::userName()); + CPPUNIT_ASSERT_EQUAL(SyncName2Str(homeDir.filename().native()), Utility::userName()); } #else std::filesystem::path homeDir(std::string(std::getenv("HOME"))); - CPPUNIT_ASSERT_EQUAL(homeDir.filename(), Utility::userName()); + CPPUNIT_ASSERT_EQUAL(homeDir.filename().native(), Utility::userName()); #endif } From 7249c666ddab30caa856ab2bf24e775242b948a1 Mon Sep 17 00:00:00 2001 From: Christophe Larchier Date: Thu, 7 Nov 2024 09:02:01 +0100 Subject: [PATCH 030/178] Add some logs --- test/libcommonserver/utility/testutility.cpp | 14 ++++++++++---- test/libcommonserver/utility/testutility.h | 1 + 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/test/libcommonserver/utility/testutility.cpp b/test/libcommonserver/utility/testutility.cpp index aedc6effd..e94567660 100644 --- a/test/libcommonserver/utility/testutility.cpp +++ b/test/libcommonserver/utility/testutility.cpp @@ -19,9 +19,10 @@ #include "testutility.h" #include "test_utility/localtemporarydirectory.h" #include "config.h" - #include "libcommon/utility/utility.h" // CommonUtility::isSubDir -#include "Poco/URI.h" +#include "libcommonserver/log/log.h" + +#include #include #include @@ -486,15 +487,20 @@ void TestUtility::testUserName() { CPPUNIT_ASSERT(!Utility::userName().empty()); #ifdef _WIN32 - std::filesystem::path homeDir(std::string(std::getenv("USERPROFILE"))); + SyncPath homeDir(std::string(std::getenv("USERPROFILE"))); + LOGW_DEBUG(Log::instance()->getLogger(), L"homeDir=" << Utility::formatSyncPath(homeDir)); + LOG_DEBUG(Log::instance()->getLogger(), "userName=" << Utility::userName().c_str()); if (homeDir.empty()) { // When the tests are run by the CI ("Github Actions Runner" process), the user is "SYSTEM" and has no home directory + LOG_DEBUG(Log::instance()->getLogger(), "Empty homeDir"); CPPUNIT_ASSERT_EQUAL(std::string("SYSTEM"), Utility::userName()); } else { CPPUNIT_ASSERT_EQUAL(SyncName2Str(homeDir.filename().native()), Utility::userName()); } #else - std::filesystem::path homeDir(std::string(std::getenv("HOME"))); + SyncPath homeDir(std::string(std::getenv("HOME"))); + LOGW_DEBUG(Log::instance()->getLogger(), L"homeDir=" << Utility::formatSyncPath(homeDir)); + LOG_DEBUG(Log::instance()->getLogger(), "userName=" << Utility::userName().c_str()); CPPUNIT_ASSERT_EQUAL(homeDir.filename().native(), Utility::userName()); #endif } diff --git a/test/libcommonserver/utility/testutility.h b/test/libcommonserver/utility/testutility.h index d8d666709..0d936f39f 100644 --- a/test/libcommonserver/utility/testutility.h +++ b/test/libcommonserver/utility/testutility.h @@ -17,6 +17,7 @@ */ #include "testincludes.h" +#include "test_utility/testhelpers.h" #include "libcommonserver/utility/utility.h" using namespace CppUnit; From 82b2f30f7b7764760a255e7da106e2c568fd6b65 Mon Sep 17 00:00:00 2001 From: Herve Eruam Date: Thu, 7 Nov 2024 09:17:53 +0100 Subject: [PATCH 031/178] Add a check for stopAsked() in VFS status integrity --- src/libsyncengine/syncpal/syncpalworker.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/libsyncengine/syncpal/syncpalworker.cpp b/src/libsyncengine/syncpal/syncpalworker.cpp index fdbb0c580..6cf309cda 100644 --- a/src/libsyncengine/syncpal/syncpalworker.cpp +++ b/src/libsyncengine/syncpal/syncpalworker.cpp @@ -51,6 +51,13 @@ void SyncPalWorker::execute() { LOG_SYNCPAL_WARN(_logger, "Error in resetVfsFilesStatus for syncDbId=" << _syncPal->syncDbId()); } + // Manage stop + if (stopAsked()) { + // Exit + exitCode = ExitCode::Ok; + setDone(exitCode); + return; + } if (_syncPal->vfsMode() == VirtualFileMode::Mac) { // Reset nodes syncing flag if (!_syncPal->_syncDb->updateNodesSyncing(false)) { @@ -536,6 +543,9 @@ bool SyncPalWorker::resetVfsFilesStatus() { return false; } for (; dirIt != std::filesystem::recursive_directory_iterator(); ++dirIt) { + if (stopAsked()) { + return true; + } #ifdef _WIN32 // skip_permission_denied doesn't work on Windows try { From 2ade90216c0c186c0f007a58d868ae75a9d92dd7 Mon Sep 17 00:00:00 2001 From: Christophe Larchier Date: Thu, 7 Nov 2024 09:22:21 +0100 Subject: [PATCH 032/178] Fix tests --- test/libcommonserver/utility/testutility.cpp | 25 ++++++++++++-------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/test/libcommonserver/utility/testutility.cpp b/test/libcommonserver/utility/testutility.cpp index e94567660..411fcec71 100644 --- a/test/libcommonserver/utility/testutility.cpp +++ b/test/libcommonserver/utility/testutility.cpp @@ -486,22 +486,27 @@ void TestUtility::testIsSameOrParentPath() { void TestUtility::testUserName() { CPPUNIT_ASSERT(!Utility::userName().empty()); -#ifdef _WIN32 - SyncPath homeDir(std::string(std::getenv("USERPROFILE"))); - LOGW_DEBUG(Log::instance()->getLogger(), L"homeDir=" << Utility::formatSyncPath(homeDir)); LOG_DEBUG(Log::instance()->getLogger(), "userName=" << Utility::userName().c_str()); - if (homeDir.empty()) { - // When the tests are run by the CI ("Github Actions Runner" process), the user is "SYSTEM" and has no home directory - LOG_DEBUG(Log::instance()->getLogger(), "Empty homeDir"); + +#ifdef _WIN32 + const char *value = std::getenv("USERPROFILE"); + if (!value) { + LOG_DEBUG(Log::instance()->getLogger(), "USERPROFILE environment variable is not set (CI)"); CPPUNIT_ASSERT_EQUAL(std::string("SYSTEM"), Utility::userName()); } else { + const SyncPath homeDir(std::string(value)); + LOGW_DEBUG(Log::instance()->getLogger(), L"homeDir=" << Utility::formatSyncPath(homeDir)); CPPUNIT_ASSERT_EQUAL(SyncName2Str(homeDir.filename().native()), Utility::userName()); } #else - SyncPath homeDir(std::string(std::getenv("HOME"))); - LOGW_DEBUG(Log::instance()->getLogger(), L"homeDir=" << Utility::formatSyncPath(homeDir)); - LOG_DEBUG(Log::instance()->getLogger(), "userName=" << Utility::userName().c_str()); - CPPUNIT_ASSERT_EQUAL(homeDir.filename().native(), Utility::userName()); + const char *value = std::getenv("HOME"); + if (!value) { + LOG_DEBUG(Log::instance()->getLogger(), "HOME environment variable is not set (CI)"); + } else { + const SyncPath homeDir(value); + LOGW_DEBUG(Log::instance()->getLogger(), L"homeDir=" << Utility::formatSyncPath(homeDir)); + CPPUNIT_ASSERT_EQUAL(homeDir.filename().native(), Utility::userName()); + } #endif } From 8504b700e55fdd2600619708f2cefd8870db5fca Mon Sep 17 00:00:00 2001 From: Christophe Larchier Date: Thu, 7 Nov 2024 10:17:39 +0100 Subject: [PATCH 033/178] Fix an issue with empty USER env var --- src/libcommonserver/utility/utility_linux.cpp | 3 ++- src/libcommonserver/utility/utility_mac.cpp | 3 ++- test/libcommonserver/utility/testutility.cpp | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/libcommonserver/utility/utility_linux.cpp b/src/libcommonserver/utility/utility_linux.cpp index 401adb9c4..725e3ccc2 100644 --- a/src/libcommonserver/utility/utility_linux.cpp +++ b/src/libcommonserver/utility/utility_linux.cpp @@ -262,7 +262,8 @@ static bool setFileDates_private(const KDC::SyncPath &filePath, std::optionalgetLogger(), "USERPROFILE environment variable is not set (CI)"); CPPUNIT_ASSERT_EQUAL(std::string("SYSTEM"), Utility::userName()); } else { - const SyncPath homeDir(std::string(value)); + const SyncPath homeDir(value); LOGW_DEBUG(Log::instance()->getLogger(), L"homeDir=" << Utility::formatSyncPath(homeDir)); CPPUNIT_ASSERT_EQUAL(SyncName2Str(homeDir.filename().native()), Utility::userName()); } From 6ac0ef2291fa312d85581b7c71af3269a05864dc Mon Sep 17 00:00:00 2001 From: Christophe Larchier Date: Thu, 7 Nov 2024 10:28:09 +0100 Subject: [PATCH 034/178] small code improvements --- src/libcommonserver/utility/utility_linux.cpp | 2 +- src/libcommonserver/utility/utility_mac.cpp | 2 +- test/libcommonserver/utility/testutility.cpp | 2 -- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/libcommonserver/utility/utility_linux.cpp b/src/libcommonserver/utility/utility_linux.cpp index 725e3ccc2..df56f98cf 100644 --- a/src/libcommonserver/utility/utility_linux.cpp +++ b/src/libcommonserver/utility/utility_linux.cpp @@ -262,7 +262,7 @@ static bool setFileDates_private(const KDC::SyncPath &filePath, std::optionalgetLogger(), "userName=" << Utility::userName().c_str()); #ifdef _WIN32 From 824206de0724a635674accc83c72e5ab9fae33fb Mon Sep 17 00:00:00 2001 From: Christophe Larchier Date: Thu, 7 Nov 2024 11:10:29 +0100 Subject: [PATCH 035/178] Fix Linux tests --- src/libcommonserver/utility/utility_linux.cpp | 2 +- test/libcommonserver/utility/testutility.cpp | 28 +++++++++---------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/libcommonserver/utility/utility_linux.cpp b/src/libcommonserver/utility/utility_linux.cpp index df56f98cf..f2c9f2c34 100644 --- a/src/libcommonserver/utility/utility_linux.cpp +++ b/src/libcommonserver/utility/utility_linux.cpp @@ -262,7 +262,7 @@ static bool setFileDates_private(const KDC::SyncPath &filePath, std::optionalgetLogger(), "userName=" << Utility::userName().c_str()); + std::string userName(Utility::userName()); + LOG_DEBUG(Log::instance()->getLogger(), "userName=" << userName.c_str()); #ifdef _WIN32 const char *value = std::getenv("USERPROFILE"); - if (!value) { - LOG_DEBUG(Log::instance()->getLogger(), "USERPROFILE environment variable is not set (CI)"); - CPPUNIT_ASSERT_EQUAL(std::string("SYSTEM"), Utility::userName()); + CPPUNIT_ASSERT(value); + const SyncPath homeDir(value); + LOGW_DEBUG(Log::instance()->getLogger(), L"homeDir=" << Utility::formatSyncPath(homeDir)); + + if (homeDir.filename().native() == std::string("systemprofile")) { + // CI execution + CPPUNIT_ASSERT_EQUAL(std::string("SYSTEM"), userName); } else { - const SyncPath homeDir(value); - LOGW_DEBUG(Log::instance()->getLogger(), L"homeDir=" << Utility::formatSyncPath(homeDir)); - CPPUNIT_ASSERT_EQUAL(SyncName2Str(homeDir.filename().native()), Utility::userName()); + CPPUNIT_ASSERT_EQUAL(SyncName2Str(homeDir.filename().native()), userName); } #else const char *value = std::getenv("HOME"); - if (!value) { - LOG_DEBUG(Log::instance()->getLogger(), "HOME environment variable is not set (CI)"); - } else { - const SyncPath homeDir(value); - LOGW_DEBUG(Log::instance()->getLogger(), L"homeDir=" << Utility::formatSyncPath(homeDir)); - CPPUNIT_ASSERT_EQUAL(homeDir.filename().native(), Utility::userName()); - } + CPPUNIT_ASSERT(value); + const SyncPath homeDir(value); + LOGW_DEBUG(Log::instance()->getLogger(), L"homeDir=" << Utility::formatSyncPath(homeDir)); + CPPUNIT_ASSERT_EQUAL(homeDir.filename().native(), userName); #endif } From 0eb0d2d891c0c9bf21abedd5b6b234ecd536a18b Mon Sep 17 00:00:00 2001 From: Christophe Larchier Date: Thu, 7 Nov 2024 11:29:45 +0100 Subject: [PATCH 036/178] Fix Windows tests --- test/libcommonserver/utility/testutility.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/libcommonserver/utility/testutility.cpp b/test/libcommonserver/utility/testutility.cpp index b609da037..adc36f87f 100644 --- a/test/libcommonserver/utility/testutility.cpp +++ b/test/libcommonserver/utility/testutility.cpp @@ -493,7 +493,7 @@ void TestUtility::testUserName() { const SyncPath homeDir(value); LOGW_DEBUG(Log::instance()->getLogger(), L"homeDir=" << Utility::formatSyncPath(homeDir)); - if (homeDir.filename().native() == std::string("systemprofile")) { + if (homeDir.filename().native() == std::wstring("systemprofile")) { // CI execution CPPUNIT_ASSERT_EQUAL(std::string("SYSTEM"), userName); } else { From 12ab0391efa094c0ef5dfcd8111eac6c0727d195 Mon Sep 17 00:00:00 2001 From: Christophe Larchier Date: Thu, 7 Nov 2024 11:57:39 +0100 Subject: [PATCH 037/178] Fix Windows build --- test/libcommonserver/utility/testutility.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/libcommonserver/utility/testutility.cpp b/test/libcommonserver/utility/testutility.cpp index adc36f87f..7684599bc 100644 --- a/test/libcommonserver/utility/testutility.cpp +++ b/test/libcommonserver/utility/testutility.cpp @@ -493,7 +493,7 @@ void TestUtility::testUserName() { const SyncPath homeDir(value); LOGW_DEBUG(Log::instance()->getLogger(), L"homeDir=" << Utility::formatSyncPath(homeDir)); - if (homeDir.filename().native() == std::wstring("systemprofile")) { + if (homeDir.filename().native() == std::wstring(L"systemprofile")) { // CI execution CPPUNIT_ASSERT_EQUAL(std::string("SYSTEM"), userName); } else { From 335a6bcd0cc49a16c5bd6af4a0444910308af3c4 Mon Sep 17 00:00:00 2001 From: Christophe Larchier Date: Thu, 7 Nov 2024 15:25:37 +0100 Subject: [PATCH 038/178] Address some Sonar issues --- src/libcommonserver/utility/utility_linux.cpp | 5 +++-- src/libcommonserver/utility/utility_mac.cpp | 5 +++-- src/libcommonserver/utility/utility_win.cpp | 6 +++--- src/server/socketapi.cpp | 2 +- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/libcommonserver/utility/utility_linux.cpp b/src/libcommonserver/utility/utility_linux.cpp index f2c9f2c34..154cdc17c 100644 --- a/src/libcommonserver/utility/utility_linux.cpp +++ b/src/libcommonserver/utility/utility_linux.cpp @@ -17,6 +17,7 @@ */ #include "log/log.h" +#include "libcommon/utility/utility.h" #include #include @@ -262,8 +263,8 @@ static bool setFileDates_private(const KDC::SyncPath &filePath, std::optional #include @@ -176,8 +177,8 @@ static bool setFileDates_private(const KDC::SyncPath &filePath, std::optional #include -#define USERNAME_BUFLEN 4096 +constexpr int userNameBufLen = 4096; namespace KDC { @@ -286,8 +286,8 @@ static bool cpuUsageByProcess_private(double &percent) { } static std::string userName_private() { - DWORD len = USERNAME_BUFLEN; - wchar_t userName[USERNAME_BUFLEN]; + DWORD len = userNameBufLen; + wchar_t userName[userNameBufLen]; GetUserName(userName, &len); return Utility::ws2s(std::wstring(userName)); } diff --git a/src/server/socketapi.cpp b/src/server/socketapi.cpp index f0283cbdf..32eee6b38 100644 --- a/src/server/socketapi.cpp +++ b/src/server/socketapi.cpp @@ -96,7 +96,7 @@ SocketApi::SocketApi(const std::unordered_map QString socketPath; if (OldUtility::isWindows()) { - socketPath = QString("\\\\.\\pipe\\%1-%2").arg(APPLICATION_SHORTNAME, Utility::userName().c_str()); + socketPath = QString(R"(\\.\pipe\%1-%2)").arg(APPLICATION_SHORTNAME, Utility::userName().c_str()); } else if (OldUtility::isMac()) { socketPath = SOCKETAPI_TEAM_IDENTIFIER_PREFIX APPLICATION_REV_DOMAIN ".socketApi"; #ifdef Q_OS_MAC From efe0b670d07bf644f818c07cc5b0c4b802eb72f1 Mon Sep 17 00:00:00 2001 From: Christophe Larchier Date: Fri, 8 Nov 2024 10:21:46 +0100 Subject: [PATCH 039/178] Crash fix --- src/server/appserver.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/server/appserver.cpp b/src/server/appserver.cpp index 6f4b46610..084dd2c7d 100644 --- a/src/server/appserver.cpp +++ b/src/server/appserver.cpp @@ -2391,12 +2391,12 @@ bool AppServer::vfsUpdateMetadata(int syncDbId, const SyncPath &path, const Sync return false; } - QByteArray fileId(id.c_str()); - QString *errorStr = nullptr; - if (!_vfsMap[syncDbId]->updateMetadata(SyncName2QStr(path.native()), creationTime, modtime, size, fileId, errorStr)) { + const QByteArray fileId(id.c_str()); + QString errorStr; + if (!_vfsMap[syncDbId]->updateMetadata(SyncName2QStr(path.native()), creationTime, modtime, size, fileId, &errorStr)) { LOGW_WARN(Log::instance()->getLogger(), L"Error in Vfs::updateMetadata for syncDbId=" << syncDbId << L" and path=" << Path2WStr(path).c_str()); - error = errorStr ? errorStr->toStdString() : ""; + error = errorStr.toStdString(); return false; } From d81869c166058ea97ff7847e8a8111b2bfef5dd0 Mon Sep 17 00:00:00 2001 From: Christophe Larchier Date: Fri, 8 Nov 2024 10:30:18 +0100 Subject: [PATCH 040/178] Manage access denied error in vfsUpdateMetadata --- src/libsyncengine/propagation/executor/executorworker.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/libsyncengine/propagation/executor/executorworker.cpp b/src/libsyncengine/propagation/executor/executorworker.cpp index 6f91cbabf..10d8605e9 100644 --- a/src/libsyncengine/propagation/executor/executorworker.cpp +++ b/src/libsyncengine/propagation/executor/executorworker.cpp @@ -1107,6 +1107,10 @@ ExitInfo ExecutorWorker::checkLiteSyncInfoForEdit(SyncOpPtr syncOp, const SyncPa syncOp->affectedNode()->size(), syncOp->affectedNode()->id().has_value() ? *syncOp->affectedNode()->id() : std::string(), error); syncOp->setOmit(true); // Do not propagate change in file system, only in DB + // TODO: Vfs functions should return an ExitInfo struct + if (!error.empty()) { + return {ExitCode::SystemError, ExitCause::FileAccessError}; + } break; } case PinState::Unspecified: From 0291aa24fe08294878fbcde858d13413357154c2 Mon Sep 17 00:00:00 2001 From: Herve Eruam Date: Fri, 8 Nov 2024 10:52:09 +0100 Subject: [PATCH 041/178] Locked files are now considered as access denied. --- src/libcommonserver/io/iohelper.cpp | 1 + src/libcommonserver/io/iohelper_win.cpp | 2 ++ 2 files changed, 3 insertions(+) diff --git a/src/libcommonserver/io/iohelper.cpp b/src/libcommonserver/io/iohelper.cpp index 64b4b9e6f..0ab0b2140 100644 --- a/src/libcommonserver/io/iohelper.cpp +++ b/src/libcommonserver/io/iohelper.cpp @@ -72,6 +72,7 @@ IoError IoHelper::stdError2ioError(int error) noexcept { case static_cast(std::errc::no_space_on_device): return IoError::DiskFull; case static_cast(std::errc::permission_denied): + case static_cast(std::errc::operation_not_permitted): return IoError::AccessDenied; default: return IoError::Unknown; diff --git a/src/libcommonserver/io/iohelper_win.cpp b/src/libcommonserver/io/iohelper_win.cpp index a87d2c1f2..3b55f9fda 100644 --- a/src/libcommonserver/io/iohelper_win.cpp +++ b/src/libcommonserver/io/iohelper_win.cpp @@ -81,6 +81,8 @@ IoError ntStatus2ioError(NTSTATUS status) noexcept { case STATUS_SUCCESS: return IoError::Success; case STATUS_ACCESS_DENIED: + case ERROR_SHARING_VIOLATION: + case ERROR_LOCK_VIOLATION: return IoError::AccessDenied; case STATUS_DISK_FULL: return IoError::DiskFull; From d111448c9e040f5415f8e638905696dfded11400 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Kunz?= Date: Fri, 8 Nov 2024 13:29:32 +0100 Subject: [PATCH 042/178] KDESKTOP-1360 - Do not restart a process if one is already ongoing --- src/server/updater/sparkleupdater.mm | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/server/updater/sparkleupdater.mm b/src/server/updater/sparkleupdater.mm index 6fc46f59f..cb51bf638 100644 --- a/src/server/updater/sparkleupdater.mm +++ b/src/server/updater/sparkleupdater.mm @@ -187,7 +187,14 @@ - (BOOL)supportsGentleScheduledUpdateReminders { } void SparkleUpdater::onUpdateFound() { - if (isVersionSkipped(versionInfo().fullVersion())) return; + if (isVersionSkipped(versionInfo().fullVersion())) { + LOG_INFO(KDC::Log::instance()->getLogger(), "Version " << versionInfo().fullVersion().c_str() << " is skipped."); + return; + } + if ([d->updater sessionInProgress]) { + LOG_INFO(KDC::Log::instance()->getLogger(), "A session is already in progress..."); + return; + } startInstaller(); } From a6d31c9a62c89feb4aae67b947ff95739de0959f Mon Sep 17 00:00:00 2001 From: Christophe Larchier Date: Fri, 8 Nov 2024 14:11:51 +0100 Subject: [PATCH 043/178] Address comments --- src/libsyncengine/propagation/executor/executorworker.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libsyncengine/propagation/executor/executorworker.cpp b/src/libsyncengine/propagation/executor/executorworker.cpp index 10d8605e9..62e3ff9f6 100644 --- a/src/libsyncengine/propagation/executor/executorworker.cpp +++ b/src/libsyncengine/propagation/executor/executorworker.cpp @@ -1106,8 +1106,8 @@ ExitInfo ExecutorWorker::checkLiteSyncInfoForEdit(SyncOpPtr syncOp, const SyncPa syncOp->affectedNode()->lastmodified().has_value() ? *syncOp->affectedNode()->lastmodified() : 0, syncOp->affectedNode()->size(), syncOp->affectedNode()->id().has_value() ? *syncOp->affectedNode()->id() : std::string(), error); - syncOp->setOmit(true); // Do not propagate change in file system, only in DB // TODO: Vfs functions should return an ExitInfo struct + syncOp->setOmit(true); // Do not propagate change in file system, only in DB if (!error.empty()) { return {ExitCode::SystemError, ExitCause::FileAccessError}; } From d7a9ea3030ec854e949b671630d16732b74a9ccc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Kunz?= Date: Fri, 8 Nov 2024 14:23:21 +0100 Subject: [PATCH 044/178] Address PR comment --- src/server/updater/sparkleupdater.mm | 1 + 1 file changed, 1 insertion(+) diff --git a/src/server/updater/sparkleupdater.mm b/src/server/updater/sparkleupdater.mm index cb51bf638..b3376d703 100644 --- a/src/server/updater/sparkleupdater.mm +++ b/src/server/updater/sparkleupdater.mm @@ -192,6 +192,7 @@ - (BOOL)supportsGentleScheduledUpdateReminders { return; } if ([d->updater sessionInProgress]) { + // An update window is already opened or installation is in progress, no need to start a new one LOG_INFO(KDC::Log::instance()->getLogger(), "A session is already in progress..."); return; } From e62495cea352b96ece1f3fcb781141446df2facd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Kunz?= Date: Fri, 8 Nov 2024 15:18:01 +0100 Subject: [PATCH 045/178] Address PR comment --- src/server/updater/sparkleupdater.mm | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/server/updater/sparkleupdater.mm b/src/server/updater/sparkleupdater.mm index b3376d703..934b75400 100644 --- a/src/server/updater/sparkleupdater.mm +++ b/src/server/updater/sparkleupdater.mm @@ -192,8 +192,7 @@ - (BOOL)supportsGentleScheduledUpdateReminders { return; } if ([d->updater sessionInProgress]) { - // An update window is already opened or installation is in progress, no need to start a new one - LOG_INFO(KDC::Log::instance()->getLogger(), "A session is already in progress..."); + LOG_INFO(KDC::Log::instance()->getLogger(), "An update window is already opened or installation is in progress. No need to start a new one."); return; } startInstaller(); From 64218910f5e3938d29d01793ccd752e5bd33a175 Mon Sep 17 00:00:00 2001 From: Herve Eruam Date: Fri, 8 Nov 2024 15:41:39 +0100 Subject: [PATCH 046/178] Fix win std::error to ioError for windows --- src/libcommonserver/io/iohelper_win.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libcommonserver/io/iohelper_win.cpp b/src/libcommonserver/io/iohelper_win.cpp index 3b55f9fda..91c97ecfc 100644 --- a/src/libcommonserver/io/iohelper_win.cpp +++ b/src/libcommonserver/io/iohelper_win.cpp @@ -54,6 +54,8 @@ IoError dWordError2ioError(DWORD error, log4cplus::Logger logger) noexcept { case ERROR_SUCCESS: return IoError::Success; case ERROR_ACCESS_DENIED: + case ERROR_SHARING_VIOLATION: + case ERROR_LOCK_VIOLATION: return IoError::AccessDenied; case ERROR_DISK_FULL: return IoError::DiskFull; @@ -81,8 +83,6 @@ IoError ntStatus2ioError(NTSTATUS status) noexcept { case STATUS_SUCCESS: return IoError::Success; case STATUS_ACCESS_DENIED: - case ERROR_SHARING_VIOLATION: - case ERROR_LOCK_VIOLATION: return IoError::AccessDenied; case STATUS_DISK_FULL: return IoError::DiskFull; @@ -585,7 +585,7 @@ static bool getRightsWindowsApi(const SyncPath &path, bool &read, bool &write, b // Get rights for trustee ACCESS_MASK rights = 0; - result = GetEffectiveRightsFromAcl(pfileACL, &IoHelper::getTrustee(), &rights); + //result = GetEffectiveRightsFromAcl(pfileACL, &IoHelper::getTrustee(), &rights); ioError = dWordError2ioError(result, logger); /* The GetEffectiveRightsFromAcl function fails and returns ERROR_INVALID_ACL if the specified ACL contains an inherited From 0a15aaa25e18c116700d456204e903293791741f Mon Sep 17 00:00:00 2001 From: Herve Eruam Date: Fri, 8 Nov 2024 15:44:41 +0100 Subject: [PATCH 047/178] Add testAccesDeniedOnLockedFiles --- .../io/testcheckdirectoryiterator.cpp | 12 ++++++++++++ test/libcommonserver/io/testio.h | 5 +++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/test/libcommonserver/io/testcheckdirectoryiterator.cpp b/test/libcommonserver/io/testcheckdirectoryiterator.cpp index bfcb38395..99a90a44a 100644 --- a/test/libcommonserver/io/testcheckdirectoryiterator.cpp +++ b/test/libcommonserver/io/testcheckdirectoryiterator.cpp @@ -323,4 +323,16 @@ void TestIo::testCheckDirectoryPermissionLost() { } } +void TestIo::testAccesDeniedOnLockedFiles() { + LocalTemporaryDirectory tmpDir("TestIo-testAccesDeniedOnLockedFiles"); + const SyncPath lockedFile = tmpDir.path() / "lockedFile.txt"; + std::ofstream file(lockedFile); + CPPUNIT_ASSERT(file.is_open()); + + std::error_code ec; + std::filesystem::remove_all(lockedFile, ec); + IoError ioError = IoHelper::stdError2ioError(ec); + CPPUNIT_ASSERT_EQUAL(IoError::AccessDenied, ioError); +} + } // namespace KDC diff --git a/test/libcommonserver/io/testio.h b/test/libcommonserver/io/testio.h index 1d8cf93c6..5db792e98 100644 --- a/test/libcommonserver/io/testio.h +++ b/test/libcommonserver/io/testio.h @@ -43,7 +43,7 @@ struct IoHelperTests : public IoHelper { class TestIo : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(TestIo); - CPPUNIT_TEST(testCheckSetAndGetRights); // Keep this test before any tests that may use set/get rights functions + CPPUNIT_TEST(testCheckSetAndGetRights); // Keep this test before any tests that may use set/get rights functions CPPUNIT_TEST(testGetItemType); CPPUNIT_TEST(testGetFileSize); CPPUNIT_TEST(testTempDirectoryPath); @@ -71,6 +71,7 @@ class TestIo : public CppUnit::TestFixture { CPPUNIT_TEST(testCreateJunction); #endif CPPUNIT_TEST(testCheckIfFileIsDehydrated); + CPPUNIT_TEST(testAccesDeniedOnLockedFiles); CPPUNIT_TEST_SUITE_END(); public: @@ -126,7 +127,7 @@ class TestIo : public CppUnit::TestFixture { void testCheckDirectoryRecursive(); void testCheckDirectoryIteratorUnexpectedDelete(); void testCheckDirectoryPermissionLost(); - + void testAccesDeniedOnLockedFiles(); private: IoHelperTests *_testObj; const SyncPath _localTestDirPath; From 8a3d1f40921d9cded571e49588bf6211f49a6b71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Kunz?= Date: Fri, 8 Nov 2024 15:47:52 +0100 Subject: [PATCH 048/178] KDESKTOP-1366 - Use generic method to generate AppID --- src/libcommon/utility/utility.cpp | 13 ------------- src/libcommon/utility/utility.h | 1 - src/libparms/db/parmsdbappstate.cpp | 2 +- 3 files changed, 1 insertion(+), 15 deletions(-) diff --git a/src/libcommon/utility/utility.cpp b/src/libcommon/utility/utility.cpp index 4530a3b6a..f405d984e 100644 --- a/src/libcommon/utility/utility.cpp +++ b/src/libcommon/utility/utility.cpp @@ -118,19 +118,6 @@ std::string CommonUtility::generateRandomStringPKCE(const int length /*= 10*/) { return generateRandomString(charArray, distrib, length); } -std::string CommonUtility::generateAppId(const int length /*= 10*/) { - // The back only accept characters from `A` to `F` - static constexpr char charArray[] = - "0123456789" - "ABCDEF" - "abcdef"; - - static std::uniform_int_distribution distrib( - 0, sizeof(charArray) - 2); // -2 in order to avoid the null terminating character - - return generateRandomString(charArray, distrib, length); -} - void CommonUtility::crash() { volatile int *a = (int *) (NULL); *a = 1; diff --git a/src/libcommon/utility/utility.h b/src/libcommon/utility/utility.h index 37960c89e..39dc1501a 100644 --- a/src/libcommon/utility/utility.h +++ b/src/libcommon/utility/utility.h @@ -50,7 +50,6 @@ struct COMMON_EXPORT CommonUtility { static std::string generateRandomStringAlphaNum(int length = 10); static std::string generateRandomStringPKCE(int length = 10); - static std::string generateAppId(int length = 10); static QString fileSystemName(const QString &dirPath); diff --git a/src/libparms/db/parmsdbappstate.cpp b/src/libparms/db/parmsdbappstate.cpp index 1f3e8d619..cf382e632 100644 --- a/src/libparms/db/parmsdbappstate.cpp +++ b/src/libparms/db/parmsdbappstate.cpp @@ -103,7 +103,7 @@ bool ParmsDb::insertDefaultAppState() { return false; } - if (!insertAppState(AppStateKey::AppUid, CommonUtility::generateAppId(25), true)) { + if (!insertAppState(AppStateKey::AppUid, CommonUtility::generateRandomStringAlphaNum(25), true)) { LOG_WARN(_logger, "Error when inserting default value for LogUploadToken"); return false; } From f72519173a23826e5347f169a1147920de342c4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Kunz?= Date: Mon, 11 Nov 2024 11:13:55 +0100 Subject: [PATCH 049/178] KDESKTOP-1370 - Fix assertion if AppState is empty --- src/libparms/db/parmsdbappstate.cpp | 32 ++++++++++++----------------- test/libparms/db/testparmsdb.cpp | 8 ++++++++ 2 files changed, 21 insertions(+), 19 deletions(-) diff --git a/src/libparms/db/parmsdbappstate.cpp b/src/libparms/db/parmsdbappstate.cpp index cf382e632..cd40702b6 100644 --- a/src/libparms/db/parmsdbappstate.cpp +++ b/src/libparms/db/parmsdbappstate.cpp @@ -113,9 +113,6 @@ bool ParmsDb::insertDefaultAppState() { bool ParmsDb::insertAppState(AppStateKey key, const std::string &value, bool noEmptyValue /*= false*/) { const std::scoped_lock lock(_mutex); - int errId = 0; - std::string error; - bool found = false; std::string valueStr = value; if (valueStr.empty()) { LOG_WARN(_logger, "Value is empty for AppStateKey: " << CommonUtility::appStateKeyToString(key).c_str()); @@ -127,31 +124,28 @@ bool ParmsDb::insertAppState(AppStateKey key, const std::string &value, bool noE ASSERT(queryResetAndClearBindings(SELECT_APP_STATE_REQUEST_ID)) ASSERT(queryBindValue(SELECT_APP_STATE_REQUEST_ID, 1, static_cast(key))) + bool found = false; if (!queryNext(SELECT_APP_STATE_REQUEST_ID, found)) { LOG_WARN(_logger, "Error getting query result: " << SELECT_APP_STATE_REQUEST_ID); return false; } std::string existingValue; - ASSERT(queryStringValue(SELECT_APP_STATE_REQUEST_ID, 0, existingValue)) + if (found) { + ASSERT(queryStringValue(SELECT_APP_STATE_REQUEST_ID, 0, existingValue)) + } ASSERT(queryResetAndClearBindings(SELECT_APP_STATE_REQUEST_ID)) - if (!found) { - ASSERT(queryResetAndClearBindings(INSERT_APP_STATE_REQUEST_ID)) - ASSERT(queryBindValue(INSERT_APP_STATE_REQUEST_ID, 1, static_cast(key))) - ASSERT(queryBindValue(INSERT_APP_STATE_REQUEST_ID, 2, valueStr)) - if (!queryExec(INSERT_APP_STATE_REQUEST_ID, errId, error)) { - LOG_WARN(_logger, "Error running query: " << INSERT_APP_STATE_REQUEST_ID); - return false; - } - } else if (noEmptyValue && existingValue.empty()) { - ASSERT(queryResetAndClearBindings(UPDATE_APP_STATE_REQUEST_ID)) - ASSERT(queryBindValue(UPDATE_APP_STATE_REQUEST_ID, 1, static_cast(key))) - ASSERT(queryBindValue(UPDATE_APP_STATE_REQUEST_ID, 2, valueStr)) - if (!queryExec(UPDATE_APP_STATE_REQUEST_ID, errId, error)) { - LOG_WARN(_logger, "Error running query: " << UPDATE_APP_STATE_REQUEST_ID); + const auto requestId = found ? UPDATE_APP_STATE_REQUEST_ID : INSERT_APP_STATE_REQUEST_ID; + if (!found || (noEmptyValue && existingValue.empty())) { + ASSERT(queryBindValue(requestId, 1, static_cast(key))) + ASSERT(queryBindValue(requestId, 2, valueStr)) + int errId = 0; + std::string error; + if (!queryExec(requestId, errId, error)) { + LOG_WARN(_logger, "Error running query: " << requestId); return false; } - ASSERT(queryResetAndClearBindings(UPDATE_APP_STATE_REQUEST_ID)) + ASSERT(queryResetAndClearBindings(requestId)) } return true; } diff --git a/test/libparms/db/testparmsdb.cpp b/test/libparms/db/testparmsdb.cpp index 956c1fc36..a3b1dfb89 100644 --- a/test/libparms/db/testparmsdb.cpp +++ b/test/libparms/db/testparmsdb.cpp @@ -394,6 +394,14 @@ void TestParmsDb::testAppState(void) { CPPUNIT_ASSERT_EQUAL(std::string("value"), std::get(valueRes)); i++; }; + + // Test add defaut value if and only if value is empty + CPPUNIT_ASSERT(ParmsDb::instance()->insertAppState(AppStateKey::Unknown, "test1", true)); + CPPUNIT_ASSERT(ParmsDb::instance()->selectAppState(AppStateKey::Unknown, value, found) && found); + CPPUNIT_ASSERT_EQUAL(std::string("test1"), std::get(value)); + CPPUNIT_ASSERT(ParmsDb::instance()->insertAppState(AppStateKey::Unknown, "test2", true)); + CPPUNIT_ASSERT(ParmsDb::instance()->selectAppState(AppStateKey::Unknown, value, found) && found); + CPPUNIT_ASSERT_EQUAL(std::string("test1"), std::get(value)); } #ifdef __APPLE__ From e76906c933081e649730d920c521de58af8bedfb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Kunz?= Date: Mon, 11 Nov 2024 11:21:02 +0100 Subject: [PATCH 050/178] KDESKTOP-1370 - Rename variable for better readability --- src/libparms/db/parmsdb.h | 2 +- src/libparms/db/parmsdbappstate.cpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libparms/db/parmsdb.h b/src/libparms/db/parmsdb.h index 2d2d0b125..d9935ad95 100644 --- a/src/libparms/db/parmsdb.h +++ b/src/libparms/db/parmsdb.h @@ -140,7 +140,7 @@ class PARMS_EXPORT ParmsDb : public Db { bool insertDefaultParameters(); bool insertDefaultAppState(); - bool insertAppState(AppStateKey key, const std::string &value, bool noEmptyValue = false); + bool insertAppState(AppStateKey key, const std::string &value, bool updateOnlyIfEmpty = false); bool updateExclusionTemplates(); bool createAppState(); diff --git a/src/libparms/db/parmsdbappstate.cpp b/src/libparms/db/parmsdbappstate.cpp index cd40702b6..84844a62e 100644 --- a/src/libparms/db/parmsdbappstate.cpp +++ b/src/libparms/db/parmsdbappstate.cpp @@ -111,7 +111,7 @@ bool ParmsDb::insertDefaultAppState() { return true; } -bool ParmsDb::insertAppState(AppStateKey key, const std::string &value, bool noEmptyValue /*= false*/) { +bool ParmsDb::insertAppState(AppStateKey key, const std::string &value, const bool updateOnlyIfEmpty /*= false*/) { const std::scoped_lock lock(_mutex); std::string valueStr = value; if (valueStr.empty()) { @@ -135,8 +135,8 @@ bool ParmsDb::insertAppState(AppStateKey key, const std::string &value, bool noE } ASSERT(queryResetAndClearBindings(SELECT_APP_STATE_REQUEST_ID)) - const auto requestId = found ? UPDATE_APP_STATE_REQUEST_ID : INSERT_APP_STATE_REQUEST_ID; - if (!found || (noEmptyValue && existingValue.empty())) { + if (!found || (updateOnlyIfEmpty && existingValue.empty())) { + const auto requestId = found ? UPDATE_APP_STATE_REQUEST_ID : INSERT_APP_STATE_REQUEST_ID; ASSERT(queryBindValue(requestId, 1, static_cast(key))) ASSERT(queryBindValue(requestId, 2, valueStr)) int errId = 0; From 55c27ce44b157f5050ac4f5c0511e6ac99707f17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Kunz?= Date: Tue, 12 Nov 2024 09:52:47 +0100 Subject: [PATCH 051/178] KDESKTOP-1372 - Remove has_prod_next flag --- .../jobs/network/getappversionjob.cpp | 47 ++++++++++--------- .../jobs/network/getappversionjob.h | 12 +++-- src/server/updater/updatechecker.cpp | 7 +-- .../jobs/network/testnetworkjobs.cpp | 3 ++ 4 files changed, 36 insertions(+), 33 deletions(-) diff --git a/src/libsyncengine/jobs/network/getappversionjob.cpp b/src/libsyncengine/jobs/network/getappversionjob.cpp index 171cb4fc9..b1d411fbe 100644 --- a/src/libsyncengine/jobs/network/getappversionjob.cpp +++ b/src/libsyncengine/jobs/network/getappversionjob.cpp @@ -24,7 +24,7 @@ namespace KDC { -static const std::string hasProdNextKey = "has_prod_next"; +static const std::string prodVersionKey = "prod_version"; static const std::string applicationKey = "application"; static const std::string publishedVersionsKey = "published_versions"; static const std::string versionTypeProdKey = "production"; @@ -41,12 +41,13 @@ static const std::string buildMinOsVersionKey = "build_min_os_version"; static const std::string downloadUrlKey = "download_link"; GetAppVersionJob::GetAppVersionJob(const Platform platform, const std::string &appID) : GetAppVersionJob(platform, appID, {}) {} + GetAppVersionJob::GetAppVersionJob(const Platform platform, const std::string &appID, const std::vector &userIdList) : _platform(platform), _appId(appID), _userIdList(userIdList) { _httpMethod = Poco::Net::HTTPRequest::HTTP_GET; } -std::string platformToStr(Platform platform) { +std::string toStr(const Platform platform) { switch (platform) { case Platform::MacOS: return platformMacOsKey; @@ -61,11 +62,20 @@ std::string platformToStr(Platform platform) { } } +DistributionChannel toDistributionChannel(const std::string &str) { + if (str == versionTypeProdKey) return DistributionChannel::Prod; + if (str == versionTypeNextKey) return DistributionChannel::Next; + if (str == versionTypeBetaKey) return DistributionChannel::Beta; + if (str == versionTypeInternalKey) return DistributionChannel::Internal; + return DistributionChannel::Unknown; +} + std::string GetAppVersionJob::getSpecificUrl() { std::stringstream ss; - ss << "/app-information/kstore-update/" << platformToStr(_platform) << "/com.infomaniak.drive/" << _appId; + ss << "/app-information/kstore-update/" << toStr(_platform) << "/com.infomaniak.drive/" << _appId; return ss.str(); } + std::string GetAppVersionJob::getContentType(bool &canceled) { canceled = false; return {}; @@ -92,16 +102,14 @@ DistributionChannel GetAppVersionJob::toDistributionChannel(const std::string &v } bool GetAppVersionJob::handleResponse(std::istream &is) { - if (!AbstractNetworkJob::handleJsonResponse(is)) { - return false; - } + if (!AbstractNetworkJob::handleJsonResponse(is)) return false; const Poco::JSON::Object::Ptr dataObj = JsonParserUtility::extractJsonObject(jsonRes(), dataKey); if (!dataObj) return false; - if (!JsonParserUtility::extractValue(dataObj, hasProdNextKey, _hasProdNext)) { - return false; - } + std::string tmpStr; + if (!JsonParserUtility::extractValue(dataObj, prodVersionKey, tmpStr)) return false; + _prodVersionChannel = toDistributionChannel(tmpStr); const Poco::JSON::Object::Ptr applicationObj = JsonParserUtility::extractJsonObject(dataObj, applicationKey); if (!applicationObj) return false; @@ -112,24 +120,16 @@ bool GetAppVersionJob::handleResponse(std::istream &is) { for (const auto &versionInfo: *publishedVersions) { const auto &obj = versionInfo.extract(); std::string versionType; - if (!JsonParserUtility::extractValue(obj, typeKey, versionType)) { - return false; - } + if (!JsonParserUtility::extractValue(obj, typeKey, versionType)) return false; const DistributionChannel channel = toDistributionChannel(versionType); _versionInfo[channel].channel = channel; - if (!JsonParserUtility::extractValue(obj, tagKey, _versionInfo[channel].tag)) { - return false; - } - if (!JsonParserUtility::extractValue(obj, buildVersionKey, _versionInfo[channel].buildVersion)) { - return false; - } - if (!JsonParserUtility::extractValue(obj, buildMinOsVersionKey, _versionInfo[channel].buildMinOsVersion, false)) { - return false; - } - if (!JsonParserUtility::extractValue(obj, downloadUrlKey, _versionInfo[channel].downloadUrl)) { + + if (!JsonParserUtility::extractValue(obj, tagKey, _versionInfo[channel].tag)) return false; + if (!JsonParserUtility::extractValue(obj, buildVersionKey, _versionInfo[channel].buildVersion)) return false; + if (!JsonParserUtility::extractValue(obj, buildMinOsVersionKey, _versionInfo[channel].buildMinOsVersion, false)) return false; - } + if (!JsonParserUtility::extractValue(obj, downloadUrlKey, _versionInfo[channel].downloadUrl)) return false; if (!_versionInfo[channel].isValid()) { LOG_WARN(_logger, "Missing mandatory value."); @@ -139,4 +139,5 @@ bool GetAppVersionJob::handleResponse(std::istream &is) { return true; } + } // namespace KDC diff --git a/src/libsyncengine/jobs/network/getappversionjob.h b/src/libsyncengine/jobs/network/getappversionjob.h index 0771cb607..5b86e0f84 100644 --- a/src/libsyncengine/jobs/network/getappversionjob.h +++ b/src/libsyncengine/jobs/network/getappversionjob.h @@ -30,12 +30,15 @@ class GetAppVersionJob : public AbstractNetworkJob { GetAppVersionJob(Platform platform, const std::string &appID, const std::vector &userIdList); ~GetAppVersionJob() override = default; - const VersionInfo &getVersionInfo(const DistributionChannel channel) { return _versionInfo[channel]; } + const VersionInfo &getVersionInfo(const DistributionChannel channel) { + return _versionInfo.contains(channel) ? _versionInfo[channel] : _defaultVersionInfo; + } + const VersionInfo &getProdVersionInfo() { + return _versionInfo.contains(_prodVersionChannel) ? _versionInfo[_prodVersionChannel] : _defaultVersionInfo; + } std::string getUrl() override { return INFOMANIAK_API_URL + getSpecificUrl(); } - [[nodiscard]] bool hasProdNext() const { return _hasProdNext; } - protected: bool handleResponse(std::istream &is) override; @@ -52,7 +55,8 @@ class GetAppVersionJob : public AbstractNetworkJob { const std::string _appId; const std::vector _userIdList; - bool _hasProdNext{false}; + const VersionInfo _defaultVersionInfo; + DistributionChannel _prodVersionChannel{DistributionChannel::Unknown}; std::unordered_map _versionInfo; }; diff --git a/src/server/updater/updatechecker.cpp b/src/server/updater/updatechecker.cpp index 72ae3254f..c87c94436 100644 --- a/src/server/updater/updatechecker.cpp +++ b/src/server/updater/updatechecker.cpp @@ -66,12 +66,7 @@ void UpdateChecker::versionInfoReceived(UniqueId jobId) { SentryHandler::instance()->captureMessage(SentryLevel::Warning, "AbstractUpdater::checkUpdateAvailable", ss.str()); LOG_ERROR(Log::instance()->getLogger(), ss.str().c_str()); } else { - DistributionChannel channel = _channel; - // hasProdNext() is true if and only if the running application has been elected for an upgrade in the context of a - // progressive update - if (channel == DistributionChannel::Prod && getAppVersionJobPtr->hasProdNext()) channel = DistributionChannel::Next; - - _versionInfo = getAppVersionJobPtr->getVersionInfo(channel); + _versionInfo = getAppVersionJobPtr->getProdVersionInfo(); if (!_versionInfo.isValid()) { std::string error = "Invalid version info!"; SentryHandler::instance()->captureMessage(SentryLevel::Warning, "AbstractUpdater::checkUpdateAvailable", error); diff --git a/test/libsyncengine/jobs/network/testnetworkjobs.cpp b/test/libsyncengine/jobs/network/testnetworkjobs.cpp index 026083215..cc13e3175 100644 --- a/test/libsyncengine/jobs/network/testnetworkjobs.cpp +++ b/test/libsyncengine/jobs/network/testnetworkjobs.cpp @@ -909,6 +909,7 @@ void TestNetworkJobs::testGetAppVersionInfo() { CPPUNIT_ASSERT(job.getVersionInfo(DistributionChannel::Beta).isValid()); CPPUNIT_ASSERT(job.getVersionInfo(DistributionChannel::Next).isValid()); CPPUNIT_ASSERT(job.getVersionInfo(DistributionChannel::Prod).isValid()); + CPPUNIT_ASSERT(job.getProdVersionInfo().isValid()); } // With 1 user ID { @@ -919,6 +920,7 @@ void TestNetworkJobs::testGetAppVersionInfo() { CPPUNIT_ASSERT(job.getVersionInfo(DistributionChannel::Beta).isValid()); CPPUNIT_ASSERT(job.getVersionInfo(DistributionChannel::Next).isValid()); CPPUNIT_ASSERT(job.getVersionInfo(DistributionChannel::Prod).isValid()); + CPPUNIT_ASSERT(job.getProdVersionInfo().isValid()); } // With several user IDs { @@ -929,6 +931,7 @@ void TestNetworkJobs::testGetAppVersionInfo() { CPPUNIT_ASSERT(job.getVersionInfo(DistributionChannel::Beta).isValid()); CPPUNIT_ASSERT(job.getVersionInfo(DistributionChannel::Next).isValid()); CPPUNIT_ASSERT(job.getVersionInfo(DistributionChannel::Prod).isValid()); + CPPUNIT_ASSERT(job.getProdVersionInfo().isValid()); } } From 7bd117b9c3f4148048c39f094e45de409b9699e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Kunz?= Date: Tue, 12 Nov 2024 15:01:09 +0100 Subject: [PATCH 052/178] KDESKTOP-1372 - Fix test --- .../jobs/network/testnetworkjobs.cpp | 30 +++++++++++-------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/test/libsyncengine/jobs/network/testnetworkjobs.cpp b/test/libsyncengine/jobs/network/testnetworkjobs.cpp index cc13e3175..fd48b5d7c 100644 --- a/test/libsyncengine/jobs/network/testnetworkjobs.cpp +++ b/test/libsyncengine/jobs/network/testnetworkjobs.cpp @@ -899,7 +899,6 @@ void TestNetworkJobs::testDriveUploadSessionAsynchronousAborted() { void TestNetworkJobs::testGetAppVersionInfo() { const auto appUid = "1234567890"; - // Without user IDs { GetAppVersionJob job(CommonUtility::platform(), appUid); @@ -913,18 +912,11 @@ void TestNetworkJobs::testGetAppVersionInfo() { } // With 1 user ID { - GetAppVersionJob job(CommonUtility::platform(), appUid, {123}); - job.runSynchronously(); - CPPUNIT_ASSERT(!job.hasHttpError()); - CPPUNIT_ASSERT(job.getVersionInfo(DistributionChannel::Internal).isValid()); - CPPUNIT_ASSERT(job.getVersionInfo(DistributionChannel::Beta).isValid()); - CPPUNIT_ASSERT(job.getVersionInfo(DistributionChannel::Next).isValid()); - CPPUNIT_ASSERT(job.getVersionInfo(DistributionChannel::Prod).isValid()); - CPPUNIT_ASSERT(job.getProdVersionInfo().isValid()); - } - // With several user IDs - { - GetAppVersionJob job(CommonUtility::platform(), appUid, {123, 456, 789}); + User user; + bool found = false; + ParmsDb::instance()->selectUser(_userDbId, user, found); + + GetAppVersionJob job(CommonUtility::platform(), appUid, {user.userId()}); job.runSynchronously(); CPPUNIT_ASSERT(!job.hasHttpError()); CPPUNIT_ASSERT(job.getVersionInfo(DistributionChannel::Internal).isValid()); @@ -933,6 +925,18 @@ void TestNetworkJobs::testGetAppVersionInfo() { CPPUNIT_ASSERT(job.getVersionInfo(DistributionChannel::Prod).isValid()); CPPUNIT_ASSERT(job.getProdVersionInfo().isValid()); } + // // With several user IDs + // TODO : commented out because we need valid user IDs but we have only one available in tests for now + // { + // GetAppVersionJob job(CommonUtility::platform(), appUid, {123, 456, 789}); + // job.runSynchronously(); + // CPPUNIT_ASSERT(!job.hasHttpError()); + // CPPUNIT_ASSERT(job.getVersionInfo(DistributionChannel::Internal).isValid()); + // CPPUNIT_ASSERT(job.getVersionInfo(DistributionChannel::Beta).isValid()); + // CPPUNIT_ASSERT(job.getVersionInfo(DistributionChannel::Next).isValid()); + // CPPUNIT_ASSERT(job.getVersionInfo(DistributionChannel::Prod).isValid()); + // CPPUNIT_ASSERT(job.getProdVersionInfo().isValid()); + // } } void TestNetworkJobs::testDirectDownload() { From 3103d4701944f7811f388b17c5fb70f19f9d7764 Mon Sep 17 00:00:00 2001 From: Christophe Larchier Date: Tue, 12 Nov 2024 16:35:10 +0100 Subject: [PATCH 053/178] Add some translations --- translations/client_de.ts | 490 +++++++++++++++++++------------------ translations/client_es.ts | 491 +++++++++++++++++++------------------- translations/client_fr.ts | 490 +++++++++++++++++++------------------ translations/client_it.ts | 490 +++++++++++++++++++------------------ 4 files changed, 960 insertions(+), 1001 deletions(-) diff --git a/translations/client_de.ts b/translations/client_de.ts index ae75845dc..0a416bec0 100644 --- a/translations/client_de.ts +++ b/translations/client_de.ts @@ -288,12 +288,12 @@ KDC::AppServer - + kDrive application is already running! Die kDrive-Anwendung läuft bereits! - + %1 and %n other file(s) have been removed. %1 und %n andere Datei(en) wurde(n) gelöscht. @@ -301,13 +301,13 @@ - + %1 has been removed. %1 names a file. %1 wurde gelöscht. - + %1 and %n other file(s) have been added. %1 und %n andere Datei(en) wurde(n) hinzugefügt. @@ -315,13 +315,13 @@ - + %1 has been added. %1 names a file. %1 wurde hinzugefügt. - + %1 and %n other file(s) have been updated. %1 und %n andere Datei(en) wurde(n) aktualisiert. @@ -329,13 +329,13 @@ - + %1 has been updated. %1 names a file. %1 wurde aktualisiert. - + %1 has been moved to %2 and %n other file(s) have been moved. %1 wurde zu %2 verschoben und %n andere Datei(en) wurde(n) verschoben. @@ -343,17 +343,17 @@ - + %1 has been moved to %2. %1 wurde zu %2 verschoben. - + Sync Activity Synchronisierungsaktivität - + A new folder larger than %1 MB has been added in the drive %2, you must validate its synchronization: %3. Ein neuer Ordner mit einer Grösse von mehr als %1 MB wurde zum Laufwerk %2 hinzugefügt, Sie müssen die Synchronisierung überprüfen: %3. @@ -396,118 +396,118 @@ Wählen Sie diejenigen aus, die Sie synchronisieren möchten: KDC::ClientGui - + Please sign in Bitte melden Sie sich an - + Folder %1: %2 Ordner %1: %2 - + There are no sync folders configured. Es wurden keine Synchronisierungsordner konfiguriert. - + Synthesis Synthese - + Preferences Einstellungen - + Quit Beenden - + Undefined State. Undefinierter Zustand. - + Waiting to start syncing. Synchronisierung ausstehend. - + Sync is running. Synchronisierung läuft. - + Sync was successful, unresolved conflicts. Synchronisierung war erfolgreich, ungelöste Konflikte. - + Last Sync was successful. Die letzte Synchronisierung war erfolgreich. - + User Abort. Benutzer-Abbruch. - + Sync is paused. Synchronisierung wurde angehalten. - + %1 (Sync is paused) %1 (Synchronisierung wurde angehalten) - + Do you really want to remove the synchronizations of the account <i>%1</i> ?<br><b>Note:</b> This will <b>not</b> delete any files. Möchten Sie die Synchronisierungen des Kontos <i>%1</i> wirklich entfernen?<br><b>Hinweis:</b> Dadurch werden <b>keine</b> Dateien gelöscht. - + REMOVE ALL SYNCHRONIZATIONS ALLE SYNC. ENTFERNEN - + CANCEL ABBRECHEN - + Failed to start synchronizations! Synchronisierungen konnten nicht gestartet werden! - + Unable to open folder path %1. Ordnerpfad %1 kann nicht geöffnet werden. - + Unable to initialize kDrive client Der kDrive-Client kann nicht initialisiert werden - + Failed to fix conflict(s) on %1 item(s) in sync folder: %2 Konflikt(e) bei %1 Element(en) im Synchronisierungsordner %2 konnten nicht behoben werden - + Synchronization is paused Synchronisierung wird angehalten - - + + The shared link has been copied to the clipboard. Der freigegebene Link wurde in die Zwischenablage kopiert. @@ -680,153 +680,153 @@ Wählen Sie diejenigen aus, die Sie synchronisieren möchten: KDC::DebuggingDialog - + Info Info - + Debug Debuggen - + Warning Warnung - + Error Fehler - + Fatal Schwer - + Debugging settings Debugging-Einstellungen - + Save debugging information in a folder on my computer (Recommended) Debugging-Informationen in einem Ordner auf meinem Computer speichern (empfohlen) - + This information enables IT support to determine the origin of an incident. Mithilfe dieser Informationen kann der IT-Support den Ursprung eines Vorfalls ermitteln. - + <a style="%1" href="%2">Open debugging folder</a> <a style="%1" href="%2">Debugging-Ordner öffnen</a> - + Debug level Debug level - + The trace level lets you choose the extent of the debugging information recorded Mit der Trace-Ebene können Sie den Umfang der aufgezeichneten Debugging-Informationen auswählen - + The extended full log collects a detailed history that can be used for debugging. Enabling it can slow down the kDrive application. Das erweiterte vollständige Protokoll erfasst einen detaillierten Verlauf, der zum Debuggen verwendet werden kann. Die Aktivierung kann die kDrive-Anwendung verlangsamen. - + Extended Full Log Erweitertes vollständiges Protokoll - + Delete logs older than %1 days Protokolle löschen, die älter als %1 Tage sind - + Share the debug folder with Infomaniak support. Geben Sie den Debug-Ordner für den Infomaniak-Support frei. - + The last session is the periode since the last kDrive start. Die letzte Sitzung ist der Zeitraum seit dem letzten kDrive-Start. - + Share only the last kDrive session Teilen Sie nur die letzte kDrive-Sitzung - + Loading Wird geladen - + Cancel Abbrechen - + SAVE SPEICHERN - + CANCEL ABBRECHEN - + Failed to share Teilen fehlgeschlagen - + 1. Check that you are logged in <br>2. Check that you have configured at least one kDrive 1. Überprüfen Sie, ob Sie angemeldet sind <br>2. Überprüfen Sie, ob Sie mindestens ein kDrive konfiguriert haben - + (Connexion interrupted) (Verbindung unterbrochen) - + Share the folder with SwissTransfer <br> Teilen Sie den Ordner mit SwissTransfer <br> - + 1. We automatically compressed your log <a style="%1" href="%2">here</a>.<br> 1. Wir haben Ihr Protokoll <a style="%1" href="%2">hier</a> automatisch komprimiert.<br> - + 2. Transfer the archive with <a style="%1" href="%2">swisstransfer.com</a><br> 2. Übertragen Sie das Archiv mit <a style="%1" href="%2">swisstransfer.com</a><br> - + 3. Share the link with <a style="%1" href="%2"> support@infomaniak.com </a><br> 3. Teilen Sie den Link mit <a style="%1" href="%2"> support@infomaniak.com </a><br> - + Last upload the %1 Letzte Hochladung am %1 Letztes Hochladen von %1 - + Sharing has been cancelled Die Freigabe wurde abgebrochen @@ -836,40 +836,40 @@ Wählen Sie diejenigen aus, die Sie synchronisieren möchten: Der gesamte Ordner ist groß (> 100 MB) und kann einige Zeit für die Freigabe benötigen. Um die Freigabezeit zu reduzieren, empfehlen wir, nur die letzte kDrive-Sitzung freizugeben. - + %1/%2/%3 at %4h%5m and %6s Date format for the last successful log upload. %1: month, %2: day, %3: year, %4: hour, %5: minute, %6: second ie: Letzte Hochladung am 29.01.24 um 13:04:06 Uhr %2.%1.%3 um %4:%5:%6 Uhr - + Do you want to save your modifications? Wollen Sie Ihre Änderungen speichern? - - + + Unable to open folder %1. Ordner %1 kann nicht geöffnet werden. - + Share Teilen - + Sharing | step 1/2 %1% Teilen | Schritt 1/2 %1% - + Sharing | step 2/2 %1% Teilen | Schritt 2/2 %1% - + Canceling... Stornieren... @@ -1513,382 +1513,372 @@ Wählen Sie diejenigen aus, die Sie synchronisieren möchten: KDC::ParametersDialog - + Unable to open folder path %1. Ordnerpfad %1 kann nicht geöffnet werden. - + Transmission done!<br>Please refer to identifier <b>%1</b> in bug reports. Übertragung abgeschlossen!<br>Weitere Einzelheiten enthält der Identifier <b>%1</b> in den Fehlerberichten. - + Transmission failed! Please, use the following link to send the logs to the support: <a style="%1" href="%2">%2</a> Übertragung fehlgeschlagen! Bitte verwenden Sie den folgenden Link, um die Protokolle an den Support zu senden: <a style="%1" href="%2">%2</a> - + No kDrive configured! Kein kDrive eingerichtet! - - - - - - - - - - - + + + + + + + + + + + A technical error has occurred (error %1).<br>Please empty the history and if the error persists, contact our support team. Ein technischer Fehler ist aufgetreten (Fehler %1).<br>Bitte leeren Sie den Verlauf und kontaktieren Sie unser Support-Team, falls der Fehler weiterhin besteht. - + It seems that your network connection is configured with too low a timeout for the application to work correctly (error %1).<br>Please check your network configuration. Es scheint, dass Ihre Netzwerkverbindung mit einem zu niedrigen Timeout konfiguriert ist, als dass die Anwendung ordnungsgemäß funktionieren könnte (Fehler %1).<br>Bitte überprüfen Sie Ihre Netzwerkkonfiguration. - - + + Cannot connect to kDrive server (error %1).<br>Attempting reconnection. Please check your Internet connection and your firewall. Es kann keine Verbindung zum kDrive-Server hergestellt werden (Fehler %1).<br>Es wird versucht, die Verbindung wiederherzustellen. Bitte überprüfen Sie Ihre Internetverbindung und Ihre Firewall. - + A login problem has occurred (error %1).<br>Please log in again and if the error persists, contact our support team. Es ist ein Anmeldeproblem aufgetreten (Fehler %1).<br>Bitte melden Sie sich erneut an. Wenn der Fehler weiterhin besteht, wenden Sie sich an unser Support-Team. - + Old synchronisation database doesn't exist or is not accessible.<br>Old blacklist data haven't been migrated. Alte Synchronisationsdatenbank besteht nicht oder ist nicht zugänglich. <br/>Alte Blacklist-Daten wurden nicht migriert. - + A new version of the application is available.<br>Please update the application to continue using it. Eine neue Version der Anwendung ist verfügbar.<br>Bitte aktualisieren Sie die Anwendung, um sie weiterhin verwenden zu können. - + The log upload failed (error %1).<br>Please try again later. Das Hochladen des Protokolls ist fehlgeschlagen (Fehler %1).<br>Bitte versuchen Sie es später erneut. - - The item misses search permission (error %1).<br>Please check that you have search/exec access to the parent folder. - Für das Element fehlt die Suchberechtigung (Fehler %1).<br>Bitte überprüfen Sie, ob Sie Such-/Ausführungszugriff auf den übergeordneten Ordner haben. - - - + The synchronization folder is no longer accessible (error %1).<br>Synchronization will resume as soon as the folder is accessible. Auf den Synchronisierungsordner kann nicht mehr zugegriffen werden (Fehler %1).<br>Die Synchronisierung wird fortgesetzt, sobald auf den Ordner zugegriffen werden kann. - - The synchronization folder is inaccessible (error %1).<br>Please check that you have read access to this folder. - Auf den Synchronisierungsordner kann nicht zugegriffen werden (Fehler %1).<br>Bitte überprüfen Sie, ob Sie Lesezugriff auf diesen Ordner haben. - - - - The synchronization folder is inaccessible (error %1).<br>Please check that you have write access to this folder. - Der Synchronisierungsordner ist nicht zugänglich (Fehler %1). <br/>Bitte überprüfen Sie, ob Sie Schreibrechte für diesen Ordner haben. - - - + There is not enough space left on your disk.<br>The synchronization has been stopped. Es ist nicht mehr genug Speicherplatz auf Ihrer Festplatte vorhanden. <br/>Die Synchronisierung wurde angehalten. - + There is not enough memory left on your machine.<br>The synchronization has been stopped. Auf Ihrem Computer ist nicht mehr genügend Speicher vorhanden.<br>Die Synchronisierung wurde gestoppt. - + Unable to start synchronization (error %1).<br>You must allow:<br>- kDrive in System Settings >> Privacy & Security >> Security<br>- kDrive LiteSync Extension in System Settings >> Privacy & Security >> Full Disk Access. Die Synchronisierung konnte nicht gestartet werden (Fehler %1).<br>Sie müssen Folgendes zulassen:<br>- kDrive in den Systemeinstellungen >> Datenschutz und Sicherheit >> Sicherheit<br>- kDrive LiteSync-Erweiterung in den Systemeinstellungen >> Datenschutz und Sicherheit >> Vollständiger Festplattenzugriff. - + Unable to start Lite Sync plugin (error %1).<br>Check that the Lite Sync extension is installed and Windows Search service is enabled.<br>Please empty the history, restart and if the error persists, contact our support team. Das Lite Sync-Plugin kann nicht gestartet werden (Fehler %1).<br>Überprüfen Sie, ob die Lite Sync-Erweiterung installiert und der Windows-Suchdienst aktiviert ist.<br>Bitte leeren Sie den Verlauf, starten Sie neu und wenden Sie sich an unser Support-Team, wenn der Fehler weiterhin besteht. - + Unable to start Lite Sync plugin (error %1).<br>Check that the Lite Sync extension has the correct permissions and is running.<br>Please empty the history, restart and if the error persists, contact our support team. Das Lite Sync-Plugin konnte nicht gestartet werden (Fehler %1).<br>Überprüfen Sie, ob die Lite Sync-Erweiterung über die richtigen Berechtigungen verfügt und ausgeführt wird.<br>Bitte leeren Sie den Verlauf, starten Sie neu und wenn der Fehler weiterhin besteht, wenden Sie sich an unser Support-Team. - + Unable to start Lite Sync plugin (error %1).<br>Please empty the history, restart and if the error persists, contact our support team. Das Lite Sync-Plugin konnte nicht gestartet werden (Fehler %1).<br>Bitte leeren Sie den Verlauf, starten Sie neu und kontaktieren Sie unser Support-Team, wenn der Fehler weiterhin besteht. - + The kDrive is in maintenance mode.<br>Synchronization will begin again as soon as possible. Please contact our support team if the error persists. Der kDrive befindet sich im Wartungsmodus. Die <br/>Synchronisierung wird schnellstmöglich wieder aufgenommen. Bitte wenden Sie sich an unseren Support, sofern der Fehler weiterhin auftritt. - + The kDrive is blocked.<br>Please renew kDrive. If no action is taken, the data will be permanently deleted and it will be impossible to recover them. Der kDrive ist gesperrt. <br/>Bitte verlängern Sie kDrive. Wenn keine Massnahmen ergriffen werden, werden die Daten dauerhaft gelöscht und können nicht wiederhergestellt werden. - + The kDrive is blocked.<br>Please contact an administrator to renew the kDrive. If no action is taken, the data will be permanently deleted and it will be impossible to recover them. Der kDrive ist gesperrt. <br/>Bitte wenden Sie sich an einen Administrator, um den kDrive zu verlängern. Wenn keine Massnahmen ergriffen werden, werden die Daten dauerhaft gelöscht und können nicht wiederhergestellt werden. - + You are not authorised to access this kDrive.<br>Synchronization has been paused. Please contact an administrator. Sie sind nicht berechtigt, auf dieses kDrive zuzugreifen.<br>Die Synchronisierung wurde angehalten. Bitte wenden Sie sich an einen Administrator. - + A technical error has occurred (error %1).<br>Synchronization will resume as soon as possible. Please contact our support team if the error persists. Es ist ein technischer Fehler aufgetreten (Fehler %1).<br>Die Synchronisierung wird so bald wie möglich fortgesetzt. Bitte wenden Sie sich an unser Support-Team, wenn der Fehler weiterhin besteht. - + The network connections have been dropped by the kernel (error %1).<br>Please empty the history and if the error persists, contact our support team. Die Netzwerkverbindungen wurden vom Kernel unterbrochen (Fehler %1).<br>Bitte leeren Sie den Verlauf. Wenn der Fehler weiterhin besteht, wenden Sie sich an unser Support-Team. - + Unfortunately your old configuration could not be migrated.<br>The application will use a blank configuration. Leider konnte Ihre alte Konfiguration nicht migriert werden. <br/>Das Programm verwendet eine leere Konfiguration. - + Unfortunately your old proxy configuration could not be migrated, SOCKS5 proxies are not supported at this time.<br>The application will use system proxy settings instead. Leider konnte Ihre alte Proxy-Konfiguration nicht migriert werden, SOCKS5-Proxies werden derzeit nicht unterstützt. Stattdessen werden <br/>die System-Proxyeinstellungen verwendet. - + A technical error has occurred (error %1).<br>Synchronization has been restarted. Please empty the history and if the error persists, please contact our support team. Ein technischer Fehler (Fehler %1) ist aufgetreten. Die <br/>Synchronisierung wurde neu gestartet. Bitte leeren Sie den Verlauf; sollte der Fehler weiterhin auftreten, dann wenden Sie sich an unseren Support. - + An error accessing the synchronization database has happened (error %1).<br>Synchronization has been stopped. Beim Zugriff auf die Synchronisierungsdatenbank ist ein Fehler aufgetreten (Fehler %1). Die <br/>Synchronisierung wurde angehalten. - + A login problem has occurred (error %1).<br>Token invalid or revoked. Es ist ein Anmeldeproblem aufgetreten (Fehler %1).<br>Token ungültig oder widerrufen. - + Nested synchronizations are prohibited (error %1).<br>You should only keep synchronizations whose folders are not nested. Verschachtelte Synchronisierungen sind verboten (Fehler %1).<br>Sie sollten nur Synchronisierungen behalten, deren Ordner nicht verschachtelt sind. - - The app does not have write rights to the synchronization folder.<br>The synchronization has been stopped. - Die App hat keine Schreibrechte für den Synchronisierungsordner.<br>Die Synchronisierung wurde gestoppt. - - - + File name parsing error (error %1).<br>Special characters such as double quotes, backslashes or line returns can cause parsing failures. Fehler beim Parsen des Dateinamens (Fehler %1).<br>Sonderzeichen wie doppelte Anführungszeichen, umgekehrte Schrägstriche oder Zeilenumbrüche können zu Parsingfehlern führen. - + An element was moved to a deleted folder.<br>The move has been canceled. Ein Element wurde in einen gelöschten Ordner verschoben. <br/>Die Verschiebung wurde abgebrochen. - + This element was moved by another user.<br>The deletion has been canceled. Dieses Element wurde von einem anderen Benutzer verschoben. <br/>Das Löschen wurde abgebrochen. - + An element was created in this folder while it was being deleted.<br>The delete operation has been propagated anyway. Während des Löschens wurde in diesem Ordner ein Element erstellt.<br>Der Löschvorgang wurde trotzdem weitergegeben. - + This element has been moved somewhere else.<br>The local operation has been canceled. Dieses Element wurde an einen anderen Ort verschoben. <br/>Der lokale Vorgang wurde abgebrochen. - - + + An element with the same name already exists in this location.<br>The local element has been renamed. An diesem Ort besteht bereits ein Element mit dem gleichen Namen. <br/>Das lokale Element wurde umbenannt. - + An element with the same name already exists in this location.<br>The local operation has been canceled. An diesem Ort besteht bereits ein Element mit dem gleichen Namen. <br/>Der lokale Vorgang wurde abgebrochen. - + The content of the file was modified while it was being deleted.<br>The deletion has been canceled. Der Inhalt der Datei wurde während des Löschens verändert. <br/>Das Löschen wurde abgebrochen. - + The content of a synchronized element was modified while a parent folder was being deleted (e.g. the folder containing the current folder).<br>The file has been moved to the root of your kDrive. Der Inhalt eines synchronisierten Elements wurde geändert, während ein übergeordneter Ordner gelöscht wurde (z.B. der Ordner mit dem aktuellen Ordner). <br/>Die Datei wurde in das Stammverzeichnis Ihres kDrive verschoben. - + The content of an already synchronized file has been modified while this one or one of its parent folders has been deleted.<br> Der Inhalt einer bereits synchronisierten Datei wurde geändert, während diese oder eines ihrer übergeordneten Verzeichnisse gelöscht wurde.<br> - + The file was modified at the same time by another user.<br>Your modifications have been saved in a copy. Die Datei wurde zur gleichen Zeit von einem anderen Benutzer geändert. <br/>Ihre Änderungen wurden in einer Kopie gespeichert. - + Another user has moved a parent folder of the destination.<br>The local operation has been canceled. Ein anderer Benutzer hat einen übergeordneten Ordner des Ziels verschoben. <br/>Der lokale Vorgang wurde abgebrochen. - + An existing file/directory has an identical name with the same case options (same upper and lower case letters).<br>The file/directory has been temporarily blacklisted. Eine vorhandene Datei/ein vorhandenes Verzeichnis hat einen identischen Namen mit denselben Groß- und Kleinschreibungsoptionen (gleiche Groß- und Kleinbuchstaben).<br>Die Datei/das Verzeichnis wurde vorübergehend auf die schwarze Liste gesetzt. - + The file/directory name contains an unsupported character.<br>The file/directory has been temporarily blacklisted. Der Datei-/Verzeichnisname enthält ein nicht unterstütztes Zeichen.<br>Die Datei/das Verzeichnis wurde vorübergehend auf die schwarze Liste gesetzt. - + This file/directory name is reserved by your operating system.<br>The file/directory has been temporarily blacklisted. Dieser Datei-/Verzeichnisname ist von Ihrem Betriebssystem reserviert.<br>Die Datei/das Verzeichnis wurde vorübergehend auf die schwarze Liste gesetzt. - + The file/directory name is too long.<br>The file/directory has been temporarily blacklisted. Der Datei-/Verzeichnisname ist zu lang.<br>Die Datei/das Verzeichnis wurde vorübergehend auf die schwarze Liste gesetzt. - + The file/directory path is too long.<br>The file/directory is ignored. Der Datei-/Verzeichnispfad ist zu lang.<br>Die Datei/das Verzeichnis wird ignoriert. - + The file/directory name contains a recent UNICODE character not yet supported by your filesystem.<br>The parent directory has been excluded from synchronization. Der Datei-/Verzeichnisname enthält ein aktuelles UNICODE-Zeichen, das von Ihrem Dateisystem noch nicht unterstützt wird.<br>Das übergeordnete Verzeichnis wurde von der Synchronisierung ausgeschlossen. - + The file/directory name coincides with the name of another item in the same directory.<br>This item is temporarily blacklisted. Consider removing duplicate items. Der Datei-/Verzeichnisname stimmt mit dem Namen eines anderen Elements im selben Verzeichnis überein.<br>Dieses Element steht vorübergehend auf der schwarzen Liste. Ziehen Sie in Erwägung, doppelte Elemente zu entfernen. - + Either you are not allowed to create an item, or another item already exists with the same name.<br>The item has been excluded from synchronization. Entweder ist es Ihnen nicht erlaubt, einen Eintrag zu erstellen, oder es existiert bereits ein anderer Eintrag mit demselben Namen.<br>Der Eintrag wurde von der Synchronisierung ausgeschlossen. - + You are not allowed to edit item.<br>The file containing your modifications has been renamed and excluded from synchronization. Sie dürfen keine Elemente bearbeiten. <br/>Die Datei mit Ihren Änderungen wurde umbenannt und von der Synchronisierung ausgeschlossen. - + You are not allowed to rename item.<br>It will be restored with its original name. Sie dürfen das Element nicht umbenennen. <br/>Es wird mit seinem ursprünglichen Namen wiederhergestellt. - + You are not allowed to move item to "%1".<br>It will be restored to its original location. Sie dürfen das Element nicht zu "%1" verschieben.<br>Es wird an seinem ursprünglichen Ort wiederhergestellt. - + You are not allowed to delete item.<br>It will be restored to its original location. Sie dürfen das Element nicht löschen. <br/>Es wird an seinem ursprünglichen Ort wiederhergestellt. - + Failed to move this item to trash, it has been blacklisted. Dieses Objekt konnte nicht in den Papierkorb verschoben werden, es wurde auf die schwarze Liste gesetzt. - + This item has been excluded from sync because it is an hard link Dieses Element wurde von der Synchronisierung ausgeschlossen, da es sich um einen Hardlink handelt. - + The operation performed on item is forbidden.<br>The item has been temporarily blacklisted. Der Vorgang, der mit dem Artikel durchgeführt wurde, ist verboten.<br>Der Artikel wurde vorübergehend auf die schwarze Liste gesetzt. - + The operation performed on this item failed.<br>The item has been temporarily blacklisted. Der für diesen Artikel durchgeführte Vorgang ist fehlgeschlagen.<br>Der Artikel wurde vorübergehend auf die schwarze Liste gesetzt. - - Can't access item.<br>Please fix the write permissions and restart the synchronization. - Zugriff auf Element nicht möglich.<br>Bitte korrigieren Sie die Schreibberechtigungen und starten Sie die Synchronisation neu. - - - + Move to trash failed. Verschieben in den Papierkorb fehlgeschlagen. - + The file is too large to be uploaded. It has been temporarily blacklisted. Die Datei ist zu groß, um hochgeladen zu werden. Sie wurde vorübergehend auf die schwarze Liste gesetzt. - + Impossible to download the file. Es ist nicht möglich, die Datei herunterzuladen. - + You have exceeded your quota. Increase your space quota to re-enable file upload. Sie haben Ihr Kontingent überschritten. Erhöhen Sie Ihr Speicherplatzkontingent, um den Datei-Upload wieder zu aktivieren. - + + The synchronization folder is inaccessible (error %1).<br>Please check that you have read and write access to this folder. + Auf den Synchronisationsordner kann nicht zugegriffen werden (Fehler %1).<br>Bitte überprüfen Sie, ob Sie Lese- und Schreibrechte für diesen Ordner haben. + + + This item already exists on remote kDrive. It is not synced because it has been blacklisted. Dieser Artikel existiert bereits auf dem entfernten kDrive. Er wird nicht synchronisiert, da er auf der Blacklist steht. - + This item already exists on local file system. It is not synced. Dieser Artikel existiert bereits im lokalen Dateisystem. Er wird nicht synchronisiert. - + Failed to synchronize this item. It has been temporarily blacklisted.<br>Another attempt to sync it will be done in one hour or on next application startup. Synchronisierung dieses Elements fehlgeschlagen. Es wurde vorübergehend auf die Blacklist gesetzt.<br>Ein weiterer Versuch zur Synchronisierung wird in einer Stunde oder beim nächsten Start der Anwendung durchgeführt. - + This item has been excluded from sync by a custom template.<br>You can disable this type of notification from the Preferences Dieser Artikel wurde durch eine benutzerdefinierte Vorlage vom Sync ausgeschlossen. Sie können diese Art von Benachrichtigung in den Einstellungen deaktivieren - - + + Synchronization error. Synchronisierungsfehler. - + + Can't access item.<br>Please fix the read and write permissions. + Zugriff auf Element nicht möglich.<br>Bitte korrigieren Sie die Lese- und Schreibberechtigungen. + + + + System error. + Systemfehler. + + + A technical error has occurred.<br>Please empty the history and if the error persists, contact our support team. Es ist ein technischer Fehler aufgetreten.<br>Bitte leeren Sie den Verlauf. Wenn der Fehler weiterhin besteht, wenden Sie sich an unser Support-Team. @@ -2218,35 +2208,35 @@ Bitte verwenden Sie den folgenden Link, um die Protokolle an den Support zu send KDC::SocketApi - - - + + + Copy private share link Link zur privaten Freigabe kopieren - - + + Resharing this file is not allowed Die erneute Freigabe dieser Datei ist nicht erlaubt - - + + Resharing this folder is not allowed Die erneute Freigabe dieses Ordners ist nicht erlaubt - - - - + + + + Copy public share link Öffentlichen Freigabelink kopieren - - + + Open in browser Im Browser öffnen @@ -2322,202 +2312,202 @@ Bitte verwenden Sie den folgenden Link, um die Protokolle an den Support zu send KDC::SynthesisPopover - - + + Never Nie - + During 1 hour 1 Stunde lang - - + + Until tomorrow 8:00AM Bis morgen 8 Uhr - + During 3 days 3 Tage lang - + During 1 week 1 Woche lang - - + + Always Immer - + For 1 more hour Für 1 weitere Stunde - + For 3 more days Für weitere 3 Tage - + For 1 more week Für 1 weitere Woche - + Update kDrive App Aktualisieren Sie die kDrive-App - + This kDrive app version is not supported anymore. To access the latest features and enhancements, please update. Diese kDrive-App-Version wird nicht mehr unterstützt. Um auf die neuesten Funktionen und Verbesserungen zuzugreifen, aktualisieren Sie bitte. - - + + Update Aktualisieren - + Please download the latest version on the website. Bitte laden Sie die neueste Version auf der Website herunter. - + Update download in progress Update-Download läuft - + Looking for update... Auf der Suche nach Updates... - + Manual update Manuelles Update - + Unavailable Nicht verfügbar - + Quit kDrive kDrive beenden - + Show errors and informations Fehler und Informationen anzeigen - + Show informations Informationen anzeigen - + You can synchronize files <a style="%1" href="%2">from your computer</a> or on <a style="%1" href="%3">kdrive.infomaniak.com</a>. Sie können Dateien <a style="%1" href="%2">von Ihrem Computer</a> oder von <a style="%1" href="%3">kdrive.infomaniak.com</a> synchronisieren. - + Open in folder Im Ordner öffnen - + More actions Weitere Aktionen - + Synchronized Synchronisiert - + Favorites Favoriten - + Activity Aktivität - - + + Not implemented! Nicht implementiert! - + No synchronized folder for this Drive! Kein synchronisierter Ordner für diesen kDrive! - + No kDrive configured! Kein kDrive eingerichtet! - + Unable to access web site %1. Zugang zu Website %1 nicht möglich. - + Open %1 web version Webversion %1 öffnen - + Notifications disabled until %1 Benachrichtigungen deaktiviert bis %1 - + Disable Notifications Benachrichtigungen deaktivieren - + Need help Hilfe benötigt - + Unable to open link %1. Link %1 kann nicht geöffnet werden. - + Invalid link %1. Ungültiger Link %1. - + Unable to open folder url %1. Ordner-URL %1 kann nicht geöffnet werden. - + Drive parameters Drive-Einstellungen - + Application preferences Anwendungseinstellungen @@ -2647,47 +2637,47 @@ Bitte verwenden Sie den folgenden Link, um die Protokolle an den Support zu send Einstellungen können nicht gespeichert werden! - + The parent folder is a sync folder or contained in one Der übergeordnete Ordner ist ein Sync-Ordner oder befindet sich in einem / einer - + Can't find a valid path Kann keinen gültigen Pfad finden - + No valid folder selected! Kein gültiger Ordner ausgewählt! - + The selected path does not exist! Der ausgewählte Pfad existiert nicht! - + The selected path is not a folder! Der ausgewählte Pfad ist kein Ordner! - + You have no permission to write to the selected folder! Sie haben keine Schreibberechtigung für den ausgewählten Ordner! - + The local folder %1 contains a folder already synced. Please pick another one! Der lokale Ordner %1 enthält einen bereits synchronisierten Ordner. Bitte wählen Sie einen anderen! - + The local folder %1 is contained in a folder already synced. Please pick another one! Der lokale Ordner %1 befindet sich in einem bereits synchronisierten Ordner. Bitte wählen Sie einen anderen! - + The local folder %1 is already synced on the same drive. Please pick another one! Der lokale Ordner %1 ist bereits auf demselben Drive synchronisiert. Bitte wählen Sie einen anderen! @@ -2807,23 +2797,23 @@ Bitte verwenden Sie den folgenden Link, um die Protokolle an den Support zu send utility - + Cancel free up local space Lokalen Speicherplatz freigeben abbrechen - - + + Cancel make available locally Lokal verfügbar machen abbrechen - + Free up local space Lokalen Speicherplatz freigeben - + Always make available locally Immer lokal verfügbar machen diff --git a/translations/client_es.ts b/translations/client_es.ts index 5174b3c89..7fafeb01f 100644 --- a/translations/client_es.ts +++ b/translations/client_es.ts @@ -288,12 +288,12 @@ KDC::AppServer - + kDrive application is already running! ¡La aplicación kDrive ya se está ejecutando! - + %1 and %n other file(s) have been removed. %1 y otros %n archivo(s) han sido borrados. @@ -301,13 +301,13 @@ - + %1 has been removed. %1 names a file. %1 ha sido eliminado. - + %1 and %n other file(s) have been added. %1 y % otros archivo(s) han sido añadidos. @@ -315,13 +315,13 @@ - + %1 has been added. %1 names a file. %1 ha sido añadido. - + %1 and %n other file(s) have been updated. %1 y otros %n archivo(s) han sido actualizados. @@ -329,13 +329,13 @@ - + %1 has been updated. %1 names a file. %1 ha sido actualizado. - + %1 has been moved to %2 and %n other file(s) have been moved. %1 ha sido movido a %2 y otros %n archivo(s) han sido movidos. @@ -343,17 +343,17 @@ - + %1 has been moved to %2. %1 ha sido movido a %2. - + Sync Activity Actividad de sincronización - + A new folder larger than %1 MB has been added in the drive %2, you must validate its synchronization: %3. Se ha añadido una nueva carpeta mayor a %1 MB en el drive %2, debes validar su sincronización: %3. @@ -396,118 +396,118 @@ Selecciona los que quieras sincronizar: KDC::ClientGui - + Please sign in Inicia sesión - + Folder %1: %2 Carpeta %1: %2 - + There are no sync folders configured. No hay carpetas de sincronización configuradas. - + Synthesis Síntesis - + Preferences Preferencias - + Quit Salir - + Undefined State. Estado no definido. - + Waiting to start syncing. Esperando para comenzar la sincronización. - + Sync is running. Ejecutando sincronización. - + Sync was successful, unresolved conflicts. La sincronización se ha realizado, pero hay conflictos sin resolver. - + Last Sync was successful. La última sincronización se ha realizado correctamente. - + User Abort. Interrupción por el usuario. - + Sync is paused. La sincronización está en pausa. - + %1 (Sync is paused) %1 (sincronización en pausa) - + Do you really want to remove the synchronizations of the account <i>%1</i> ?<br><b>Note:</b> This will <b>not</b> delete any files. ¿Realmente desea eliminar las sincronizaciones de la cuenta <i>%1</i>?<br><b>Nota:</b> Esto <b>no</b> eliminará ningún archivo. - + REMOVE ALL SYNCHRONIZATIONS ELIMINAR TODAS LAS SINC. - + CANCEL CANCELAR - + Failed to start synchronizations! ¡Error al iniciar las sincronizaciones! - + Unable to open folder path %1. No es posible abrir la ruta de la carpeta %1. - + Unable to initialize kDrive client No se puede inicializar el cliente de kDrive - + Failed to fix conflict(s) on %1 item(s) in sync folder: %2 No se pudieron solucionar los conflictos en %1 elementos en la carpeta de sincronización: %2 - + Synchronization is paused La sincronización está en pausa - - + + The shared link has been copied to the clipboard. El enlace compartido se ha copiado en el portapapeles. @@ -680,152 +680,152 @@ Selecciona los que quieras sincronizar: KDC::DebuggingDialog - + Info Información - + Debug Depurar - + Warning Advertencia - + Error Error - + Fatal Fatal - + Debugging settings Configuración de depuración - + Save debugging information in a folder on my computer (Recommended) Guardar información de depuración en una carpeta de mi computadora (recomendado) - + This information enables IT support to determine the origin of an incident. Esta información permite al soporte de TI determinar el origen de un incidente. - + <a style="%1" href="%2">Open debugging folder</a> <a style="%1" href="%2">Abrir carpeta de depuración</a> - + Debug level Nivel de depuración - + The trace level lets you choose the extent of the debugging information recorded El nivel de seguimiento le permite elegir el alcance de la información de depuración registrada - + The extended full log collects a detailed history that can be used for debugging. Enabling it can slow down the kDrive application. El registro completo extendido recopila un historial detallado que se puede utilizar para la depuración. Habilitarlo puede ralentizar la aplicación kDrive. - + Extended Full Log Registro completo extendido - + Delete logs older than %1 days Eliminar registros de más de %1 días - + Share the debug folder with Infomaniak support. Comparte la carpeta de depuración con el soporte de Infomaniak. - + The last session is the periode since the last kDrive start. La última sesión es el período desde el último inicio de kDrive. - + Share only the last kDrive session Comparte solo la última sesión de kDrive - + Loading Cargando - + Cancel Cancelar - + SAVE GUARDAR - + CANCEL CANCELAR - + Failed to share No se pudo compartir - + 1. Check that you are logged in <br>2. Check that you have configured at least one kDrive 1. Verifique que haya iniciado sesión <br>2. Comprueba que tienes configurado al menos un kDrive - + (Connexion interrupted) (Conexión interrumpida) - + Share the folder with SwissTransfer <br> Compartir la carpeta con SwissTransfer <br> - + 1. We automatically compressed your log <a style="%1" href="%2">here</a>.<br> 1. Comprimimos automáticamente su registro <a style="%1" href="%2">aquí</a>.<br> - + 2. Transfer the archive with <a style="%1" href="%2">swisstransfer.com</a><br> 2. Transfiera el archivo con <a style="%1" href="%2">swisstransfer.com</a><br> - + 3. Share the link with <a style="%1" href="%2"> support@infomaniak.com </a><br> 3. Comparte el enlace con <a style="%1" href="%2"> support@infomaniak.com </a><br> - + Last upload the %1 Última carga el %1 - + Sharing has been cancelled Compartir ha sido cancelado @@ -835,39 +835,39 @@ Selecciona los que quieras sincronizar: La carpeta completa es grande (> 100 MB) y puede tardar algún tiempo en compartirse. Para reducir el tiempo de compartición, le recomendamos que comparta sólo la última sesión de kDrive. - + %1/%2/%3 at %4h%5m and %6s Date format for the last successful log upload. %1: month, %2: day, %3: year, %4: hour, %5: minute, %6: second %2/%1/%3 a las %4:%5 y %6s - + Do you want to save your modifications? ¿Deseas guardar tus cambios? - - + + Unable to open folder %1. No se puede abrir la carpeta %1. - + Share Compartir - + Sharing | step 1/2 %1% Compartir | paso 1/2 %1% - + Sharing | step 2/2 %1% Compartir | paso 2/2 %1% - + Canceling... Cancelado... @@ -1511,383 +1511,372 @@ Selecciona los que quieras sincronizar: KDC::ParametersDialog - + Unable to open folder path %1. No es posible abrir la ruta de la carpeta %1. - + Transmission done!<br>Please refer to identifier <b>%1</b> in bug reports. ¡Transmisión realizada!<br>Consulta el identificador <b>%1</b> en informes de fallos. - + Transmission failed! Please, use the following link to send the logs to the support: <a style="%1" href="%2">%2</a> ¡La transmisión falló! Por favor, utilice el siguiente enlace para enviar los registros al soporte: <a style="%1" href="%2">%2</a> - + No kDrive configured! ¡No hay ningún kDrive configurado! - - - - - - - - - - - + + + + + + + + + + + A technical error has occurred (error %1).<br>Please empty the history and if the error persists, contact our support team. Se ha producido un error técnico (error %1).<br>Vacíe el historial y, si el error persiste, póngase en contacto con nuestro equipo de soporte. - + It seems that your network connection is configured with too low a timeout for the application to work correctly (error %1).<br>Please check your network configuration. Parece que su conexión de red está configurada con un tiempo de espera demasiado bajo para que la aplicación funcione correctamente (error %1).<br>Compruebe su configuración de red. - - + + Cannot connect to kDrive server (error %1).<br>Attempting reconnection. Please check your Internet connection and your firewall. No se puede conectar al servidor kDrive (error %1).<br>Intentando reconexión. Por favor verifique su conexión a Internet y su firewall. - + A login problem has occurred (error %1).<br>Please log in again and if the error persists, contact our support team. Se ha producido un problema de inicio de sesión (error %1).<br>Inicie sesión nuevamente y, si el error persiste, comuníquese con nuestro equipo de soporte. - + Old synchronisation database doesn't exist or is not accessible.<br>Old blacklist data haven't been migrated. La antigua base de datos de sincronización no existe o no es accesible.<br>Los datos de la lista negra antigua no se han migrado. - + A new version of the application is available.<br>Please update the application to continue using it. Hay una nueva versión de la aplicación disponible.<br>Actualice la aplicación para seguir usándola. - + The log upload failed (error %1).<br>Please try again later. Error al cargar el registro (error %1).<br>Inténtelo de nuevo más tarde. - - The item misses search permission (error %1).<br>Please check that you have search/exec access to the parent folder. - El elemento no tiene permiso de búsqueda (error %1).<br>Compruebe que tiene acceso de búsqueda/ejecución a la carpeta principal. - - - + The synchronization folder is no longer accessible (error %1).<br>Synchronization will resume as soon as the folder is accessible. Ya no se puede acceder a la carpeta de sincronización (error %1).<br>La sincronización se reanudará tan pronto como se pueda acceder a la carpeta. - - The synchronization folder is inaccessible (error %1).<br>Please check that you have read access to this folder. - No se puede acceder a la carpeta de sincronización (error %1).<br>Compruebe que tiene acceso de lectura a esta carpeta. - - - - The synchronization folder is inaccessible (error %1).<br>Please check that you have write access to this folder. - La carpeta de sincronización es inaccesible (error %1). Comprueba que tienes acceso de escritura a esta carpeta. - - - + There is not enough space left on your disk.<br>The synchronization has been stopped. No queda suficiente espacio en tu disco.<br>La sincronización se ha detenido. - + There is not enough memory left on your machine.<br>The synchronization has been stopped. No queda suficiente memoria en su máquina.<br>La sincronización se ha detenido. - + Unable to start synchronization (error %1).<br>You must allow:<br>- kDrive in System Settings >> Privacy & Security >> Security<br>- kDrive LiteSync Extension in System Settings >> Privacy & Security >> Full Disk Access. No se puede iniciar la sincronización (error %1).<br>Debe permitir:<br>- kDrive en Configuración del sistema >> Privacidad y seguridad >> Seguridad<br>- Extensión kDrive LiteSync en Configuración del sistema >> Privacidad y seguridad >> Acceso total al disco. - + Unable to start Lite Sync plugin (error %1).<br>Check that the Lite Sync extension is installed and Windows Search service is enabled.<br>Please empty the history, restart and if the error persists, contact our support team. No se puede iniciar el complemento Lite Sync (error %1).<br>Compruebe que la extensión Lite Sync esté instalada y que el servicio de búsqueda de Windows esté habilitado.<br>Vacia el historial, reinicia y, si el error persiste, contacta a nuestro equipo de soporte. - + Unable to start Lite Sync plugin (error %1).<br>Check that the Lite Sync extension has the correct permissions and is running.<br>Please empty the history, restart and if the error persists, contact our support team. No se puede iniciar el complemento Lite Sync (error %1).<br>Compruebe que la extensión Lite Sync tenga los permisos correctos y se esté ejecutando.<br>Vacia el historial, reinicia y, si el error persiste, contacta a nuestro equipo de soporte. - + Unable to start Lite Sync plugin (error %1).<br>Please empty the history, restart and if the error persists, contact our support team. No se puede iniciar el complemento Lite Sync (error %1).<br>Vacia el historial, reinicia y, si el error persiste, contacta a nuestro equipo de soporte. - + The kDrive is in maintenance mode.<br>Synchronization will begin again as soon as possible. Please contact our support team if the error persists. kDrive está en modo de mantenimiento.<br>La sincronización comenzará de nuevo lo antes posible. Ponte en contacto con nuestro equipo de asistencia si el error persiste. - + The kDrive is blocked.<br>Please renew kDrive. If no action is taken, the data will be permanently deleted and it will be impossible to recover them. El kDrive está bloqueado.<br>Renueva kDrive. Si no se toman medidas, los datos se eliminarán permanentemente y será imposible recuperarlos. - + The kDrive is blocked.<br>Please contact an administrator to renew the kDrive. If no action is taken, the data will be permanently deleted and it will be impossible to recover them. El kDrive está bloqueado.<br>Ponte en contacto con un administrador para renovar el kDrive. Si no se toman medidas, los datos se eliminarán permanentemente y será imposible recuperarlos. - + You are not authorised to access this kDrive.<br>Synchronization has been paused. Please contact an administrator. No estás autorizado a acceder a este kDrive.<br>La sincronización se ha pausado. Por favor contacte a un administrador. - + A technical error has occurred (error %1).<br>Synchronization will resume as soon as possible. Please contact our support team if the error persists. Se ha producido un error técnico (error %1).<br>La sincronización se reanudará lo antes posible. Comuníquese con nuestro equipo de soporte si el error persiste. - + The network connections have been dropped by the kernel (error %1).<br>Please empty the history and if the error persists, contact our support team. El kernel ha interrumpido las conexiones de red (error %1).<br>Vacia el historial y, si el error persiste, ponte en contacto con nuestro equipo de soporte. - + Unfortunately your old configuration could not be migrated.<br>The application will use a blank configuration. Desafortunadamente no se ha podido migrar tu configuración anterior.<br>La aplicación usará una configuración en blanco. - + Unfortunately your old proxy configuration could not be migrated, SOCKS5 proxies are not supported at this time.<br>The application will use system proxy settings instead. Desafortunadamente no se ha podido migrar tu antigua configuración de proxy. Los proxies SOCKS5 no son compatibles en este momento.<br>La aplicación usará la configuración del proxy del sistema en su lugar. - + A technical error has occurred (error %1).<br>Synchronization has been restarted. Please empty the history and if the error persists, please contact our support team. Se ha producido un error técnico (error %1).<br>Se ha reiniciado la sincronización. Vacía el historial y si el error persiste, contacta con nuestro equipo de asistencia. - + An error accessing the synchronization database has happened (error %1).<br>Synchronization has been stopped. Se ha producido un error al acceder a la base de datos de sincronización (error %1).<br>La sincronización se ha detenido. - + A login problem has occurred (error %1).<br>Token invalid or revoked. Se ha producido un problema de inicio de sesión (error %1).<br>Token no válido o revocado. - + Nested synchronizations are prohibited (error %1).<br>You should only keep synchronizations whose folders are not nested. Las sincronizaciones anidadas están prohibidas (error %1).<br>Solo debes conservar las sincronizaciones cuyas carpetas no estén anidadas. - - The app does not have write rights to the synchronization folder.<br>The synchronization has been stopped. - La aplicación no tiene derechos de escritura en la carpeta de sincronización.<br>La sincronización se ha detenido. - - - + File name parsing error (error %1).<br>Special characters such as double quotes, backslashes or line returns can cause parsing failures. Error de análisis del nombre de archivo (error %1).<br>Los caracteres especiales como comillas dobles, barras invertidas o retornos de línea pueden provocar errores de análisis. - + An element was moved to a deleted folder.<br>The move has been canceled. Se ha movido un elemento a una carpeta eliminada.<br>El movimiento ha sido cancelado. - + This element was moved by another user.<br>The deletion has been canceled. Este elemento ha sido movido por otro usuario.<br>La eliminación ha sido cancelada. - + An element was created in this folder while it was being deleted.<br>The delete operation has been propagated anyway. Se creó un elemento en esta carpeta mientras se eliminaba.<br>La operación de eliminación se propagó de todos modos. - + This element has been moved somewhere else.<br>The local operation has been canceled. Este elemento se ha movido a otro lugar.<br>La operación local ha sido cancelada. - - + + An element with the same name already exists in this location.<br>The local element has been renamed. Ya existe un elemento con el mismo nombre en esta ubicación.<br>Se ha cambiado el nombre del elemento local. - + An element with the same name already exists in this location.<br>The local operation has been canceled. Ya existe un elemento con el mismo nombre en esta ubicación.<br>La operación local ha sido cancelada. - + The content of the file was modified while it was being deleted.<br>The deletion has been canceled. El contenido del archivo se modificó mientras se estaba borrando.<br>La eliminación ha sido cancelada. - + The content of a synchronized element was modified while a parent folder was being deleted (e.g. the folder containing the current folder).<br>The file has been moved to the root of your kDrive. El contenido de un elemento sincronizado se modificó mientras se estaba borrando una carpeta principal (p. ej., la carpeta que contiene la carpeta actual).<br>El archivo se ha movido a la raíz de tu kDrive. - + The content of an already synchronized file has been modified while this one or one of its parent folders has been deleted.<br> El contenido de un archivo ya sincronizado se cambió cuando el archivo o un directorio principal se había eliminado.<br> - + The file was modified at the same time by another user.<br>Your modifications have been saved in a copy. El archivo fue modificado al mismo tiempo por otro usuario.<br>Tus modificaciones se han guardado en una copia. - + Another user has moved a parent folder of the destination.<br>The local operation has been canceled. Otro usuario ha movido una carpeta principal del destino.<br>La operación local ha sido cancelada. - + An existing file/directory has an identical name with the same case options (same upper and lower case letters).<br>The file/directory has been temporarily blacklisted. Un archivo/directorio existente tiene un nombre idéntico con las mismas opciones de mayúsculas y minúsculas (mismas letras mayúsculas y minúsculas).<br>El archivo/directorio se ha incluido temporalmente en la lista negra. - + The file/directory name contains an unsupported character.<br>The file/directory has been temporarily blacklisted. El nombre del archivo/directorio contiene un carácter no admitido.<br>El archivo/directorio se ha incluido temporalmente en la lista negra. - + This file/directory name is reserved by your operating system.<br>The file/directory has been temporarily blacklisted. Este nombre de archivo/directorio está reservado por su sistema operativo.<br>El archivo/directorio se ha incluido temporalmente en la lista negra. - + The file/directory name is too long.<br>The file/directory has been temporarily blacklisted. El nombre del archivo/directorio es demasiado largo.<br>El archivo/directorio se ha incluido temporalmente en la lista negra. - + The file/directory path is too long.<br>The file/directory is ignored. La ruta del archivo/directorio es demasiado larga.<br>El archivo/directorio se ignora. - + The file/directory name contains a recent UNICODE character not yet supported by your filesystem.<br>The parent directory has been excluded from synchronization. El nombre del archivo/directorio contiene un carácter UNICODE reciente que aún no es compatible con su sistema de archivos.<br>El directorio principal se ha excluido de la sincronización. - + The file/directory name coincides with the name of another item in the same directory.<br>This item is temporarily blacklisted. Consider removing duplicate items. El nombre del archivo/directorio coincide con el nombre de otro elemento en el mismo directorio.<br>Este elemento está temporalmente en la lista negra. Considere eliminar elementos duplicados. - + Either you are not allowed to create an item, or another item already exists with the same name.<br>The item has been excluded from synchronization. O bien no se le permite crear un elemento, o bien ya existe otro elemento con el mismo nombre.<br>El elemento se ha excluido de la sincronización. - + You are not allowed to edit item.<br>The file containing your modifications has been renamed and excluded from synchronization. No tienes permiso para editar elementos.<br>Se ha cambiado el nombre del archivo que contiene tus modificaciones y se le ha excluido de la sincronización. - + You are not allowed to rename item.<br>It will be restored with its original name. No tienes permiso para cambiar el nombre del elemento.<br>Se restaurará con su nombre original. - + You are not allowed to move item to "%1".<br>It will be restored to its original location. No tienes permiso para mover el elemento a "%1".<br>Se restaurará a su ubicación original. - + You are not allowed to delete item.<br>It will be restored to its original location. No tienes permiso para eliminar el elemento.<br>Se restaurará a su ubicación original. - + Failed to move this item to trash, it has been blacklisted. No se ha podido mover este elemento a la papelera, se ha incluido en la lista negra. - + This item has been excluded from sync because it is an hard link Este elemento se ha excluido de la sincronización porque es un enlace duro - + The operation performed on item is forbidden.<br>The item has been temporarily blacklisted. La operación realizada en el artículo está prohibida.<br>El artículo ha sido incluido temporalmente en la lista negra. - + The operation performed on this item failed.<br>The item has been temporarily blacklisted. La operación realizada en este artículo ha fallado.<br>El artículo ha sido incluido temporalmente en la lista negra. - - Can't access item.<br>Please fix the write permissions and restart the synchronization. - Mover a la papelera fallido. - No se puede acceder al elemento.<br>Corrija los permisos de escritura y reinicie la sincronización. - - - + Move to trash failed. - + The file is too large to be uploaded. It has been temporarily blacklisted. El archivo es demasiado grande para ser cargado. Ha sido temporalmente bloqueado. - + Impossible to download the file. Imposible descargar el archivo. - + You have exceeded your quota. Increase your space quota to re-enable file upload. Has excedido tu cuota. Aumente su cuota de espacio para volver a habilitar la carga de archivos. - + + The synchronization folder is inaccessible (error %1).<br>Please check that you have read and write access to this folder. + La carpeta de sincronización es inaccesible (error %1).<br>Por favor, compruebe que tiene acceso de lectura y escritura a esta carpeta. + + + This item already exists on remote kDrive. It is not synced because it has been blacklisted. Este artículo ya existe en el kDrive remoto. No se sincroniza porque está en la lista negra. - + This item already exists on local file system. It is not synced. Este artículo ya existe en el sistema de archivos local. No está sincronizado. - + Failed to synchronize this item. It has been temporarily blacklisted.<br>Another attempt to sync it will be done in one hour or on next application startup. No se pudo sincronizar este elemento. Se ha incluido temporalmente en la lista negra.<br>Se realizará otro intento de sincronización en una hora o en el próximo inicio de la aplicación. - + This item has been excluded from sync by a custom template.<br>You can disable this type of notification from the Preferences Este artículo ha sido excluido del sincronizado por una plantilla personalizada. Puede desactivar este tipo de notificación desde las preferencias - - + + Synchronization error. Error de sincronización. - + + Can't access item.<br>Please fix the read and write permissions. + No se puede acceder al elemento.<br>Por favor, corrija los permisos de lectura y escritura. + + + + System error. + Error del sistema. + + + A technical error has occurred.<br>Please empty the history and if the error persists, contact our support team. Se ha producido un error técnico.<br>Vacíe el historial y, si el error persiste, póngase en contacto con nuestro equipo de soporte. @@ -2217,35 +2206,35 @@ Por favor, utilice el siguiente enlace para enviar los registros al soporte: < KDC::SocketApi - - - + + + Copy private share link Copiar enlace para compartir privado - - + + Resharing this file is not allowed No está permitido volver a compartir este archivo - - + + Resharing this folder is not allowed No está permitido volver a compartir esta carpeta - - - - + + + + Copy public share link Copiar enlace para compartir públicamente - - + + Open in browser Abrir en navegador @@ -2321,202 +2310,202 @@ Por favor, utilice el siguiente enlace para enviar los registros al soporte: < KDC::SynthesisPopover - - + + Never Nunca - + During 1 hour Durante 1 hora - - + + Until tomorrow 8:00AM Hasta mañana a las 8:00AM - + During 3 days Durante 3 días - + During 1 week Durante 1 semana - - + + Always Siempre - + For 1 more hour Por 1 hora más - + For 3 more days Por 3 días más - + For 1 more week Por 1 semana más - + Update kDrive App Actualizar la aplicación kDrive - + This kDrive app version is not supported anymore. To access the latest features and enhancements, please update. Esta versión de la aplicación kDrive ya no es compatible. Para acceder a las últimas funciones y mejoras, actualice. - - + + Update Actualizar - + Please download the latest version on the website. Descargue la última versión del sitio web. - + Update download in progress Descarga de actualización en curso - + Looking for update... Buscando actualización... - + Manual update Actualización manual - + Unavailable Indisponible - + Quit kDrive Salir de kDrive - + Show errors and informations Mostrar errores e informaciones - + Show informations Mostrar información - + You can synchronize files <a style="%1" href="%2">from your computer</a> or on <a style="%1" href="%3">kdrive.infomaniak.com</a>. Puedes sincronizar archivos <a style="%1" href="%2">desde tu ordenador</a> o en <a style="%1" href="%3">kdrive.infomaniak.com</a>. - + Open in folder Abrir en carpeta - + More actions Más acciones - + Synchronized Sincronizado - + Favorites Favoritos - + Activity Actividad - - + + Not implemented! ¡No implementado! - + No synchronized folder for this Drive! ¡No hay ninguna carpeta sincronizada para este Drive! - + No kDrive configured! ¡No hay ningún kDrive configurado! - + Unable to access web site %1. No es posible acceder al sitio web %1. - + Open %1 web version Abrir la versión web de %1 - + Notifications disabled until %1 Notificaciones deshabilitadas hasta %1 - + Disable Notifications Deshabilitar Notificaciones - + Need help Se necesita ayuda - + Unable to open link %1. No se puede abrir el enlace %1. - + Invalid link %1. Enlace %1 no válido. - + Unable to open folder url %1. No es posible abrir la url de carpeta %1. - + Drive parameters Parámetros de drive - + Application preferences Preferencias de aplicación @@ -2646,47 +2635,47 @@ Por favor, utilice el siguiente enlace para enviar los registros al soporte: < ¡No se pueden guardar los parámetros! - + The parent folder is a sync folder or contained in one La carpeta principal es una carpeta de sincronización o está contenida en una - + Can't find a valid path No se puede encontrar una ruta válida - + No valid folder selected! ¡No se ha seleccionado una carpeta válida! - + The selected path does not exist! ¡La ruta seleccionada no existe! - + The selected path is not a folder! ¡La ruta seleccionada no es una carpeta! - + You have no permission to write to the selected folder! ¡No tienes permiso para escribir en la carpeta seleccionada! - + The local folder %1 contains a folder already synced. Please pick another one! La carpeta local %1 contiene una carpeta ya sincronizada.¡Elige otra! - + The local folder %1 is contained in a folder already synced. Please pick another one! La carpeta local %1 está contenida en una carpeta ya sincronizada.¡Elige otra! - + The local folder %1 is already synced on the same drive. Please pick another one! La carpeta local %1 ya está sincronizada en el mismo drive.¡Elige otra! @@ -2806,23 +2795,23 @@ Por favor, utilice el siguiente enlace para enviar los registros al soporte: < utility - + Cancel free up local space Cancelar liberar espacio local - - + + Cancel make available locally Cancelar disponible localmente - + Free up local space Liberar espacio local - + Always make available locally Siempre disponible en local diff --git a/translations/client_fr.ts b/translations/client_fr.ts index 738097edb..b7b45dc1a 100644 --- a/translations/client_fr.ts +++ b/translations/client_fr.ts @@ -288,12 +288,12 @@ KDC::AppServer - + kDrive application is already running! L'application kDrive est déjà en cours d'exécution! - + %1 and %n other file(s) have been removed. %1 a été supprimé. @@ -301,13 +301,13 @@ - + %1 has been removed. %1 names a file. %1 a été supprimé. - + %1 and %n other file(s) have been added. %1 et %n autre(s) fichier(s) ont été ajouté(s). @@ -315,13 +315,13 @@ - + %1 has been added. %1 names a file. %1 a été ajouté. - + %1 and %n other file(s) have been updated. %1 a été mis à jour. @@ -329,13 +329,13 @@ - + %1 has been updated. %1 names a file. %1 a été mis à jour. - + %1 has been moved to %2 and %n other file(s) have been moved. %1 a été déplacé vers %2. @@ -343,17 +343,17 @@ - + %1 has been moved to %2. %1 a été déplacé vers %2. - + Sync Activity Activité de synchronisation - + A new folder larger than %1 MB has been added in the drive %2, you must validate its synchronization: %3. Un nouveau dossier supérieur à %1 Mo a été ajouté dans le lecteur %2, vous devez valider sa synchronisation: %3. @@ -395,119 +395,119 @@ Sélectionnez ceux que vous souhaitez synchroniser: KDC::ClientGui - + Failed to fix conflict(s) on %1 item(s) in sync folder: %2 Échec de la résolution des conflits sur %1 élément(s) dans le dossier de synchronisation : %2 - + Please sign in Veuillez vous connecter - + Folder %1: %2 Dossier %1 : %2 - + There are no sync folders configured. Aucun dossier à synchroniser n'est configuré. - + Synthesis Synthèse - + Preferences Préférences Préférences - + Quit Quitter - + Undefined State. Statut indéfini. - + Waiting to start syncing. En attente de synchronisation. - + Sync is running. Synchronisation en cours. - + Sync was successful, unresolved conflicts. Synchronisation réussie, conflits non résolus. - + Last Sync was successful. Synchronisation terminée avec succès. - + User Abort. Abandon par l'utilisateur. - + Sync is paused. La synchronisation est en pause. - + %1 (Sync is paused) %1 (Synchronisation en pause) - + Do you really want to remove the synchronizations of the account <i>%1</i> ?<br><b>Note:</b> This will <b>not</b> delete any files. Voulez-vous vraiment supprimer les synchronisations du compte <i>%1</i> ?<br><b>Remarque :</b> Cela <b>ne</b> supprimera aucun fichier. - + REMOVE ALL SYNCHRONIZATIONS SUPPRIMER TOUTES LES SYNC - + CANCEL ANNULER - + Failed to start synchronizations! Échec du démarrage des synchronisations ! - + Unable to open folder path %1. Impossible d’ouvrir le dossier de débogage %1. - + Unable to initialize kDrive client Impossible d'initialiser le client kDrive - + Synchronization is paused La synchronisation est en pause - - + + The shared link has been copied to the clipboard. Le lien partagé a été copié dans le presse-papier. @@ -680,152 +680,152 @@ Sélectionnez ceux que vous souhaitez synchroniser: KDC::DebuggingDialog - + Info Information - + Debug Débogage - + Warning Avertissement - + Error Erreur - + Fatal Fatal - + Debugging settings Paramètres de débogage - + Save debugging information in a folder on my computer (Recommended) Enregistrer les informations de débogage dans un dossier sur mon ordinateur (recommandé) - + This information enables IT support to determine the origin of an incident. Ces informations permettent au support informatique de déterminer l’origine d’un incident. - + <a style="%1" href="%2">Open debugging folder</a> <a style="%1" href="%2">Ouvrir le dossier de débogage</a> - + Debug level Niveau de débogage - + The trace level lets you choose the extent of the debugging information recorded Le niveau de trace vous permet de choisir l'étendue des informations de débogage enregistrées - + The extended full log collects a detailed history that can be used for debugging. Enabling it can slow down the kDrive application. Le journal complet étendu collecte un historique détaillé qui peut être utilisé pour le débogage. L'activer peut ralentir l'application kDrive. - + Extended Full Log Journal complet étendu - + Delete logs older than %1 days Supprimer les journaux datant de plus de %1 jours - + Share the debug folder with Infomaniak support. Partagez le dossier debug avec le support Infomaniak. - + The last session is the periode since the last kDrive start. La dernière session est la période depuis le dernier démarrage de kDrive. - + Share only the last kDrive session Partager uniquement la dernière session kDrive - + Loading Chargement - + Cancel Annuler - + SAVE ENREGISTRER - + CANCEL ANNULER - + Failed to share Échec du partage - + 1. Check that you are logged in <br>2. Check that you have configured at least one kDrive 1. Vérifiez que vous êtes connecté <br>2. Vérifiez que vous avez configuré au moins un kDrive - + (Connexion interrupted) (Connexion interrompue) - + Share the folder with SwissTransfer <br> Partager le dossier avec SwissTransfer <br> - + 1. We automatically compressed your log <a style="%1" href="%2">here</a>.<br> 1. Nous avons automatiquement compressé votre journal <a style="%1" href="%2">ici</a>.<br> - + 2. Transfer the archive with <a style="%1" href="%2">swisstransfer.com</a><br> 2. Transférez l'archive avec <a style="%1" href="%2">swisstransfer.com</a><br> - + 3. Share the link with <a style="%1" href="%2"> support@infomaniak.com </a><br> 3. Partagez le lien avec <a style="%1" href="%2"> support@infomaniak.com </a><br> - + Last upload the %1 Dernier envoi le %1 - + Sharing has been cancelled Le partage a été annulé @@ -835,39 +835,39 @@ Sélectionnez ceux que vous souhaitez synchroniser: Le dossier entier est volumineux (> 100 Mo) et son partage peut prendre un certain temps. Pour réduire le temps de partage, nous vous recommandons de ne partager que la dernière session kDrive. - + %1/%2/%3 at %4h%5m and %6s Date format for the last successful log upload. %1: month, %2: day, %3: year, %4: hour, %5: minute, %6: second %2/%1/%3 à %4h%5 et %6s - + Do you want to save your modifications? Voulez-vous enregistrer vos modifications ? - - + + Unable to open folder %1. Impossible d'ouvrir le dossier %1. - + Share Partager - + Sharing | step 1/2 %1% Partage | étape 1/2 %1% - + Sharing | step 2/2 %1% Partage | étape 2/2 %1% - + Canceling... Annulation... @@ -1511,382 +1511,372 @@ Sélectionnez ceux que vous souhaitez synchroniser: KDC::ParametersDialog - + Unable to open folder path %1. Impossible d’ouvrir le dossier de débogage %1. - + Transmission done!<br>Please refer to identifier <b>%1</b> in bug reports. Transmission effectuée !<br>Veuillez vous référer à l'identifiant <b>%1</b> dans vos rapports de bugs. - + No kDrive configured! Aucun kDrive configuré ! - + Transmission failed! Please, use the following link to send the logs to the support: <a style="%1" href="%2">%2</a> Échec de la transmission ! Veuillez utiliser le lien suivant pour envoyer les logs au support: <a style="%1" href="%2">%2</a> - - - - - - - - - - - + + + + + + + + + + + A technical error has occurred (error %1).<br>Please empty the history and if the error persists, contact our support team. Une erreur technique s'est produite (erreur %1).<br>Veuillez vider l'historique et si l'erreur persiste, contactez notre équipe d'assistance. - + It seems that your network connection is configured with too low a timeout for the application to work correctly (error %1).<br>Please check your network configuration. Il semble que votre connexion réseau soit configurée avec un délai d'expiration trop court pour que l'application fonctionne correctement (erreur %1).<br>Veuillez vérifier votre configuration réseau. - - + + Cannot connect to kDrive server (error %1).<br>Attempting reconnection. Please check your Internet connection and your firewall. Impossible de se connecter au serveur kDrive (erreur %1).<br>Tentative de reconnexion. Veuillez vérifier votre connexion Internet et votre pare-feu. - + A login problem has occurred (error %1).<br>Please log in again and if the error persists, contact our support team. Un problème de connexion est survenu (erreur %1).<br>Veuillez vous reconnecter et si l'erreur persiste, contactez notre équipe d'assistance. - + Old synchronisation database doesn't exist or is not accessible.<br>Old blacklist data haven't been migrated. L'ancienne base de données de synchronisation n'existe pas ou n'est pas accessible.<br>Les données de l'ancienne liste noire n'ont pas été migrées. - + A new version of the application is available.<br>Please update the application to continue using it. Une nouvelle version de l'application est disponible.<br>Veuillez mettre à jour l'application pour continuer à l'utiliser. - + The log upload failed (error %1).<br>Please try again later. Le téléchargement du journal a échoué (erreur %1).<br>Veuillez réessayer plus tard. - - The item misses search permission (error %1).<br>Please check that you have search/exec access to the parent folder. - L'élément ne dispose pas de l'autorisation de recherche (erreur %1).<br>Veuillez vérifier que vous disposez d'un accès de recherche/exécution au dossier parent. - - - + The synchronization folder is no longer accessible (error %1).<br>Synchronization will resume as soon as the folder is accessible. Le dossier de synchronisation n'est plus accessible (erreur %1).<br>La synchronisation reprendra dès que le dossier sera accessible. - - The synchronization folder is inaccessible (error %1).<br>Please check that you have read access to this folder. - Le dossier de synchronisation est inaccessible (erreur %1).<br>Veuillez vérifier que vous disposez d'un accès en lecture à ce dossier. - - - - The synchronization folder is inaccessible (error %1).<br>Please check that you have write access to this folder. - Le dossier de synchronisation est inaccessible (erreur %1).<br>Veuillez vérifier que vous disposez d'un accès en écriture à ce dossier. - - - + There is not enough space left on your disk.<br>The synchronization has been stopped. Il ne reste plus assez d'espace sur votre disque.<br>La synchronisation a été arrêtée. - + There is not enough memory left on your machine.<br>The synchronization has been stopped. Il ne reste plus assez de mémoire sur votre machine.<br>La synchronisation a été arrêtée. - + Unable to start synchronization (error %1).<br>You must allow:<br>- kDrive in System Settings >> Privacy & Security >> Security<br>- kDrive LiteSync Extension in System Settings >> Privacy & Security >> Full Disk Access. Impossible de démarrer la synchronisation (erreur %1).<br>Vous devez autoriser :<br>- kDrive dans les paramètres système >> Confidentialité et sécurité >> Sécurité<br>- l'extension kDrive LiteSync dans les paramètres système >> Confidentialité et sécurité >> Accès complet au disque. - + Unable to start Lite Sync plugin (error %1).<br>Check that the Lite Sync extension is installed and Windows Search service is enabled.<br>Please empty the history, restart and if the error persists, contact our support team. Impossible de démarrer le plug-in Lite Sync (erreur %1).<br>Vérifiez que l'extension Lite Sync est installée et que le service Windows Search est activé.<br>Veuillez vider l'historique, redémarrer et si l'erreur persiste, contactez notre équipe d'assistance. - + Unable to start Lite Sync plugin (error %1).<br>Check that the Lite Sync extension has the correct permissions and is running.<br>Please empty the history, restart and if the error persists, contact our support team. Impossible de démarrer le plugin Lite Sync (erreur %1).<br>Vérifiez que l'extension Lite Sync dispose des autorisations appropriées et est en cours d'exécution.<br>Veuillez vider l'historique, redémarrer et si l'erreur persiste, contactez notre équipe d'assistance. - + Unable to start Lite Sync plugin (error %1).<br>Please empty the history, restart and if the error persists, contact our support team. Impossible de démarrer le plugin Lite Sync (erreur %1).<br>Veuillez vider l'historique, redémarrer et si l'erreur persiste, contactez notre équipe d'assistance. - + The kDrive is in maintenance mode.<br>Synchronization will begin again as soon as possible. Please contact our support team if the error persists. Le kDrive est en mode maintenance.<br>La synchronisation recommencera dès que possible. Veuillez contacter notre équipe d'assistance si l'erreur persiste. - + The kDrive is blocked.<br>Please renew kDrive. If no action is taken, the data will be permanently deleted and it will be impossible to recover them. Le kDrive est bloqué.<br>Veuillez renouveler le kDrive. Si aucune action n'est entreprise, les données seront définitivement supprimées et il sera impossible de les récupérer. - + The kDrive is blocked.<br>Please contact an administrator to renew the kDrive. If no action is taken, the data will be permanently deleted and it will be impossible to recover them. Le kDrive est bloqué.<br>Veuillez contacter un administrateur pour renouveler le kDrive. Si aucune action n'est entreprise, les données seront définitivement supprimées et il sera impossible de les récupérer. - + You are not authorised to access this kDrive.<br>Synchronization has been paused. Please contact an administrator. Vous n'êtes pas autorisé à accéder à ce kDrive.<br>La synchronisation a été suspendue. Veuillez contacter un administrateur. - + A technical error has occurred (error %1).<br>Synchronization will resume as soon as possible. Please contact our support team if the error persists. Une erreur technique s'est produite (erreur %1).<br>La synchronisation reprendra dès que possible. Veuillez contacter notre équipe d'assistance si l'erreur persiste. - + The network connections have been dropped by the kernel (error %1).<br>Please empty the history and if the error persists, contact our support team. Les connexions réseau ont été interrompues par le noyau (erreur %1).<br>Veuillez vider l'historique et si l'erreur persiste, contactez notre équipe d'assistance. - + Unfortunately your old configuration could not be migrated.<br>The application will use a blank configuration. Malheureusement, votre ancienne configuration n'a pas pu être migrée.<br>L'application utilisera une configuration vierge. - + Unfortunately your old proxy configuration could not be migrated, SOCKS5 proxies are not supported at this time.<br>The application will use system proxy settings instead. Malheureusement, votre ancienne configuration de proxy n'a pas pu être migrée, les proxys SOCKS5 ne sont pas pris en charge pour le moment.<br>L'application utilisera à la place les paramètres de proxy du système. - + A technical error has occurred (error %1).<br>Synchronization has been restarted. Please empty the history and if the error persists, please contact our support team. Une erreur technique s'est produite (erreur %1).<br>La synchronisation a été redémarrée. Veuillez vider l'historique et si l'erreur persiste, veuillez contacter notre équipe d'assistance. - + An error accessing the synchronization database has happened (error %1).<br>Synchronization has been stopped. Une erreur d'accès à la base de données de synchronisation s'est produite (erreur %1).<br>La synchronisation a été arrêtée. - + A login problem has occurred (error %1).<br>Token invalid or revoked. Un problème de connexion est survenu (erreur %1).<br>Jeton invalide ou révoqué. - + Nested synchronizations are prohibited (error %1).<br>You should only keep synchronizations whose folders are not nested. Les synchronisations imbriquées sont interdites (erreur %1).<br>Vous ne devez conserver que les synchronisations dont les dossiers ne sont pas imbriqués. - - The app does not have write rights to the synchronization folder.<br>The synchronization has been stopped. - L'application ne dispose pas de droits d'écriture sur le dossier de synchronisation.<br>La synchronisation a été arrêtée. - - - + File name parsing error (error %1).<br>Special characters such as double quotes, backslashes or line returns can cause parsing failures. Erreur d'analyse du nom de fichier (erreur %1).<br>Les caractères spéciaux tels que les guillemets doubles, les barres obliques inverses ou les retours de ligne peuvent provoquer des échecs d'analyse. - + An element was moved to a deleted folder.<br>The move has been canceled. Un élément a été déplacé vers un dossier supprimé.<br>Le déplacement a été annulé. - + This element was moved by another user.<br>The deletion has been canceled. Cet élément a été déplacé par un autre utilisateur.<br>La suppression a été annulée. - + An element was created in this folder while it was being deleted.<br>The delete operation has been propagated anyway. Un élément a été créé dans ce dossier alors qu'il était en cours de suppression.<br>L'opération de suppression a quand même été propagée. - + This element has been moved somewhere else.<br>The local operation has been canceled. Cet élément a été déplacé ailleurs.<br>L'opération locale a été annulée. - - + + An element with the same name already exists in this location.<br>The local element has been renamed. Un élément portant le même nom existe déjà à cet emplacement.<br>L'élément local a été renommé. - + An element with the same name already exists in this location.<br>The local operation has been canceled. Un élément portant le même nom existe déjà à cet emplacement.<br>L'opération locale a été annulée. - + The content of the file was modified while it was being deleted.<br>The deletion has been canceled. Le contenu du fichier a été modifié lors de sa suppression.<br>La suppression a été annulée. - + The content of a synchronized element was modified while a parent folder was being deleted (e.g. the folder containing the current folder).<br>The file has been moved to the root of your kDrive. Le contenu d'un élément synchronisé a été modifié alors qu'un dossier parent était en cours de suppression (par exemple le dossier contenant le dossier en cours).<br>Le fichier a été déplacé à la racine de votre kDrive. - + The content of an already synchronized file has been modified while this one or one of its parent folders has been deleted.<br> Le contenu d'un fichier déjà synchronisé a été modifié alors qu'un répertoire parent ou celui-ci a été supprimé.<br> - + The file was modified at the same time by another user.<br>Your modifications have been saved in a copy. Le fichier a été modifié au même moment par un autre utilisateur.<br>Vos modifications ont été enregistrées dans une copie. - + Another user has moved a parent folder of the destination.<br>The local operation has been canceled. Un autre utilisateur a déplacé un dossier parent de la destination.<br>L'opération locale a été annulée. - + An existing file/directory has an identical name with the same case options (same upper and lower case letters).<br>The file/directory has been temporarily blacklisted. Un fichier/répertoire existant a un nom identique avec les mêmes options de casse (mêmes lettres majuscules et minuscules).<br>Le fichier/répertoire a été temporairement mis sur liste noire. - + The file/directory name contains an unsupported character.<br>The file/directory has been temporarily blacklisted. Le nom du fichier/répertoire contient un caractère non pris en charge.<br>Le fichier/répertoire a été temporairement mis sur liste noire. - + This file/directory name is reserved by your operating system.<br>The file/directory has been temporarily blacklisted. Ce nom de fichier/répertoire est réservé par votre système d'exploitation.<br>Le fichier/répertoire a été temporairement mis sur liste noire. - + The file/directory name is too long.<br>The file/directory has been temporarily blacklisted. Le nom du fichier/répertoire est trop long.<br>Le fichier/répertoire a été temporairement mis sur liste noire. - + The file/directory path is too long.<br>The file/directory is ignored. Le chemin du fichier/répertoire est trop long.<br>Le fichier/répertoire est ignoré. - + The file/directory name contains a recent UNICODE character not yet supported by your filesystem.<br>The parent directory has been excluded from synchronization. Le nom du fichier/répertoire contient un caractère UNICODE récent qui n'est pas encore pris en charge par votre système de fichiers.<br>Le répertoire parent a été exclu de la synchronisation. - + The file/directory name coincides with the name of another item in the same directory.<br>This item is temporarily blacklisted. Consider removing duplicate items. Le nom du fichier/répertoire coïncide avec le nom d'un autre élément dans le même répertoire.<br>Cet élément est temporairement mis sur liste noire. Envisagez de supprimer les éléments en double. - + Either you are not allowed to create an item, or another item already exists with the same name.<br>The item has been excluded from synchronization. Soit vous n'êtes pas autorisé à créer un élément, soit un autre élément existe déjà avec le même nom.<br>L'élément a été exclu de la synchronisation. - + You are not allowed to edit item.<br>The file containing your modifications has been renamed and excluded from synchronization. Vous n'êtes pas autorisé à modifier l'élément.<br>Le fichier contenant vos modifications a été renommé et exclu de la synchronisation. - + You are not allowed to rename item.<br>It will be restored with its original name. Vous n'êtes pas autorisé à renommer l'élément.<br>Il sera restauré avec son nom d'origine. - + You are not allowed to move item to "%1".<br>It will be restored to its original location. Vous n'êtes pas autorisé à déplacer l'élément vers "%1".<br>Il sera restauré à son emplacement d'origine. - + You are not allowed to delete item.<br>It will be restored to its original location. Vous n'êtes pas autorisé à supprimer l'élément.<br>Il sera restauré à son emplacement d'origine. - + Failed to move this item to trash, it has been blacklisted. Échec du déplacement de cet élément vers la corbeille, il a été mis sur liste noire. - + This item has been excluded from sync because it is an hard link Cet élément a été exclu de la synchronisation parce qu'il s'agit d'un lien dur. - + The operation performed on item is forbidden.<br>The item has been temporarily blacklisted. L'opération effectuée sur l'élément est interdite.<br>L'article a été temporairement mis sur liste noire. - + The operation performed on this item failed.<br>The item has been temporarily blacklisted. L'opération effectuée sur cet élément a échoué.<br>L'article a été temporairement mis sur liste noire. - - Can't access item.<br>Please fix the write permissions and restart the synchronization. - Impossible d'accéder à l'élément.<br>Veuillez corriger les autorisations d'écriture et redémarrer la synchronisation. - - - + Move to trash failed. Le déplacement vers la corbeille a échoué. - + The file is too large to be uploaded. It has been temporarily blacklisted. Le fichier est trop volumineux pour être téléchargé. Il a été temporairement mis sur liste noire. - + Impossible to download the file. Impossible de télécharger le fichier. - + You have exceeded your quota. Increase your space quota to re-enable file upload. Vous avez dépassé votre quota. Augmentez votre quota d'espace pour réactiver le téléchargement de fichiers. - + + The synchronization folder is inaccessible (error %1).<br>Please check that you have read and write access to this folder. + Le dossier de synchronisation est inaccessible (erreur %1).<br>Veuillez vérifier que vous avez accès en lecture et en écriture à ce dossier. + + + This item already exists on remote kDrive. It is not synced because it has been blacklisted. Cet élément existe déjà sur le kDrive distant. Il n'est pas synchronisé car il a été mis sur liste noire. - + This item already exists on local file system. It is not synced. Cet élément existe déjà sur le système de fichiers local. Il n'est pas synchronisé. - + Failed to synchronize this item. It has been temporarily blacklisted.<br>Another attempt to sync it will be done in one hour or on next application startup. Échec de la synchronisation de cet élément. Il a été temporairement mis sur liste noire.<br>Une autre tentative de synchronisation sera effectuée dans une heure ou au prochain démarrage de l'application. - + This item has been excluded from sync by a custom template.<br>You can disable this type of notification from the Preferences Cet élément a été exclu de la synchronisation par un modèle personnalisé. Vous pouvez désactiver ce type de notification dans les préférences - - + + Synchronization error. Erreur de synchronisation. - + + Can't access item.<br>Please fix the read and write permissions. + Impossible d'accéder à l'élément.<br>Veuillez corriger les autorisations de lecture et d'écriture. + + + + System error. + Erreur système. + + + A technical error has occurred.<br>Please empty the history and if the error persists, contact our support team. Une erreur technique s'est produite.<br>Veuillez vider l'historique et si l'erreur persiste, contactez notre équipe d'assistance. @@ -2216,35 +2206,35 @@ Veuillez utiliser le lien suivant pour envoyer les logs au support: <a style= KDC::SocketApi - - - + + + Copy private share link Copier le lien de partage privé - - + + Resharing this file is not allowed Le partage de ce fichier n'est pas autorisé - - + + Resharing this folder is not allowed Le partage de ce dossier n'est pas autorisé - - - - + + + + Copy public share link Copier le lien de partage public - - + + Open in browser Ouvrir dans le navigateur web @@ -2320,202 +2310,202 @@ Veuillez utiliser le lien suivant pour envoyer les logs au support: <a style= KDC::SynthesisPopover - - + + Never Jamais - + During 1 hour Pendant 1 heure - - + + Until tomorrow 8:00AM Jusqu’à demain 8h00 - + During 3 days Pendant 3 jours - + During 1 week Pendant 1 semaine - - + + Always Toujours - + For 1 more hour Pour 1 heure de plus - + For 3 more days Pour 3 heures de plus - + For 1 more week Pour 1 semaine de plus - + Update kDrive App Mettre à jour l'application kDrive - + This kDrive app version is not supported anymore. To access the latest features and enhancements, please update. Cette version de l'application kDrive n'est plus prise en charge. Pour accéder aux dernières fonctionnalités et améliorations, veuillez mettre à jour. - - + + Update Mise à jour - + Please download the latest version on the website. Veuillez télécharger la dernière version sur le site Web. - + Update download in progress Téléchargement de la mise à jour en cours - + Looking for update... Recherche d'une mise à jour... - + Manual update Mise à jour manuelle - + Unavailable Indisponible - + Quit kDrive Quitter kDrive - + Show errors and informations Afficher les erreurs et les informations - + Show informations Afficher les informations - + You can synchronize files <a style="%1" href="%2">from your computer</a> or on <a style="%1" href="%3">kdrive.infomaniak.com</a>. Vous pouvez synchroniser les fichiers <a style="%1" href="%2">depuis votre ordinateur</a> ou sur <a style="%1" href="%3">kdrive.infomaniak.com</ un>. - + Open in folder Ouvrir dans le dossier - + More actions Autres actions - + Synchronized Synchronisé - + Favorites Favoris - + Activity Activité - - + + Not implemented! Non implémenté ! - + No synchronized folder for this Drive! Aucun fichier synchronisé pour ce kDrive ! - + No kDrive configured! Aucun kDrive configuré ! - + Unable to access web site %1. Impossible d’accéder au site %1. - + Open %1 web version Ouvrir la version Web de %1 - + Notifications disabled until %1 Notifications désactivées jusqu’à %1 - + Disable Notifications Désactiver les notifications - + Need help Besoin d’aide - + Unable to open link %1. Impossible d’ouvrir le lien %1. - + Invalid link %1. Lien %1 invalide. - + Unable to open folder url %1. Impossible d’ouvrir l’URL du dossier %1. - + Drive parameters Paramètres du kDrive - + Application preferences Préférences de l’application @@ -2645,47 +2635,47 @@ Veuillez utiliser le lien suivant pour envoyer les logs au support: <a style= Impossible d'enregistrer les paramètres ! - + The parent folder is a sync folder or contained in one Le dossier parent est un dossier de synchronisation ou contenu dans un - + Can't find a valid path Impossible de trouver un chemin valide - + No valid folder selected! Aucun dossier valable sélectionné! - + The selected path does not exist! Le chemin sélectionné n’existe pas! - + The selected path is not a folder! Le chemin sélectionné n'est pas un dossier! - + You have no permission to write to the selected folder! Vous n'avez pas la permission d'écrire dans le dossier sélectionné! - + The local folder %1 contains a folder already synced. Please pick another one! Le dossier local %1 contient un dossier déjà synchronisé. Veuillez en choisir un autre ! - + The local folder %1 is contained in a folder already synced. Please pick another one! Le dossier local %1 est contenu dans un dossier déjà synchronisé. Veuillez en choisir un autre ! - + The local folder %1 is already synced on the same drive. Please pick another one! Le dossier local %1 est déjà synchronisé sur le même lecteur. Veuillez en choisir un autre ! @@ -2870,18 +2860,18 @@ Veuillez utiliser le lien suivant pour envoyer les logs au support: <a style= Démarrage de la synchronisation - + Free up local space Libérer de l’espace local - + Cancel free up local space Annuler libérer l'espace local - - + + Cancel make available locally Annuler rendre disponible localement @@ -2920,7 +2910,7 @@ You can add one from the kDrive settings. Ajoutez-en un depuis la configuration du kDrive. - + Always make available locally Rendre toujours disponible localement diff --git a/translations/client_it.ts b/translations/client_it.ts index 66e7743d7..900104430 100644 --- a/translations/client_it.ts +++ b/translations/client_it.ts @@ -288,12 +288,12 @@ KDC::AppServer - + kDrive application is already running! L'applicazione kDrive è già in esecuzione! - + %1 and %n other file(s) have been removed. %1 e %n altri file sono stati rimossi. @@ -301,13 +301,13 @@ - + %1 has been removed. %1 names a file. %1 è stato rimosso. - + %1 and %n other file(s) have been added. %1 e %n altri file sono stati aggiunti. @@ -315,13 +315,13 @@ - + %1 has been added. %1 names a file. %1 è stato aggiunto. - + %1 and %n other file(s) have been updated. %1 e %n altri file sono stati aggiornati. @@ -329,13 +329,13 @@ - + %1 has been updated. %1 names a file. %1 è stato aggiornato. - + %1 has been moved to %2 and %n other file(s) have been moved. %1 è stato spostato in %2 e %n altri file sono stati spostati. @@ -343,17 +343,17 @@ - + %1 has been moved to %2. %1 è stato spostato in %2. - + Sync Activity Sincronizza attività - + A new folder larger than %1 MB has been added in the drive %2, you must validate its synchronization: %3. È stata aggiunta una nuova cartella più grande di %1 MB nell'unità %2, devi convalidarne la sincronizzazione: %3. @@ -396,118 +396,118 @@ Seleziona quelli che desideri sincronizzare: KDC::ClientGui - + Please sign in Accedi - + Folder %1: %2 Cartella %1: %2 - + There are no sync folders configured. Non è stata configurata alcuna cartella per la sincronizzazione. - + Synthesis Sintesi - + Preferences Preferenze - + Quit Esci - + Undefined State. Stato non definito. - + Waiting to start syncing. In attesa di iniziare la sincronizzazione. - + Sync is running. Sincronizzazione in corso. - + Sync was successful, unresolved conflicts. La sincronizzazione è stata completata correttamente, sono presenti conflitti non risolti. - + Last Sync was successful. L'ultima sincronizzazione è stata completata correttamente. - + User Abort. Interrotto dall'utente. - + Sync is paused. Sincronizzazione sospesa. - + %1 (Sync is paused) %1 (Sincronizzazione sospesa) - + Do you really want to remove the synchronizations of the account <i>%1</i> ?<br><b>Note:</b> This will <b>not</b> delete any files. Vuoi davvero rimuovere le sincronizzazioni dell'account <i>%1</i> ?<br><b>Nota:</b> questo <b>non</b> eliminerà alcun file. - + REMOVE ALL SYNCHRONIZATIONS RIMUOVERE TUTTE LE SINC - + CANCEL ANNULLA - + Failed to start synchronizations! Impossibile avviare la sincronizzazione! - + Unable to open folder path %1. Impossibile aprire il percorso della cartella %1. - + Unable to initialize kDrive client Impossibile inizializzare il client kDrive - + Failed to fix conflict(s) on %1 item(s) in sync folder: %2 Impossibile risolvere i conflitti su %1 elemento/i nella cartella di sincronizzazione: %2 - + Synchronization is paused Sincronizzazione sospesa - - + + The shared link has been copied to the clipboard. Il link condiviso è stato copiato negli appunti. @@ -680,152 +680,152 @@ Seleziona quelli che desideri sincronizzare: KDC::DebuggingDialog - + Info Info - + Debug Debug - + Warning Avviso - + Error Errore - + Fatal Irreversibile - + Debugging settings Impostazioni di debug - + Save debugging information in a folder on my computer (Recommended) Salva le informazioni di debug in una cartella sul mio computer (consigliato) - + This information enables IT support to determine the origin of an incident. Queste informazioni consentono al supporto IT di determinare l'origine di un incidente. - + <a style="%1" href="%2">Open debugging folder</a> <a style="%1" href="%2">Apri cartella di debug</a> - + Debug level Livello di debug - + The trace level lets you choose the extent of the debugging information recorded Il livello di traccia consente di scegliere l'entità delle informazioni di debug registrate - + The extended full log collects a detailed history that can be used for debugging. Enabling it can slow down the kDrive application. Il registro completo esteso raccoglie una cronologia dettagliata che può essere utilizzata per il debug. Abilitarla può rallentare l'applicazione kDrive. - + Extended Full Log Log completo esteso - + Delete logs older than %1 days Elimina i registri più vecchi di %1 giorni - + Share the debug folder with Infomaniak support. Condividi la cartella debug con il supporto di Infomaniak. - + The last session is the periode since the last kDrive start. L'ultima sessione è il periodo trascorso dall'ultimo avvio di kDrive. - + Share only the last kDrive session Condividi solo l'ultima sessione di kDrive - + Loading Caricamento - + Cancel Annulla - + SAVE SALVA - + CANCEL ANNULLA - + Failed to share Impossibile condividere - + 1. Check that you are logged in <br>2. Check that you have configured at least one kDrive 1. Verifica di aver effettuato l'accesso<br>2. Verifica di aver configurato almeno un kDrive - + (Connexion interrupted) (Connessione interrotta) - + Share the folder with SwissTransfer <br> Condividi la cartella con SwissTransfer <br> - + 1. We automatically compressed your log <a style="%1" href="%2">here</a>.<br> 1. Abbiamo compresso automaticamente il tuo registro <a style="%1" href="%2">qui</a>.<br> - + 2. Transfer the archive with <a style="%1" href="%2">swisstransfer.com</a><br> 2. Trasferisci l'archivio con <a style="%1" href="%2">swisstransfer.com</a><br> - + 3. Share the link with <a style="%1" href="%2"> support@infomaniak.com </a><br> 3. Condividi il link con <a style="%1" href="%2"> support@infomaniak.com </a><br> - + Last upload the %1 Ultimo caricamento il %1 - + Sharing has been cancelled La condivisione è stata annullata @@ -835,39 +835,39 @@ Seleziona quelli che desideri sincronizzare: L'intera cartella è di grandi dimensioni (> 100 MB) e potrebbe richiedere del tempo per essere condivisa. Per ridurre il tempo di condivisione, si consiglia di condividere solo l'ultima sessione di kDrive. - + %1/%2/%3 at %4h%5m and %6s Date format for the last successful log upload. %1: month, %2: day, %3: year, %4: hour, %5: minute, %6: second %2/%1/%3 alle %4:%5:%6 - + Do you want to save your modifications? Salvare le modifiche? - - + + Unable to open folder %1. Impossibile aprire la cartella %1. - + Share Condividere - + Sharing | step 1/2 %1% Condivisione | passaggio 1/2 %1% - + Sharing | step 2/2 %1% Condivisione | passaggio 2/2 %1% - + Canceling... Annullamento... @@ -1511,382 +1511,372 @@ Seleziona quelli che desideri sincronizzare: KDC::ParametersDialog - + Unable to open folder path %1. Impossibile aprire il percorso della cartella %1. - + Transmission done!<br>Please refer to identifier <b>%1</b> in bug reports. Invio completato!<br>Fai riferimento all'identificatore <b>%1</b> nelle segnalazioni di bug. - + Transmission failed! Please, use the following link to send the logs to the support: <a style="%1" href="%2">%2</a> Trasmissione fallita! Per favore, utilizza il seguente link per inviare i log al supporto: <a style="%1" href="%2">%2</a> - + No kDrive configured! Nessun kDrive configurato! - - - - - - - - - - - + + + + + + + + + + + A technical error has occurred (error %1).<br>Please empty the history and if the error persists, contact our support team. Si è verificato un errore tecnico (errore %1).<br>Svuota la cronologia e, se l'errore persiste, contatta il nostro team di supporto. - + It seems that your network connection is configured with too low a timeout for the application to work correctly (error %1).<br>Please check your network configuration. Sembra che la tua connessione di rete sia configurata con un timeout troppo basso perché l'applicazione funzioni correttamente (errore %1).<br>Verifica la configurazione di rete. - - + + Cannot connect to kDrive server (error %1).<br>Attempting reconnection. Please check your Internet connection and your firewall. Impossibile connettersi al server kDrive (errore %1).<br>Tentativo di riconnessione. Controlla la tua connessione Internet e il tuo firewall. - + A login problem has occurred (error %1).<br>Please log in again and if the error persists, contact our support team. Si è verificato un problema di accesso (errore %1).<br>Accedi nuovamente e se l'errore persiste, contatta il nostro team di supporto. - + Old synchronisation database doesn't exist or is not accessible.<br>Old blacklist data haven't been migrated. Il vecchio database di sincronizzazione non esiste o non è accessibile. I <br>vecchi dati della blacklist non sono stati migrati. - + A new version of the application is available.<br>Please update the application to continue using it. È disponibile una nuova versione dell'applicazione.<br>Aggiorna l'applicazione per continuare a utilizzarla. - + The log upload failed (error %1).<br>Please try again later. Il caricamento del registro non è riuscito (errore %1).<br>Riprova più tardi. - - The item misses search permission (error %1).<br>Please check that you have search/exec access to the parent folder. - L'elemento non dispone dell'autorizzazione di ricerca (errore %1).<br>Verifica di disporre dell'accesso di ricerca/esecuzione alla cartella principale. - - - + The synchronization folder is no longer accessible (error %1).<br>Synchronization will resume as soon as the folder is accessible. La cartella di sincronizzazione non è più accessibile (errore %1).<br>La sincronizzazione riprenderà non appena la cartella sarà accessibile. - - The synchronization folder is inaccessible (error %1).<br>Please check that you have read access to this folder. - La cartella di sincronizzazione non è accessibile (errore %1).<br>Verifica di avere accesso in lettura a questa cartella. - - - - The synchronization folder is inaccessible (error %1).<br>Please check that you have write access to this folder. - La cartella di sincronizzazione è inaccessibile (errore %1).<br>Controlla di avere accesso in scrittura a questa cartella. - - - + There is not enough space left on your disk.<br>The synchronization has been stopped. Non c'è spazio sufficiente sul disco.<br>La sincronizzazione è stata interrotta. - + There is not enough memory left on your machine.<br>The synchronization has been stopped. Memoria insufficiente sul computer.<br>La sincronizzazione è stata interrotta. - + Unable to start synchronization (error %1).<br>You must allow:<br>- kDrive in System Settings >> Privacy & Security >> Security<br>- kDrive LiteSync Extension in System Settings >> Privacy & Security >> Full Disk Access. Impossibile avviare la sincronizzazione (errore %1).<br>Devi consentire:<br>- kDrive in Impostazioni di sistema >> Privacy e sicurezza >> Sicurezza<br>- Estensione kDrive LiteSync in Impostazioni di sistema >> Privacy e sicurezza >> Accesso completo al disco. - + Unable to start Lite Sync plugin (error %1).<br>Check that the Lite Sync extension is installed and Windows Search service is enabled.<br>Please empty the history, restart and if the error persists, contact our support team. Impossibile avviare il plug-in Lite Sync (errore %1).<br>Verifica che l'estensione Lite Sync sia installata e che il servizio di ricerca di Windows sia abilitato.<br>Svuota la cronologia, riavvia e se l'errore persiste, contatta il nostro team di supporto. - + Unable to start Lite Sync plugin (error %1).<br>Check that the Lite Sync extension has the correct permissions and is running.<br>Please empty the history, restart and if the error persists, contact our support team. Impossibile avviare il plug-in Lite Sync (errore %1).<br>Verifica che l'estensione Lite Sync disponga delle autorizzazioni corrette e sia in esecuzione.<br>Svuota la cronologia, riavvia e se l'errore persiste, contatta il nostro team di supporto. - + Unable to start Lite Sync plugin (error %1).<br>Please empty the history, restart and if the error persists, contact our support team. Impossibile avviare il plug-in Lite Sync (errore %1).<br>Svuota la cronologia, riavvia e se l'errore persiste, contatta il nostro team di supporto. - + The kDrive is in maintenance mode.<br>Synchronization will begin again as soon as possible. Please contact our support team if the error persists. Il kDrive è in modalità di manutenzione.<br>La sincronizzazione riprenderà appena possibile. Contatta il nostro team di assistenza se l'errore persiste. - + The kDrive is blocked.<br>Please renew kDrive. If no action is taken, the data will be permanently deleted and it will be impossible to recover them. Il kDrive è bloccato.<br>Rinnovare kDrive. Se non si interviene, i dati verranno cancellati in modo definitivo e sarà impossibile recuperarli. - + The kDrive is blocked.<br>Please contact an administrator to renew the kDrive. If no action is taken, the data will be permanently deleted and it will be impossible to recover them. Il kDrive è bloccato.<br>Contatta un amministratore per rinnovare il kDrive. Se non si interviene, i dati verranno cancellati in modo definitivo e sarà impossibile recuperarli. - + You are not authorised to access this kDrive.<br>Synchronization has been paused. Please contact an administrator. Non sei autorizzato ad accedere a questo kDrive.<br>La sincronizzazione è stata sospesa. Contatta un amministratore. - + A technical error has occurred (error %1).<br>Synchronization will resume as soon as possible. Please contact our support team if the error persists. Si è verificato un errore tecnico (errore %1).<br>La sincronizzazione riprenderà il prima possibile. Contatta il nostro team di supporto se l'errore persiste. - + The network connections have been dropped by the kernel (error %1).<br>Please empty the history and if the error persists, contact our support team. Le connessioni di rete sono state interrotte dal kernel (errore %1).<br>Svuota la cronologia e se l'errore persiste, contatta il nostro team di supporto. - + Unfortunately your old configuration could not be migrated.<br>The application will use a blank configuration. Purtroppo la tua vecchia configurazione non può essere migrata. <br>L'applicazione userà una configurazione vuota. - + Unfortunately your old proxy configuration could not be migrated, SOCKS5 proxies are not supported at this time.<br>The application will use system proxy settings instead. Purtroppo la tua vecchia configurazione proxy non può essere migrata, i proxy SOCKS5 non sono supportati al momento. <br>L'applicazione userà invece le impostazioni del proxy di sistema. - + A technical error has occurred (error %1).<br>Synchronization has been restarted. Please empty the history and if the error persists, please contact our support team. Si è verificato un errore tecnico (errore %1).<br>La sincronizzazione è stata riavviata. Svuota la cronologia e se l'errore persiste, contatta il nostro team di assistenza. - + An error accessing the synchronization database has happened (error %1).<br>Synchronization has been stopped. Si è verificato un errore nell'accedere al database di sincronizzazione (errore %1). <br>La sincronizzazione è stata interrotta. - + A login problem has occurred (error %1).<br>Token invalid or revoked. Si è verificato un problema di accesso (errore %1).<br>Token non valido o revocato. - + Nested synchronizations are prohibited (error %1).<br>You should only keep synchronizations whose folders are not nested. Le sincronizzazioni nidificate sono vietate (errore %1).<br>Conservare solo le sincronizzazioni le cui cartelle non sono nidificate. - - The app does not have write rights to the synchronization folder.<br>The synchronization has been stopped. - L'app non dispone dei diritti di scrittura sulla cartella di sincronizzazione.<br>La sincronizzazione è stata interrotta. - - - + File name parsing error (error %1).<br>Special characters such as double quotes, backslashes or line returns can cause parsing failures. Errore durante l'analisi del nome file (errore %1).<br>Caratteri speciali come virgolette doppie, barre rovesciate o ritorni a capo possono causare errori di analisi. - + An element was moved to a deleted folder.<br>The move has been canceled. Un elemento è stato spostato in una cartella eliminata.<br>L'operazione è stata annullata. - + This element was moved by another user.<br>The deletion has been canceled. Questo elemento è stato spostato da un altro utente.<br>L'eliminazione è stata annullata. - + An element was created in this folder while it was being deleted.<br>The delete operation has been propagated anyway. Un elemento è stato creato in questa cartella durante l'eliminazione.<br>L'operazione di eliminazione è stata comunque propagata. - + This element has been moved somewhere else.<br>The local operation has been canceled. Questo elemento è stato spostato altrove.<br>L'operazione locale è stata annullata. - - + + An element with the same name already exists in this location.<br>The local element has been renamed. In questa posizione esiste già un elemento con lo stesso nome.<br>L'elemento locale è stato rinominato. - + An element with the same name already exists in this location.<br>The local operation has been canceled. Un elemento con lo stesso nome esiste già in questa posizione.<br>L'operazione locale è stata annullata. - + The content of the file was modified while it was being deleted.<br>The deletion has been canceled. Il contenuto del file è stato modificato mentre veniva eliminato.<br>L'eliminazione è stata annullata. - + The content of a synchronized element was modified while a parent folder was being deleted (e.g. the folder containing the current folder).<br>The file has been moved to the root of your kDrive. Il contenuto di un elemento sincronizzato è stato modificato mentre veniva eliminata una cartella padre (ad es. la cartella contenente la cartella corrente).<br>Il file è stato spostato nella radice del tuo kDrive. - + The content of an already synchronized file has been modified while this one or one of its parent folders has been deleted.<br> Il contenuto di un file già sincronizzato è stato modificato mentre esso o una sua directory padre è stata eliminata.<br> - + The file was modified at the same time by another user.<br>Your modifications have been saved in a copy. Il file è stato modificato contemporaneamente da un altro utente.<br>Le tue modifiche sono state salvate in una copia. - + Another user has moved a parent folder of the destination.<br>The local operation has been canceled. Un altro utente ha spostato una cartella padre della destinazione.<br>L'operazione locale è stata annullata. - + An existing file/directory has an identical name with the same case options (same upper and lower case letters).<br>The file/directory has been temporarily blacklisted. Un file/directory esistente ha un nome identico con le stesse opzioni maiuscole e minuscole (stesse lettere maiuscole e minuscole).<br>Il file/directory è stato temporaneamente inserito nella lista nera. - + The file/directory name contains an unsupported character.<br>The file/directory has been temporarily blacklisted. Il nome del file/della directory contiene un carattere non supportato.<br>Il file/la directory è stato temporaneamente inserito nella lista nera. - + This file/directory name is reserved by your operating system.<br>The file/directory has been temporarily blacklisted. Questo nome di file/directory è riservato dal tuo sistema operativo.<br>Il file/directory è stato temporaneamente inserito nella blacklist. - + The file/directory name is too long.<br>The file/directory has been temporarily blacklisted. Il nome file/directory è troppo lungo.<br>Il file/directory è stato temporaneamente inserito nella blacklist. - + The file/directory path is too long.<br>The file/directory is ignored. Il percorso del file/directory è troppo lungo.<br>Il file/directory viene ignorato. - + The file/directory name contains a recent UNICODE character not yet supported by your filesystem.<br>The parent directory has been excluded from synchronization. Il nome del file/directory contiene un carattere UNICODE recente non ancora supportato dal file system.<br>La directory principale è stata esclusa dalla sincronizzazione. - + The file/directory name coincides with the name of another item in the same directory.<br>This item is temporarily blacklisted. Consider removing duplicate items. Il nome del file/directory coincide con il nome di un altro elemento nella stessa directory.<br>Questo elemento è temporaneamente inserito nella lista nera. Valuta la possibilità di rimuovere gli elementi duplicati. - + Either you are not allowed to create an item, or another item already exists with the same name.<br>The item has been excluded from synchronization. O non si è autorizzati a creare un elemento, oppure esiste già un altro elemento con lo stesso nome.<br>L'elemento è stato escluso dalla sincronizzazione. - + You are not allowed to edit item.<br>The file containing your modifications has been renamed and excluded from synchronization. Non disponi dell'autorizzazione per modificare l'elemento.<br>Il file contenente le tue modifiche è stato rinominato ed escluso dalla sincronizzazione. - + You are not allowed to rename item.<br>It will be restored with its original name. Non disponi dell'autorizzazione per rinominare l'elemento.<br>Verrà ripristinato con il suo nome originale. - + You are not allowed to move item to "%1".<br>It will be restored to its original location. Non disponi dell'autorizzazione per spostare l'elemento in "%1".<br>Verrà ripristinato alla sua posizione originale. - + You are not allowed to delete item.<br>It will be restored to its original location. Non disponi dell'autorizzazione per eliminare l'elemento.<br>Verrà ripristinato alla sua posizione originale. - + Failed to move this item to trash, it has been blacklisted. Impossibile spostare questo elemento nel cestino, è stato inserito nella lista nera. - + This item has been excluded from sync because it is an hard link Questo elemento è stato escluso dalla sincronizzazione perché si tratta di un collegamento rigido. - + The operation performed on item is forbidden.<br>The item has been temporarily blacklisted. L'operazione eseguita sull'articolo è vietata.<br>L'articolo è stato temporaneamente inserito nella lista nera. - + The operation performed on this item failed.<br>The item has been temporarily blacklisted. L'operazione eseguita su questo articolo non è riuscita.<br>L'articolo è stato temporaneamente inserito nella lista nera. - - Can't access item.<br>Please fix the write permissions and restart the synchronization. - Impossibile accedere all'elemento.<br>Correggere i permessi di scrittura e riavviare la sincronizzazione. - - - + Move to trash failed. Spostamento nel cestino non riuscito. - + The file is too large to be uploaded. It has been temporarily blacklisted. Il file è troppo grande per essere caricato. È stato temporaneamente inserito nella lista nera. - + Impossible to download the file. Impossibile scaricare il file. - + You have exceeded your quota. Increase your space quota to re-enable file upload. Hai superato la tua quota. Aumenta la tua quota di spazio per riattivare il caricamento dei file. - + + The synchronization folder is inaccessible (error %1).<br>Please check that you have read and write access to this folder. + La cartella di sincronizzazione è inaccessibile (errore %1).<br>Verificare di avere accesso in lettura e scrittura a questa cartella. + + + This item already exists on remote kDrive. It is not synced because it has been blacklisted. Questo elemento esiste già su kDrive remoto. Non è sincronizzato perché è stato inserito nella lista nera. - + This item already exists on local file system. It is not synced. Questo elemento esiste già nel sistema di file locale. Non è sincronizzato. - + Failed to synchronize this item. It has been temporarily blacklisted.<br>Another attempt to sync it will be done in one hour or on next application startup. La sincronizzazione di questo elemento è fallita. È stato temporaneamente inserito nella lista nera.<br>Un altro tentativo di sincronizzazione verrà effettuato tra un'ora o al successivo avvio dell'applicazione. - + This item has been excluded from sync by a custom template.<br>You can disable this type of notification from the Preferences Questo elemento è stato escluso dalla sincronizzazione da un modello personalizzato. È possibile disattivare questo tipo di notifica dalle preferenze - - + + Synchronization error. Errore di sincronizzazione. - + + Can't access item.<br>Please fix the read and write permissions. + Impossibile accedere all'elemento.<br>Si prega di correggere i permessi di lettura e scrittura. + + + + System error. + Errore di sistema. + + + A technical error has occurred.<br>Please empty the history and if the error persists, contact our support team. Si è verificato un errore tecnico.<br>Svuota la cronologia e, se l'errore persiste, contatta il nostro team di assistenza. @@ -2216,35 +2206,35 @@ Per favore, utilizza il seguente link per inviare i log al supporto: <a style KDC::SocketApi - - - + + + Copy private share link Copia il collegamento di condivisione privata - - + + Resharing this file is not allowed Ricondivisione di questo file non consentita - - + + Resharing this folder is not allowed Ricondivisione di questa cartella non consentita - - - - + + + + Copy public share link Copia il collegamento di condivisione pubblica - - + + Open in browser Apri nel browser @@ -2320,202 +2310,202 @@ Per favore, utilizza il seguente link per inviare i log al supporto: <a style KDC::SynthesisPopover - - + + Never Mai - + During 1 hour Per 1 ora - - + + Until tomorrow 8:00AM Fino alle 8:00 di domani - + During 3 days Per 3 giorni - + During 1 week Per 1 settimana - - + + Always Sempre - + For 1 more hour Per 1 altra ora - + For 3 more days Per altri 3 giorni - + For 1 more week Per 1 altra settimana - + Update kDrive App Aggiorna l'app kDrive - + This kDrive app version is not supported anymore. To access the latest features and enhancements, please update. Questa versione dell'app kDrive non è più supportata. Per accedere alle funzionalità e ai miglioramenti più recenti, aggiornare. - - + + Update Aggiornamento - + Please download the latest version on the website. Si prega di scaricare l'ultima versione dal sito web. - + Update download in progress Download dell'aggiornamento in corso - + Looking for update... In cerca di aggiornamento... - + Manual update Aggiornamento manuale - + Unavailable Non disponibile - + Quit kDrive Esci da kDrive - + Show errors and informations Mostra errori e informazioni - + Show informations Mostra informazioni - + You can synchronize files <a style="%1" href="%2">from your computer</a> or on <a style="%1" href="%3">kdrive.infomaniak.com</a>. Puoi sincronizzare i file <a style="%1" href="%2">dal tuo computer</a> o su <a style="%1" href="%3">kdrive.infomaniak.com</a>. - + Open in folder Apri nella cartella - + More actions Più azioni - + Synchronized Sincronizzata - + Favorites Preferiti - + Activity Attività - - + + Not implemented! Non implementato! - + No synchronized folder for this Drive! Nessuna cartella sincronizzata per questo kDrive! - + No kDrive configured! Nessun kDrive configurato! - + Unable to access web site %1. Impossibile accedere al sito web %1. - + Open %1 web version Apri la versione web %1 - + Notifications disabled until %1 Notifiche disabilitate fino al %1 - + Disable Notifications Disabilita notifiche - + Need help Hai bisogno di aiuto - + Unable to open link %1. Impossibile aprire il link %1. - + Invalid link %1. Link %1 non valido. - + Unable to open folder url %1. Impossibile aprire l'URL della cartella %1. - + Drive parameters Parametri unità - + Application preferences Preferenze dell'applicazione @@ -2645,47 +2635,47 @@ Per favore, utilizza il seguente link per inviare i log al supporto: <a style Impossibile salvare i parametri! - + The parent folder is a sync folder or contained in one La cartella padre è una cartella di sincronizzazione o contenuta in un - + Can't find a valid path Impossibile trovare un percorso valido - + No valid folder selected! Nessuna cartella valida selezionata! - + The selected path does not exist! Il percorso selezionato non esiste! - + The selected path is not a folder! Il percorso selezionato non è una cartella! - + You have no permission to write to the selected folder! Non disponi dell'autorizzazione di scrittura per la cartella selezionata! - + The local folder %1 contains a folder already synced. Please pick another one! La cartella locale %1 contiene una cartella già sincronizzata. Scegline un'altra! - + The local folder %1 is contained in a folder already synced. Please pick another one! La cartella locale %1 è contenuta in una cartella già sincronizzata. Scegline un'altra! - + The local folder %1 is already synced on the same drive. Please pick another one! La cartella locale %1 è già sincronizzata sulla stessa unità. Scegline un'altra! @@ -2806,23 +2796,23 @@ Per favore, utilizza il seguente link per inviare i log al supporto: <a style utility - + Free up local space Libera spazio locale - + Cancel free up local space Annulla liberazione di spazio locale - - + + Cancel make available locally Annulla rendere disponibile localmente - + Always make available locally Rendi sempre disponibile localmente From 3407b8b4094be402008dc2a682c375b66602218e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Kunz?= Date: Wed, 13 Nov 2024 08:14:00 +0100 Subject: [PATCH 054/178] KDESKTOP-1372 - Fix TestUpdateChecker::testCheckUpdateAvailable --- test/server/updater/testupdatechecker.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/server/updater/testupdatechecker.cpp b/test/server/updater/testupdatechecker.cpp index 2a95c1156..a8de9e0ae 100644 --- a/test/server/updater/testupdatechecker.cpp +++ b/test/server/updater/testupdatechecker.cpp @@ -27,9 +27,9 @@ namespace KDC { static const std::string bigVersionJsonUpdateStr = - R"({"result":"success","data":{"application_id":27,"has_prod_next":false,"version":{"tag":"99.99.99","tag_updated_at":"2124-06-04 15:06:37","version_changelog":"test","type":"production","build_version":"21240604","build_min_os_version":"21240604","download_link":"test","data":["[]"]},"application":{"id":27,"name":"com.infomaniak.drive","platform":"mac-os","store":"kStore","api_id":"com.infomaniak.drive","min_version":"99.99.99","next_version_rate":0,"published_versions":[{"tag":"99.99.99","tag_updated_at":"2124-06-04 15:06:37","version_changelog":"test","type":"production","build_version":"21240604","build_min_os_version":"21240604","download_link":"test","data":["[]"]},{"tag":"99.99.99","tag_updated_at":"2124-06-04 15:06:12","version_changelog":"test","type":"beta","build_version":"21240604","build_min_os_version":"21240604","download_link":"test","data":["[]"]},{"tag":"99.99.99","tag_updated_at":"2124-06-04 15:05:44","version_changelog":"test","type":"internal","build_version":"21240604","build_min_os_version":"21240604","download_link":"test","data":["[]"]},{"tag":"99.99.99","tag_updated_at":"2124-06-04 15:03:29","version_changelog":"test","type":"production-next","build_version":"21240604","build_min_os_version":"21240604","download_link":"test","data":["[]"]}]}}})"; + R"({"result":"success","data":{"application_id":27,"prod_version":"production","version":{"tag":"99.99.99","tag_updated_at":"2124-06-04 15:06:37","version_changelog":"test","type":"production","build_version":"21240604","build_min_os_version":"21240604","download_link":"test","data":["[]"]},"application":{"id":27,"name":"com.infomaniak.drive","platform":"mac-os","store":"kStore","api_id":"com.infomaniak.drive","min_version":"99.99.99","next_version_rate":0,"published_versions":[{"tag":"99.99.99","tag_updated_at":"2124-06-04 15:06:37","version_changelog":"test","type":"production","build_version":"21240604","build_min_os_version":"21240604","download_link":"test","data":["[]"]},{"tag":"99.99.99","tag_updated_at":"2124-06-04 15:06:12","version_changelog":"test","type":"beta","build_version":"21240604","build_min_os_version":"21240604","download_link":"test","data":["[]"]},{"tag":"99.99.99","tag_updated_at":"2124-06-04 15:05:44","version_changelog":"test","type":"internal","build_version":"21240604","build_min_os_version":"21240604","download_link":"test","data":["[]"]},{"tag":"99.99.99","tag_updated_at":"2124-06-04 15:03:29","version_changelog":"test","type":"production-next","build_version":"21240604","build_min_os_version":"21240604","download_link":"test","data":["[]"]}]}}})"; static const std::string smallVersionJsonUpdateStr = - R"({"result":"success","data":{"application_id":27,"has_prod_next":false,"version":{"tag":"1.1.1","tag_updated_at":"2020-06-04 15:06:37","version_changelog":"test","type":"production","build_version":"20200604","build_min_os_version":"20200604","download_link":"test","data":["[]"]},"application":{"id":27,"name":"com.infomaniak.drive","platform":"mac-os","store":"kStore","api_id":"com.infomaniak.drive","min_version":"1.1.1","next_version_rate":0,"published_versions":[{"tag":"1.1.1","tag_updated_at":"2020-06-04 15:06:37","version_changelog":"test","type":"production","build_version":"20200604","build_min_os_version":"20200604","download_link":"test","data":["[]"]},{"tag":"1.1.1","tag_updated_at":"2020-06-04 15:06:12","version_changelog":"test","type":"beta","build_version":"20200604","build_min_os_version":"20200604","download_link":"test","data":["[]"]},{"tag":"1.1.1","tag_updated_at":"2020-06-04 15:05:44","version_changelog":"test","type":"internal","build_version":"20200604","build_min_os_version":"20200604","download_link":"test","data":["[]"]},{"tag":"1.1.1","tag_updated_at":"2020-06-04 15:03:29","version_changelog":"test","type":"production-next","build_version":"20200604","build_min_os_version":"20200604","download_link":"test","data":["[]"]}]}}})"; + R"({"result":"success","data":{"application_id":27,"prod_version":"production","version":{"tag":"1.1.1","tag_updated_at":"2020-06-04 15:06:37","version_changelog":"test","type":"production","build_version":"20200604","build_min_os_version":"20200604","download_link":"test","data":["[]"]},"application":{"id":27,"name":"com.infomaniak.drive","platform":"mac-os","store":"kStore","api_id":"com.infomaniak.drive","min_version":"1.1.1","next_version_rate":0,"published_versions":[{"tag":"1.1.1","tag_updated_at":"2020-06-04 15:06:37","version_changelog":"test","type":"production","build_version":"20200604","build_min_os_version":"20200604","download_link":"test","data":["[]"]},{"tag":"1.1.1","tag_updated_at":"2020-06-04 15:06:12","version_changelog":"test","type":"beta","build_version":"20200604","build_min_os_version":"20200604","download_link":"test","data":["[]"]},{"tag":"1.1.1","tag_updated_at":"2020-06-04 15:05:44","version_changelog":"test","type":"internal","build_version":"20200604","build_min_os_version":"20200604","download_link":"test","data":["[]"]},{"tag":"1.1.1","tag_updated_at":"2020-06-04 15:03:29","version_changelog":"test","type":"production-next","build_version":"20200604","build_min_os_version":"20200604","download_link":"test","data":["[]"]}]}}})"; class GetAppVersionJobTest final : public GetAppVersionJob { public: From 4ad40c1a17386c7afbcab654548d81295a6aa1ca Mon Sep 17 00:00:00 2001 From: Herve Eruam Date: Wed, 13 Nov 2024 08:57:47 +0100 Subject: [PATCH 055/178] Uncomment a line + fix indentation issue --- src/libcommonserver/io/iohelper_win.cpp | 2 +- test/libcommonserver/io/testio.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libcommonserver/io/iohelper_win.cpp b/src/libcommonserver/io/iohelper_win.cpp index 91c97ecfc..0b1e699fb 100644 --- a/src/libcommonserver/io/iohelper_win.cpp +++ b/src/libcommonserver/io/iohelper_win.cpp @@ -585,7 +585,7 @@ static bool getRightsWindowsApi(const SyncPath &path, bool &read, bool &write, b // Get rights for trustee ACCESS_MASK rights = 0; - //result = GetEffectiveRightsFromAcl(pfileACL, &IoHelper::getTrustee(), &rights); + result = GetEffectiveRightsFromAcl(pfileACL, &IoHelper::getTrustee(), &rights); ioError = dWordError2ioError(result, logger); /* The GetEffectiveRightsFromAcl function fails and returns ERROR_INVALID_ACL if the specified ACL contains an inherited diff --git a/test/libcommonserver/io/testio.h b/test/libcommonserver/io/testio.h index 5db792e98..fd3793219 100644 --- a/test/libcommonserver/io/testio.h +++ b/test/libcommonserver/io/testio.h @@ -43,7 +43,7 @@ struct IoHelperTests : public IoHelper { class TestIo : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(TestIo); - CPPUNIT_TEST(testCheckSetAndGetRights); // Keep this test before any tests that may use set/get rights functions + CPPUNIT_TEST(testCheckSetAndGetRights); // Keep this test before any tests that may use set/get rights functions CPPUNIT_TEST(testGetItemType); CPPUNIT_TEST(testGetFileSize); CPPUNIT_TEST(testTempDirectoryPath); From ee63ba2364fc9d78ce589e6d50eb1ef441dd1199 Mon Sep 17 00:00:00 2001 From: Herve Eruam Date: Wed, 13 Nov 2024 10:00:30 +0100 Subject: [PATCH 056/178] Fix testAccesDeniedOnLockedFiles on mac and linux. --- .../io/testcheckdirectoryiterator.cpp | 13 -------- test/libcommonserver/io/testio.cpp | 30 +++++++++++++++++++ 2 files changed, 30 insertions(+), 13 deletions(-) diff --git a/test/libcommonserver/io/testcheckdirectoryiterator.cpp b/test/libcommonserver/io/testcheckdirectoryiterator.cpp index 99a90a44a..7f563565c 100644 --- a/test/libcommonserver/io/testcheckdirectoryiterator.cpp +++ b/test/libcommonserver/io/testcheckdirectoryiterator.cpp @@ -322,17 +322,4 @@ void TestIo::testCheckDirectoryPermissionLost() { CPPUNIT_ASSERT(endOfDirectory); } } - -void TestIo::testAccesDeniedOnLockedFiles() { - LocalTemporaryDirectory tmpDir("TestIo-testAccesDeniedOnLockedFiles"); - const SyncPath lockedFile = tmpDir.path() / "lockedFile.txt"; - std::ofstream file(lockedFile); - CPPUNIT_ASSERT(file.is_open()); - - std::error_code ec; - std::filesystem::remove_all(lockedFile, ec); - IoError ioError = IoHelper::stdError2ioError(ec); - CPPUNIT_ASSERT_EQUAL(IoError::AccessDenied, ioError); -} - } // namespace KDC diff --git a/test/libcommonserver/io/testio.cpp b/test/libcommonserver/io/testio.cpp index 67d34a42c..3871e4c0e 100644 --- a/test/libcommonserver/io/testio.cpp +++ b/test/libcommonserver/io/testio.cpp @@ -149,4 +149,34 @@ void TestIo::testLogDirectoryPath() { } } +void TestIo::testAccesDeniedOnLockedFiles() { + LocalTemporaryDirectory tmpDir("TestIo-testAccesDeniedOnLockedFiles"); + const SyncPath lockedFile = tmpDir.path() / "lockedFile.txt"; + std::ofstream file(lockedFile); + CPPUNIT_ASSERT(file.is_open()); + file.close(); + + // Lock the file +#ifdef _WIN32 + auto hFile = CreateFile(lockedFile.c_str(), GENERIC_READ, 0, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); + CPPUNIT_ASSERT(hFile != INVALID_HANDLE_VALUE); +#else + int fd = open(lockedFile.c_str(), O_RDONLY); + CPPUNIT_ASSERT(fd != -1); +#endif + + std::error_code ec; + std::filesystem::remove_all(lockedFile, ec); + IoError ioError = IoHelper::stdError2ioError(ec); + + // Unlock the file +#ifdef _WIN32 + CloseHandle(hFile); +#else + close(fd); +#endif + + CPPUNIT_ASSERT_EQUAL(IoError::AccessDenied, ioError); +} + } // namespace KDC From 7f001afe54ac100682bec0765abbab7e325e226c Mon Sep 17 00:00:00 2001 From: Herve Eruam Date: Wed, 13 Nov 2024 10:29:43 +0100 Subject: [PATCH 057/178] Fix testAccesDeniedOnLockedFiles on mac and linux. --- test/libcommonserver/io/testio.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/test/libcommonserver/io/testio.cpp b/test/libcommonserver/io/testio.cpp index 3871e4c0e..2a84722c7 100644 --- a/test/libcommonserver/io/testio.cpp +++ b/test/libcommonserver/io/testio.cpp @@ -20,6 +20,10 @@ #include "config.h" #include +#ifndef _WIN32 +#include +#include +#endif using namespace CppUnit; @@ -161,7 +165,7 @@ void TestIo::testAccesDeniedOnLockedFiles() { auto hFile = CreateFile(lockedFile.c_str(), GENERIC_READ, 0, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); CPPUNIT_ASSERT(hFile != INVALID_HANDLE_VALUE); #else - int fd = open(lockedFile.c_str(), O_RDONLY); + int fd = open(lockedFile.c_str(), O_RDWR); CPPUNIT_ASSERT(fd != -1); #endif From 3499d58b0711bc692e814e885711852e5088c3d5 Mon Sep 17 00:00:00 2001 From: Luc Guyot Date: Wed, 13 Nov 2024 10:46:37 +0100 Subject: [PATCH 058/178] [KDESKTOP-1378] Check the type of a created item to in Common Documents to decide if it can be replicated on the remote side --- src/libsyncengine/propagation/executor/executorworker.cpp | 8 +++++--- src/libsyncengine/reconciliation/syncoperation.cpp | 4 ++++ src/libsyncengine/reconciliation/syncoperation.h | 1 + 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/libsyncengine/propagation/executor/executorworker.cpp b/src/libsyncengine/propagation/executor/executorworker.cpp index 62e3ff9f6..522b879e7 100644 --- a/src/libsyncengine/propagation/executor/executorworker.cpp +++ b/src/libsyncengine/propagation/executor/executorworker.cpp @@ -405,7 +405,7 @@ ExitInfo ExecutorWorker::handleCreateOp(SyncOpPtr syncOp, std::shared_ptraffectedNode()->type() == NodeType::Directory) { // Propagate the directory creation immediately in order to avoid blocking other dependant job creation - if (const ExitInfo exitInfoRunCreateDirJob = runCreateDirJob(syncOp, job); !exitInfoRunCreateDirJob ) { + if (const ExitInfo exitInfoRunCreateDirJob = runCreateDirJob(syncOp, job); !exitInfoRunCreateDirJob) { std::shared_ptr createDirJob = std::dynamic_pointer_cast(job); if (createDirJob && (createDirJob->getStatusCode() == Poco::Net::HTTPResponse::HTTP_BAD_REQUEST || createDirJob->getStatusCode() == Poco::Net::HTTPResponse::HTTP_FORBIDDEN)) { @@ -423,7 +423,7 @@ ExitInfo ExecutorWorker::handleCreateOp(SyncOpPtr syncOp, std::shared_ptrisCommonDocumentsFolder()) { + + if (newCorrespondingParentNode->isCommonDocumentsFolder() && syncOp->nodeType() != NodeType::Directory) { return false; } @@ -1445,6 +1446,7 @@ bool ExecutorWorker::isValidDestination(const SyncOpPtr syncOp) { return false; } } + return true; } diff --git a/src/libsyncengine/reconciliation/syncoperation.cpp b/src/libsyncengine/reconciliation/syncoperation.cpp index d94a6f6e3..7a2375ff0 100644 --- a/src/libsyncengine/reconciliation/syncoperation.cpp +++ b/src/libsyncengine/reconciliation/syncoperation.cpp @@ -36,6 +36,10 @@ SyncPath SyncOperation::nodePath(const ReplicaSide side) const { return node->getPath(); } +NodeType SyncOperation::nodeType() const noexcept { + return _affectedNode ? _affectedNode->type() : NodeType::Unknown; +} + bool SyncOperation::operator==(const SyncOperation &other) const { return _id == other.id(); } diff --git a/src/libsyncengine/reconciliation/syncoperation.h b/src/libsyncengine/reconciliation/syncoperation.h index 8782d7c8b..ad3992f5f 100644 --- a/src/libsyncengine/reconciliation/syncoperation.h +++ b/src/libsyncengine/reconciliation/syncoperation.h @@ -51,6 +51,7 @@ class SyncOperation { [[nodiscard]] SyncName nodeName(ReplicaSide side) const; [[nodiscard]] SyncPath nodePath(ReplicaSide side) const; + [[nodiscard]] NodeType nodeType() const noexcept; bool operator==(const SyncOperation &other) const; From 624fec583c3b3d6d3fd8fd65d3dfcd1688e05383 Mon Sep 17 00:00:00 2001 From: Herve Eruam Date: Wed, 13 Nov 2024 11:08:23 +0100 Subject: [PATCH 059/178] Fix testAccesDeniedOnLockedFiles --- test/libcommonserver/io/testio.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test/libcommonserver/io/testio.cpp b/test/libcommonserver/io/testio.cpp index 2a84722c7..b832a3a54 100644 --- a/test/libcommonserver/io/testio.cpp +++ b/test/libcommonserver/io/testio.cpp @@ -154,6 +154,10 @@ void TestIo::testLogDirectoryPath() { } void TestIo::testAccesDeniedOnLockedFiles() { +#if !_WIN32 && !__APPLE__ // This test is only relevant on Windows and macOS + return; +#endif + LocalTemporaryDirectory tmpDir("TestIo-testAccesDeniedOnLockedFiles"); const SyncPath lockedFile = tmpDir.path() / "lockedFile.txt"; std::ofstream file(lockedFile); @@ -167,6 +171,7 @@ void TestIo::testAccesDeniedOnLockedFiles() { #else int fd = open(lockedFile.c_str(), O_RDWR); CPPUNIT_ASSERT(fd != -1); + fcntl(fd, F_SETLK, nullptr); #endif std::error_code ec; From 0ec334d685e27b69195694bd9df84dacbc7d8f29 Mon Sep 17 00:00:00 2001 From: Herve Eruam Date: Wed, 13 Nov 2024 11:11:56 +0100 Subject: [PATCH 060/178] add #include --- test/libcommonserver/io/testio.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/test/libcommonserver/io/testio.cpp b/test/libcommonserver/io/testio.cpp index b832a3a54..882787933 100644 --- a/test/libcommonserver/io/testio.cpp +++ b/test/libcommonserver/io/testio.cpp @@ -23,6 +23,7 @@ #ifndef _WIN32 #include #include +#include #endif using namespace CppUnit; From 1d962d0d8538b9b11d900a9110b250033bb9f5e1 Mon Sep 17 00:00:00 2001 From: Herve Eruam Date: Wed, 13 Nov 2024 11:26:28 +0100 Subject: [PATCH 061/178] Do not test AccesDeniedOnLockedFiles on Linux and mac OS --- test/libcommonserver/io/testio.cpp | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/test/libcommonserver/io/testio.cpp b/test/libcommonserver/io/testio.cpp index 882787933..5ede11fe6 100644 --- a/test/libcommonserver/io/testio.cpp +++ b/test/libcommonserver/io/testio.cpp @@ -155,7 +155,7 @@ void TestIo::testLogDirectoryPath() { } void TestIo::testAccesDeniedOnLockedFiles() { -#if !_WIN32 && !__APPLE__ // This test is only relevant on Windows and macOS +#ifndef _WIN32 // This test is only relevant on Windows, as on Unix systems, there is no standard way to lock files. return; #endif @@ -166,26 +166,16 @@ void TestIo::testAccesDeniedOnLockedFiles() { file.close(); // Lock the file -#ifdef _WIN32 auto hFile = CreateFile(lockedFile.c_str(), GENERIC_READ, 0, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); CPPUNIT_ASSERT(hFile != INVALID_HANDLE_VALUE); -#else - int fd = open(lockedFile.c_str(), O_RDWR); - CPPUNIT_ASSERT(fd != -1); - fcntl(fd, F_SETLK, nullptr); -#endif + // Try to delete the file std::error_code ec; std::filesystem::remove_all(lockedFile, ec); IoError ioError = IoHelper::stdError2ioError(ec); // Unlock the file -#ifdef _WIN32 CloseHandle(hFile); -#else - close(fd); -#endif - CPPUNIT_ASSERT_EQUAL(IoError::AccessDenied, ioError); } From 88a1dc6ef6fd1e2a535a7fd9fb036dd4166e7a57 Mon Sep 17 00:00:00 2001 From: Herve Eruam Date: Wed, 13 Nov 2024 11:40:26 +0100 Subject: [PATCH 062/178] Remove useless include. --- test/libcommonserver/io/testio.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/test/libcommonserver/io/testio.cpp b/test/libcommonserver/io/testio.cpp index 5ede11fe6..0562d0d3b 100644 --- a/test/libcommonserver/io/testio.cpp +++ b/test/libcommonserver/io/testio.cpp @@ -20,11 +20,6 @@ #include "config.h" #include -#ifndef _WIN32 -#include -#include -#include -#endif using namespace CppUnit; From 04fdf269d7cad56384ccc834806ffd2c37e2d1b7 Mon Sep 17 00:00:00 2001 From: Herve Eruam Date: Wed, 13 Nov 2024 11:45:55 +0100 Subject: [PATCH 063/178] Fix compilation issue. --- test/libcommonserver/io/testio.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/test/libcommonserver/io/testio.cpp b/test/libcommonserver/io/testio.cpp index 0562d0d3b..7f7feb52c 100644 --- a/test/libcommonserver/io/testio.cpp +++ b/test/libcommonserver/io/testio.cpp @@ -150,10 +150,7 @@ void TestIo::testLogDirectoryPath() { } void TestIo::testAccesDeniedOnLockedFiles() { -#ifndef _WIN32 // This test is only relevant on Windows, as on Unix systems, there is no standard way to lock files. - return; -#endif - +#ifdef _WIN32 // This test is only relevant on Windows, as on Unix systems, there is no standard way to lock files. LocalTemporaryDirectory tmpDir("TestIo-testAccesDeniedOnLockedFiles"); const SyncPath lockedFile = tmpDir.path() / "lockedFile.txt"; std::ofstream file(lockedFile); @@ -172,6 +169,7 @@ void TestIo::testAccesDeniedOnLockedFiles() { // Unlock the file CloseHandle(hFile); CPPUNIT_ASSERT_EQUAL(IoError::AccessDenied, ioError); +#endif } } // namespace KDC From 0402787e854634d5e4b78eacb67b6e39ab1abeb5 Mon Sep 17 00:00:00 2001 From: Luc Guyot Date: Wed, 13 Nov 2024 11:59:27 +0100 Subject: [PATCH 064/178] Adds unit tests for ExecutorWorker::isValidDestination --- .../propagation/executor/executorworker.cpp | 1 - .../jobs/network/testsnapshotitemhandler.h | 2 -- .../executor/testexecutorworker.cpp | 24 ++++++++++++++++++- .../propagation/executor/testexecutorworker.h | 6 +++-- 4 files changed, 27 insertions(+), 6 deletions(-) diff --git a/src/libsyncengine/propagation/executor/executorworker.cpp b/src/libsyncengine/propagation/executor/executorworker.cpp index 522b879e7..4f0c67d06 100644 --- a/src/libsyncengine/propagation/executor/executorworker.cpp +++ b/src/libsyncengine/propagation/executor/executorworker.cpp @@ -1437,7 +1437,6 @@ bool ExecutorWorker::isValidDestination(const SyncOpPtr syncOp) { return false; } - if (newCorrespondingParentNode->isCommonDocumentsFolder() && syncOp->nodeType() != NodeType::Directory) { return false; } diff --git a/test/libsyncengine/jobs/network/testsnapshotitemhandler.h b/test/libsyncengine/jobs/network/testsnapshotitemhandler.h index bb4685753..a66cbee97 100644 --- a/test/libsyncengine/jobs/network/testsnapshotitemhandler.h +++ b/test/libsyncengine/jobs/network/testsnapshotitemhandler.h @@ -49,8 +49,6 @@ struct Result { bool success{true}; std::string message; }; -static std::string makeMessage(const CppUnit::Exception &e); -static Result compare(const SnapshotItem &lhs, const SnapshotItem &rhs) noexcept; } // namespace snapshotitem_checker } // namespace KDC diff --git a/test/libsyncengine/propagation/executor/testexecutorworker.cpp b/test/libsyncengine/propagation/executor/testexecutorworker.cpp index aeb04e229..2cdbde318 100644 --- a/test/libsyncengine/propagation/executor/testexecutorworker.cpp +++ b/test/libsyncengine/propagation/executor/testexecutorworker.cpp @@ -161,7 +161,8 @@ void TestExecutorWorker::testCheckLiteSyncInfoForCreate() { #endif } -SyncOpPtr TestExecutorWorker::generateSyncOperation(const DbNodeId dbNodeId, const SyncName &filename) { +SyncOpPtr TestExecutorWorker::generateSyncOperation(const DbNodeId dbNodeId, const SyncName &filename, + const OperationType opType) { auto node = std::make_shared(dbNodeId, ReplicaSide::Local, filename, NodeType::File, OperationType::None, "lid", testhelpers::defaultTime, testhelpers::defaultTime, testhelpers::defaultFileSize, _syncPal->updateTree(ReplicaSide::Local)->rootNode()); @@ -172,10 +173,31 @@ SyncOpPtr TestExecutorWorker::generateSyncOperation(const DbNodeId dbNodeId, con SyncOpPtr op = std::make_shared(); op->setAffectedNode(node); op->setCorrespondingNode(correspondingNode); + op->setType(opType); return op; } +void TestExecutorWorker::testIsValidDestination() { + // Always true if the target side is local or unknown + { + SyncOpPtr op = generateSyncOperation(1, Str("test_file.txt")); + CPPUNIT_ASSERT(_syncPal->_executorWorker->isValidDestination(op)); + } + // Always true if the operation is not of type Create + { + SyncOpPtr op = generateSyncOperation(1, Str("test_file.txt")); + op->setTargetSide(ReplicaSide::Remote); + CPPUNIT_ASSERT(_syncPal->_executorWorker->isValidDestination(op)); + } + // Always true if the item is created on the local replica, at the root of the synchronisation folder + { + SyncOpPtr op = generateSyncOperation(1, Str("test_file.txt"), OperationType::Create); + op->setTargetSide(ReplicaSide::Remote); + CPPUNIT_ASSERT(_syncPal->_executorWorker->isValidDestination(op)); + } +} + void TestExecutorWorker::testLogCorrespondingNodeErrorMsg() { SyncOpPtr op = generateSyncOperation(1, Str("test_file.txt")); _syncPal->_executorWorker->logCorrespondingNodeErrorMsg(op); diff --git a/test/libsyncengine/propagation/executor/testexecutorworker.h b/test/libsyncengine/propagation/executor/testexecutorworker.h index d4de7790f..316590112 100644 --- a/test/libsyncengine/propagation/executor/testexecutorworker.h +++ b/test/libsyncengine/propagation/executor/testexecutorworker.h @@ -19,7 +19,6 @@ #pragma once #include "testincludes.h" -#include "vfs.h" #include "propagation/executor/executorworker.h" #include "test_utility/localtemporarydirectory.h" @@ -33,6 +32,7 @@ class TestExecutorWorker : public CppUnit::TestFixture { CPPUNIT_TEST(testTargetUpdateTree); CPPUNIT_TEST(testLogCorrespondingNodeErrorMsg); CPPUNIT_TEST(testRemoveDependentOps); + CPPUNIT_TEST(testIsValidDestination); CPPUNIT_TEST_SUITE_END(); public: @@ -46,9 +46,11 @@ class TestExecutorWorker : public CppUnit::TestFixture { void testTargetUpdateTree(); void testLogCorrespondingNodeErrorMsg(); void testRemoveDependentOps(); + void testIsValidDestination(); bool opsExist(SyncOpPtr op); - SyncOpPtr generateSyncOperation(const DbNodeId dbNodeId, const SyncName &filename); + SyncOpPtr generateSyncOperation(const DbNodeId dbNodeId, const SyncName &filename, + const OperationType opType = OperationType::None); std::shared_ptr _syncPal; Sync _sync; From 10b346977a098f17184ad4290fa82854f99f517b Mon Sep 17 00:00:00 2001 From: Christophe Larchier Date: Thu, 14 Nov 2024 10:08:37 +0100 Subject: [PATCH 065/178] Fix multiple installations of the connector --- src/server/vfs/mac/vfs_mac.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/server/vfs/mac/vfs_mac.cpp b/src/server/vfs/mac/vfs_mac.cpp index b2b70e581..1e95659eb 100644 --- a/src/server/vfs/mac/vfs_mac.cpp +++ b/src/server/vfs/mac/vfs_mac.cpp @@ -95,10 +95,6 @@ VirtualFileMode VfsMac::mode() const { } bool VfsMac::startImpl(bool &installationDone, bool &activationDone, bool &connectionDone) { - installationDone = false; - activationDone = false; - connectionDone = false; - LOG_DEBUG(logger(), "startImpl - syncDbId=" << _vfsSetupParams._syncDbId); if (!_connector) { @@ -107,6 +103,8 @@ bool VfsMac::startImpl(bool &installationDone, bool &activationDone, bool &conne } if (!installationDone) { + activationDone = false; + connectionDone = false; installationDone = _connector->install(activationDone); if (!installationDone) { LOG_WARN(logger(), "Error in LiteSyncExtConnector::install!"); @@ -116,6 +114,7 @@ bool VfsMac::startImpl(bool &installationDone, bool &activationDone, bool &conne if (!activationDone) { LOG_INFO(logger(), "LiteSync extension activation pending"); + connectionDone = false; return false; } From 30d0bf0c394d66a42085c2b56fbb6a13bc1df9ee Mon Sep 17 00:00:00 2001 From: Christophe Larchier Date: Thu, 14 Nov 2024 10:08:59 +0100 Subject: [PATCH 066/178] Fix paused syncs restart --- src/server/appserver.cpp | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/server/appserver.cpp b/src/server/appserver.cpp index 084dd2c7d..b8f74d690 100644 --- a/src/server/appserver.cpp +++ b/src/server/appserver.cpp @@ -4354,8 +4354,24 @@ void AppServer::onRestartSyncs() { continue; } - // Start sync - syncPalMapElt.second->start(); + // Start SyncPal if not paused + Sync sync; + bool found = false; + if (!ParmsDb::instance()->selectSync(syncPalMapElt.first, sync, found)) { + LOG_WARN(Log::instance()->getLogger(), "Error in ParmsDb::selectSync"); + continue; + } + + if (!found) { + LOG_WARN(Log::instance()->getLogger(), + "Sync not found in sync table for syncDbId=" << syncPalMapElt.first); + continue; + } + + if (!sync.paused()) { + // Start sync + syncPalMapElt.second->start(); + } } } } From 7c089008c216d08a2e301213003134dc545d3f30 Mon Sep 17 00:00:00 2001 From: Christophe Larchier Date: Thu, 14 Nov 2024 10:09:31 +0100 Subject: [PATCH 067/178] Remove unused code --- src/gui/appclient.cpp | 2 -- src/gui/guiutility.cpp | 2 -- 2 files changed, 4 deletions(-) diff --git a/src/gui/appclient.cpp b/src/gui/appclient.cpp index 28dd72f9f..b0532cbb9 100644 --- a/src/gui/appclient.cpp +++ b/src/gui/appclient.cpp @@ -48,8 +48,6 @@ #include #include -#define LITE_SYNC_EXT_BUNDLE_ID "com.infomaniak.drive.desktopclient.LiteSyncExt" - #define CONNECTION_TRIALS 3 #define CHECKCOMMSTATUS_TRIALS 5 diff --git a/src/gui/guiutility.cpp b/src/gui/guiutility.cpp index f54917aef..d957adff2 100644 --- a/src/gui/guiutility.cpp +++ b/src/gui/guiutility.cpp @@ -49,8 +49,6 @@ #include #endif -#define LITE_SYNC_EXT_BUNDLE_ID "com.infomaniak.drive.desktopclient.LiteSyncExt" - namespace KDC { static const QString styleSheetWhiteFile(":/client/resources/styles/stylesheetwhite.qss"); From 71317f781cf458dad73ccd63f1174bf55376cced Mon Sep 17 00:00:00 2001 From: Christophe Larchier Date: Thu, 14 Nov 2024 11:08:52 +0100 Subject: [PATCH 068/178] New test added --- src/libcommon/utility/utility.cpp | 18 +++++-- src/libcommon/utility/utility.h | 2 + src/server/socketapisocket_mac.mm | 53 ++++++++++++-------- src/server/vfs/mac/litesyncextconnector.mm | 19 +++++--- test/server/workers/testworkers.cpp | 57 ++++++++++++++++++---- test/server/workers/testworkers.h | 7 +++ 6 files changed, 115 insertions(+), 41 deletions(-) diff --git a/src/libcommon/utility/utility.cpp b/src/libcommon/utility/utility.cpp index f405d984e..0fff9f9d8 100644 --- a/src/libcommon/utility/utility.cpp +++ b/src/libcommon/utility/utility.cpp @@ -66,7 +66,8 @@ #define MAX_PATH_LENGTH_MAC 1023 #define MAX_PATH_LENGTH_LINUX 4096 -#define LITE_SYNC_EXT_BUNDLE_ID "com.infomaniak.drive.desktopclient.LiteSyncExt" +constexpr char liteSyncExtBundleIdStr[] = "com.infomaniak.drive.desktopclient.LiteSyncExt"; +constexpr char loginItemAgentIdStr[] = "864VDCS2QY.com.infomaniak.drive.desktopclient.LoginItemAgent"; namespace KDC { const int CommonUtility::logsPurgeRate = 7; // days @@ -782,6 +783,14 @@ bool CommonUtility::fileNameIsValid(const SyncName &name) { return true; } +const std::string CommonUtility::loginItemAgentId() { + return loginItemAgentIdStr; +} + +const std::string CommonUtility::liteSyncExtBundleId() { + return liteSyncExtBundleIdStr; +} + std::string CommonUtility::envVarValue(const std::string &name) { bool isSet = false; return envVarValue(name, isSet); @@ -873,7 +882,7 @@ bool CommonUtility::isLiteSyncExtEnabled() { process->start( "bash", QStringList() << "-c" - << QString("systemextensionsctl list | grep %1 | grep enabled | wc -l").arg(LITE_SYNC_EXT_BUNDLE_ID)); + << QString("systemextensionsctl list | grep %1 | grep enabled | wc -l").arg(liteSyncExtBundleIdStr)); process->waitForStarted(); process->waitForFinished(); QByteArray result = process->readAll(); @@ -894,14 +903,14 @@ bool CommonUtility::isLiteSyncExtFullDiskAccessAuthOk(std::string &errorDescr) { " and client = \"%2\"" " and client_type = 0") .arg(serviceStr) - .arg(LITE_SYNC_EXT_BUNDLE_ID)); + .arg(liteSyncExtBundleIdStr)); } else { query.prepare(QString("SELECT auth_value FROM access" " WHERE service = \"%1\"" " and client = \"%2\"" " and client_type = 0") .arg(serviceStr) - .arg(LITE_SYNC_EXT_BUNDLE_ID)); + .arg(liteSyncExtBundleIdStr)); } query.exec(); @@ -930,5 +939,6 @@ bool CommonUtility::isLiteSyncExtFullDiskAccessAuthOk(std::string &errorDescr) { return false; } + #endif } // namespace KDC diff --git a/src/libcommon/utility/utility.h b/src/libcommon/utility/utility.h index 39dc1501a..e91c247b0 100644 --- a/src/libcommon/utility/utility.h +++ b/src/libcommon/utility/utility.h @@ -105,6 +105,8 @@ struct COMMON_EXPORT CommonUtility { static bool fileNameIsValid(const SyncName &name); #ifdef Q_OS_MAC + static const std::string loginItemAgentId(); + static const std::string liteSyncExtBundleId(); static bool isLiteSyncExtEnabled(); static bool isLiteSyncExtFullDiskAccessAuthOk(std::string &errorDescr); #endif diff --git a/src/server/socketapisocket_mac.mm b/src/server/socketapisocket_mac.mm index a64388bd4..1676dc101 100644 --- a/src/server/socketapisocket_mac.mm +++ b/src/server/socketapisocket_mac.mm @@ -22,6 +22,9 @@ #include "../extensions/MacOSX/kDriveFinderSync/Extension/xpcExtensionProtocol.h" #include "../extensions/MacOSX/kDriveFinderSync/LoginItemAgent/xpcLoginItemProtocol.h" +#include "libcommon/utility/utility.h" + +#include @interface LocalEnd : NSObject @@ -174,28 +177,36 @@ - (void)connectToLoginAgent { // Setup our connection to the launch item's service // This will start the launch item if it isn't already running NSLog(@"[KD] Setup connection with login item agent"); - NSBundle *appBundle = [NSBundle bundleForClass:[self class]]; - NSString *loginItemAgentMachName = [appBundle objectForInfoDictionaryKey:@"LoginItemAgentMachName"]; - if (!loginItemAgentMachName) { - NSLog(@"[KD] LoginItemAgentMachName undefined"); - return; - } - - NSError *error = nil; - _loginItemAgentConnection = [[NSXPCConnection alloc] initWithLoginItemName:loginItemAgentMachName error:&error]; - if (_loginItemAgentConnection == nil) { - NSLog(@"[KD] Failed to connect to login item agent: %@", [error description]); - return; - } - - /* - // To debug with an existing login item agent - _loginItemAgentConnection = [[NSXPCConnection alloc] initWithMachServiceName:loginItemAgentMachName options:0]; - if (_loginItemAgentConnection == nil) { - NSLog(@"[KD] Failed to connect to login item agent"); - return; + NSString *loginItemAgentMachName; + if (qApp) { + NSBundle *appBundle = [NSBundle bundleForClass:[self class]]; + loginItemAgentMachName = [appBundle objectForInfoDictionaryKey:@"LoginItemAgentMachName"]; + if (!loginItemAgentMachName) { + NSLog(@"[KD] LoginItemAgentMachName undefined"); + return; + } + + NSError *error = nil; + _loginItemAgentConnection = [[NSXPCConnection alloc] + initWithLoginItemName:loginItemAgentMachName + error:&error]; + if (_loginItemAgentConnection == nil) { + NSLog(@"[KD] Failed to connect to login item agent: %@", [error description]); + return; + } + } else { + // For testing + loginItemAgentMachName = [NSString + stringWithUTF8String:KDC::CommonUtility::loginItemAgentId().c_str()]; + + _loginItemAgentConnection = [[NSXPCConnection alloc] + initWithMachServiceName:loginItemAgentMachName + options:0]; + if (_loginItemAgentConnection == nil) { + NSLog(@"[KD] Failed to connect to login item agent"); + return; + } } - */ // Set exported interface NSLog(@"[KD] Set exported interface for connection with ext"); diff --git a/src/server/vfs/mac/litesyncextconnector.mm b/src/server/vfs/mac/litesyncextconnector.mm index d8ab01eb4..d8cae121d 100644 --- a/src/server/vfs/mac/litesyncextconnector.mm +++ b/src/server/vfs/mac/litesyncextconnector.mm @@ -217,12 +217,19 @@ - (BOOL)connectToExt { // Setup connection with LiteSync extension NSLog(@"[KD] Setup connection with LiteSync extension"); - // Read LiteSyncExtMachName from plist - NSBundle *appBundle = [NSBundle mainBundle]; - NSString *liteSyncExtMachName = [appBundle objectForInfoDictionaryKey:@"LiteSyncExtMachName"]; - if (!liteSyncExtMachName) { - NSLog(@"[KD] LiteSyncExtMachName undefined"); - return FALSE; + NSString *liteSyncExtMachName; + if (qApp) { + // Read LiteSyncExtMachName from plist + NSBundle *appBundle = [NSBundle mainBundle]; + liteSyncExtMachName = [appBundle objectForInfoDictionaryKey:@"LiteSyncExtMachName"]; + if (!liteSyncExtMachName) { + NSLog(@"[KD] LiteSyncExtMachName undefined"); + return FALSE; + } + } else { + // For testing + liteSyncExtMachName = [NSString + stringWithUTF8String:KDC::CommonUtility::liteSyncExtBundleId().c_str()]; } _connection = [[NSXPCConnection alloc] initWithMachServiceName:liteSyncExtMachName options:0]; diff --git a/test/server/workers/testworkers.cpp b/test/server/workers/testworkers.cpp index a918e0787..686b1bc9b 100644 --- a/test/server/workers/testworkers.cpp +++ b/test/server/workers/testworkers.cpp @@ -38,6 +38,16 @@ std::shared_ptr TestWorkers::_vfsPtr = nullptr; std::shared_ptr TestWorkers::_vfsPtr = nullptr; #endif +bool TestWorkers::_vfsInstallationDone = false; +bool TestWorkers::_vfsActivationDone = false; +bool TestWorkers::_vfsConnectionDone = false; + +#ifdef __APPLE__ +// TODO: On macOS, SIP should be deactivated and LiteSync extension signed to be able to install the Lite Sync extension. +// Set to true if the Login Item Agent and the Lite Sync extensions are already installed on the test machine. +constexpr bool connectorsAreAlreadyInstalled = true; +#endif + bool TestWorkers::createPlaceholder(int syncDbId, const SyncPath &relativeLocalPath, const SyncFileItem &item) { (void) syncDbId; @@ -124,6 +134,7 @@ void TestWorkers::setUp() { vfsSetupParams._localPath = _sync.localPath(); vfsSetupParams._targetPath = _sync.targetPath(); vfsSetupParams._logger = _logger; + vfsSetupParams._executeCommand = [](const char *) {}; #if defined(__APPLE__) _vfsPtr = std::shared_ptr(new VfsMac(vfsSetupParams)); @@ -133,6 +144,10 @@ void TestWorkers::setUp() { _vfsPtr = std::shared_ptr(new VfsOff(vfsSetupParams)); #endif +#if defined(__APPLE__) + _vfsPtr->setExclusionAppListCallback([](QString &) {}); +#endif + // Setup SyncPal _syncPal = std::make_shared(_sync.dbId(), KDRIVE_VERSION_STRING); _syncPal->createWorkers(); @@ -154,17 +169,15 @@ void TestWorkers::setUp() { CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED); #endif -#if !defined(__APPLE__) - // TODO: on macOS, SIP should be deactivated and LiteSync extension signed to be able to start Vfs - // Start Vfs - bool installationDone = false; - bool activationDone = false; - bool connectionDone = false; - CPPUNIT_ASSERT(_vfsPtr->startImpl(installationDone, activationDone, connectionDone)); - CPPUNIT_ASSERT(installationDone); - CPPUNIT_ASSERT(activationDone); - CPPUNIT_ASSERT(connectionDone); +#ifdef __APPLE__ + if (connectorsAreAlreadyInstalled) { + _vfsInstallationDone = true; + _vfsActivationDone = true; + startVfs(); + } +#else + startVfs(); #endif } @@ -181,6 +194,25 @@ void TestWorkers::tearDown() { } } +void TestWorkers::testStartVfs() { +#ifdef __APPLE__ + if (!connectorsAreAlreadyInstalled) { + return; + } +#endif + + // Make sure that Vfs is installed/activated/connected + CPPUNIT_ASSERT(_vfsInstallationDone); + CPPUNIT_ASSERT(_vfsActivationDone); + CPPUNIT_ASSERT(_vfsConnectionDone); + + // Try to start Vfs another time + CPPUNIT_ASSERT(startVfs()); + CPPUNIT_ASSERT(_vfsInstallationDone); + CPPUNIT_ASSERT(_vfsActivationDone); + CPPUNIT_ASSERT(_vfsConnectionDone); +} + void TestWorkers::testCreatePlaceholder() { _syncPal->resetEstimateUpdates(); ExitInfo exitInfo; @@ -348,4 +380,9 @@ void TestWorkers::testConvertToPlaceholder() { CPPUNIT_ASSERT_EQUAL(ExitCause::Unknown, exitInfo.cause()); } } + +bool TestWorkers::startVfs() { + return _vfsPtr->startImpl(_vfsInstallationDone, _vfsActivationDone, _vfsConnectionDone); +} + } // namespace KDC diff --git a/test/server/workers/testworkers.h b/test/server/workers/testworkers.h index da895768f..7ae4d3c8f 100644 --- a/test/server/workers/testworkers.h +++ b/test/server/workers/testworkers.h @@ -34,6 +34,7 @@ namespace KDC { class TestWorkers : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(TestWorkers); + CPPUNIT_TEST(testStartVfs); CPPUNIT_TEST(testCreatePlaceholder); CPPUNIT_TEST(testConvertToPlaceholder); CPPUNIT_TEST_SUITE_END(); @@ -41,10 +42,12 @@ class TestWorkers : public CppUnit::TestFixture { public: void setUp(void) final; void tearDown() override; + void testStartVfs(); void testCreatePlaceholder(); void testConvertToPlaceholder(); protected: + static bool startVfs(); static bool createPlaceholder(int syncDbId, const SyncPath &relativeLocalPath, const SyncFileItem &item); static bool convertToPlaceholder(int syncDbId, const SyncPath &relativeLocalPath, const SyncFileItem &item); static bool setPinState(int syncDbId, const SyncPath &relativeLocalPath, PinState pinState); @@ -63,6 +66,10 @@ class TestWorkers : public CppUnit::TestFixture { #else static std::shared_ptr _vfsPtr; #endif + + static bool _vfsInstallationDone; + static bool _vfsActivationDone; + static bool _vfsConnectionDone; }; } // namespace KDC From 54c09e5e12ac255f2eed5c5f16766c5517ef8db9 Mon Sep 17 00:00:00 2001 From: Christophe Larchier Date: Thu, 14 Nov 2024 11:25:47 +0100 Subject: [PATCH 069/178] Fix build --- src/libcommon/utility/utility.cpp | 4 ++++ src/libcommon/utility/utility.h | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/libcommon/utility/utility.cpp b/src/libcommon/utility/utility.cpp index 0fff9f9d8..d6d0fee3a 100644 --- a/src/libcommon/utility/utility.cpp +++ b/src/libcommon/utility/utility.cpp @@ -66,8 +66,10 @@ #define MAX_PATH_LENGTH_MAC 1023 #define MAX_PATH_LENGTH_LINUX 4096 +#ifdef __APPLE__ constexpr char liteSyncExtBundleIdStr[] = "com.infomaniak.drive.desktopclient.LiteSyncExt"; constexpr char loginItemAgentIdStr[] = "864VDCS2QY.com.infomaniak.drive.desktopclient.LoginItemAgent"; +#endif namespace KDC { const int CommonUtility::logsPurgeRate = 7; // days @@ -783,6 +785,7 @@ bool CommonUtility::fileNameIsValid(const SyncName &name) { return true; } +#ifdef __APPLE__ const std::string CommonUtility::loginItemAgentId() { return loginItemAgentIdStr; } @@ -790,6 +793,7 @@ const std::string CommonUtility::loginItemAgentId() { const std::string CommonUtility::liteSyncExtBundleId() { return liteSyncExtBundleIdStr; } +#endif std::string CommonUtility::envVarValue(const std::string &name) { bool isSet = false; diff --git a/src/libcommon/utility/utility.h b/src/libcommon/utility/utility.h index e91c247b0..e2768cb57 100644 --- a/src/libcommon/utility/utility.h +++ b/src/libcommon/utility/utility.h @@ -104,7 +104,7 @@ struct COMMON_EXPORT CommonUtility { static bool dirNameIsValid(const SyncName &name); static bool fileNameIsValid(const SyncName &name); -#ifdef Q_OS_MAC +#ifdef __APPLE__ static const std::string loginItemAgentId(); static const std::string liteSyncExtBundleId(); static bool isLiteSyncExtEnabled(); From b60786c833bb91cbbcaaa88c2f148ebcf79c9d76 Mon Sep 17 00:00:00 2001 From: Christophe Larchier Date: Thu, 14 Nov 2024 11:39:13 +0100 Subject: [PATCH 070/178] Fix test --- test/server/workers/testworkers.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/server/workers/testworkers.cpp b/test/server/workers/testworkers.cpp index 686b1bc9b..8201db314 100644 --- a/test/server/workers/testworkers.cpp +++ b/test/server/workers/testworkers.cpp @@ -45,7 +45,7 @@ bool TestWorkers::_vfsConnectionDone = false; #ifdef __APPLE__ // TODO: On macOS, SIP should be deactivated and LiteSync extension signed to be able to install the Lite Sync extension. // Set to true if the Login Item Agent and the Lite Sync extensions are already installed on the test machine. -constexpr bool connectorsAreAlreadyInstalled = true; +constexpr bool connectorsAreAlreadyInstalled = false; #endif bool TestWorkers::createPlaceholder(int syncDbId, const SyncPath &relativeLocalPath, const SyncFileItem &item) { From 0e8b7f98bb40265d49a4fffe47623e1de65c1200 Mon Sep 17 00:00:00 2001 From: Christophe Larchier Date: Thu, 14 Nov 2024 14:58:11 +0100 Subject: [PATCH 071/178] Fix Windows test --- src/libcommonserver/vfs.cpp | 5 +---- src/server/vfs/win/vfs_win.cpp | 10 +--------- test/server/workers/testworkers.cpp | 30 +++++++++++++++-------------- 3 files changed, 18 insertions(+), 27 deletions(-) diff --git a/src/libcommonserver/vfs.cpp b/src/libcommonserver/vfs.cpp index 940d10a1a..3027c1d6c 100644 --- a/src/libcommonserver/vfs.cpp +++ b/src/libcommonserver/vfs.cpp @@ -109,10 +109,7 @@ bool VfsOff::forceStatus(const QString &path, bool isSyncing, int /*progress*/, return true; } -bool VfsOff::startImpl(bool &installationDone, bool &activationDone, bool &connectionDone) { - installationDone = true; - activationDone = true; - connectionDone = true; +bool VfsOff::startImpl(bool &, bool &, bool &) { return true; } diff --git a/src/server/vfs/win/vfs_win.cpp b/src/server/vfs/win/vfs_win.cpp index 0a6d49553..259aada4b 100644 --- a/src/server/vfs/win/vfs_win.cpp +++ b/src/server/vfs/win/vfs_win.cpp @@ -122,11 +122,7 @@ VirtualFileMode VfsWin::mode() const { return VirtualFileMode::Win; } -bool VfsWin::startImpl(bool &installationDone, bool &activationDone, bool &connectionDone) { - installationDone = false; - activationDone = false; - connectionDone = false; - +bool VfsWin::startImpl(bool &, bool &, bool &) { LOG_DEBUG(logger(), "startImpl: syncDbId=" << _vfsSetupParams._syncDbId); wchar_t clsid[39] = L""; @@ -140,10 +136,6 @@ bool VfsWin::startImpl(bool &installationDone, bool &activationDone, bool &conne _vfsSetupParams._namespaceCLSID = Utility::ws2s(std::wstring(clsid)); - installationDone = true; - activationDone = true; - connectionDone = true; - return true; } diff --git a/test/server/workers/testworkers.cpp b/test/server/workers/testworkers.cpp index 8201db314..af6ac1aef 100644 --- a/test/server/workers/testworkers.cpp +++ b/test/server/workers/testworkers.cpp @@ -195,22 +195,24 @@ void TestWorkers::tearDown() { } void TestWorkers::testStartVfs() { -#ifdef __APPLE__ - if (!connectorsAreAlreadyInstalled) { - return; +#if defined(__APPLE__) + if (connectorsAreAlreadyInstalled) { + // Make sure that Vfs is installed/activated/connected + CPPUNIT_ASSERT(_vfsInstallationDone); + CPPUNIT_ASSERT(_vfsActivationDone); + CPPUNIT_ASSERT(_vfsConnectionDone); + + // Try to start Vfs another time + CPPUNIT_ASSERT(startVfs()); + CPPUNIT_ASSERT(_vfsInstallationDone); + CPPUNIT_ASSERT(_vfsActivationDone); + CPPUNIT_ASSERT(_vfsConnectionDone); } -#endif - - // Make sure that Vfs is installed/activated/connected - CPPUNIT_ASSERT(_vfsInstallationDone); - CPPUNIT_ASSERT(_vfsActivationDone); - CPPUNIT_ASSERT(_vfsConnectionDone); - +#elif defined(_WIN32) // Try to start Vfs another time - CPPUNIT_ASSERT(startVfs()); - CPPUNIT_ASSERT(_vfsInstallationDone); - CPPUNIT_ASSERT(_vfsActivationDone); - CPPUNIT_ASSERT(_vfsConnectionDone); + // => WinRT error caught : hr 8007017a - The cloud sync root is already connected with another cloud sync provider. + CPPUNIT_ASSERT(!startVfs()); +#endif } void TestWorkers::testCreatePlaceholder() { From debda74601cfc6502952092ed2a1193957d952a9 Mon Sep 17 00:00:00 2001 From: Christophe Larchier Date: Fri, 15 Nov 2024 10:20:17 +0100 Subject: [PATCH 072/178] Address comments --- src/server/socketapisocket_mac.mm | 2 +- src/server/vfs/mac/litesyncextconnector.mm | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/server/socketapisocket_mac.mm b/src/server/socketapisocket_mac.mm index 1676dc101..62b1e12ce 100644 --- a/src/server/socketapisocket_mac.mm +++ b/src/server/socketapisocket_mac.mm @@ -177,7 +177,7 @@ - (void)connectToLoginAgent { // Setup our connection to the launch item's service // This will start the launch item if it isn't already running NSLog(@"[KD] Setup connection with login item agent"); - NSString *loginItemAgentMachName; + NSString *loginItemAgentMachName = nil; if (qApp) { NSBundle *appBundle = [NSBundle bundleForClass:[self class]]; loginItemAgentMachName = [appBundle objectForInfoDictionaryKey:@"LoginItemAgentMachName"]; diff --git a/src/server/vfs/mac/litesyncextconnector.mm b/src/server/vfs/mac/litesyncextconnector.mm index d8cae121d..717529d6c 100644 --- a/src/server/vfs/mac/litesyncextconnector.mm +++ b/src/server/vfs/mac/litesyncextconnector.mm @@ -217,7 +217,7 @@ - (BOOL)connectToExt { // Setup connection with LiteSync extension NSLog(@"[KD] Setup connection with LiteSync extension"); - NSString *liteSyncExtMachName; + NSString *liteSyncExtMachName = nil; if (qApp) { // Read LiteSyncExtMachName from plist NSBundle *appBundle = [NSBundle mainBundle]; From d22069bf0d4036fc61e5a9a18f9f68de126f22e9 Mon Sep 17 00:00:00 2001 From: Christophe Larchier Date: Fri, 15 Nov 2024 15:42:07 +0100 Subject: [PATCH 073/178] Remove unused code --- src/common/utility.cpp | 1 - src/gui/confirmsynchronizationdialog.cpp | 1 - src/gui/foldertreeitemwidget.h | 1 - 3 files changed, 3 deletions(-) diff --git a/src/common/utility.cpp b/src/common/utility.cpp index 0885f4d2c..3b8566444 100644 --- a/src/common/utility.cpp +++ b/src/common/utility.cpp @@ -30,7 +30,6 @@ #include #include #include -#include #include #include #include diff --git a/src/gui/confirmsynchronizationdialog.cpp b/src/gui/confirmsynchronizationdialog.cpp index 0f18adf63..49f34024f 100644 --- a/src/gui/confirmsynchronizationdialog.cpp +++ b/src/gui/confirmsynchronizationdialog.cpp @@ -26,7 +26,6 @@ #include #include -#include #include namespace KDC { diff --git a/src/gui/foldertreeitemwidget.h b/src/gui/foldertreeitemwidget.h index 52369eb4a..e51662acd 100644 --- a/src/gui/foldertreeitemwidget.h +++ b/src/gui/foldertreeitemwidget.h @@ -26,7 +26,6 @@ #include #include #include -#include namespace KDC { From 36646bdebfae312b9ba098c77207f51fbe047441 Mon Sep 17 00:00:00 2001 From: Christophe Larchier Date: Fri, 15 Nov 2024 15:44:43 +0100 Subject: [PATCH 074/178] Activate ARC on .mm sources --- src/libcommon/CMakeLists.txt | 1 + src/libcommonserver/CMakeLists.txt | 3 +++ 2 files changed, 4 insertions(+) diff --git a/src/libcommon/CMakeLists.txt b/src/libcommon/CMakeLists.txt index 7225d27b3..b34462f1b 100644 --- a/src/libcommon/CMakeLists.txt +++ b/src/libcommon/CMakeLists.txt @@ -45,6 +45,7 @@ set(libcommon_SRCS if(APPLE) list(APPEND libcommon_SRCS utility/utility_mac.mm) + set_property(SOURCE utility/utility_mac.mm APPEND_STRING PROPERTY COMPILE_FLAGS "-fobjc-arc") endif() # Target diff --git a/src/libcommonserver/CMakeLists.txt b/src/libcommonserver/CMakeLists.txt index cf16ab3aa..b9db404e9 100644 --- a/src/libcommonserver/CMakeLists.txt +++ b/src/libcommonserver/CMakeLists.txt @@ -39,7 +39,10 @@ set(libcommonserver_SRCS if(APPLE) list(APPEND libcommonserver_SRCS io/iohelper_mac.mm io/iohelper_mac.cpp) + set_property(SOURCE io/iohelper_mac.mm APPEND_STRING PROPERTY COMPILE_FLAGS "-fobjc-arc") + list(APPEND libcommonserver_SRCS utility/utility_mac.mm) + set_property(SOURCE utility/utility_mac.mm APPEND_STRING PROPERTY COMPILE_FLAGS "-fobjc-arc") elseif(WIN32) list(APPEND libcommonserver_SRCS io/iohelper_win.h io/iohelper_win.cpp) else() From 98d2c7e04fb48ff3eb710427e0bb7a4f6727b3bb Mon Sep 17 00:00:00 2001 From: Christophe Larchier Date: Fri, 15 Nov 2024 15:46:39 +0100 Subject: [PATCH 075/178] Cleanup log4cplus memory at the end of all functions running in a thread --- src/libcommonserver/utility/utility.cpp | 5 +++++ src/libcommonserver/utility/utility.h | 2 ++ src/libsyncengine/jobs/jobmanager.cpp | 3 ++- .../performance_watcher/performancewatcher.cpp | 2 ++ .../propagation/executor/executorworker.cpp | 2 +- .../operation_sorter/operationsorterworker.cpp | 2 +- .../conflict_finder/conflictfinderworker.cpp | 3 +-- .../conflict_resolver/conflictresolverworker.cpp | 2 +- .../operationgeneratorworker.cpp | 2 +- .../platforminconsistencycheckerworker.cpp | 2 +- src/libsyncengine/requests/serverrequests.cpp | 16 ++++++++-------- src/libsyncengine/requests/serverrequests.h | 2 +- src/libsyncengine/syncpal/isyncworker.cpp | 2 ++ src/libsyncengine/syncpal/syncpalworker.cpp | 2 +- .../checksum/contentchecksumworker.cpp | 2 +- .../computefsoperationworker.cpp | 4 ++-- .../file_system_observer/folderwatcher_linux.cpp | 7 +++++-- .../file_system_observer/folderwatcher_mac.cpp | 3 +++ .../file_system_observer/folderwatcher_win.cpp | 1 + .../localfilesystemobserverworker.cpp | 2 +- .../remotefilesystemobserverworker.cpp | 2 +- .../update_detector/updatetreeworker.cpp | 2 +- src/server/appserver.cpp | 5 +++-- src/server/appserver.h | 3 +-- src/server/vfs/mac/vfs_mac.cpp | 1 + 25 files changed, 49 insertions(+), 30 deletions(-) diff --git a/src/libcommonserver/utility/utility.cpp b/src/libcommonserver/utility/utility.cpp index 98ffda46a..4f3040a59 100644 --- a/src/libcommonserver/utility/utility.cpp +++ b/src/libcommonserver/utility/utility.cpp @@ -913,4 +913,9 @@ std::string Utility::userName() { return userName_private(); } +ExitInfo Utility::terminateThreadFunction(ExitInfo exitInfo) { + log4cplus::threadCleanup(); + return exitInfo; +} + } // namespace KDC diff --git a/src/libcommonserver/utility/utility.h b/src/libcommonserver/utility/utility.h index 0c4735661..e018f1634 100644 --- a/src/libcommonserver/utility/utility.h +++ b/src/libcommonserver/utility/utility.h @@ -184,6 +184,8 @@ struct COMMONSERVER_EXPORT Utility { static SyncPath sharedFolderName(); static std::string userName(); + static ExitInfo terminateThreadFunction(ExitInfo exitInfo = ExitInfo()); + private: static log4cplus::Logger _logger; diff --git a/src/libsyncengine/jobs/jobmanager.cpp b/src/libsyncengine/jobs/jobmanager.cpp index 1340fe99e..02c690b72 100644 --- a/src/libsyncengine/jobs/jobmanager.cpp +++ b/src/libsyncengine/jobs/jobmanager.cpp @@ -25,7 +25,6 @@ #include "performance_watcher/performancewatcher.h" #include "requests/parameterscache.h" -#include #include // std::max #include @@ -197,6 +196,8 @@ void JobManager::run() noexcept { Utility::msleep(100); // Sleep for 0.1s } + + Utility::terminateThreadFunction(); } void JobManager::startJob(std::pair, Poco::Thread::Priority> nextJob) { diff --git a/src/libsyncengine/performance_watcher/performancewatcher.cpp b/src/libsyncengine/performance_watcher/performancewatcher.cpp index dffddb808..cffdd1fe8 100644 --- a/src/libsyncengine/performance_watcher/performancewatcher.cpp +++ b/src/libsyncengine/performance_watcher/performancewatcher.cpp @@ -85,6 +85,8 @@ void PerformanceWatcher::run() { Utility::msleep(1000); // Sleep for 1s } + + Utility::terminateThreadFunction(); } bool PerformanceWatcher::updateCpuUsage() { diff --git a/src/libsyncengine/propagation/executor/executorworker.cpp b/src/libsyncengine/propagation/executor/executorworker.cpp index 4f0c67d06..dba68d50f 100644 --- a/src/libsyncengine/propagation/executor/executorworker.cpp +++ b/src/libsyncengine/propagation/executor/executorworker.cpp @@ -219,8 +219,8 @@ void ExecutorWorker::execute() { _syncPal->vfsCleanUpStatuses(); setExitCause(executorExitInfo.cause()); - setDone(executorExitInfo.code()); LOG_SYNCPAL_DEBUG(_logger, "Worker stopped: name=" << name().c_str()); + setDone(executorExitInfo.code()); } void ExecutorWorker::initProgressManager() { diff --git a/src/libsyncengine/propagation/operation_sorter/operationsorterworker.cpp b/src/libsyncengine/propagation/operation_sorter/operationsorterworker.cpp index 227eb8e5d..919fcdc5e 100644 --- a/src/libsyncengine/propagation/operation_sorter/operationsorterworker.cpp +++ b/src/libsyncengine/propagation/operation_sorter/operationsorterworker.cpp @@ -41,8 +41,8 @@ void OperationSorterWorker::execute() { std::chrono::duration elapsed_seconds = std::chrono::steady_clock::now() - start; LOG_SYNCPAL_INFO(_logger, "Operation sorting finished in: " << elapsed_seconds.count() << "s"); - setDone(exitCode); LOG_SYNCPAL_DEBUG(_logger, "Worker stopped: name=" << name().c_str()); + setDone(exitCode); } ExitCode OperationSorterWorker::sortOperations() { diff --git a/src/libsyncengine/reconciliation/conflict_finder/conflictfinderworker.cpp b/src/libsyncengine/reconciliation/conflict_finder/conflictfinderworker.cpp index 4b5a83b20..bb93ba6e9 100644 --- a/src/libsyncengine/reconciliation/conflict_finder/conflictfinderworker.cpp +++ b/src/libsyncengine/reconciliation/conflict_finder/conflictfinderworker.cpp @@ -33,9 +33,8 @@ void ConflictFinderWorker::execute() { findConflicts(); exitCode = ExitCode::Ok; - setDone(exitCode); LOG_SYNCPAL_DEBUG(_logger, "Worker stopped: name=" << name().c_str()); - return; + setDone(exitCode); } void ConflictFinderWorker::findConflicts() { diff --git a/src/libsyncengine/reconciliation/conflict_resolver/conflictresolverworker.cpp b/src/libsyncengine/reconciliation/conflict_resolver/conflictresolverworker.cpp index aba184557..f0f1158d2 100644 --- a/src/libsyncengine/reconciliation/conflict_resolver/conflictresolverworker.cpp +++ b/src/libsyncengine/reconciliation/conflict_resolver/conflictresolverworker.cpp @@ -50,8 +50,8 @@ void ConflictResolverWorker::execute() { // The sync must be restarted after the execution of the operations that resolve the conflict _syncPal->setRestart(true); - setDone(exitCode); LOG_SYNCPAL_DEBUG(_logger, "Worker stopped: name=" << name().c_str()); + setDone(exitCode); } ExitCode ConflictResolverWorker::generateOperations(const Conflict &conflict, bool &continueSolving) { diff --git a/src/libsyncengine/reconciliation/operation_generator/operationgeneratorworker.cpp b/src/libsyncengine/reconciliation/operation_generator/operationgeneratorworker.cpp index b87c212c4..5f5371ee7 100644 --- a/src/libsyncengine/reconciliation/operation_generator/operationgeneratorworker.cpp +++ b/src/libsyncengine/reconciliation/operation_generator/operationgeneratorworker.cpp @@ -129,8 +129,8 @@ void OperationGeneratorWorker::execute() { } } - setDone(exitCode); LOG_SYNCPAL_DEBUG(_logger, "Worker stopped: name=" << name().c_str()); + setDone(exitCode); } void OperationGeneratorWorker::generateCreateOperation(std::shared_ptr currentNode, diff --git a/src/libsyncengine/reconciliation/platform_inconsistency_checker/platforminconsistencycheckerworker.cpp b/src/libsyncengine/reconciliation/platform_inconsistency_checker/platforminconsistencycheckerworker.cpp index 1784a70c0..1c2687701 100644 --- a/src/libsyncengine/reconciliation/platform_inconsistency_checker/platforminconsistencycheckerworker.cpp +++ b/src/libsyncengine/reconciliation/platform_inconsistency_checker/platforminconsistencycheckerworker.cpp @@ -53,8 +53,8 @@ void PlatformInconsistencyCheckerWorker::execute() { _syncPal->updateTree(ReplicaSide::Remote)->setInconsistencyCheckDone(); - setDone(ExitCode::Ok); LOG_SYNCPAL_DEBUG(_logger, "Worker stopped: name=" << name().c_str()); + setDone(ExitCode::Ok); } ExitCode PlatformInconsistencyCheckerWorker::checkTree(ReplicaSide side) { diff --git a/src/libsyncengine/requests/serverrequests.cpp b/src/libsyncengine/requests/serverrequests.cpp index 137365795..7d80acc76 100644 --- a/src/libsyncengine/requests/serverrequests.cpp +++ b/src/libsyncengine/requests/serverrequests.cpp @@ -1115,11 +1115,11 @@ ExitCode ServerRequests::getPublicLinkUrl(int driveDbId, const QString &fileId, return ExitCode::Ok; } -ExitCode ServerRequests::getFolderSize(int userDbId, int driveId, const NodeId &nodeId, +ExitInfo ServerRequests::getFolderSize(int userDbId, int driveId, const NodeId &nodeId, std::function callback) { if (nodeId.empty()) { LOG_WARN(Log::instance()->getLogger(), "Node ID is empty"); - return ExitCode::DataError; + return Utility::terminateThreadFunction(ExitCode::DataError); } // get size of folder @@ -1130,7 +1130,7 @@ ExitCode ServerRequests::getFolderSize(int userDbId, int driveId, const NodeId & LOG_WARN(Log::instance()->getLogger(), "Error in GetSizeJob::GetSizeJob for userDbId=" << userDbId << " driveId=" << driveId << " nodeId=" << nodeId.c_str() << " error=" << e.what()); - return ExitCode::DataError; + return Utility::terminateThreadFunction(ExitCode::DataError); } ExitCode exitCode = job->runSynchronously(); @@ -1138,7 +1138,7 @@ ExitCode ServerRequests::getFolderSize(int userDbId, int driveId, const NodeId & LOG_WARN(Log::instance()->getLogger(), "Error in GetSizeJob::runSynchronously for userDbId=" << userDbId << " driveId=" << driveId << " nodeId=" << nodeId.c_str() << " code=" << exitCode); - return exitCode; + return Utility::terminateThreadFunction(exitCode); } Poco::JSON::Object::Ptr resObj = job->jsonRes(); @@ -1146,24 +1146,24 @@ ExitCode ServerRequests::getFolderSize(int userDbId, int driveId, const NodeId & // Level = Debug because access forbidden is a normal case LOG_DEBUG(Log::instance()->getLogger(), "GetSizeJob failed for userDbId=" << userDbId << " driveId=" << driveId << " nodeId=" << nodeId.c_str()); - return ExitCode::BackError; + return Utility::terminateThreadFunction(ExitCode::BackError); } Poco::JSON::Object::Ptr dataObj = resObj->getObject(dataKey); if (!dataObj) { LOG_WARN(Log::instance()->getLogger(), "GetSizeJob failed for userDbId=" << userDbId << " driveId=" << driveId << " nodeId=" << nodeId.c_str()); - return ExitCode::BackError; + return Utility::terminateThreadFunction(ExitCode::BackError); } qint64 size = 0; if (!JsonParserUtility::extractValue(dataObj, sizeKey, size)) { - return ExitCode::BackError; + return Utility::terminateThreadFunction(ExitCode::BackError); } callback(QString::fromStdString(nodeId), size); - return ExitCode::Ok; + return Utility::terminateThreadFunction(ExitCode::Ok); } ExitCode ServerRequests::getPrivateLinkUrl(int driveDbId, const QString &fileId, QString &linkUrl) { diff --git a/src/libsyncengine/requests/serverrequests.h b/src/libsyncengine/requests/serverrequests.h index f6c03d105..a338eddfb 100644 --- a/src/libsyncengine/requests/serverrequests.h +++ b/src/libsyncengine/requests/serverrequests.h @@ -99,7 +99,7 @@ struct SYNCENGINE_EXPORT ServerRequests { static ExitCode getSubFolders(int driveDbId, const QString &nodeId, QList &list, bool withPath = false); static ExitCode createDir(int driveDbId, const QString &parentNodeId, const QString &dirName, QString &newNodeId); static ExitCode getPublicLinkUrl(int driveDbId, const QString &fileId, QString &linkUrl); - static ExitCode getFolderSize(int userDbId, int driveId, const NodeId &nodeId, + static ExitInfo getFolderSize(int userDbId, int driveId, const NodeId &nodeId, std::function callback); static ExitCode getNodeIdByPath(int userDbId, int driveId, const SyncPath &path, QString &nodeId); static ExitCode getPathByNodeId(int userDbId, int driveId, const QString &nodeId, QString &path); diff --git a/src/libsyncengine/syncpal/isyncworker.cpp b/src/libsyncengine/syncpal/isyncworker.cpp index 638bce75f..1d2e26935 100644 --- a/src/libsyncengine/syncpal/isyncworker.cpp +++ b/src/libsyncengine/syncpal/isyncworker.cpp @@ -37,6 +37,7 @@ ISyncWorker::~ISyncWorker() { } LOG_SYNCPAL_DEBUG(_logger, "Worker " << _name.c_str() << " destroyed"); + log4cplus::threadCleanup(); } void ISyncWorker::start() { @@ -150,6 +151,7 @@ void ISyncWorker::setDone(ExitCode exitCode) { _isRunning = false; _stopAsked = false; _exitCode = exitCode; + log4cplus::threadCleanup(); } void *ISyncWorker::executeFunc(void *thisWorker) { diff --git a/src/libsyncengine/syncpal/syncpalworker.cpp b/src/libsyncengine/syncpal/syncpalworker.cpp index fdbb0c580..398e82b41 100644 --- a/src/libsyncengine/syncpal/syncpalworker.cpp +++ b/src/libsyncengine/syncpal/syncpalworker.cpp @@ -220,8 +220,8 @@ void SyncPalWorker::execute() { Utility::msleep(LOOP_EXEC_SLEEP_PERIOD); } - setDone(exitCode); LOG_SYNCPAL_INFO(_logger, "Worker " << name().c_str() << " stoped"); + setDone(exitCode); } std::string SyncPalWorker::stepName(SyncStep step) { diff --git a/src/libsyncengine/update_detection/file_system_observer/checksum/contentchecksumworker.cpp b/src/libsyncengine/update_detection/file_system_observer/checksum/contentchecksumworker.cpp index 9b32bda16..c68b57626 100644 --- a/src/libsyncengine/update_detection/file_system_observer/checksum/contentchecksumworker.cpp +++ b/src/libsyncengine/update_detection/file_system_observer/checksum/contentchecksumworker.cpp @@ -101,8 +101,8 @@ void ContentChecksumWorker::execute() { Utility::msleep(10); } - setDone(exitCode); LOG_DEBUG(_logger, "Worker stopped: name=" << name().c_str()); + setDone(exitCode); } } // namespace KDC diff --git a/src/libsyncengine/update_detection/file_system_observer/computefsoperationworker.cpp b/src/libsyncengine/update_detection/file_system_observer/computefsoperationworker.cpp index fa80ffdae..8352df475 100644 --- a/src/libsyncengine/update_detection/file_system_observer/computefsoperationworker.cpp +++ b/src/libsyncengine/update_detection/file_system_observer/computefsoperationworker.cpp @@ -60,8 +60,8 @@ void ComputeFSOperationWorker::execute() { ok = false; } if (!ok) { - setDone(exitCode); LOG_SYNCPAL_DEBUG(_logger, "Worker stopped: name=" << name().c_str()); + setDone(exitCode); return; } @@ -102,8 +102,8 @@ void ComputeFSOperationWorker::execute() { std::chrono::duration elapsed_seconds = std::chrono::steady_clock::now() - start; LOG_SYNCPAL_INFO(_logger, "FS operation sets generated in: " << elapsed_seconds.count() << "s"); - setDone(exitCode); LOG_SYNCPAL_DEBUG(_logger, "Worker stopped: name=" << name().c_str()); + setDone(exitCode); } diff --git a/src/libsyncengine/update_detection/file_system_observer/folderwatcher_linux.cpp b/src/libsyncengine/update_detection/file_system_observer/folderwatcher_linux.cpp index cc3766595..bf28d04dc 100644 --- a/src/libsyncengine/update_detection/file_system_observer/folderwatcher_linux.cpp +++ b/src/libsyncengine/update_detection/file_system_observer/folderwatcher_linux.cpp @@ -46,11 +46,11 @@ void FolderWatcher_linux::startWatching() { _fileDescriptor = inotify_init(); if (_fileDescriptor == -1) { LOG4CPLUS_WARN(_logger, "inotify_init() failed: " << strerror(errno)); - return; + return Utility::terminateThreadFunction(); } if (!addFolderRecursive(_folder)) { - return; + return Utility::terminateThreadFunction(); } while (!_stop) { @@ -125,6 +125,9 @@ void FolderWatcher_linux::startWatching() { Utility::msleep(SLEEP_TIME); } } + + LOGW_DEBUG(_logger, L"Folder watching stopped: " << _folder.wstring().c_str()); + Utility::terminateThreadFunction(); } bool FolderWatcher_linux::findSubFolders(const SyncPath &dir, std::list &fullList) { diff --git a/src/libsyncengine/update_detection/file_system_observer/folderwatcher_mac.cpp b/src/libsyncengine/update_detection/file_system_observer/folderwatcher_mac.cpp index 18fcb5989..3cd914573 100644 --- a/src/libsyncengine/update_detection/file_system_observer/folderwatcher_mac.cpp +++ b/src/libsyncengine/update_detection/file_system_observer/folderwatcher_mac.cpp @@ -108,6 +108,9 @@ void FolderWatcher_mac::startWatching() { FSEventStreamScheduleWithRunLoop(_stream, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); FSEventStreamStart(_stream); CFRunLoopRun(); + + LOGW_DEBUG(_logger, L"Folder watching stopped: " << _folder.wstring().c_str()); + Utility::terminateThreadFunction(); } void FolderWatcher_mac::doNotifyParent(const std::list> &changes) { diff --git a/src/libsyncengine/update_detection/file_system_observer/folderwatcher_win.cpp b/src/libsyncengine/update_detection/file_system_observer/folderwatcher_win.cpp index 99da64c60..c20c6469b 100644 --- a/src/libsyncengine/update_detection/file_system_observer/folderwatcher_win.cpp +++ b/src/libsyncengine/update_detection/file_system_observer/folderwatcher_win.cpp @@ -67,6 +67,7 @@ void FolderWatcher_win::startWatching() { } LOGW_DEBUG(_logger, L"Folder watching stopped: " << _folder.wstring().c_str()); + Utility::terminateThreadFunction(); } void FolderWatcher_win::stopWatching() { diff --git a/src/libsyncengine/update_detection/file_system_observer/localfilesystemobserverworker.cpp b/src/libsyncengine/update_detection/file_system_observer/localfilesystemobserverworker.cpp index 0bf20577a..beb9dccf5 100644 --- a/src/libsyncengine/update_detection/file_system_observer/localfilesystemobserverworker.cpp +++ b/src/libsyncengine/update_detection/file_system_observer/localfilesystemobserverworker.cpp @@ -475,8 +475,8 @@ void LocalFileSystemObserverWorker::execute() { Utility::msleep(LOOP_EXEC_SLEEP_PERIOD); } - setDone(exitCode); LOG_SYNCPAL_DEBUG(_logger, "Worker stopped: name=" << name().c_str()); + setDone(exitCode); } ExitCode LocalFileSystemObserverWorker::generateInitialSnapshot() { diff --git a/src/libsyncengine/update_detection/file_system_observer/remotefilesystemobserverworker.cpp b/src/libsyncengine/update_detection/file_system_observer/remotefilesystemobserverworker.cpp index e008a8133..8a39a5d8a 100644 --- a/src/libsyncengine/update_detection/file_system_observer/remotefilesystemobserverworker.cpp +++ b/src/libsyncengine/update_detection/file_system_observer/remotefilesystemobserverworker.cpp @@ -82,8 +82,8 @@ void RemoteFileSystemObserverWorker::execute() { Utility::msleep(LOOP_EXEC_SLEEP_PERIOD); } - setDone(exitCode); LOG_SYNCPAL_DEBUG(_logger, "Worker stopped: name=" << name().c_str()); + setDone(exitCode); } ExitCode RemoteFileSystemObserverWorker::generateInitialSnapshot() { diff --git a/src/libsyncengine/update_detection/update_detector/updatetreeworker.cpp b/src/libsyncengine/update_detection/update_detector/updatetreeworker.cpp index f611618bb..1f1b04c85 100644 --- a/src/libsyncengine/update_detection/update_detector/updatetreeworker.cpp +++ b/src/libsyncengine/update_detection/update_detector/updatetreeworker.cpp @@ -92,8 +92,8 @@ void UpdateTreeWorker::execute() { // Clear unexpected operation set once used _operationSet->clear(); - setDone(exitCode); LOG_SYNCPAL_DEBUG(_logger, "Worker stopped: name=" << name().c_str()); + setDone(exitCode); } ExitCode UpdateTreeWorker::step1MoveDirectory() { diff --git a/src/server/appserver.cpp b/src/server/appserver.cpp index b8f74d690..149c553d4 100644 --- a/src/server/appserver.cpp +++ b/src/server/appserver.cpp @@ -2106,7 +2106,7 @@ void AppServer::cancelLogUpload() { sendLogUploadStatusUpdated(LogUploadState::CancelRequested, 0); } -void AppServer::uploadLog(bool includeArchivedLogs) { +ExitInfo AppServer::uploadLog(bool includeArchivedLogs) { if (bool found = false; !ParmsDb::instance()->updateAppState(AppStateKey::LogUploadState, LogUploadState::None, found) || !found) { // Reset status LOG_WARN(_logger, "Error in ParmsDb::updateAppState"); @@ -2143,12 +2143,13 @@ void AppServer::uploadLog(bool includeArchivedLogs) { if (exitCause == ExitCause::OperationCanceled) { LOG_DEBUG(_logger, "Log transfert canceled"); sendLogUploadStatusUpdated(LogUploadState::Canceled, 0); - return; + return Utility::terminateThreadFunction({exitCode, exitCause}); } else if (exitCode != ExitCode::Ok) { LOG_WARN(_logger, "Error in LogArchiverHelper::sendLogToSupport: code=" << exitCode << " cause=" << exitCause); addError(Error(errId(), ExitCode::LogUploadFailed, exitCause)); } sendLogUploadStatusUpdated(exitCode == ExitCode::Ok ? LogUploadState::Success : LogUploadState::Failed, 0); + return Utility::terminateThreadFunction({exitCode, exitCause}); } ExitCode AppServer::checkIfSyncIsValid(const Sync &sync) { diff --git a/src/server/appserver.h b/src/server/appserver.h index 313c6277e..2196b1ca5 100644 --- a/src/server/appserver.h +++ b/src/server/appserver.h @@ -36,7 +36,6 @@ #include #include #include -#include #include namespace KDC { @@ -182,7 +181,7 @@ class AppServer : public SharedTools::QtSingleApplication { // See types.h -> AppStateKey for the possible values of status void cancelLogUpload(); - void uploadLog(bool includeArchivedLogs); + ExitInfo uploadLog(bool includeArchivedLogs); void sendLogUploadStatusUpdated(LogUploadState status, int percent); void startSyncPals(); diff --git a/src/server/vfs/mac/vfs_mac.cpp b/src/server/vfs/mac/vfs_mac.cpp index 1e95659eb..978ad57a2 100644 --- a/src/server/vfs/mac/vfs_mac.cpp +++ b/src/server/vfs/mac/vfs_mac.cpp @@ -822,6 +822,7 @@ void Worker::start() { } LOG_DEBUG(logger(), "Worker " << _type << " - " << _num << " ended"); + Utility::terminateThreadFunction(); } } // namespace KDC From 444432bea8e1a04aba7ac03cf52c59e890d480d6 Mon Sep 17 00:00:00 2001 From: Christophe Larchier Date: Fri, 15 Nov 2024 16:16:38 +0100 Subject: [PATCH 076/178] Fix build --- src/libcommonserver/io/iohelper_mac.mm | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/libcommonserver/io/iohelper_mac.mm b/src/libcommonserver/io/iohelper_mac.mm index c12aa7618..b6ed2dc44 100644 --- a/src/libcommonserver/io/iohelper_mac.mm +++ b/src/libcommonserver/io/iohelper_mac.mm @@ -104,7 +104,7 @@ IoError nsError2ioError(NSError *nsError) noexcept { CFRelease(aliasUrl); if (!ret) { if (error) { - ioError = nsError2ioError((NSError *)error); + ioError = nsError2ioError((__bridge NSError *) error); CFRelease(error); if (ioError != IoError::Unknown) { return true; @@ -136,7 +136,7 @@ IoError nsError2ioError(NSError *nsError) noexcept { CFRelease(aliasUrl); if (bookmarkRef == nil) { if (error) { - ioError = nsError2ioError((NSError *)error); + ioError = nsError2ioError((__bridge NSError *) error); CFRelease(error); if (ioError != IoError::Unknown) { return true; @@ -170,7 +170,7 @@ IoError nsError2ioError(NSError *nsError) noexcept { CFStringRef targetPathStr = CFURLCopyFileSystemPath(targetUrl, kCFURLPOSIXPathStyle); CFRelease(targetUrl); - targetPath = SyncPath(std::string([(NSString *)targetPathStr UTF8String])); + targetPath = SyncPath(std::string([(__bridge NSString *) targetPathStr UTF8String])); CFRelease(targetPathStr); return true; @@ -194,7 +194,7 @@ IoError nsError2ioError(NSError *nsError) noexcept { if (bookmarkRef == nil) { if (error) { - ioError = nsError2ioError((NSError *)error); + ioError = nsError2ioError((__bridge NSError *) error); CFRelease(error); } CFRelease(aliasUrl); @@ -212,7 +212,7 @@ IoError nsError2ioError(NSError *nsError) noexcept { if (!result) { if (error) { - ioError = nsError2ioError((NSError *)error); + ioError = nsError2ioError((__bridge NSError *) error); CFRelease(error); } LOGW_WARN(logger(), L"Error in CFURLWriteBookmarkDataToFile: " << Utility::formatSyncPath(aliasPath).c_str()); From 15b7385d1ad41bf0b807eb4c6ea655ae87474390 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Kunz?= Date: Fri, 15 Nov 2024 16:21:10 +0100 Subject: [PATCH 077/178] KDESKTOP-1384 - Differenciate events Move from MoveOut --- src/libcommon/utility/types.cpp | 2 ++ src/libcommon/utility/types.h | 2 +- .../file_system_observer/folderwatcher_win.cpp | 12 ++++-------- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/libcommon/utility/types.cpp b/src/libcommon/utility/types.cpp index 233421b87..9a6530ea9 100644 --- a/src/libcommon/utility/types.cpp +++ b/src/libcommon/utility/types.cpp @@ -70,6 +70,8 @@ std::string toString(const OperationType e) { return "Delete"; case OperationType::Rights: return "Rights"; + case OperationType::MoveOut: + return "MoveOut"; default: return noConversionStr; } diff --git a/src/libcommon/utility/types.h b/src/libcommon/utility/types.h index 5c4fc95c8..e23a161f0 100644 --- a/src/libcommon/utility/types.h +++ b/src/libcommon/utility/types.h @@ -168,7 +168,7 @@ enum class NodeType { }; std::string toString(NodeType e); -enum class OperationType { None = 0x00, Create = 0x01, Move = 0x02, Edit = 0x04, Delete = 0x08, Rights = 0x10 }; +enum class OperationType { None = 0x00, Create = 0x01, Move = 0x02, Edit = 0x04, Delete = 0x08, Rights = 0x10, MoveOut = 0x20 }; std::string toString(OperationType e); enum class ExitCode { diff --git a/src/libsyncengine/update_detection/file_system_observer/folderwatcher_win.cpp b/src/libsyncengine/update_detection/file_system_observer/folderwatcher_win.cpp index 99da64c60..207fedd79 100644 --- a/src/libsyncengine/update_detection/file_system_observer/folderwatcher_win.cpp +++ b/src/libsyncengine/update_detection/file_system_observer/folderwatcher_win.cpp @@ -118,8 +118,7 @@ void FolderWatcher_win::watchChanges() { _ready = true; HANDLE handles[] = {_resultEventHandle, _stopEventHandle}; - DWORD result = WaitForMultipleObjects(2, handles, false // awake once one of them arrives - , + DWORD result = WaitForMultipleObjects(2, handles, false, // awake once one of them arrives INFINITE); if (result == 1) { @@ -180,6 +179,8 @@ void FolderWatcher_win::watchChanges() { << L" detected on item with " << Utility::formatSyncPath(longfilepath)); } + if (opType == OperationType::MoveOut) opType = OperationType::Move; // "MoveOut" is considered as Move from now on + changeDetected(longfilepath, opType); } @@ -213,20 +214,15 @@ void FolderWatcher_win::closeHandle() { OperationType FolderWatcher_win::operationFromAction(DWORD action) { switch (action) { case FILE_ACTION_RENAMED_OLD_NAME: - return OperationType::Move; - break; + return OperationType::MoveOut; case FILE_ACTION_RENAMED_NEW_NAME: return OperationType::Move; - break; case FILE_ACTION_ADDED: return OperationType::Create; - break; case FILE_ACTION_REMOVED: return OperationType::Delete; - break; case FILE_ACTION_MODIFIED: return OperationType::Edit; - break; } return OperationType::None; From 30a0c59331923fb7f99a86d9edf5af256eaa5850 Mon Sep 17 00:00:00 2001 From: Christophe Larchier Date: Mon, 18 Nov 2024 07:45:58 +0100 Subject: [PATCH 078/178] Fix Linux build --- .../file_system_observer/folderwatcher_linux.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libsyncengine/update_detection/file_system_observer/folderwatcher_linux.cpp b/src/libsyncengine/update_detection/file_system_observer/folderwatcher_linux.cpp index bf28d04dc..967b6cde2 100644 --- a/src/libsyncengine/update_detection/file_system_observer/folderwatcher_linux.cpp +++ b/src/libsyncengine/update_detection/file_system_observer/folderwatcher_linux.cpp @@ -46,11 +46,11 @@ void FolderWatcher_linux::startWatching() { _fileDescriptor = inotify_init(); if (_fileDescriptor == -1) { LOG4CPLUS_WARN(_logger, "inotify_init() failed: " << strerror(errno)); - return Utility::terminateThreadFunction(); + Utility::terminateThreadFunction(); } if (!addFolderRecursive(_folder)) { - return Utility::terminateThreadFunction(); + Utility::terminateThreadFunction(); } while (!_stop) { From 68a185b2a1bea7c7da90c35b92fbf1abb9307360 Mon Sep 17 00:00:00 2001 From: Herve Eruam <82284536+herve-er@users.noreply.github.com> Date: Mon, 18 Nov 2024 08:26:55 +0100 Subject: [PATCH 079/178] Update test/libcommonserver/io/testio.cpp Co-authored-by: Luc Guyot <162997198+luc-guyot-infomaniak@users.noreply.github.com> --- test/libcommonserver/io/testio.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/libcommonserver/io/testio.cpp b/test/libcommonserver/io/testio.cpp index 7f7feb52c..111bbc62c 100644 --- a/test/libcommonserver/io/testio.cpp +++ b/test/libcommonserver/io/testio.cpp @@ -164,7 +164,7 @@ void TestIo::testAccesDeniedOnLockedFiles() { // Try to delete the file std::error_code ec; std::filesystem::remove_all(lockedFile, ec); - IoError ioError = IoHelper::stdError2ioError(ec); + const IoError ioError = IoHelper::stdError2ioError(ec); // Unlock the file CloseHandle(hFile); From 2b6fa9f22171c5b02c98e10eaba2b073c31a5368 Mon Sep 17 00:00:00 2001 From: Herve Eruam <82284536+herve-er@users.noreply.github.com> Date: Mon, 18 Nov 2024 08:29:21 +0100 Subject: [PATCH 080/178] Apply suggestions from code review Co-authored-by: Luc Guyot <162997198+luc-guyot-infomaniak@users.noreply.github.com> --- src/libsyncengine/jobs/network/API_v2/downloadjob.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libsyncengine/jobs/network/API_v2/downloadjob.cpp b/src/libsyncengine/jobs/network/API_v2/downloadjob.cpp index 4b8d864c6..93ee3ae53 100644 --- a/src/libsyncengine/jobs/network/API_v2/downloadjob.cpp +++ b/src/libsyncengine/jobs/network/API_v2/downloadjob.cpp @@ -119,7 +119,7 @@ bool DownloadJob::canRun() { if (_isCreate && exists) { LOGW_DEBUG(_logger, - L"Item: " << Utility::formatSyncPath(_localpath) << L" already exist. Aborting current sync and restart."); + L"Item with " << Utility::formatSyncPath(_localpath) << L" already exists. Aborting current sync and restarting."); _exitCode = ExitCode::NeedRestart; _exitCause = ExitCause::UnexpectedFileSystemEvent; return false; @@ -436,7 +436,7 @@ bool DownloadJob::createLink(const std::string &mimeType, const std::string &dat } LOGW_DEBUG(_logger, - L"Create symlink: " << Utility::formatSyncPath(targetPath) << L", " << Utility::formatSyncPath(_localpath)); + L"Create symlink with target " << Utility::formatSyncPath(targetPath) << L", " << Utility::formatSyncPath(_localpath)); bool isFolder = mimeType == mimeTypeSymlinkFolder; IoError ioError = IoError::Success; @@ -527,11 +527,11 @@ bool DownloadJob::moveTmpFile(const SyncPath &tmpPath, bool &restartSync) { bool removed = removeTmpFile(tmpPath); if (ec) { LOGW_WARN(_logger, - L"Failed to copy: " << Utility::formatSyncPath(_localpath) << L", " << Utility::formatStdError(ec)); + L"Failed to copy to " << Utility::formatSyncPath(_localpath) << L", " << Utility::formatStdError(ec)); return false; } if (!removed) { - LOGW_WARN(_logger, L"Failed to remove: " << Utility::formatSyncPath(tmpPath)); + LOGW_WARN(_logger, L"Failed to remove " << Utility::formatSyncPath(tmpPath)); return false; } } From 991bf87aba272e9e15833ffb9df45d4f31beef6c Mon Sep 17 00:00:00 2001 From: Herve Eruam <82284536+herve-er@users.noreply.github.com> Date: Mon, 18 Nov 2024 08:33:19 +0100 Subject: [PATCH 081/178] Update src/libsyncengine/jobs/network/API_v2/downloadjob.cpp --- src/libsyncengine/jobs/network/API_v2/downloadjob.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libsyncengine/jobs/network/API_v2/downloadjob.cpp b/src/libsyncengine/jobs/network/API_v2/downloadjob.cpp index 93ee3ae53..5ec72840c 100644 --- a/src/libsyncengine/jobs/network/API_v2/downloadjob.cpp +++ b/src/libsyncengine/jobs/network/API_v2/downloadjob.cpp @@ -210,7 +210,7 @@ bool DownloadJob::handleResponse(std::istream &is) { SyncPath tmpPath; IoError ioError = IoError::Success; if (!IoHelper::tempDirectoryPath(tmpPath, ioError)) { - LOGW_WARN(_logger, L"Failed to get temporary directory tmpPath: " << Utility::formatIoError(tmpPath, ioError)); + LOGW_WARN(_logger, L"Failed to get temporary directory path: " << Utility::formatIoError(tmpPath, ioError)); _exitCode = ExitCode::SystemError; _exitCause = ExitCause::Unknown; return false; From f258837e135aabe2a44ed66f34028026acc43f0d Mon Sep 17 00:00:00 2001 From: Herve Eruam Date: Mon, 18 Nov 2024 09:51:29 +0100 Subject: [PATCH 082/178] Handle file not found in upload job. --- .../jobs/network/API_v2/uploadjob.cpp | 15 +++++++++++++++ .../propagation/executor/executorworker.cpp | 17 +++++++++++++++++ .../propagation/executor/executorworker.h | 1 + 3 files changed, 33 insertions(+) diff --git a/src/libsyncengine/jobs/network/API_v2/uploadjob.cpp b/src/libsyncengine/jobs/network/API_v2/uploadjob.cpp index 42a1fa041..317955d1d 100644 --- a/src/libsyncengine/jobs/network/API_v2/uploadjob.cpp +++ b/src/libsyncengine/jobs/network/API_v2/uploadjob.cpp @@ -187,6 +187,21 @@ ExitInfo UploadJob::readFile() { std::ifstream file(_filePath, std::ios_base::in | std::ios_base::binary); if (!file.is_open()) { LOGW_WARN(_logger, L"Failed to open file - path=" << Path2WStr(_filePath)); + bool exists = false; + IoError ioError = IoError::Success; + if (!IoHelper::checkIfPathExists(_filePath, exists, ioError)) { + LOGW_WARN(_logger, L"Error in IoHelper::checkIfPathExists: " << Utility::formatIoError(_filePath, ioError)); + return {ExitCode::SystemError, ExitCause::Unknown}; + } + if (ioError == IoError::AccessDenied) { + LOGW_WARN(_logger, L"Access denied to " << Utility::formatSyncPath(_filePath)); + return {ExitCode::SystemError, ExitCause::FileAccessError}; + } + if (!exists) { + LOGW_DEBUG(_logger, L"Item does not exist anymore - " << Utility::formatSyncPath(_filePath)); + return {ExitCode::SystemError, ExitCause::NotFound}; + } + return {ExitCode::SystemError, ExitCause::FileAccessError}; } diff --git a/src/libsyncengine/propagation/executor/executorworker.cpp b/src/libsyncengine/propagation/executor/executorworker.cpp index 4f0c67d06..890c332d1 100644 --- a/src/libsyncengine/propagation/executor/executorworker.cpp +++ b/src/libsyncengine/propagation/executor/executorworker.cpp @@ -2507,6 +2507,9 @@ ExitInfo ExecutorWorker::handleExecutorError(SyncOpPtr syncOp, ExitInfo opsExitI case static_cast(ExitInfo(ExitCode::SystemError, ExitCause::MoveToTrashFailed)): { return handleOpsFileAccessError(syncOp, opsExitInfo); } + case static_cast(ExitInfo(ExitCode::SystemError, ExitCause::NotFound)): { + return handleOpsFileNotFound(syncOp, opsExitInfo); + } case static_cast(ExitInfo(ExitCode::BackError, ExitCause::FileAlreadyExist)): case static_cast(ExitInfo(ExitCode::DataError, ExitCause::FileAlreadyExist)): { return handleOpsAlreadyExistError(syncOp, opsExitInfo); @@ -2540,6 +2543,20 @@ ExitInfo ExecutorWorker::handleOpsFileAccessError(SyncOpPtr syncOp, ExitInfo ops return removeDependentOps(syncOp); } +ExitInfo ExecutorWorker::handleOpsFileNotFound(SyncOpPtr syncOp, ExitInfo opsExitInfo) { + auto job = std::dynamic_pointer_cast(_ongoingJobs[syncOp->id()]); + if (!job) { + auto job = std::dynamic_pointer_cast(_ongoingJobs[syncOp->id()]); + if (!job) { + LOGW_SYNCPAL_WARN(_logger, L"Job not found for operation: " << syncOp->id()); + return opsExitInfo; // Unable to handle this error + } + } + + _syncPal->setRestart(true); + return removeDependentOps(syncOp); +} + ExitInfo ExecutorWorker::handleOpsAlreadyExistError(SyncOpPtr syncOp, ExitInfo opsExitInfo) { // If the file/directory already exist either on local or remote side, we blacklist it localy and the remote // verson will be downloaded again. diff --git a/src/libsyncengine/propagation/executor/executorworker.h b/src/libsyncengine/propagation/executor/executorworker.h index ee740520a..d662fb947 100644 --- a/src/libsyncengine/propagation/executor/executorworker.h +++ b/src/libsyncengine/propagation/executor/executorworker.h @@ -147,6 +147,7 @@ class ExecutorWorker : public OperationProcessor { // return opsExitInfo. ExitInfo handleExecutorError(SyncOpPtr syncOp, ExitInfo opsExitInfo); ExitInfo handleOpsFileAccessError(SyncOpPtr syncOp, ExitInfo opsExitInfo); + ExitInfo handleOpsFileNotFound(SyncOpPtr syncOp, ExitInfo opsExitInfo); ExitInfo handleOpsAlreadyExistError(SyncOpPtr syncOp, ExitInfo opsExitInfo); ExitInfo removeDependentOps(SyncOpPtr syncOp); From 906eb6fdcdc9160d63633799ce763ba7aaf68a01 Mon Sep 17 00:00:00 2001 From: Herve Eruam Date: Mon, 18 Nov 2024 11:15:55 +0100 Subject: [PATCH 083/178] Add unit test for duplicate insertion in snapshot. --- .../file_system_observer/testsnapshot.cpp | 19 +++++++++++++++++++ .../file_system_observer/testsnapshot.h | 2 ++ 2 files changed, 21 insertions(+) diff --git a/test/libsyncengine/update_detection/file_system_observer/testsnapshot.cpp b/test/libsyncengine/update_detection/file_system_observer/testsnapshot.cpp index 78f3c2450..2885c91d8 100644 --- a/test/libsyncengine/update_detection/file_system_observer/testsnapshot.cpp +++ b/test/libsyncengine/update_detection/file_system_observer/testsnapshot.cpp @@ -117,6 +117,25 @@ void TestSnapshot::testSnapshot() { CPPUNIT_ASSERT_EQUAL(static_cast(1), snapshot.nbItems()); } +void TestSnapshot::testDuplicatedItem() { + const NodeId rootNodeId = *SyncDb::driveRootNode().nodeIdLocal(); + + const DbNode dummyRootNode(0, std::nullopt, Str("Local Drive"), SyncName(), "1", "1", std::nullopt, std::nullopt, + std::nullopt, NodeType::Directory, 0, std::nullopt); + Snapshot snapshot(ReplicaSide::Local, dummyRootNode); + + const SnapshotItem file1("A", rootNodeId, Str("file1"), 1640995201, -1640995201, NodeType::File, 123, + false, true, true); + const SnapshotItem file2("B", rootNodeId, Str("file1"), 1640995201, -1640995201, NodeType::File, 123, + false, true, true); + + snapshot.updateItem(file1); + snapshot.updateItem(file2); + + CPPUNIT_ASSERT(!snapshot.exists("A")); + CPPUNIT_ASSERT(snapshot.exists("B")); +} + void TestSnapshot::testSnapshotInsertionWithDifferentEncodings() { const NodeId rootNodeId = *SyncDb::driveRootNode().nodeIdLocal(); diff --git a/test/libsyncengine/update_detection/file_system_observer/testsnapshot.h b/test/libsyncengine/update_detection/file_system_observer/testsnapshot.h index c0365b400..a21d64d83 100644 --- a/test/libsyncengine/update_detection/file_system_observer/testsnapshot.h +++ b/test/libsyncengine/update_detection/file_system_observer/testsnapshot.h @@ -28,6 +28,7 @@ namespace KDC { class TestSnapshot : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(TestSnapshot); CPPUNIT_TEST(testSnapshot); + CPPUNIT_TEST(testDuplicatedItem); CPPUNIT_TEST(testSnapshotInsertionWithDifferentEncodings); CPPUNIT_TEST_SUITE_END(); @@ -37,6 +38,7 @@ class TestSnapshot : public CppUnit::TestFixture { private: void testSnapshot(); + void testDuplicatedItem(); void testSnapshotInsertionWithDifferentEncodings(); }; From 1678281bfeae5635e073aa52ff944f5bba6a46d7 Mon Sep 17 00:00:00 2001 From: Herve Eruam Date: Mon, 18 Nov 2024 13:00:31 +0100 Subject: [PATCH 084/178] Add LFSO test for MS office. --- .../localfilesystemobserverworker.h | 2 +- .../testlocalfilesystemobserverworker.cpp | 34 +++++++++++++++--- .../testlocalfilesystemobserverworker.h | 36 ++++++++++++++++--- 3 files changed, 63 insertions(+), 9 deletions(-) diff --git a/src/libsyncengine/update_detection/file_system_observer/localfilesystemobserverworker.h b/src/libsyncengine/update_detection/file_system_observer/localfilesystemobserverworker.h index 0fd2c313a..643424439 100644 --- a/src/libsyncengine/update_detection/file_system_observer/localfilesystemobserverworker.h +++ b/src/libsyncengine/update_detection/file_system_observer/localfilesystemobserverworker.h @@ -32,7 +32,7 @@ class LocalFileSystemObserverWorker : public FileSystemObserverWorker { void start() override; void stop() override; - void changesDetected(const std::list> &changes); + virtual void changesDetected(const std::list> &changes); virtual void forceUpdate() override; protected: diff --git a/test/libsyncengine/update_detection/file_system_observer/testlocalfilesystemobserverworker.cpp b/test/libsyncengine/update_detection/file_system_observer/testlocalfilesystemobserverworker.cpp index 3d65ac1c6..4362479d8 100644 --- a/test/libsyncengine/update_detection/file_system_observer/testlocalfilesystemobserverworker.cpp +++ b/test/libsyncengine/update_detection/file_system_observer/testlocalfilesystemobserverworker.cpp @@ -408,19 +408,45 @@ void TestLocalFileSystemObserverWorker::testLFSOWithSpecialCases2() { CPPUNIT_ASSERT(_syncPal->snapshot(ReplicaSide::Local)->name(initItemId) == testFilename); } -void TestLocalFileSystemObserverWorker::testLFSOFastMoveDelete() { +void TestLocalFileSystemObserverWorker::testLFSOFastMoveDeleteMove() { // MS Office test LOGW_DEBUG(_logger, L"***** Test fast move/delete *****"); + _syncPal->_localFSObserverWorker->stop(); + _syncPal->_localFSObserverWorker.reset(); + + // Create a slow observer +#if defined(_WIN32) + _syncPal->_localFSObserverWorker = + std::make_shared(_syncPal, "Local File System Observer", "LFSO"); +#else + _syncPal->_localFSObserverWorker = + std::make_shared(_syncPal, "Local File System Observer", "LFSO"); +#endif + _syncPal->_localFSObserverWorker->start(); + + int count = 0; + while (!_syncPal->snapshot(ReplicaSide::Local)->isValid()) { // Wait for the snapshot generation + Utility::msleep(100); + CPPUNIT_ASSERT(count++ < 20); // Do not wait more than 2s + } + CPPUNIT_ASSERT(_syncPal->snapshot(ReplicaSide::Local)->exists(_testFiles[0].first)); IoError ioError = IoError::Unknown; SyncPath destinationPath = _testFiles[0].second.parent_path() / (_testFiles[0].second.filename().string() + "2"); - CPPUNIT_ASSERT(IoHelper::renameItem(_testFiles[0].second, destinationPath, ioError)); + CPPUNIT_ASSERT(IoHelper::renameItem(_testFiles[0].second, destinationPath, ioError)); // test0.txt -> test0.txt2 + CPPUNIT_ASSERT_EQUAL(IoError::Success, ioError); + CPPUNIT_ASSERT(IoHelper::deleteItem(destinationPath, ioError)); // Delete test0.txt2 (before the previous rename is processed) CPPUNIT_ASSERT_EQUAL(IoError::Success, ioError); - CPPUNIT_ASSERT(IoHelper::deleteItem(destinationPath, ioError)); + CPPUNIT_ASSERT(IoHelper::renameItem(_testFiles[1].second, _testFiles[0].second, + ioError)); // test1.txt -> test0.txt (before the previous rename and delete is processed) CPPUNIT_ASSERT_EQUAL(IoError::Success, ioError); + Utility::msleep(1000); // Wait 1sec for the slow observer to process the events (+-200ms per event). - Utility::msleep(1000); // Wait 1sec + FileStat fileStat; + CPPUNIT_ASSERT(IoHelper::getFileStat(_testFiles[0].second, &fileStat, ioError)); + CPPUNIT_ASSERT_EQUAL(IoError::Success, ioError); CPPUNIT_ASSERT(!_syncPal->snapshot(ReplicaSide::Local)->exists(_testFiles[0].first)); + CPPUNIT_ASSERT(_syncPal->snapshot(ReplicaSide::Local)->exists(std::to_string(fileStat.inode))); } } // namespace KDC diff --git a/test/libsyncengine/update_detection/file_system_observer/testlocalfilesystemobserverworker.h b/test/libsyncengine/update_detection/file_system_observer/testlocalfilesystemobserverworker.h index d9f6d3ce9..e953ede7a 100644 --- a/test/libsyncengine/update_detection/file_system_observer/testlocalfilesystemobserverworker.h +++ b/test/libsyncengine/update_detection/file_system_observer/testlocalfilesystemobserverworker.h @@ -20,9 +20,12 @@ #include "testincludes.h" #include "test_utility/localtemporarydirectory.h" - #include "syncpal/syncpal.h" - +#if defined(_WIN32) +#include "libsyncengine/update_detection/file_system_observer/localfilesystemobserverworker_win.h" +#else +#include "libsyncengine/update_detection/file_system_observer/localfilesystemobserverworker_unix.h" +#endif #include using namespace CppUnit; @@ -30,6 +33,31 @@ using namespace CppUnit; namespace KDC { class LocalFileSystemObserverWorker; +#if defined(_WIN32) +class MockLocalFileSystemObserverWorker_win : public LocalFileSystemObserverWorker_win { + public: + MockLocalFileSystemObserverWorker_win(std::shared_ptr syncPal, const std::string &name, + const std::string &shortName) : + LocalFileSystemObserverWorker_win(syncPal, name, shortName) {} + + void changesDetected(const std::list> &changes) final { + Utility::msleep(200); + LocalFileSystemObserverWorker_win::changesDetected(changes); + } +}; +#else +class MockLocalFileSystemObserverWorker_unix : public LocalFileSystemObserverWorker_unix { + public: + MockLocalFileSystemObserverWorker_unix(std::shared_ptr syncPal, const std::string &name, + const std::string &shortName) : + LocalFileSystemObserverWorker_unix(syncPal, name, shortName) {} + + void changesDetected(const std::list> &changes) final { + Utility::msleep(200); + LocalFileSystemObserverWorker_unix::changesDetected(changes); + } +}; +#endif class TestLocalFileSystemObserverWorker : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(TestLocalFileSystemObserverWorker); @@ -38,7 +66,7 @@ class TestLocalFileSystemObserverWorker : public CppUnit::TestFixture { CPPUNIT_TEST(testLFSOWithDuplicateFileNames); CPPUNIT_TEST(testLFSODeleteDir); CPPUNIT_TEST(testLFSOWithDirs); - CPPUNIT_TEST(testLFSOFastMoveDelete); + CPPUNIT_TEST(testLFSOFastMoveDeleteMove); CPPUNIT_TEST(testLFSOWithSpecialCases1); CPPUNIT_TEST(testLFSOWithSpecialCases2); CPPUNIT_TEST_SUITE_END(); @@ -61,7 +89,7 @@ class TestLocalFileSystemObserverWorker : public CppUnit::TestFixture { void testLFSOWithDuplicateFileNames(); void testLFSOWithDirs(); void testLFSODeleteDir(); - void testLFSOFastMoveDelete(); + void testLFSOFastMoveDeleteMove(); void testLFSOWithSpecialCases1(); void testLFSOWithSpecialCases2(); }; From 6e2c56b800be7303a4148b20cf10b9f27fd0c70c Mon Sep 17 00:00:00 2001 From: Herve Eruam Date: Mon, 18 Nov 2024 13:01:13 +0100 Subject: [PATCH 085/178] Check for item dupliacation in Snapshot::updateItem --- .../snapshot/snapshot.cpp | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/libsyncengine/update_detection/file_system_observer/snapshot/snapshot.cpp b/src/libsyncengine/update_detection/file_system_observer/snapshot/snapshot.cpp index 23509e9e2..9bb147e6b 100644 --- a/src/libsyncengine/update_detection/file_system_observer/snapshot/snapshot.cpp +++ b/src/libsyncengine/update_detection/file_system_observer/snapshot/snapshot.cpp @@ -77,6 +77,27 @@ bool Snapshot::updateItem(const SnapshotItem &newItem) { return false; } + // Check if the item already exists in the new parent + if (auto itNewParent = _items.find(newItem.parentId()); itNewParent != _items.end()) { + auto childrenIds = itNewParent->second.childrenIds(); // Copy to avoid iterator invalidation + for (const NodeId &childId: childrenIds) { + auto child = _items.find(childId); + if (child == _items.end()) { + assert(false && "Child not found in snapshot"); + LOG_WARN(Log::instance()->getLogger(), "Child " << childId.c_str() << " not found in snapshot"); + continue; + } + + if (child->second.name() == newItem.name() && child->second.id() != newItem.id()) { + LOGW_DEBUG(Log::instance()->getLogger(), + L"Item: " << SyncName2WStr(newItem.name()) << L" (" << Utility::s2ws(newItem.id()) + << L") already exists in parent: " << Utility::s2ws(newItem.parentId()) + << L" with a different id. Removing it and adding the new one."); + removeItem(childId); + } + } + } + const SnapshotItem &prevItem = _items[newItem.id()]; // Update parent's children lists From 56a5eccaac8e1edbf8c51cd51050a2fabd3366ec Mon Sep 17 00:00:00 2001 From: Herve Eruam Date: Mon, 18 Nov 2024 13:09:36 +0100 Subject: [PATCH 086/178] Time optimisation of duplicate item check. --- .../file_system_observer/snapshot/snapshot.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/libsyncengine/update_detection/file_system_observer/snapshot/snapshot.cpp b/src/libsyncengine/update_detection/file_system_observer/snapshot/snapshot.cpp index 9bb147e6b..482a4d42d 100644 --- a/src/libsyncengine/update_detection/file_system_observer/snapshot/snapshot.cpp +++ b/src/libsyncengine/update_detection/file_system_observer/snapshot/snapshot.cpp @@ -79,8 +79,7 @@ bool Snapshot::updateItem(const SnapshotItem &newItem) { // Check if the item already exists in the new parent if (auto itNewParent = _items.find(newItem.parentId()); itNewParent != _items.end()) { - auto childrenIds = itNewParent->second.childrenIds(); // Copy to avoid iterator invalidation - for (const NodeId &childId: childrenIds) { + for (const NodeId &childId: itNewParent->second.childrenIds()) { auto child = _items.find(childId); if (child == _items.end()) { assert(false && "Child not found in snapshot"); @@ -94,8 +93,10 @@ bool Snapshot::updateItem(const SnapshotItem &newItem) { << L") already exists in parent: " << Utility::s2ws(newItem.parentId()) << L" with a different id. Removing it and adding the new one."); removeItem(childId); + break; // There should be (at most) only one item with the same name in a folder } } + } const SnapshotItem &prevItem = _items[newItem.id()]; From 64d66e7bf97265fce9c4511acf35bb87d0bdd3a5 Mon Sep 17 00:00:00 2001 From: Herve Eruam Date: Mon, 18 Nov 2024 14:44:23 +0100 Subject: [PATCH 087/178] Fix tests on mac and linux. --- .../snapshot/snapshot.cpp | 2 +- .../file_system_observer/snapshot/snapshot.h | 2 +- .../testlocalfilesystemobserverworker.cpp | 24 ++++++++++++------- .../testlocalfilesystemobserverworker.h | 15 +++++++----- 4 files changed, 27 insertions(+), 16 deletions(-) diff --git a/src/libsyncengine/update_detection/file_system_observer/snapshot/snapshot.cpp b/src/libsyncengine/update_detection/file_system_observer/snapshot/snapshot.cpp index 482a4d42d..e1e9ccc28 100644 --- a/src/libsyncengine/update_detection/file_system_observer/snapshot/snapshot.cpp +++ b/src/libsyncengine/update_detection/file_system_observer/snapshot/snapshot.cpp @@ -140,7 +140,7 @@ bool Snapshot::updateItem(const SnapshotItem &newItem) { return true; } -bool Snapshot::removeItem(const NodeId &id) { +bool Snapshot::removeItem(const NodeId id) { const std::scoped_lock lock(_mutex); if (id.empty()) { diff --git a/src/libsyncengine/update_detection/file_system_observer/snapshot/snapshot.h b/src/libsyncengine/update_detection/file_system_observer/snapshot/snapshot.h index 311a9eaa6..21e2aa711 100644 --- a/src/libsyncengine/update_detection/file_system_observer/snapshot/snapshot.h +++ b/src/libsyncengine/update_detection/file_system_observer/snapshot/snapshot.h @@ -40,7 +40,7 @@ class Snapshot : public SharedObject { void init(); bool updateItem(const SnapshotItem &newItem); - bool removeItem(const NodeId &id); + bool removeItem(const NodeId id); // Do not pass by reference to avoid dangling references NodeId itemId(const SyncPath &path) const; NodeId parentId(const NodeId &itemId) const; diff --git a/test/libsyncengine/update_detection/file_system_observer/testlocalfilesystemobserverworker.cpp b/test/libsyncengine/update_detection/file_system_observer/testlocalfilesystemobserverworker.cpp index 4362479d8..d4a00b582 100644 --- a/test/libsyncengine/update_detection/file_system_observer/testlocalfilesystemobserverworker.cpp +++ b/test/libsyncengine/update_detection/file_system_observer/testlocalfilesystemobserverworker.cpp @@ -414,13 +414,8 @@ void TestLocalFileSystemObserverWorker::testLFSOFastMoveDeleteMove() { // MS Off _syncPal->_localFSObserverWorker.reset(); // Create a slow observer -#if defined(_WIN32) - _syncPal->_localFSObserverWorker = - std::make_shared(_syncPal, "Local File System Observer", "LFSO"); -#else - _syncPal->_localFSObserverWorker = - std::make_shared(_syncPal, "Local File System Observer", "LFSO"); -#endif + auto slowObserver = std::make_shared(_syncPal, "Local File System Observer", "LFSO"); + _syncPal->_localFSObserverWorker = slowObserver; _syncPal->_localFSObserverWorker->start(); int count = 0; @@ -439,7 +434,8 @@ void TestLocalFileSystemObserverWorker::testLFSOFastMoveDeleteMove() { // MS Off CPPUNIT_ASSERT(IoHelper::renameItem(_testFiles[1].second, _testFiles[0].second, ioError)); // test1.txt -> test0.txt (before the previous rename and delete is processed) CPPUNIT_ASSERT_EQUAL(IoError::Success, ioError); - Utility::msleep(1000); // Wait 1sec for the slow observer to process the events (+-200ms per event). + + CPPUNIT_ASSERT_MESSAGE("No update detected in the expected time.", slowObserver->waitForUpdate()); FileStat fileStat; CPPUNIT_ASSERT(IoHelper::getFileStat(_testFiles[0].second, &fileStat, ioError)); @@ -449,4 +445,16 @@ void TestLocalFileSystemObserverWorker::testLFSOFastMoveDeleteMove() { // MS Off CPPUNIT_ASSERT(_syncPal->snapshot(ReplicaSide::Local)->exists(std::to_string(fileStat.inode))); } +bool MockLocalFileSystemObserverWorker::waitForUpdate(uint64_t timeoutMs) const { + using namespace std::chrono; + auto start = system_clock::now(); + while (!_updating && duration_cast(system_clock::now() - start).count() < timeoutMs) { + Utility::msleep(10); + } + while (_updating && duration_cast(system_clock::now() - start).count() < timeoutMs) { + Utility::msleep(10); + } + return duration_cast(system_clock::now() - start).count() < timeoutMs; +} + } // namespace KDC diff --git a/test/libsyncengine/update_detection/file_system_observer/testlocalfilesystemobserverworker.h b/test/libsyncengine/update_detection/file_system_observer/testlocalfilesystemobserverworker.h index e953ede7a..b0a55b521 100644 --- a/test/libsyncengine/update_detection/file_system_observer/testlocalfilesystemobserverworker.h +++ b/test/libsyncengine/update_detection/file_system_observer/testlocalfilesystemobserverworker.h @@ -34,28 +34,31 @@ namespace KDC { class LocalFileSystemObserverWorker; #if defined(_WIN32) -class MockLocalFileSystemObserverWorker_win : public LocalFileSystemObserverWorker_win { +class MockLocalFileSystemObserverWorker : public LocalFileSystemObserverWorker_win { public: - MockLocalFileSystemObserverWorker_win(std::shared_ptr syncPal, const std::string &name, - const std::string &shortName) : + MockLocalFileSystemObserverWorker(std::shared_ptr syncPal, const std::string &name, + const std::string &shortName) : LocalFileSystemObserverWorker_win(syncPal, name, shortName) {} void changesDetected(const std::list> &changes) final { Utility::msleep(200); LocalFileSystemObserverWorker_win::changesDetected(changes); } + + bool waitForUpdate(uint64_t timeoutMs = 100000) const; }; #else -class MockLocalFileSystemObserverWorker_unix : public LocalFileSystemObserverWorker_unix { +class MockLocalFileSystemObserverWorker : public LocalFileSystemObserverWorker_unix { public: - MockLocalFileSystemObserverWorker_unix(std::shared_ptr syncPal, const std::string &name, - const std::string &shortName) : + MockLocalFileSystemObserverWorker(std::shared_ptr syncPal, const std::string &name, + const std::string &shortName) : LocalFileSystemObserverWorker_unix(syncPal, name, shortName) {} void changesDetected(const std::list> &changes) final { Utility::msleep(200); LocalFileSystemObserverWorker_unix::changesDetected(changes); } + bool waitForUpdate(uint64_t timeoutMs = 100000) const; }; #endif From 407bfd87b236e3bf27b05a35738af225e37fd1b2 Mon Sep 17 00:00:00 2001 From: Herve Eruam Date: Mon, 18 Nov 2024 14:51:31 +0100 Subject: [PATCH 088/178] Comment enhancement. --- .../update_detection/file_system_observer/snapshot/snapshot.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libsyncengine/update_detection/file_system_observer/snapshot/snapshot.cpp b/src/libsyncengine/update_detection/file_system_observer/snapshot/snapshot.cpp index e1e9ccc28..5c5814a8b 100644 --- a/src/libsyncengine/update_detection/file_system_observer/snapshot/snapshot.cpp +++ b/src/libsyncengine/update_detection/file_system_observer/snapshot/snapshot.cpp @@ -77,7 +77,7 @@ bool Snapshot::updateItem(const SnapshotItem &newItem) { return false; } - // Check if the item already exists in the new parent + // Check if `newItem` already exists with the same path but a different Id if (auto itNewParent = _items.find(newItem.parentId()); itNewParent != _items.end()) { for (const NodeId &childId: itNewParent->second.childrenIds()) { auto child = _items.find(childId); From 949d2206235f09497056c3ab3e7c609a1a5d1522 Mon Sep 17 00:00:00 2001 From: Herve Eruam Date: Mon, 18 Nov 2024 16:23:04 +0100 Subject: [PATCH 089/178] Retry for 10s in case of access denied in uploadjob. --- .../upload_session/abstractuploadsession.cpp | 42 ++++++++++++++-- .../jobs/network/API_v2/uploadjob.cpp | 48 ++++++++++++------- .../propagation/executor/executorworker.cpp | 10 ++-- 3 files changed, 71 insertions(+), 29 deletions(-) diff --git a/src/libsyncengine/jobs/network/API_v2/upload_session/abstractuploadsession.cpp b/src/libsyncengine/jobs/network/API_v2/upload_session/abstractuploadsession.cpp index 8b9ec69b3..07ef82dd4 100644 --- a/src/libsyncengine/jobs/network/API_v2/upload_session/abstractuploadsession.cpp +++ b/src/libsyncengine/jobs/network/API_v2/upload_session/abstractuploadsession.cpp @@ -265,13 +265,47 @@ bool AbstractUploadSession::sendChunks() { bool checksumError = false; bool jobCreationError = false; bool sendChunksCanceled = false; - std::ifstream file(_filePath.native().c_str(), std::ifstream::binary); - if (!file.is_open()) { - LOGW_WARN(_logger, L"Failed to open file " << Path2WStr(_filePath).c_str()); - _exitCode = ExitCode::DataError; + std::ifstream file; + int count = 0; + do { + file.open(_filePath.native().c_str(), std::ifstream::binary); + if (!file.is_open()) { + bool exists = false; + IoError ioError = IoError::Success; + if (!IoHelper::checkIfPathExists(_filePath, exists, ioError)) { + LOGW_WARN(_logger, L"Error in IoHelper::checkIfPathExists: " << Utility::formatIoError(_filePath, ioError)); + _exitCode = ExitCode::SystemError; + return false; + } + if (ioError == IoError::AccessDenied) { + LOGW_WARN(_logger, L"Access denied to " << Utility::formatSyncPath(_filePath)); + _exitCode = ExitCode::SystemError; + _exitCause = ExitCause::FileAccessError; + return false; + } + if (!exists) { + LOGW_DEBUG(_logger, L"Item does not exist anymore - " << Utility::formatSyncPath(_filePath)); + _exitCode = ExitCode::SystemError; + _exitCause = ExitCause::NotFound; + return false; + } + } + Utility::msleep(1000); + + // Some applications generate locked temporary files during save operations. To avoid spurious "access denied" errors, + // we retry for 10 seconds, which is usually sufficient for the application to delete the tmp file. If the file is still + // locked after 10 seconds, a file access error is displayed to the user. Proper handling is also implemented for + // "file not found" errors. + } while (count++ < 10 && !file.is_open()); + + if (count >= 10) { + LOGW_WARN(_logger, L"Failed to open file - path=" << Path2WStr(_filePath)); + _exitCode = ExitCode::SystemError; + _exitCause = ExitCause::FileAccessError; return false; } + // Create a hash state XXH3_state_t *const state = XXH3_createState(); if (!state) { diff --git a/src/libsyncengine/jobs/network/API_v2/uploadjob.cpp b/src/libsyncengine/jobs/network/API_v2/uploadjob.cpp index 317955d1d..8e50fddbd 100644 --- a/src/libsyncengine/jobs/network/API_v2/uploadjob.cpp +++ b/src/libsyncengine/jobs/network/API_v2/uploadjob.cpp @@ -30,8 +30,8 @@ namespace KDC { UploadJob::UploadJob(int driveDbId, const SyncPath &filepath, const SyncName &filename, const NodeId &remoteParentDirId, SyncTime modtime) : - AbstractTokenNetworkJob(ApiType::Drive, 0, 0, driveDbId, 0), _filePath(filepath), _filename(filename), - _remoteParentDirId(remoteParentDirId), _modtimeIn(modtime) { + AbstractTokenNetworkJob(ApiType::Drive, 0, 0, driveDbId, 0), + _filePath(filepath), _filename(filename), _remoteParentDirId(remoteParentDirId), _modtimeIn(modtime) { _httpMethod = Poco::Net::HTTPRequest::HTTP_POST; _customTimeout = 60; _trials = TRIALS; @@ -184,24 +184,36 @@ std::string UploadJob::getContentType(bool &canceled) { } ExitInfo UploadJob::readFile() { - std::ifstream file(_filePath, std::ios_base::in | std::ios_base::binary); - if (!file.is_open()) { - LOGW_WARN(_logger, L"Failed to open file - path=" << Path2WStr(_filePath)); - bool exists = false; - IoError ioError = IoError::Success; - if (!IoHelper::checkIfPathExists(_filePath, exists, ioError)) { - LOGW_WARN(_logger, L"Error in IoHelper::checkIfPathExists: " << Utility::formatIoError(_filePath, ioError)); - return {ExitCode::SystemError, ExitCause::Unknown}; - } - if (ioError == IoError::AccessDenied) { - LOGW_WARN(_logger, L"Access denied to " << Utility::formatSyncPath(_filePath)); - return {ExitCode::SystemError, ExitCause::FileAccessError}; - } - if (!exists) { - LOGW_DEBUG(_logger, L"Item does not exist anymore - " << Utility::formatSyncPath(_filePath)); - return {ExitCode::SystemError, ExitCause::NotFound}; + std::ifstream file; + int count = 0; + do { + file.open(_filePath, std::ios_base::in | std::ios_base::binary); + if (!file.is_open()) { + bool exists = false; + IoError ioError = IoError::Success; + if (!IoHelper::checkIfPathExists(_filePath, exists, ioError)) { + LOGW_WARN(_logger, L"Error in IoHelper::checkIfPathExists: " << Utility::formatIoError(_filePath, ioError)); + return {ExitCode::SystemError, ExitCause::Unknown}; + } + if (ioError == IoError::AccessDenied) { + LOGW_WARN(_logger, L"Access denied to " << Utility::formatSyncPath(_filePath)); + return {ExitCode::SystemError, ExitCause::FileAccessError}; + } + if (!exists) { + LOGW_DEBUG(_logger, L"Item does not exist anymore - " << Utility::formatSyncPath(_filePath)); + return {ExitCode::SystemError, ExitCause::NotFound}; + } } + Utility::msleep(1000); + + // Some applications generate locked temporary files during save operations. To avoid spurious "access denied" errors, + // we retry for 10 seconds, which is usually sufficient for the application to delete the tmp file. If the file is still + // locked after 10 seconds, a file access error is displayed to the user. Proper handling is also implemented for + // "file not found" errors. + } while (count++ < 10 && !file.is_open()); + if (count >= 10) { + LOGW_WARN(_logger, L"Failed to open file - path=" << Path2WStr(_filePath)); return {ExitCode::SystemError, ExitCause::FileAccessError}; } diff --git a/src/libsyncengine/propagation/executor/executorworker.cpp b/src/libsyncengine/propagation/executor/executorworker.cpp index 890c332d1..906f17e84 100644 --- a/src/libsyncengine/propagation/executor/executorworker.cpp +++ b/src/libsyncengine/propagation/executor/executorworker.cpp @@ -2544,13 +2544,9 @@ ExitInfo ExecutorWorker::handleOpsFileAccessError(SyncOpPtr syncOp, ExitInfo ops } ExitInfo ExecutorWorker::handleOpsFileNotFound(SyncOpPtr syncOp, ExitInfo opsExitInfo) { - auto job = std::dynamic_pointer_cast(_ongoingJobs[syncOp->id()]); - if (!job) { - auto job = std::dynamic_pointer_cast(_ongoingJobs[syncOp->id()]); - if (!job) { - LOGW_SYNCPAL_WARN(_logger, L"Job not found for operation: " << syncOp->id()); - return opsExitInfo; // Unable to handle this error - } + if (syncOp->targetSide() != ReplicaSide::Remote) { + LOGW_SYNCPAL_WARN(_logger, L"Invalid target side for SystemError | FileNotFound error: " << syncOp->targetSide()); + return opsExitInfo; // Unable to handle this error } _syncPal->setRestart(true); From 830459dfa5ddc62c0c6f4d5c736acc8dba70bef6 Mon Sep 17 00:00:00 2001 From: Herve Eruam Date: Mon, 18 Nov 2024 16:48:12 +0100 Subject: [PATCH 090/178] Fix UploadJob::readFile() --- .../network/API_v2/upload_session/abstractuploadsession.cpp | 5 +++-- src/libsyncengine/jobs/network/API_v2/uploadjob.cpp | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/libsyncengine/jobs/network/API_v2/upload_session/abstractuploadsession.cpp b/src/libsyncengine/jobs/network/API_v2/upload_session/abstractuploadsession.cpp index 07ef82dd4..24b854367 100644 --- a/src/libsyncengine/jobs/network/API_v2/upload_session/abstractuploadsession.cpp +++ b/src/libsyncengine/jobs/network/API_v2/upload_session/abstractuploadsession.cpp @@ -36,7 +36,8 @@ namespace KDC { AbstractUploadSession::AbstractUploadSession(const SyncPath &filepath, const SyncName &filename, uint64_t nbParalleleThread /*= 1*/) : - _logger(Log::instance()->getLogger()), _filePath(filepath), _filename(filename), _nbParalleleThread(nbParalleleThread) { + _logger(Log::instance()->getLogger()), + _filePath(filepath), _filename(filename), _nbParalleleThread(nbParalleleThread) { IoError ioError = IoError::Success; if (!IoHelper::getFileSize(_filePath, _filesize, ioError)) { std::wstring exceptionMessage = L"Error in IoHelper::getFileSize for " + Utility::formatIoError(_filePath, ioError); @@ -289,8 +290,8 @@ bool AbstractUploadSession::sendChunks() { _exitCause = ExitCause::NotFound; return false; } + Utility::msleep(1000); } - Utility::msleep(1000); // Some applications generate locked temporary files during save operations. To avoid spurious "access denied" errors, // we retry for 10 seconds, which is usually sufficient for the application to delete the tmp file. If the file is still diff --git a/src/libsyncengine/jobs/network/API_v2/uploadjob.cpp b/src/libsyncengine/jobs/network/API_v2/uploadjob.cpp index 8e50fddbd..63b3b19b3 100644 --- a/src/libsyncengine/jobs/network/API_v2/uploadjob.cpp +++ b/src/libsyncengine/jobs/network/API_v2/uploadjob.cpp @@ -203,8 +203,8 @@ ExitInfo UploadJob::readFile() { LOGW_DEBUG(_logger, L"Item does not exist anymore - " << Utility::formatSyncPath(_filePath)); return {ExitCode::SystemError, ExitCause::NotFound}; } + Utility::msleep(1000); } - Utility::msleep(1000); // Some applications generate locked temporary files during save operations. To avoid spurious "access denied" errors, // we retry for 10 seconds, which is usually sufficient for the application to delete the tmp file. If the file is still From c23f919edd07df06faa22a0c695010ce15577508 Mon Sep 17 00:00:00 2001 From: Luc Guyot Date: Wed, 13 Nov 2024 16:16:14 +0100 Subject: [PATCH 091/178] [KDESKTOP-1378] Add further unit tests for the ExecutorWorker::isValidDestination method --- .../syncpal/operationprocessor.h | 2 +- .../executor/testexecutorworker.cpp | 146 ++++++++++++++---- .../propagation/executor/testexecutorworker.h | 3 + 3 files changed, 124 insertions(+), 27 deletions(-) diff --git a/src/libsyncengine/syncpal/operationprocessor.h b/src/libsyncengine/syncpal/operationprocessor.h index bcd54b033..8724e03c5 100644 --- a/src/libsyncengine/syncpal/operationprocessor.h +++ b/src/libsyncengine/syncpal/operationprocessor.h @@ -36,7 +36,7 @@ class OperationProcessor : public ISyncWorker { * @param node a shared pointer to the node in current tree. * @return a shared pointer to the node in other tree. nullptr il not found. */ - std::shared_ptr correspondingNodeInOtherTree(std::shared_ptr node); + virtual std::shared_ptr correspondingNodeInOtherTree(std::shared_ptr node); /** * Find the corresponding node in other tree. * Looks in DB only. diff --git a/test/libsyncengine/propagation/executor/testexecutorworker.cpp b/test/libsyncengine/propagation/executor/testexecutorworker.cpp index 2cdbde318..7a1fecb36 100644 --- a/test/libsyncengine/propagation/executor/testexecutorworker.cpp +++ b/test/libsyncengine/propagation/executor/testexecutorworker.cpp @@ -69,7 +69,7 @@ void TestExecutorWorker::setUp() { } _syncPal = std::make_shared(_sync.dbId(), KDRIVE_VERSION_STRING); - _syncPal->createWorkers(); + _executorWorker = std::shared_ptr(new ExecutorWorker(_syncPal, "Executor", "EXEC")); _syncPal->syncDb()->setAutoDelete(true); } @@ -103,7 +103,7 @@ void TestExecutorWorker::testCheckLiteSyncInfoForCreate() { }); bool isDehydratedPlaceholder = false; - _syncPal->_executorWorker->checkLiteSyncInfoForCreate(opPtr, "/", isDehydratedPlaceholder); + _executorWorker->checkLiteSyncInfoForCreate(opPtr, "/", isDehydratedPlaceholder); CPPUNIT_ASSERT(!isDehydratedPlaceholder); } @@ -120,7 +120,7 @@ void TestExecutorWorker::testCheckLiteSyncInfoForCreate() { }); bool isDehydratedPlaceholder = false; - _syncPal->_executorWorker->checkLiteSyncInfoForCreate(opPtr, "/", isDehydratedPlaceholder); + _executorWorker->checkLiteSyncInfoForCreate(opPtr, "/", isDehydratedPlaceholder); CPPUNIT_ASSERT(isDehydratedPlaceholder); } @@ -137,7 +137,7 @@ void TestExecutorWorker::testCheckLiteSyncInfoForCreate() { }); bool isDehydratedPlaceholder = false; - _syncPal->_executorWorker->checkLiteSyncInfoForCreate(opPtr, "/", isDehydratedPlaceholder); + _executorWorker->checkLiteSyncInfoForCreate(opPtr, "/", isDehydratedPlaceholder); CPPUNIT_ASSERT(!isDehydratedPlaceholder); } @@ -154,7 +154,7 @@ void TestExecutorWorker::testCheckLiteSyncInfoForCreate() { }); bool isDehydratedPlaceholder = false; - _syncPal->_executorWorker->checkLiteSyncInfoForCreate(opPtr, "/", isDehydratedPlaceholder); + _executorWorker->checkLiteSyncInfoForCreate(opPtr, "/", isDehydratedPlaceholder); CPPUNIT_ASSERT(!isDehydratedPlaceholder); } @@ -178,32 +178,126 @@ SyncOpPtr TestExecutorWorker::generateSyncOperation(const DbNodeId dbNodeId, con return op; } + +SyncOpPtr TestExecutorWorker::generateSyncOperationWithNestedNodes(const DbNodeId dbNodeId, const SyncName &parentFilename, + const OperationType opType, const NodeType nodeType) { + auto parentNode = + std::make_shared(dbNodeId, ReplicaSide::Local, parentFilename, NodeType::Directory, OperationType::None, + "local_parent_id", testhelpers::defaultTime, testhelpers::defaultTime, + testhelpers::defaultFileSize, _syncPal->updateTree(ReplicaSide::Local)->rootNode()); + + auto node = + std::make_shared(dbNodeId, ReplicaSide::Local, "test_file.txt", nodeType, OperationType::None, "local_child_id", + testhelpers::defaultTime, testhelpers::defaultTime, testhelpers::defaultFileSize, parentNode); + + + auto correspondingNode = + std::make_shared(dbNodeId, ReplicaSide::Remote, "test_file.txt", nodeType, OperationType::None, + "remote_child_id", testhelpers::defaultTime, testhelpers::defaultTime, + testhelpers::defaultFileSize, _syncPal->updateTree(ReplicaSide::Remote)->rootNode()); + + SyncOpPtr op = std::make_shared(); + op->setAffectedNode(node); + op->setCorrespondingNode(correspondingNode); + op->setType(opType); + + return op; +} + +class ExecutorWorkerMock : public ExecutorWorker { + public: + ExecutorWorkerMock(std::shared_ptr syncPal, const std::string &name, const std::string &shortName) : + ExecutorWorker(syncPal, name, shortName){}; + + using ArgsMap = std::map, std::shared_ptr>; + void setCorrespondingNodeInOtherTree(ArgsMap nodeMap) { _correspondingNodeInOtherTree = nodeMap; }; + + protected: + ArgsMap _correspondingNodeInOtherTree; + virtual std::shared_ptr correspondingNodeInOtherTree(const std::shared_ptr node) { + if (auto it = _correspondingNodeInOtherTree.find(node); it != _correspondingNodeInOtherTree.cend()) { + return it->second; + } + + return nullptr; + }; +}; + void TestExecutorWorker::testIsValidDestination() { // Always true if the target side is local or unknown { SyncOpPtr op = generateSyncOperation(1, Str("test_file.txt")); - CPPUNIT_ASSERT(_syncPal->_executorWorker->isValidDestination(op)); + CPPUNIT_ASSERT(_executorWorker->isValidDestination(op)); } // Always true if the operation is not of type Create { SyncOpPtr op = generateSyncOperation(1, Str("test_file.txt")); op->setTargetSide(ReplicaSide::Remote); - CPPUNIT_ASSERT(_syncPal->_executorWorker->isValidDestination(op)); + CPPUNIT_ASSERT(_executorWorker->isValidDestination(op)); + } + // Always true if the item is created on the local replica at the root of the synchronisation folder + { + SyncOpPtr op = generateSyncOperation(1, Str("parent_dir")); + op->setTargetSide(ReplicaSide::Remote); + CPPUNIT_ASSERT(_executorWorker->isValidDestination(op)); + } + + + const auto executorWorkerMock = std::shared_ptr(new ExecutorWorkerMock(_syncPal, "Executor", "EXEC")); + // False if the item is created on the local replica is not at the root of the synchronisation folder and has no + // corresponding parent node. + { + SyncOpPtr op = generateSyncOperationWithNestedNodes(1, Str("test_file.txt"), OperationType::Create, NodeType::File); + executorWorkerMock->setCorrespondingNodeInOtherTree({{op->affectedNode()->parentNode(), nullptr}}); + op->setTargetSide(ReplicaSide::Remote); + CPPUNIT_ASSERT(!executorWorkerMock->isValidDestination(op)); } - // Always true if the item is created on the local replica, at the root of the synchronisation folder + + const auto root = _syncPal->updateTree(ReplicaSide::Remote)->rootNode(); + + // False if the item is created on the local replica is not at the root of the synchronisation folder and has a + // corresponding parent node with no id. + { + const auto correspondingParentNode = std::make_shared(666, ReplicaSide::Remote, "parent_dir", NodeType::Directory, + OperationType::None, std::nullopt, testhelpers::defaultTime, + testhelpers::defaultTime, testhelpers::defaultFileSize, root); + + + SyncOpPtr op = generateSyncOperationWithNestedNodes(1, Str("test_file.txt"), OperationType::Create, NodeType::File); + executorWorkerMock->setCorrespondingNodeInOtherTree({{op->affectedNode()->parentNode(), correspondingParentNode}}); + op->setTargetSide(ReplicaSide::Remote); + CPPUNIT_ASSERT(!executorWorkerMock->isValidDestination(op)); + } + + const auto correspondingParentCommonDocsNode = std::make_shared( + 666, ReplicaSide::Remote, Utility::commonDocumentsFolderName(), NodeType::Directory, OperationType::None, + "common_docs_id", testhelpers::defaultTime, testhelpers::defaultTime, testhelpers::defaultFileSize, root); + + // False if the item is created on the local replica is a file and has Common Documents as corresponding parent node. + { + SyncOpPtr op = generateSyncOperationWithNestedNodes(1, Str("test_file.txt"), OperationType::Create, NodeType::File); + op->setTargetSide(ReplicaSide::Remote); + executorWorkerMock->setCorrespondingNodeInOtherTree( + {{op->affectedNode()->parentNode(), correspondingParentCommonDocsNode}}); + CPPUNIT_ASSERT(!executorWorkerMock->isValidDestination(op)); + } + + // True if the item is created on the local replica is a directory and has Common Documents as corresponding parent node. { - SyncOpPtr op = generateSyncOperation(1, Str("test_file.txt"), OperationType::Create); + SyncOpPtr op = generateSyncOperationWithNestedNodes(1, Str("test_dir"), OperationType::Create, NodeType::Directory); op->setTargetSide(ReplicaSide::Remote); - CPPUNIT_ASSERT(_syncPal->_executorWorker->isValidDestination(op)); + executorWorkerMock->setCorrespondingNodeInOtherTree( + {{op->affectedNode()->parentNode(), correspondingParentCommonDocsNode}}); + CPPUNIT_ASSERT(executorWorkerMock->isValidDestination(op)); } } void TestExecutorWorker::testLogCorrespondingNodeErrorMsg() { SyncOpPtr op = generateSyncOperation(1, Str("test_file.txt")); - _syncPal->_executorWorker->logCorrespondingNodeErrorMsg(op); + _executorWorker->logCorrespondingNodeErrorMsg(op); op->setCorrespondingNode(nullptr); - _syncPal->_executorWorker->logCorrespondingNodeErrorMsg(op); + _executorWorker->logCorrespondingNodeErrorMsg(op); } void TestExecutorWorker::testFixModificationDate() { @@ -226,7 +320,7 @@ void TestExecutorWorker::testFixModificationDate() { _syncPal->syncDb()->insertNode(dbNode, dbNodeId, constraintError); SyncOpPtr op = generateSyncOperation(dbNodeId, filename); - CPPUNIT_ASSERT(_syncPal->_executorWorker->fixModificationDate(op, path)); + CPPUNIT_ASSERT(_executorWorker->fixModificationDate(op, path)); FileStat filestat; IoError ioError = IoError::Unknown; @@ -241,28 +335,28 @@ void TestExecutorWorker::testAffectedUpdateTree() { auto syncOp = std::make_shared(); syncOp->setTargetSide(ReplicaSide::Local); - CPPUNIT_ASSERT_EQUAL(ReplicaSide::Remote, _syncPal->_executorWorker->affectedUpdateTree(syncOp)->side()); + CPPUNIT_ASSERT_EQUAL(ReplicaSide::Remote, _executorWorker->affectedUpdateTree(syncOp)->side()); syncOp->setTargetSide(ReplicaSide::Remote); - CPPUNIT_ASSERT_EQUAL(ReplicaSide::Local, _syncPal->_executorWorker->affectedUpdateTree(syncOp)->side()); + CPPUNIT_ASSERT_EQUAL(ReplicaSide::Local, _executorWorker->affectedUpdateTree(syncOp)->side()); // ReplicaSide::Unknown case syncOp->setTargetSide(ReplicaSide::Unknown); - CPPUNIT_ASSERT_EQUAL(std::shared_ptr(nullptr), _syncPal->_executorWorker->affectedUpdateTree(syncOp)); + CPPUNIT_ASSERT_EQUAL(std::shared_ptr(nullptr), _executorWorker->affectedUpdateTree(syncOp)); } void TestExecutorWorker::testTargetUpdateTree() { // Normal cases auto syncOp = std::make_shared(); syncOp->setTargetSide(ReplicaSide::Local); - CPPUNIT_ASSERT_EQUAL(ReplicaSide::Local, _syncPal->_executorWorker->targetUpdateTree(syncOp)->side()); + CPPUNIT_ASSERT_EQUAL(ReplicaSide::Local, _executorWorker->targetUpdateTree(syncOp)->side()); syncOp->setTargetSide(ReplicaSide::Remote); - CPPUNIT_ASSERT_EQUAL(ReplicaSide::Remote, _syncPal->_executorWorker->targetUpdateTree(syncOp)->side()); + CPPUNIT_ASSERT_EQUAL(ReplicaSide::Remote, _executorWorker->targetUpdateTree(syncOp)->side()); // ReplicaSide::Unknown case syncOp->setTargetSide(ReplicaSide::Unknown); - CPPUNIT_ASSERT_EQUAL(std::shared_ptr(nullptr), _syncPal->_executorWorker->targetUpdateTree(syncOp)); + CPPUNIT_ASSERT_EQUAL(std::shared_ptr(nullptr), _executorWorker->targetUpdateTree(syncOp)); } void TestExecutorWorker::testRemoveDependentOps() { @@ -294,8 +388,8 @@ void TestExecutorWorker::testRemoveDependentOps() { _syncPal->_syncOps->pushOp(op2Create); _syncPal->_syncOps->pushOp(op3Create); - _syncPal->_executorWorker->_opList = _syncPal->_syncOps->opSortedList(); - _syncPal->_executorWorker->removeDependentOps(op1Create); // op1Create failed, we should remove op2Create and op3Create. + _executorWorker->_opList = _syncPal->_syncOps->opSortedList(); + _executorWorker->removeDependentOps(op1Create); // op1Create failed, we should remove op2Create and op3Create. CPPUNIT_ASSERT(opsExist(op1Create)); CPPUNIT_ASSERT(!opsExist(op2Create)); @@ -326,8 +420,8 @@ void TestExecutorWorker::testRemoveDependentOps() { _syncPal->_syncOps->pushOp(op1Create); _syncPal->_syncOps->pushOp(op2Move); - _syncPal->_executorWorker->_opList = _syncPal->_syncOps->opSortedList(); - _syncPal->_executorWorker->removeDependentOps(op1Create); // op2Move failed, we should remove op2Edit. + _executorWorker->_opList = _syncPal->_syncOps->opSortedList(); + _executorWorker->removeDependentOps(op1Create); // op2Move failed, we should remove op2Edit. CPPUNIT_ASSERT(opsExist(op1Create)); CPPUNIT_ASSERT(!opsExist(op2Move)); } @@ -360,15 +454,15 @@ void TestExecutorWorker::testRemoveDependentOps() { _syncPal->_syncOps->pushOp(op1Move); _syncPal->_syncOps->pushOp(op2Move); - _syncPal->_executorWorker->_opList = _syncPal->_syncOps->opSortedList(); - _syncPal->_executorWorker->removeDependentOps(op1Move); // op2Move failed, we should remove op2Edit. + _executorWorker->_opList = _syncPal->_syncOps->opSortedList(); + _executorWorker->removeDependentOps(op1Move); // op2Move failed, we should remove op2Edit. CPPUNIT_ASSERT(opsExist(op1Move)); CPPUNIT_ASSERT(!opsExist(op2Move)); } } bool TestExecutorWorker::opsExist(SyncOpPtr op) { - for (const auto &opId: _syncPal->_executorWorker->_opList) { + for (const auto &opId: _executorWorker->_opList) { if (_syncPal->_syncOps->getOp(opId) == op) { return true; } diff --git a/test/libsyncengine/propagation/executor/testexecutorworker.h b/test/libsyncengine/propagation/executor/testexecutorworker.h index 316590112..16adc6255 100644 --- a/test/libsyncengine/propagation/executor/testexecutorworker.h +++ b/test/libsyncengine/propagation/executor/testexecutorworker.h @@ -51,9 +51,12 @@ class TestExecutorWorker : public CppUnit::TestFixture { bool opsExist(SyncOpPtr op); SyncOpPtr generateSyncOperation(const DbNodeId dbNodeId, const SyncName &filename, const OperationType opType = OperationType::None); + SyncOpPtr generateSyncOperationWithNestedNodes(const DbNodeId dbNodeId, const SyncName &filename, + const OperationType opType, const NodeType nodeType); std::shared_ptr _syncPal; Sync _sync; + std::shared_ptr _executorWorker; LocalTemporaryDirectory _localTempDir{"TestExecutorWorker"}; }; From 5f68f9c112e15b33e41bd3b9febce83078ac003a Mon Sep 17 00:00:00 2001 From: Luc Guyot Date: Wed, 13 Nov 2024 16:49:45 +0100 Subject: [PATCH 092/178] Fixes Windows build error caused by unhandled string conversion --- .../propagation/executor/testexecutorworker.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/libsyncengine/propagation/executor/testexecutorworker.cpp b/test/libsyncengine/propagation/executor/testexecutorworker.cpp index 7a1fecb36..68fd8a6ae 100644 --- a/test/libsyncengine/propagation/executor/testexecutorworker.cpp +++ b/test/libsyncengine/propagation/executor/testexecutorworker.cpp @@ -186,13 +186,13 @@ SyncOpPtr TestExecutorWorker::generateSyncOperationWithNestedNodes(const DbNodeI "local_parent_id", testhelpers::defaultTime, testhelpers::defaultTime, testhelpers::defaultFileSize, _syncPal->updateTree(ReplicaSide::Local)->rootNode()); - auto node = - std::make_shared(dbNodeId, ReplicaSide::Local, "test_file.txt", nodeType, OperationType::None, "local_child_id", - testhelpers::defaultTime, testhelpers::defaultTime, testhelpers::defaultFileSize, parentNode); + auto node = std::make_shared(dbNodeId, ReplicaSide::Local, Str("test_file.txt"), nodeType, OperationType::None, + "local_child_id", testhelpers::defaultTime, testhelpers::defaultTime, + testhelpers::defaultFileSize, parentNode); auto correspondingNode = - std::make_shared(dbNodeId, ReplicaSide::Remote, "test_file.txt", nodeType, OperationType::None, + std::make_shared(dbNodeId, ReplicaSide::Remote, Str("test_file.txt"), nodeType, OperationType::None, "remote_child_id", testhelpers::defaultTime, testhelpers::defaultTime, testhelpers::defaultFileSize, _syncPal->updateTree(ReplicaSide::Remote)->rootNode()); From 6fb01589e4efd738f963c05a3e59dc91f201ee3f Mon Sep 17 00:00:00 2001 From: Luc Guyot Date: Wed, 13 Nov 2024 17:10:47 +0100 Subject: [PATCH 093/178] Fixes another string conversion causing a build error on Windows --- .../propagation/executor/testexecutorworker.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/libsyncengine/propagation/executor/testexecutorworker.cpp b/test/libsyncengine/propagation/executor/testexecutorworker.cpp index 68fd8a6ae..1246a965f 100644 --- a/test/libsyncengine/propagation/executor/testexecutorworker.cpp +++ b/test/libsyncengine/propagation/executor/testexecutorworker.cpp @@ -258,9 +258,9 @@ void TestExecutorWorker::testIsValidDestination() { // False if the item is created on the local replica is not at the root of the synchronisation folder and has a // corresponding parent node with no id. { - const auto correspondingParentNode = std::make_shared(666, ReplicaSide::Remote, "parent_dir", NodeType::Directory, - OperationType::None, std::nullopt, testhelpers::defaultTime, - testhelpers::defaultTime, testhelpers::defaultFileSize, root); + const auto correspondingParentNode = std::make_shared( + 666, ReplicaSide::Remote, Str("parent_dir"), NodeType::Directory, OperationType::None, std::nullopt, + testhelpers::defaultTime, testhelpers::defaultTime, testhelpers::defaultFileSize, root); SyncOpPtr op = generateSyncOperationWithNestedNodes(1, Str("test_file.txt"), OperationType::Create, NodeType::File); From 28aae8d5142d571a5ab816fd21a730e5fe993b85 Mon Sep 17 00:00:00 2001 From: Luc Guyot Date: Mon, 18 Nov 2024 16:47:05 +0100 Subject: [PATCH 094/178] =?UTF-8?q?Addresses=20Cl=C3=A9ment's=20comment:?= =?UTF-8?q?=20adds=20unit=20tests=20for=20the=20case=20where=20Shared=20is?= =?UTF-8?q?=20a=20corresponding=20parent=20node?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../executor/testexecutorworker.cpp | 28 ++++++++++++++++--- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/test/libsyncengine/propagation/executor/testexecutorworker.cpp b/test/libsyncengine/propagation/executor/testexecutorworker.cpp index 1246a965f..ee3d05a5f 100644 --- a/test/libsyncengine/propagation/executor/testexecutorworker.cpp +++ b/test/libsyncengine/propagation/executor/testexecutorworker.cpp @@ -244,7 +244,7 @@ void TestExecutorWorker::testIsValidDestination() { const auto executorWorkerMock = std::shared_ptr(new ExecutorWorkerMock(_syncPal, "Executor", "EXEC")); - // False if the item is created on the local replica is not at the root of the synchronisation folder and has no + // False if the item created on the local replica is not at the root of the synchronisation folder and has no // corresponding parent node. { SyncOpPtr op = generateSyncOperationWithNestedNodes(1, Str("test_file.txt"), OperationType::Create, NodeType::File); @@ -255,7 +255,7 @@ void TestExecutorWorker::testIsValidDestination() { const auto root = _syncPal->updateTree(ReplicaSide::Remote)->rootNode(); - // False if the item is created on the local replica is not at the root of the synchronisation folder and has a + // False if the item created on the local replica is not at the root of the synchronisation folder and has a // corresponding parent node with no id. { const auto correspondingParentNode = std::make_shared( @@ -273,7 +273,7 @@ void TestExecutorWorker::testIsValidDestination() { 666, ReplicaSide::Remote, Utility::commonDocumentsFolderName(), NodeType::Directory, OperationType::None, "common_docs_id", testhelpers::defaultTime, testhelpers::defaultTime, testhelpers::defaultFileSize, root); - // False if the item is created on the local replica is a file and has Common Documents as corresponding parent node. + // False if the item created on the local replica is a file and has Common Documents as corresponding parent node. { SyncOpPtr op = generateSyncOperationWithNestedNodes(1, Str("test_file.txt"), OperationType::Create, NodeType::File); op->setTargetSide(ReplicaSide::Remote); @@ -282,7 +282,7 @@ void TestExecutorWorker::testIsValidDestination() { CPPUNIT_ASSERT(!executorWorkerMock->isValidDestination(op)); } - // True if the item is created on the local replica is a directory and has Common Documents as corresponding parent node. + // True if the item created on the local replica is a directory and has Common Documents as corresponding parent node. { SyncOpPtr op = generateSyncOperationWithNestedNodes(1, Str("test_dir"), OperationType::Create, NodeType::Directory); op->setTargetSide(ReplicaSide::Remote); @@ -290,6 +290,26 @@ void TestExecutorWorker::testIsValidDestination() { {{op->affectedNode()->parentNode(), correspondingParentCommonDocsNode}}); CPPUNIT_ASSERT(executorWorkerMock->isValidDestination(op)); } + + const auto correspondingParentSharedNode = std::make_shared( + 777, ReplicaSide::Remote, Utility::sharedFolderName(), NodeType::Directory, OperationType::None, "shared_id", + testhelpers::defaultTime, testhelpers::defaultTime, testhelpers::defaultFileSize, root); + + // False if the item is created on the local replica is a file and has Shared as corresponding parent node. + { + SyncOpPtr op = generateSyncOperationWithNestedNodes(1, Str("test_file.txt"), OperationType::Create, NodeType::File); + op->setTargetSide(ReplicaSide::Remote); + executorWorkerMock->setCorrespondingNodeInOtherTree({{op->affectedNode()->parentNode(), correspondingParentSharedNode}}); + CPPUNIT_ASSERT(!executorWorkerMock->isValidDestination(op)); + } + + // False if the item created on the local replica is a directory and has Shared as corresponding parent node. + { + SyncOpPtr op = generateSyncOperationWithNestedNodes(1, Str("test_dir"), OperationType::Create, NodeType::Directory); + op->setTargetSide(ReplicaSide::Remote); + executorWorkerMock->setCorrespondingNodeInOtherTree({{op->affectedNode()->parentNode(), correspondingParentSharedNode}}); + CPPUNIT_ASSERT(!executorWorkerMock->isValidDestination(op)); + } } void TestExecutorWorker::testLogCorrespondingNodeErrorMsg() { From 280810c49d60fb9d986651e9f0aaa8019cedf38d Mon Sep 17 00:00:00 2001 From: Herve Eruam Date: Mon, 18 Nov 2024 17:13:37 +0100 Subject: [PATCH 095/178] Add unit tests for uploadjob and driveuploadsessions. --- .../jobs/network/testnetworkjobs.cpp | 91 ++++++++++++++++--- 1 file changed, 77 insertions(+), 14 deletions(-) diff --git a/test/libsyncengine/jobs/network/testnetworkjobs.cpp b/test/libsyncengine/jobs/network/testnetworkjobs.cpp index fd48b5d7c..53b72907f 100644 --- a/test/libsyncengine/jobs/network/testnetworkjobs.cpp +++ b/test/libsyncengine/jobs/network/testnetworkjobs.cpp @@ -649,26 +649,57 @@ void TestNetworkJobs::testRename() { } void TestNetworkJobs::testUpload() { - const RemoteTemporaryDirectory remoteTmpDir(_driveDbId, _remoteDirId, "testUpload"); - SyncPath localFilePath = testhelpers::localTestDirPath / bigFileDirName / bigFileName; + { + const RemoteTemporaryDirectory remoteTmpDir(_driveDbId, _remoteDirId, "testUpload"); + SyncPath localFilePath = testhelpers::localTestDirPath / bigFileDirName / bigFileName; - UploadJob job(_driveDbId, localFilePath, localFilePath.filename().native(), remoteTmpDir.id(), 0); - ExitCode exitCode = job.runSynchronously(); - CPPUNIT_ASSERT(exitCode == ExitCode::Ok); + UploadJob job(_driveDbId, localFilePath, localFilePath.filename().native(), remoteTmpDir.id(), 0); + ExitCode exitCode = job.runSynchronously(); + CPPUNIT_ASSERT(exitCode == ExitCode::Ok); - NodeId newNodeId = job.nodeId(); + NodeId newNodeId = job.nodeId(); - GetFileInfoJob fileInfoJob(_driveDbId, newNodeId); - exitCode = fileInfoJob.runSynchronously(); - CPPUNIT_ASSERT(exitCode == ExitCode::Ok); + GetFileInfoJob fileInfoJob(_driveDbId, newNodeId); + exitCode = fileInfoJob.runSynchronously(); + CPPUNIT_ASSERT(exitCode == ExitCode::Ok); - Poco::JSON::Object::Ptr dataObj = fileInfoJob.jsonRes()->getObject(dataKey); - std::string name; - if (dataObj) { - name = dataObj->get(nameKey).toString(); + Poco::JSON::Object::Ptr dataObj = fileInfoJob.jsonRes()->getObject(dataKey); + std::string name; + if (dataObj) { + name = dataObj->get(nameKey).toString(); + } + CPPUNIT_ASSERT(name == bigFileName); + } + { + const RemoteTemporaryDirectory remoteTmpDir(_driveDbId, _remoteDirId, "testUpload"); + const LocalTemporaryDirectory localTmpDir("testUpload"); + const SyncPath localDestFilePath = localTmpDir.path() / bigFileName; + testhelpers::generateOrEditTestFile(localDestFilePath); + IoError ioError = IoError::Unknown; + IoHelper::setRights(localDestFilePath, false, false, false, ioError); + CPPUNIT_ASSERT_EQUAL(IoError::Success, ioError); + + UploadJob job(_driveDbId, localDestFilePath, localDestFilePath.filename().native(), remoteTmpDir.id(), 0); + ExitCode exitCode = job.runSynchronously(); + CPPUNIT_ASSERT_EQUAL(ExitCode::SystemError, exitCode); + CPPUNIT_ASSERT_EQUAL(ExitCause::FileAccessError, job.exitCause()); + } + { + const RemoteTemporaryDirectory remoteTmpDir(_driveDbId, _remoteDirId, "testUpload"); + const LocalTemporaryDirectory localTmpDir("testUpload"); + const SyncPath localDestFilePath = localTmpDir.path() / bigFileName; + testhelpers::generateOrEditTestFile(localDestFilePath); + + UploadJob job(_driveDbId, localDestFilePath, localDestFilePath.filename().native(), remoteTmpDir.id(), 0); + IoError ioErrror = IoError::Unknown; + IoHelper::deleteItem(localDestFilePath, ioErrror); + CPPUNIT_ASSERT_EQUAL(IoError::Success, ioErrror); + + ExitCode exitCode = job.runSynchronously(); + CPPUNIT_ASSERT_EQUAL(ExitCode::SystemError, exitCode); + CPPUNIT_ASSERT_EQUAL(ExitCause::NotFound, job.exitCause()); } - CPPUNIT_ASSERT(name == bigFileName); } void TestNetworkJobs::testUploadAborted() { @@ -750,6 +781,38 @@ void TestNetworkJobs::testDriveUploadSessionSynchronous() { int64_t fileSizeRemote = fileSizeJob.size(); CPPUNIT_ASSERT_EQUAL(static_cast(fileSizeLocal), fileSizeRemote); + + // A file with no rights + LOGW_DEBUG(Log::instance()->getLogger(), L"$$$$$ testDriveUploadSessionSynchronous No rights"); + const SyncPath localFilePathNoRights = localTmpDir.path() / "no_rights.txt"; + testhelpers::generateOrEditTestFile(localFilePathNoRights); + IoHelper::setRights(localFilePathNoRights, false, false, false, ioError); + CPPUNIT_ASSERT_EQUAL(IoError::Success, ioError); + + DriveUploadSession driveUploadSessionJobNoRights(_driveDbId, nullptr, localFilePathNoRights, + localFilePathNoRights.filename().native(), remoteTmpDir.id(), 12345, false, + 1); + exitCode = driveUploadSessionJobNoRights.runSynchronously(); + CPPUNIT_ASSERT_EQUAL(ExitCode::SystemError, exitCode); + CPPUNIT_ASSERT_EQUAL(ExitCause::FileAccessError, driveUploadSessionJobNoRights.exitCause()); + + // A file removed + LOGW_DEBUG(Log::instance()->getLogger(), L"$$$$$ testDriveUploadSessionSynchronous Removed"); + const SyncPath localFilePathRemoved = localTmpDir.path() / "removed.txt"; + testhelpers::generateOrEditTestFile(localFilePathRemoved); + DriveUploadSession driveUploadSessionJobRemoved(_driveDbId, nullptr, localFilePathRemoved, + localFilePathRemoved.filename().native(), remoteTmpDir.id(), 12345, false, + 1); + + IoError ioErrror = IoError::Unknown; + IoHelper::deleteItem(localFilePathRemoved, ioErrror); + CPPUNIT_ASSERT_EQUAL(IoError::Success, ioErrror); + + exitCode = driveUploadSessionJobRemoved.runSynchronously(); + CPPUNIT_ASSERT_EQUAL(ExitCode::SystemError, exitCode); + CPPUNIT_ASSERT_EQUAL(ExitCause::NotFound, driveUploadSessionJobRemoved.exitCause()); + + } void TestNetworkJobs::testDriveUploadSessionAsynchronous() { From 694e5171c491b0359e5da359088e7e8d61a84fad Mon Sep 17 00:00:00 2001 From: Herve Eruam Date: Mon, 18 Nov 2024 17:13:37 +0100 Subject: [PATCH 096/178] Add unit tests for uploadjob and driveuploadsessions. --- .../upload_session/abstractuploadsession.cpp | 7 +- .../jobs/network/API_v2/uploadjob.cpp | 6 +- .../jobs/network/testnetworkjobs.cpp | 117 +++++++++++++++--- 3 files changed, 109 insertions(+), 21 deletions(-) diff --git a/src/libsyncengine/jobs/network/API_v2/upload_session/abstractuploadsession.cpp b/src/libsyncengine/jobs/network/API_v2/upload_session/abstractuploadsession.cpp index 24b854367..221ee2742 100644 --- a/src/libsyncengine/jobs/network/API_v2/upload_session/abstractuploadsession.cpp +++ b/src/libsyncengine/jobs/network/API_v2/upload_session/abstractuploadsession.cpp @@ -179,10 +179,9 @@ bool AbstractUploadSession::canRun() { } if (!exists) { - LOGW_DEBUG(_logger, - L"Item does not exist anymore. Aborting current sync and restart. - path=" << Path2WStr(_filePath).c_str()); - _exitCode = ExitCode::NeedRestart; - _exitCause = ExitCause::UnexpectedFileSystemEvent; + LOGW_DEBUG(_logger, L"Item does not exist anymore " << Utility::formatSyncPath(_filePath.filename())); + _exitCode = ExitCode::SystemError; + _exitCause = ExitCause::NotFound; return false; } diff --git a/src/libsyncengine/jobs/network/API_v2/uploadjob.cpp b/src/libsyncengine/jobs/network/API_v2/uploadjob.cpp index 63b3b19b3..a9558edff 100644 --- a/src/libsyncengine/jobs/network/API_v2/uploadjob.cpp +++ b/src/libsyncengine/jobs/network/API_v2/uploadjob.cpp @@ -79,9 +79,9 @@ bool UploadJob::canRun() { } if (!exists) { - LOGW_DEBUG(_logger, L"Item does not exist anymore. Aborting current sync and restart - path=" << Path2WStr(_filePath)); - _exitCode = ExitCode::NeedRestart; - _exitCause = ExitCause::UnexpectedFileSystemEvent; + LOGW_DEBUG(_logger, L"Item does not exist anymore " << Utility::formatSyncPath(_filePath)); + _exitCode = ExitCode::SystemError; + _exitCause = ExitCause::NotFound; return false; } diff --git a/test/libsyncengine/jobs/network/testnetworkjobs.cpp b/test/libsyncengine/jobs/network/testnetworkjobs.cpp index fd48b5d7c..3c4b62cad 100644 --- a/test/libsyncengine/jobs/network/testnetworkjobs.cpp +++ b/test/libsyncengine/jobs/network/testnetworkjobs.cpp @@ -649,26 +649,72 @@ void TestNetworkJobs::testRename() { } void TestNetworkJobs::testUpload() { - const RemoteTemporaryDirectory remoteTmpDir(_driveDbId, _remoteDirId, "testUpload"); + { + const RemoteTemporaryDirectory remoteTmpDir(_driveDbId, _remoteDirId, "testUpload"); + SyncPath localFilePath = testhelpers::localTestDirPath / bigFileDirName / bigFileName; - SyncPath localFilePath = testhelpers::localTestDirPath / bigFileDirName / bigFileName; + UploadJob job(_driveDbId, localFilePath, localFilePath.filename().native(), remoteTmpDir.id(), 0); + ExitCode exitCode = job.runSynchronously(); + CPPUNIT_ASSERT(exitCode == ExitCode::Ok); - UploadJob job(_driveDbId, localFilePath, localFilePath.filename().native(), remoteTmpDir.id(), 0); - ExitCode exitCode = job.runSynchronously(); - CPPUNIT_ASSERT(exitCode == ExitCode::Ok); + NodeId newNodeId = job.nodeId(); - NodeId newNodeId = job.nodeId(); + GetFileInfoJob fileInfoJob(_driveDbId, newNodeId); + exitCode = fileInfoJob.runSynchronously(); + CPPUNIT_ASSERT(exitCode == ExitCode::Ok); - GetFileInfoJob fileInfoJob(_driveDbId, newNodeId); - exitCode = fileInfoJob.runSynchronously(); - CPPUNIT_ASSERT(exitCode == ExitCode::Ok); + Poco::JSON::Object::Ptr dataObj = fileInfoJob.jsonRes()->getObject(dataKey); + std::string name; + if (dataObj) { + name = dataObj->get(nameKey).toString(); + } + CPPUNIT_ASSERT(name == bigFileName); + } + { + const RemoteTemporaryDirectory remoteTmpDir(_driveDbId, _remoteDirId, "testUpload"); + const LocalTemporaryDirectory localTmpDir("testUpload"); + const SyncPath localDestFilePath = localTmpDir.path() / bigFileName; + testhelpers::generateOrEditTestFile(localDestFilePath); + IoError ioError = IoError::Unknown; + IoHelper::setRights(localDestFilePath, false, false, false, ioError); + CPPUNIT_ASSERT_EQUAL(IoError::Success, ioError); + + UploadJob job(_driveDbId, localDestFilePath, localDestFilePath.filename().native(), remoteTmpDir.id(), 0); + ExitCode exitCode = job.runSynchronously(); + CPPUNIT_ASSERT_EQUAL(ExitCode::SystemError, exitCode); + CPPUNIT_ASSERT_EQUAL(ExitCause::FileAccessError, job.exitCause()); + } + { + const RemoteTemporaryDirectory remoteTmpDir(_driveDbId, _remoteDirId, "testUpload"); + const LocalTemporaryDirectory localTmpDir("testUpload"); + const SyncPath localDestFilePath = localTmpDir.path() / "removed.txt"; + testhelpers::generateOrEditTestFile(localDestFilePath); - Poco::JSON::Object::Ptr dataObj = fileInfoJob.jsonRes()->getObject(dataKey); - std::string name; - if (dataObj) { - name = dataObj->get(nameKey).toString(); + UploadJob job(_driveDbId, localDestFilePath, localDestFilePath.filename().native(), remoteTmpDir.id(), 0); + IoError ioErrror = IoError::Unknown; + + IoError ioError = IoError::Unknown; + IoHelper::setRights(localDestFilePath, false, false, false, ioError); + CPPUNIT_ASSERT_EQUAL(IoError::Success, ioError); + + Utility::msleep(1000); // Wait 1sec + + IoHelper::deleteItem(localDestFilePath, ioErrror); + CPPUNIT_ASSERT_EQUAL(IoError::Success, ioErrror); + + ExitCode exitCode = job.runSynchronously(); + CPPUNIT_ASSERT_EQUAL(ExitCode::SystemError, exitCode); + CPPUNIT_ASSERT_EQUAL(ExitCause::NotFound, job.exitCause()); + } + { + const RemoteTemporaryDirectory remoteTmpDir(_driveDbId, _remoteDirId, "testUpload"); + const LocalTemporaryDirectory localTmpDir("testUpload"); + const SyncPath localDestFilePath = localTmpDir.path() / "non_existing.txt"; + UploadJob job(_driveDbId, localDestFilePath, localDestFilePath.filename().native(), remoteTmpDir.id(), 0); + ExitCode exitCode = job.runSynchronously(); + CPPUNIT_ASSERT_EQUAL(ExitCode::SystemError, exitCode); + CPPUNIT_ASSERT_EQUAL(ExitCause::NotFound, job.exitCause()); } - CPPUNIT_ASSERT(name == bigFileName); } void TestNetworkJobs::testUploadAborted() { @@ -750,6 +796,49 @@ void TestNetworkJobs::testDriveUploadSessionSynchronous() { int64_t fileSizeRemote = fileSizeJob.size(); CPPUNIT_ASSERT_EQUAL(static_cast(fileSizeLocal), fileSizeRemote); + + // A file with no rights + LOGW_DEBUG(Log::instance()->getLogger(), L"$$$$$ testDriveUploadSessionSynchronous No rights"); + const SyncPath localFilePathNoRights = localTmpDir.path() / "no_rights.txt"; + testhelpers::generateOrEditTestFile(localFilePathNoRights); + IoHelper::setRights(localFilePathNoRights, false, true, true, ioError); + CPPUNIT_ASSERT_EQUAL(IoError::Success, ioError); + + DriveUploadSession driveUploadSessionJobNoRights(_driveDbId, nullptr, localFilePathNoRights, + localFilePathNoRights.filename().native(), remoteTmpDir.id(), 12345, false, + 1); + exitCode = driveUploadSessionJobNoRights.runSynchronously(); + CPPUNIT_ASSERT_EQUAL(ExitCode::SystemError, exitCode); + CPPUNIT_ASSERT_EQUAL(ExitCause::FileAccessError, driveUploadSessionJobNoRights.exitCause()); + + // A file removed + LOGW_DEBUG(Log::instance()->getLogger(), L"$$$$$ testDriveUploadSessionSynchronous Removed"); + const SyncPath localFilePathRemoved = localTmpDir.path() / "removed.txt"; + testhelpers::generateOrEditTestFile(localFilePathRemoved); + DriveUploadSession driveUploadSessionJobRemoved(_driveDbId, nullptr, localFilePathRemoved, + localFilePathRemoved.filename().native(), remoteTmpDir.id(), 12345, false, 1); + IoHelper::setRights(localFilePathNoRights, false, true, true, ioError); + CPPUNIT_ASSERT_EQUAL(IoError::Success, ioError); + + Utility::msleep(1000); // Wait 1sec + + IoError ioErrror = IoError::Unknown; + IoHelper::deleteItem(localFilePathRemoved, ioErrror); + CPPUNIT_ASSERT_EQUAL(IoError::Success, ioErrror); + + exitCode = driveUploadSessionJobRemoved.runSynchronously(); + CPPUNIT_ASSERT_EQUAL(ExitCode::SystemError, exitCode); + CPPUNIT_ASSERT_EQUAL(ExitCause::NotFound, driveUploadSessionJobRemoved.exitCause()); + + // A non existing file + LOGW_DEBUG(Log::instance()->getLogger(), L"$$$$$ testDriveUploadSessionSynchronous Non existing"); + const SyncPath localFilePathNonExisting = localTmpDir.path() / "non_existing.txt"; + DriveUploadSession driveUploadSessionJobNonExisting(_driveDbId, nullptr, localFilePathNonExisting, + localFilePathNonExisting.filename().native(), remoteTmpDir.id(), 12345, + false, 1); + exitCode = driveUploadSessionJobNonExisting.runSynchronously(); + CPPUNIT_ASSERT_EQUAL(ExitCode::SystemError, exitCode); + CPPUNIT_ASSERT_EQUAL(ExitCause::NotFound, driveUploadSessionJobNonExisting.exitCause()); } void TestNetworkJobs::testDriveUploadSessionAsynchronous() { From caffabfa29e4c2e3ed4c2bec1bfc4a4a2b89728a Mon Sep 17 00:00:00 2001 From: Herve Eruam Date: Mon, 18 Nov 2024 17:53:39 +0100 Subject: [PATCH 097/178] Fix tests. --- .../jobs/network/testnetworkjobs.cpp | 68 ++----------------- 1 file changed, 4 insertions(+), 64 deletions(-) diff --git a/test/libsyncengine/jobs/network/testnetworkjobs.cpp b/test/libsyncengine/jobs/network/testnetworkjobs.cpp index 3c4b62cad..92fa48a8c 100644 --- a/test/libsyncengine/jobs/network/testnetworkjobs.cpp +++ b/test/libsyncengine/jobs/network/testnetworkjobs.cpp @@ -649,7 +649,7 @@ void TestNetworkJobs::testRename() { } void TestNetworkJobs::testUpload() { - { + { // Test upload const RemoteTemporaryDirectory remoteTmpDir(_driveDbId, _remoteDirId, "testUpload"); SyncPath localFilePath = testhelpers::localTestDirPath / bigFileDirName / bigFileName; @@ -670,13 +670,13 @@ void TestNetworkJobs::testUpload() { } CPPUNIT_ASSERT(name == bigFileName); } - { + { // Test upload with a file that has no read rights const RemoteTemporaryDirectory remoteTmpDir(_driveDbId, _remoteDirId, "testUpload"); const LocalTemporaryDirectory localTmpDir("testUpload"); - const SyncPath localDestFilePath = localTmpDir.path() / bigFileName; + const SyncPath localDestFilePath = localTmpDir.path() / "no_rights.txt"; testhelpers::generateOrEditTestFile(localDestFilePath); IoError ioError = IoError::Unknown; - IoHelper::setRights(localDestFilePath, false, false, false, ioError); + IoHelper::setRights(localDestFilePath, false, true, true, ioError); CPPUNIT_ASSERT_EQUAL(IoError::Success, ioError); UploadJob job(_driveDbId, localDestFilePath, localDestFilePath.filename().native(), remoteTmpDir.id(), 0); @@ -684,37 +684,6 @@ void TestNetworkJobs::testUpload() { CPPUNIT_ASSERT_EQUAL(ExitCode::SystemError, exitCode); CPPUNIT_ASSERT_EQUAL(ExitCause::FileAccessError, job.exitCause()); } - { - const RemoteTemporaryDirectory remoteTmpDir(_driveDbId, _remoteDirId, "testUpload"); - const LocalTemporaryDirectory localTmpDir("testUpload"); - const SyncPath localDestFilePath = localTmpDir.path() / "removed.txt"; - testhelpers::generateOrEditTestFile(localDestFilePath); - - UploadJob job(_driveDbId, localDestFilePath, localDestFilePath.filename().native(), remoteTmpDir.id(), 0); - IoError ioErrror = IoError::Unknown; - - IoError ioError = IoError::Unknown; - IoHelper::setRights(localDestFilePath, false, false, false, ioError); - CPPUNIT_ASSERT_EQUAL(IoError::Success, ioError); - - Utility::msleep(1000); // Wait 1sec - - IoHelper::deleteItem(localDestFilePath, ioErrror); - CPPUNIT_ASSERT_EQUAL(IoError::Success, ioErrror); - - ExitCode exitCode = job.runSynchronously(); - CPPUNIT_ASSERT_EQUAL(ExitCode::SystemError, exitCode); - CPPUNIT_ASSERT_EQUAL(ExitCause::NotFound, job.exitCause()); - } - { - const RemoteTemporaryDirectory remoteTmpDir(_driveDbId, _remoteDirId, "testUpload"); - const LocalTemporaryDirectory localTmpDir("testUpload"); - const SyncPath localDestFilePath = localTmpDir.path() / "non_existing.txt"; - UploadJob job(_driveDbId, localDestFilePath, localDestFilePath.filename().native(), remoteTmpDir.id(), 0); - ExitCode exitCode = job.runSynchronously(); - CPPUNIT_ASSERT_EQUAL(ExitCode::SystemError, exitCode); - CPPUNIT_ASSERT_EQUAL(ExitCause::NotFound, job.exitCause()); - } } void TestNetworkJobs::testUploadAborted() { @@ -810,35 +779,6 @@ void TestNetworkJobs::testDriveUploadSessionSynchronous() { exitCode = driveUploadSessionJobNoRights.runSynchronously(); CPPUNIT_ASSERT_EQUAL(ExitCode::SystemError, exitCode); CPPUNIT_ASSERT_EQUAL(ExitCause::FileAccessError, driveUploadSessionJobNoRights.exitCause()); - - // A file removed - LOGW_DEBUG(Log::instance()->getLogger(), L"$$$$$ testDriveUploadSessionSynchronous Removed"); - const SyncPath localFilePathRemoved = localTmpDir.path() / "removed.txt"; - testhelpers::generateOrEditTestFile(localFilePathRemoved); - DriveUploadSession driveUploadSessionJobRemoved(_driveDbId, nullptr, localFilePathRemoved, - localFilePathRemoved.filename().native(), remoteTmpDir.id(), 12345, false, 1); - IoHelper::setRights(localFilePathNoRights, false, true, true, ioError); - CPPUNIT_ASSERT_EQUAL(IoError::Success, ioError); - - Utility::msleep(1000); // Wait 1sec - - IoError ioErrror = IoError::Unknown; - IoHelper::deleteItem(localFilePathRemoved, ioErrror); - CPPUNIT_ASSERT_EQUAL(IoError::Success, ioErrror); - - exitCode = driveUploadSessionJobRemoved.runSynchronously(); - CPPUNIT_ASSERT_EQUAL(ExitCode::SystemError, exitCode); - CPPUNIT_ASSERT_EQUAL(ExitCause::NotFound, driveUploadSessionJobRemoved.exitCause()); - - // A non existing file - LOGW_DEBUG(Log::instance()->getLogger(), L"$$$$$ testDriveUploadSessionSynchronous Non existing"); - const SyncPath localFilePathNonExisting = localTmpDir.path() / "non_existing.txt"; - DriveUploadSession driveUploadSessionJobNonExisting(_driveDbId, nullptr, localFilePathNonExisting, - localFilePathNonExisting.filename().native(), remoteTmpDir.id(), 12345, - false, 1); - exitCode = driveUploadSessionJobNonExisting.runSynchronously(); - CPPUNIT_ASSERT_EQUAL(ExitCode::SystemError, exitCode); - CPPUNIT_ASSERT_EQUAL(ExitCause::NotFound, driveUploadSessionJobNonExisting.exitCause()); } void TestNetworkJobs::testDriveUploadSessionAsynchronous() { From cd2f4b15ebcb9f3ccb89ece1e230f59efa4e3c81 Mon Sep 17 00:00:00 2001 From: Herve Eruam Date: Mon, 18 Nov 2024 17:55:09 +0100 Subject: [PATCH 098/178] Remove build file. --- .../testnetworkjobs.cpp | 1119 ----------------- 1 file changed, 1119 deletions(-) delete mode 100644 enc_temp_folder/e1bd41f957b0cb1fb4d729307c2c54d0/testnetworkjobs.cpp diff --git a/enc_temp_folder/e1bd41f957b0cb1fb4d729307c2c54d0/testnetworkjobs.cpp b/enc_temp_folder/e1bd41f957b0cb1fb4d729307c2c54d0/testnetworkjobs.cpp deleted file mode 100644 index d6c96a405..000000000 --- a/enc_temp_folder/e1bd41f957b0cb1fb4d729307c2c54d0/testnetworkjobs.cpp +++ /dev/null @@ -1,1119 +0,0 @@ -/* - * Infomaniak kDrive - Desktop - * Copyright (C) 2023-2024 Infomaniak Network SA - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "testnetworkjobs.h" -#include "jobs/network/API_v2/copytodirectoryjob.h" -#include "jobs/network/API_v2/createdirjob.h" -#include "jobs/network/API_v2/deletejob.h" -#include "jobs/network/API_v2/downloadjob.h" -#include "jobs/network/API_v2/duplicatejob.h" -#include "jobs/network/API_v2/csvfullfilelistwithcursorjob.h" -#include "jobs/network/getavatarjob.h" -#include "jobs/network/API_v2/getdriveslistjob.h" -#include "jobs/network/API_v2/getfileinfojob.h" -#include "jobs/network/API_v2/getfilelistjob.h" -#include "jobs/network/API_v2/initfilelistwithcursorjob.h" -#include "jobs/network/API_v2/getinfouserjob.h" -#include "jobs/network/API_v2/getinfodrivejob.h" -#include "jobs/network/API_v2/getthumbnailjob.h" -#include "jobs/network/API_v2/jsonfullfilelistwithcursorjob.h" -#include "jobs/network/API_v2/movejob.h" -#include "jobs/network/API_v2/renamejob.h" -#include "jobs/network/API_v2/upload_session/driveuploadsession.h" -#include "jobs/network/API_v2/upload_session/loguploadsession.h" -#include "jobs/network/API_v2/uploadjob.h" -#include "jobs/network/API_v2/getsizejob.h" -#include "jobs/jobmanager.h" -#include "network/proxy.h" -#include "libcommon/keychainmanager/keychainmanager.h" -#include "libcommonserver/utility/utility.h" -#include "libcommonserver/io/filestat.h" -#include "libcommonserver/io/iohelper.h" -#include "libparms/db/parmsdb.h" -#include "utility/jsonparserutility.h" -#include "requests/parameterscache.h" -#include "test_utility/localtemporarydirectory.h" -#include "test_utility/remotetemporarydirectory.h" -#include - -#include "jobs/network/getappversionjob.h" -#include "test_utility/testhelpers.h" -#include "jobs/network/directdownloadjob.h" - -using namespace CppUnit; - -namespace KDC { -static const NodeId pictureDirRemoteId = "56851"; // test_ci/test_pictures -static const NodeId picture1RemoteId = "97373"; // test_ci/test_pictures/picture-1.jpg -static const NodeId testFileRemoteId = "97370"; // test_ci/test_networkjobs/test_download.txt -static const NodeId testFileRemoteRenameId = "97376"; // test_ci/test_networkjobs/test_rename*.txt -static const NodeId testBigFileRemoteId = "97601"; // test_ci/big_file_dir/big_text_file.txt -static const NodeId testDummyDirRemoteId = "98648"; // test_ci/dummy_dir -static const NodeId testDummyFileRemoteId = "98649"; // test_ci/dummy_dir/picture.jpg - -static const std::string desktopTeamTestDriveName = "kDrive Desktop Team"; -static const std::string bigFileDirName = "big_file_dir"; -static const std::string bigFileName = "big_text_file.txt"; -static const std::string dummyDirName = "dummy_dir"; -static const std::string dummyFileName = "picture.jpg"; - -uint64_t TestNetworkJobs::_nbParalleleThreads = 10; - -void TestNetworkJobs::setUp() { - LOGW_DEBUG(Log::instance()->getLogger(), L"$$$$$ Set Up"); - - const testhelpers::TestVariables testVariables; - - // Insert api token into keystore - ApiToken apiToken; - apiToken.setAccessToken(testVariables.apiToken); - - const std::string keychainKey("123"); - KeyChainManager::instance(true); - KeyChainManager::instance()->writeToken(keychainKey, apiToken.reconstructJsonString()); - - // Create parmsDb - bool alreadyExists = false; - std::filesystem::path parmsDbPath = Db::makeDbName(alreadyExists, true); - ParmsDb::instance(parmsDbPath, KDRIVE_VERSION_STRING, true, true); - ParametersCache::instance()->parameters().setExtendedLog(true); - - // Insert user, account & drive - const int userId(atoi(testVariables.userId.c_str())); - User user(1, userId, keychainKey); - ParmsDb::instance()->insertUser(user); - _userDbId = user.dbId(); - - const int accountId(atoi(testVariables.accountId.c_str())); - Account account(1, accountId, user.dbId()); - ParmsDb::instance()->insertAccount(account); - - _driveDbId = 1; - const int driveId = atoi(testVariables.driveId.c_str()); - Drive drive(_driveDbId, driveId, account.dbId(), std::string(), 0, std::string()); - ParmsDb::instance()->insertDrive(drive); - - _remoteDirId = testVariables.remoteDirId; - - // Setup proxy - Parameters parameters; - bool found = false; - if (ParmsDb::instance()->selectParameters(parameters, found) && found) { - Proxy::instance(parameters.proxyConfig()); - } -} - -void TestNetworkJobs::tearDown() { - LOGW_DEBUG(Log::instance()->getLogger(), L"$$$$$ Tear Down"); - - if (!_dummyRemoteFileId.empty()) { - DeleteJob job(_driveDbId, _dummyRemoteFileId, "", ""); - job.setBypassCheck(true); - job.runSynchronously(); - } - if (!_dummyLocalFilePath.empty()) std::filesystem::remove_all(_dummyLocalFilePath); - - ParmsDb::instance()->close(); - ParmsDb::reset(); -} - -void TestNetworkJobs::testCreateDir() { - const RemoteTemporaryDirectory remoteTmpDir(_driveDbId, _remoteDirId, "testCreateDir"); - - GetFileListJob fileListJob(_driveDbId, _remoteDirId); - const ExitCode exitCode = fileListJob.runSynchronously(); - CPPUNIT_ASSERT(exitCode == ExitCode::Ok); - - Poco::JSON::Object::Ptr resObj = fileListJob.jsonRes(); - CPPUNIT_ASSERT(resObj); - - bool newDirFound = false; - for (const auto dataArray = resObj->getArray(dataKey); const auto &item: *dataArray) { - const auto &dirObj = item.extract(); - - SyncName name; - CPPUNIT_ASSERT(JsonParserUtility::extractValue(dirObj, nameKey, name)); - - if (remoteTmpDir.name() == name) { - newDirFound = true; - break; - } - } - CPPUNIT_ASSERT(newDirFound); -} - -void TestNetworkJobs::testCopyToDir() { - // Create test dir - const RemoteTemporaryDirectory remoteTmpDir(_driveDbId, _remoteDirId, "testCopyToDir"); - - const SyncName filename = Str("testCopyToDir_") + Str2SyncName(CommonUtility::generateRandomStringAlphaNum()) + Str(".txt"); - CopyToDirectoryJob job(_driveDbId, testFileRemoteId, remoteTmpDir.id(), filename); - ExitCode exitCode = job.runSynchronously(); - CPPUNIT_ASSERT(exitCode == ExitCode::Ok); - - GetFileListJob fileListJob(_driveDbId, remoteTmpDir.id()); - exitCode = fileListJob.runSynchronously(); - CPPUNIT_ASSERT(exitCode == ExitCode::Ok); - - Poco::JSON::Object::Ptr resObj = fileListJob.jsonRes(); - CPPUNIT_ASSERT(resObj); - - bool found = false; - Poco::JSON::Array::Ptr dataArray = resObj->getArray(dataKey); - for (const auto &it: *dataArray) { - Poco::JSON::Object::Ptr dirObj = it.extract(); - if (filename == Str2SyncName(dirObj->get(nameKey))) { - found = true; - break; - } - } - CPPUNIT_ASSERT(found); -} - -void TestNetworkJobs::testDelete() { - CPPUNIT_ASSERT(createTestFiles()); - - // Delete file - Empty local id & path provided => canRun == false - DeleteJob jobEmptyLocalFileId(_driveDbId, _dummyRemoteFileId, "", ""); - CPPUNIT_ASSERT(!jobEmptyLocalFileId.canRun()); - - // Delete file - A local file exists with the same path & id => canRun == false - DeleteJob jobLocalFileExists(_driveDbId, _dummyRemoteFileId, _dummyLocalFileId, _dummyLocalFilePath); - CPPUNIT_ASSERT(!jobLocalFileExists.canRun()); - - // Delete file - A local file exists with the same path but not the same id => canRun == true - DeleteJob jobLocalFileSynonymExists(_driveDbId, _dummyRemoteFileId, "1234", _dummyLocalFilePath); - CPPUNIT_ASSERT(jobLocalFileSynonymExists.canRun()); - ExitCode exitCode = jobLocalFileSynonymExists.runSynchronously(); - CPPUNIT_ASSERT(exitCode == ExitCode::Ok); - - // Check that the file has been deleted - GetFileListJob fileListJob(_driveDbId, testDummyDirRemoteId); - exitCode = fileListJob.runSynchronously(); - CPPUNIT_ASSERT(exitCode == ExitCode::Ok); - - Poco::JSON::Object::Ptr resObj = fileListJob.jsonRes(); - CPPUNIT_ASSERT(resObj); - - bool newFileFound = false; - for (const auto dataArray = resObj->getArray(dataKey); const auto &item: *dataArray) { - const auto &dirObj = item.extract(); - if (_dummyFileName == dirObj->get(nameKey)) { - newFileFound = true; - break; - } - } - CPPUNIT_ASSERT(!newFileFound); - - RemoteTemporaryDirectory remoteTmpDir(_driveDbId, _remoteDirId, "testDelete"); - const LocalTemporaryDirectory localTmpDir("testDelete"); - - // Delete directory - Empty local id & path provided => canRun == false - DeleteJob jobEmptyLocalDirId(_driveDbId, remoteTmpDir.id(), "", ""); - CPPUNIT_ASSERT(!jobEmptyLocalDirId.canRun()); - - // Delete directory - A local dir exists with the same path & id => canRun == false - DeleteJob jobLocalDirExists(_driveDbId, remoteTmpDir.id(), localTmpDir.id(), localTmpDir.path()); - CPPUNIT_ASSERT(!jobLocalDirExists.canRun()); - - // Delete directory - A local dir exists with the same path but not the same id => canRun == true - DeleteJob jobLocalDirSynonymExists(_driveDbId, remoteTmpDir.id(), "1234", localTmpDir.path()); - CPPUNIT_ASSERT(jobLocalDirSynonymExists.canRun()); - exitCode = jobLocalDirSynonymExists.runSynchronously(); - CPPUNIT_ASSERT(exitCode == ExitCode::Ok); - - // Check that the dir has been deleted - GetFileListJob fileListJob2(_driveDbId, _remoteDirId); - exitCode = fileListJob2.runSynchronously(); - CPPUNIT_ASSERT(exitCode == ExitCode::Ok); - - resObj = fileListJob2.jsonRes(); - CPPUNIT_ASSERT(resObj); - - bool newDirFound = false; - const auto dataArray = resObj->getArray(dataKey); - for (Poco::JSON::Array::ConstIterator it = dataArray->begin(); it != dataArray->end(); ++it) { - Poco::JSON::Object::Ptr dirObj = it->extract(); - SyncName currentName = dirObj->get(nameKey); - if (remoteTmpDir.name() == currentName) { - newDirFound = true; - break; - } - } - CPPUNIT_ASSERT(!newDirFound); - remoteTmpDir.setDeleted(); -} - -void TestNetworkJobs::testDownload() { - const LocalTemporaryDirectory temporaryDirectory("testDownload"); - SyncPath localDestFilePath = temporaryDirectory.path() / "test_file.txt"; - DownloadJob job(_driveDbId, testFileRemoteId, localDestFilePath, 0, 0, 0, false); - const ExitCode exitCode = job.runSynchronously(); - CPPUNIT_ASSERT(exitCode == ExitCode::Ok); - - CPPUNIT_ASSERT(std::filesystem::exists(localDestFilePath)); - - // Check file content - std::ifstream ifs(localDestFilePath.string().c_str()); - std::string content((std::istreambuf_iterator(ifs)), (std::istreambuf_iterator())); - CPPUNIT_ASSERT(content == "test"); -} - -void TestNetworkJobs::testDownloadAborted() { - const LocalTemporaryDirectory temporaryDirectory("testDownloadAborted"); - SyncPath localDestFilePath = temporaryDirectory.path() / bigFileName; - std::shared_ptr job = - std::make_shared(_driveDbId, testBigFileRemoteId, localDestFilePath, 0, 0, 0, false); - JobManager::instance()->queueAsyncJob(job); - - Utility::msleep(1000); // Wait 1sec - - job->abort(); - - Utility::msleep(1000); // Wait 1sec - - CPPUNIT_ASSERT(!std::filesystem::exists(localDestFilePath)); -} - -void TestNetworkJobs::testGetAvatar() { - GetInfoUserJob job(_userDbId); - ExitCode exitCode = job.runSynchronously(); - CPPUNIT_ASSERT(exitCode == ExitCode::Ok); - - CPPUNIT_ASSERT(job.jsonRes()); - Poco::JSON::Object::Ptr data = job.jsonRes()->getObject(dataKey); - std::string avatarUrl = data->get(avatarKey); - - GetAvatarJob avatarJob(avatarUrl); - exitCode = avatarJob.runSynchronously(); - CPPUNIT_ASSERT(exitCode == ExitCode::Ok); - - CPPUNIT_ASSERT(avatarJob.avatar()); - CPPUNIT_ASSERT(!avatarJob.avatar().get()->empty()); -} - -void TestNetworkJobs::testGetDriveList() { - GetDrivesListJob job(_userDbId); - job.runSynchronously(); - const ExitCode exitCode = job.runSynchronously(); - CPPUNIT_ASSERT(exitCode == ExitCode::Ok); - - bool found = false; - Poco::JSON::Array::Ptr data = job.jsonRes()->getArray("data"); - for (size_t i = 0; i < data->size(); i++) { - Poco::JSON::Object::Ptr obj = data->getObject(static_cast(i)); - std::string name = obj->get("drive_name"); - found = name == desktopTeamTestDriveName; - if (found) { - break; - } - } - CPPUNIT_ASSERT(found); -} - -void TestNetworkJobs::testGetFileInfo() { - { - GetFileInfoJob job(_driveDbId, testFileRemoteId); - CPPUNIT_ASSERT_EQUAL(ExitCode::Ok, job.runSynchronously()); - CPPUNIT_ASSERT(job.jsonRes()); - CPPUNIT_ASSERT(job.path().empty()); - } - - // The returned path is relative to the remote drive root. - { - GetFileInfoJob jobWithPath(_driveDbId, testFileRemoteId); - jobWithPath.setWithPath(true); - CPPUNIT_ASSERT_EQUAL(ExitCode::Ok, jobWithPath.runSynchronously()); - - const auto expectedPath = - SyncPath("Common documents") / "Test kDrive" / "test_ci" / "test_networkjobs" / "test_download.txt"; - CPPUNIT_ASSERT_EQUAL(expectedPath, jobWithPath.path()); - } - - // The returned path is empty if the job requests info on the remote drive root. - { - GetFileInfoJob jobWithPath(_driveDbId, "1"); // The identifier of the remote root drive is always 1. - CPPUNIT_ASSERT_EQUAL(ExitCode::Ok, jobWithPath.runSynchronously()); - jobWithPath.setWithPath(true); - CPPUNIT_ASSERT(jobWithPath.path().empty()); - } -} - -void TestNetworkJobs::testGetFileList() { - GetFileListJob job(_driveDbId, pictureDirRemoteId); - const ExitCode exitCode = job.runSynchronously(); - CPPUNIT_ASSERT(exitCode == ExitCode::Ok); - - int counter = 0; - Poco::JSON::Array::Ptr dataArray = job.jsonRes()->getArray(dataKey); - for (Poco::JSON::Array::ConstIterator it = dataArray->begin(); it != dataArray->end(); ++it) { - counter++; - } - CPPUNIT_ASSERT(counter == 5); -} - -void TestNetworkJobs::testGetFileListWithCursor() { - InitFileListWithCursorJob job(_driveDbId, pictureDirRemoteId); - const ExitCode exitCode = job.runSynchronously(); - CPPUNIT_ASSERT(exitCode == ExitCode::Ok); - - int counter = 0; - std::string cursor; - Poco::JSON::Object::Ptr dataObj = job.jsonRes()->getObject(dataKey); - if (dataObj) { - cursor = dataObj->get(cursorKey).toString(); - - Poco::JSON::Array::Ptr filesArray = dataObj->getArray(filesKey); - if (filesArray) { - for (auto it = filesArray->begin(); it != filesArray->end(); ++it) { - counter++; - } - } - } - - CPPUNIT_ASSERT(!cursor.empty()); - CPPUNIT_ASSERT(counter == 5); -} - -void TestNetworkJobs::testFullFileListWithCursorJson() { - JsonFullFileListWithCursorJob job(_driveDbId, "1", {}, false); - const ExitCode exitCode = job.runSynchronously(); - CPPUNIT_ASSERT(exitCode == ExitCode::Ok); - - int counter = 0; - std::string cursor; - Poco::JSON::Object::Ptr dataObj = job.jsonRes()->getObject(dataKey); - if (dataObj) { - cursor = dataObj->get(cursorKey).toString(); - - Poco::JSON::Array::Ptr filesArray = dataObj->getArray(filesKey); - if (filesArray) { - for (auto it = filesArray->begin(); it != filesArray->end(); ++it) { - Poco::JSON::Object::Ptr obj = it->extract(); - if (obj->get(parentIdKey).toString() == pictureDirRemoteId) { - counter++; - } - } - } - } - - CPPUNIT_ASSERT(!cursor.empty()); - CPPUNIT_ASSERT(counter == 5); -} - -void TestNetworkJobs::testFullFileListWithCursorJsonZip() { - JsonFullFileListWithCursorJob job(_driveDbId, "1", {}, true); - const ExitCode exitCode = job.runSynchronously(); - CPPUNIT_ASSERT(exitCode == ExitCode::Ok); - - int counter = 0; - std::string cursor; - Poco::JSON::Object::Ptr dataObj = job.jsonRes()->getObject(dataKey); - if (dataObj) { - cursor = dataObj->get(cursorKey).toString(); - - Poco::JSON::Array::Ptr filesArray = dataObj->getArray(filesKey); - if (filesArray) { - for (auto it = filesArray->begin(); it != filesArray->end(); ++it) { - Poco::JSON::Object::Ptr obj = it->extract(); - if (obj->get(parentIdKey).toString() == pictureDirRemoteId) { - counter++; - } - } - } - } - - CPPUNIT_ASSERT(!cursor.empty()); - CPPUNIT_ASSERT(counter == 5); -} - -void TestNetworkJobs::testFullFileListWithCursorCsv() { - CsvFullFileListWithCursorJob job(_driveDbId, "1", {}, false); - const ExitCode exitCode = job.runSynchronously(); - CPPUNIT_ASSERT(exitCode == ExitCode::Ok); - - int counter = 0; - std::string cursor = job.getCursor(); - SnapshotItem item; - bool error = false; - bool ignore = false; - bool eof = false; - while (job.getItem(item, error, ignore, eof)) { - if (ignore) { - continue; - } - - if (item.parentId() == pictureDirRemoteId) { - counter++; - } - } - - CPPUNIT_ASSERT(!cursor.empty()); - CPPUNIT_ASSERT(counter == 5); - CPPUNIT_ASSERT(eof); -} - -void TestNetworkJobs::testFullFileListWithCursorCsvZip() { - CsvFullFileListWithCursorJob job(_driveDbId, "1", {}, true); - const ExitCode exitCode = job.runSynchronously(); - CPPUNIT_ASSERT(exitCode == ExitCode::Ok); - - int counter = 0; - std::string cursor = job.getCursor(); - SnapshotItem item; - bool error = false; - bool ignore = false; - bool eof = false; - while (job.getItem(item, error, ignore, eof)) { - if (ignore) { - continue; - } - - if (item.parentId() == pictureDirRemoteId) { - counter++; - } - } - - CPPUNIT_ASSERT(!cursor.empty()); - CPPUNIT_ASSERT(counter == 5); - CPPUNIT_ASSERT(eof); -} - -void TestNetworkJobs::testFullFileListWithCursorJsonBlacklist() { - JsonFullFileListWithCursorJob job(_driveDbId, "1", {pictureDirRemoteId}, true); - const ExitCode exitCode = job.runSynchronously(); - CPPUNIT_ASSERT(exitCode == ExitCode::Ok); - - int counter = 0; - std::string cursor; - Poco::JSON::Object::Ptr dataObj = job.jsonRes()->getObject(dataKey); - if (dataObj) { - cursor = dataObj->get(cursorKey).toString(); - - Poco::JSON::Array::Ptr filesArray = dataObj->getArray(filesKey); - if (filesArray) { - for (auto it = filesArray->begin(); it != filesArray->end(); ++it) { - Poco::JSON::Object::Ptr obj = it->extract(); - if (obj->get(parentIdKey).toString() == pictureDirRemoteId) { - counter++; - } - } - } - } - - CPPUNIT_ASSERT(!cursor.empty()); - CPPUNIT_ASSERT(counter == 0); -} - -void TestNetworkJobs::testFullFileListWithCursorCsvBlacklist() { - CsvFullFileListWithCursorJob job(_driveDbId, "1", {pictureDirRemoteId}, true); - const ExitCode exitCode = job.runSynchronously(); - CPPUNIT_ASSERT(exitCode == ExitCode::Ok); - - int counter = 0; - std::string cursor = job.getCursor(); - SnapshotItem item; - bool error = false; - bool ignore = false; - bool eof = false; - while (job.getItem(item, error, ignore, eof)) { - if (ignore) { - continue; - } - - if (item.parentId() == pictureDirRemoteId) { - counter++; - } - } - - CPPUNIT_ASSERT(!cursor.empty()); - CPPUNIT_ASSERT(counter == 0); - CPPUNIT_ASSERT(eof); -} - -void TestNetworkJobs::testFullFileListWithCursorMissingEof() { - CsvFullFileListWithCursorJob job(_driveDbId, "1"); - const ExitCode exitCode = job.runSynchronously(); - CPPUNIT_ASSERT(exitCode == ExitCode::Ok); - - int counter = 0; - const std::string cursor = job.getCursor(); - SnapshotItem item; - bool error = false; - bool ignore = false; - bool eof = false; - // Call getItem only once to simulate a troncated CSV file - job.getItem(item, error, ignore, eof); - if (item.parentId() == pictureDirRemoteId) { - counter++; - } - - CPPUNIT_ASSERT(!cursor.empty()); - CPPUNIT_ASSERT_LESS(5, counter); - CPPUNIT_ASSERT(!eof); -} - -void TestNetworkJobs::testGetInfoUser() { - GetInfoUserJob job(_userDbId); - const ExitCode exitCode = job.runSynchronously(); - CPPUNIT_ASSERT(exitCode == ExitCode::Ok); - - Poco::JSON::Object::Ptr data = job.jsonRes()->getObject(dataKey); - // CPPUNIT_ASSERT(data->get(emailKey).toString() == _email); -} - -void TestNetworkJobs::testGetInfoDrive() { - GetInfoDriveJob job(_driveDbId); - const ExitCode exitCode = job.runSynchronously(); - CPPUNIT_ASSERT(exitCode == ExitCode::Ok); - - Poco::JSON::Object::Ptr data = job.jsonRes()->getObject(dataKey); - CPPUNIT_ASSERT(data->get(nameKey).toString() == "kDrive Desktop Team"); -} - -void TestNetworkJobs::testThumbnail() { - GetThumbnailJob job(_driveDbId, picture1RemoteId.c_str(), 50); - const ExitCode exitCode = job.runSynchronously(); - CPPUNIT_ASSERT(exitCode == ExitCode::Ok); - - CPPUNIT_ASSERT(!job.octetStreamRes().empty()); -} - -void TestNetworkJobs::testDuplicateRenameMove() { - const RemoteTemporaryDirectory remoteTmpDir(_driveDbId, _remoteDirId, "testDuplicateRenameMove"); - - // Duplicate - DuplicateJob dupJob(_driveDbId, testFileRemoteId, Str("test_duplicate.txt")); - ExitCode exitCode = dupJob.runSynchronously(); - CPPUNIT_ASSERT(exitCode == ExitCode::Ok); - - NodeId dupFileId; - if (dupJob.jsonRes()) { - Poco::JSON::Object::Ptr dataObj = dupJob.jsonRes()->getObject(dataKey); - if (dataObj) { - dupFileId = dataObj->get(idKey).toString(); - } - } - - CPPUNIT_ASSERT(!dupFileId.empty()); - - // Move - MoveJob moveJob(_driveDbId, "", dupFileId, remoteTmpDir.id()); - moveJob.setBypassCheck(true); - exitCode = moveJob.runSynchronously(); - CPPUNIT_ASSERT(exitCode == ExitCode::Ok); - - GetFileListJob fileListJob(_driveDbId, remoteTmpDir.id()); - exitCode = fileListJob.runSynchronously(); - CPPUNIT_ASSERT(exitCode == ExitCode::Ok); - - Poco::JSON::Object::Ptr resObj = fileListJob.jsonRes(); - CPPUNIT_ASSERT(resObj); - Poco::JSON::Array::Ptr dataArray = resObj->getArray(dataKey); - CPPUNIT_ASSERT(dataArray->getObject(0)->get(idKey) == dupFileId); - CPPUNIT_ASSERT(dataArray->getObject(0)->get(nameKey) == "test_duplicate.txt"); -} - -void TestNetworkJobs::testRename() { - // Rename - const SyncName filename = Str("test_rename_") + Str2SyncName(CommonUtility::generateRandomStringAlphaNum()) + Str(".txt"); - RenameJob renamejob(_driveDbId, testFileRemoteRenameId, filename); - renamejob.runSynchronously(); - - // Check the name has changed - GetFileInfoJob fileInfoJob(_driveDbId, testFileRemoteRenameId); - ExitCode exitCode = fileInfoJob.runSynchronously(); - CPPUNIT_ASSERT(exitCode == ExitCode::Ok); - - Poco::JSON::Object::Ptr dataObj = fileInfoJob.jsonRes()->getObject(dataKey); - SyncName name; - if (dataObj) { - name = Str2SyncName(dataObj->get(nameKey).toString()); - } - CPPUNIT_ASSERT(name == filename); -} - -void TestNetworkJobs::testUpload() { -<<<<<<< HEAD - { - const RemoteTemporaryDirectory remoteTmpDir(_driveDbId, _remoteDirId, "testUpload"); - SyncPath localFilePath = testhelpers::localTestDirPath / bigFileDirName / bigFileName; - - UploadJob job(_driveDbId, localFilePath, localFilePath.filename().native(), remoteTmpDir.id(), 0); - ExitCode exitCode = job.runSynchronously(); - CPPUNIT_ASSERT(exitCode == ExitCode::Ok); - - NodeId newNodeId = job.nodeId(); - - GetFileInfoJob fileInfoJob(_driveDbId, newNodeId); - exitCode = fileInfoJob.runSynchronously(); - CPPUNIT_ASSERT(exitCode == ExitCode::Ok); - -======= - - { - const RemoteTemporaryDirectory remoteTmpDir(_driveDbId, _remoteDirId, "testUpload"); - SyncPath localFilePath = testhelpers::localTestDirPath / bigFileDirName / bigFileName; - - UploadJob job(_driveDbId, localFilePath, localFilePath.filename().native(), remoteTmpDir.id(), 0); - ExitCode exitCode = job.runSynchronously(); - CPPUNIT_ASSERT(exitCode == ExitCode::Ok); - - NodeId newNodeId = job.nodeId(); - - GetFileInfoJob fileInfoJob(_driveDbId, newNodeId); - exitCode = fileInfoJob.runSynchronously(); - CPPUNIT_ASSERT(exitCode == ExitCode::Ok); - ->>>>>>> 280810c49d60fb9d986651e9f0aaa8019cedf38d - Poco::JSON::Object::Ptr dataObj = fileInfoJob.jsonRes()->getObject(dataKey); - std::string name; - if (dataObj) { - name = dataObj->get(nameKey).toString(); - } - CPPUNIT_ASSERT(name == bigFileName); - } - { - const RemoteTemporaryDirectory remoteTmpDir(_driveDbId, _remoteDirId, "testUpload"); - const LocalTemporaryDirectory localTmpDir("testUpload"); - const SyncPath localDestFilePath = localTmpDir.path() / bigFileName; - testhelpers::generateOrEditTestFile(localDestFilePath); - IoError ioError = IoError::Unknown; - IoHelper::setRights(localDestFilePath, false, false, false, ioError); - CPPUNIT_ASSERT_EQUAL(IoError::Success, ioError); - - UploadJob job(_driveDbId, localDestFilePath, localDestFilePath.filename().native(), remoteTmpDir.id(), 0); - ExitCode exitCode = job.runSynchronously(); - CPPUNIT_ASSERT_EQUAL(ExitCode::SystemError, exitCode); - CPPUNIT_ASSERT_EQUAL(ExitCause::FileAccessError, job.exitCause()); - } - { - const RemoteTemporaryDirectory remoteTmpDir(_driveDbId, _remoteDirId, "testUpload"); - const LocalTemporaryDirectory localTmpDir("testUpload"); -<<<<<<< HEAD - const SyncPath localDestFilePath = localTmpDir.path() / "removed.txt"; -======= - const SyncPath localDestFilePath = localTmpDir.path() / bigFileName; ->>>>>>> 280810c49d60fb9d986651e9f0aaa8019cedf38d - testhelpers::generateOrEditTestFile(localDestFilePath); - - UploadJob job(_driveDbId, localDestFilePath, localDestFilePath.filename().native(), remoteTmpDir.id(), 0); - IoError ioErrror = IoError::Unknown; -<<<<<<< HEAD - - IoError ioError = IoError::Unknown; - IoHelper::setRights(localDestFilePath, false, false, false, ioError); - CPPUNIT_ASSERT_EQUAL(IoError::Success, ioError); - - Utility::msleep(1000); // Wait 1sec - - IoHelper::deleteItem(localDestFilePath, ioErrror); - CPPUNIT_ASSERT_EQUAL(IoError::Success, ioErrror); - - ExitCode exitCode = job.runSynchronously(); - CPPUNIT_ASSERT_EQUAL(ExitCode::SystemError, exitCode); - CPPUNIT_ASSERT_EQUAL(ExitCause::NotFound, job.exitCause()); - } - { - const RemoteTemporaryDirectory remoteTmpDir(_driveDbId, _remoteDirId, "testUpload"); - const LocalTemporaryDirectory localTmpDir("testUpload"); - const SyncPath localDestFilePath = localTmpDir.path() / "non_existing.txt"; - UploadJob job(_driveDbId, localDestFilePath, localDestFilePath.filename().native(), remoteTmpDir.id(), 0); -======= - IoHelper::deleteItem(localDestFilePath, ioErrror); - CPPUNIT_ASSERT_EQUAL(IoError::Success, ioErrror); - ->>>>>>> 280810c49d60fb9d986651e9f0aaa8019cedf38d - ExitCode exitCode = job.runSynchronously(); - CPPUNIT_ASSERT_EQUAL(ExitCode::SystemError, exitCode); - CPPUNIT_ASSERT_EQUAL(ExitCause::NotFound, job.exitCause()); - } -} - -void TestNetworkJobs::testUploadAborted() { - const RemoteTemporaryDirectory remoteTmpDir(_driveDbId, _remoteDirId, "testUploadAborted"); - - SyncPath localFilePath = testhelpers::localTestDirPath / bigFileDirName / bigFileName; - - const std::shared_ptr job = - std::make_shared(_driveDbId, localFilePath, localFilePath.filename().native(), remoteTmpDir.id(), 0); - JobManager::instance()->queueAsyncJob(job); - - Utility::msleep(1000); // Wait 1sec - - job->abort(); - - Utility::msleep(1000); // Wait 1sec - - NodeId newNodeId = job->nodeId(); - CPPUNIT_ASSERT(newNodeId.empty()); -} - -void TestNetworkJobs::testDriveUploadSessionConstructorException() { - const RemoteTemporaryDirectory remoteTmpDir(_driveDbId, _remoteDirId, "testDriveUploadSessionConstructorException"); - - SyncPath localFilePath = testhelpers::localTestDirPath; - // The constructor of DriveUploadSession will attempt to retrieve the file size of directory. - - CPPUNIT_ASSERT_THROW_MESSAGE("DriveUploadSession() didn't throw as expected", - DriveUploadSession(_driveDbId, nullptr, localFilePath, localFilePath.filename().native(), - remoteTmpDir.id(), 12345, false, 1), - std::runtime_error); -} - -void TestNetworkJobs::testDriveUploadSessionSynchronous() { - // Create a file - LOGW_DEBUG(Log::instance()->getLogger(), L"$$$$$ testDriveUploadSessionSynchronous Create"); - - const RemoteTemporaryDirectory remoteTmpDir(_driveDbId, _remoteDirId, "testDriveUploadSessionSynchronous"); - const LocalTemporaryDirectory localTmpDir("testDriveUploadSessionSynchronous"); - const SyncPath localFilePath = localTmpDir.path() / bigFileName; - - IoError ioError = IoError::Unknown; - CPPUNIT_ASSERT( - IoHelper::copyFileOrDirectory(testhelpers::localTestDirPath / bigFileDirName / bigFileName, localFilePath, ioError)); - CPPUNIT_ASSERT_EQUAL(IoError::Success, ioError); - - DriveUploadSession driveUploadSessionJobCreate(_driveDbId, nullptr, localFilePath, localFilePath.filename().native(), - remoteTmpDir.id(), 12345, false, 1); - ExitCode exitCode = driveUploadSessionJobCreate.runSynchronously(); - CPPUNIT_ASSERT_EQUAL(ExitCode::Ok, exitCode); - - const NodeId newNodeId = driveUploadSessionJobCreate.nodeId(); - GetFileListJob fileListJob(_driveDbId, remoteTmpDir.id()); - exitCode = fileListJob.runSynchronously(); - CPPUNIT_ASSERT_EQUAL(ExitCode::Ok, exitCode); - - Poco::JSON::Object::Ptr resObj = fileListJob.jsonRes(); - CPPUNIT_ASSERT(resObj); - Poco::JSON::Array::Ptr dataArray = resObj->getArray(dataKey); - CPPUNIT_ASSERT(dataArray->getObject(0)->get(idKey) == newNodeId); - CPPUNIT_ASSERT(Utility::s2ws(dataArray->getObject(0)->get(nameKey)) == Path2WStr(localFilePath.filename())); - - // Update a file - LOGW_DEBUG(Log::instance()->getLogger(), L"$$$$$ testDriveUploadSessionSynchronous Edit"); - std::ofstream ofs(localFilePath, std::ios::app); - ofs << "test"; - ofs.close(); - uint64_t fileSizeLocal = 0; - CPPUNIT_ASSERT(IoHelper::getFileSize(localFilePath, fileSizeLocal, ioError)); - CPPUNIT_ASSERT_EQUAL(IoError::Success, ioError); - - DriveUploadSession driveUploadSessionJobEdit(_driveDbId, nullptr, localFilePath, newNodeId, false, 1); - exitCode = driveUploadSessionJobEdit.runSynchronously(); - CPPUNIT_ASSERT_EQUAL(ExitCode::Ok, exitCode); - - GetSizeJob fileSizeJob(_driveDbId, newNodeId); - exitCode = fileSizeJob.runSynchronously(); - CPPUNIT_ASSERT_EQUAL(ExitCode::Ok, exitCode); - int64_t fileSizeRemote = fileSizeJob.size(); - - CPPUNIT_ASSERT_EQUAL(static_cast(fileSizeLocal), fileSizeRemote); - - // A file with no rights - LOGW_DEBUG(Log::instance()->getLogger(), L"$$$$$ testDriveUploadSessionSynchronous No rights"); - const SyncPath localFilePathNoRights = localTmpDir.path() / "no_rights.txt"; - testhelpers::generateOrEditTestFile(localFilePathNoRights); -<<<<<<< HEAD - IoHelper::setRights(localFilePathNoRights, false, true, true, ioError); -======= - IoHelper::setRights(localFilePathNoRights, false, false, false, ioError); ->>>>>>> 280810c49d60fb9d986651e9f0aaa8019cedf38d - CPPUNIT_ASSERT_EQUAL(IoError::Success, ioError); - - DriveUploadSession driveUploadSessionJobNoRights(_driveDbId, nullptr, localFilePathNoRights, - localFilePathNoRights.filename().native(), remoteTmpDir.id(), 12345, false, - 1); - exitCode = driveUploadSessionJobNoRights.runSynchronously(); - CPPUNIT_ASSERT_EQUAL(ExitCode::SystemError, exitCode); - CPPUNIT_ASSERT_EQUAL(ExitCause::FileAccessError, driveUploadSessionJobNoRights.exitCause()); - - // A file removed - LOGW_DEBUG(Log::instance()->getLogger(), L"$$$$$ testDriveUploadSessionSynchronous Removed"); - const SyncPath localFilePathRemoved = localTmpDir.path() / "removed.txt"; - testhelpers::generateOrEditTestFile(localFilePathRemoved); - DriveUploadSession driveUploadSessionJobRemoved(_driveDbId, nullptr, localFilePathRemoved, -<<<<<<< HEAD - localFilePathRemoved.filename().native(), remoteTmpDir.id(), 12345, false, 1); - IoHelper::setRights(localFilePathNoRights, false, true, true, ioError); - CPPUNIT_ASSERT_EQUAL(IoError::Success, ioError); - - Utility::msleep(1000); // Wait 1sec -======= - localFilePathRemoved.filename().native(), remoteTmpDir.id(), 12345, false, - 1); ->>>>>>> 280810c49d60fb9d986651e9f0aaa8019cedf38d - - IoError ioErrror = IoError::Unknown; - IoHelper::deleteItem(localFilePathRemoved, ioErrror); - CPPUNIT_ASSERT_EQUAL(IoError::Success, ioErrror); - - exitCode = driveUploadSessionJobRemoved.runSynchronously(); - CPPUNIT_ASSERT_EQUAL(ExitCode::SystemError, exitCode); - CPPUNIT_ASSERT_EQUAL(ExitCause::NotFound, driveUploadSessionJobRemoved.exitCause()); - -<<<<<<< HEAD - // A non existing file - LOGW_DEBUG(Log::instance()->getLogger(), L"$$$$$ testDriveUploadSessionSynchronous Non existing"); - const SyncPath localFilePathNonExisting = localTmpDir.path() / "non_existing.txt"; - DriveUploadSession driveUploadSessionJobNonExisting(_driveDbId, nullptr, localFilePathNonExisting, - localFilePathNonExisting.filename().native(), remoteTmpDir.id(), 12345, - false, 1); - exitCode = driveUploadSessionJobNonExisting.runSynchronously(); - CPPUNIT_ASSERT_EQUAL(ExitCode::SystemError, exitCode); - CPPUNIT_ASSERT_EQUAL(ExitCause::NotFound, driveUploadSessionJobNonExisting.exitCause()); -======= - ->>>>>>> 280810c49d60fb9d986651e9f0aaa8019cedf38d -} - -void TestNetworkJobs::testDriveUploadSessionAsynchronous() { - // Create a file - LOGW_DEBUG(Log::instance()->getLogger(), L"$$$$$ testDriveUploadSessionAsynchronousCreate"); - - const RemoteTemporaryDirectory remoteTmpDir(_driveDbId, _remoteDirId, "testDriveUploadSessionAsynchronous"); - const LocalTemporaryDirectory localTmpDir("testDriveUploadSessionASynchronous"); - const SyncPath localFilePath = localTmpDir.path() / bigFileName; - - IoError ioError = IoError::Unknown; - CPPUNIT_ASSERT( - IoHelper::copyFileOrDirectory(testhelpers::localTestDirPath / bigFileDirName / bigFileName, localFilePath, ioError)); - CPPUNIT_ASSERT_EQUAL(IoError::Success, ioError); - - ExitCode exitCode = ExitCode::Unknown; - NodeId newNodeId; - uint64_t initialNbParalleleThreads = _nbParalleleThreads; - while (_nbParalleleThreads > 0) { - LOG_DEBUG(Log::instance()->getLogger(), - "$$$$$ testDriveUploadSessionAsynchronous - " << _nbParalleleThreads << " threads"); - DriveUploadSession driveUploadSessionJob(_driveDbId, nullptr, localFilePath, localFilePath.filename().native(), - remoteTmpDir.id(), 12345, false, _nbParalleleThreads); - exitCode = driveUploadSessionJob.runSynchronously(); - if (exitCode == ExitCode::Ok) { - newNodeId = driveUploadSessionJob.nodeId(); - break; - } else if (exitCode == ExitCode::NetworkError && driveUploadSessionJob.exitCause() == ExitCause::SocketsDefuncted) { - LOGW_DEBUG(Log::instance()->getLogger(), L"$$$$$ testDriveUploadSessionAsynchronous - Sockets defuncted by kernel"); - // Decrease upload session max parallel jobs - if (_nbParalleleThreads > 1) { - _nbParalleleThreads = static_cast(std::floor(static_cast(_nbParalleleThreads) / 2.0)); - } else { - break; - } - } else { - break; - } - } - _nbParalleleThreads = initialNbParalleleThreads; - CPPUNIT_ASSERT_EQUAL(ExitCode::Ok, exitCode); - - GetFileListJob fileListJob(_driveDbId, remoteTmpDir.id()); - exitCode = fileListJob.runSynchronously(); - CPPUNIT_ASSERT_EQUAL(ExitCode::Ok, exitCode); - - Poco::JSON::Object::Ptr resObj = fileListJob.jsonRes(); - CPPUNIT_ASSERT(resObj); - Poco::JSON::Array::Ptr dataArray = resObj->getArray(dataKey); - CPPUNIT_ASSERT(dataArray->getObject(0)->get(idKey) == newNodeId); - CPPUNIT_ASSERT(dataArray->getObject(0)->get(nameKey) == localFilePath.filename().string()); - - // Edit a file - _nbParalleleThreads = 10; - LOGW_DEBUG(Log::instance()->getLogger(), L"$$$$$ testDriveUploadSessionAsynchronousEdit"); - std::ofstream ofs(localFilePath, std::ios::app); - ofs << "test"; - ofs.close(); - uint64_t fileSizeLocal = 0; - CPPUNIT_ASSERT(IoHelper::getFileSize(localFilePath, fileSizeLocal, ioError)); - CPPUNIT_ASSERT_EQUAL(IoError::Success, ioError); - while (_nbParalleleThreads > 0) { - LOG_DEBUG(Log::instance()->getLogger(), - "$$$$$ testDriveUploadSessionAsynchronous - " << _nbParalleleThreads << " threads"); - DriveUploadSession driveUploadSessionJob(_driveDbId, nullptr, localFilePath, newNodeId, 12345, false, - _nbParalleleThreads); - exitCode = driveUploadSessionJob.runSynchronously(); - if (exitCode == ExitCode::Ok) { - break; - } else if (exitCode == ExitCode::NetworkError && driveUploadSessionJob.exitCause() == ExitCause::SocketsDefuncted) { - LOGW_DEBUG(Log::instance()->getLogger(), L"$$$$$ testDriveUploadSessionAsynchronous - Sockets defuncted by kernel"); - // Decrease upload session max parallel jobs - if (_nbParalleleThreads > 1) { - _nbParalleleThreads = static_cast(std::floor(static_cast(_nbParalleleThreads) / 2.0)); - } else { - break; - } - } else { - break; - } - } - _nbParalleleThreads = initialNbParalleleThreads; - - CPPUNIT_ASSERT_EQUAL(ExitCode::Ok, exitCode); - - GetSizeJob fileSizeJob(_driveDbId, newNodeId); - exitCode = fileSizeJob.runSynchronously(); - CPPUNIT_ASSERT_EQUAL(ExitCode::Ok, exitCode); - - int64_t fileSizeRemote = fileSizeJob.size(); - CPPUNIT_ASSERT_EQUAL(static_cast(fileSizeLocal), fileSizeRemote); -} - -void TestNetworkJobs::testDriveUploadSessionSynchronousAborted() { - LOGW_DEBUG(Log::instance()->getLogger(), L"$$$$$ testDriveUploadSessionSynchronousAborted"); - - const RemoteTemporaryDirectory remoteTmpDir(_driveDbId, _remoteDirId, "testDriveUploadSessionSynchronousAborted"); - - SyncPath localFilePath = testhelpers::localTestDirPath / bigFileDirName / bigFileName; - - LOG_DEBUG(Log::instance()->getLogger(), - "$$$$$ testDriveUploadSessionSynchronousAborted - " << _nbParalleleThreads << " threads"); - std::shared_ptr DriveUploadSessionJob = std::make_shared( - _driveDbId, nullptr, localFilePath, localFilePath.filename().native(), remoteTmpDir.id(), 12345, false, 1); - JobManager::instance()->queueAsyncJob(DriveUploadSessionJob); - - Utility::msleep(1000); // Wait 1sec - - DriveUploadSessionJob->abort(); - - Utility::msleep(1000); // Wait 1sec - - NodeId newNodeId = DriveUploadSessionJob->nodeId(); - CPPUNIT_ASSERT(newNodeId.empty()); -} - -void TestNetworkJobs::testDriveUploadSessionAsynchronousAborted() { - LOGW_DEBUG(Log::instance()->getLogger(), L"$$$$$ testDriveUploadSessionAsynchronousAborted"); - - const RemoteTemporaryDirectory remoteTmpDir(_driveDbId, _remoteDirId, "testDriveUploadSessionAsynchronousAborted"); - - SyncPath localFilePath = testhelpers::localTestDirPath / bigFileDirName / bigFileName; - - std::shared_ptr DriveUploadSessionJob = - std::make_shared(_driveDbId, nullptr, localFilePath, localFilePath.filename().native(), - remoteTmpDir.id(), 12345, false, _nbParalleleThreads); - JobManager::instance()->queueAsyncJob(DriveUploadSessionJob); - - Utility::msleep(1000); // Wait 1sec - - LOGW_DEBUG(Log::instance()->getLogger(), L"$$$$$ testDriveUploadSessionAsynchronousAborted - Abort"); - DriveUploadSessionJob->abort(); - - Utility::msleep(1000); // Wait 1sec - - LOGW_DEBUG(Log::instance()->getLogger(), L"$$$$$ testDriveUploadSessionAsynchronousAborted - Check jobs"); - GetFileListJob fileListJob(_driveDbId, remoteTmpDir.id()); - ExitCode exitCode = fileListJob.runSynchronously(); - CPPUNIT_ASSERT(exitCode == ExitCode::Ok); - - Poco::JSON::Object::Ptr resObj = fileListJob.jsonRes(); - CPPUNIT_ASSERT(resObj); - Poco::JSON::Array::Ptr dataArray = resObj->getArray(dataKey); - CPPUNIT_ASSERT(dataArray); - CPPUNIT_ASSERT(dataArray->empty()); -} - -void TestNetworkJobs::testGetAppVersionInfo() { - const auto appUid = "1234567890"; - // Without user IDs - { - GetAppVersionJob job(CommonUtility::platform(), appUid); - job.runSynchronously(); - CPPUNIT_ASSERT(!job.hasHttpError()); - CPPUNIT_ASSERT(job.getVersionInfo(DistributionChannel::Internal).isValid()); - CPPUNIT_ASSERT(job.getVersionInfo(DistributionChannel::Beta).isValid()); - CPPUNIT_ASSERT(job.getVersionInfo(DistributionChannel::Next).isValid()); - CPPUNIT_ASSERT(job.getVersionInfo(DistributionChannel::Prod).isValid()); - CPPUNIT_ASSERT(job.getProdVersionInfo().isValid()); - } - // With 1 user ID - { - User user; - bool found = false; - ParmsDb::instance()->selectUser(_userDbId, user, found); - - GetAppVersionJob job(CommonUtility::platform(), appUid, {user.userId()}); - job.runSynchronously(); - CPPUNIT_ASSERT(!job.hasHttpError()); - CPPUNIT_ASSERT(job.getVersionInfo(DistributionChannel::Internal).isValid()); - CPPUNIT_ASSERT(job.getVersionInfo(DistributionChannel::Beta).isValid()); - CPPUNIT_ASSERT(job.getVersionInfo(DistributionChannel::Next).isValid()); - CPPUNIT_ASSERT(job.getVersionInfo(DistributionChannel::Prod).isValid()); - CPPUNIT_ASSERT(job.getProdVersionInfo().isValid()); - } - // // With several user IDs - // TODO : commented out because we need valid user IDs but we have only one available in tests for now - // { - // GetAppVersionJob job(CommonUtility::platform(), appUid, {123, 456, 789}); - // job.runSynchronously(); - // CPPUNIT_ASSERT(!job.hasHttpError()); - // CPPUNIT_ASSERT(job.getVersionInfo(DistributionChannel::Internal).isValid()); - // CPPUNIT_ASSERT(job.getVersionInfo(DistributionChannel::Beta).isValid()); - // CPPUNIT_ASSERT(job.getVersionInfo(DistributionChannel::Next).isValid()); - // CPPUNIT_ASSERT(job.getVersionInfo(DistributionChannel::Prod).isValid()); - // CPPUNIT_ASSERT(job.getProdVersionInfo().isValid()); - // } -} - -void TestNetworkJobs::testDirectDownload() { - const LocalTemporaryDirectory temporaryDirectory("testDirectDownload"); - SyncPath localDestFilePath = temporaryDirectory.path() / "testInstaller.exe"; - - DirectDownloadJob job(localDestFilePath, - "https://download.storage.infomaniak.com/drive/desktopclient/kDrive-3.6.1.20240604.exe"); - job.runSynchronously(); - CPPUNIT_ASSERT(std::filesystem::exists(localDestFilePath)); - CPPUNIT_ASSERT_EQUAL(119771744, static_cast(std::filesystem::file_size(localDestFilePath))); -} - -bool TestNetworkJobs::createTestFiles() { - _dummyFileName = Str("test_file_") + Str2SyncName(CommonUtility::generateRandomStringAlphaNum(10)); - - // Create local test file - SyncPath dummyLocalFilePath = testhelpers::localTestDirPath / dummyDirName / dummyFileName; - _dummyLocalFilePath = testhelpers::localTestDirPath / dummyDirName / _dummyFileName; - - CPPUNIT_ASSERT(std::filesystem::copy_file(dummyLocalFilePath, _dummyLocalFilePath)); - - // Extract local file ID - FileStat fileStat; - IoError ioError = IoError::Success; - IoHelper::getFileStat(_dummyLocalFilePath, &fileStat, ioError); - CPPUNIT_ASSERT(ioError == IoError::Success); - _dummyLocalFileId = std::to_string(fileStat.inode); - - // Create remote test file - CopyToDirectoryJob job(_driveDbId, testDummyFileRemoteId, testDummyDirRemoteId, _dummyFileName); - const ExitCode exitCode = job.runSynchronously(); - CPPUNIT_ASSERT(exitCode == ExitCode::Ok); - - // Extract remote file ID - if (job.jsonRes()) { - Poco::JSON::Object::Ptr dataObj = job.jsonRes()->getObject(dataKey); - if (dataObj) { - _dummyRemoteFileId = dataObj->get(idKey).toString(); - } - } - - if (_dummyRemoteFileId.empty()) { - return false; - } - - return true; -} - -} // namespace KDC From 9fc616ccba4a810b940e34536c601b40d33da460 Mon Sep 17 00:00:00 2001 From: Herve Eruam Date: Mon, 18 Nov 2024 18:06:51 +0100 Subject: [PATCH 099/178] revert not urgent change in can run behaviour. --- .../network/API_v2/upload_session/abstractuploadsession.cpp | 4 ++-- src/libsyncengine/jobs/network/API_v2/uploadjob.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libsyncengine/jobs/network/API_v2/upload_session/abstractuploadsession.cpp b/src/libsyncengine/jobs/network/API_v2/upload_session/abstractuploadsession.cpp index 221ee2742..4a4806fc3 100644 --- a/src/libsyncengine/jobs/network/API_v2/upload_session/abstractuploadsession.cpp +++ b/src/libsyncengine/jobs/network/API_v2/upload_session/abstractuploadsession.cpp @@ -180,8 +180,8 @@ bool AbstractUploadSession::canRun() { if (!exists) { LOGW_DEBUG(_logger, L"Item does not exist anymore " << Utility::formatSyncPath(_filePath.filename())); - _exitCode = ExitCode::SystemError; - _exitCause = ExitCause::NotFound; + _exitCode = ExitCode::NeedRestart; + _exitCause = ExitCause::UnexpectedFileSystemEvent; return false; } diff --git a/src/libsyncengine/jobs/network/API_v2/uploadjob.cpp b/src/libsyncengine/jobs/network/API_v2/uploadjob.cpp index a9558edff..0ff1d7d96 100644 --- a/src/libsyncengine/jobs/network/API_v2/uploadjob.cpp +++ b/src/libsyncengine/jobs/network/API_v2/uploadjob.cpp @@ -80,8 +80,8 @@ bool UploadJob::canRun() { if (!exists) { LOGW_DEBUG(_logger, L"Item does not exist anymore " << Utility::formatSyncPath(_filePath)); - _exitCode = ExitCode::SystemError; - _exitCause = ExitCause::NotFound; + _exitCode = ExitCode::NeedRestart; + _exitCause = ExitCause::UnexpectedFileSystemEvent; return false; } From c64659903f67876808c9ffaa104f9be5c0534db7 Mon Sep 17 00:00:00 2001 From: Herve Eruam Date: Tue, 19 Nov 2024 08:23:28 +0100 Subject: [PATCH 100/178] Add comment. --- .../network/API_v2/upload_session/abstractuploadsession.cpp | 2 +- src/libsyncengine/jobs/network/API_v2/uploadjob.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libsyncengine/jobs/network/API_v2/upload_session/abstractuploadsession.cpp b/src/libsyncengine/jobs/network/API_v2/upload_session/abstractuploadsession.cpp index 4a4806fc3..bd64de933 100644 --- a/src/libsyncengine/jobs/network/API_v2/upload_session/abstractuploadsession.cpp +++ b/src/libsyncengine/jobs/network/API_v2/upload_session/abstractuploadsession.cpp @@ -179,7 +179,7 @@ bool AbstractUploadSession::canRun() { } if (!exists) { - LOGW_DEBUG(_logger, L"Item does not exist anymore " << Utility::formatSyncPath(_filePath.filename())); + LOGW_DEBUG(_logger, L"Item does not exist anymore. Aborting current sync and restart " << Utility::formatSyncPath(_filePath.filename())); _exitCode = ExitCode::NeedRestart; _exitCause = ExitCause::UnexpectedFileSystemEvent; return false; diff --git a/src/libsyncengine/jobs/network/API_v2/uploadjob.cpp b/src/libsyncengine/jobs/network/API_v2/uploadjob.cpp index 0ff1d7d96..8b6979856 100644 --- a/src/libsyncengine/jobs/network/API_v2/uploadjob.cpp +++ b/src/libsyncengine/jobs/network/API_v2/uploadjob.cpp @@ -79,7 +79,7 @@ bool UploadJob::canRun() { } if (!exists) { - LOGW_DEBUG(_logger, L"Item does not exist anymore " << Utility::formatSyncPath(_filePath)); + LOGW_DEBUG(_logger, L"Item does not exist anymore. Aborting current sync and restart " << Utility::formatSyncPath(_filePath)); _exitCode = ExitCode::NeedRestart; _exitCause = ExitCause::UnexpectedFileSystemEvent; return false; From f92e0f509d3976fb8133e63fbdc072b13c1eddf3 Mon Sep 17 00:00:00 2001 From: Herve Eruam Date: Tue, 19 Nov 2024 08:25:02 +0100 Subject: [PATCH 101/178] clang format --- .../network/API_v2/upload_session/abstractuploadsession.cpp | 3 ++- src/libsyncengine/jobs/network/API_v2/uploadjob.cpp | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/libsyncengine/jobs/network/API_v2/upload_session/abstractuploadsession.cpp b/src/libsyncengine/jobs/network/API_v2/upload_session/abstractuploadsession.cpp index bd64de933..2686a8a81 100644 --- a/src/libsyncengine/jobs/network/API_v2/upload_session/abstractuploadsession.cpp +++ b/src/libsyncengine/jobs/network/API_v2/upload_session/abstractuploadsession.cpp @@ -179,7 +179,8 @@ bool AbstractUploadSession::canRun() { } if (!exists) { - LOGW_DEBUG(_logger, L"Item does not exist anymore. Aborting current sync and restart " << Utility::formatSyncPath(_filePath.filename())); + LOGW_DEBUG(_logger, L"Item does not exist anymore. Aborting current sync and restart " + << Utility::formatSyncPath(_filePath.filename())); _exitCode = ExitCode::NeedRestart; _exitCause = ExitCause::UnexpectedFileSystemEvent; return false; diff --git a/src/libsyncengine/jobs/network/API_v2/uploadjob.cpp b/src/libsyncengine/jobs/network/API_v2/uploadjob.cpp index 8b6979856..350915a8d 100644 --- a/src/libsyncengine/jobs/network/API_v2/uploadjob.cpp +++ b/src/libsyncengine/jobs/network/API_v2/uploadjob.cpp @@ -79,7 +79,8 @@ bool UploadJob::canRun() { } if (!exists) { - LOGW_DEBUG(_logger, L"Item does not exist anymore. Aborting current sync and restart " << Utility::formatSyncPath(_filePath)); + LOGW_DEBUG(_logger, + L"Item does not exist anymore. Aborting current sync and restart " << Utility::formatSyncPath(_filePath)); _exitCode = ExitCode::NeedRestart; _exitCause = ExitCause::UnexpectedFileSystemEvent; return false; From 98fa914bc38d31ec4e9f4bf039a394a8ca5eb7ea Mon Sep 17 00:00:00 2001 From: Herve Eruam <82284536+herve-er@users.noreply.github.com> Date: Tue, 19 Nov 2024 08:28:49 +0100 Subject: [PATCH 102/178] Apply suggestions from code review Co-authored-by: Luc Guyot <162997198+luc-guyot-infomaniak@users.noreply.github.com> --- .../network/API_v2/upload_session/abstractuploadsession.cpp | 2 +- src/libsyncengine/jobs/network/API_v2/uploadjob.cpp | 2 +- test/libsyncengine/jobs/network/testnetworkjobs.cpp | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libsyncengine/jobs/network/API_v2/upload_session/abstractuploadsession.cpp b/src/libsyncengine/jobs/network/API_v2/upload_session/abstractuploadsession.cpp index 2686a8a81..20d5c2514 100644 --- a/src/libsyncengine/jobs/network/API_v2/upload_session/abstractuploadsession.cpp +++ b/src/libsyncengine/jobs/network/API_v2/upload_session/abstractuploadsession.cpp @@ -300,7 +300,7 @@ bool AbstractUploadSession::sendChunks() { } while (count++ < 10 && !file.is_open()); if (count >= 10) { - LOGW_WARN(_logger, L"Failed to open file - path=" << Path2WStr(_filePath)); + LOGW_WARN(_logger, L"Failed to open file - " << Utility::formatSyncPath(_filePath)); _exitCode = ExitCode::SystemError; _exitCause = ExitCause::FileAccessError; return false; diff --git a/src/libsyncengine/jobs/network/API_v2/uploadjob.cpp b/src/libsyncengine/jobs/network/API_v2/uploadjob.cpp index 350915a8d..fd8350015 100644 --- a/src/libsyncengine/jobs/network/API_v2/uploadjob.cpp +++ b/src/libsyncengine/jobs/network/API_v2/uploadjob.cpp @@ -214,7 +214,7 @@ ExitInfo UploadJob::readFile() { } while (count++ < 10 && !file.is_open()); if (count >= 10) { - LOGW_WARN(_logger, L"Failed to open file - path=" << Path2WStr(_filePath)); + LOGW_WARN(_logger, L"Failed to open file - path=" << Utility::formatSyncPath(_filePath)); return {ExitCode::SystemError, ExitCause::FileAccessError}; } diff --git a/test/libsyncengine/jobs/network/testnetworkjobs.cpp b/test/libsyncengine/jobs/network/testnetworkjobs.cpp index 92fa48a8c..8967ca946 100644 --- a/test/libsyncengine/jobs/network/testnetworkjobs.cpp +++ b/test/libsyncengine/jobs/network/testnetworkjobs.cpp @@ -670,7 +670,7 @@ void TestNetworkJobs::testUpload() { } CPPUNIT_ASSERT(name == bigFileName); } - { // Test upload with a file that has no read rights + { // Uploading a file that has no read rights should fail with `ExitCause::FileAccessError`. const RemoteTemporaryDirectory remoteTmpDir(_driveDbId, _remoteDirId, "testUpload"); const LocalTemporaryDirectory localTmpDir("testUpload"); const SyncPath localDestFilePath = localTmpDir.path() / "no_rights.txt"; @@ -766,7 +766,7 @@ void TestNetworkJobs::testDriveUploadSessionSynchronous() { CPPUNIT_ASSERT_EQUAL(static_cast(fileSizeLocal), fileSizeRemote); - // A file with no rights + // Uploading a file that has no rights should fail with `ExitCause::FileAccessError`. with no rights LOGW_DEBUG(Log::instance()->getLogger(), L"$$$$$ testDriveUploadSessionSynchronous No rights"); const SyncPath localFilePathNoRights = localTmpDir.path() / "no_rights.txt"; testhelpers::generateOrEditTestFile(localFilePathNoRights); From ffedf231d940bedb12aee00aff04d360fefeea8f Mon Sep 17 00:00:00 2001 From: Herve Eruam <82284536+herve-er@users.noreply.github.com> Date: Tue, 19 Nov 2024 08:29:09 +0100 Subject: [PATCH 103/178] Update test/libsyncengine/jobs/network/testnetworkjobs.cpp Co-authored-by: Luc Guyot <162997198+luc-guyot-infomaniak@users.noreply.github.com> --- test/libsyncengine/jobs/network/testnetworkjobs.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/libsyncengine/jobs/network/testnetworkjobs.cpp b/test/libsyncengine/jobs/network/testnetworkjobs.cpp index 8967ca946..b7f748944 100644 --- a/test/libsyncengine/jobs/network/testnetworkjobs.cpp +++ b/test/libsyncengine/jobs/network/testnetworkjobs.cpp @@ -649,7 +649,7 @@ void TestNetworkJobs::testRename() { } void TestNetworkJobs::testUpload() { - { // Test upload + { // Successful upload const RemoteTemporaryDirectory remoteTmpDir(_driveDbId, _remoteDirId, "testUpload"); SyncPath localFilePath = testhelpers::localTestDirPath / bigFileDirName / bigFileName; From 242169f3a93dd6ae74efe9efeb30b49487b72ac4 Mon Sep 17 00:00:00 2001 From: Herve Eruam Date: Tue, 19 Nov 2024 09:59:42 +0100 Subject: [PATCH 104/178] Extract file open method. --- src/libcommonserver/io/iohelper.cpp | 57 +++++++- src/libcommonserver/io/iohelper.h | 3 + .../upload_session/abstractuploadsession.cpp | 48 ++----- .../jobs/network/API_v2/uploadjob.cpp | 37 +---- test/libcommonserver/CMakeLists.txt | 2 +- test/libcommonserver/io/testio.h | 9 ++ test/libcommonserver/io/testopenfile.cpp | 127 ++++++++++++++++++ .../jobs/network/testnetworkjobs.cpp | 59 +++----- .../jobs/network/testnetworkjobs.h | 5 +- test/libsyncengine/jobs/testjobmanager.h | 6 +- test/libsyncengine/test.cpp | 7 +- 11 files changed, 239 insertions(+), 121 deletions(-) create mode 100644 test/libcommonserver/io/testopenfile.cpp diff --git a/src/libcommonserver/io/iohelper.cpp b/src/libcommonserver/io/iohelper.cpp index 64b4b9e6f..883187c96 100644 --- a/src/libcommonserver/io/iohelper.cpp +++ b/src/libcommonserver/io/iohelper.cpp @@ -29,7 +29,7 @@ #if defined(__APPLE__) || defined(__unix__) #include #endif - +#include #include // LOGW_WARN namespace KDC { @@ -150,6 +150,61 @@ std::string IoHelper::ioError2StdString(IoError ioError) noexcept { } } +bool IoHelper::openFile(const SyncPath &path, int timeOut /*in seconds*/, std::ifstream &file, IoError &ioError) { + int count = 0; + file.close(); + do { + file.open(path.native(), std::ifstream::binary); + if (!file.is_open()) { + bool exists = false; + if (!IoHelper::checkIfPathExists(path, exists, ioError)) { + LOGW_WARN(_logger, L"Error in IoHelper::checkIfPathExists: " << Utility::formatIoError(path, ioError)); + return isExpectedError(ioError); + } + if (ioError == IoError::AccessDenied) { + LOGW_WARN(_logger, L"Access denied to " << Utility::formatSyncPath(path)); + return isExpectedError(ioError); + } + if (!exists) { + LOGW_DEBUG(_logger, L"Item does not exist anymore - " << Utility::formatSyncPath(path)); + ioError = IoError::NoSuchFileOrDirectory; + return isExpectedError(ioError); + } + Utility::msleep(1000); + } + + // Some applications generate locked temporary files during save operations. To avoid spurious "access denied" errors, + // we retry for 10 seconds, which is usually sufficient for the application to delete the tmp file. If the file is still + // locked after 10 seconds, a file access error is displayed to the user. Proper handling is also implemented for + // "file not found" errors. + } while (++count < timeOut && !file.is_open()); + + if (count >= timeOut && !file.is_open()) { + LOGW_WARN(_logger, L"Failed to open file - " << Utility::formatSyncPath(path)); + ioError = IoError::AccessDenied; + return isExpectedError(ioError); + } + + ioError = IoError::Success; + return true; +} + +ExitInfo IoHelper::openFile(const SyncPath &path, int timeOut /*in seconds*/, std::ifstream &file) { + IoError ioError = IoError::Success; + openFile(path, timeOut, file, ioError); + switch (ioError) { + case IoError::Success: + return ExitCode::Ok; + case IoError::AccessDenied: + return ExitInfo{ExitCode::SystemError, ExitCause::FileAccessError}; + case IoError::NoSuchFileOrDirectory: + return ExitInfo{ExitCode::SystemError, ExitCause::NotFound}; + default: + LOG_WARN(logger(), "Unexpected read error for " << Utility::formatIoError(path, ioError)); + return ExitCode::SystemError; + } +} + bool IoHelper::isExpectedError(IoError ioError) noexcept { return (ioError == IoError::NoSuchFileOrDirectory) || (ioError == IoError::AccessDenied); } diff --git a/src/libcommonserver/io/iohelper.h b/src/libcommonserver/io/iohelper.h index 5dabcad4f..51a26c9e8 100644 --- a/src/libcommonserver/io/iohelper.h +++ b/src/libcommonserver/io/iohelper.h @@ -393,6 +393,9 @@ struct IoHelper { // The most common and expected errors during IO operations static bool isExpectedError(IoError ioError) noexcept; + static bool openFile(const SyncPath &path, int timeOut /*in seconds*/, std::ifstream &file, IoError &ioError); + static ExitInfo openFile(const SyncPath &path, int timeOut /*in seconds*/, std::ifstream &file); + protected: friend class DirectoryIterator; friend class TestIo; diff --git a/src/libsyncengine/jobs/network/API_v2/upload_session/abstractuploadsession.cpp b/src/libsyncengine/jobs/network/API_v2/upload_session/abstractuploadsession.cpp index 20d5c2514..af0abd210 100644 --- a/src/libsyncengine/jobs/network/API_v2/upload_session/abstractuploadsession.cpp +++ b/src/libsyncengine/jobs/network/API_v2/upload_session/abstractuploadsession.cpp @@ -180,7 +180,7 @@ bool AbstractUploadSession::canRun() { if (!exists) { LOGW_DEBUG(_logger, L"Item does not exist anymore. Aborting current sync and restart " - << Utility::formatSyncPath(_filePath.filename())); + << Utility::formatSyncPath(_filePath)); _exitCode = ExitCode::NeedRestart; _exitCause = ExitCause::UnexpectedFileSystemEvent; return false; @@ -266,47 +266,17 @@ bool AbstractUploadSession::sendChunks() { bool checksumError = false; bool jobCreationError = false; bool sendChunksCanceled = false; - std::ifstream file; - int count = 0; - do { - file.open(_filePath.native().c_str(), std::ifstream::binary); - if (!file.is_open()) { - bool exists = false; - IoError ioError = IoError::Success; - if (!IoHelper::checkIfPathExists(_filePath, exists, ioError)) { - LOGW_WARN(_logger, L"Error in IoHelper::checkIfPathExists: " << Utility::formatIoError(_filePath, ioError)); - _exitCode = ExitCode::SystemError; - return false; - } - if (ioError == IoError::AccessDenied) { - LOGW_WARN(_logger, L"Access denied to " << Utility::formatSyncPath(_filePath)); - _exitCode = ExitCode::SystemError; - _exitCause = ExitCause::FileAccessError; - return false; - } - if (!exists) { - LOGW_DEBUG(_logger, L"Item does not exist anymore - " << Utility::formatSyncPath(_filePath)); - _exitCode = ExitCode::SystemError; - _exitCause = ExitCause::NotFound; - return false; - } - Utility::msleep(1000); - } - - // Some applications generate locked temporary files during save operations. To avoid spurious "access denied" errors, - // we retry for 10 seconds, which is usually sufficient for the application to delete the tmp file. If the file is still - // locked after 10 seconds, a file access error is displayed to the user. Proper handling is also implemented for - // "file not found" errors. - } while (count++ < 10 && !file.is_open()); - if (count >= 10) { - LOGW_WARN(_logger, L"Failed to open file - " << Utility::formatSyncPath(_filePath)); - _exitCode = ExitCode::SystemError; - _exitCause = ExitCause::FileAccessError; - return false; + // Some applications generate locked temporary files during save operations. To avoid spurious "access denied" errors, + // we retry for 10 seconds, which is usually sufficient for the application to delete the tmp file. If the file is still + // locked after 10 seconds, a file access error is displayed to the user. Proper handling is also implemented for + // "file not found" errors. + std::ifstream file; + if (ExitInfo exitInfo = IoHelper::openFile(_filePath, 10, file); !exitInfo) { + LOGW_WARN(_logger, L"Failed to open file " << Utility::formatSyncPath(_filePath)); + return exitInfo; } - // Create a hash state XXH3_state_t *const state = XXH3_createState(); if (!state) { diff --git a/src/libsyncengine/jobs/network/API_v2/uploadjob.cpp b/src/libsyncengine/jobs/network/API_v2/uploadjob.cpp index fd8350015..7d3f958fc 100644 --- a/src/libsyncengine/jobs/network/API_v2/uploadjob.cpp +++ b/src/libsyncengine/jobs/network/API_v2/uploadjob.cpp @@ -185,37 +185,14 @@ std::string UploadJob::getContentType(bool &canceled) { } ExitInfo UploadJob::readFile() { + // Some applications generate locked temporary files during save operations. To avoid spurious "access denied" errors, + // we retry for 10 seconds, which is usually sufficient for the application to delete the tmp file. If the file is still + // locked after 10 seconds, a file access error is displayed to the user. Proper handling is also implemented for + // "file not found" errors. std::ifstream file; - int count = 0; - do { - file.open(_filePath, std::ios_base::in | std::ios_base::binary); - if (!file.is_open()) { - bool exists = false; - IoError ioError = IoError::Success; - if (!IoHelper::checkIfPathExists(_filePath, exists, ioError)) { - LOGW_WARN(_logger, L"Error in IoHelper::checkIfPathExists: " << Utility::formatIoError(_filePath, ioError)); - return {ExitCode::SystemError, ExitCause::Unknown}; - } - if (ioError == IoError::AccessDenied) { - LOGW_WARN(_logger, L"Access denied to " << Utility::formatSyncPath(_filePath)); - return {ExitCode::SystemError, ExitCause::FileAccessError}; - } - if (!exists) { - LOGW_DEBUG(_logger, L"Item does not exist anymore - " << Utility::formatSyncPath(_filePath)); - return {ExitCode::SystemError, ExitCause::NotFound}; - } - Utility::msleep(1000); - } - - // Some applications generate locked temporary files during save operations. To avoid spurious "access denied" errors, - // we retry for 10 seconds, which is usually sufficient for the application to delete the tmp file. If the file is still - // locked after 10 seconds, a file access error is displayed to the user. Proper handling is also implemented for - // "file not found" errors. - } while (count++ < 10 && !file.is_open()); - - if (count >= 10) { - LOGW_WARN(_logger, L"Failed to open file - path=" << Utility::formatSyncPath(_filePath)); - return {ExitCode::SystemError, ExitCause::FileAccessError}; + if (ExitInfo exitInfo = IoHelper::openFile(_filePath, 10, file); !exitInfo) { + LOGW_WARN(_logger, L"Failed to open file " << Utility::formatSyncPath(_filePath)); + return exitInfo; } std::ostringstream ostrm; diff --git a/test/libcommonserver/CMakeLists.txt b/test/libcommonserver/CMakeLists.txt index 665ba0b88..fdc2ba605 100644 --- a/test/libcommonserver/CMakeLists.txt +++ b/test/libcommonserver/CMakeLists.txt @@ -19,7 +19,7 @@ set(testcommonserver_SRCS db/testdb.h db/testdb.cpp # io io/testio.h io/testio.cpp io/testgetitemtype.cpp io/testgetfilesize.cpp io/testcheckifpathexists.cpp io/testgetnodeid.cpp io/testgetfilestat.cpp io/testgetrights.cpp io/testisfileaccessible.cpp io/testfilechanged.cpp - io/testcheckifisdirectory.cpp io/testcreatesymlink.cpp io/testcheckifdehydrated.cpp io/testcheckdirectoryiterator.cpp io/testchecksetgetrights.cpp + io/testcheckifisdirectory.cpp io/testcreatesymlink.cpp io/testcheckifdehydrated.cpp io/testcheckdirectoryiterator.cpp io/testchecksetgetrights.cpp io/testopenfile.cpp ) if (APPLE) diff --git a/test/libcommonserver/io/testio.h b/test/libcommonserver/io/testio.h index 1d8cf93c6..2f9b02e7f 100644 --- a/test/libcommonserver/io/testio.h +++ b/test/libcommonserver/io/testio.h @@ -71,6 +71,10 @@ class TestIo : public CppUnit::TestFixture { CPPUNIT_TEST(testCreateJunction); #endif CPPUNIT_TEST(testCheckIfFileIsDehydrated); + CPPUNIT_TEST(testOpenFileSuccess); + CPPUNIT_TEST(testOpenFileAccessDenied); + CPPUNIT_TEST(testOpenFileNonExisting); + CPPUNIT_TEST(testOpenFileAccessDeniedRemovedBeforeTimedOut); CPPUNIT_TEST_SUITE_END(); public: @@ -126,6 +130,11 @@ class TestIo : public CppUnit::TestFixture { void testCheckDirectoryRecursive(); void testCheckDirectoryIteratorUnexpectedDelete(); void testCheckDirectoryPermissionLost(); + void testOpenFileSuccess(); + void testOpenFileAccessDenied(); + void testOpenFileNonExisting(); + void testOpenFileAccessDeniedRemovedBeforeTimedOut(); + private: IoHelperTests *_testObj; diff --git a/test/libcommonserver/io/testopenfile.cpp b/test/libcommonserver/io/testopenfile.cpp new file mode 100644 index 000000000..d47df8de8 --- /dev/null +++ b/test/libcommonserver/io/testopenfile.cpp @@ -0,0 +1,127 @@ +/* + * Infomaniak kDrive - Desktop + * Copyright (C) 2023-2024 Infomaniak Network SA + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "testio.h" +#include "test_utility/testhelpers.h" + +using namespace CppUnit; + +namespace KDC { + +class TimeOutChecker { + public: + explicit TimeOutChecker(bool start = false) { + if (start) this->start(); + } + void start() { _time = std::chrono::steady_clock::now(); } + void stop() { + auto end = std::chrono::steady_clock::now(); + _diff = std::chrono::duration_cast(end - _time).count(); + } + bool lessThan(long long value) { return _diff < value; } + bool greaterThan(long long value) { return _diff > value; } + bool between(long long min, long long max) { return _diff > min && _diff < max; } + + private: + std::chrono::steady_clock::time_point _time; + long long _diff{0}; +}; + +bool checkContent(std::ifstream &file) { + std::string content; + std::getline(file, content); + return content == "test\n"; +} + +void TestIo::testOpenFileSuccess() { + LocalTemporaryDirectory tempDir("testOpenFileSuccess"); + SyncPath filePath = tempDir.path() / "testOpenFileSuccess.txt"; + testhelpers::generateOrEditTestFile(filePath); + std::ifstream file; + CPPUNIT_ASSERT(IoHelper::openFile(filePath, 0, file)); + CPPUNIT_ASSERT(file.is_open()); + CPPUNIT_ASSERT(checkContent(file)); + file.close(); +} + +void TestIo::testOpenFileAccessDenied() { + LocalTemporaryDirectory tempDir("testOpenFileAccessDenied"); + SyncPath filePath = tempDir.path() / "testOpenFileAccessDenied.txt"; + testhelpers::generateOrEditTestFile(filePath); + IoError ioError; + IoHelper::setRights(filePath, false, true, true, ioError); + CPPUNIT_ASSERT_EQUAL(IoError::Success, ioError); + + // Without timeout + std::ifstream file; + ExitInfo exitInfo = IoHelper::openFile(filePath, 0, file); + CPPUNIT_ASSERT_EQUAL(ExitInfo(ExitCode::SystemError, ExitCause::FileAccessError), exitInfo); + CPPUNIT_ASSERT(!file.is_open()); + + // Check timeout + auto start = std::chrono::steady_clock::now(); + TimeOutChecker timeOutChecker(true); + CPPUNIT_ASSERT_EQUAL(ExitInfo(ExitCode::SystemError, ExitCause::FileAccessError), IoHelper::openFile(filePath, 2, file)); + timeOutChecker.stop(); + CPPUNIT_ASSERT(timeOutChecker.between(2000, 2100)); + CPPUNIT_ASSERT(!file.is_open()); +} + +void TestIo::testOpenFileNonExisting() { + LocalTemporaryDirectory tempDir("testOpenFileNonExisting"); + SyncPath filePath = tempDir.path() / "testOpenFileNonExisting.txt"; + std::ifstream file; + TimeOutChecker timeOutChecker(true); + CPPUNIT_ASSERT_EQUAL(ExitInfo(ExitCode::SystemError, ExitCause::NotFound), IoHelper::openFile(filePath, 5, file)); + timeOutChecker.stop(); + CPPUNIT_ASSERT(timeOutChecker.lessThan(200)); + CPPUNIT_ASSERT(!file.is_open()); +} + +void TestIo::testOpenFileAccessDeniedRemovedBeforeTimedOut() { + LocalTemporaryDirectory tempDir("testOpenFileAccessDeniedRemovedBeforeTimedOut"); + SyncPath filePath = tempDir.path() / "testOpenFileAccessDeniedRemovedBeforeTimedOut.txt"; + testhelpers::generateOrEditTestFile(filePath); + IoError ioError; + IoHelper::setRights(filePath, false, true, true, ioError); + CPPUNIT_ASSERT_EQUAL(IoError::Success, ioError); + + std::ifstream file; + ExitInfo exitInfo = IoHelper::openFile(filePath, 5, file); + CPPUNIT_ASSERT_EQUAL(ExitInfo(ExitCode::SystemError, ExitCause::FileAccessError), exitInfo); + CPPUNIT_ASSERT(!file.is_open()); + + IoHelper::setRights(filePath, true, true, true, ioError); + CPPUNIT_ASSERT_EQUAL(IoError::Success, ioError); + + std::function restoreRights = [filePath, &ioError]() { + Utility::msleep(2000); + IoHelper::setRights(filePath, false, true, true, ioError); + CPPUNIT_ASSERT_EQUAL(IoError::Success, ioError); + }; + std::thread restoreRightsThread(restoreRights); + TimeOutChecker timeOutChecker(true); + CPPUNIT_ASSERT_EQUAL(ExitInfo(ExitCode::Ok), IoHelper::openFile(filePath, 4, file)); + timeOutChecker.stop(); + restoreRightsThread.join(); + CPPUNIT_ASSERT(timeOutChecker.between(2000, 2200)); + CPPUNIT_ASSERT(file.is_open()); + CPPUNIT_ASSERT(checkContent(file)); + file.close(); +} +} // namespace KDC diff --git a/test/libsyncengine/jobs/network/testnetworkjobs.cpp b/test/libsyncengine/jobs/network/testnetworkjobs.cpp index b7f748944..807f5636e 100644 --- a/test/libsyncengine/jobs/network/testnetworkjobs.cpp +++ b/test/libsyncengine/jobs/network/testnetworkjobs.cpp @@ -649,41 +649,26 @@ void TestNetworkJobs::testRename() { } void TestNetworkJobs::testUpload() { - { // Successful upload - const RemoteTemporaryDirectory remoteTmpDir(_driveDbId, _remoteDirId, "testUpload"); - SyncPath localFilePath = testhelpers::localTestDirPath / bigFileDirName / bigFileName; + // Successful upload + const RemoteTemporaryDirectory remoteTmpDir(_driveDbId, _remoteDirId, "testUpload"); + SyncPath localFilePath = testhelpers::localTestDirPath / bigFileDirName / bigFileName; - UploadJob job(_driveDbId, localFilePath, localFilePath.filename().native(), remoteTmpDir.id(), 0); - ExitCode exitCode = job.runSynchronously(); - CPPUNIT_ASSERT(exitCode == ExitCode::Ok); + UploadJob job(_driveDbId, localFilePath, localFilePath.filename().native(), remoteTmpDir.id(), 0); + ExitCode exitCode = job.runSynchronously(); + CPPUNIT_ASSERT(exitCode == ExitCode::Ok); - NodeId newNodeId = job.nodeId(); + NodeId newNodeId = job.nodeId(); - GetFileInfoJob fileInfoJob(_driveDbId, newNodeId); - exitCode = fileInfoJob.runSynchronously(); - CPPUNIT_ASSERT(exitCode == ExitCode::Ok); + GetFileInfoJob fileInfoJob(_driveDbId, newNodeId); + exitCode = fileInfoJob.runSynchronously(); + CPPUNIT_ASSERT(exitCode == ExitCode::Ok); - Poco::JSON::Object::Ptr dataObj = fileInfoJob.jsonRes()->getObject(dataKey); - std::string name; - if (dataObj) { - name = dataObj->get(nameKey).toString(); - } - CPPUNIT_ASSERT(name == bigFileName); - } - { // Uploading a file that has no read rights should fail with `ExitCause::FileAccessError`. - const RemoteTemporaryDirectory remoteTmpDir(_driveDbId, _remoteDirId, "testUpload"); - const LocalTemporaryDirectory localTmpDir("testUpload"); - const SyncPath localDestFilePath = localTmpDir.path() / "no_rights.txt"; - testhelpers::generateOrEditTestFile(localDestFilePath); - IoError ioError = IoError::Unknown; - IoHelper::setRights(localDestFilePath, false, true, true, ioError); - CPPUNIT_ASSERT_EQUAL(IoError::Success, ioError); - - UploadJob job(_driveDbId, localDestFilePath, localDestFilePath.filename().native(), remoteTmpDir.id(), 0); - ExitCode exitCode = job.runSynchronously(); - CPPUNIT_ASSERT_EQUAL(ExitCode::SystemError, exitCode); - CPPUNIT_ASSERT_EQUAL(ExitCause::FileAccessError, job.exitCause()); + Poco::JSON::Object::Ptr dataObj = fileInfoJob.jsonRes()->getObject(dataKey); + std::string name; + if (dataObj) { + name = dataObj->get(nameKey).toString(); } + CPPUNIT_ASSERT(name == bigFileName); } void TestNetworkJobs::testUploadAborted() { @@ -765,20 +750,6 @@ void TestNetworkJobs::testDriveUploadSessionSynchronous() { int64_t fileSizeRemote = fileSizeJob.size(); CPPUNIT_ASSERT_EQUAL(static_cast(fileSizeLocal), fileSizeRemote); - - // Uploading a file that has no rights should fail with `ExitCause::FileAccessError`. with no rights - LOGW_DEBUG(Log::instance()->getLogger(), L"$$$$$ testDriveUploadSessionSynchronous No rights"); - const SyncPath localFilePathNoRights = localTmpDir.path() / "no_rights.txt"; - testhelpers::generateOrEditTestFile(localFilePathNoRights); - IoHelper::setRights(localFilePathNoRights, false, true, true, ioError); - CPPUNIT_ASSERT_EQUAL(IoError::Success, ioError); - - DriveUploadSession driveUploadSessionJobNoRights(_driveDbId, nullptr, localFilePathNoRights, - localFilePathNoRights.filename().native(), remoteTmpDir.id(), 12345, false, - 1); - exitCode = driveUploadSessionJobNoRights.runSynchronously(); - CPPUNIT_ASSERT_EQUAL(ExitCode::SystemError, exitCode); - CPPUNIT_ASSERT_EQUAL(ExitCause::FileAccessError, driveUploadSessionJobNoRights.exitCause()); } void TestNetworkJobs::testDriveUploadSessionAsynchronous() { diff --git a/test/libsyncengine/jobs/network/testnetworkjobs.h b/test/libsyncengine/jobs/network/testnetworkjobs.h index d5b2c60ca..894ed71f0 100644 --- a/test/libsyncengine/jobs/network/testnetworkjobs.h +++ b/test/libsyncengine/jobs/network/testnetworkjobs.h @@ -26,7 +26,7 @@ namespace KDC { class TestNetworkJobs : public CppUnit::TestFixture { public: CPPUNIT_TEST_SUITE(TestNetworkJobs); - CPPUNIT_TEST(testCreateDir); + /* CPPUNIT_TEST(testCreateDir); CPPUNIT_TEST(testCopyToDir); CPPUNIT_TEST(testDelete); CPPUNIT_TEST(testDownload); @@ -56,7 +56,8 @@ class TestNetworkJobs : public CppUnit::TestFixture { CPPUNIT_TEST(testDriveUploadSessionSynchronousAborted); CPPUNIT_TEST(testDriveUploadSessionAsynchronousAborted); CPPUNIT_TEST(testGetAppVersionInfo); - CPPUNIT_TEST(testDirectDownload); + CPPUNIT_TEST(testDirectDownload);*/ + CPPUNIT_TEST(testUpload); CPPUNIT_TEST_SUITE_END(); public: diff --git a/test/libsyncengine/jobs/testjobmanager.h b/test/libsyncengine/jobs/testjobmanager.h index af1b4a70b..8a8ac6dd2 100644 --- a/test/libsyncengine/jobs/testjobmanager.h +++ b/test/libsyncengine/jobs/testjobmanager.h @@ -37,7 +37,9 @@ namespace KDC { class TestJobManager : public CppUnit::TestFixture { public: CPPUNIT_TEST_SUITE(TestJobManager); - CPPUNIT_TEST(testWithoutCallback); + //CPPUNIT_TEST(testCancelJobs); + + /*CPPUNIT_TEST(testWithoutCallback); CPPUNIT_TEST(testWithCallback); CPPUNIT_TEST(testWithCallbackMediumFiles); CPPUNIT_TEST(testWithCallbackBigFiles); @@ -45,7 +47,7 @@ class TestJobManager : public CppUnit::TestFixture { CPPUNIT_TEST(testJobDependencies); CPPUNIT_TEST(testJobPriority); CPPUNIT_TEST(testJobPriority2); - CPPUNIT_TEST(testJobPriority3); + CPPUNIT_TEST(testJobPriority3);*/ // CPPUNIT_TEST(testReuseSocket); CPPUNIT_TEST_SUITE_END(); diff --git a/test/libsyncengine/test.cpp b/test/libsyncengine/test.cpp index e66b19270..e9f641163 100644 --- a/test/libsyncengine/test.cpp +++ b/test/libsyncengine/test.cpp @@ -48,7 +48,10 @@ #endif namespace KDC { -CPPUNIT_TEST_SUITE_REGISTRATION(TestExclusionTemplateCache); +CPPUNIT_TEST_SUITE_REGISTRATION(TestJobManager); +CPPUNIT_TEST_SUITE_REGISTRATION(TestNetworkJobs); + +/*CPPUNIT_TEST_SUITE_REGISTRATION(TestExclusionTemplateCache); CPPUNIT_TEST_SUITE_REGISTRATION(TestSyncDb); CPPUNIT_TEST_SUITE_REGISTRATION(TestLocalJobs); @@ -77,7 +80,7 @@ CPPUNIT_TEST_SUITE_REGISTRATION(TestConflictResolverWorker); CPPUNIT_TEST_SUITE_REGISTRATION(TestExecutorWorker); CPPUNIT_TEST_SUITE_REGISTRATION(TestSyncPal); // CPPUNIT_TEST_SUITE_REGISTRATION(TestIntegration); -CPPUNIT_TEST_SUITE_REGISTRATION(TestServerRequests); +CPPUNIT_TEST_SUITE_REGISTRATION(TestServerRequests);*/ } // namespace KDC int main(int, char **) { From 32725cd94c2b9c12514fca8f045c98dcd0d9db05 Mon Sep 17 00:00:00 2001 From: Herve Eruam Date: Tue, 19 Nov 2024 10:10:21 +0100 Subject: [PATCH 105/178] Reactivate some tests and fix log error. --- src/libcommonserver/io/iohelper.cpp | 11 +++-------- test/libsyncengine/jobs/network/testnetworkjobs.h | 4 ++-- test/libsyncengine/jobs/testjobmanager.h | 6 ++---- test/libsyncengine/test.cpp | 7 ++----- 4 files changed, 9 insertions(+), 19 deletions(-) diff --git a/src/libcommonserver/io/iohelper.cpp b/src/libcommonserver/io/iohelper.cpp index 883187c96..445879365 100644 --- a/src/libcommonserver/io/iohelper.cpp +++ b/src/libcommonserver/io/iohelper.cpp @@ -152,7 +152,7 @@ std::string IoHelper::ioError2StdString(IoError ioError) noexcept { bool IoHelper::openFile(const SyncPath &path, int timeOut /*in seconds*/, std::ifstream &file, IoError &ioError) { int count = 0; - file.close(); + if (file.is_open()) file.close(); do { file.open(path.native(), std::ifstream::binary); if (!file.is_open()) { @@ -172,14 +172,9 @@ bool IoHelper::openFile(const SyncPath &path, int timeOut /*in seconds*/, std::i } Utility::msleep(1000); } - - // Some applications generate locked temporary files during save operations. To avoid spurious "access denied" errors, - // we retry for 10 seconds, which is usually sufficient for the application to delete the tmp file. If the file is still - // locked after 10 seconds, a file access error is displayed to the user. Proper handling is also implemented for - // "file not found" errors. } while (++count < timeOut && !file.is_open()); - if (count >= timeOut && !file.is_open()) { + if (!file.is_open()) { LOGW_WARN(_logger, L"Failed to open file - " << Utility::formatSyncPath(path)); ioError = IoError::AccessDenied; return isExpectedError(ioError); @@ -200,7 +195,7 @@ ExitInfo IoHelper::openFile(const SyncPath &path, int timeOut /*in seconds*/, st case IoError::NoSuchFileOrDirectory: return ExitInfo{ExitCode::SystemError, ExitCause::NotFound}; default: - LOG_WARN(logger(), "Unexpected read error for " << Utility::formatIoError(path, ioError)); + LOG_WARN(logger(), L"Unexpected read error for " << Utility::formatIoError(path, ioError)); return ExitCode::SystemError; } } diff --git a/test/libsyncengine/jobs/network/testnetworkjobs.h b/test/libsyncengine/jobs/network/testnetworkjobs.h index 894ed71f0..949e52d7d 100644 --- a/test/libsyncengine/jobs/network/testnetworkjobs.h +++ b/test/libsyncengine/jobs/network/testnetworkjobs.h @@ -26,7 +26,7 @@ namespace KDC { class TestNetworkJobs : public CppUnit::TestFixture { public: CPPUNIT_TEST_SUITE(TestNetworkJobs); - /* CPPUNIT_TEST(testCreateDir); + CPPUNIT_TEST(testCreateDir); CPPUNIT_TEST(testCopyToDir); CPPUNIT_TEST(testDelete); CPPUNIT_TEST(testDownload); @@ -56,7 +56,7 @@ class TestNetworkJobs : public CppUnit::TestFixture { CPPUNIT_TEST(testDriveUploadSessionSynchronousAborted); CPPUNIT_TEST(testDriveUploadSessionAsynchronousAborted); CPPUNIT_TEST(testGetAppVersionInfo); - CPPUNIT_TEST(testDirectDownload);*/ + CPPUNIT_TEST(testDirectDownload); CPPUNIT_TEST(testUpload); CPPUNIT_TEST_SUITE_END(); diff --git a/test/libsyncengine/jobs/testjobmanager.h b/test/libsyncengine/jobs/testjobmanager.h index 8a8ac6dd2..af1b4a70b 100644 --- a/test/libsyncengine/jobs/testjobmanager.h +++ b/test/libsyncengine/jobs/testjobmanager.h @@ -37,9 +37,7 @@ namespace KDC { class TestJobManager : public CppUnit::TestFixture { public: CPPUNIT_TEST_SUITE(TestJobManager); - //CPPUNIT_TEST(testCancelJobs); - - /*CPPUNIT_TEST(testWithoutCallback); + CPPUNIT_TEST(testWithoutCallback); CPPUNIT_TEST(testWithCallback); CPPUNIT_TEST(testWithCallbackMediumFiles); CPPUNIT_TEST(testWithCallbackBigFiles); @@ -47,7 +45,7 @@ class TestJobManager : public CppUnit::TestFixture { CPPUNIT_TEST(testJobDependencies); CPPUNIT_TEST(testJobPriority); CPPUNIT_TEST(testJobPriority2); - CPPUNIT_TEST(testJobPriority3);*/ + CPPUNIT_TEST(testJobPriority3); // CPPUNIT_TEST(testReuseSocket); CPPUNIT_TEST_SUITE_END(); diff --git a/test/libsyncengine/test.cpp b/test/libsyncengine/test.cpp index e9f641163..e66b19270 100644 --- a/test/libsyncengine/test.cpp +++ b/test/libsyncengine/test.cpp @@ -48,10 +48,7 @@ #endif namespace KDC { -CPPUNIT_TEST_SUITE_REGISTRATION(TestJobManager); -CPPUNIT_TEST_SUITE_REGISTRATION(TestNetworkJobs); - -/*CPPUNIT_TEST_SUITE_REGISTRATION(TestExclusionTemplateCache); +CPPUNIT_TEST_SUITE_REGISTRATION(TestExclusionTemplateCache); CPPUNIT_TEST_SUITE_REGISTRATION(TestSyncDb); CPPUNIT_TEST_SUITE_REGISTRATION(TestLocalJobs); @@ -80,7 +77,7 @@ CPPUNIT_TEST_SUITE_REGISTRATION(TestConflictResolverWorker); CPPUNIT_TEST_SUITE_REGISTRATION(TestExecutorWorker); CPPUNIT_TEST_SUITE_REGISTRATION(TestSyncPal); // CPPUNIT_TEST_SUITE_REGISTRATION(TestIntegration); -CPPUNIT_TEST_SUITE_REGISTRATION(TestServerRequests);*/ +CPPUNIT_TEST_SUITE_REGISTRATION(TestServerRequests); } // namespace KDC int main(int, char **) { From aa6b05fadb20df79e88166f811fa50d88e22afb2 Mon Sep 17 00:00:00 2001 From: Herve Eruam Date: Tue, 19 Nov 2024 10:12:47 +0100 Subject: [PATCH 106/178] Remove duplicate test run. --- test/libcommonserver/io/testio.h | 1 - test/libsyncengine/jobs/network/testnetworkjobs.h | 1 - 2 files changed, 2 deletions(-) diff --git a/test/libcommonserver/io/testio.h b/test/libcommonserver/io/testio.h index 2f9b02e7f..c36778815 100644 --- a/test/libcommonserver/io/testio.h +++ b/test/libcommonserver/io/testio.h @@ -135,7 +135,6 @@ class TestIo : public CppUnit::TestFixture { void testOpenFileNonExisting(); void testOpenFileAccessDeniedRemovedBeforeTimedOut(); - private: IoHelperTests *_testObj; const SyncPath _localTestDirPath; diff --git a/test/libsyncengine/jobs/network/testnetworkjobs.h b/test/libsyncengine/jobs/network/testnetworkjobs.h index 949e52d7d..d5b2c60ca 100644 --- a/test/libsyncengine/jobs/network/testnetworkjobs.h +++ b/test/libsyncengine/jobs/network/testnetworkjobs.h @@ -57,7 +57,6 @@ class TestNetworkJobs : public CppUnit::TestFixture { CPPUNIT_TEST(testDriveUploadSessionAsynchronousAborted); CPPUNIT_TEST(testGetAppVersionInfo); CPPUNIT_TEST(testDirectDownload); - CPPUNIT_TEST(testUpload); CPPUNIT_TEST_SUITE_END(); public: From 68422f7d6d4fd068bd83e3a708b0ddd3a00477ab Mon Sep 17 00:00:00 2001 From: Christophe Larchier Date: Tue, 19 Nov 2024 10:19:10 +0100 Subject: [PATCH 107/178] Fix SyncPalWorker --- src/libsyncengine/syncpal/isyncworker.cpp | 22 ++++----------------- src/libsyncengine/syncpal/syncpal.cpp | 12 +++++------ src/libsyncengine/syncpal/syncpalworker.cpp | 1 + 3 files changed, 11 insertions(+), 24 deletions(-) diff --git a/src/libsyncengine/syncpal/isyncworker.cpp b/src/libsyncengine/syncpal/isyncworker.cpp index 1d2e26935..713cad2cc 100644 --- a/src/libsyncengine/syncpal/isyncworker.cpp +++ b/src/libsyncengine/syncpal/isyncworker.cpp @@ -31,11 +31,6 @@ ISyncWorker::~ISyncWorker() { stop(); } - if (_thread && _thread->joinable()) { - _thread->join(); - _thread = nullptr; - } - LOG_SYNCPAL_DEBUG(_logger, "Worker " << _name.c_str() << " destroyed"); log4cplus::threadCleanup(); } @@ -48,12 +43,6 @@ void ISyncWorker::start() { LOG_SYNCPAL_DEBUG(_logger, "Worker " << _name.c_str() << " start"); - if (_thread && _thread->joinable()) { - _thread->join(); - _thread.release(); - _thread = nullptr; - } - _stopAsked = false; _isRunning = true; _exitCause = ExitCause::Unknown; @@ -115,14 +104,11 @@ void ISyncWorker::stop() { } void ISyncWorker::waitForExit() { - if (!_isRunning) { - LOG_SYNCPAL_DEBUG(_logger, "Worker " << _name.c_str() << " is not running"); - return; + if (_thread && _thread->joinable()) { + _thread->join(); + _thread.release(); + _thread = nullptr; } - - _thread->join(); - - _isRunning = false; } void ISyncWorker::setPauseDone() { diff --git a/src/libsyncengine/syncpal/syncpal.cpp b/src/libsyncengine/syncpal/syncpal.cpp index 8c8ac86a2..60e303888 100644 --- a/src/libsyncengine/syncpal/syncpal.cpp +++ b/src/libsyncengine/syncpal/syncpal.cpp @@ -531,12 +531,12 @@ void SyncPal::createSharedObjects() { void SyncPal::resetSharedObjects() { LOG_SYNCPAL_DEBUG(_logger, "Reset shared objects"); - _localOperationSet->clear(); - _remoteOperationSet->clear(); - _localUpdateTree->init(); - _remoteUpdateTree->init(); - _conflictQueue->clear(); - _syncOps->clear(); + if (_localOperationSet) _localOperationSet->clear(); + if (_remoteOperationSet) _remoteOperationSet->clear(); + if (_localUpdateTree) _localUpdateTree->init(); + if (_remoteUpdateTree) _remoteUpdateTree->init(); + if (_conflictQueue) _conflictQueue->clear(); + if (_syncOps) _syncOps->clear(); setSyncHasFullyCompleted(false); LOG_SYNCPAL_DEBUG(_logger, "Reset shared objects done"); diff --git a/src/libsyncengine/syncpal/syncpalworker.cpp b/src/libsyncengine/syncpal/syncpalworker.cpp index 398e82b41..7db15d1ff 100644 --- a/src/libsyncengine/syncpal/syncpalworker.cpp +++ b/src/libsyncengine/syncpal/syncpalworker.cpp @@ -136,6 +136,7 @@ void SyncPalWorker::execute() { SyncStep step = nextStep(); if (step != _step) { LOG_SYNCPAL_INFO(_logger, "***** Step " << stepName(_step).c_str() << " has finished"); + waitForExitOfWorkers(stepWorkers); initStep(step, stepWorkers, inputSharedObject); isStepInProgress = false; } From 47d181ac98f136c35466863b15e7eb0e9d3a2a67 Mon Sep 17 00:00:00 2001 From: Herve Eruam Date: Tue, 19 Nov 2024 10:19:16 +0100 Subject: [PATCH 108/178] Fix a W log. --- src/libcommonserver/io/iohelper.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcommonserver/io/iohelper.cpp b/src/libcommonserver/io/iohelper.cpp index 445879365..a973cf3f3 100644 --- a/src/libcommonserver/io/iohelper.cpp +++ b/src/libcommonserver/io/iohelper.cpp @@ -195,7 +195,7 @@ ExitInfo IoHelper::openFile(const SyncPath &path, int timeOut /*in seconds*/, st case IoError::NoSuchFileOrDirectory: return ExitInfo{ExitCode::SystemError, ExitCause::NotFound}; default: - LOG_WARN(logger(), L"Unexpected read error for " << Utility::formatIoError(path, ioError)); + LOGW_WARN(logger(), L"Unexpected read error for " << Utility::formatIoError(path, ioError)); return ExitCode::SystemError; } } From 5fa457ddf6fa9d22884f34723a190c1b2f74079f Mon Sep 17 00:00:00 2001 From: Christophe Larchier Date: Tue, 19 Nov 2024 10:21:16 +0100 Subject: [PATCH 109/178] Use snapshotCopy function instead of snapshot(..., true) --- src/libsyncengine/syncpal/operationprocessor.cpp | 4 ++-- src/libsyncengine/syncpal/syncpal.cpp | 4 ++-- src/libsyncengine/syncpal/syncpal.h | 2 +- src/libsyncengine/syncpal/syncpalworker.cpp | 8 ++++---- .../computefsoperationworker.cpp | 16 ++++++++-------- .../file_system_observer/snapshot/snapshot.cpp | 10 +++++----- .../file_system_observer/snapshot/snapshot.h | 4 ++-- 7 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/libsyncengine/syncpal/operationprocessor.cpp b/src/libsyncengine/syncpal/operationprocessor.cpp index f0644e24d..62224bbc0 100644 --- a/src/libsyncengine/syncpal/operationprocessor.cpp +++ b/src/libsyncengine/syncpal/operationprocessor.cpp @@ -31,8 +31,8 @@ bool OperationProcessor::isPseudoConflict(std::shared_ptr node, std::share return false; } - std::shared_ptr snapshot = _syncPal->snapshot(node->side(), true); - std::shared_ptr otherSnapshot = _syncPal->snapshot(correspondingNode->side(), true); + std::shared_ptr snapshot = _syncPal->snapshotCopy(node->side()); + std::shared_ptr otherSnapshot = _syncPal->snapshotCopy(correspondingNode->side()); // Create-Create pseudo-conflict if (node->hasChangeEvent(OperationType::Create) && correspondingNode->hasChangeEvent(OperationType::Create) && diff --git a/src/libsyncengine/syncpal/syncpal.cpp b/src/libsyncengine/syncpal/syncpal.cpp index 8c8ac86a2..e1b2d62f8 100644 --- a/src/libsyncengine/syncpal/syncpal.cpp +++ b/src/libsyncengine/syncpal/syncpal.cpp @@ -943,8 +943,8 @@ ExitCode SyncPal::updateSyncNode(SyncNodeType syncNodeType) { auto nodeIdIt = nodeIdSet.begin(); while (nodeIdIt != nodeIdSet.end()) { - const bool ok = syncNodeType == SyncNodeType::TmpLocalBlacklist ? snapshot(ReplicaSide::Local, true)->exists(*nodeIdIt) - : snapshot(ReplicaSide::Remote, true)->exists(*nodeIdIt); + const bool ok = syncNodeType == SyncNodeType::TmpLocalBlacklist ? snapshotCopy(ReplicaSide::Local)->exists(*nodeIdIt) + : snapshotCopy(ReplicaSide::Remote)->exists(*nodeIdIt); if (!ok) { nodeIdIt = nodeIdSet.erase(nodeIdIt); } else { diff --git a/src/libsyncengine/syncpal/syncpal.h b/src/libsyncengine/syncpal/syncpal.h index 2a23b2d7a..c2fb34a28 100644 --- a/src/libsyncengine/syncpal/syncpal.h +++ b/src/libsyncengine/syncpal/syncpal.h @@ -353,7 +353,7 @@ class SYNCENGINE_EXPORT SyncPal : public std::enable_shared_from_this { ExitCode updateSyncNode(SyncNodeType syncNodeType); ExitCode updateSyncNode(); std::shared_ptr snapshot(ReplicaSide side, bool copy = false) const; - const std::shared_ptr snapshotCopy(ReplicaSide side) { return snapshot(side, true); }; + const std::shared_ptr snapshotCopy(ReplicaSide side) { return snapshot(side, true); } std::shared_ptr operationSet(ReplicaSide side) const; std::shared_ptr updateTree(ReplicaSide side) const; diff --git a/src/libsyncengine/syncpal/syncpalworker.cpp b/src/libsyncengine/syncpal/syncpalworker.cpp index 398e82b41..704eb0fba 100644 --- a/src/libsyncengine/syncpal/syncpalworker.cpp +++ b/src/libsyncengine/syncpal/syncpalworker.cpp @@ -287,12 +287,12 @@ void SyncPalWorker::initStep(SyncStep step, std::shared_ptr (&worke workers[0] = _syncPal->computeFSOperationsWorker(); workers[1] = nullptr; _syncPal->copySnapshots(); - assert(_syncPal->snapshot(ReplicaSide::Local, true)->checkIntegrityRecursively() && + assert(_syncPal->snapshotCopy(ReplicaSide::Local)->checkIntegrityRecursively() && "Local snapshot is corrupted, see logs for details"); - assert(_syncPal->snapshot(ReplicaSide::Remote, true)->checkIntegrityRecursively() && + assert(_syncPal->snapshotCopy(ReplicaSide::Remote)->checkIntegrityRecursively() && "Remote snapshot is corrupted, see logs for details"); - inputSharedObject[0] = _syncPal->snapshot(ReplicaSide::Local, true); - inputSharedObject[1] = _syncPal->snapshot(ReplicaSide::Remote, true); + inputSharedObject[0] = nullptr; + inputSharedObject[1] = nullptr; _syncPal->setRestart(false); break; case SyncStep::UpdateDetection2: diff --git a/src/libsyncengine/update_detection/file_system_observer/computefsoperationworker.cpp b/src/libsyncengine/update_detection/file_system_observer/computefsoperationworker.cpp index 8352df475..9605dc002 100644 --- a/src/libsyncengine/update_detection/file_system_observer/computefsoperationworker.cpp +++ b/src/libsyncengine/update_detection/file_system_observer/computefsoperationworker.cpp @@ -574,29 +574,29 @@ ExitCode ComputeFSOperationWorker::checkFileIntegrity(const DbNode &dbNode) { return ExitCode::Ok; } - if (!_syncPal->snapshot(ReplicaSide::Local, true)->exists(dbNode.nodeIdLocal().value()) || - !_syncPal->snapshot(ReplicaSide::Remote, true)->exists(dbNode.nodeIdRemote().value())) { + if (!_syncPal->snapshotCopy(ReplicaSide::Local)->exists(dbNode.nodeIdLocal().value()) || + !_syncPal->snapshotCopy(ReplicaSide::Remote)->exists(dbNode.nodeIdRemote().value())) { // Ignore if item does not exist return ExitCode::Ok; } - if (const bool localSnapshotIsLink = _syncPal->snapshot(ReplicaSide::Local, true)->isLink(dbNode.nodeIdLocal().value()); + if (const bool localSnapshotIsLink = _syncPal->snapshotCopy(ReplicaSide::Local)->isLink(dbNode.nodeIdLocal().value()); localSnapshotIsLink) { // Local and remote links sizes are not always the same (macOS aliases, Windows junctions) return ExitCode::Ok; } - int64_t localSnapshotSize = _syncPal->snapshot(ReplicaSide::Local, true)->size(dbNode.nodeIdLocal().value()); - int64_t remoteSnapshotSize = _syncPal->snapshot(ReplicaSide::Remote, true)->size(dbNode.nodeIdRemote().value()); - SyncTime localSnapshotLastModified = _syncPal->snapshot(ReplicaSide::Local, true)->lastModified(dbNode.nodeIdLocal().value()); + int64_t localSnapshotSize = _syncPal->snapshotCopy(ReplicaSide::Local)->size(dbNode.nodeIdLocal().value()); + int64_t remoteSnapshotSize = _syncPal->snapshotCopy(ReplicaSide::Remote)->size(dbNode.nodeIdRemote().value()); + SyncTime localSnapshotLastModified = _syncPal->snapshotCopy(ReplicaSide::Local)->lastModified(dbNode.nodeIdLocal().value()); SyncTime remoteSnapshotLastModified = - _syncPal->snapshot(ReplicaSide::Remote, true)->lastModified(dbNode.nodeIdRemote().value()); + _syncPal->snapshotCopy(ReplicaSide::Remote)->lastModified(dbNode.nodeIdRemote().value()); // A mismatch is detected if all timestamps are equal but the sizes in snapshots differ. if (localSnapshotSize != remoteSnapshotSize && localSnapshotLastModified == dbNode.lastModifiedLocal().value() && localSnapshotLastModified == remoteSnapshotLastModified) { SyncPath localSnapshotPath; - if (!_syncPal->snapshot(ReplicaSide::Local, true)->path(dbNode.nodeIdLocal().value(), localSnapshotPath)) { + if (!_syncPal->snapshotCopy(ReplicaSide::Local)->path(dbNode.nodeIdLocal().value(), localSnapshotPath)) { LOGW_SYNCPAL_WARN(_logger, L"Failed to retrieve path from snapshot for item " << SyncName2WStr(dbNode.nameLocal()) << L" (" << Utility::s2ws(dbNode.nodeIdLocal().value()) << L")"); diff --git a/src/libsyncengine/update_detection/file_system_observer/snapshot/snapshot.cpp b/src/libsyncengine/update_detection/file_system_observer/snapshot/snapshot.cpp index 23509e9e2..e6189dbe1 100644 --- a/src/libsyncengine/update_detection/file_system_observer/snapshot/snapshot.cpp +++ b/src/libsyncengine/update_detection/file_system_observer/snapshot/snapshot.cpp @@ -482,25 +482,25 @@ void Snapshot::setValid(bool newIsValid) { _isValid = newIsValid; } -bool Snapshot::checkIntegrityRecursively() { +bool Snapshot::checkIntegrityRecursively() const { return checkIntegrityRecursively(rootFolderId()); } -bool Snapshot::checkIntegrityRecursively(const NodeId &parentId) { +bool Snapshot::checkIntegrityRecursively(const NodeId &parentId) const { // Check that we do not have the same file twice in the same folder - const auto &parentItem = _items[parentId]; + const auto &parentItem = _items.at(parentId); std::set names; for (auto childId = parentItem.childrenIds().begin(), end = parentItem.childrenIds().end(); childId != end; childId++) { if (!checkIntegrityRecursively(*childId)) { return false; } - auto result = names.insert(_items[*childId].name()); + auto result = names.insert(_items.at(*childId).name()); if (!result.second) { LOGW_WARN(Log::instance()->getLogger(), L"Snapshot integrity check failed, the folder named: \"" << SyncName2WStr(parentItem.name()).c_str() << L"\"(" << Utility::s2ws(parentItem.id()).c_str() << L") contains: \"" - << SyncName2WStr(_items[*childId].name()).c_str() + << SyncName2WStr(_items.at(*childId).name()).c_str() << L"\" twice with two differents NodeId"); return false; } diff --git a/src/libsyncengine/update_detection/file_system_observer/snapshot/snapshot.h b/src/libsyncengine/update_detection/file_system_observer/snapshot/snapshot.h index 311a9eaa6..a52589731 100644 --- a/src/libsyncengine/update_detection/file_system_observer/snapshot/snapshot.h +++ b/src/libsyncengine/update_detection/file_system_observer/snapshot/snapshot.h @@ -83,11 +83,11 @@ class Snapshot : public SharedObject { bool isValid() const; void setValid(bool newIsValid); - bool checkIntegrityRecursively(); + bool checkIntegrityRecursively() const; private: void removeChildrenRecursively(const NodeId &parentId); - bool checkIntegrityRecursively(const NodeId &parentId); + bool checkIntegrityRecursively(const NodeId &parentId) const; ReplicaSide _side = ReplicaSide::Unknown; NodeId _rootFolderId; From 5ab704e37f7ab3fb2dd8b88a51951e862fd8c965 Mon Sep 17 00:00:00 2001 From: Christophe Larchier Date: Tue, 19 Nov 2024 10:21:50 +0100 Subject: [PATCH 110/178] Fix commserver --- src/libcommonserver/commserver.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libcommonserver/commserver.cpp b/src/libcommonserver/commserver.cpp index 6dbef9f91..deeb06f32 100644 --- a/src/libcommonserver/commserver.cpp +++ b/src/libcommonserver/commserver.cpp @@ -19,8 +19,9 @@ #include "commserver.h" #include "common/utility.h" #include "libcommon/comm.h" -#include "libcommonserver/log/log.h" #include "libcommon/utility/utility.h" +#include "libcommonserver/log/log.h" +#include "libcommonserver/utility/utility.h" #include #include @@ -397,6 +398,7 @@ void Worker::onStart() { } LOG_DEBUG(Log::instance()->getLogger(), "Worker ended"); + Utility::terminateThreadFunction(); } } // namespace KDC From f288be06968876e6bfcf2eedfef10c68e88dd0d1 Mon Sep 17 00:00:00 2001 From: Herve Eruam Date: Tue, 19 Nov 2024 11:35:37 +0100 Subject: [PATCH 111/178] Add toString for ExitInfo. --- src/libcommon/utility/types.cpp | 4 ++++ src/libcommon/utility/types.h | 21 ++++++++++++------- .../propagation/executor/executorworker.cpp | 2 +- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/libcommon/utility/types.cpp b/src/libcommon/utility/types.cpp index 9a6530ea9..31f5973a3 100644 --- a/src/libcommon/utility/types.cpp +++ b/src/libcommon/utility/types.cpp @@ -203,6 +203,10 @@ std::string toString(const ExitCause e) { } } +std::string toString(const ExitInfo e) { + return e; +} + std::string toString(const ConflictType e) { switch (e) { case ConflictType::None: diff --git a/src/libcommon/utility/types.h b/src/libcommon/utility/types.h index e23a161f0..27230e703 100644 --- a/src/libcommon/utility/types.h +++ b/src/libcommon/utility/types.h @@ -118,11 +118,14 @@ concept EnumClass = std::is_enum_v; template // Any enum class that can be converted to (and from) int concept IntegralEnum = EnumClass && std::is_convertible_v, int>; -template // Any enum class that can be printed (with enumClassToString) -concept PrintableEnum = EnumClass && requires(C e) { toString(e); }; +template // Any types that can be converted to an int +concept ConvertibleToInt = requires(C e) { static_cast(e); }; + +template // Any types that can be converted to string +concept LogableType = requires(C e) { toString(e); }; // Converters -template +template inline constexpr int toInt(C e) { return static_cast(e); } @@ -246,6 +249,7 @@ struct ExitInfo { const ExitCause &cause() const { return _cause; } operator ExitCode() const { return _code; } operator ExitCause() const { return _cause; } + operator std::string() const { return "ExitInfo{" + toString(code()) + ", " + toString(cause()) + "}"; } constexpr operator bool() const { return _code == ExitCode::Ok; } constexpr explicit operator int() const { return toInt(_code) * 100 + toInt(_cause); } constexpr bool operator==(const ExitInfo &other) const { return _code == other._code && _cause == other._cause; } @@ -254,6 +258,7 @@ struct ExitInfo { ExitCode _code{ExitCode::Unknown}; ExitCause _cause{ExitCause::Unknown}; }; +std::string toString(ExitInfo e); // Conflict types ordered by priority enum class ConflictType { @@ -589,27 +594,27 @@ std::wstring stringToWideString(const std::string &str); // Convert string to ws // Stream Operator (toString) static const std::string noConversionStr("No conversion to string available"); -template +template std::string toStringWithCode(C e) { return toString(e) + "(" + std::to_string(toInt(e)) + ")"; // Example: "Ok(1)" } -template +template inline std::wostream &operator<<(std::wostream &wos, C e) { return wos << typesUtility::stringToWideString(toStringWithCode(e)); } -template +template inline std::ostream &operator<<(std::ostream &os, C e) { return os << toStringWithCode(e); } -template +template inline CustomLogWStream &operator<<(CustomLogWStream &os, C e) { return os << typesUtility::stringToWideString(toStringWithCode(e)); } -template +template inline QDebug &operator<<(QDebug &os, C e) { return os << toStringWithCode(e).c_str(); } diff --git a/src/libsyncengine/propagation/executor/executorworker.cpp b/src/libsyncengine/propagation/executor/executorworker.cpp index 906f17e84..6caf2f028 100644 --- a/src/libsyncengine/propagation/executor/executorworker.cpp +++ b/src/libsyncengine/propagation/executor/executorworker.cpp @@ -2545,7 +2545,7 @@ ExitInfo ExecutorWorker::handleOpsFileAccessError(SyncOpPtr syncOp, ExitInfo ops ExitInfo ExecutorWorker::handleOpsFileNotFound(SyncOpPtr syncOp, ExitInfo opsExitInfo) { if (syncOp->targetSide() != ReplicaSide::Remote) { - LOGW_SYNCPAL_WARN(_logger, L"Invalid target side for SystemError | FileNotFound error: " << syncOp->targetSide()); + LOGW_SYNCPAL_WARN(_logger, L"Unhandled target side for " << opsExitInfo << L": " << syncOp->targetSide()); return opsExitInfo; // Unable to handle this error } From 5d89fdc881c7b388c7183ef3171612e9e79934b1 Mon Sep 17 00:00:00 2001 From: Herve Eruam Date: Tue, 19 Nov 2024 11:48:37 +0100 Subject: [PATCH 112/178] Make timeOut an optional parameter (with default value 10). --- src/libcommonserver/io/iohelper.cpp | 12 +++++++----- src/libcommonserver/io/iohelper.h | 4 ++-- .../API_v2/upload_session/abstractuploadsession.cpp | 2 +- src/libsyncengine/jobs/network/API_v2/uploadjob.cpp | 2 +- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/libcommonserver/io/iohelper.cpp b/src/libcommonserver/io/iohelper.cpp index a973cf3f3..ce4e9e4c8 100644 --- a/src/libcommonserver/io/iohelper.cpp +++ b/src/libcommonserver/io/iohelper.cpp @@ -150,7 +150,7 @@ std::string IoHelper::ioError2StdString(IoError ioError) noexcept { } } -bool IoHelper::openFile(const SyncPath &path, int timeOut /*in seconds*/, std::ifstream &file, IoError &ioError) { +bool IoHelper::openFile(const SyncPath &path, std::ifstream &file, IoError &ioError, int timeOut /*in seconds*/) { int count = 0; if (file.is_open()) file.close(); do { @@ -162,7 +162,7 @@ bool IoHelper::openFile(const SyncPath &path, int timeOut /*in seconds*/, std::i return isExpectedError(ioError); } if (ioError == IoError::AccessDenied) { - LOGW_WARN(_logger, L"Access denied to " << Utility::formatSyncPath(path)); + LOGW_DEBUG(_logger, L"Access denied to " << Utility::formatSyncPath(path)); return isExpectedError(ioError); } if (!exists) { @@ -170,12 +170,14 @@ bool IoHelper::openFile(const SyncPath &path, int timeOut /*in seconds*/, std::i ioError = IoError::NoSuchFileOrDirectory; return isExpectedError(ioError); } + LOGW_DEBUG(_logger, L"File is locked, retrying in one second " << Utility::formatSyncPath(path)); + Utility::msleep(1000); } } while (++count < timeOut && !file.is_open()); if (!file.is_open()) { - LOGW_WARN(_logger, L"Failed to open file - " << Utility::formatSyncPath(path)); + LOGW_DEBUG(_logger, L"Failed to open file - " << Utility::formatSyncPath(path)); ioError = IoError::AccessDenied; return isExpectedError(ioError); } @@ -184,9 +186,9 @@ bool IoHelper::openFile(const SyncPath &path, int timeOut /*in seconds*/, std::i return true; } -ExitInfo IoHelper::openFile(const SyncPath &path, int timeOut /*in seconds*/, std::ifstream &file) { +ExitInfo IoHelper::openFile(const SyncPath &path, std::ifstream &file, int timeOut /*in seconds*/) { IoError ioError = IoError::Success; - openFile(path, timeOut, file, ioError); + openFile(path, file, ioError, timeOut); switch (ioError) { case IoError::Success: return ExitCode::Ok; diff --git a/src/libcommonserver/io/iohelper.h b/src/libcommonserver/io/iohelper.h index 51a26c9e8..4f06a0f5e 100644 --- a/src/libcommonserver/io/iohelper.h +++ b/src/libcommonserver/io/iohelper.h @@ -393,8 +393,8 @@ struct IoHelper { // The most common and expected errors during IO operations static bool isExpectedError(IoError ioError) noexcept; - static bool openFile(const SyncPath &path, int timeOut /*in seconds*/, std::ifstream &file, IoError &ioError); - static ExitInfo openFile(const SyncPath &path, int timeOut /*in seconds*/, std::ifstream &file); + static bool openFile(const SyncPath &path, std::ifstream &file, IoError &ioError, int timeOut = 10 /*in seconds*/); + static ExitInfo openFile(const SyncPath &path, std::ifstream &file, int timeOut = 10 /*in seconds*/); protected: friend class DirectoryIterator; diff --git a/src/libsyncengine/jobs/network/API_v2/upload_session/abstractuploadsession.cpp b/src/libsyncengine/jobs/network/API_v2/upload_session/abstractuploadsession.cpp index af0abd210..37c8159e0 100644 --- a/src/libsyncengine/jobs/network/API_v2/upload_session/abstractuploadsession.cpp +++ b/src/libsyncengine/jobs/network/API_v2/upload_session/abstractuploadsession.cpp @@ -272,7 +272,7 @@ bool AbstractUploadSession::sendChunks() { // locked after 10 seconds, a file access error is displayed to the user. Proper handling is also implemented for // "file not found" errors. std::ifstream file; - if (ExitInfo exitInfo = IoHelper::openFile(_filePath, 10, file); !exitInfo) { + if (ExitInfo exitInfo = IoHelper::openFile(_filePath, file, 10); !exitInfo) { LOGW_WARN(_logger, L"Failed to open file " << Utility::formatSyncPath(_filePath)); return exitInfo; } diff --git a/src/libsyncengine/jobs/network/API_v2/uploadjob.cpp b/src/libsyncengine/jobs/network/API_v2/uploadjob.cpp index 7d3f958fc..d34d41991 100644 --- a/src/libsyncengine/jobs/network/API_v2/uploadjob.cpp +++ b/src/libsyncengine/jobs/network/API_v2/uploadjob.cpp @@ -190,7 +190,7 @@ ExitInfo UploadJob::readFile() { // locked after 10 seconds, a file access error is displayed to the user. Proper handling is also implemented for // "file not found" errors. std::ifstream file; - if (ExitInfo exitInfo = IoHelper::openFile(_filePath, 10, file); !exitInfo) { + if (ExitInfo exitInfo = IoHelper::openFile(_filePath, file, 10); !exitInfo) { LOGW_WARN(_logger, L"Failed to open file " << Utility::formatSyncPath(_filePath)); return exitInfo; } From ac6af1c2ad5c1607798fcb6be4c45922d1af01c2 Mon Sep 17 00:00:00 2001 From: Herve Eruam Date: Tue, 19 Nov 2024 11:51:27 +0100 Subject: [PATCH 113/178] Fix TestIo::testOpenXXX --- test/libcommonserver/io/testopenfile.cpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/test/libcommonserver/io/testopenfile.cpp b/test/libcommonserver/io/testopenfile.cpp index d47df8de8..1dd1e2c15 100644 --- a/test/libcommonserver/io/testopenfile.cpp +++ b/test/libcommonserver/io/testopenfile.cpp @@ -18,7 +18,7 @@ #include "testio.h" #include "test_utility/testhelpers.h" - +#include using namespace CppUnit; namespace KDC { @@ -53,7 +53,7 @@ void TestIo::testOpenFileSuccess() { SyncPath filePath = tempDir.path() / "testOpenFileSuccess.txt"; testhelpers::generateOrEditTestFile(filePath); std::ifstream file; - CPPUNIT_ASSERT(IoHelper::openFile(filePath, 0, file)); + CPPUNIT_ASSERT(IoHelper::openFile(filePath, file)); CPPUNIT_ASSERT(file.is_open()); CPPUNIT_ASSERT(checkContent(file)); file.close(); @@ -69,14 +69,13 @@ void TestIo::testOpenFileAccessDenied() { // Without timeout std::ifstream file; - ExitInfo exitInfo = IoHelper::openFile(filePath, 0, file); + ExitInfo exitInfo = IoHelper::openFile(filePath, file, 0); CPPUNIT_ASSERT_EQUAL(ExitInfo(ExitCode::SystemError, ExitCause::FileAccessError), exitInfo); CPPUNIT_ASSERT(!file.is_open()); // Check timeout - auto start = std::chrono::steady_clock::now(); TimeOutChecker timeOutChecker(true); - CPPUNIT_ASSERT_EQUAL(ExitInfo(ExitCode::SystemError, ExitCause::FileAccessError), IoHelper::openFile(filePath, 2, file)); + CPPUNIT_ASSERT_EQUAL(ExitInfo(ExitCode::SystemError, ExitCause::FileAccessError), IoHelper::openFile(filePath, file, 2)); timeOutChecker.stop(); CPPUNIT_ASSERT(timeOutChecker.between(2000, 2100)); CPPUNIT_ASSERT(!file.is_open()); @@ -87,7 +86,7 @@ void TestIo::testOpenFileNonExisting() { SyncPath filePath = tempDir.path() / "testOpenFileNonExisting.txt"; std::ifstream file; TimeOutChecker timeOutChecker(true); - CPPUNIT_ASSERT_EQUAL(ExitInfo(ExitCode::SystemError, ExitCause::NotFound), IoHelper::openFile(filePath, 5, file)); + CPPUNIT_ASSERT_EQUAL(ExitInfo(ExitCode::SystemError, ExitCause::NotFound), IoHelper::openFile(filePath, file, 5)); timeOutChecker.stop(); CPPUNIT_ASSERT(timeOutChecker.lessThan(200)); CPPUNIT_ASSERT(!file.is_open()); @@ -102,7 +101,7 @@ void TestIo::testOpenFileAccessDeniedRemovedBeforeTimedOut() { CPPUNIT_ASSERT_EQUAL(IoError::Success, ioError); std::ifstream file; - ExitInfo exitInfo = IoHelper::openFile(filePath, 5, file); + ExitInfo exitInfo = IoHelper::openFile(filePath, file, 5); CPPUNIT_ASSERT_EQUAL(ExitInfo(ExitCode::SystemError, ExitCause::FileAccessError), exitInfo); CPPUNIT_ASSERT(!file.is_open()); @@ -116,7 +115,7 @@ void TestIo::testOpenFileAccessDeniedRemovedBeforeTimedOut() { }; std::thread restoreRightsThread(restoreRights); TimeOutChecker timeOutChecker(true); - CPPUNIT_ASSERT_EQUAL(ExitInfo(ExitCode::Ok), IoHelper::openFile(filePath, 4, file)); + CPPUNIT_ASSERT_EQUAL(ExitInfo(ExitCode::Ok), IoHelper::openFile(filePath, file, 4)); timeOutChecker.stop(); restoreRightsThread.join(); CPPUNIT_ASSERT(timeOutChecker.between(2000, 2200)); From 975ef7948515229284281dd8cb8c8ab2df5b5445 Mon Sep 17 00:00:00 2001 From: Herve Eruam Date: Tue, 19 Nov 2024 12:19:03 +0100 Subject: [PATCH 114/178] Address Sonar and tests issues. --- src/libcommon/utility/types.cpp | 2 +- src/libcommon/utility/types.h | 2 +- src/libcommonserver/io/iohelper.cpp | 12 +++++----- test/libcommonserver/io/testio.h | 4 ++-- test/libcommonserver/io/testopenfile.cpp | 29 +++++++++++++----------- 5 files changed, 26 insertions(+), 23 deletions(-) diff --git a/src/libcommon/utility/types.cpp b/src/libcommon/utility/types.cpp index 31f5973a3..73c3697ea 100644 --- a/src/libcommon/utility/types.cpp +++ b/src/libcommon/utility/types.cpp @@ -204,7 +204,7 @@ std::string toString(const ExitCause e) { } std::string toString(const ExitInfo e) { - return e; + return static_cast(e); } std::string toString(const ConflictType e) { diff --git a/src/libcommon/utility/types.h b/src/libcommon/utility/types.h index 27230e703..3fea8198f 100644 --- a/src/libcommon/utility/types.h +++ b/src/libcommon/utility/types.h @@ -249,7 +249,7 @@ struct ExitInfo { const ExitCause &cause() const { return _cause; } operator ExitCode() const { return _code; } operator ExitCause() const { return _cause; } - operator std::string() const { return "ExitInfo{" + toString(code()) + ", " + toString(cause()) + "}"; } + explicit operator std::string() const { return "ExitInfo{" + toString(code()) + ", " + toString(cause()) + "}"; } constexpr operator bool() const { return _code == ExitCode::Ok; } constexpr explicit operator int() const { return toInt(_code) * 100 + toInt(_cause); } constexpr bool operator==(const ExitInfo &other) const { return _code == other._code && _cause == other._cause; } diff --git a/src/libcommonserver/io/iohelper.cpp b/src/libcommonserver/io/iohelper.cpp index ce4e9e4c8..821d8b8e8 100644 --- a/src/libcommonserver/io/iohelper.cpp +++ b/src/libcommonserver/io/iohelper.cpp @@ -158,26 +158,26 @@ bool IoHelper::openFile(const SyncPath &path, std::ifstream &file, IoError &ioEr if (!file.is_open()) { bool exists = false; if (!IoHelper::checkIfPathExists(path, exists, ioError)) { - LOGW_WARN(_logger, L"Error in IoHelper::checkIfPathExists: " << Utility::formatIoError(path, ioError)); + LOGW_WARN(logger(), L"Error in IoHelper::checkIfPathExists: " << Utility::formatIoError(path, ioError)); return isExpectedError(ioError); } if (ioError == IoError::AccessDenied) { - LOGW_DEBUG(_logger, L"Access denied to " << Utility::formatSyncPath(path)); + LOGW_DEBUG(logger(), L"Access denied to " << Utility::formatSyncPath(path)); return isExpectedError(ioError); } if (!exists) { - LOGW_DEBUG(_logger, L"Item does not exist anymore - " << Utility::formatSyncPath(path)); + LOGW_DEBUG(logger(), L"Item does not exist anymore - " << Utility::formatSyncPath(path)); ioError = IoError::NoSuchFileOrDirectory; return isExpectedError(ioError); } - LOGW_DEBUG(_logger, L"File is locked, retrying in one second " << Utility::formatSyncPath(path)); + LOGW_DEBUG(logger(), L"File is locked, retrying in one second " << Utility::formatSyncPath(path)); - Utility::msleep(1000); + if(count < timeOut) Utility::msleep(1000); } } while (++count < timeOut && !file.is_open()); if (!file.is_open()) { - LOGW_DEBUG(_logger, L"Failed to open file - " << Utility::formatSyncPath(path)); + LOGW_DEBUG(logger(), L"Failed to open file - " << Utility::formatSyncPath(path)); ioError = IoError::AccessDenied; return isExpectedError(ioError); } diff --git a/test/libcommonserver/io/testio.h b/test/libcommonserver/io/testio.h index c36778815..bd141792c 100644 --- a/test/libcommonserver/io/testio.h +++ b/test/libcommonserver/io/testio.h @@ -74,7 +74,7 @@ class TestIo : public CppUnit::TestFixture { CPPUNIT_TEST(testOpenFileSuccess); CPPUNIT_TEST(testOpenFileAccessDenied); CPPUNIT_TEST(testOpenFileNonExisting); - CPPUNIT_TEST(testOpenFileAccessDeniedRemovedBeforeTimedOut); + CPPUNIT_TEST(testOpenLockedFileRemovedBeforeTimedOut); CPPUNIT_TEST_SUITE_END(); public: @@ -133,7 +133,7 @@ class TestIo : public CppUnit::TestFixture { void testOpenFileSuccess(); void testOpenFileAccessDenied(); void testOpenFileNonExisting(); - void testOpenFileAccessDeniedRemovedBeforeTimedOut(); + void testOpenLockedFileRemovedBeforeTimedOut(); private: IoHelperTests *_testObj; diff --git a/test/libcommonserver/io/testopenfile.cpp b/test/libcommonserver/io/testopenfile.cpp index 1dd1e2c15..1fcdc3eac 100644 --- a/test/libcommonserver/io/testopenfile.cpp +++ b/test/libcommonserver/io/testopenfile.cpp @@ -45,7 +45,7 @@ class TimeOutChecker { bool checkContent(std::ifstream &file) { std::string content; std::getline(file, content); - return content == "test\n"; + return content.find("test") != std::string::npos; } void TestIo::testOpenFileSuccess() { @@ -69,15 +69,17 @@ void TestIo::testOpenFileAccessDenied() { // Without timeout std::ifstream file; - ExitInfo exitInfo = IoHelper::openFile(filePath, file, 0); - CPPUNIT_ASSERT_EQUAL(ExitInfo(ExitCode::SystemError, ExitCause::FileAccessError), exitInfo); + TimeOutChecker timeOutChecker(true); + CPPUNIT_ASSERT_EQUAL(ExitInfo(ExitCode::SystemError, ExitCause::FileAccessError), IoHelper::openFile(filePath, file, 0)); + timeOutChecker.stop(); + CPPUNIT_ASSERT(timeOutChecker.lessThan(200)); CPPUNIT_ASSERT(!file.is_open()); // Check timeout - TimeOutChecker timeOutChecker(true); - CPPUNIT_ASSERT_EQUAL(ExitInfo(ExitCode::SystemError, ExitCause::FileAccessError), IoHelper::openFile(filePath, file, 2)); + timeOutChecker.start(); + CPPUNIT_ASSERT_EQUAL(ExitInfo(ExitCode::SystemError, ExitCause::FileAccessError), IoHelper::openFile(filePath, file, 1)); timeOutChecker.stop(); - CPPUNIT_ASSERT(timeOutChecker.between(2000, 2100)); + CPPUNIT_ASSERT(timeOutChecker.between(1000, 1200)); CPPUNIT_ASSERT(!file.is_open()); } @@ -92,9 +94,9 @@ void TestIo::testOpenFileNonExisting() { CPPUNIT_ASSERT(!file.is_open()); } -void TestIo::testOpenFileAccessDeniedRemovedBeforeTimedOut() { - LocalTemporaryDirectory tempDir("testOpenFileAccessDeniedRemovedBeforeTimedOut"); - SyncPath filePath = tempDir.path() / "testOpenFileAccessDeniedRemovedBeforeTimedOut.txt"; +void TestIo::testOpenLockedFileRemovedBeforeTimedOut() { + LocalTemporaryDirectory tempDir("testOpenLockedFileRemovedBeforeTimedOut"); + SyncPath filePath = tempDir.path() / "testOpenLockedFileRemovedBeforeTimedOut.txt"; testhelpers::generateOrEditTestFile(filePath); IoError ioError; IoHelper::setRights(filePath, false, true, true, ioError); @@ -105,20 +107,21 @@ void TestIo::testOpenFileAccessDeniedRemovedBeforeTimedOut() { CPPUNIT_ASSERT_EQUAL(ExitInfo(ExitCode::SystemError, ExitCause::FileAccessError), exitInfo); CPPUNIT_ASSERT(!file.is_open()); - IoHelper::setRights(filePath, true, true, true, ioError); + IoHelper::setRights(filePath, false, true, true, ioError); CPPUNIT_ASSERT_EQUAL(IoError::Success, ioError); std::function restoreRights = [filePath, &ioError]() { - Utility::msleep(2000); - IoHelper::setRights(filePath, false, true, true, ioError); + Utility::msleep(900); + IoHelper::setRights(filePath, true, true, true, ioError); CPPUNIT_ASSERT_EQUAL(IoError::Success, ioError); }; + std::thread restoreRightsThread(restoreRights); TimeOutChecker timeOutChecker(true); CPPUNIT_ASSERT_EQUAL(ExitInfo(ExitCode::Ok), IoHelper::openFile(filePath, file, 4)); timeOutChecker.stop(); restoreRightsThread.join(); - CPPUNIT_ASSERT(timeOutChecker.between(2000, 2200)); + CPPUNIT_ASSERT(timeOutChecker.between(1000, 1200)); CPPUNIT_ASSERT(file.is_open()); CPPUNIT_ASSERT(checkContent(file)); file.close(); From d611837f3b3b0e0a0618fb56d727fd8cc45f288f Mon Sep 17 00:00:00 2001 From: Herve Eruam Date: Tue, 19 Nov 2024 12:34:43 +0100 Subject: [PATCH 115/178] Reactivate testMsSleep --- test/libcommonserver/utility/testutility.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/libcommonserver/utility/testutility.cpp b/test/libcommonserver/utility/testutility.cpp index 7684599bc..a39bce39e 100644 --- a/test/libcommonserver/utility/testutility.cpp +++ b/test/libcommonserver/utility/testutility.cpp @@ -106,8 +106,8 @@ void TestUtility::testMsSleep() { auto end = std::chrono::high_resolution_clock::now(); auto timeSpan = std::chrono::duration_cast(end - start); std::cout << " timeSpan=" << timeSpan.count(); - // CPPUNIT_ASSERT(timeSpan.count() > 800 && timeSpan.count() < 1200); - CPPUNIT_ASSERT(true); + CPPUNIT_ASSERT_GREATER(long long(800), timeSpan.count()); + CPPUNIT_ASSERT_LESS(long long(1200), timeSpan.count()); } void TestUtility::testV2ws() { From 735a535749cddad684fb7aed4542ff91084d0714 Mon Sep 17 00:00:00 2001 From: Herve Eruam Date: Tue, 19 Nov 2024 12:34:43 +0100 Subject: [PATCH 116/178] Reactivate testMsSleep --- test/libcommonserver/utility/testutility.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/libcommonserver/utility/testutility.cpp b/test/libcommonserver/utility/testutility.cpp index 7684599bc..2ac06794b 100644 --- a/test/libcommonserver/utility/testutility.cpp +++ b/test/libcommonserver/utility/testutility.cpp @@ -106,8 +106,9 @@ void TestUtility::testMsSleep() { auto end = std::chrono::high_resolution_clock::now(); auto timeSpan = std::chrono::duration_cast(end - start); std::cout << " timeSpan=" << timeSpan.count(); - // CPPUNIT_ASSERT(timeSpan.count() > 800 && timeSpan.count() < 1200); - CPPUNIT_ASSERT(true); + long long timeSpanCount = static_cast(timeSpan.count()); + CPPUNIT_ASSERT_GREATER((long long) (800), timeSpanCount); + CPPUNIT_ASSERT_LESS((long long) (1200), timeSpanCount); } void TestUtility::testV2ws() { From 326a878a89cd012685215736091f40c40ef34701 Mon Sep 17 00:00:00 2001 From: Herve Eruam Date: Tue, 19 Nov 2024 12:50:29 +0100 Subject: [PATCH 117/178] Add verbose in case of test faillure. --- test/libcommonserver/io/testopenfile.cpp | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/test/libcommonserver/io/testopenfile.cpp b/test/libcommonserver/io/testopenfile.cpp index 1fcdc3eac..666d0e2a9 100644 --- a/test/libcommonserver/io/testopenfile.cpp +++ b/test/libcommonserver/io/testopenfile.cpp @@ -33,9 +33,20 @@ class TimeOutChecker { auto end = std::chrono::steady_clock::now(); _diff = std::chrono::duration_cast(end - _time).count(); } - bool lessThan(long long value) { return _diff < value; } - bool greaterThan(long long value) { return _diff > value; } - bool between(long long min, long long max) { return _diff > min && _diff < max; } + bool lessThan(long long value) { + if (_diff >= value) std::cout << "TimeOutChecker::lessThan: " << _diff << " >= " << value << std::endl; + return _diff < value; + } + bool greaterThan(long long value) { + if (_diff <= value) std::cout << "TimeOutChecker::greaterThan: " << _diff << " <= " << value << std::endl; + return _diff > value; + } + bool between(long long min, long long max) { + if (_diff <= min || _diff >= max) + std::cout << "TimeOutChecker::between: " << _diff << " <= " << min << " || " << _diff << " >= " << max + << std::endl; + return _diff > min && _diff < max; + } private: std::chrono::steady_clock::time_point _time; From 4979b2d08a8dc7420a72a4ac9f303af3f1f25745 Mon Sep 17 00:00:00 2001 From: Herve Eruam Date: Tue, 19 Nov 2024 13:14:43 +0100 Subject: [PATCH 118/178] TimeOutChecker allow equal value. --- test/libcommonserver/io/testopenfile.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/test/libcommonserver/io/testopenfile.cpp b/test/libcommonserver/io/testopenfile.cpp index 666d0e2a9..2c4b2f5da 100644 --- a/test/libcommonserver/io/testopenfile.cpp +++ b/test/libcommonserver/io/testopenfile.cpp @@ -33,19 +33,19 @@ class TimeOutChecker { auto end = std::chrono::steady_clock::now(); _diff = std::chrono::duration_cast(end - _time).count(); } - bool lessThan(long long value) { - if (_diff >= value) std::cout << "TimeOutChecker::lessThan: " << _diff << " >= " << value << std::endl; - return _diff < value; + bool lessOrEqualThan(long long value) { + if (_diff > value) std::cout << "TimeOutChecker::lessThan: " << _diff << " >= " << value << std::endl; + return _diff <= value; } - bool greaterThan(long long value) { - if (_diff <= value) std::cout << "TimeOutChecker::greaterThan: " << _diff << " <= " << value << std::endl; - return _diff > value; + bool greaterOrEqualThan(long long value) { + if (_diff < value) std::cout << "TimeOutChecker::greaterThan: " << _diff << " <= " << value << std::endl; + return _diff >= value; } bool between(long long min, long long max) { - if (_diff <= min || _diff >= max) + if (_diff < min || _diff > max) std::cout << "TimeOutChecker::between: " << _diff << " <= " << min << " || " << _diff << " >= " << max << std::endl; - return _diff > min && _diff < max; + return _diff >= min && _diff <= max; } private: @@ -83,7 +83,7 @@ void TestIo::testOpenFileAccessDenied() { TimeOutChecker timeOutChecker(true); CPPUNIT_ASSERT_EQUAL(ExitInfo(ExitCode::SystemError, ExitCause::FileAccessError), IoHelper::openFile(filePath, file, 0)); timeOutChecker.stop(); - CPPUNIT_ASSERT(timeOutChecker.lessThan(200)); + CPPUNIT_ASSERT(timeOutChecker.lessOrEqualThan(200)); CPPUNIT_ASSERT(!file.is_open()); // Check timeout @@ -101,7 +101,7 @@ void TestIo::testOpenFileNonExisting() { TimeOutChecker timeOutChecker(true); CPPUNIT_ASSERT_EQUAL(ExitInfo(ExitCode::SystemError, ExitCause::NotFound), IoHelper::openFile(filePath, file, 5)); timeOutChecker.stop(); - CPPUNIT_ASSERT(timeOutChecker.lessThan(200)); + CPPUNIT_ASSERT(timeOutChecker.lessOrEqualThan(200)); CPPUNIT_ASSERT(!file.is_open()); } From d3286a73c162bafb23650f9c123170b4deb9c18d Mon Sep 17 00:00:00 2001 From: Herve Eruam Date: Tue, 19 Nov 2024 14:31:58 +0100 Subject: [PATCH 119/178] Replace uint64_t by in int64_t --- .../file_system_observer/testlocalfilesystemobserverworker.cpp | 2 +- .../file_system_observer/testlocalfilesystemobserverworker.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/libsyncengine/update_detection/file_system_observer/testlocalfilesystemobserverworker.cpp b/test/libsyncengine/update_detection/file_system_observer/testlocalfilesystemobserverworker.cpp index d4a00b582..4a3d71b80 100644 --- a/test/libsyncengine/update_detection/file_system_observer/testlocalfilesystemobserverworker.cpp +++ b/test/libsyncengine/update_detection/file_system_observer/testlocalfilesystemobserverworker.cpp @@ -445,7 +445,7 @@ void TestLocalFileSystemObserverWorker::testLFSOFastMoveDeleteMove() { // MS Off CPPUNIT_ASSERT(_syncPal->snapshot(ReplicaSide::Local)->exists(std::to_string(fileStat.inode))); } -bool MockLocalFileSystemObserverWorker::waitForUpdate(uint64_t timeoutMs) const { +bool MockLocalFileSystemObserverWorker::waitForUpdate(int64_t timeoutMs) const { using namespace std::chrono; auto start = system_clock::now(); while (!_updating && duration_cast(system_clock::now() - start).count() < timeoutMs) { diff --git a/test/libsyncengine/update_detection/file_system_observer/testlocalfilesystemobserverworker.h b/test/libsyncengine/update_detection/file_system_observer/testlocalfilesystemobserverworker.h index b0a55b521..42995b1b6 100644 --- a/test/libsyncengine/update_detection/file_system_observer/testlocalfilesystemobserverworker.h +++ b/test/libsyncengine/update_detection/file_system_observer/testlocalfilesystemobserverworker.h @@ -45,7 +45,7 @@ class MockLocalFileSystemObserverWorker : public LocalFileSystemObserverWorker_w LocalFileSystemObserverWorker_win::changesDetected(changes); } - bool waitForUpdate(uint64_t timeoutMs = 100000) const; + bool waitForUpdate(int64_t timeoutMs = 100000) const; }; #else class MockLocalFileSystemObserverWorker : public LocalFileSystemObserverWorker_unix { From 24b2f1cb97c8ce03bb774abcb4674fa847f8559f Mon Sep 17 00:00:00 2001 From: Herve Eruam Date: Tue, 19 Nov 2024 14:37:10 +0100 Subject: [PATCH 120/178] Also apply change to unix mock. --- .../file_system_observer/testlocalfilesystemobserverworker.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/libsyncengine/update_detection/file_system_observer/testlocalfilesystemobserverworker.h b/test/libsyncengine/update_detection/file_system_observer/testlocalfilesystemobserverworker.h index 42995b1b6..33fb4cddd 100644 --- a/test/libsyncengine/update_detection/file_system_observer/testlocalfilesystemobserverworker.h +++ b/test/libsyncengine/update_detection/file_system_observer/testlocalfilesystemobserverworker.h @@ -58,7 +58,7 @@ class MockLocalFileSystemObserverWorker : public LocalFileSystemObserverWorker_u Utility::msleep(200); LocalFileSystemObserverWorker_unix::changesDetected(changes); } - bool waitForUpdate(uint64_t timeoutMs = 100000) const; + bool waitForUpdate(int64_t timeoutMs = 100000) const; }; #endif From bc786dbc71ec990640874178fd54d822df856357 Mon Sep 17 00:00:00 2001 From: Christophe Larchier Date: Tue, 19 Nov 2024 15:00:22 +0100 Subject: [PATCH 121/178] Code improvement --- src/libsyncengine/syncpal/syncpal.cpp | 98 ++++++++++--------- src/libsyncengine/syncpal/syncpal.h | 7 +- .../update_detector/updatetree.cpp | 2 - .../update_detector/updatetree.h | 3 +- 4 files changed, 57 insertions(+), 53 deletions(-) diff --git a/src/libsyncengine/syncpal/syncpal.cpp b/src/libsyncengine/syncpal/syncpal.cpp index 55ded5561..6a99fbfe0 100644 --- a/src/libsyncengine/syncpal/syncpal.cpp +++ b/src/libsyncengine/syncpal/syncpal.cpp @@ -62,8 +62,6 @@ SyncPal::SyncPal(const SyncPath &syncDbPath, const std::string &version, const b if (!createOrOpenDb(syncDbPath, version)) { throw std::runtime_error(SYNCPAL_NEW_ERROR_MSG); } - - createSharedObjects(); } SyncPal::SyncPal(const int syncDbId_, const std::string &version) : _logger(Log::instance()->getLogger()) { @@ -166,8 +164,6 @@ SyncPal::SyncPal(const int syncDbId_, const std::string &version) : _logger(Log: fixInconsistentFileNames(); fixNodeTableDeleteItemsWithNullParentNodeId(); - - createSharedObjects(); } SyncPal::~SyncPal() { @@ -523,9 +519,45 @@ void SyncPal::createSharedObjects() { _remoteUpdateTree = std::make_shared(ReplicaSide::Remote, _syncDb->rootNode()); _conflictQueue = std::make_shared(_localUpdateTree, _remoteUpdateTree); _syncOps = std::make_shared(); + _progressInfo = std::make_shared(shared_from_this()); - // Init SyncNode table cache - SyncNodeCache::instance()->initCache(syncDbId(), _syncDb); + initSharedObjects(); +} + +void SyncPal::freeSharedObjects() { + _interruptSync.reset(); + _localSnapshot.reset(); + _remoteSnapshot.reset(); + _localSnapshotCopy.reset(); + _remoteSnapshotCopy.reset(); + _localOperationSet.reset(); + _remoteOperationSet.reset(); + _localUpdateTree.reset(); + _remoteUpdateTree.reset(); + _conflictQueue.reset(); + _syncOps.reset(); + _progressInfo.reset(); + + // Check that there is no memory leak + ASSERT(_interruptSync.use_count() == 0); + ASSERT(_localSnapshot.use_count() == 0); + ASSERT(_remoteSnapshot.use_count() == 0); + ASSERT(_localSnapshotCopy.use_count() == 0); + ASSERT(_remoteSnapshotCopy.use_count() == 0); + ASSERT(_localOperationSet.use_count() == 0); + ASSERT(_remoteOperationSet.use_count() == 0); + ASSERT(_localUpdateTree.use_count() == 0); + ASSERT(_remoteUpdateTree.use_count() == 0); + ASSERT(_conflictQueue.use_count() == 0); + ASSERT(_syncOps.use_count() == 0); + ASSERT(_progressInfo.use_count() == 0); +} + +void SyncPal::initSharedObjects() { + if (_localUpdateTree) _localUpdateTree->init(); + if (_remoteUpdateTree) _remoteUpdateTree->init(); + + setSyncHasFullyCompleted(false); } void SyncPal::resetSharedObjects() { @@ -533,11 +565,12 @@ void SyncPal::resetSharedObjects() { if (_localOperationSet) _localOperationSet->clear(); if (_remoteOperationSet) _remoteOperationSet->clear(); - if (_localUpdateTree) _localUpdateTree->init(); - if (_remoteUpdateTree) _remoteUpdateTree->init(); + if (_localUpdateTree) _localUpdateTree->clear(); + if (_remoteUpdateTree) _remoteUpdateTree->clear(); if (_conflictQueue) _conflictQueue->clear(); if (_syncOps) _syncOps->clear(); - setSyncHasFullyCompleted(false); + + initSharedObjects(); LOG_SYNCPAL_DEBUG(_logger, "Reset shared objects done"); } @@ -574,7 +607,7 @@ void SyncPal::createWorkers() { _tmpBlacklistManager = std::shared_ptr(new TmpBlacklistManager(shared_from_this())); } -void SyncPal::free() { +void SyncPal::freeWorkers() { _localFSObserverWorker.reset(); _remoteFSObserverWorker.reset(); _computeFSOperationsWorker.reset(); @@ -588,31 +621,6 @@ void SyncPal::free() { _executorWorker.reset(); _syncPalWorker.reset(); _tmpBlacklistManager.reset(); - - _interruptSync.reset(); - _localSnapshot.reset(); - _remoteSnapshot.reset(); - _localSnapshotCopy.reset(); - _remoteSnapshotCopy.reset(); - _localOperationSet.reset(); - _remoteOperationSet.reset(); - _localUpdateTree.reset(); - _remoteUpdateTree.reset(); - _conflictQueue.reset(); - _syncOps.reset(); - - // Check that there is no memory leak - ASSERT(_interruptSync.use_count() == 0); - ASSERT(_localSnapshot.use_count() == 0); - ASSERT(_remoteSnapshot.use_count() == 0); - ASSERT(_localSnapshotCopy.use_count() == 0); - ASSERT(_remoteSnapshotCopy.use_count() == 0); - ASSERT(_localOperationSet.use_count() == 0); - ASSERT(_remoteOperationSet.use_count() == 0); - ASSERT(_localUpdateTree.use_count() == 0); - ASSERT(_remoteUpdateTree.use_count() == 0); - ASSERT(_conflictQueue.use_count() == 0); - ASSERT(_syncOps.use_count() == 0); } ExitCode SyncPal::setSyncPaused(bool value) { @@ -644,6 +652,9 @@ bool SyncPal::createOrOpenDb(const SyncPath &syncDbPath, const std::string &vers return false; } + // Init SyncNode table cache + SyncNodeCache::instance()->initCache(syncDbId(), _syncDb); + return true; } @@ -1193,15 +1204,12 @@ void SyncPal::start() { } setVfsMode(sync.virtualFileMode()); - // Reset shared objects - resetSharedObjects(); - // Clear tmp blacklist SyncNodeCache::instance()->update(syncDbId(), SyncNodeType::TmpRemoteBlacklist, std::unordered_set()); SyncNodeCache::instance()->update(syncDbId(), SyncNodeType::TmpLocalBlacklist, std::unordered_set()); - // Create ProgressInfo - createProgressInfo(); + // Create and init shared objects + createSharedObjects(); // Create workers createWorkers(); @@ -1281,13 +1289,11 @@ void SyncPal::stop(bool pausedByUser, bool quit, bool clear) { } } - if (quit) { - // Free workers - free(); + // Free workers + freeWorkers(); - // Free progressInfo - _progressInfo.reset(); - } + // Free shared objects + freeSharedObjects(); _syncDb->setAutoDelete(clear); } diff --git a/src/libsyncengine/syncpal/syncpal.h b/src/libsyncengine/syncpal/syncpal.h index c2fb34a28..20a3e6ac9 100644 --- a/src/libsyncengine/syncpal/syncpal.h +++ b/src/libsyncengine/syncpal/syncpal.h @@ -320,6 +320,7 @@ class SYNCENGINE_EXPORT SyncPal : public std::enable_shared_from_this { std::shared_ptr _remoteUpdateTree{nullptr}; std::shared_ptr _conflictQueue{nullptr}; std::shared_ptr _syncOps{nullptr}; + std::shared_ptr _progressInfo{nullptr}; // Workers std::shared_ptr _syncPalWorker{nullptr}; @@ -335,14 +336,14 @@ class SYNCENGINE_EXPORT SyncPal : public std::enable_shared_from_this { std::shared_ptr _operationsSorterWorker{nullptr}; std::shared_ptr _executorWorker{nullptr}; - std::shared_ptr _progressInfo{nullptr}; - std::shared_ptr _tmpBlacklistManager{nullptr}; void createSharedObjects(); + void freeSharedObjects(); + void initSharedObjects(); void resetSharedObjects(); void createWorkers(); - void free(); + void freeWorkers(); ExitCode setSyncPaused(bool value); bool createOrOpenDb(const SyncPath &syncDbPath, const std::string &version, const std::string &targetNodeId = std::string()); diff --git a/src/libsyncengine/update_detection/update_detector/updatetree.cpp b/src/libsyncengine/update_detection/update_detector/updatetree.cpp index 0633d8241..3a2c0ac46 100644 --- a/src/libsyncengine/update_detection/update_detector/updatetree.cpp +++ b/src/libsyncengine/update_detection/update_detector/updatetree.cpp @@ -156,8 +156,6 @@ void UpdateTree::markAllNodesUnprocessed() { } void UpdateTree::init() { - clear(); - insertNode(_rootNode); _inconsistencyCheckDone = false; } diff --git a/src/libsyncengine/update_detection/update_detector/updatetree.h b/src/libsyncengine/update_detection/update_detector/updatetree.h index c24d397a2..acabdd216 100644 --- a/src/libsyncengine/update_detection/update_detector/updatetree.h +++ b/src/libsyncengine/update_detection/update_detector/updatetree.h @@ -50,6 +50,7 @@ class UpdateTree : public SharedObject { bool isAncestor(const NodeId &nodeId, const NodeId &ancestorNodeId) const; void markAllNodesUnprocessed(); + void clear(); void init(); inline bool inconsistencyCheckDone() const { return _inconsistencyCheckDone; } @@ -67,8 +68,6 @@ class UpdateTree : public SharedObject { bool _inconsistencyCheckDone = false; - void clear(); - friend class TestUpdateTree; friend class TestUpdateTreeWorker; }; From be440aa642bfc3d1a9a97c09b6b1bc0a881d2e75 Mon Sep 17 00:00:00 2001 From: Christophe Larchier Date: Tue, 19 Nov 2024 15:02:48 +0100 Subject: [PATCH 122/178] Address comment --- .../file_system_observer/folderwatcher_linux.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libsyncengine/update_detection/file_system_observer/folderwatcher_linux.cpp b/src/libsyncengine/update_detection/file_system_observer/folderwatcher_linux.cpp index 967b6cde2..10099dfa5 100644 --- a/src/libsyncengine/update_detection/file_system_observer/folderwatcher_linux.cpp +++ b/src/libsyncengine/update_detection/file_system_observer/folderwatcher_linux.cpp @@ -126,7 +126,7 @@ void FolderWatcher_linux::startWatching() { } } - LOGW_DEBUG(_logger, L"Folder watching stopped: " << _folder.wstring().c_str()); + LOGW_DEBUG(_logger, L"Folder watching stopped: " << Utility::formatSyncPath(_folder)); Utility::terminateThreadFunction(); } From 121cca700220e28766aa49290c03185bde9010b1 Mon Sep 17 00:00:00 2001 From: Christophe Larchier Date: Tue, 19 Nov 2024 16:35:45 +0100 Subject: [PATCH 123/178] Fixed an issue and added some logs --- src/libsyncengine/syncpal/isyncworker.cpp | 1 + src/libsyncengine/syncpal/syncpal.cpp | 7 ++++++- src/libsyncengine/syncpal/syncpal.h | 2 +- .../file_system_observer/filesystemobserverworker.h | 2 +- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/libsyncengine/syncpal/isyncworker.cpp b/src/libsyncengine/syncpal/isyncworker.cpp index 713cad2cc..033cafef9 100644 --- a/src/libsyncengine/syncpal/isyncworker.cpp +++ b/src/libsyncengine/syncpal/isyncworker.cpp @@ -104,6 +104,7 @@ void ISyncWorker::stop() { } void ISyncWorker::waitForExit() { + LOG_SYNCPAL_DEBUG(_logger, "Worker " << _name.c_str() << " wait for exit"); if (_thread && _thread->joinable()) { _thread->join(); _thread.release(); diff --git a/src/libsyncengine/syncpal/syncpal.cpp b/src/libsyncengine/syncpal/syncpal.cpp index 6a99fbfe0..89d72f83d 100644 --- a/src/libsyncengine/syncpal/syncpal.cpp +++ b/src/libsyncengine/syncpal/syncpal.cpp @@ -508,7 +508,8 @@ void SyncPal::loadProgress(int64_t ¤tFile, int64_t &totalFiles, int64_t &c } void SyncPal::createSharedObjects() { - // Create shared objects + LOG_SYNCPAL_DEBUG(_logger, "Create shared objects"); + _interruptSync = std::make_shared(false); _localSnapshot = std::make_shared(ReplicaSide::Local, _syncDb->rootNode()); _remoteSnapshot = std::make_shared(ReplicaSide::Remote, _syncDb->rootNode()); _localSnapshotCopy = std::make_shared(ReplicaSide::Local, _syncDb->rootNode()); @@ -525,6 +526,7 @@ void SyncPal::createSharedObjects() { } void SyncPal::freeSharedObjects() { + LOG_SYNCPAL_DEBUG(_logger, "Free shared objects"); _interruptSync.reset(); _localSnapshot.reset(); _remoteSnapshot.reset(); @@ -554,6 +556,7 @@ void SyncPal::freeSharedObjects() { } void SyncPal::initSharedObjects() { + LOG_SYNCPAL_DEBUG(_logger, "Init shared objects"); if (_localUpdateTree) _localUpdateTree->init(); if (_remoteUpdateTree) _remoteUpdateTree->init(); @@ -576,6 +579,7 @@ void SyncPal::resetSharedObjects() { } void SyncPal::createWorkers() { + LOG_SYNCPAL_DEBUG(_logger, "Create workers"); #if defined(_WIN32) _localFSObserverWorker = std::shared_ptr( new LocalFileSystemObserverWorker_win(shared_from_this(), "Local File System Observer", "LFSO")); @@ -608,6 +612,7 @@ void SyncPal::createWorkers() { } void SyncPal::freeWorkers() { + LOG_SYNCPAL_DEBUG(_logger, "Free workers"); _localFSObserverWorker.reset(); _remoteFSObserverWorker.reset(); _computeFSOperationsWorker.reset(); diff --git a/src/libsyncengine/syncpal/syncpal.h b/src/libsyncengine/syncpal/syncpal.h index 20a3e6ac9..29069f6cc 100644 --- a/src/libsyncengine/syncpal/syncpal.h +++ b/src/libsyncengine/syncpal/syncpal.h @@ -307,7 +307,7 @@ class SYNCENGINE_EXPORT SyncPal : public std::enable_shared_from_this { std::shared_ptr _syncDb{nullptr}; // Shared objects - std::shared_ptr _interruptSync{new bool(false)}; + std::shared_ptr _interruptSync{nullptr}; std::shared_ptr _localSnapshot{nullptr}; // Real time local snapshot std::shared_ptr _remoteSnapshot{nullptr}; // Real time remote snapshot std::shared_ptr _localSnapshotCopy{ diff --git a/src/libsyncengine/update_detection/file_system_observer/filesystemobserverworker.h b/src/libsyncengine/update_detection/file_system_observer/filesystemobserverworker.h index 30137ec88..ea86852b7 100644 --- a/src/libsyncengine/update_detection/file_system_observer/filesystemobserverworker.h +++ b/src/libsyncengine/update_detection/file_system_observer/filesystemobserverworker.h @@ -38,7 +38,7 @@ class FileSystemObserverWorker : public ISyncWorker { virtual void forceUpdate(); virtual inline bool updating() const { return _updating; } - std::shared_ptr snapshot() const { return _snapshot; }; + std::shared_ptr snapshot() const { return _snapshot; } protected: std::shared_ptr _syncDb; From 77ab059ccec6ee8b66c1d16713bcd3c080ce6bb3 Mon Sep 17 00:00:00 2001 From: Christophe Larchier Date: Tue, 19 Nov 2024 17:38:42 +0100 Subject: [PATCH 124/178] Fix memory leak --- src/libsyncengine/syncpal/isyncworker.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/libsyncengine/syncpal/isyncworker.cpp b/src/libsyncengine/syncpal/isyncworker.cpp index 033cafef9..ada5b1adc 100644 --- a/src/libsyncengine/syncpal/isyncworker.cpp +++ b/src/libsyncengine/syncpal/isyncworker.cpp @@ -32,7 +32,6 @@ ISyncWorker::~ISyncWorker() { } LOG_SYNCPAL_DEBUG(_logger, "Worker " << _name.c_str() << " destroyed"); - log4cplus::threadCleanup(); } void ISyncWorker::start() { @@ -105,6 +104,7 @@ void ISyncWorker::stop() { void ISyncWorker::waitForExit() { LOG_SYNCPAL_DEBUG(_logger, "Worker " << _name.c_str() << " wait for exit"); + if (_thread && _thread->joinable()) { _thread->join(); _thread.release(); @@ -138,12 +138,11 @@ void ISyncWorker::setDone(ExitCode exitCode) { _isRunning = false; _stopAsked = false; _exitCode = exitCode; - log4cplus::threadCleanup(); } void *ISyncWorker::executeFunc(void *thisWorker) { ((ISyncWorker *) thisWorker)->execute(); - return nullptr; + Utility::terminateThreadFunction(); } } // namespace KDC From ae783373f7e40e826891cf6b00297ce9d54e7549 Mon Sep 17 00:00:00 2001 From: Christophe Larchier Date: Wed, 20 Nov 2024 11:53:40 +0100 Subject: [PATCH 125/178] Fix memory leaks --- src/libsyncengine/syncpal/isyncworker.cpp | 6 ++---- src/libsyncengine/syncpal/isyncworker.h | 2 +- .../file_system_observer/folderwatcher.cpp | 11 ++--------- .../file_system_observer/folderwatcher.h | 4 ++-- .../file_system_observer/folderwatcher_linux.cpp | 2 -- .../file_system_observer/folderwatcher_linux.h | 1 - .../file_system_observer/folderwatcher_mac.cpp | 2 -- .../file_system_observer/folderwatcher_mac.h | 1 - .../file_system_observer/folderwatcher_win.cpp | 2 -- .../file_system_observer/folderwatcher_win.h | 1 - 10 files changed, 7 insertions(+), 25 deletions(-) diff --git a/src/libsyncengine/syncpal/isyncworker.cpp b/src/libsyncengine/syncpal/isyncworker.cpp index ada5b1adc..1cbd27586 100644 --- a/src/libsyncengine/syncpal/isyncworker.cpp +++ b/src/libsyncengine/syncpal/isyncworker.cpp @@ -28,7 +28,7 @@ ISyncWorker::ISyncWorker(std::shared_ptr syncPal, const std::string &na ISyncWorker::~ISyncWorker() { if (_isRunning) { - stop(); + ISyncWorker::stop(); } LOG_SYNCPAL_DEBUG(_logger, "Worker " << _name.c_str() << " destroyed"); @@ -107,8 +107,6 @@ void ISyncWorker::waitForExit() { if (_thread && _thread->joinable()) { _thread->join(); - _thread.release(); - _thread = nullptr; } } @@ -140,7 +138,7 @@ void ISyncWorker::setDone(ExitCode exitCode) { _exitCode = exitCode; } -void *ISyncWorker::executeFunc(void *thisWorker) { +void ISyncWorker::executeFunc(void *thisWorker) { ((ISyncWorker *) thisWorker)->execute(); Utility::terminateThreadFunction(); } diff --git a/src/libsyncengine/syncpal/isyncworker.h b/src/libsyncengine/syncpal/isyncworker.h index b3830dcb4..081f42aa7 100644 --- a/src/libsyncengine/syncpal/isyncworker.h +++ b/src/libsyncengine/syncpal/isyncworker.h @@ -73,7 +73,7 @@ class ISyncWorker { inline int syncDbId() const { return _syncPal ? _syncPal->syncDbId() : -1; } private: - static void *executeFunc(void *thisWorker); + static void executeFunc(void *thisWorker); const std::string _name; const std::string _shortName; diff --git a/src/libsyncengine/update_detection/file_system_observer/folderwatcher.cpp b/src/libsyncengine/update_detection/file_system_observer/folderwatcher.cpp index d67d9c917..0d37539ca 100644 --- a/src/libsyncengine/update_detection/file_system_observer/folderwatcher.cpp +++ b/src/libsyncengine/update_detection/file_system_observer/folderwatcher.cpp @@ -26,12 +26,6 @@ namespace KDC { FolderWatcher::FolderWatcher(LocalFileSystemObserverWorker *parent, const SyncPath &path) : _logger(Log::instance()->getLogger()), _parent(parent), _folder(path) {} -FolderWatcher::~FolderWatcher() { - if (_thread) { - stop(); - } -} - void FolderWatcher::start() { LOG_DEBUG(_logger, "Start Folder Watcher"); _stop = false; @@ -52,16 +46,15 @@ void FolderWatcher::stop() { #if !defined(__APPLE__) if (_thread && _thread->joinable()) { _thread->join(); - _thread.release(); } #endif _thread = nullptr; } -void *FolderWatcher::executeFunc(void *thisWorker) { +void FolderWatcher::executeFunc(void *thisWorker) { ((FolderWatcher *) thisWorker)->startWatching(); - return nullptr; + Utility::terminateThreadFunction(); } } // namespace KDC diff --git a/src/libsyncengine/update_detection/file_system_observer/folderwatcher.h b/src/libsyncengine/update_detection/file_system_observer/folderwatcher.h index ee459df8e..ec157b664 100644 --- a/src/libsyncengine/update_detection/file_system_observer/folderwatcher.h +++ b/src/libsyncengine/update_detection/file_system_observer/folderwatcher.h @@ -31,7 +31,7 @@ class LocalFileSystemObserverWorker; class FolderWatcher { public: FolderWatcher(LocalFileSystemObserverWorker *parent, const SyncPath &rootFolder); - virtual ~FolderWatcher(); + virtual ~FolderWatcher() = default; const log4cplus::Logger &logger() const { return _logger; } @@ -54,7 +54,7 @@ class FolderWatcher { bool _stop = false; private: - static void *executeFunc(void *thisWorker); + static void executeFunc(void *thisWorker); std::unique_ptr _thread = nullptr; ExitInfo _exitInfo = ExitCode::Ok; diff --git a/src/libsyncengine/update_detection/file_system_observer/folderwatcher_linux.cpp b/src/libsyncengine/update_detection/file_system_observer/folderwatcher_linux.cpp index 967b6cde2..463d4aa83 100644 --- a/src/libsyncengine/update_detection/file_system_observer/folderwatcher_linux.cpp +++ b/src/libsyncengine/update_detection/file_system_observer/folderwatcher_linux.cpp @@ -37,8 +37,6 @@ namespace KDC { FolderWatcher_linux::FolderWatcher_linux(LocalFileSystemObserverWorker *parent, const SyncPath &path) : FolderWatcher(parent, path) {} -FolderWatcher_linux::~FolderWatcher_linux() {} - void FolderWatcher_linux::startWatching() { LOG4CPLUS_DEBUG(_logger, L"Start watching folder: " << Path2WStr(_folder).c_str()); LOG4CPLUS_DEBUG(_logger, "File system format: " << Utility::fileSystemName(_folder).c_str()); diff --git a/src/libsyncengine/update_detection/file_system_observer/folderwatcher_linux.h b/src/libsyncengine/update_detection/file_system_observer/folderwatcher_linux.h index 5df1e4171..f52b03583 100644 --- a/src/libsyncengine/update_detection/file_system_observer/folderwatcher_linux.h +++ b/src/libsyncengine/update_detection/file_system_observer/folderwatcher_linux.h @@ -29,7 +29,6 @@ class LocalFileSystemObserverWorker; class FolderWatcher_linux : public FolderWatcher { public: FolderWatcher_linux(LocalFileSystemObserverWorker *parent, const SyncPath &path); - ~FolderWatcher_linux(); void startWatching() override; void stopWatching() override; diff --git a/src/libsyncengine/update_detection/file_system_observer/folderwatcher_mac.cpp b/src/libsyncengine/update_detection/file_system_observer/folderwatcher_mac.cpp index 3cd914573..1622a2aab 100644 --- a/src/libsyncengine/update_detection/file_system_observer/folderwatcher_mac.cpp +++ b/src/libsyncengine/update_detection/file_system_observer/folderwatcher_mac.cpp @@ -28,8 +28,6 @@ namespace KDC { FolderWatcher_mac::FolderWatcher_mac(LocalFileSystemObserverWorker *parent, const SyncPath &path) : FolderWatcher(parent, path), _stream(nullptr) {} -FolderWatcher_mac::~FolderWatcher_mac() {} - static void callback([[maybe_unused]] ConstFSEventStreamRef streamRef, void *clientCallBackInfo, size_t numEvents, void *eventPathsVoid, const FSEventStreamEventFlags eventFlags[], [[maybe_unused]] const FSEventStreamEventId eventIds[]) { diff --git a/src/libsyncengine/update_detection/file_system_observer/folderwatcher_mac.h b/src/libsyncengine/update_detection/file_system_observer/folderwatcher_mac.h index 7a6d729e2..3db20b779 100644 --- a/src/libsyncengine/update_detection/file_system_observer/folderwatcher_mac.h +++ b/src/libsyncengine/update_detection/file_system_observer/folderwatcher_mac.h @@ -29,7 +29,6 @@ class LocalFileSystemObserverWorker; class FolderWatcher_mac : public FolderWatcher { public: FolderWatcher_mac(LocalFileSystemObserverWorker *parent, const SyncPath &path); - ~FolderWatcher_mac(); void startWatching() override; void stopWatching() override; diff --git a/src/libsyncengine/update_detection/file_system_observer/folderwatcher_win.cpp b/src/libsyncengine/update_detection/file_system_observer/folderwatcher_win.cpp index 30baf83b7..143aa6bf8 100644 --- a/src/libsyncengine/update_detection/file_system_observer/folderwatcher_win.cpp +++ b/src/libsyncengine/update_detection/file_system_observer/folderwatcher_win.cpp @@ -30,8 +30,6 @@ namespace KDC { FolderWatcher_win::FolderWatcher_win(LocalFileSystemObserverWorker *parent, const SyncPath &path) : FolderWatcher(parent, path) {} -FolderWatcher_win::~FolderWatcher_win() {} - bool FolderWatcher_win::ready() const { return _ready; } diff --git a/src/libsyncengine/update_detection/file_system_observer/folderwatcher_win.h b/src/libsyncengine/update_detection/file_system_observer/folderwatcher_win.h index ac44fa9ef..cc0537b8c 100644 --- a/src/libsyncengine/update_detection/file_system_observer/folderwatcher_win.h +++ b/src/libsyncengine/update_detection/file_system_observer/folderwatcher_win.h @@ -32,7 +32,6 @@ class LocalFileSystemObserverWorker; class FolderWatcher_win : public FolderWatcher { public: FolderWatcher_win(LocalFileSystemObserverWorker *parent, const SyncPath &path); - ~FolderWatcher_win(); bool ready() const; From 094baa2c09b8fd2c8f2d8ffe3644bc5ae0a3a8bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Kunz?= Date: Wed, 20 Nov 2024 13:08:16 +0100 Subject: [PATCH 126/178] KDESKTOP-1394 - Update release notes 3.6.7 --- infomaniak-build-tools/kDrive-template.html | 2 +- .../kDrive-3.6.7.20241120-linux-de.html} | 2 +- .../kDrive-3.6.7.20241120-linux-en.html} | 2 +- .../kDrive-3.6.7.20241120-linux-es.html} | 2 +- .../kDrive-3.6.7.20241120-linux-fr.html} | 2 +- .../kDrive-3.6.7.20241120-linux-it.html} | 4 ++-- .../kDrive-3.6.7.20241120-macos-de.html} | 2 +- .../kDrive-3.6.7.20241120-macos-en.html} | 2 +- .../kDrive-3.6.7.20241120-macos-es.html} | 2 +- .../kDrive-3.6.7.20241120-macos-fr.html} | 2 +- .../kDrive-3.6.7.20241120-macos-it.html} | 4 ++-- .../kDrive-3.6.7.20241120-win-de.html} | 2 +- .../kDrive-3.6.7.20241120-win-en.html} | 2 +- .../kDrive-3.6.7.20241120-win-es.html} | 2 +- .../kDrive-3.6.7.20241120-win-fr.html} | 2 +- .../kDrive-3.6.7.20241120-win-it.html} | 4 ++-- 16 files changed, 19 insertions(+), 19 deletions(-) rename release_notes/{kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-linux-de.html => kDrive-3.6.7.20241120/kDrive-3.6.7.20241120-linux-de.html} (95%) rename release_notes/{kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-macos-en.html => kDrive-3.6.7.20241120/kDrive-3.6.7.20241120-linux-en.html} (94%) rename release_notes/{kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-macos-es.html => kDrive-3.6.7.20241120/kDrive-3.6.7.20241120-linux-es.html} (94%) rename release_notes/{kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-macos-fr.html => kDrive-3.6.7.20241120/kDrive-3.6.7.20241120-linux-fr.html} (94%) rename release_notes/{kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-macos-it.html => kDrive-3.6.7.20241120/kDrive-3.6.7.20241120-linux-it.html} (91%) rename release_notes/{kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-macos-de.html => kDrive-3.6.7.20241120/kDrive-3.6.7.20241120-macos-de.html} (95%) rename release_notes/{kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-linux-en.html => kDrive-3.6.7.20241120/kDrive-3.6.7.20241120-macos-en.html} (94%) rename release_notes/{kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-linux-es.html => kDrive-3.6.7.20241120/kDrive-3.6.7.20241120-macos-es.html} (94%) rename release_notes/{kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-linux-fr.html => kDrive-3.6.7.20241120/kDrive-3.6.7.20241120-macos-fr.html} (94%) rename release_notes/{kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-linux-it.html => kDrive-3.6.7.20241120/kDrive-3.6.7.20241120-macos-it.html} (91%) rename release_notes/{kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-win-de.html => kDrive-3.6.7.20241120/kDrive-3.6.7.20241120-win-de.html} (95%) rename release_notes/{kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-win-en.html => kDrive-3.6.7.20241120/kDrive-3.6.7.20241120-win-en.html} (94%) rename release_notes/{kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-win-es.html => kDrive-3.6.7.20241120/kDrive-3.6.7.20241120-win-es.html} (94%) rename release_notes/{kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-win-fr.html => kDrive-3.6.7.20241120/kDrive-3.6.7.20241120-win-fr.html} (95%) rename release_notes/{kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-win-it.html => kDrive-3.6.7.20241120/kDrive-3.6.7.20241120-win-it.html} (91%) diff --git a/infomaniak-build-tools/kDrive-template.html b/infomaniak-build-tools/kDrive-template.html index fb4d69d3e..e10a6dac3 100644 --- a/infomaniak-build-tools/kDrive-template.html +++ b/infomaniak-build-tools/kDrive-template.html @@ -26,11 +26,11 @@

New features

Bug fixes

    +
  • Resolution of a file synchronization problem affecting the Office suite in particular
  • Fixed new file wrongly downloaded in LiteSync mode
  • Fixed missing share links entries in contextual menu
  • Consolidation of error management during the propagation step
  • Do not block application startup if local sync folder is missing
  • -
  • Added "*.tmp" files to default exclusion templates
  • Fixed wrongly blacklisted files
  • Fixed broken sync on FAT systems
  • Fixed startup issue in case of unknown proxy type
  • diff --git a/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-linux-de.html b/release_notes/kDrive-3.6.7.20241120/kDrive-3.6.7.20241120-linux-de.html similarity index 95% rename from release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-linux-de.html rename to release_notes/kDrive-3.6.7.20241120/kDrive-3.6.7.20241120-linux-de.html index 6c2277ccc..26227bea2 100644 --- a/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-linux-de.html +++ b/release_notes/kDrive-3.6.7.20241120/kDrive-3.6.7.20241120-linux-de.html @@ -26,11 +26,11 @@

    Neue Funktionen

Fehlerbehebungen

    +
  • Behebung eines Dateisynchronisationsproblems, das insbesondere die Office-Suite betrifft
  • Neue Datei wurde im LiteSync-Modus fälschlicherweise heruntergeladen
  • Fehlende Einträge für Freigabelinks im Kontextmenü behoben
  • Konsolidierung des Fehlermanagements während der Ausbreitungsphase
  • Start der Anwendung nicht blockieren, wenn der lokale Synchronisierungsordner fehlt
  • -
  • *.tmp"-Dateien zu Standard-Ausschlussvorlagen hinzugefügt
  • Falsch auf die schwarze Liste gesetzte Dateien korrigiert
  • Fehlerhafte Synchronisierung auf FAT-Systemen behoben
  • Startproblem im Falle eines unbekannten Proxy-Typs behoben
  • diff --git a/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-macos-en.html b/release_notes/kDrive-3.6.7.20241120/kDrive-3.6.7.20241120-linux-en.html similarity index 94% rename from release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-macos-en.html rename to release_notes/kDrive-3.6.7.20241120/kDrive-3.6.7.20241120-linux-en.html index 122e7014a..120319f26 100644 --- a/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-macos-en.html +++ b/release_notes/kDrive-3.6.7.20241120/kDrive-3.6.7.20241120-linux-en.html @@ -26,11 +26,11 @@

    New features

Bug fixes

    +
  • Resolution of a file synchronization problem affecting the Office suite in particular
  • Fixed new file wrongly downloaded in LiteSync mode
  • Fixed missing share links entries in contextual menu
  • Consolidation of error management during the propagation step
  • Do not block application startup if local sync folder is missing
  • -
  • Added "*.tmp" files to default exclusion templates
  • Fixed wrongly blacklisted files
  • Fixed broken sync on FAT systems
  • Fixed startup issue in case of unknown proxy type
  • diff --git a/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-macos-es.html b/release_notes/kDrive-3.6.7.20241120/kDrive-3.6.7.20241120-linux-es.html similarity index 94% rename from release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-macos-es.html rename to release_notes/kDrive-3.6.7.20241120/kDrive-3.6.7.20241120-linux-es.html index b2ede6ad7..e40e56611 100644 --- a/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-macos-es.html +++ b/release_notes/kDrive-3.6.7.20241120/kDrive-3.6.7.20241120-linux-es.html @@ -26,11 +26,11 @@

    Novedades

Corrección de errores

    +
  • Resolución de un problema de sincronización de archivos que afectaba sobre todo al paquete Office.
  • Corregido el error de descarga de un nuevo archivo en el modo LiteSync
  • Se ha corregido la falta de entradas de enlaces compartidos en el menú contextual.
  • Consolidación de la gestión de errores durante la etapa de propagación
  • No bloquear el inicio de la aplicación si falta la carpeta de sincronización local
  • -
  • Añadidos los archivos "*.tmp" a las plantillas de exclusión por defecto
  • Corrección de archivos incluidos erróneamente en la lista negra
  • Corregida la sincronización rota en sistemas FAT
  • Se ha corregido un problema de inicio en caso de tipo de proxy desconocido.
  • diff --git a/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-macos-fr.html b/release_notes/kDrive-3.6.7.20241120/kDrive-3.6.7.20241120-linux-fr.html similarity index 94% rename from release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-macos-fr.html rename to release_notes/kDrive-3.6.7.20241120/kDrive-3.6.7.20241120-linux-fr.html index adf5c75ba..5a93f04dc 100644 --- a/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-macos-fr.html +++ b/release_notes/kDrive-3.6.7.20241120/kDrive-3.6.7.20241120-linux-fr.html @@ -26,11 +26,11 @@

    Nouvelles fonctionnalités

Correction de bugs

    +
  • Résolution d'un problème de synchronisation de fichiers affectant notamment la suite Office
  • Correction d'un nouveau fichier mal téléchargé en mode LiteSync
  • Correction de l'absence de liens de partage dans le menu contextuel
  • Consolidation de la gestion des erreurs lors de l'étape de propagation
  • Ne pas bloquer le démarrage de l'application si le dossier de synchronisation local est manquant
  • -
  • Ajout des fichiers "*.tmp" aux modèles d'exclusion par défaut
  • Correction des fichiers mis sur liste noire à tort
  • Correction de la synchronisation interrompue sur les systèmes FAT
  • Correction du problème de démarrage en cas de type de proxy inconnu
  • diff --git a/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-macos-it.html b/release_notes/kDrive-3.6.7.20241120/kDrive-3.6.7.20241120-linux-it.html similarity index 91% rename from release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-macos-it.html rename to release_notes/kDrive-3.6.7.20241120/kDrive-3.6.7.20241120-linux-it.html index fa7082646..5ed9fa53e 100644 --- a/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-macos-it.html +++ b/release_notes/kDrive-3.6.7.20241120/kDrive-3.6.7.20241120-linux-it.html @@ -26,17 +26,17 @@

    Nuove caratteristiche

Correzioni di bug

    +
  • Risoluzione di un problema di sincronizzazione dei file che riguardava in particolare la suite Office.
  • Corretto il nuovo file scaricato erroneamente in modalità LiteSync
  • Correzione delle voci mancanti dei link di condivisione nel menu contestuale
  • Consolidamento della gestione degli errori durante la fase di propagazione
  • Non bloccare l'avvio dell'applicazione se manca la cartella di sincronizzazione locale
  • -
  • Aggiunti i file "*.tmp" ai modelli di esclusione predefiniti
  • Corretti i file erroneamente inseriti nella lista nera
  • Corretta la sincronizzazione interrotta sui sistemi FAT
  • Corretto il problema di avvio in caso di tipo di proxy sconosciuto
  • Problemi di migrazione corretti
  • Corretto lo stato in caso di interruzione del caricamento
  • -
  • Escludere i file e le cartelle con nomi di lunghezza superiore a 255 caratteri.
  • +
  • Escludete i file e le cartelle con nomi di lunghezza superiore a 255 caratteri.
  • Corretto l'errore di parsing CSV che portava a un'istantanea remota incompleta.
  • Gestione migliorata degli errori di accesso negato
diff --git a/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-macos-de.html b/release_notes/kDrive-3.6.7.20241120/kDrive-3.6.7.20241120-macos-de.html similarity index 95% rename from release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-macos-de.html rename to release_notes/kDrive-3.6.7.20241120/kDrive-3.6.7.20241120-macos-de.html index 6c2277ccc..26227bea2 100644 --- a/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-macos-de.html +++ b/release_notes/kDrive-3.6.7.20241120/kDrive-3.6.7.20241120-macos-de.html @@ -26,11 +26,11 @@

Neue Funktionen

Fehlerbehebungen

    +
  • Behebung eines Dateisynchronisationsproblems, das insbesondere die Office-Suite betrifft
  • Neue Datei wurde im LiteSync-Modus fälschlicherweise heruntergeladen
  • Fehlende Einträge für Freigabelinks im Kontextmenü behoben
  • Konsolidierung des Fehlermanagements während der Ausbreitungsphase
  • Start der Anwendung nicht blockieren, wenn der lokale Synchronisierungsordner fehlt
  • -
  • *.tmp"-Dateien zu Standard-Ausschlussvorlagen hinzugefügt
  • Falsch auf die schwarze Liste gesetzte Dateien korrigiert
  • Fehlerhafte Synchronisierung auf FAT-Systemen behoben
  • Startproblem im Falle eines unbekannten Proxy-Typs behoben
  • diff --git a/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-linux-en.html b/release_notes/kDrive-3.6.7.20241120/kDrive-3.6.7.20241120-macos-en.html similarity index 94% rename from release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-linux-en.html rename to release_notes/kDrive-3.6.7.20241120/kDrive-3.6.7.20241120-macos-en.html index 122e7014a..120319f26 100644 --- a/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-linux-en.html +++ b/release_notes/kDrive-3.6.7.20241120/kDrive-3.6.7.20241120-macos-en.html @@ -26,11 +26,11 @@

    New features

Bug fixes

    +
  • Resolution of a file synchronization problem affecting the Office suite in particular
  • Fixed new file wrongly downloaded in LiteSync mode
  • Fixed missing share links entries in contextual menu
  • Consolidation of error management during the propagation step
  • Do not block application startup if local sync folder is missing
  • -
  • Added "*.tmp" files to default exclusion templates
  • Fixed wrongly blacklisted files
  • Fixed broken sync on FAT systems
  • Fixed startup issue in case of unknown proxy type
  • diff --git a/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-linux-es.html b/release_notes/kDrive-3.6.7.20241120/kDrive-3.6.7.20241120-macos-es.html similarity index 94% rename from release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-linux-es.html rename to release_notes/kDrive-3.6.7.20241120/kDrive-3.6.7.20241120-macos-es.html index b2ede6ad7..e40e56611 100644 --- a/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-linux-es.html +++ b/release_notes/kDrive-3.6.7.20241120/kDrive-3.6.7.20241120-macos-es.html @@ -26,11 +26,11 @@

    Novedades

Corrección de errores

    +
  • Resolución de un problema de sincronización de archivos que afectaba sobre todo al paquete Office.
  • Corregido el error de descarga de un nuevo archivo en el modo LiteSync
  • Se ha corregido la falta de entradas de enlaces compartidos en el menú contextual.
  • Consolidación de la gestión de errores durante la etapa de propagación
  • No bloquear el inicio de la aplicación si falta la carpeta de sincronización local
  • -
  • Añadidos los archivos "*.tmp" a las plantillas de exclusión por defecto
  • Corrección de archivos incluidos erróneamente en la lista negra
  • Corregida la sincronización rota en sistemas FAT
  • Se ha corregido un problema de inicio en caso de tipo de proxy desconocido.
  • diff --git a/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-linux-fr.html b/release_notes/kDrive-3.6.7.20241120/kDrive-3.6.7.20241120-macos-fr.html similarity index 94% rename from release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-linux-fr.html rename to release_notes/kDrive-3.6.7.20241120/kDrive-3.6.7.20241120-macos-fr.html index adf5c75ba..5a93f04dc 100644 --- a/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-linux-fr.html +++ b/release_notes/kDrive-3.6.7.20241120/kDrive-3.6.7.20241120-macos-fr.html @@ -26,11 +26,11 @@

    Nouvelles fonctionnalités

Correction de bugs

    +
  • Résolution d'un problème de synchronisation de fichiers affectant notamment la suite Office
  • Correction d'un nouveau fichier mal téléchargé en mode LiteSync
  • Correction de l'absence de liens de partage dans le menu contextuel
  • Consolidation de la gestion des erreurs lors de l'étape de propagation
  • Ne pas bloquer le démarrage de l'application si le dossier de synchronisation local est manquant
  • -
  • Ajout des fichiers "*.tmp" aux modèles d'exclusion par défaut
  • Correction des fichiers mis sur liste noire à tort
  • Correction de la synchronisation interrompue sur les systèmes FAT
  • Correction du problème de démarrage en cas de type de proxy inconnu
  • diff --git a/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-linux-it.html b/release_notes/kDrive-3.6.7.20241120/kDrive-3.6.7.20241120-macos-it.html similarity index 91% rename from release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-linux-it.html rename to release_notes/kDrive-3.6.7.20241120/kDrive-3.6.7.20241120-macos-it.html index fa7082646..5ed9fa53e 100644 --- a/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-linux-it.html +++ b/release_notes/kDrive-3.6.7.20241120/kDrive-3.6.7.20241120-macos-it.html @@ -26,17 +26,17 @@

    Nuove caratteristiche

Correzioni di bug

    +
  • Risoluzione di un problema di sincronizzazione dei file che riguardava in particolare la suite Office.
  • Corretto il nuovo file scaricato erroneamente in modalità LiteSync
  • Correzione delle voci mancanti dei link di condivisione nel menu contestuale
  • Consolidamento della gestione degli errori durante la fase di propagazione
  • Non bloccare l'avvio dell'applicazione se manca la cartella di sincronizzazione locale
  • -
  • Aggiunti i file "*.tmp" ai modelli di esclusione predefiniti
  • Corretti i file erroneamente inseriti nella lista nera
  • Corretta la sincronizzazione interrotta sui sistemi FAT
  • Corretto il problema di avvio in caso di tipo di proxy sconosciuto
  • Problemi di migrazione corretti
  • Corretto lo stato in caso di interruzione del caricamento
  • -
  • Escludere i file e le cartelle con nomi di lunghezza superiore a 255 caratteri.
  • +
  • Escludete i file e le cartelle con nomi di lunghezza superiore a 255 caratteri.
  • Corretto l'errore di parsing CSV che portava a un'istantanea remota incompleta.
  • Gestione migliorata degli errori di accesso negato
diff --git a/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-win-de.html b/release_notes/kDrive-3.6.7.20241120/kDrive-3.6.7.20241120-win-de.html similarity index 95% rename from release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-win-de.html rename to release_notes/kDrive-3.6.7.20241120/kDrive-3.6.7.20241120-win-de.html index 0e5b63b9b..b357c56ba 100644 --- a/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-win-de.html +++ b/release_notes/kDrive-3.6.7.20241120/kDrive-3.6.7.20241120-win-de.html @@ -26,11 +26,11 @@

Neue Funktionen

Fehlerbehebungen

    +
  • Behebung eines Dateisynchronisationsproblems, das insbesondere die Office-Suite betrifft
  • Neue Datei wurde im LiteSync-Modus fälschlicherweise heruntergeladen
  • Fehlende Einträge für Freigabelinks im Kontextmenü behoben
  • Konsolidierung des Fehlermanagements während der Ausbreitungsphase
  • Start der Anwendung nicht blockieren, wenn der lokale Synchronisierungsordner fehlt
  • -
  • *.tmp"-Dateien zu Standard-Ausschlussvorlagen hinzugefügt
  • Falsch auf die schwarze Liste gesetzte Dateien korrigiert
  • Fehlerhafte Synchronisierung auf FAT-Systemen behoben
  • Startproblem im Falle eines unbekannten Proxy-Typs behoben
  • diff --git a/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-win-en.html b/release_notes/kDrive-3.6.7.20241120/kDrive-3.6.7.20241120-win-en.html similarity index 94% rename from release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-win-en.html rename to release_notes/kDrive-3.6.7.20241120/kDrive-3.6.7.20241120-win-en.html index 92290b222..4bf4e60b6 100644 --- a/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-win-en.html +++ b/release_notes/kDrive-3.6.7.20241120/kDrive-3.6.7.20241120-win-en.html @@ -26,11 +26,11 @@

    New features

Bug fixes

    +
  • Resolution of a file synchronization problem affecting the Office suite in particular
  • Fixed new file wrongly downloaded in LiteSync mode
  • Fixed missing share links entries in contextual menu
  • Consolidation of error management during the propagation step
  • Do not block application startup if local sync folder is missing
  • -
  • Added "*.tmp" files to default exclusion templates
  • Fixed wrongly blacklisted files
  • Fixed broken sync on FAT systems
  • Fixed startup issue in case of unknown proxy type
  • diff --git a/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-win-es.html b/release_notes/kDrive-3.6.7.20241120/kDrive-3.6.7.20241120-win-es.html similarity index 94% rename from release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-win-es.html rename to release_notes/kDrive-3.6.7.20241120/kDrive-3.6.7.20241120-win-es.html index 5022129f7..517ae4a5b 100644 --- a/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-win-es.html +++ b/release_notes/kDrive-3.6.7.20241120/kDrive-3.6.7.20241120-win-es.html @@ -26,11 +26,11 @@

    Novedades

Corrección de errores

    +
  • Resolución de un problema de sincronización de archivos que afectaba sobre todo al paquete Office.
  • Corregido el error de descarga de un nuevo archivo en el modo LiteSync
  • Se ha corregido la falta de entradas de enlaces compartidos en el menú contextual.
  • Consolidación de la gestión de errores durante la etapa de propagación
  • No bloquear el inicio de la aplicación si falta la carpeta de sincronización local
  • -
  • Añadidos los archivos "*.tmp" a las plantillas de exclusión por defecto
  • Corrección de archivos incluidos erróneamente en la lista negra
  • Corregida la sincronización rota en sistemas FAT
  • Se ha corregido un problema de inicio en caso de tipo de proxy desconocido.
  • diff --git a/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-win-fr.html b/release_notes/kDrive-3.6.7.20241120/kDrive-3.6.7.20241120-win-fr.html similarity index 95% rename from release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-win-fr.html rename to release_notes/kDrive-3.6.7.20241120/kDrive-3.6.7.20241120-win-fr.html index 6aca9264b..6885d5f55 100644 --- a/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-win-fr.html +++ b/release_notes/kDrive-3.6.7.20241120/kDrive-3.6.7.20241120-win-fr.html @@ -26,11 +26,11 @@

    Nouvelles fonctionnalités

Correction de bugs

    +
  • Résolution d'un problème de synchronisation de fichiers affectant notamment la suite Office
  • Correction d'un nouveau fichier mal téléchargé en mode LiteSync
  • Correction de l'absence de liens de partage dans le menu contextuel
  • Consolidation de la gestion des erreurs lors de l'étape de propagation
  • Ne pas bloquer le démarrage de l'application si le dossier de synchronisation local est manquant
  • -
  • Ajout des fichiers "*.tmp" aux modèles d'exclusion par défaut
  • Correction des fichiers mis sur liste noire à tort
  • Correction de la synchronisation interrompue sur les systèmes FAT
  • Correction du problème de démarrage en cas de type de proxy inconnu
  • diff --git a/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-win-it.html b/release_notes/kDrive-3.6.7.20241120/kDrive-3.6.7.20241120-win-it.html similarity index 91% rename from release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-win-it.html rename to release_notes/kDrive-3.6.7.20241120/kDrive-3.6.7.20241120-win-it.html index fd5946fae..5e1b5ed34 100644 --- a/release_notes/kDrive-3.6.7.20241105/kDrive-3.6.7.20241105-win-it.html +++ b/release_notes/kDrive-3.6.7.20241120/kDrive-3.6.7.20241120-win-it.html @@ -26,17 +26,17 @@

    Nuove caratteristiche

Correzioni di bug

    +
  • Risoluzione di un problema di sincronizzazione dei file che riguardava in particolare la suite Office.
  • Corretto il nuovo file scaricato erroneamente in modalità LiteSync
  • Correzione delle voci mancanti dei link di condivisione nel menu contestuale
  • Consolidamento della gestione degli errori durante la fase di propagazione
  • Non bloccare l'avvio dell'applicazione se manca la cartella di sincronizzazione locale
  • -
  • Aggiunti i file "*.tmp" ai modelli di esclusione predefiniti
  • Corretti i file erroneamente inseriti nella lista nera
  • Corretta la sincronizzazione interrotta sui sistemi FAT
  • Corretto il problema di avvio in caso di tipo di proxy sconosciuto
  • Problemi di migrazione corretti
  • Corretto lo stato in caso di interruzione del caricamento
  • -
  • Escludere i file e le cartelle con nomi di lunghezza superiore a 255 caratteri.
  • +
  • Escludete i file e le cartelle con nomi di lunghezza superiore a 255 caratteri.
  • Corretto il problema dei collegamenti simbolici e delle giunzioni
  • Corretto l'errore di parsing CSV che portava a un'istantanea remota incompleta.
  • Gestione migliorata degli errori di accesso negato
  • From 10e560ed29d5236fbacb862e4c23f0c2ee6b3bbc Mon Sep 17 00:00:00 2001 From: Christophe Larchier Date: Thu, 21 Nov 2024 08:55:02 +0100 Subject: [PATCH 127/178] Fix tests --- test/libsyncengine/propagation/executor/testexecutorworker.cpp | 1 + test/libsyncengine/propagation/executor/testintegration.cpp | 1 + .../propagation/operation_sorter/testoperationsorterworker.cpp | 1 + .../conflict_finder/testconflictfinderworker.cpp | 3 ++- .../conflict_resolver/testconflictresolverworker.cpp | 1 + .../operation_generator/testoperationgeneratorworker.cpp | 1 + .../testplatforminconsistencycheckerworker.cpp | 1 + test/libsyncengine/syncpal/testsyncpal.cpp | 3 ++- .../file_system_observer/testcomputefsoperationworker.cpp | 1 + .../file_system_observer/testlocalfilesystemobserverworker.cpp | 2 ++ .../testremotefilesystemobserverworker.cpp | 1 + test/server/workers/testworkers.cpp | 1 + 12 files changed, 15 insertions(+), 2 deletions(-) diff --git a/test/libsyncengine/propagation/executor/testexecutorworker.cpp b/test/libsyncengine/propagation/executor/testexecutorworker.cpp index 2cdbde318..8e228d539 100644 --- a/test/libsyncengine/propagation/executor/testexecutorworker.cpp +++ b/test/libsyncengine/propagation/executor/testexecutorworker.cpp @@ -69,6 +69,7 @@ void TestExecutorWorker::setUp() { } _syncPal = std::make_shared(_sync.dbId(), KDRIVE_VERSION_STRING); + _syncPal->createSharedObjects(); _syncPal->createWorkers(); _syncPal->syncDb()->setAutoDelete(true); } diff --git a/test/libsyncengine/propagation/executor/testintegration.cpp b/test/libsyncengine/propagation/executor/testintegration.cpp index e222e84cf..5ee9c99b5 100644 --- a/test/libsyncengine/propagation/executor/testintegration.cpp +++ b/test/libsyncengine/propagation/executor/testintegration.cpp @@ -108,6 +108,7 @@ void TestIntegration::setUp() { } _syncPal = std::make_shared(sync.dbId(), KDRIVE_VERSION_STRING); + _syncPal->createSharedObjects(); // Insert items to blacklist SyncNodeCache::instance()->update(_syncPal->syncDbId(), SyncNodeType::BlackList, {test_beaucoupRemoteId}); diff --git a/test/libsyncengine/propagation/operation_sorter/testoperationsorterworker.cpp b/test/libsyncengine/propagation/operation_sorter/testoperationsorterworker.cpp index 803d47b10..79610a27d 100644 --- a/test/libsyncengine/propagation/operation_sorter/testoperationsorterworker.cpp +++ b/test/libsyncengine/propagation/operation_sorter/testoperationsorterworker.cpp @@ -42,6 +42,7 @@ void TestOperationSorterWorker::setUp() { std::filesystem::remove(syncDbPath); _syncPal = std::make_shared(syncDbPath, KDRIVE_VERSION_STRING, true); _syncPal->syncDb()->setAutoDelete(true); + _syncPal->createSharedObjects(); _syncPal->_operationsSorterWorker = std::make_shared(_syncPal, "Operation Sorter", "OPSO"); } diff --git a/test/libsyncengine/reconciliation/conflict_finder/testconflictfinderworker.cpp b/test/libsyncengine/reconciliation/conflict_finder/testconflictfinderworker.cpp index f704c07a7..e766d745b 100644 --- a/test/libsyncengine/reconciliation/conflict_finder/testconflictfinderworker.cpp +++ b/test/libsyncengine/reconciliation/conflict_finder/testconflictfinderworker.cpp @@ -32,8 +32,9 @@ void TestConflictFinderWorker::setUp() { SyncPath syncDbPath = Db::makeDbName(1, 1, 1, 1, alreadyExists); std::filesystem::remove(syncDbPath); - _syncPal = std::shared_ptr(new SyncPal(syncDbPath, KDRIVE_VERSION_STRING, true)); + _syncPal = std::make_shared(syncDbPath, KDRIVE_VERSION_STRING, true); _syncPal->syncDb()->setAutoDelete(true); + _syncPal->createSharedObjects(); _syncPal->_conflictFinderWorker = std::shared_ptr(new ConflictFinderWorker(_syncPal, "Conflict Finder", "COFD")); diff --git a/test/libsyncengine/reconciliation/conflict_resolver/testconflictresolverworker.cpp b/test/libsyncengine/reconciliation/conflict_resolver/testconflictresolverworker.cpp index e7183a0cd..14c6a348e 100644 --- a/test/libsyncengine/reconciliation/conflict_resolver/testconflictresolverworker.cpp +++ b/test/libsyncengine/reconciliation/conflict_resolver/testconflictresolverworker.cpp @@ -35,6 +35,7 @@ void TestConflictResolverWorker::setUp() { std::filesystem::remove(syncDbPath); _syncPal = std::make_shared(syncDbPath, KDRIVE_VERSION_STRING, true); _syncPal->syncDb()->setAutoDelete(true); + _syncPal->createSharedObjects(); _syncPal->_conflictResolverWorker = std::make_shared(_syncPal, "Conflict Resolver", "CORE"); diff --git a/test/libsyncengine/reconciliation/operation_generator/testoperationgeneratorworker.cpp b/test/libsyncengine/reconciliation/operation_generator/testoperationgeneratorworker.cpp index 3a7560d58..8d85b3465 100644 --- a/test/libsyncengine/reconciliation/operation_generator/testoperationgeneratorworker.cpp +++ b/test/libsyncengine/reconciliation/operation_generator/testoperationgeneratorworker.cpp @@ -38,6 +38,7 @@ void KDC::TestOperationGeneratorWorker::setUp() { std::filesystem::remove(syncDbPath); _syncPal = std::make_shared(syncDbPath, KDRIVE_VERSION_STRING, true); _syncPal->syncDb()->setAutoDelete(true); + _syncPal->createSharedObjects(); _syncPal->_operationsGeneratorWorker = std::make_shared(_syncPal, "Operation Generator", "OPGE"); diff --git a/test/libsyncengine/reconciliation/platform_inconsistency_checker/testplatforminconsistencycheckerworker.cpp b/test/libsyncengine/reconciliation/platform_inconsistency_checker/testplatforminconsistencycheckerworker.cpp index a7d823add..8e429d66c 100644 --- a/test/libsyncengine/reconciliation/platform_inconsistency_checker/testplatforminconsistencycheckerworker.cpp +++ b/test/libsyncengine/reconciliation/platform_inconsistency_checker/testplatforminconsistencycheckerworker.cpp @@ -65,6 +65,7 @@ void TestPlatformInconsistencyCheckerWorker::setUp() { // Create SyncPal _syncPal = std::make_shared(sync.dbId(), KDRIVE_VERSION_STRING); _syncPal->syncDb()->setAutoDelete(true); + _syncPal->createSharedObjects(); _syncPal->_tmpBlacklistManager = std::make_shared(_syncPal); _syncPal->_platformInconsistencyCheckerWorker = diff --git a/test/libsyncengine/syncpal/testsyncpal.cpp b/test/libsyncengine/syncpal/testsyncpal.cpp index 9ef536b74..3a0c3038c 100644 --- a/test/libsyncengine/syncpal/testsyncpal.cpp +++ b/test/libsyncengine/syncpal/testsyncpal.cpp @@ -72,7 +72,8 @@ void TestSyncPal::setUp() { Proxy::instance(parameters.proxyConfig()); } - _syncPal = std::shared_ptr(new SyncPal(sync.dbId(), KDRIVE_VERSION_STRING)); + _syncPal = std::make_shared(sync.dbId(), KDRIVE_VERSION_STRING); + _syncPal->createSharedObjects(); } void TestSyncPal::tearDown() { diff --git a/test/libsyncengine/update_detection/file_system_observer/testcomputefsoperationworker.cpp b/test/libsyncengine/update_detection/file_system_observer/testcomputefsoperationworker.cpp index 8f30ca9c2..ee9ebf1e7 100644 --- a/test/libsyncengine/update_detection/file_system_observer/testcomputefsoperationworker.cpp +++ b/test/libsyncengine/update_detection/file_system_observer/testcomputefsoperationworker.cpp @@ -77,6 +77,7 @@ void TestComputeFSOperationWorker::setUp() { _syncPal = std::make_shared(sync.dbId(), KDRIVE_VERSION_STRING); _syncPal->syncDb()->setAutoDelete(true); + _syncPal->createSharedObjects(); /// Insert node "AC" in blacklist SyncNodeCache::instance()->update(_syncPal->syncDbId(), SyncNodeType::BlackList, {"lac"}); diff --git a/test/libsyncengine/update_detection/file_system_observer/testlocalfilesystemobserverworker.cpp b/test/libsyncengine/update_detection/file_system_observer/testlocalfilesystemobserverworker.cpp index d4a00b582..8e18d44f5 100644 --- a/test/libsyncengine/update_detection/file_system_observer/testlocalfilesystemobserverworker.cpp +++ b/test/libsyncengine/update_detection/file_system_observer/testlocalfilesystemobserverworker.cpp @@ -81,6 +81,7 @@ void TestLocalFileSystemObserverWorker::setUp() { // Create SyncPal _syncPal = std::make_shared(syncDbPath, KDRIVE_VERSION_STRING, true); _syncPal->syncDb()->setAutoDelete(true); + _syncPal->createSharedObjects(); _syncPal->setLocalPath(_rootFolderPath); _syncPal->_tmpBlacklistManager = std::make_shared(_syncPal); #if defined(_WIN32) @@ -411,6 +412,7 @@ void TestLocalFileSystemObserverWorker::testLFSOWithSpecialCases2() { void TestLocalFileSystemObserverWorker::testLFSOFastMoveDeleteMove() { // MS Office test LOGW_DEBUG(_logger, L"***** Test fast move/delete *****"); _syncPal->_localFSObserverWorker->stop(); + _syncPal->_localFSObserverWorker->waitForExit(); _syncPal->_localFSObserverWorker.reset(); // Create a slow observer diff --git a/test/libsyncengine/update_detection/file_system_observer/testremotefilesystemobserverworker.cpp b/test/libsyncengine/update_detection/file_system_observer/testremotefilesystemobserverworker.cpp index bbfed8fbd..bbfd24d97 100644 --- a/test/libsyncengine/update_detection/file_system_observer/testremotefilesystemobserverworker.cpp +++ b/test/libsyncengine/update_detection/file_system_observer/testremotefilesystemobserverworker.cpp @@ -85,6 +85,7 @@ void TestRemoteFileSystemObserverWorker::setUp() { _syncPal = std::make_shared(sync.dbId(), KDRIVE_VERSION_STRING); _syncPal->syncDb()->setAutoDelete(true); + _syncPal->createSharedObjects(); /// Insert node in blacklist SyncNodeCache::instance()->update(_syncPal->syncDbId(), SyncNodeType::BlackList, {testBlackListedDirId}); diff --git a/test/server/workers/testworkers.cpp b/test/server/workers/testworkers.cpp index af6ac1aef..97e09f253 100644 --- a/test/server/workers/testworkers.cpp +++ b/test/server/workers/testworkers.cpp @@ -150,6 +150,7 @@ void TestWorkers::setUp() { // Setup SyncPal _syncPal = std::make_shared(_sync.dbId(), KDRIVE_VERSION_STRING); + _syncPal->createSharedObjects(); _syncPal->createWorkers(); _syncPal->syncDb()->setAutoDelete(true); _syncPal->createProgressInfo(); From 75b7ac739c62ae734890d748e07893bf85ca28be Mon Sep 17 00:00:00 2001 From: Christophe Larchier Date: Thu, 21 Nov 2024 09:55:01 +0100 Subject: [PATCH 128/178] Address comment --- src/libcommonserver/utility/utility.cpp | 2 +- src/libcommonserver/utility/utility.h | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/libcommonserver/utility/utility.cpp b/src/libcommonserver/utility/utility.cpp index 4f3040a59..8ecfc4315 100644 --- a/src/libcommonserver/utility/utility.cpp +++ b/src/libcommonserver/utility/utility.cpp @@ -913,7 +913,7 @@ std::string Utility::userName() { return userName_private(); } -ExitInfo Utility::terminateThreadFunction(ExitInfo exitInfo) { +ExitInfo Utility::terminateThreadFunction(const ExitInfo exitInfo) { log4cplus::threadCleanup(); return exitInfo; } diff --git a/src/libcommonserver/utility/utility.h b/src/libcommonserver/utility/utility.h index e018f1634..8787533f2 100644 --- a/src/libcommonserver/utility/utility.h +++ b/src/libcommonserver/utility/utility.h @@ -184,7 +184,13 @@ struct COMMONSERVER_EXPORT Utility { static SyncPath sharedFolderName(); static std::string userName(); - static ExitInfo terminateThreadFunction(ExitInfo exitInfo = ExitInfo()); + //! Releases the memory used by log4cplus and returns the exitInfo parameter passed as parameter. + //! Functions executed in a thread must use this function to exit. + /*! + \param exitInfo to return + \return exitInfo passed as parameter + */ + static ExitInfo terminateThreadFunction(const ExitInfo exitInfo = ExitInfo()); private: static log4cplus::Logger _logger; From f91d1be434d0224bcd1ffc4baaa11e397c111b90 Mon Sep 17 00:00:00 2001 From: Christophe Larchier Date: Thu, 21 Nov 2024 10:36:10 +0100 Subject: [PATCH 129/178] Fix crash --- src/libsyncengine/syncpal/syncpalworker.cpp | 7 ++++++- src/libsyncengine/syncpal/syncpalworker.h | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/libsyncengine/syncpal/syncpalworker.cpp b/src/libsyncengine/syncpal/syncpalworker.cpp index 19d612d86..1d456e630 100644 --- a/src/libsyncengine/syncpal/syncpalworker.cpp +++ b/src/libsyncengine/syncpal/syncpalworker.cpp @@ -74,7 +74,7 @@ void SyncPalWorker::execute() { // Pause sync LOG_SYNCPAL_DEBUG(_logger, "Stop FSO worker " << index); isFSOInProgress[index] = false; - fsoWorkers[index]->stop(); + stopAndWaitForExitOfWorker(fsoWorkers[index]); pause(); } else { // Start worker @@ -464,6 +464,11 @@ SyncStep SyncPalWorker::nextStep() const { } } +void SyncPalWorker::stopAndWaitForExitOfWorker(std::shared_ptr worker) { + worker->stop(); + worker->waitForExit(); +} + void SyncPalWorker::stopWorkers(std::shared_ptr workers[2]) { for (int index = 0; index < 2; index++) { if (workers[index]) { diff --git a/src/libsyncengine/syncpal/syncpalworker.h b/src/libsyncengine/syncpal/syncpalworker.h index 9e00b2cfd..34ec75357 100644 --- a/src/libsyncengine/syncpal/syncpalworker.h +++ b/src/libsyncengine/syncpal/syncpalworker.h @@ -45,6 +45,7 @@ class SyncPalWorker : public ISyncWorker { bool reset); bool interruptCondition() const; SyncStep nextStep() const; + void stopAndWaitForExitOfWorker(std::shared_ptr worker); void stopWorkers(std::shared_ptr workers[2]); void waitForExitOfWorkers(std::shared_ptr workers[2]); void stopAndWaitForExitOfWorkers(std::shared_ptr workers[2]); From 8d5b15eaece84eefb44ccdd4e732e32a4f51344a Mon Sep 17 00:00:00 2001 From: Herve Eruam Date: Thu, 21 Nov 2024 11:02:52 +0100 Subject: [PATCH 130/178] Allow to lock TerminatedJobsQueue as a mutex. --- .../propagation/executor/executorworker.cpp | 1 + .../propagation/executor/executorworker.h | 17 +++--- test/libcommonserver/CMakeLists.txt | 2 +- test/libcommonserver/io/testopenfile.cpp | 38 ++------------ .../executor/testexecutorworker.cpp | 52 +++++++++++++++++++ .../propagation/executor/testexecutorworker.h | 2 + test/test_utility/timechecker.h | 49 +++++++++++++++++ 7 files changed, 121 insertions(+), 40 deletions(-) create mode 100644 test/test_utility/timechecker.h diff --git a/src/libsyncengine/propagation/executor/executorworker.cpp b/src/libsyncengine/propagation/executor/executorworker.cpp index 6caf2f028..3ece2de34 100644 --- a/src/libsyncengine/propagation/executor/executorworker.cpp +++ b/src/libsyncengine/propagation/executor/executorworker.cpp @@ -1513,6 +1513,7 @@ ExitInfo ExecutorWorker::waitForAllJobsToFinish() { ExitInfo ExecutorWorker::deleteFinishedAsyncJobs() { ExitInfo exitInfo = ExitCode::Ok; while (!_terminatedJobs.empty()) { + std::scoped_lock lock(_terminatedJobs); // Delete all terminated jobs if (exitInfo && _ongoingJobs.find(_terminatedJobs.front()) != _ongoingJobs.end()) { auto onGoingJobIt = _ongoingJobs.find(_terminatedJobs.front()); diff --git a/src/libsyncengine/propagation/executor/executorworker.h b/src/libsyncengine/propagation/executor/executorworker.h index d662fb947..6851ba511 100644 --- a/src/libsyncengine/propagation/executor/executorworker.h +++ b/src/libsyncengine/propagation/executor/executorworker.h @@ -38,22 +38,27 @@ class SyncDb; * In the context of `ExecutorWorker`, the terminated jobs queue is the only container that can be accessed from multiple threads, * namely, the job threads. Therefore, it is the only container that requires to be thread safe. */ -class TerminatedJobsQueue { +class TerminatedJobsQueue : public std::recursive_mutex { public: void push(const UniqueId id) { - const std::scoped_lock lock(_mutex); + const std::scoped_lock lock(*this); _terminatedJobs.push(id); } void pop() { - const std::scoped_lock lock(_mutex); + const std::scoped_lock lock(*this); _terminatedJobs.pop(); } - [[nodiscard]] UniqueId front() const { return _terminatedJobs.front(); } - [[nodiscard]] bool empty() const { return _terminatedJobs.empty(); } + [[nodiscard]] UniqueId front() { + const std::scoped_lock lock(*this); + return _terminatedJobs.front(); + } + [[nodiscard]] bool empty() { + const std::scoped_lock lock(*this); + return _terminatedJobs.empty(); + } private: std::queue _terminatedJobs; - std::mutex _mutex; }; class ExecutorWorker : public OperationProcessor { diff --git a/test/libcommonserver/CMakeLists.txt b/test/libcommonserver/CMakeLists.txt index fdc2ba605..73b1fb1ff 100644 --- a/test/libcommonserver/CMakeLists.txt +++ b/test/libcommonserver/CMakeLists.txt @@ -9,7 +9,7 @@ set(testcommonserver_SRCS ../test.cpp ../test_utility/localtemporarydirectory.cpp ../test_utility/testhelpers.h ../test_utility/testhelpers.cpp - + ../test_utility/timechecker.h test.cpp # Utility utility/testutility.h utility/testutility.cpp diff --git a/test/libcommonserver/io/testopenfile.cpp b/test/libcommonserver/io/testopenfile.cpp index 2c4b2f5da..df2444784 100644 --- a/test/libcommonserver/io/testopenfile.cpp +++ b/test/libcommonserver/io/testopenfile.cpp @@ -18,41 +18,13 @@ #include "testio.h" #include "test_utility/testhelpers.h" +#include "test_utility/timechecker.h" + #include using namespace CppUnit; namespace KDC { -class TimeOutChecker { - public: - explicit TimeOutChecker(bool start = false) { - if (start) this->start(); - } - void start() { _time = std::chrono::steady_clock::now(); } - void stop() { - auto end = std::chrono::steady_clock::now(); - _diff = std::chrono::duration_cast(end - _time).count(); - } - bool lessOrEqualThan(long long value) { - if (_diff > value) std::cout << "TimeOutChecker::lessThan: " << _diff << " >= " << value << std::endl; - return _diff <= value; - } - bool greaterOrEqualThan(long long value) { - if (_diff < value) std::cout << "TimeOutChecker::greaterThan: " << _diff << " <= " << value << std::endl; - return _diff >= value; - } - bool between(long long min, long long max) { - if (_diff < min || _diff > max) - std::cout << "TimeOutChecker::between: " << _diff << " <= " << min << " || " << _diff << " >= " << max - << std::endl; - return _diff >= min && _diff <= max; - } - - private: - std::chrono::steady_clock::time_point _time; - long long _diff{0}; -}; - bool checkContent(std::ifstream &file) { std::string content; std::getline(file, content); @@ -80,7 +52,7 @@ void TestIo::testOpenFileAccessDenied() { // Without timeout std::ifstream file; - TimeOutChecker timeOutChecker(true); + TimeChecker timeOutChecker(true); CPPUNIT_ASSERT_EQUAL(ExitInfo(ExitCode::SystemError, ExitCause::FileAccessError), IoHelper::openFile(filePath, file, 0)); timeOutChecker.stop(); CPPUNIT_ASSERT(timeOutChecker.lessOrEqualThan(200)); @@ -98,7 +70,7 @@ void TestIo::testOpenFileNonExisting() { LocalTemporaryDirectory tempDir("testOpenFileNonExisting"); SyncPath filePath = tempDir.path() / "testOpenFileNonExisting.txt"; std::ifstream file; - TimeOutChecker timeOutChecker(true); + TimeChecker timeOutChecker(true); CPPUNIT_ASSERT_EQUAL(ExitInfo(ExitCode::SystemError, ExitCause::NotFound), IoHelper::openFile(filePath, file, 5)); timeOutChecker.stop(); CPPUNIT_ASSERT(timeOutChecker.lessOrEqualThan(200)); @@ -128,7 +100,7 @@ void TestIo::testOpenLockedFileRemovedBeforeTimedOut() { }; std::thread restoreRightsThread(restoreRights); - TimeOutChecker timeOutChecker(true); + TimeChecker timeOutChecker(true); CPPUNIT_ASSERT_EQUAL(ExitInfo(ExitCode::Ok), IoHelper::openFile(filePath, file, 4)); timeOutChecker.stop(); restoreRightsThread.join(); diff --git a/test/libsyncengine/propagation/executor/testexecutorworker.cpp b/test/libsyncengine/propagation/executor/testexecutorworker.cpp index 2cdbde318..6e57822d1 100644 --- a/test/libsyncengine/propagation/executor/testexecutorworker.cpp +++ b/test/libsyncengine/propagation/executor/testexecutorworker.cpp @@ -198,6 +198,58 @@ void TestExecutorWorker::testIsValidDestination() { } } +void TestExecutorWorker::testTerminatedJobsQueue() { + TerminatedJobsQueue terminatedJobsQueue; + + int ended = 0; // count the number of ended threads + + // Function objects to be used in the thread + std::function inserter = [&terminatedJobsQueue, &ended](const UniqueId id) { + terminatedJobsQueue.push(id); + ended++; + }; + std::function popper = [&terminatedJobsQueue, &ended]() { + terminatedJobsQueue.pop(); + ended++; + }; + std::function fronter = [&terminatedJobsQueue, &ended]() { + [[maybe_unused]] auto foo = terminatedJobsQueue.front(); + ended++; + }; + std::function emptyChecker = [&terminatedJobsQueue, &ended]() { + [[maybe_unused]] auto foo = terminatedJobsQueue.empty(); + ended++; + }; + + // Check that all functions are thread safe + terminatedJobsQueue.lock(); // Lock the queue for the current thread + + std::thread t1(inserter, 1); + Utility::msleep(10); // Give enough time for the thread to terminate + CPPUNIT_ASSERT_EQUAL(0, ended); + + std::thread t2(fronter); + Utility::msleep(10); + CPPUNIT_ASSERT_EQUAL(0, ended); + + std::thread t3(popper); + Utility::msleep(10); + CPPUNIT_ASSERT_EQUAL(0, ended); + + std::thread t4(emptyChecker); + Utility::msleep(10); + CPPUNIT_ASSERT_EQUAL(0, ended); + + terminatedJobsQueue.unlock(); // Unlock the queue for the current thread + Utility::msleep(10); + CPPUNIT_ASSERT_EQUAL(4, ended); + + t1.join(); + t2.join(); + t3.join(); + t4.join(); // Wait for all threads to finish. +} + void TestExecutorWorker::testLogCorrespondingNodeErrorMsg() { SyncOpPtr op = generateSyncOperation(1, Str("test_file.txt")); _syncPal->_executorWorker->logCorrespondingNodeErrorMsg(op); diff --git a/test/libsyncengine/propagation/executor/testexecutorworker.h b/test/libsyncengine/propagation/executor/testexecutorworker.h index 316590112..963795482 100644 --- a/test/libsyncengine/propagation/executor/testexecutorworker.h +++ b/test/libsyncengine/propagation/executor/testexecutorworker.h @@ -33,6 +33,7 @@ class TestExecutorWorker : public CppUnit::TestFixture { CPPUNIT_TEST(testLogCorrespondingNodeErrorMsg); CPPUNIT_TEST(testRemoveDependentOps); CPPUNIT_TEST(testIsValidDestination); + CPPUNIT_TEST(testTerminatedJobsQueue); CPPUNIT_TEST_SUITE_END(); public: @@ -47,6 +48,7 @@ class TestExecutorWorker : public CppUnit::TestFixture { void testLogCorrespondingNodeErrorMsg(); void testRemoveDependentOps(); void testIsValidDestination(); + void testTerminatedJobsQueue(); bool opsExist(SyncOpPtr op); SyncOpPtr generateSyncOperation(const DbNodeId dbNodeId, const SyncName &filename, diff --git a/test/test_utility/timechecker.h b/test/test_utility/timechecker.h new file mode 100644 index 000000000..551f770cb --- /dev/null +++ b/test/test_utility/timechecker.h @@ -0,0 +1,49 @@ +/* + * Infomaniak kDrive - Desktop + * Copyright (C) 2023-2024 Infomaniak Network SA + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +class TimeChecker { + public: + explicit TimeChecker(bool start = false) { + if (start) this->start(); + } + void start() { _time = std::chrono::steady_clock::now(); } + void stop() { + auto end = std::chrono::steady_clock::now(); + _diff = std::chrono::duration_cast(end - _time).count(); + } + bool lessOrEqualThan(long long value) { + if (_diff > value) std::cout << "TimeChecker::lessThan: " << _diff << " >= " << value << std::endl; + return _diff <= value; + } + bool greaterOrEqualThan(long long value) { + if (_diff < value) std::cout << "TimeChecker::greaterThan: " << _diff << " <= " << value << std::endl; + return _diff >= value; + } + bool between(long long min, long long max) { + if (_diff < min || _diff > max) + std::cout << "TimeChecker::between: " << _diff << " <= " << min << " || " << _diff << " >= " << max + << std::endl; + return _diff >= min && _diff <= max; + } + + private: + std::chrono::steady_clock::time_point _time; + long long _diff{0}; +}; From a2b3e3e3ace163895eafc75a6548e19028f72c2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Kunz?= Date: Thu, 21 Nov 2024 14:30:54 +0100 Subject: [PATCH 131/178] KDESKTOP-1399 - Add some logs --- src/server/updater/sparkleupdater.mm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/server/updater/sparkleupdater.mm b/src/server/updater/sparkleupdater.mm index 934b75400..32be98510 100644 --- a/src/server/updater/sparkleupdater.mm +++ b/src/server/updater/sparkleupdater.mm @@ -126,9 +126,9 @@ - (void)updater:(SPUUpdater *)updater didFindValidUpdate:(SUAppcastItem *)update } // Sent when a valid update is not found. -- (void)updaterDidNotFindUpdate:(SPUUpdater *)update { +- (void)updaterDidNotFindUpdate:(SPUUpdater *)update error:(nonnull NSError *)error { (void)update; - LOG_DEBUG(KDC::Log::instance()->getLogger(), "No valid update found"); + LOG_DEBUG(KDC::Log::instance()->getLogger(), "No valid update found - Error code: " << [error code] << ", reason: " << [error.userInfo[SPUNoUpdateFoundReasonKey] integerValue]); } // Sent immediately before installing the specified update. From 8c136b5fb0e23fa8e60d13107798b2afba2b92af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Kunz?= Date: Thu, 21 Nov 2024 16:21:14 +0100 Subject: [PATCH 132/178] KDESKTOP-1399 - Cleanup skipped version --- src/server/updater/updatemanager.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/server/updater/updatemanager.cpp b/src/server/updater/updatemanager.cpp index 509c8588d..79730b84c 100644 --- a/src/server/updater/updatemanager.cpp +++ b/src/server/updater/updatemanager.cpp @@ -54,6 +54,15 @@ UpdateManager::UpdateManager(QObject *parent) : QObject(parent) { void UpdateManager::startInstaller() const { LOG_DEBUG(Log::instance()->getLogger(), "startInstaller called!"); + + // Cleanup skipped version + ParametersCache::instance()->parameters().setSeenVersion(""); + ParametersCache::instance()->save(); +#if defined(__APPLE__) + // Discard skipped version in Sparkle + std::system("defaults delete com.infomaniak.drive.desktopclient SUSkippedVersion"); +#endif + _updater->startInstaller(); } From d0fb6030223346e502f79b834cd0f287cb3562ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Kunz?= Date: Thu, 21 Nov 2024 16:56:52 +0100 Subject: [PATCH 133/178] KDESKTOP-1399 - Re-write unskip method in objective-c --- src/server/updater/abstractupdater.cpp | 4 ++++ src/server/updater/sparkleupdater.h | 2 ++ src/server/updater/sparkleupdater.mm | 6 ++++++ src/server/updater/updatemanager.cpp | 7 +------ 4 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/server/updater/abstractupdater.cpp b/src/server/updater/abstractupdater.cpp index aa38f9497..a18c60976 100644 --- a/src/server/updater/abstractupdater.cpp +++ b/src/server/updater/abstractupdater.cpp @@ -18,6 +18,7 @@ #include "abstractupdater.h" +#include "sparkleupdater.h" #include "libcommon/utility/utility.h" #include "log/log.h" #include "requests/parameterscache.h" @@ -65,6 +66,9 @@ void AbstractUpdater::unskipVersion() { ParametersCache::instance()->parameters().setSeenVersion(""); ParametersCache::instance()->save(); } +#if defined(__APPLE__) + SparkleUpdater::unskipVersion(); +#endif } bool AbstractUpdater::isVersionSkipped(const std::string& version) { diff --git a/src/server/updater/sparkleupdater.h b/src/server/updater/sparkleupdater.h index 605d24e76..0d56a4f25 100644 --- a/src/server/updater/sparkleupdater.h +++ b/src/server/updater/sparkleupdater.h @@ -32,6 +32,8 @@ class SparkleUpdater final : public AbstractUpdater { void setQuitCallback(const std::function &quitCallback) override; void startInstaller() override; + static void unskipVersion(); + private: void reset(const std::string &url); void deleteUpdater(); diff --git a/src/server/updater/sparkleupdater.mm b/src/server/updater/sparkleupdater.mm index 32be98510..b8bf620af 100644 --- a/src/server/updater/sparkleupdater.mm +++ b/src/server/updater/sparkleupdater.mm @@ -209,6 +209,12 @@ - (BOOL)supportsGentleScheduledUpdateReminders { [d->spuStandardUserDriver showUpdateInFocus]; } +void SparkleUpdater::unskipVersion() { + // Discard skipped version in Sparkle + [[NSUserDefaults standardUserDefaults] removeObjectForKey:@ "SUSkippedVersion"]; + [[NSUserDefaults standardUserDefaults] synchronize]; +} + void SparkleUpdater::reset(const std::string &url) { [d->spuStandardUserDriver dismissUpdateInstallation]; deleteUpdater(); diff --git a/src/server/updater/updatemanager.cpp b/src/server/updater/updatemanager.cpp index 79730b84c..51fa81536 100644 --- a/src/server/updater/updatemanager.cpp +++ b/src/server/updater/updatemanager.cpp @@ -56,12 +56,7 @@ void UpdateManager::startInstaller() const { LOG_DEBUG(Log::instance()->getLogger(), "startInstaller called!"); // Cleanup skipped version - ParametersCache::instance()->parameters().setSeenVersion(""); - ParametersCache::instance()->save(); -#if defined(__APPLE__) - // Discard skipped version in Sparkle - std::system("defaults delete com.infomaniak.drive.desktopclient SUSkippedVersion"); -#endif + AbstractUpdater::unskipVersion(); _updater->startInstaller(); } From 6bd7e97c4c7b902792801b43badafefb5b4913ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Kunz?= Date: Fri, 22 Nov 2024 08:13:59 +0100 Subject: [PATCH 134/178] KDESKTOP-1399 - Address PR comment --- src/server/updater/abstractupdater.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/server/updater/abstractupdater.cpp b/src/server/updater/abstractupdater.cpp index a18c60976..addd13c2f 100644 --- a/src/server/updater/abstractupdater.cpp +++ b/src/server/updater/abstractupdater.cpp @@ -18,10 +18,12 @@ #include "abstractupdater.h" -#include "sparkleupdater.h" #include "libcommon/utility/utility.h" #include "log/log.h" #include "requests/parameterscache.h" +#if defined(__APPLE__) +#include "sparkleupdater.h" +#endif namespace KDC { From b5bd9544807e55ba95764729d8265720ecb131d3 Mon Sep 17 00:00:00 2001 From: Christophe Larchier Date: Fri, 22 Nov 2024 09:58:44 +0100 Subject: [PATCH 135/178] Fix start --- .../file_system_observer/localfilesystemobserverworker.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/libsyncengine/update_detection/file_system_observer/localfilesystemobserverworker.cpp b/src/libsyncengine/update_detection/file_system_observer/localfilesystemobserverworker.cpp index 0bf20577a..7945ec8d9 100644 --- a/src/libsyncengine/update_detection/file_system_observer/localfilesystemobserverworker.cpp +++ b/src/libsyncengine/update_detection/file_system_observer/localfilesystemobserverworker.cpp @@ -86,6 +86,12 @@ void LocalFileSystemObserverWorker::changesDetected(const std::listlocalPath(), absolutePath); +#ifdef __APPLE__ + // Reset extended attributes of new items + if (opTypeFromOS == OperationType::Create) { + } +#endif + // Check if exists with same nodeId if (opTypeFromOS == OperationType::Delete) { NodeId prevNodeId = _snapshot->itemId(relativePath); From 30f5f2c03b7c32fd7d54cd27660b365b57431b08 Mon Sep 17 00:00:00 2001 From: Christophe Larchier Date: Fri, 22 Nov 2024 10:05:46 +0100 Subject: [PATCH 136/178] Address comments --- .../file_system_observer/snapshot/snapshot.cpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/libsyncengine/update_detection/file_system_observer/snapshot/snapshot.cpp b/src/libsyncengine/update_detection/file_system_observer/snapshot/snapshot.cpp index aad9a2bfc..2a6a2d31a 100644 --- a/src/libsyncengine/update_detection/file_system_observer/snapshot/snapshot.cpp +++ b/src/libsyncengine/update_detection/file_system_observer/snapshot/snapshot.cpp @@ -132,8 +132,8 @@ bool Snapshot::updateItem(const SnapshotItem &newItem) { } if (ParametersCache::isExtendedLogEnabled()) { - LOGW_DEBUG(Log::instance()->getLogger(), L"Item: " << SyncName2WStr(newItem.name()).c_str() << L" (" - << Utility::s2ws(newItem.id()).c_str() << L") updated at:" + LOGW_DEBUG(Log::instance()->getLogger(), L"Item: " << SyncName2WStr(newItem.name()) << L" (" + << Utility::s2ws(newItem.id()) << L") updated at:" << newItem.lastModified()); } @@ -519,11 +519,10 @@ bool Snapshot::checkIntegrityRecursively(const NodeId &parentId) const { auto result = names.insert(_items.at(*childId).name()); if (!result.second) { - LOGW_WARN(Log::instance()->getLogger(), L"Snapshot integrity check failed, the folder named: \"" - << SyncName2WStr(parentItem.name()).c_str() << L"\"(" - << Utility::s2ws(parentItem.id()).c_str() << L") contains: \"" - << SyncName2WStr(_items.at(*childId).name()).c_str() - << L"\" twice with two differents NodeId"); + LOGW_WARN(Log::instance()->getLogger(), + L"Snapshot integrity check failed, the folder named: \"" + << SyncName2WStr(parentItem.name()) << L"\"(" << Utility::s2ws(parentItem.id()) << L") contains: \"" + << SyncName2WStr(_items.at(*childId).name()) << L"\" twice with two different NodeIds"); return false; } } From 1e2e505773ae2531092093b99040e38e6fa4e779 Mon Sep 17 00:00:00 2001 From: Luc Guyot Date: Fri, 15 Nov 2024 11:34:12 +0100 Subject: [PATCH 137/178] Enables the logger to handle std::string directly --- src/libcommon/CMakeLists.txt | 2 +- ...{customlogwstream.h => customlogstreams.h} | 75 ++++++++++++- src/libcommon/utility/types.h | 7 +- src/libcommonserver/db/db.cpp | 6 +- src/libcommonserver/log/log.h | 100 +++++++++++++----- .../jobs/network/abstractnetworkjob.cpp | 2 +- .../platforminconsistencycheckerworker.cpp | 6 +- test/libcommonserver/log/testlog.cpp | 25 +++-- 8 files changed, 180 insertions(+), 43 deletions(-) rename src/libcommon/log/{customlogwstream.h => customlogstreams.h} (50%) diff --git a/src/libcommon/CMakeLists.txt b/src/libcommon/CMakeLists.txt index 7225d27b3..16b474be0 100644 --- a/src/libcommon/CMakeLists.txt +++ b/src/libcommon/CMakeLists.txt @@ -39,7 +39,7 @@ set(libcommon_SRCS info/proxyconfiginfo.h info/proxyconfiginfo.cpp log/sentry/sentryhandler.h log/sentry/sentryhandler.cpp log/sentry/sentryuser.h - log/customlogwstream.h + log/customlogstreams.h theme/theme.h theme/theme.cpp ) diff --git a/src/libcommon/log/customlogwstream.h b/src/libcommon/log/customlogstreams.h similarity index 50% rename from src/libcommon/log/customlogwstream.h rename to src/libcommon/log/customlogstreams.h index bcc4d045c..aa52a8300 100644 --- a/src/libcommon/log/customlogwstream.h +++ b/src/libcommon/log/customlogstreams.h @@ -17,7 +17,71 @@ */ #pragma once #include -#include "libcommon/utility/types.h" + +#include + +class CustomLogStream : private std::stringstream { + public: + CustomLogStream() = default; + inline CustomLogStream(const CustomLogStream &str) = delete; + CustomLogStream &operator=(const CustomLogStream &) = delete; + + std::string str() const { return std::basic_stringstream::str(); } + + // We need to cast to std::stringstream as operators<<(std::stringstream, const wchar_t *str /*and const std::wstring + // &str*/) are defined outside of the class std::stringstream and therefore it is not applicable to the current object + // because of the private inheritance + CustomLogStream &operator<<(const char *str) { + static_cast(*this) << str; + return *this; + } + CustomLogStream &operator<<(const std::string &str) { + static_cast(*this) << str; + return *this; + } + + CustomLogStream &operator<<(bool b) { + std::stringstream::operator<<(std::boolalpha); + std::stringstream::operator<<(b); + return *this; + } + CustomLogStream &operator<<(int i) { + std::stringstream::operator<<(i); + return *this; + } + CustomLogStream &operator<<(long i64) { + std::stringstream::operator<<(i64); + return *this; + } + CustomLogStream &operator<<(unsigned int ui) { + std::stringstream::operator<<(ui); + return *this; + } + CustomLogStream &operator<<(long long i64) { + std::stringstream::operator<<(i64); + return *this; + } + CustomLogStream &operator<<(unsigned long ul) { + std::stringstream::operator<<(ul); + return *this; + } + CustomLogStream &operator<<(unsigned long long ui64) { + std::stringstream::operator<<(ui64); + return *this; + } + CustomLogStream &operator<<(double d) { + std::stringstream::operator<<(d); + return *this; + } + CustomLogStream &operator<<(const QIODevice *ptr) { + std::stringstream::operator<<(ptr); + return *this; + } + CustomLogStream &operator<<(const std::error_code &code) { + std::stringstream::operator<<(code.value()); + return *this; + } +}; class CustomLogWStream : private std::wstringstream { public: @@ -40,6 +104,7 @@ class CustomLogWStream : private std::wstringstream { } CustomLogWStream &operator<<(bool b) { + std::wstringstream::operator<<(std::boolalpha); std::wstringstream::operator<<(b); return *this; } @@ -47,6 +112,10 @@ class CustomLogWStream : private std::wstringstream { std::wstringstream::operator<<(i); return *this; } + CustomLogWStream &operator<<(unsigned int ui) { + std::wstringstream::operator<<(ui); + return *this; + } CustomLogWStream &operator<<(long i64) { std::wstringstream::operator<<(i64); return *this; @@ -71,4 +140,8 @@ class CustomLogWStream : private std::wstringstream { std::wstringstream::operator<<(ptr); return *this; } + CustomLogWStream &operator<<(const std::error_code &code) { + std::wstringstream::operator<<(code.value()); + return *this; + } }; diff --git a/src/libcommon/utility/types.h b/src/libcommon/utility/types.h index 3fea8198f..d9f151991 100644 --- a/src/libcommon/utility/types.h +++ b/src/libcommon/utility/types.h @@ -28,7 +28,7 @@ #include #include #include -#include "libcommon/log/customlogwstream.h" +#include "libcommon/log/customlogstreams.h" namespace KDC { @@ -615,6 +615,11 @@ inline CustomLogWStream &operator<<(CustomLogWStream &os, C e) { } template + inline CustomLogStream &operator<<(CustomLogStream &os, C e) { + return os << toStringWithCode(e); +} + +template inline QDebug &operator<<(QDebug &os, C e) { return os << toStringWithCode(e).c_str(); } diff --git a/src/libcommonserver/db/db.cpp b/src/libcommonserver/db/db.cpp index 7bb749eec..4152ae186 100644 --- a/src/libcommonserver/db/db.cpp +++ b/src/libcommonserver/db/db.cpp @@ -376,7 +376,7 @@ bool Db::init(const std::string &version) { queryFree(CREATE_VERSION_TABLE_ID); // Insert version - LOG_DEBUG(_logger, "Insert version " << version.c_str()); + LOG_DEBUG(_logger, "Insert version " << version); if (!prepareQuery(INSERT_VERSION_REQUEST_ID, INSERT_VERSION_REQUEST)) return false; if (!insertVersion(version)) { LOG_WARN(_logger, "Error in Db::insertVersion"); @@ -386,7 +386,7 @@ bool Db::init(const std::string &version) { queryFree(INSERT_VERSION_REQUEST_ID); // Create DB - LOG_INFO(_logger, "Create " << dbType().c_str() << " DB"); + LOG_INFO(_logger, "Create " << dbType() << " DB"); if (bool retry = false; !create(retry)) { if (retry) { LOG_WARN(_logger, "Error in Db::create - Retry"); @@ -413,7 +413,7 @@ bool Db::init(const std::string &version) { void Db::startTransaction() { if (!_transaction) { if (!_sqliteDb->startTransaction()) { - LOG_WARN(_logger, "ERROR starting transaction: " << _sqliteDb->error().c_str()); + LOG_WARN(_logger, "ERROR starting transaction: " << _sqliteDb->error()); return; } _transaction = true; diff --git a/src/libcommonserver/log/log.h b/src/libcommonserver/log/log.h index ddb704524..e6e1d8fcb 100644 --- a/src/libcommonserver/log/log.h +++ b/src/libcommonserver/log/log.h @@ -25,14 +25,15 @@ #include #include "libcommon/log/sentry/sentryhandler.h" -#include "libcommon/log/customlogwstream.h" +#include "libcommon/log/customlogstreams.h" +#include "libcommon/utility/types.h" namespace KDC { #ifdef NDEBUG #define LOG_DEBUG(logger, logEvent) \ { \ - std::ostringstream stream; \ + CustomLogStream stream; \ stream << logEvent; \ sentry_value_t crumb = sentry_value_new_breadcrumb(nullptr, stream.str().c_str()); \ sentry_value_set_by_key(crumb, "level", sentry_value_new_string("debug")); \ @@ -52,7 +53,7 @@ namespace KDC { #define LOG_INFO(logger, logEvent) \ { \ - std::ostringstream stream; \ + CustomLogStream stream; \ stream << logEvent; \ sentry_value_t crumb = sentry_value_new_breadcrumb(nullptr, stream.str().c_str()); \ sentry_value_set_by_key(crumb, "level", sentry_value_new_string("info")); \ @@ -72,7 +73,7 @@ namespace KDC { #define LOG_WARN(logger, logEvent) \ { \ - std::ostringstream stream; \ + CustomLogStream stream; \ stream << logEvent; \ sentry_value_t crumb = sentry_value_new_breadcrumb(nullptr, stream.str().c_str()); \ sentry_value_set_by_key(crumb, "level", sentry_value_new_string("warning")); \ @@ -92,7 +93,7 @@ namespace KDC { #define LOG_ERROR(logger, logEvent) \ { \ - std::ostringstream stream; \ + CustomLogStream stream; \ stream << logEvent; \ sentry_value_t crumb = sentry_value_new_breadcrumb(nullptr, stream.str().c_str()); \ sentry_value_set_by_key(crumb, "level", sentry_value_new_string("error")); \ @@ -112,7 +113,7 @@ namespace KDC { #define LOG_FATAL(logger, logEvent) \ { \ - std::ostringstream stream; \ + CustomLogStream stream; \ stream << logEvent; \ sentry_value_t crumb = sentry_value_new_breadcrumb(nullptr, stream.str().c_str()); \ sentry_value_set_by_key(crumb, "level", sentry_value_new_string("fatal")); \ @@ -130,25 +131,76 @@ namespace KDC { } \ LOG4CPLUS_FATAL(logger, logEvent) #else -#define LOG_DEBUG(logger, logEvent) LOG4CPLUS_DEBUG(logger, logEvent) - -#define LOGW_DEBUG(logger, logEvent) LOG4CPLUS_DEBUG(logger, logEvent) - -#define LOG_INFO(logger, logEvent) LOG4CPLUS_INFO(logger, logEvent) - -#define LOGW_INFO(logger, logEvent) LOG4CPLUS_INFO(logger, logEvent) - -#define LOG_WARN(logger, logEvent) LOG4CPLUS_WARN(logger, logEvent) - -#define LOGW_WARN(logger, logEvent) LOG4CPLUS_WARN(logger, logEvent) - -#define LOG_ERROR(logger, logEvent) LOG4CPLUS_ERROR(logger, logEvent) - -#define LOGW_ERROR(logger, logEvent) LOG4CPLUS_ERROR(logger, logEvent) - -#define LOG_FATAL(logger, logEvent) LOG4CPLUS_FATAL(logger, logEvent) +#define LOG_DEBUG(logger, logEvent) \ + { \ + CustomLogStream customLogstream_; \ + customLogstream_ << logEvent; \ + LOG4CPLUS_DEBUG(logger, customLogstream_.str().c_str()); \ + } + +#define LOGW_DEBUG(logger, logEvent) \ + { \ + CustomLogWStream customLogWstream_; \ + customLogWstream_ << logEvent; \ + LOG4CPLUS_DEBUG(logger, customLogWstream_.str().c_str()); \ + } + +#define LOG_INFO(logger, logEvent) \ + { \ + CustomLogStream customLogstream_; \ + customLogstream_ << logEvent; \ + LOG4CPLUS_INFO(logger, customLogstream_.str().c_str()); \ + } + +#define LOGW_INFO(logger, logEvent) \ + { \ + CustomLogWStream customLogWstream_; \ + customLogWstream_ << logEvent; \ + LOG4CPLUS_INFO(logger, customLogWstream_.str().c_str()); \ + } + +#define LOG_WARN(logger, logEvent) \ + { \ + CustomLogStream customLogstream_; \ + customLogstream_ << logEvent; \ + LOG4CPLUS_WARN(logger, customLogstream_.str().c_str()); \ + } + +#define LOGW_WARN(logger, logEvent) \ + { \ + CustomLogWStream customLogWstream_; \ + customLogWstream_ << logEvent; \ + LOG4CPLUS_WARN(logger, customLogWstream_.str().c_str()); \ + } + +#define LOG_ERROR(logger, logEvent) \ + { \ + CustomLogStream customLogstream_; \ + customLogstream_ << logEvent; \ + LOG4CPLUS_ERROR(logger, customLogstream_.str().c_str()); \ + } + +#define LOGW_ERROR(logger, logEvent) \ + { \ + CustomLogWStream customLogWstream_; \ + customLogWstream_ << logEvent; \ + LOG4CPLUS_ERROR(logger, customLogWstream_.str().c_str()); \ + } + +#define LOG_FATAL(logger, logEvent) \ + { \ + CustomLogStream customLogstream_; \ + customLogstream_ << logEvent; \ + LOG4CPLUS_FATAL(logger, customLogstream_.str().c_str()); \ + } + +#define LOGW_FATAL(logger, logEvent) \ + { \ + CustomLogWStream customLogWstream_; \ + customLogWstream_ << logEvent; \ + LOG4CPLUS_FATAL(logger, customLogWstream_.str().c_str()); \ + } -#define LOGW_FATAL(logger, logEvent) LOG4CPLUS_FATAL(logger, logEvent) #endif class COMMONSERVER_EXPORT Log { diff --git a/src/libsyncengine/jobs/network/abstractnetworkjob.cpp b/src/libsyncengine/jobs/network/abstractnetworkjob.cpp index da1243d10..bfc5dfd92 100644 --- a/src/libsyncengine/jobs/network/abstractnetworkjob.cpp +++ b/src/libsyncengine/jobs/network/abstractnetworkjob.cpp @@ -76,7 +76,7 @@ AbstractNetworkJob::AbstractNetworkJob() { LOG_INFO(_logger, "Unknown error in Poco::Net::Context constructor: " << errorText(e).c_str() << ", retrying..."); } else { - LOG_ERROR(_logger, "Unknown error in Poco::Net::Context constructor: " << errorText(e).c_str()); + LOG_ERROR(_logger, "Unknown error in Poco::Net::Context constructor: " << errorText(e)); throw std::runtime_error(ABSTRACTNETWORKJOB_NEW_ERROR_MSG); } } diff --git a/src/libsyncengine/reconciliation/platform_inconsistency_checker/platforminconsistencycheckerworker.cpp b/src/libsyncengine/reconciliation/platform_inconsistency_checker/platforminconsistencycheckerworker.cpp index 1784a70c0..c55f8a867 100644 --- a/src/libsyncengine/reconciliation/platform_inconsistency_checker/platforminconsistencycheckerworker.cpp +++ b/src/libsyncengine/reconciliation/platform_inconsistency_checker/platforminconsistencycheckerworker.cpp @@ -291,9 +291,9 @@ void PlatformInconsistencyCheckerWorker::removeLocalNodeFromDb(std::shared_ptr Date: Fri, 15 Nov 2024 14:31:50 +0100 Subject: [PATCH 138/178] Re-use the custom logger stream string once it is computed --- src/libcommonserver/log/log.h | 238 ++++++++++++++++++---------------- 1 file changed, 124 insertions(+), 114 deletions(-) diff --git a/src/libcommonserver/log/log.h b/src/libcommonserver/log/log.h index e6e1d8fcb..ceab122eb 100644 --- a/src/libcommonserver/log/log.h +++ b/src/libcommonserver/log/log.h @@ -31,111 +31,121 @@ namespace KDC { #ifdef NDEBUG -#define LOG_DEBUG(logger, logEvent) \ - { \ - CustomLogStream stream; \ - stream << logEvent; \ - sentry_value_t crumb = sentry_value_new_breadcrumb(nullptr, stream.str().c_str()); \ - sentry_value_set_by_key(crumb, "level", sentry_value_new_string("debug")); \ - sentry_add_breadcrumb(crumb); \ - } \ - LOG4CPLUS_DEBUG(logger, logEvent) - -#define LOGW_DEBUG(logger, logEvent) \ - { \ - CustomLogWStream stream; \ - stream << logEvent; \ - sentry_value_t crumb = sentry_value_new_breadcrumb(nullptr, Utility::ws2s(stream.str()).c_str()); \ - sentry_value_set_by_key(crumb, "level", sentry_value_new_string("debug")); \ - sentry_add_breadcrumb(crumb); \ - } \ - LOG4CPLUS_DEBUG(logger, logEvent) - -#define LOG_INFO(logger, logEvent) \ - { \ - CustomLogStream stream; \ - stream << logEvent; \ - sentry_value_t crumb = sentry_value_new_breadcrumb(nullptr, stream.str().c_str()); \ - sentry_value_set_by_key(crumb, "level", sentry_value_new_string("info")); \ - sentry_add_breadcrumb(crumb); \ - } \ - LOG4CPLUS_INFO(logger, logEvent) - -#define LOGW_INFO(logger, logEvent) \ - { \ - CustomLogWStream stream; \ - stream << logEvent; \ - sentry_value_t crumb = sentry_value_new_breadcrumb(nullptr, Utility::ws2s(stream.str()).c_str()); \ - sentry_value_set_by_key(crumb, "level", sentry_value_new_string("info")); \ - sentry_add_breadcrumb(crumb); \ - } \ - LOG4CPLUS_INFO(logger, logEvent) - -#define LOG_WARN(logger, logEvent) \ - { \ - CustomLogStream stream; \ - stream << logEvent; \ - sentry_value_t crumb = sentry_value_new_breadcrumb(nullptr, stream.str().c_str()); \ - sentry_value_set_by_key(crumb, "level", sentry_value_new_string("warning")); \ - sentry_add_breadcrumb(crumb); \ - } \ - LOG4CPLUS_WARN(logger, logEvent) - -#define LOGW_WARN(logger, logEvent) \ - { \ - CustomLogWStream stream; \ - stream << logEvent; \ - sentry_value_t crumb = sentry_value_new_breadcrumb(nullptr, Utility::ws2s(stream.str()).c_str()); \ - sentry_value_set_by_key(crumb, "level", sentry_value_new_string("warning")); \ - sentry_add_breadcrumb(crumb); \ - } \ - LOG4CPLUS_WARN(logger, logEvent) - -#define LOG_ERROR(logger, logEvent) \ - { \ - CustomLogStream stream; \ - stream << logEvent; \ - sentry_value_t crumb = sentry_value_new_breadcrumb(nullptr, stream.str().c_str()); \ - sentry_value_set_by_key(crumb, "level", sentry_value_new_string("error")); \ - sentry_add_breadcrumb(crumb); \ - } \ - LOG4CPLUS_ERROR(logger, logEvent) - -#define LOGW_ERROR(logger, logEvent) \ - { \ - CustomLogWStream stream; \ - stream << logEvent; \ - sentry_value_t crumb = sentry_value_new_breadcrumb(nullptr, Utility::ws2s(stream.str()).c_str()); \ - sentry_value_set_by_key(crumb, "level", sentry_value_new_string("error")); \ - sentry_add_breadcrumb(crumb); \ - } \ - LOG4CPLUS_ERROR(logger, logEvent) - -#define LOG_FATAL(logger, logEvent) \ - { \ - CustomLogStream stream; \ - stream << logEvent; \ - sentry_value_t crumb = sentry_value_new_breadcrumb(nullptr, stream.str().c_str()); \ - sentry_value_set_by_key(crumb, "level", sentry_value_new_string("fatal")); \ - sentry_add_breadcrumb(crumb); \ - } \ - LOG4CPLUS_FATAL(logger, logEvent) - -#define LOGW_FATAL(logger, logEvent) \ - { \ - CustomLogWStream stream; \ - stream << logEvent; \ - sentry_value_t crumb = sentry_value_new_breadcrumb(nullptr, Utility::ws2s(stream.str()).c_str()); \ - sentry_value_set_by_key(crumb, "level", sentry_value_new_string("fatal")); \ - sentry_add_breadcrumb(crumb); \ - } \ - LOG4CPLUS_FATAL(logger, logEvent) +#define LOG_DEBUG(logger, logEvent) \ + { \ + CustomLogStream customLogStream_; \ + customLogStream_ << logEvent; \ + const auto &customLogStreamStr_ = customLogStream_.str(); \ + sentry_value_t crumb = sentry_value_new_breadcrumb(nullptr, customLogStreamStr_.c_str())); \ + sentry_value_set_by_key(crumb, "level", sentry_value_new_string("debug")); \ + sentry_add_breadcrumb(crumb); \ + } \ + LOG4CPLUS_DEBUG(logger, customLogStreamStr_.c_str()) + +#define LOGW_DEBUG(logger, logEvent) \ + { \ + CustomLogWStream customLogWStream_; \ + customLogWStream_ << logEvent; \ + const auto &customLogWStreamStr_ = customLogWStream_.str(); \ + sentry_value_t crumb = sentry_value_new_breadcrumb(nullptr, Utility::ws2s(customLogWStreamStr_).c_str()); \ + sentry_value_set_by_key(crumb, "level", sentry_value_new_string("debug")); \ + sentry_add_breadcrumb(crumb); \ + } \ + LOG4CPLUS_DEBUG(logger, customLogWStreamStr_.c_str()) + +#define LOG_INFO(logger, logEvent) \ + { \ + CustomLogStream customLogStream_; \ + customLogStream_ << logEvent; \ + const auto customLogStreamStr_ = customLogStream_.str(); \ + sentry_value_t crumb = sentry_value_new_breadcrumb(nullptr, customLogStreamStr_.c_str()); \ + sentry_value_set_by_key(crumb, "level", sentry_value_new_string("info")); \ + sentry_add_breadcrumb(crumb); \ + } \ + LOG4CPLUS_INFO(logger, customLogStreamStr_.c_str()) + +#define LOGW_INFO(logger, logEvent) \ + { \ + CustomLogWStream customLogWStream_; \ + customLogWStream_ << logEvent; \ + const auto &customLogWStreamStr_ = customLogWStream_.str(); \ + sentry_value_t crumb = sentry_value_new_breadcrumb(nullptr, Utility::ws2s(customLogWStreamStr_).c_str()); \ + sentry_value_set_by_key(crumb, "level", sentry_value_new_string("info")); \ + sentry_add_breadcrumb(crumb); \ + } \ + LOG4CPLUS_INFO(logger, customLogWStreamStr_.c_str()) + +#define LOG_WARN(logger, logEvent) \ + { \ + CustomLogStream customLogStream_; \ + customLogStream_ << logEvent; \ + const auto customLogStreamStr_ = customLogStream_.str(); \ + sentry_value_t crumb = sentry_value_new_breadcrumb(nullptr, customLogStreamStr_.c_str()); \ + sentry_value_set_by_key(crumb, "level", sentry_value_new_string("warning")); \ + sentry_add_breadcrumb(crumb); \ + } \ + LOG4CPLUS_WARN(logger, customLogStreamStr_.c_str()) + +#define LOGW_WARN(logger, logEvent) \ + { \ + CustomLogWStream customLogWStream_; \ + customLogWStream_ << logEvent; \ + const auto &customLogWStreamStr_ = customLogWStream_.str(); \ + sentry_value_t crumb = sentry_value_new_breadcrumb(nullptr, Utility::ws2s(customLogWStreamStr_).c_str()); \ + sentry_value_set_by_key(crumb, "level", sentry_value_new_string("warning")); \ + sentry_add_breadcrumb(crumb); \ + } \ + LOG4CPLUS_WARN(logger, customLogWStreamStr_.c_str()) + +#define LOG_ERROR(logger, logEvent) \ + { \ + CustomLogStream customLogStream_; \ + customLogStream_ << logEvent; \ + const auto customLogStreamStr_ = customLogStream_.str(); \ + sentry_value_t crumb = sentry_value_new_breadcrumb(nullptr, customLogStreamStr_.c_str()); \ + sentry_value_set_by_key(crumb, "level", sentry_value_new_string("error")); \ + sentry_add_breadcrumb(crumb); \ + } \ + LOG4CPLUS_ERROR(logger, customLogStreamStr_.c_str()) + +#define LOGW_ERROR(logger, logEvent) \ + { \ + CustomLogWStream customLogWStream_; \ + customLogWStream_ << logEvent; \ + const auto &customLogWStreamStr_ = customLogWStream_.str(); \ + sentry_value_t crumb = sentry_value_new_breadcrumb(nullptr, Utility::ws2s(customLogWStreamStr_).c_str()); \ + sentry_value_set_by_key(crumb, "level", sentry_value_new_string("error")); \ + sentry_add_breadcrumb(crumb); \ + } \ + LOG4CPLUS_ERROR(logger, customLogWStreamStr_.c_str()) + +#define LOG_FATAL(logger, logEvent) \ + { \ + CustomLogStream customLogStream_; \ + customLogStream_ << logEvent; \ + const auto customLogStreamStr_ = customLogStream_.str(); \ + sentry_value_t crumb = sentry_value_new_breadcrumb(nullptr, customLogStreamStr_.c_str()); \ + sentry_value_set_by_key(crumb, "level", sentry_value_new_string("fatal")); \ + sentry_add_breadcrumb(crumb); \ + } \ + LOG4CPLUS_FATAL(logger, customLogStreamStr_.c_str()) + +#define LOGW_FATAL(logger, logEvent) \ + { \ + CustomLogWStream customLogWStream_; \ + customLogWStream_ << logEvent; \ + const auto &customLogWStreamStr_ = customLogWStream_.str(); \ + sentry_value_t crumb = sentry_value_new_breadcrumb(nullptr, Utility::ws2s(customLogWStreamStr_).c_str()); \ + sentry_value_set_by_key(crumb, "level", sentry_value_new_string("fatal")); \ + sentry_add_breadcrumb(crumb); \ + } +LOG4CPLUS_FATAL(logger, customLogWStreamStr_.c_str()) #else #define LOG_DEBUG(logger, logEvent) \ { \ - CustomLogStream customLogstream_; \ - customLogstream_ << logEvent; \ - LOG4CPLUS_DEBUG(logger, customLogstream_.str().c_str()); \ + CustomLogStream customLogStream_; \ + customLogStream_ << logEvent; \ + LOG4CPLUS_DEBUG(logger, customLogStream_.str().c_str()); \ } #define LOGW_DEBUG(logger, logEvent) \ @@ -147,9 +157,9 @@ namespace KDC { #define LOG_INFO(logger, logEvent) \ { \ - CustomLogStream customLogstream_; \ - customLogstream_ << logEvent; \ - LOG4CPLUS_INFO(logger, customLogstream_.str().c_str()); \ + CustomLogStream customLogStream_; \ + customLogStream_ << logEvent; \ + LOG4CPLUS_INFO(logger, customLogStream_.str().c_str()); \ } #define LOGW_INFO(logger, logEvent) \ @@ -161,9 +171,9 @@ namespace KDC { #define LOG_WARN(logger, logEvent) \ { \ - CustomLogStream customLogstream_; \ - customLogstream_ << logEvent; \ - LOG4CPLUS_WARN(logger, customLogstream_.str().c_str()); \ + CustomLogStream customLogStream_; \ + customLogStream_ << logEvent; \ + LOG4CPLUS_WARN(logger, customLogStream_.str().c_str()); \ } #define LOGW_WARN(logger, logEvent) \ @@ -175,9 +185,9 @@ namespace KDC { #define LOG_ERROR(logger, logEvent) \ { \ - CustomLogStream customLogstream_; \ - customLogstream_ << logEvent; \ - LOG4CPLUS_ERROR(logger, customLogstream_.str().c_str()); \ + CustomLogStream customLogStream_; \ + customLogStream_ << logEvent; \ + LOG4CPLUS_ERROR(logger, customLogStream_.str().c_str()); \ } #define LOGW_ERROR(logger, logEvent) \ @@ -189,9 +199,9 @@ namespace KDC { #define LOG_FATAL(logger, logEvent) \ { \ - CustomLogStream customLogstream_; \ - customLogstream_ << logEvent; \ - LOG4CPLUS_FATAL(logger, customLogstream_.str().c_str()); \ + CustomLogStream customLogStream_; \ + customLogStream_ << logEvent; \ + LOG4CPLUS_FATAL(logger, customLogStream_.str().c_str()); \ } #define LOGW_FATAL(logger, logEvent) \ From 3b9779df73e15f06c4ccd9661e84b458bf15d42d Mon Sep 17 00:00:00 2001 From: Luc Guyot Date: Fri, 15 Nov 2024 14:42:31 +0100 Subject: [PATCH 139/178] Fixes some variables scopes in log macros (build failures) --- src/libcommonserver/log/log.h | 39 ++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/src/libcommonserver/log/log.h b/src/libcommonserver/log/log.h index ceab122eb..81a1773c7 100644 --- a/src/libcommonserver/log/log.h +++ b/src/libcommonserver/log/log.h @@ -39,8 +39,8 @@ namespace KDC { sentry_value_t crumb = sentry_value_new_breadcrumb(nullptr, customLogStreamStr_.c_str())); \ sentry_value_set_by_key(crumb, "level", sentry_value_new_string("debug")); \ sentry_add_breadcrumb(crumb); \ - } \ - LOG4CPLUS_DEBUG(logger, customLogStreamStr_.c_str()) + LOG4CPLUS_DEBUG(logger, customLogStreamStr_.c_str()) \ + } #define LOGW_DEBUG(logger, logEvent) \ { \ @@ -50,8 +50,8 @@ namespace KDC { sentry_value_t crumb = sentry_value_new_breadcrumb(nullptr, Utility::ws2s(customLogWStreamStr_).c_str()); \ sentry_value_set_by_key(crumb, "level", sentry_value_new_string("debug")); \ sentry_add_breadcrumb(crumb); \ - } \ - LOG4CPLUS_DEBUG(logger, customLogWStreamStr_.c_str()) + LOG4CPLUS_DEBUG(logger, customLogWStreamStr_.c_str()) \ + } #define LOG_INFO(logger, logEvent) \ { \ @@ -61,8 +61,8 @@ namespace KDC { sentry_value_t crumb = sentry_value_new_breadcrumb(nullptr, customLogStreamStr_.c_str()); \ sentry_value_set_by_key(crumb, "level", sentry_value_new_string("info")); \ sentry_add_breadcrumb(crumb); \ - } \ - LOG4CPLUS_INFO(logger, customLogStreamStr_.c_str()) + LOG4CPLUS_INFO(logger, customLogStreamStr_.c_str()) \ + } #define LOGW_INFO(logger, logEvent) \ { \ @@ -72,8 +72,8 @@ namespace KDC { sentry_value_t crumb = sentry_value_new_breadcrumb(nullptr, Utility::ws2s(customLogWStreamStr_).c_str()); \ sentry_value_set_by_key(crumb, "level", sentry_value_new_string("info")); \ sentry_add_breadcrumb(crumb); \ - } \ - LOG4CPLUS_INFO(logger, customLogWStreamStr_.c_str()) + LOG4CPLUS_INFO(logger, customLogWStreamStr_.c_str()) \ + } #define LOG_WARN(logger, logEvent) \ { \ @@ -83,8 +83,9 @@ namespace KDC { sentry_value_t crumb = sentry_value_new_breadcrumb(nullptr, customLogStreamStr_.c_str()); \ sentry_value_set_by_key(crumb, "level", sentry_value_new_string("warning")); \ sentry_add_breadcrumb(crumb); \ - } \ - LOG4CPLUS_WARN(logger, customLogStreamStr_.c_str()) + LOG4CPLUS_WARN(logger, customLogStreamStr_.c_str()) \ + } + #define LOGW_WARN(logger, logEvent) \ { \ @@ -94,8 +95,8 @@ namespace KDC { sentry_value_t crumb = sentry_value_new_breadcrumb(nullptr, Utility::ws2s(customLogWStreamStr_).c_str()); \ sentry_value_set_by_key(crumb, "level", sentry_value_new_string("warning")); \ sentry_add_breadcrumb(crumb); \ - } \ - LOG4CPLUS_WARN(logger, customLogWStreamStr_.c_str()) + LOG4CPLUS_WARN(logger, customLogWStreamStr_.c_str()) \ + } #define LOG_ERROR(logger, logEvent) \ { \ @@ -105,8 +106,8 @@ namespace KDC { sentry_value_t crumb = sentry_value_new_breadcrumb(nullptr, customLogStreamStr_.c_str()); \ sentry_value_set_by_key(crumb, "level", sentry_value_new_string("error")); \ sentry_add_breadcrumb(crumb); \ - } \ - LOG4CPLUS_ERROR(logger, customLogStreamStr_.c_str()) + LOG4CPLUS_ERROR(logger, customLogStreamStr_.c_str()) \ + } #define LOGW_ERROR(logger, logEvent) \ { \ @@ -116,8 +117,8 @@ namespace KDC { sentry_value_t crumb = sentry_value_new_breadcrumb(nullptr, Utility::ws2s(customLogWStreamStr_).c_str()); \ sentry_value_set_by_key(crumb, "level", sentry_value_new_string("error")); \ sentry_add_breadcrumb(crumb); \ - } \ - LOG4CPLUS_ERROR(logger, customLogWStreamStr_.c_str()) + LOG4CPLUS_ERROR(logger, customLogWStreamStr_.c_str()) \ + } #define LOG_FATAL(logger, logEvent) \ { \ @@ -127,8 +128,8 @@ namespace KDC { sentry_value_t crumb = sentry_value_new_breadcrumb(nullptr, customLogStreamStr_.c_str()); \ sentry_value_set_by_key(crumb, "level", sentry_value_new_string("fatal")); \ sentry_add_breadcrumb(crumb); \ - } \ - LOG4CPLUS_FATAL(logger, customLogStreamStr_.c_str()) + LOG4CPLUS_FATAL(logger, customLogStreamStr_.c_str()) \ + } #define LOGW_FATAL(logger, logEvent) \ { \ @@ -138,8 +139,8 @@ namespace KDC { sentry_value_t crumb = sentry_value_new_breadcrumb(nullptr, Utility::ws2s(customLogWStreamStr_).c_str()); \ sentry_value_set_by_key(crumb, "level", sentry_value_new_string("fatal")); \ sentry_add_breadcrumb(crumb); \ + LOG4CPLUS_FATAL(logger, customLogWStreamStr_.c_str()) \ } -LOG4CPLUS_FATAL(logger, customLogWStreamStr_.c_str()) #else #define LOG_DEBUG(logger, logEvent) \ { \ From edff61d00776388b573914d256c84c72833d3bfd Mon Sep 17 00:00:00 2001 From: Luc Guyot Date: Fri, 15 Nov 2024 14:47:39 +0100 Subject: [PATCH 140/178] Fixes typo in macros causing build errors --- src/libcommonserver/log/log.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/libcommonserver/log/log.h b/src/libcommonserver/log/log.h index 81a1773c7..a57dcae84 100644 --- a/src/libcommonserver/log/log.h +++ b/src/libcommonserver/log/log.h @@ -31,15 +31,15 @@ namespace KDC { #ifdef NDEBUG -#define LOG_DEBUG(logger, logEvent) \ - { \ - CustomLogStream customLogStream_; \ - customLogStream_ << logEvent; \ - const auto &customLogStreamStr_ = customLogStream_.str(); \ - sentry_value_t crumb = sentry_value_new_breadcrumb(nullptr, customLogStreamStr_.c_str())); \ - sentry_value_set_by_key(crumb, "level", sentry_value_new_string("debug")); \ - sentry_add_breadcrumb(crumb); \ - LOG4CPLUS_DEBUG(logger, customLogStreamStr_.c_str()) \ +#define LOG_DEBUG(logger, logEvent) \ + { \ + CustomLogStream customLogStream_; \ + customLogStream_ << logEvent; \ + const auto &customLogStreamStr_ = customLogStream_.str(); \ + sentry_value_t crumb = sentry_value_new_breadcrumb(nullptr, customLogStreamStr_.c_str()); \ + sentry_value_set_by_key(crumb, "level", sentry_value_new_string("debug")); \ + sentry_add_breadcrumb(crumb); \ + LOG4CPLUS_DEBUG(logger, customLogStreamStr_.c_str()) \ } #define LOGW_DEBUG(logger, logEvent) \ From 2723a2cd9e46ef70592238beeb5180928581a874 Mon Sep 17 00:00:00 2001 From: Luc Guyot Date: Fri, 15 Nov 2024 15:08:36 +0100 Subject: [PATCH 141/178] Adds semicolon after macro to fix build errors caused by macro expansions --- src/libcommonserver/log/log.h | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/libcommonserver/log/log.h b/src/libcommonserver/log/log.h index a57dcae84..cf85f5aee 100644 --- a/src/libcommonserver/log/log.h +++ b/src/libcommonserver/log/log.h @@ -39,7 +39,7 @@ namespace KDC { sentry_value_t crumb = sentry_value_new_breadcrumb(nullptr, customLogStreamStr_.c_str()); \ sentry_value_set_by_key(crumb, "level", sentry_value_new_string("debug")); \ sentry_add_breadcrumb(crumb); \ - LOG4CPLUS_DEBUG(logger, customLogStreamStr_.c_str()) \ + LOG4CPLUS_DEBUG(logger, customLogStreamStr_.c_str()); \ } #define LOGW_DEBUG(logger, logEvent) \ @@ -50,7 +50,7 @@ namespace KDC { sentry_value_t crumb = sentry_value_new_breadcrumb(nullptr, Utility::ws2s(customLogWStreamStr_).c_str()); \ sentry_value_set_by_key(crumb, "level", sentry_value_new_string("debug")); \ sentry_add_breadcrumb(crumb); \ - LOG4CPLUS_DEBUG(logger, customLogWStreamStr_.c_str()) \ + LOG4CPLUS_DEBUG(logger, customLogWStreamStr_.c_str()); \ } #define LOG_INFO(logger, logEvent) \ @@ -61,7 +61,7 @@ namespace KDC { sentry_value_t crumb = sentry_value_new_breadcrumb(nullptr, customLogStreamStr_.c_str()); \ sentry_value_set_by_key(crumb, "level", sentry_value_new_string("info")); \ sentry_add_breadcrumb(crumb); \ - LOG4CPLUS_INFO(logger, customLogStreamStr_.c_str()) \ + LOG4CPLUS_INFO(logger, customLogStreamStr_.c_str()); \ } #define LOGW_INFO(logger, logEvent) \ @@ -72,7 +72,7 @@ namespace KDC { sentry_value_t crumb = sentry_value_new_breadcrumb(nullptr, Utility::ws2s(customLogWStreamStr_).c_str()); \ sentry_value_set_by_key(crumb, "level", sentry_value_new_string("info")); \ sentry_add_breadcrumb(crumb); \ - LOG4CPLUS_INFO(logger, customLogWStreamStr_.c_str()) \ + LOG4CPLUS_INFO(logger, customLogWStreamStr_.c_str()); \ } #define LOG_WARN(logger, logEvent) \ @@ -83,7 +83,7 @@ namespace KDC { sentry_value_t crumb = sentry_value_new_breadcrumb(nullptr, customLogStreamStr_.c_str()); \ sentry_value_set_by_key(crumb, "level", sentry_value_new_string("warning")); \ sentry_add_breadcrumb(crumb); \ - LOG4CPLUS_WARN(logger, customLogStreamStr_.c_str()) \ + LOG4CPLUS_WARN(logger, customLogStreamStr_.c_str()); \ } @@ -95,7 +95,7 @@ namespace KDC { sentry_value_t crumb = sentry_value_new_breadcrumb(nullptr, Utility::ws2s(customLogWStreamStr_).c_str()); \ sentry_value_set_by_key(crumb, "level", sentry_value_new_string("warning")); \ sentry_add_breadcrumb(crumb); \ - LOG4CPLUS_WARN(logger, customLogWStreamStr_.c_str()) \ + LOG4CPLUS_WARN(logger, customLogWStreamStr_.c_str()); \ } #define LOG_ERROR(logger, logEvent) \ @@ -106,7 +106,7 @@ namespace KDC { sentry_value_t crumb = sentry_value_new_breadcrumb(nullptr, customLogStreamStr_.c_str()); \ sentry_value_set_by_key(crumb, "level", sentry_value_new_string("error")); \ sentry_add_breadcrumb(crumb); \ - LOG4CPLUS_ERROR(logger, customLogStreamStr_.c_str()) \ + LOG4CPLUS_ERROR(logger, customLogStreamStr_.c_str()); \ } #define LOGW_ERROR(logger, logEvent) \ @@ -117,7 +117,7 @@ namespace KDC { sentry_value_t crumb = sentry_value_new_breadcrumb(nullptr, Utility::ws2s(customLogWStreamStr_).c_str()); \ sentry_value_set_by_key(crumb, "level", sentry_value_new_string("error")); \ sentry_add_breadcrumb(crumb); \ - LOG4CPLUS_ERROR(logger, customLogWStreamStr_.c_str()) \ + LOG4CPLUS_ERROR(logger, customLogWStreamStr_.c_str()); \ } #define LOG_FATAL(logger, logEvent) \ @@ -128,7 +128,7 @@ namespace KDC { sentry_value_t crumb = sentry_value_new_breadcrumb(nullptr, customLogStreamStr_.c_str()); \ sentry_value_set_by_key(crumb, "level", sentry_value_new_string("fatal")); \ sentry_add_breadcrumb(crumb); \ - LOG4CPLUS_FATAL(logger, customLogStreamStr_.c_str()) \ + LOG4CPLUS_FATAL(logger, customLogStreamStr_.c_str()); \ } #define LOGW_FATAL(logger, logEvent) \ @@ -139,7 +139,7 @@ namespace KDC { sentry_value_t crumb = sentry_value_new_breadcrumb(nullptr, Utility::ws2s(customLogWStreamStr_).c_str()); \ sentry_value_set_by_key(crumb, "level", sentry_value_new_string("fatal")); \ sentry_add_breadcrumb(crumb); \ - LOG4CPLUS_FATAL(logger, customLogWStreamStr_.c_str()) \ + LOG4CPLUS_FATAL(logger, customLogWStreamStr_.c_str()); \ } #else #define LOG_DEBUG(logger, logEvent) \ From 3a1d8dfc137c39a336d70752039529939f4a8b41 Mon Sep 17 00:00:00 2001 From: Luc Guyot Date: Mon, 18 Nov 2024 08:58:31 +0100 Subject: [PATCH 142/178] Fixes unit tests failure --- .../log/customrollingfileappender.cpp | 4 +-- test/libcommonserver/log/testlog.cpp | 34 ++++++++++++------- test/test_utility/testhelpers.cpp | 25 +++++++++++++- test/test_utility/testhelpers.h | 3 ++ 4 files changed, 51 insertions(+), 15 deletions(-) diff --git a/src/libcommonserver/log/customrollingfileappender.cpp b/src/libcommonserver/log/customrollingfileappender.cpp index 573600b1c..73fcd2804 100644 --- a/src/libcommonserver/log/customrollingfileappender.cpp +++ b/src/libcommonserver/log/customrollingfileappender.cpp @@ -303,8 +303,8 @@ void CustomRollingFileAppender::checkForExpiredFiles() { // Delete expired files if (_expire > 0 && entry.path().string().find(APPLICATION_NAME) != std::string::npos) { const auto now = std::chrono::system_clock::now(); - auto lastModified = std::chrono::system_clock::from_time_t(fileStat.modtime); - auto expireDateTime = lastModified + std::chrono::seconds(_expire); + const auto lastModified = std::chrono::system_clock::from_time_t(fileStat.modtime); // Only 1s precision. + const auto expireDateTime = lastModified + std::chrono::seconds(_expire); if (expireDateTime < now) { log4cplus::file_remove(Utility::s2ws(entry.path().string())); continue; diff --git a/test/libcommonserver/log/testlog.cpp b/test/libcommonserver/log/testlog.cpp index aba057cfd..fc65aafe8 100644 --- a/test/libcommonserver/log/testlog.cpp +++ b/test/libcommonserver/log/testlog.cpp @@ -16,16 +16,20 @@ * along with this program. If not, see . */ +#include "test_utility/testhelpers.h" #include "testlog.h" + #include "libcommonserver/log/log.h" #include "libcommonserver/utility/utility.h" #include "libcommonserver/io/iohelper.h" #include "libcommon/utility/utility.h" #include +#include #include + #include -#include +#include using namespace CppUnit; namespace KDC { @@ -41,17 +45,16 @@ void TestLog::testLog() { LOG_WARN(_logger, "Test warn log " << (long unsigned int) 3 << " " << false << " " << std::error_code{}); LOG_ERROR(_logger, "Test error log " << (long long unsigned int) 4 << " " << true); const QIODevice *device = nullptr; - LOG_FATAL(_logger, "Test fatal log" << std::error_code{} << device); - - LOG_DEBUG(_logger, "家屋香袈睷晦"); + LOG_FATAL(_logger, "Test fatal log" << std::error_code{} << " " << device); LOGW_DEBUG(_logger, L"Test debug log " << (int) 1 << L" " << true << L" " << (double) 1.0); LOGW_INFO(_logger, L"Test info log " << (unsigned int) 2 << L" " << false << L" " << (float) 1.0); LOGW_WARN(_logger, L"Test warn log " << (long unsigned int) 3 << L" " << false << L" " << std::error_code{}); LOGW_ERROR(_logger, L"Test error log " << (long long unsigned int) 4 << L" " << true); - LOGW_FATAL(_logger, L"Test fatal log " << std::error_code{} << device << (long unsigned int) 5); + LOGW_FATAL(_logger, L"Test fatal log " << std::error_code{} << L" " << device << L" " << (long unsigned int) 5); - LOGW_DEBUG(_logger, L"家屋香袈睷晦"); + // Wide characters are mandatory in this case as a bare call to LOG4CPLUS_DEBUG fails to print the string below. + LOGW_DEBUG(_logger, L"Test debug log " << L" " << L"家屋香袈睷晦"); CPPUNIT_ASSERT(true); } @@ -66,11 +69,13 @@ void TestLog::testLargeLogRolling(void) { customRollingFileAppender->setMaxFileSize(maxSize); LOG_DEBUG(_logger, "Ensure the log file is created"); + CPPUNIT_ASSERT_GREATER(1, countFilesInDirectory(_logDir)); // Generate a log larger than the max log file size. (log header is 50bytes) const auto testLog = std::string(maxSize, 'a'); LOG_DEBUG(_logger, testLog.c_str()); + CPPUNIT_ASSERT_GREATER(2, countFilesInDirectory(_logDir)); SyncPath rolledFile = _logDir / (Log::instance()->getLogFilePath().filename().string() + ".1.gz"); @@ -90,20 +95,24 @@ void TestLog::testExpiredLogFiles(void) { std::ofstream fakeLogFile(_logDir / APPLICATION_NAME "_fake.log.gz"); fakeLogFile << "Fake old log file" << std::endl; fakeLogFile.close(); - LOG_INFO(_logger, "Test log file expiration"); // Ensure the log file is created + LOG_INFO(_logger, "Test log file expiration"); // Ensure the log file is created. - CPPUNIT_ASSERT_EQUAL(2, countFilesInDirectory(_logDir)); // The current log file and the fake archived log file + CPPUNIT_ASSERT_EQUAL(2, countFilesInDirectory(_logDir)); // The current log file and the fake archived log file. auto *appender = static_cast(_logger.getAppender(Log::rfName).get()); - appender->setExpire(2); // 1 seconds + appender->setExpire(2); // 2 seconds Utility::msleep(1000); appender->checkForExpiredFiles(); - LOG_INFO(_logger, "Test log file expiration"); // Ensure the current log file is not older than 2 seconds - CPPUNIT_ASSERT_EQUAL(2, countFilesInDirectory(_logDir)); // The fake log file should not be deleted (< 2 seconds) + + const auto now = std::chrono::system_clock::now(); + KDC::testhelpers::setModificationDate(Log::instance()->getLogFilePath(), now); + + CPPUNIT_ASSERT_EQUAL(2, countFilesInDirectory(_logDir)); // The fake log file should not be deleted yet (< 2 seconds). Utility::msleep(1000); appender->checkForExpiredFiles(); - CPPUNIT_ASSERT_EQUAL(1, countFilesInDirectory(_logDir)); // The fake log file should be deleted + + CPPUNIT_ASSERT_EQUAL(1, countFilesInDirectory(_logDir)); // The fake log file should be deleted now. appender->setExpire(CommonUtility::logsPurgeRate * 24 * 3600); } @@ -120,6 +129,7 @@ int TestLog::countFilesInDirectory(const SyncPath &directory) const { count++; } CPPUNIT_ASSERT(endOfDirectory); + return count; } diff --git a/test/test_utility/testhelpers.cpp b/test/test_utility/testhelpers.cpp index b47dbc4c8..228ac5ae7 100644 --- a/test/test_utility/testhelpers.cpp +++ b/test/test_utility/testhelpers.cpp @@ -15,11 +15,20 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -#include + #include "testhelpers.h" #include "libcommon/utility/utility.h" +#include +#include +#include + + +#if defined(__APPLE__) || defined(__unix__) +#include +#endif + namespace KDC::testhelpers { SyncName makeNfdSyncName() { @@ -52,4 +61,18 @@ std::string loadEnvVariable(const std::string& key) { return val; } +void setModificationDate(const SyncPath& path, const std::chrono::time_point& timePoint) { + struct stat fileStat; + struct utimbuf new_times; + + const auto fileNameStr = path.string(); + const auto fileName = fileNameStr.c_str(); + + stat(fileName, &fileStat); + + const std::time_t timeInSeconds = std::chrono::system_clock::to_time_t(timePoint); + new_times.modtime = timeInSeconds; + utime(fileName, &new_times); +} + } // namespace KDC::testhelpers diff --git a/test/test_utility/testhelpers.h b/test/test_utility/testhelpers.h index 4ea30f93d..24debe4cf 100644 --- a/test/test_utility/testhelpers.h +++ b/test/test_utility/testhelpers.h @@ -25,6 +25,8 @@ #include +#include + namespace KDC::testhelpers { const SyncPath localTestDirPath(KDC::Utility::s2ws(TEST_DIR) + L"/test_ci"); @@ -54,5 +56,6 @@ struct TestVariables { }; void generateOrEditTestFile(const SyncPath &path); +void setModificationDate(const SyncPath &path, const std::chrono::time_point &timePoint); } // namespace KDC::testhelpers From 76a08dd41147327fd209f4ca0e44fe07d8aa202c Mon Sep 17 00:00:00 2001 From: Luc Guyot Date: Mon, 18 Nov 2024 09:01:33 +0100 Subject: [PATCH 143/178] Fixes doc string as suggested by Sonar Cloud --- src/libcommon/log/customlogstreams.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/libcommon/log/customlogstreams.h b/src/libcommon/log/customlogstreams.h index aa52a8300..8a273b6dc 100644 --- a/src/libcommon/log/customlogstreams.h +++ b/src/libcommon/log/customlogstreams.h @@ -16,6 +16,7 @@ * along with this program. If not, see . */ #pragma once +#include #include #include @@ -28,8 +29,8 @@ class CustomLogStream : private std::stringstream { std::string str() const { return std::basic_stringstream::str(); } - // We need to cast to std::stringstream as operators<<(std::stringstream, const wchar_t *str /*and const std::wstring - // &str*/) are defined outside of the class std::stringstream and therefore it is not applicable to the current object + // We need to cast to std::stringstream as operators<<(std::stringstream, const wchar_t *str) and const std::string + // &str) are defined outside of the class std::stringstream and therefore it is not applicable to the current object // because of the private inheritance CustomLogStream &operator<<(const char *str) { static_cast(*this) << str; @@ -91,8 +92,8 @@ class CustomLogWStream : private std::wstringstream { std::wstring str() const { return std::basic_stringstream::str(); } - // We need to cast to std::wstringstream as operators<<(std::wstringstream, const wchar_t *str /*and const std::wstring - // &str*/) are defined outside of the class std::wstringstream and therefore it is not applicable to the current object + // We need to cast to std::wstringstream as operators<<(std::wstringstream, const wchar_t *str and const std::wstring + // &str) are defined outside of the class std::wstringstream and therefore it is not applicable to the current object // because of the private inheritance CustomLogWStream &operator<<(const wchar_t *str) { static_cast(*this) << str; From 2f3a66465457e487729e5a5d21b55c6972dc27e8 Mon Sep 17 00:00:00 2001 From: Luc Guyot Date: Mon, 18 Nov 2024 10:54:19 +0100 Subject: [PATCH 144/178] Define testhelpers::setModificationDate for Windows --- test/test_utility/testhelpers.cpp | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/test/test_utility/testhelpers.cpp b/test/test_utility/testhelpers.cpp index 228ac5ae7..e47539501 100644 --- a/test/test_utility/testhelpers.cpp +++ b/test/test_utility/testhelpers.cpp @@ -20,12 +20,12 @@ #include "libcommon/utility/utility.h" -#include #include #include - -#if defined(__APPLE__) || defined(__unix__) +#ifdef _WIN32 +#include "libcommonserver/io/iohelper.h" +#else #include #endif @@ -60,10 +60,23 @@ std::string loadEnvVariable(const std::string& key) { } return val; } +#ifdef _WIN32 +void setModificationDate(const SyncPath& path, const std::chrono::time_point& timePoint) { + struct _utimebuf timeBuffer; + const std::time_t timeInSeconds = std::chrono::system_clock::to_time_t(timePoint); + + IoError ioError = IoError::Success; + FileStat fileStat; + IoHelper::getFileStat(path, &fileStat, ioError); + timeBuffer.tma = fileStat.creationTime; + timeBuffer.tmm = timeInSeconds; + _utime(path.c_str(), &timeBuffer); +} +#else void setModificationDate(const SyncPath& path, const std::chrono::time_point& timePoint) { struct stat fileStat; - struct utimbuf new_times; + struct utimbuf newTime; const auto fileNameStr = path.string(); const auto fileName = fileNameStr.c_str(); @@ -71,8 +84,8 @@ void setModificationDate(const SyncPath& path, const std::chrono::time_point Date: Mon, 18 Nov 2024 11:15:23 +0100 Subject: [PATCH 145/178] Fixes header file inclusion causing build error on Windows --- test/server/socketapi/testsocketapi.cpp | 51 +++++++++++++++++++++++++ test/server/socketapi/testsocketapi.h | 39 +++++++++++++++++++ test/test_utility/testhelpers.cpp | 2 +- 3 files changed, 91 insertions(+), 1 deletion(-) create mode 100644 test/server/socketapi/testsocketapi.cpp create mode 100644 test/server/socketapi/testsocketapi.h diff --git a/test/server/socketapi/testsocketapi.cpp b/test/server/socketapi/testsocketapi.cpp new file mode 100644 index 000000000..87385ad46 --- /dev/null +++ b/test/server/socketapi/testsocketapi.cpp @@ -0,0 +1,51 @@ +/* + * Infomaniak kDrive - Desktop + * Copyright (C) 2023-2024 Infomaniak Network SA + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "socketapi.h" +#include "testsocketapi.h" + +#include +#include + +#ifdef _WIN32 +#include +#endif + +namespace KDC { + + +void TestSocketApi::setUp() {} + +void TestSocketApi::tearDown() {} + +void TestSocketApi::testFileData() { + FileData fileData; + QString localPath = QString("/Users/hyphensmbp/kDrive Labör/Common documents/"); + + QByteArray b1 = localPath.toLatin1(); + CPPUNIT_ASSERT(QString(b1) == localPath); + + // QString parentPath = QFileInfo(localPath).dir().path().toUtf8(); + + // CPPUNIT_ASSERT(QString("/Users/hyphensmbp/kDrive Labör").toStdString() == parentPath.toStdString()); + + // std::filesystem::path localPath_ = QStr2Path(parentPath); + + // CPPUNIT_ASSERT(localPath_ == SyncPath(QString("/Users/hyphensmbp/kDrive Labör").toStdString())); +} +} // namespace KDC diff --git a/test/server/socketapi/testsocketapi.h b/test/server/socketapi/testsocketapi.h new file mode 100644 index 000000000..5021a4915 --- /dev/null +++ b/test/server/socketapi/testsocketapi.h @@ -0,0 +1,39 @@ +/* + * Infomaniak kDrive - Desktop + * Copyright (C) 2023-2024 Infomaniak Network SA + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "testincludes.h" + + +namespace KDC { + +class TestSocketApi : public CppUnit::TestFixture { + CPPUNIT_TEST_SUITE(TestSocketApi); + CPPUNIT_TEST(testFileData); + CPPUNIT_TEST_SUITE_END(); + + public: + void setUp(void) final; + void tearDown() override; + void testCreatePlaceholder(); + void testConvertToPlaceholder(); + + protected: + void testFileData(); +}; + +} // namespace KDC diff --git a/test/test_utility/testhelpers.cpp b/test/test_utility/testhelpers.cpp index e47539501..ce95210ef 100644 --- a/test/test_utility/testhelpers.cpp +++ b/test/test_utility/testhelpers.cpp @@ -20,13 +20,13 @@ #include "libcommon/utility/utility.h" -#include #include #ifdef _WIN32 #include "libcommonserver/io/iohelper.h" #else #include +#include #endif namespace KDC::testhelpers { From 2a4344ddb8508d1ceb2d085405c428c3398bda00 Mon Sep 17 00:00:00 2001 From: Luc Guyot Date: Mon, 18 Nov 2024 13:51:01 +0100 Subject: [PATCH 146/178] Adds missing include statements for Windows --- test/test_utility/testhelpers.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/test_utility/testhelpers.cpp b/test/test_utility/testhelpers.cpp index ce95210ef..f2dd5d433 100644 --- a/test/test_utility/testhelpers.cpp +++ b/test/test_utility/testhelpers.cpp @@ -24,6 +24,8 @@ #ifdef _WIN32 #include "libcommonserver/io/iohelper.h" +#include +#include #else #include #include From 00cdcabbc5b59c2fd7365c145c7895f85b559256 Mon Sep 17 00:00:00 2001 From: Luc Guyot Date: Mon, 18 Nov 2024 16:35:41 +0100 Subject: [PATCH 147/178] Fixes typo in Windows struct name --- test/test_utility/testhelpers.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/test_utility/testhelpers.cpp b/test/test_utility/testhelpers.cpp index f2dd5d433..e49264437 100644 --- a/test/test_utility/testhelpers.cpp +++ b/test/test_utility/testhelpers.cpp @@ -22,6 +22,7 @@ #include + #ifdef _WIN32 #include "libcommonserver/io/iohelper.h" #include @@ -64,12 +65,12 @@ std::string loadEnvVariable(const std::string& key) { } #ifdef _WIN32 void setModificationDate(const SyncPath& path, const std::chrono::time_point& timePoint) { - struct _utimebuf timeBuffer; + struct _utimbuf timeBuffer; const std::time_t timeInSeconds = std::chrono::system_clock::to_time_t(timePoint); IoError ioError = IoError::Success; FileStat fileStat; - IoHelper::getFileStat(path, &fileStat, ioError); + ::KDC::IoHelper::getFileStat(path, &fileStat, ioError); timeBuffer.tma = fileStat.creationTime; timeBuffer.tmm = timeInSeconds; From 9f5de8a3e849fb3d366fe9c7265b6b07dcde68c0 Mon Sep 17 00:00:00 2001 From: Luc Guyot Date: Mon, 18 Nov 2024 16:56:21 +0100 Subject: [PATCH 148/178] Include missing header and use correct data members of _utimbuf on Windows --- src/libcommonserver/io/iohelper.cpp | 1 - test/test_utility/testhelpers.cpp | 7 ++++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libcommonserver/io/iohelper.cpp b/src/libcommonserver/io/iohelper.cpp index 821d8b8e8..761d98098 100644 --- a/src/libcommonserver/io/iohelper.cpp +++ b/src/libcommonserver/io/iohelper.cpp @@ -19,7 +19,6 @@ #include "libcommonserver/io/filestat.h" #include "libcommonserver/io/iohelper.h" #include "libcommonserver/utility/utility.h" // Path2WStr -#include "libcommon/utility/utility.h" #include "config.h" // APPLICATION diff --git a/test/test_utility/testhelpers.cpp b/test/test_utility/testhelpers.cpp index e49264437..e7541bc5c 100644 --- a/test/test_utility/testhelpers.cpp +++ b/test/test_utility/testhelpers.cpp @@ -24,6 +24,7 @@ #ifdef _WIN32 +#include "libcommonserver/io/filestat.h" #include "libcommonserver/io/iohelper.h" #include #include @@ -72,9 +73,9 @@ void setModificationDate(const SyncPath& path, const std::chrono::time_point& timePoint) { From 8f62c04fdf1949e621851221155030aa956a74c0 Mon Sep 17 00:00:00 2001 From: Luc Guyot Date: Thu, 21 Nov 2024 16:46:46 +0100 Subject: [PATCH 149/178] Fixes error introduced while rebasing wrt develop --- src/libcommon/utility/types.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libcommon/utility/types.h b/src/libcommon/utility/types.h index d9f151991..4541a3dd7 100644 --- a/src/libcommon/utility/types.h +++ b/src/libcommon/utility/types.h @@ -615,11 +615,11 @@ inline CustomLogWStream &operator<<(CustomLogWStream &os, C e) { } template - inline CustomLogStream &operator<<(CustomLogStream &os, C e) { - return os << toStringWithCode(e); +inline CustomLogStream &operator<<(CustomLogStream &os, C e) { + return os << toStringWithCode(e); } -template +template inline QDebug &operator<<(QDebug &os, C e) { return os << toStringWithCode(e).c_str(); } From 07de4e8f76937c5b5a574e537931d9c3664e8619 Mon Sep 17 00:00:00 2001 From: Luc Guyot Date: Fri, 22 Nov 2024 09:57:56 +0100 Subject: [PATCH 150/178] Addresses one of the comment of Sonar Cloud: uses the Hidden Friend Pattern --- src/libcommon/log/customlogstreams.h | 13 +++++++++++++ src/libcommon/utility/types.h | 11 ----------- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/libcommon/log/customlogstreams.h b/src/libcommon/log/customlogstreams.h index 8a273b6dc..37b635f0f 100644 --- a/src/libcommon/log/customlogstreams.h +++ b/src/libcommon/log/customlogstreams.h @@ -21,6 +21,8 @@ #include +#include "libcommon/utility/types.h" + class CustomLogStream : private std::stringstream { public: CustomLogStream() = default; @@ -29,6 +31,12 @@ class CustomLogStream : private std::stringstream { std::string str() const { return std::basic_stringstream::str(); } + template + friend inline CustomLogStream &operator<<(CustomLogStream &os, C e) { + return os << KDC::toStringWithCode(e); + } + + // We need to cast to std::stringstream as operators<<(std::stringstream, const wchar_t *str) and const std::string // &str) are defined outside of the class std::stringstream and therefore it is not applicable to the current object // because of the private inheritance @@ -92,6 +100,11 @@ class CustomLogWStream : private std::wstringstream { std::wstring str() const { return std::basic_stringstream::str(); } + template + friend inline CustomLogWStream &operator<<(CustomLogWStream &os, C e) { + return os << KDC::typesUtility::stringToWideString(toStringWithCode(e)); + } + // We need to cast to std::wstringstream as operators<<(std::wstringstream, const wchar_t *str and const std::wstring // &str) are defined outside of the class std::wstringstream and therefore it is not applicable to the current object // because of the private inheritance diff --git a/src/libcommon/utility/types.h b/src/libcommon/utility/types.h index 4541a3dd7..fa44c321d 100644 --- a/src/libcommon/utility/types.h +++ b/src/libcommon/utility/types.h @@ -28,7 +28,6 @@ #include #include #include -#include "libcommon/log/customlogstreams.h" namespace KDC { @@ -609,16 +608,6 @@ inline std::ostream &operator<<(std::ostream &os, C e) { return os << toStringWithCode(e); } -template -inline CustomLogWStream &operator<<(CustomLogWStream &os, C e) { - return os << typesUtility::stringToWideString(toStringWithCode(e)); -} - -template -inline CustomLogStream &operator<<(CustomLogStream &os, C e) { - return os << toStringWithCode(e); -} - template inline QDebug &operator<<(QDebug &os, C e) { return os << toStringWithCode(e).c_str(); From 5e6c5aec09eb0987b3d6ddda4a53a41572d6da0c Mon Sep 17 00:00:00 2001 From: Luc Guyot Date: Wed, 27 Nov 2024 08:51:24 +0100 Subject: [PATCH 151/178] Removes irrelevent unit test files comitted accidentally (Clement CR comment) --- test/server/socketapi/testsocketapi.cpp | 51 ------------------------- test/server/socketapi/testsocketapi.h | 39 ------------------- 2 files changed, 90 deletions(-) delete mode 100644 test/server/socketapi/testsocketapi.cpp delete mode 100644 test/server/socketapi/testsocketapi.h diff --git a/test/server/socketapi/testsocketapi.cpp b/test/server/socketapi/testsocketapi.cpp deleted file mode 100644 index 87385ad46..000000000 --- a/test/server/socketapi/testsocketapi.cpp +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Infomaniak kDrive - Desktop - * Copyright (C) 2023-2024 Infomaniak Network SA - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "socketapi.h" -#include "testsocketapi.h" - -#include -#include - -#ifdef _WIN32 -#include -#endif - -namespace KDC { - - -void TestSocketApi::setUp() {} - -void TestSocketApi::tearDown() {} - -void TestSocketApi::testFileData() { - FileData fileData; - QString localPath = QString("/Users/hyphensmbp/kDrive Labör/Common documents/"); - - QByteArray b1 = localPath.toLatin1(); - CPPUNIT_ASSERT(QString(b1) == localPath); - - // QString parentPath = QFileInfo(localPath).dir().path().toUtf8(); - - // CPPUNIT_ASSERT(QString("/Users/hyphensmbp/kDrive Labör").toStdString() == parentPath.toStdString()); - - // std::filesystem::path localPath_ = QStr2Path(parentPath); - - // CPPUNIT_ASSERT(localPath_ == SyncPath(QString("/Users/hyphensmbp/kDrive Labör").toStdString())); -} -} // namespace KDC diff --git a/test/server/socketapi/testsocketapi.h b/test/server/socketapi/testsocketapi.h deleted file mode 100644 index 5021a4915..000000000 --- a/test/server/socketapi/testsocketapi.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Infomaniak kDrive - Desktop - * Copyright (C) 2023-2024 Infomaniak Network SA - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "testincludes.h" - - -namespace KDC { - -class TestSocketApi : public CppUnit::TestFixture { - CPPUNIT_TEST_SUITE(TestSocketApi); - CPPUNIT_TEST(testFileData); - CPPUNIT_TEST_SUITE_END(); - - public: - void setUp(void) final; - void tearDown() override; - void testCreatePlaceholder(); - void testConvertToPlaceholder(); - - protected: - void testFileData(); -}; - -} // namespace KDC From 1095c5c2090eaeac44082dc96dc60b0c98aa71cb Mon Sep 17 00:00:00 2001 From: Herve Eruam Date: Wed, 27 Nov 2024 15:20:17 +0100 Subject: [PATCH 152/178] Enhance FileAccessError on a parent detection. --- src/libsyncengine/syncpal/syncpal.cpp | 41 ++++++++++++++++++--------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/src/libsyncengine/syncpal/syncpal.cpp b/src/libsyncengine/syncpal/syncpal.cpp index 8c8ac86a2..7e6df0a57 100644 --- a/src/libsyncengine/syncpal/syncpal.cpp +++ b/src/libsyncengine/syncpal/syncpal.cpp @@ -48,6 +48,7 @@ #include "jobs/jobmanager.h" #include "libcommon/utility/utility.h" #include "libcommonserver/utility/utility.h" +#include "libcommonserver/io/iohelper.h" #include "tmpblacklistmanager.h" #define SYNCPAL_NEW_ERROR_MSG "Failed to create SyncPal instance!" @@ -1459,33 +1460,45 @@ ExitInfo SyncPal::handleAccessDeniedItem(const SyncPath &relativePath, ExitCause NodeId localNodeId; if (localNodeId = snapshot(ReplicaSide::Local)->itemId(relativePath); localNodeId.empty()) { - // The file does not exit yet on local file system, or we do not have sufficient right on a parent folder. - LOGW_DEBUG(_logger, L"Item " << Utility::formatSyncPath(relativePath) - << L"is not present local file system, blacklisting the parent item."); - return handleAccessDeniedItem(relativePath.parent_path(), cause); + SyncPath absolutePath = localPath() / relativePath; + if (!IoHelper::getNodeId(absolutePath, localNodeId)) { + bool exists = false; + IoError ioError = IoError::Success; + if (!IoHelper::checkIfPathExists(absolutePath, exists, ioError)) { + LOGW_WARN(_logger, L"IoHelper::checkIfPathExists failed with: " << Utility::formatIoError(absolutePath, ioError)); + return ExitCode::SystemError; + } + if (ioError == IoError::AccessDenied) { // A parent of the file does not have sufficient right + LOGW_DEBUG(_logger, L"A parent of " << Utility::formatSyncPath(relativePath) + << L"does not have sufficient right, blacklisting the parent item."); + return handleAccessDeniedItem(relativePath.parent_path(), cause); + } + } } LOGW_SYNCPAL_DEBUG(_logger, L"Item " << Utility::formatSyncPath(relativePath) << L" (NodeId: " << Utility::s2ws(localNodeId) << L" is blacklisted temporarily because of a denied access."); - NodeId correspondingNodeId; - correspondingNodeId = snapshot(ReplicaSide::Remote)->itemId(relativePath); - if (bool found; correspondingNodeId.empty() && - !_syncDb->correspondingNodeId(ReplicaSide::Local, localNodeId, correspondingNodeId, found)) { + NodeId remoteNodeId; + remoteNodeId = snapshot(ReplicaSide::Remote)->itemId(relativePath); + if (bool found; remoteNodeId.empty() && !localNodeId.empty() && + !_syncDb->correspondingNodeId(ReplicaSide::Local, localNodeId, remoteNodeId, found)) { LOG_SYNCPAL_WARN(_logger, "Error in SyncDb::correspondingNodeId"); return {ExitCode::DbError, ExitCause::Unknown}; } // Blacklist the item - _tmpBlacklistManager->blacklistItem(localNodeId, relativePath, ReplicaSide::Local); - if (!updateTree(ReplicaSide::Local)->deleteNode(localNodeId)) { - LOGW_SYNCPAL_WARN(_logger, L"Error in UpdateTree::deleteNode: " << Utility::formatSyncPath(relativePath)); + if (!localNodeId.empty()) { + _tmpBlacklistManager->blacklistItem(localNodeId, relativePath, ReplicaSide::Local); + if (!updateTree(ReplicaSide::Local)->deleteNode(localNodeId)) { + LOGW_SYNCPAL_WARN(_logger, L"Error in UpdateTree::deleteNode: " << Utility::formatSyncPath(relativePath)); + } } - if (!correspondingNodeId.empty()) { - _tmpBlacklistManager->blacklistItem(correspondingNodeId, relativePath, ReplicaSide::Remote); - if (!updateTree(ReplicaSide::Remote)->deleteNode(correspondingNodeId)) { + if (!remoteNodeId.empty()) { + _tmpBlacklistManager->blacklistItem(remoteNodeId, relativePath, ReplicaSide::Remote); + if (!updateTree(ReplicaSide::Remote)->deleteNode(remoteNodeId)) { LOGW_SYNCPAL_WARN(_logger, L"Error in UpdateTree::deleteNode: " << Utility::formatSyncPath(relativePath)); } } From 9242242bb71fd7f837ece808427c0eb9fd71d060 Mon Sep 17 00:00:00 2001 From: Christophe Larchier Date: Thu, 28 Nov 2024 08:53:31 +0100 Subject: [PATCH 153/178] Address comment --- src/gui/CMakeLists.txt | 1 - src/gui/abstractfileitemwidget.cpp | 1 + src/gui/synchronizeditemwidget.cpp | 1 + src/gui/versionwidget.cpp | 1 + src/libcommon/CMakeLists.txt | 2 ++ src/libcommon/utility/utility.h | 28 +++++++++++++++++-- src/libcommongui/CMakeLists.txt | 1 + src/libcommongui/commclient.cpp | 2 +- src/libcommongui/commclient.h | 4 +-- src/libcommongui/utility/utility.cpp | 5 ++-- src/libcommongui/utility/utility.h | 1 - src/libcommonserver/CMakeLists.txt | 5 ---- src/libcommonserver/commserver.cpp | 5 +--- src/libcommonserver/commserver.h | 3 +- src/libcommonserver/utility/utility.cpp | 5 ---- src/libcommonserver/utility/utility.h | 8 ------ src/libsyncengine/jobs/jobmanager.cpp | 4 +-- src/libsyncengine/jobs/jobmanager.h | 3 +- .../performancewatcher.cpp | 4 +-- .../performance_watcher/performancewatcher.h | 3 +- src/libsyncengine/requests/serverrequests.cpp | 14 +++++----- src/libsyncengine/syncpal/isyncworker.cpp | 4 +-- src/libsyncengine/syncpal/isyncworker.h | 3 +- src/libsyncengine/syncpal/syncpalworker.h | 2 +- .../checksum/contentchecksumworker.h | 2 +- .../computefsoperationworker.h | 2 +- .../filesystemobserverworker.h | 3 +- .../file_system_observer/folderwatcher.cpp | 6 ++-- .../file_system_observer/folderwatcher.h | 3 +- .../folderwatcher_mac.cpp | 1 - .../localfilesystemobserverworker_unix.cpp | 5 ---- .../localfilesystemobserverworker_unix.h | 1 - src/server/appserver.cpp | 4 +-- src/server/vfs/mac/vfs_mac.cpp | 3 +- src/server/vfs/mac/vfs_mac.h | 4 +-- 35 files changed, 71 insertions(+), 73 deletions(-) diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index f730082ad..dd03ddc08 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -261,7 +261,6 @@ target_link_libraries(${APPLICATION_CLIENT_EXECUTABLE} Qt6::Network Qt6::Sql Qt6::SvgWidgets Qt6::WebEngineWidgets sentry::sentry Poco::Foundation Poco::Net - ${libcommon_NAME} ${libcommongui_NAME}) ## handle DBUS for Fdo notifications diff --git a/src/gui/abstractfileitemwidget.cpp b/src/gui/abstractfileitemwidget.cpp index 04c317bea..a2e5d24c3 100644 --- a/src/gui/abstractfileitemwidget.cpp +++ b/src/gui/abstractfileitemwidget.cpp @@ -19,6 +19,7 @@ #include "abstractfileitemwidget.h" #include "gui/custommessagebox.h" #include "guiutility.h" +#include "libcommon/utility/utility.h" #include #include diff --git a/src/gui/synchronizeditemwidget.cpp b/src/gui/synchronizeditemwidget.cpp index 8de6bc3cd..bd94be606 100644 --- a/src/gui/synchronizeditemwidget.cpp +++ b/src/gui/synchronizeditemwidget.cpp @@ -23,6 +23,7 @@ #include "languagechangefilter.h" #include "utility/utility.h" #include "parameterscache.h" +#include "libcommon/utility/utility.h" #include #include diff --git a/src/gui/versionwidget.cpp b/src/gui/versionwidget.cpp index eb50ee14f..8d8049fb8 100644 --- a/src/gui/versionwidget.cpp +++ b/src/gui/versionwidget.cpp @@ -26,6 +26,7 @@ #include "preferencesblocwidget.h" #include "utility/utility.h" #include "utility/widgetsignalblocker.h" +#include "libcommon/utility/utility.h" #include #include diff --git a/src/libcommon/CMakeLists.txt b/src/libcommon/CMakeLists.txt index b34462f1b..accd297bd 100644 --- a/src/libcommon/CMakeLists.txt +++ b/src/libcommon/CMakeLists.txt @@ -2,6 +2,7 @@ project(libcommon) find_package(Qt6 REQUIRED COMPONENTS Network Widgets Gui Sql) find_package(Poco 1.13.3 REQUIRED Foundation JSON Util) +find_package(log4cplus 2.1.0 REQUIRED) find_package(sentry REQUIRED) if (UNIX AND CMAKE_BUILD_TYPE MATCHES "RelWithDebInfo") @@ -83,6 +84,7 @@ endif() target_link_libraries(${libcommon_NAME} Qt6::Core Qt6::Gui Qt6::Widgets Qt6::Network Qt6::Sql Poco::Foundation Poco::JSON Poco::Util + log4cplus::log4cplusU sentry::sentry keychain libzip::zip diff --git a/src/libcommon/utility/utility.h b/src/libcommon/utility/utility.h index e2768cb57..5e45f8c85 100644 --- a/src/libcommon/utility/utility.h +++ b/src/libcommon/utility/utility.h @@ -23,15 +23,19 @@ #include "libcommon/info/nodeinfo.h" #include +#include + +#ifdef _WIN32 +#include +#endif #include #include #include #include +#include -#ifdef _WIN32 -#include -#endif +#include namespace KDC { struct COMMON_EXPORT CommonUtility { @@ -122,6 +126,24 @@ struct COMMON_EXPORT CommonUtility { static void extractIntFromStrVersion(const std::string &version, std::vector &tabVersion); }; +struct COMMON_EXPORT StdLoggingThread : public std::thread { + template + explicit StdLoggingThread(void (*runFct)(Args...), Args &&...args) : + std::thread( + [=]() { + runFct(args...); + log4cplus::threadCleanup(); + }, + args...) {} +}; + +struct COMMON_EXPORT QtLoggingThread : public QThread { + void run() override { + QThread::run(); + log4cplus::threadCleanup(); + } +}; + struct ArgsReader { template explicit ArgsReader(Args... args) : stream(¶ms, QIODevice::WriteOnly) { diff --git a/src/libcommongui/CMakeLists.txt b/src/libcommongui/CMakeLists.txt index 3230583ed..ab51cdc9e 100644 --- a/src/libcommongui/CMakeLists.txt +++ b/src/libcommongui/CMakeLists.txt @@ -25,5 +25,6 @@ set_target_properties(${libcommongui_NAME} PROPERTIES ) target_link_libraries(${libcommongui_NAME} + ${libcommon_NAME} Qt6::Core ) diff --git a/src/libcommongui/commclient.cpp b/src/libcommongui/commclient.cpp index d221834e1..e3fc6b543 100644 --- a/src/libcommongui/commclient.cpp +++ b/src/libcommongui/commclient.cpp @@ -47,7 +47,7 @@ std::shared_ptr CommClient::instance(QObject *parent) { } CommClient::CommClient(QObject *parent) : - QObject(parent), _requestWorkerThread(new QThread()), _requestWorker(new Worker()), _tcpConnection(new QTcpSocket()), + QObject(parent), _requestWorkerThread(new QtLoggingThread()), _requestWorker(new Worker()), _tcpConnection(new QTcpSocket()), _buffer(QByteArray()) { // Start worker thread _requestWorker->moveToThread(_requestWorkerThread); diff --git a/src/libcommongui/commclient.h b/src/libcommongui/commclient.h index 98c0fbebe..b935f26e4 100644 --- a/src/libcommongui/commclient.h +++ b/src/libcommongui/commclient.h @@ -19,6 +19,7 @@ #pragma once #include "libcommon/comm.h" +#include "libcommon/utility/utility.h" #include @@ -29,7 +30,6 @@ #include #include #include -#include #include namespace KDC { @@ -61,7 +61,7 @@ class CommClient : public QObject { private: static std::shared_ptr _instance; - QThread *_requestWorkerThread; + QtLoggingThread *_requestWorkerThread; Worker *_requestWorker; QTcpSocket *_tcpConnection; QByteArray _buffer; diff --git a/src/libcommongui/utility/utility.cpp b/src/libcommongui/utility/utility.cpp index 17b3990b3..00ac15fd7 100644 --- a/src/libcommongui/utility/utility.cpp +++ b/src/libcommongui/utility/utility.cpp @@ -18,8 +18,6 @@ #include "utility.h" -#include - #if defined(Q_OS_WIN) #include "utility_win.cpp" #elif defined(Q_OS_MAC) @@ -28,6 +26,9 @@ #include "utility_linux.cpp" #endif +#include +#include + namespace KDC { struct Period { const char *name; diff --git a/src/libcommongui/utility/utility.h b/src/libcommongui/utility/utility.h index 139d4306c..c7a20986d 100644 --- a/src/libcommongui/utility/utility.h +++ b/src/libcommongui/utility/utility.h @@ -23,7 +23,6 @@ #include "libcommon/info/nodeinfo.h" #include -#include #include static const QString dirSeparator = "/"; diff --git a/src/libcommonserver/CMakeLists.txt b/src/libcommonserver/CMakeLists.txt index b9db404e9..2ffa385b4 100644 --- a/src/libcommonserver/CMakeLists.txt +++ b/src/libcommonserver/CMakeLists.txt @@ -3,7 +3,6 @@ project(libcommonserver) find_package(SQLite3 3.8.0 REQUIRED) find_package(Poco 1.13.3 REQUIRED Foundation Net JSON Util) find_package(OpenSSL 3.1.0 REQUIRED SSL Crypto) -find_package(log4cplus 2.1.0 REQUIRED) find_package(xxHash 0.8.2 REQUIRED) if (UNIX AND CMAKE_BUILD_TYPE MATCHES "RelWithDebInfo") @@ -73,7 +72,6 @@ if (WIN32) target_include_directories(${libcommonserver_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} - "C:/Program Files (x86)/log4cplus/include" "C:/Program Files (x86)/libzip/include" "C:/Program Files (x86)/xxHash/include" ) @@ -102,7 +100,6 @@ target_link_libraries(${libcommonserver_NAME} if (WIN32) target_link_libraries(${libcommonserver_NAME} - log4cplus::log4cplusU xxHash::xxhash Secur32) elseif(APPLE) @@ -112,7 +109,6 @@ elseif(APPLE) find_library(APPKIT_LIBRARY NAMES AppKit) target_link_libraries(${libcommonserver_NAME} - log4cplus::log4cplusU xxHash::xxhash ${FOUNDATION_LIBRARY} ${CORESERVICES_LIBRARY} @@ -120,7 +116,6 @@ elseif(APPLE) utf8proc) else() target_link_libraries(${libcommonserver_NAME} - "/usr/local/lib/liblog4cplusU.so" "/usr/local/lib/libxxhash.so" utf8proc) endif() diff --git a/src/libcommonserver/commserver.cpp b/src/libcommonserver/commserver.cpp index deeb06f32..c30a21dc7 100644 --- a/src/libcommonserver/commserver.cpp +++ b/src/libcommonserver/commserver.cpp @@ -19,7 +19,6 @@ #include "commserver.h" #include "common/utility.h" #include "libcommon/comm.h" -#include "libcommon/utility/utility.h" #include "libcommonserver/log/log.h" #include "libcommonserver/utility/utility.h" @@ -29,7 +28,6 @@ #include #include #include -#include #include #include @@ -53,7 +51,7 @@ std::shared_ptr CommServer::instance(QObject *parent) { } CommServer::CommServer(QObject *parent) : - QObject(parent), _requestWorkerThread(new QThread()), _requestWorker(new Worker()), _tcpSocket(nullptr), + QObject(parent), _requestWorkerThread(new QtLoggingThread()), _requestWorker(new Worker()), _tcpSocket(nullptr), _buffer(QByteArray()), _hasQuittedProperly(false) { // Start worker thread _requestWorker->moveToThread(_requestWorkerThread); @@ -398,7 +396,6 @@ void Worker::onStart() { } LOG_DEBUG(Log::instance()->getLogger(), "Worker ended"); - Utility::terminateThreadFunction(); } } // namespace KDC diff --git a/src/libcommonserver/commserver.h b/src/libcommonserver/commserver.h index 75a6d84d1..fff7b3e23 100644 --- a/src/libcommonserver/commserver.h +++ b/src/libcommonserver/commserver.h @@ -19,6 +19,7 @@ #pragma once #include "libcommon/comm.h" +#include "libcommon/utility/utility.h" #include @@ -59,7 +60,7 @@ class CommServer : public QObject { private: static std::shared_ptr _instance; - QThread *_requestWorkerThread; + QtLoggingThread *_requestWorkerThread; Worker *_requestWorker; QTcpServer _tcpServer; QTcpSocket *_tcpSocket; diff --git a/src/libcommonserver/utility/utility.cpp b/src/libcommonserver/utility/utility.cpp index 8ecfc4315..98ffda46a 100644 --- a/src/libcommonserver/utility/utility.cpp +++ b/src/libcommonserver/utility/utility.cpp @@ -913,9 +913,4 @@ std::string Utility::userName() { return userName_private(); } -ExitInfo Utility::terminateThreadFunction(const ExitInfo exitInfo) { - log4cplus::threadCleanup(); - return exitInfo; -} - } // namespace KDC diff --git a/src/libcommonserver/utility/utility.h b/src/libcommonserver/utility/utility.h index 8787533f2..0c4735661 100644 --- a/src/libcommonserver/utility/utility.h +++ b/src/libcommonserver/utility/utility.h @@ -184,14 +184,6 @@ struct COMMONSERVER_EXPORT Utility { static SyncPath sharedFolderName(); static std::string userName(); - //! Releases the memory used by log4cplus and returns the exitInfo parameter passed as parameter. - //! Functions executed in a thread must use this function to exit. - /*! - \param exitInfo to return - \return exitInfo passed as parameter - */ - static ExitInfo terminateThreadFunction(const ExitInfo exitInfo = ExitInfo()); - private: static log4cplus::Logger _logger; diff --git a/src/libsyncengine/jobs/jobmanager.cpp b/src/libsyncengine/jobs/jobmanager.cpp index 02c690b72..6347a4c68 100644 --- a/src/libsyncengine/jobs/jobmanager.cpp +++ b/src/libsyncengine/jobs/jobmanager.cpp @@ -138,7 +138,7 @@ JobManager::JobManager() : _logger(Log::instance()->getLogger()) { _cpuUsageThreshold = ParametersCache::instance()->parameters().maxAllowedCpu() / 100.0; - _thread = std::make_unique(run); + _thread = std::make_unique(run); LOG_DEBUG(_logger, "Network Job Manager started with max " << _maxNbThread << " threads"); } @@ -196,8 +196,6 @@ void JobManager::run() noexcept { Utility::msleep(100); // Sleep for 0.1s } - - Utility::terminateThreadFunction(); } void JobManager::startJob(std::pair, Poco::Thread::Priority> nextJob) { diff --git a/src/libsyncengine/jobs/jobmanager.h b/src/libsyncengine/jobs/jobmanager.h index c3cd1f558..b7dc0d6f9 100644 --- a/src/libsyncengine/jobs/jobmanager.h +++ b/src/libsyncengine/jobs/jobmanager.h @@ -20,6 +20,7 @@ #pragma once #include "abstractjob.h" +#include "libcommon/utility/utility.h" #include @@ -96,7 +97,7 @@ class JobManager { static std::chrono::time_point _maxNbThreadChrono; log4cplus::Logger _logger; - std::unique_ptr _thread; + std::unique_ptr _thread; static std::unordered_map> _managedJobs; // queued + running + pending jobs static std::priority_queue, Poco::Thread::Priority>, diff --git a/src/libsyncengine/performance_watcher/performancewatcher.cpp b/src/libsyncengine/performance_watcher/performancewatcher.cpp index cffdd1fe8..73134c7c8 100644 --- a/src/libsyncengine/performance_watcher/performancewatcher.cpp +++ b/src/libsyncengine/performance_watcher/performancewatcher.cpp @@ -59,7 +59,7 @@ void PerformanceWatcher::stop() { } PerformanceWatcher::PerformanceWatcher() { - _thread = std::make_unique(run); + _thread = std::make_unique(run); LOG_DEBUG(_logger, "Performance Watcher started"); } @@ -85,8 +85,6 @@ void PerformanceWatcher::run() { Utility::msleep(1000); // Sleep for 1s } - - Utility::terminateThreadFunction(); } bool PerformanceWatcher::updateCpuUsage() { diff --git a/src/libsyncengine/performance_watcher/performancewatcher.h b/src/libsyncengine/performance_watcher/performancewatcher.h index 7e4d09cc0..ab4c94a78 100644 --- a/src/libsyncengine/performance_watcher/performancewatcher.h +++ b/src/libsyncengine/performance_watcher/performancewatcher.h @@ -18,6 +18,7 @@ #pragma once +#include "libcommon/utility/utility.h" #include "libcommonserver/utility/utility.h" #include "log/log.h" @@ -51,7 +52,7 @@ class PerformanceWatcher { static bool _stop; log4cplus::Logger _logger = Log::instance()->getLogger(); - std::unique_ptr _thread = nullptr; + std::unique_ptr _thread = nullptr; static void updateAllStats(); diff --git a/src/libsyncengine/requests/serverrequests.cpp b/src/libsyncengine/requests/serverrequests.cpp index 7d80acc76..6ed0c7113 100644 --- a/src/libsyncengine/requests/serverrequests.cpp +++ b/src/libsyncengine/requests/serverrequests.cpp @@ -1119,7 +1119,7 @@ ExitInfo ServerRequests::getFolderSize(int userDbId, int driveId, const NodeId & std::function callback) { if (nodeId.empty()) { LOG_WARN(Log::instance()->getLogger(), "Node ID is empty"); - return Utility::terminateThreadFunction(ExitCode::DataError); + return ExitCode::DataError; } // get size of folder @@ -1130,7 +1130,7 @@ ExitInfo ServerRequests::getFolderSize(int userDbId, int driveId, const NodeId & LOG_WARN(Log::instance()->getLogger(), "Error in GetSizeJob::GetSizeJob for userDbId=" << userDbId << " driveId=" << driveId << " nodeId=" << nodeId.c_str() << " error=" << e.what()); - return Utility::terminateThreadFunction(ExitCode::DataError); + return ExitCode::DataError; } ExitCode exitCode = job->runSynchronously(); @@ -1138,7 +1138,7 @@ ExitInfo ServerRequests::getFolderSize(int userDbId, int driveId, const NodeId & LOG_WARN(Log::instance()->getLogger(), "Error in GetSizeJob::runSynchronously for userDbId=" << userDbId << " driveId=" << driveId << " nodeId=" << nodeId.c_str() << " code=" << exitCode); - return Utility::terminateThreadFunction(exitCode); + return exitCode; } Poco::JSON::Object::Ptr resObj = job->jsonRes(); @@ -1146,24 +1146,24 @@ ExitInfo ServerRequests::getFolderSize(int userDbId, int driveId, const NodeId & // Level = Debug because access forbidden is a normal case LOG_DEBUG(Log::instance()->getLogger(), "GetSizeJob failed for userDbId=" << userDbId << " driveId=" << driveId << " nodeId=" << nodeId.c_str()); - return Utility::terminateThreadFunction(ExitCode::BackError); + return ExitCode::BackError; } Poco::JSON::Object::Ptr dataObj = resObj->getObject(dataKey); if (!dataObj) { LOG_WARN(Log::instance()->getLogger(), "GetSizeJob failed for userDbId=" << userDbId << " driveId=" << driveId << " nodeId=" << nodeId.c_str()); - return Utility::terminateThreadFunction(ExitCode::BackError); + return ExitCode::BackError; } qint64 size = 0; if (!JsonParserUtility::extractValue(dataObj, sizeKey, size)) { - return Utility::terminateThreadFunction(ExitCode::BackError); + return ExitCode::BackError; } callback(QString::fromStdString(nodeId), size); - return Utility::terminateThreadFunction(ExitCode::Ok); + return ExitCode::Ok; } ExitCode ServerRequests::getPrivateLinkUrl(int driveDbId, const QString &fileId, QString &linkUrl) { diff --git a/src/libsyncengine/syncpal/isyncworker.cpp b/src/libsyncengine/syncpal/isyncworker.cpp index 1d2e26935..8a8b42fe8 100644 --- a/src/libsyncengine/syncpal/isyncworker.cpp +++ b/src/libsyncengine/syncpal/isyncworker.cpp @@ -154,9 +154,9 @@ void ISyncWorker::setDone(ExitCode exitCode) { log4cplus::threadCleanup(); } -void *ISyncWorker::executeFunc(void *thisWorker) { +void ISyncWorker::executeFunc(void *thisWorker) { ((ISyncWorker *) thisWorker)->execute(); - return nullptr; + log4cplus::threadCleanup(); } } // namespace KDC diff --git a/src/libsyncengine/syncpal/isyncworker.h b/src/libsyncengine/syncpal/isyncworker.h index b3830dcb4..70e703898 100644 --- a/src/libsyncengine/syncpal/isyncworker.h +++ b/src/libsyncengine/syncpal/isyncworker.h @@ -20,6 +20,7 @@ #include "syncpal.h" #include "libcommon/utility/types.h" +#include "libcommon/utility/utility.h" #include @@ -73,7 +74,7 @@ class ISyncWorker { inline int syncDbId() const { return _syncPal ? _syncPal->syncDbId() : -1; } private: - static void *executeFunc(void *thisWorker); + static void executeFunc(void *thisWorker); const std::string _name; const std::string _shortName; diff --git a/src/libsyncengine/syncpal/syncpalworker.h b/src/libsyncengine/syncpal/syncpalworker.h index 9e00b2cfd..2ba85d91d 100644 --- a/src/libsyncengine/syncpal/syncpalworker.h +++ b/src/libsyncengine/syncpal/syncpalworker.h @@ -30,7 +30,7 @@ class SyncPalWorker : public ISyncWorker { public: SyncPalWorker(std::shared_ptr syncPal, const std::string &name, const std::string &shortName); - void execute(); + void execute() override; inline SyncStep step() const { return _step; } inline std::chrono::time_point pauseTime() const { return _pauseTime; } static std::string stepName(SyncStep step); diff --git a/src/libsyncengine/update_detection/file_system_observer/checksum/contentchecksumworker.h b/src/libsyncengine/update_detection/file_system_observer/checksum/contentchecksumworker.h index 5f9688738..47048c559 100644 --- a/src/libsyncengine/update_detection/file_system_observer/checksum/contentchecksumworker.h +++ b/src/libsyncengine/update_detection/file_system_observer/checksum/contentchecksumworker.h @@ -44,7 +44,7 @@ class ContentChecksumWorker : public ISyncWorker { static void callback(UniqueId jobId); protected: - virtual void execute() override; + void execute() override; private: std::shared_ptr _localSnapshot; diff --git a/src/libsyncengine/update_detection/file_system_observer/computefsoperationworker.h b/src/libsyncengine/update_detection/file_system_observer/computefsoperationworker.h index ee3f702ac..b1000b300 100644 --- a/src/libsyncengine/update_detection/file_system_observer/computefsoperationworker.h +++ b/src/libsyncengine/update_detection/file_system_observer/computefsoperationworker.h @@ -42,7 +42,7 @@ class ComputeFSOperationWorker : public ISyncWorker { const std::unordered_map getFileSizeMismatchMap() const { return _fileSizeMismatchMap; } protected: - virtual void execute() override; + void execute() override; private: using NodeIdSet = std::unordered_set; diff --git a/src/libsyncengine/update_detection/file_system_observer/filesystemobserverworker.h b/src/libsyncengine/update_detection/file_system_observer/filesystemobserverworker.h index 30137ec88..ff6da91b5 100644 --- a/src/libsyncengine/update_detection/file_system_observer/filesystemobserverworker.h +++ b/src/libsyncengine/update_detection/file_system_observer/filesystemobserverworker.h @@ -38,7 +38,7 @@ class FileSystemObserverWorker : public ISyncWorker { virtual void forceUpdate(); virtual inline bool updating() const { return _updating; } - std::shared_ptr snapshot() const { return _snapshot; }; + std::shared_ptr snapshot() const { return _snapshot; } protected: std::shared_ptr _syncDb; @@ -55,7 +55,6 @@ class FileSystemObserverWorker : public ISyncWorker { virtual bool isFolderWatcherReliable() const { return true; } private: - static void *executeFunc(void *thisWorker); virtual ReplicaSide getSnapshotType() const = 0; friend class TestLocalFileSystemObserverWorker; diff --git a/src/libsyncengine/update_detection/file_system_observer/folderwatcher.cpp b/src/libsyncengine/update_detection/file_system_observer/folderwatcher.cpp index d67d9c917..41da58a83 100644 --- a/src/libsyncengine/update_detection/file_system_observer/folderwatcher.cpp +++ b/src/libsyncengine/update_detection/file_system_observer/folderwatcher.cpp @@ -36,7 +36,7 @@ void FolderWatcher::start() { LOG_DEBUG(_logger, "Start Folder Watcher"); _stop = false; - _thread = std::unique_ptr(new std::thread(executeFunc, this)); + _thread = std::make_unique(executeFunc, this); #if defined(__APPLE__) _thread->detach(); @@ -59,9 +59,9 @@ void FolderWatcher::stop() { _thread = nullptr; } -void *FolderWatcher::executeFunc(void *thisWorker) { +void FolderWatcher::executeFunc(void *thisWorker) { ((FolderWatcher *) thisWorker)->startWatching(); - return nullptr; + log4cplus::threadCleanup(); } } // namespace KDC diff --git a/src/libsyncengine/update_detection/file_system_observer/folderwatcher.h b/src/libsyncengine/update_detection/file_system_observer/folderwatcher.h index ee459df8e..1ca420cc6 100644 --- a/src/libsyncengine/update_detection/file_system_observer/folderwatcher.h +++ b/src/libsyncengine/update_detection/file_system_observer/folderwatcher.h @@ -19,6 +19,7 @@ #pragma once #include "libcommon/utility/types.h" +#include "libcommon/utility/utility.h" #include "libcommonserver/log/log.h" #include @@ -54,7 +55,7 @@ class FolderWatcher { bool _stop = false; private: - static void *executeFunc(void *thisWorker); + static void executeFunc(void *thisWorker); std::unique_ptr _thread = nullptr; ExitInfo _exitInfo = ExitCode::Ok; diff --git a/src/libsyncengine/update_detection/file_system_observer/folderwatcher_mac.cpp b/src/libsyncengine/update_detection/file_system_observer/folderwatcher_mac.cpp index 3cd914573..eed0c6fc3 100644 --- a/src/libsyncengine/update_detection/file_system_observer/folderwatcher_mac.cpp +++ b/src/libsyncengine/update_detection/file_system_observer/folderwatcher_mac.cpp @@ -110,7 +110,6 @@ void FolderWatcher_mac::startWatching() { CFRunLoopRun(); LOGW_DEBUG(_logger, L"Folder watching stopped: " << _folder.wstring().c_str()); - Utility::terminateThreadFunction(); } void FolderWatcher_mac::doNotifyParent(const std::list> &changes) { diff --git a/src/libsyncengine/update_detection/file_system_observer/localfilesystemobserverworker_unix.cpp b/src/libsyncengine/update_detection/file_system_observer/localfilesystemobserverworker_unix.cpp index 22657d848..d3591b88a 100644 --- a/src/libsyncengine/update_detection/file_system_observer/localfilesystemobserverworker_unix.cpp +++ b/src/libsyncengine/update_detection/file_system_observer/localfilesystemobserverworker_unix.cpp @@ -38,9 +38,4 @@ LocalFileSystemObserverWorker_unix::LocalFileSystemObserverWorker_unix(std::shar #endif } -LocalFileSystemObserverWorker_unix::~LocalFileSystemObserverWorker_unix() { - FolderWatcher *ptr = _folderWatcher.release(); - delete ptr; -} - } // namespace KDC diff --git a/src/libsyncengine/update_detection/file_system_observer/localfilesystemobserverworker_unix.h b/src/libsyncengine/update_detection/file_system_observer/localfilesystemobserverworker_unix.h index 389c5d648..2fdc6a70c 100644 --- a/src/libsyncengine/update_detection/file_system_observer/localfilesystemobserverworker_unix.h +++ b/src/libsyncengine/update_detection/file_system_observer/localfilesystemobserverworker_unix.h @@ -26,7 +26,6 @@ class LocalFileSystemObserverWorker_unix : public LocalFileSystemObserverWorker public: LocalFileSystemObserverWorker_unix(std::shared_ptr syncPal, const std::string &name, const std::string &shortName); - ~LocalFileSystemObserverWorker_unix(); protected: virtual bool isFolderWatcherReliable() const override { return (_folderWatcher && _folderWatcher->isReliable()); } diff --git a/src/server/appserver.cpp b/src/server/appserver.cpp index 149c553d4..cfd785f86 100644 --- a/src/server/appserver.cpp +++ b/src/server/appserver.cpp @@ -2143,13 +2143,13 @@ ExitInfo AppServer::uploadLog(bool includeArchivedLogs) { if (exitCause == ExitCause::OperationCanceled) { LOG_DEBUG(_logger, "Log transfert canceled"); sendLogUploadStatusUpdated(LogUploadState::Canceled, 0); - return Utility::terminateThreadFunction({exitCode, exitCause}); + return {exitCode, exitCause}; } else if (exitCode != ExitCode::Ok) { LOG_WARN(_logger, "Error in LogArchiverHelper::sendLogToSupport: code=" << exitCode << " cause=" << exitCause); addError(Error(errId(), ExitCode::LogUploadFailed, exitCause)); } sendLogUploadStatusUpdated(exitCode == ExitCode::Ok ? LogUploadState::Success : LogUploadState::Failed, 0); - return Utility::terminateThreadFunction({exitCode, exitCause}); + return {exitCode, exitCause}; } ExitCode AppServer::checkIfSyncIsValid(const Sync &sync) { diff --git a/src/server/vfs/mac/vfs_mac.cpp b/src/server/vfs/mac/vfs_mac.cpp index 978ad57a2..b9b680d86 100644 --- a/src/server/vfs/mac/vfs_mac.cpp +++ b/src/server/vfs/mac/vfs_mac.cpp @@ -53,7 +53,7 @@ VfsMac::VfsMac(KDC::VfsSetupParams &vfsSetupParams, QObject *parent) : // Start worker threads for (int i = 0; i < NB_WORKERS; i++) { for (int j = 0; j < s_nb_threads[i]; j++) { - QThread *workerThread = new QThread(); + QtLoggingThread *workerThread = new QtLoggingThread(); _workerInfo[i]._threadList.append(workerThread); Worker *worker = new Worker(this, i, j, logger()); worker->moveToThread(workerThread); @@ -822,7 +822,6 @@ void Worker::start() { } LOG_DEBUG(logger(), "Worker " << _type << " - " << _num << " ended"); - Utility::terminateThreadFunction(); } } // namespace KDC diff --git a/src/server/vfs/mac/vfs_mac.h b/src/server/vfs/mac/vfs_mac.h index 6ce28622c..9d4036319 100644 --- a/src/server/vfs/mac/vfs_mac.h +++ b/src/server/vfs/mac/vfs_mac.h @@ -18,6 +18,7 @@ #pragma once +#include "libcommon/utility/utility.h" #include "libcommonserver/vfs.h" #include "libcommonserver/plugin.h" #include "litesyncextconnector.h" @@ -28,7 +29,6 @@ #include #include #include -#include #include #define WORKER_HYDRATION 0 @@ -44,7 +44,7 @@ struct WorkerInfo { std::deque _queue; QWaitCondition _queueWC; bool _stop = false; - QList _threadList; + QList _threadList; }; class VfsMac : public Vfs { From c0909909528b3902474c8b94feba7f593bc5da8c Mon Sep 17 00:00:00 2001 From: Christophe Larchier Date: Thu, 28 Nov 2024 08:59:42 +0100 Subject: [PATCH 154/178] Fix Windows and Linux builds --- .../file_system_observer/folderwatcher_linux.cpp | 5 ++--- .../file_system_observer/folderwatcher_win.cpp | 1 - 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/libsyncengine/update_detection/file_system_observer/folderwatcher_linux.cpp b/src/libsyncengine/update_detection/file_system_observer/folderwatcher_linux.cpp index 10099dfa5..33fa7df48 100644 --- a/src/libsyncengine/update_detection/file_system_observer/folderwatcher_linux.cpp +++ b/src/libsyncengine/update_detection/file_system_observer/folderwatcher_linux.cpp @@ -46,11 +46,11 @@ void FolderWatcher_linux::startWatching() { _fileDescriptor = inotify_init(); if (_fileDescriptor == -1) { LOG4CPLUS_WARN(_logger, "inotify_init() failed: " << strerror(errno)); - Utility::terminateThreadFunction(); + return; } if (!addFolderRecursive(_folder)) { - Utility::terminateThreadFunction(); + return; } while (!_stop) { @@ -127,7 +127,6 @@ void FolderWatcher_linux::startWatching() { } LOGW_DEBUG(_logger, L"Folder watching stopped: " << Utility::formatSyncPath(_folder)); - Utility::terminateThreadFunction(); } bool FolderWatcher_linux::findSubFolders(const SyncPath &dir, std::list &fullList) { diff --git a/src/libsyncengine/update_detection/file_system_observer/folderwatcher_win.cpp b/src/libsyncengine/update_detection/file_system_observer/folderwatcher_win.cpp index 30baf83b7..207fedd79 100644 --- a/src/libsyncengine/update_detection/file_system_observer/folderwatcher_win.cpp +++ b/src/libsyncengine/update_detection/file_system_observer/folderwatcher_win.cpp @@ -67,7 +67,6 @@ void FolderWatcher_win::startWatching() { } LOGW_DEBUG(_logger, L"Folder watching stopped: " << _folder.wstring().c_str()); - Utility::terminateThreadFunction(); } void FolderWatcher_win::stopWatching() { From a6ffed126a8127dd7849efd2f2487bf04c532d77 Mon Sep 17 00:00:00 2001 From: Luc Guyot Date: Fri, 22 Nov 2024 19:02:52 +0100 Subject: [PATCH 155/178] Do not add a slash at the end of a directory or file path if the event has no name --- .../folderwatcher_linux.cpp | 28 +++++++++++-------- .../folderwatcher_linux.h | 3 ++ 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/src/libsyncengine/update_detection/file_system_observer/folderwatcher_linux.cpp b/src/libsyncengine/update_detection/file_system_observer/folderwatcher_linux.cpp index cc3766595..d1d937d48 100644 --- a/src/libsyncengine/update_detection/file_system_observer/folderwatcher_linux.cpp +++ b/src/libsyncengine/update_detection/file_system_observer/folderwatcher_linux.cpp @@ -39,8 +39,14 @@ FolderWatcher_linux::FolderWatcher_linux(LocalFileSystemObserverWorker *parent, FolderWatcher_linux::~FolderWatcher_linux() {} +SyncPath FolderWatcher_linux::getSyncPath(const inotify_event *event) const { + const auto syncName = SyncName(event->name); // `syncName` can be empty if the event is a permission change. + + return syncName.empty() ? _watchToPath.at(event->wd) : _watchToPath.at(event->wd) / syncName; +} + void FolderWatcher_linux::startWatching() { - LOG4CPLUS_DEBUG(_logger, L"Start watching folder: " << Path2WStr(_folder).c_str()); + LOG4CPLUS_DEBUG(_logger, L"Start watching folder " << Utility::formatSyncPath(_folder)); LOG4CPLUS_DEBUG(_logger, "File system format: " << Utility::fileSystemName(_folder).c_str()); _fileDescriptor = inotify_init(); @@ -88,11 +94,11 @@ void FolderWatcher_linux::startWatching() { } if (!skip && !_stop) { - if (_watchToPath.find(event->wd) != _watchToPath.end()) { - const SyncPath path = _watchToPath[event->wd] / SyncName(event->name); + if (_watchToPath.contains(event->wd)) { + const SyncPath path = getSyncPath(event); if (ParametersCache::isExtendedLogEnabled()) { - LOGW_DEBUG(_logger, L"Operation " << opType << L" detected on item with " - << Utility::formatSyncPath(path).c_str()); + LOGW_DEBUG(_logger, + L"Operation " << opType << L" detected on item with " << Utility::formatSyncPath(path)); } changeDetected(path, opType); @@ -106,7 +112,7 @@ void FolderWatcher_linux::startWatching() { } if (ioError == IoError::AccessDenied) { - LOGW_WARN(_logger, L"The item misses search/exec permission - path=" << Path2WStr(path).c_str()); + LOGW_WARN(_logger, L"The item misses search/exec permission - " << Utility::formatSyncPath(path)); } if ((event->mask & (IN_MOVED_TO | IN_CREATE)) && isDirectory) { @@ -131,17 +137,17 @@ bool FolderWatcher_linux::findSubFolders(const SyncPath &dir, std::list +struct inotify_event; + namespace KDC { class LocalFileSystemObserverWorker; @@ -45,6 +47,7 @@ class FolderWatcher_linux : public FolderWatcher { bool addFolderRecursive(const SyncPath &path); void removeFoldersBelow(const SyncPath &dirPath); + SyncPath getSyncPath(const inotify_event *event) const; void changeDetected(const SyncPath &path, OperationType opType); std::unordered_map _watchToPath; From d1a6c20063778efd0b89780e11724ea60b2bf4cd Mon Sep 17 00:00:00 2001 From: Luc Guyot Date: Mon, 25 Nov 2024 15:57:51 +0100 Subject: [PATCH 156/178] Adds a unit test for the makeSyncPath method --- .../folderwatcher_linux.cpp | 11 ++++--- .../folderwatcher_linux.h | 6 +++- test/libsyncengine/CMakeLists.txt | 6 +++- test/libsyncengine/test.cpp | 4 +++ .../testfolderwatcherlinux.cpp | 31 +++++++++++++++++ .../testfolderwatcherlinux.h | 33 +++++++++++++++++++ 6 files changed, 84 insertions(+), 7 deletions(-) create mode 100644 test/libsyncengine/update_detection/file_system_observer/testfolderwatcherlinux.cpp create mode 100644 test/libsyncengine/update_detection/file_system_observer/testfolderwatcherlinux.h diff --git a/src/libsyncengine/update_detection/file_system_observer/folderwatcher_linux.cpp b/src/libsyncengine/update_detection/file_system_observer/folderwatcher_linux.cpp index d1d937d48..058ccea98 100644 --- a/src/libsyncengine/update_detection/file_system_observer/folderwatcher_linux.cpp +++ b/src/libsyncengine/update_detection/file_system_observer/folderwatcher_linux.cpp @@ -39,10 +39,11 @@ FolderWatcher_linux::FolderWatcher_linux(LocalFileSystemObserverWorker *parent, FolderWatcher_linux::~FolderWatcher_linux() {} -SyncPath FolderWatcher_linux::getSyncPath(const inotify_event *event) const { - const auto syncName = SyncName(event->name); // `syncName` can be empty if the event is a permission change. +SyncPath FolderWatcher_linux::makeSyncPath(const SyncPath &watchedFolderPath, const char *fileName) { + const auto syncName = SyncName(fileName); // `syncName` is empty if for instance the event is a permission change on a watched + // directory (check inotify man page). - return syncName.empty() ? _watchToPath.at(event->wd) : _watchToPath.at(event->wd) / syncName; + return syncName.empty() ? watchedFolderPath : watchedFolderPath / syncName; } void FolderWatcher_linux::startWatching() { @@ -95,7 +96,7 @@ void FolderWatcher_linux::startWatching() { if (!skip && !_stop) { if (_watchToPath.contains(event->wd)) { - const SyncPath path = getSyncPath(event); + const SyncPath path = makeSyncPath(_watchToPath[event->wd], event->name); if (ParametersCache::isExtendedLogEnabled()) { LOGW_DEBUG(_logger, L"Operation " << opType << L" detected on item with " << Utility::formatSyncPath(path)); @@ -103,7 +104,7 @@ void FolderWatcher_linux::startWatching() { changeDetected(path, opType); bool isDirectory = false; - IoError ioError = IoError::Success; + auto ioError = IoError::Success; const bool isDirSuccess = IoHelper::checkIfIsDirectory(path, isDirectory, ioError); if (!isDirSuccess) { LOGW_WARN(_logger, L"Error in IoHelper::checkIfIsDirectory: " diff --git a/src/libsyncengine/update_detection/file_system_observer/folderwatcher_linux.h b/src/libsyncengine/update_detection/file_system_observer/folderwatcher_linux.h index 4a30a45d5..02b7bd814 100644 --- a/src/libsyncengine/update_detection/file_system_observer/folderwatcher_linux.h +++ b/src/libsyncengine/update_detection/file_system_observer/folderwatcher_linux.h @@ -47,11 +47,15 @@ class FolderWatcher_linux : public FolderWatcher { bool addFolderRecursive(const SyncPath &path); void removeFoldersBelow(const SyncPath &dirPath); - SyncPath getSyncPath(const inotify_event *event) const; + void changeDetected(const SyncPath &path, OperationType opType); std::unordered_map _watchToPath; std::map _pathToWatch; + + static SyncPath makeSyncPath(const SyncPath &path, const char *name); + + friend class TestFolderWatcherLinux; }; } // namespace KDC diff --git a/test/libsyncengine/CMakeLists.txt b/test/libsyncengine/CMakeLists.txt index df1289c1c..0419167a5 100644 --- a/test/libsyncengine/CMakeLists.txt +++ b/test/libsyncengine/CMakeLists.txt @@ -55,6 +55,8 @@ set(testsyncengine_SRCS if (APPLE) list(APPEND testsyncengine_SRCS update_detection/file_system_observer/testfolderwatchermac.h update_detection/file_system_observer/testfolderwatchermac.cpp) +elif (__unix__) + list(APPEND testsyncengine_SRCS update_detection/file_system_observer/testfolderwatcherlinux.h update_detection/file_system_observer/testfolderwatcherlinux.cpp) endif () if (USE_OUR_OWN_SQLITE3) @@ -68,7 +70,9 @@ else() include_directories("/usr/local/include") endif () -add_executable(${testsyncengine_NAME} ${testsyncengine_SRCS}) +add_executable(${testsyncengine_NAME} ${testsyncengine_SRCS} + update_detection/file_system_observer/testfolderwatcherlinux.cpp + update_detection/file_system_observer/testfolderwatcherlinux.hpp) set_target_properties(${testsyncengine_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${BIN_OUTPUT_DIRECTORY}) diff --git a/test/libsyncengine/test.cpp b/test/libsyncengine/test.cpp index e66b19270..6acb4dbae 100644 --- a/test/libsyncengine/test.cpp +++ b/test/libsyncengine/test.cpp @@ -45,6 +45,8 @@ #ifdef __APPLE__ #include "update_detection/file_system_observer/testfolderwatchermac.h" +#elif __unix__ +#include "update_detection/file_system_observer/testfolderwatcherlinux.h" #endif namespace KDC { @@ -60,6 +62,8 @@ CPPUNIT_TEST_SUITE_REGISTRATION(TestFsOperationSet); CPPUNIT_TEST_SUITE_REGISTRATION(TestLocalFileSystemObserverWorker); #ifdef __APPLE__ CPPUNIT_TEST_SUITE_REGISTRATION(TestFolderWatcher_mac); +#elif __unix__ +CPPUNIT_TEST_SUITE_REGISTRATION(TestFolderWatcherLinux); #endif CPPUNIT_TEST_SUITE_REGISTRATION(TestSnapshotItemHandler); CPPUNIT_TEST_SUITE_REGISTRATION(TestRemoteFileSystemObserverWorker); diff --git a/test/libsyncengine/update_detection/file_system_observer/testfolderwatcherlinux.cpp b/test/libsyncengine/update_detection/file_system_observer/testfolderwatcherlinux.cpp new file mode 100644 index 000000000..df222fcd2 --- /dev/null +++ b/test/libsyncengine/update_detection/file_system_observer/testfolderwatcherlinux.cpp @@ -0,0 +1,31 @@ +/* + * Infomaniak kDrive - Desktop + * Copyright (C) 2023-2024 Infomaniak Network SA + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "testfolderwatcherlinux.h" + +#include "update_detection/file_system_observer/folderwatcher_linux.h" + + +namespace KDC { + +void TestFolderWatcherLinux::testGetSyncName() { + CPPUNIT_ASSERT(!FolderWatcher_linux::makeSyncPath("/A/B", "file.txt").filename().empty()); + CPPUNIT_ASSERT(!FolderWatcher_linux::makeSyncPath("/A/B", "").filename().empty()); +} + +} // namespace KDC diff --git a/test/libsyncengine/update_detection/file_system_observer/testfolderwatcherlinux.h b/test/libsyncengine/update_detection/file_system_observer/testfolderwatcherlinux.h new file mode 100644 index 000000000..5170a6912 --- /dev/null +++ b/test/libsyncengine/update_detection/file_system_observer/testfolderwatcherlinux.h @@ -0,0 +1,33 @@ +/* + * Infomaniak kDrive - Desktop + * Copyright (C) 2023-2024 Infomaniak Network SA + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include "testincludes.h" + +namespace KDC { + +class TestFolderWatcherLinux final : public CppUnit::TestFixture { + CPPUNIT_TEST_SUITE(TestFolderWatcherLinux); + CPPUNIT_TEST(testGetSyncName); + CPPUNIT_TEST_SUITE_END(); + + void testGetSyncName(); +}; + +} // namespace KDC From 61b543ed838e53e086f00b458dbc3ff9200a9ca1 Mon Sep 17 00:00:00 2001 From: Luc Guyot Date: Mon, 25 Nov 2024 16:51:45 +0100 Subject: [PATCH 157/178] Fixes unit tests CMakeList.txt and new test names --- test/libsyncengine/CMakeLists.txt | 6 ++---- .../file_system_observer/testfolderwatcherlinux.cpp | 2 +- .../file_system_observer/testfolderwatcherlinux.h | 5 +++-- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/test/libsyncengine/CMakeLists.txt b/test/libsyncengine/CMakeLists.txt index 0419167a5..d0e78417e 100644 --- a/test/libsyncengine/CMakeLists.txt +++ b/test/libsyncengine/CMakeLists.txt @@ -55,7 +55,7 @@ set(testsyncengine_SRCS if (APPLE) list(APPEND testsyncengine_SRCS update_detection/file_system_observer/testfolderwatchermac.h update_detection/file_system_observer/testfolderwatchermac.cpp) -elif (__unix__) +elseif (UNIX) list(APPEND testsyncengine_SRCS update_detection/file_system_observer/testfolderwatcherlinux.h update_detection/file_system_observer/testfolderwatcherlinux.cpp) endif () @@ -70,9 +70,7 @@ else() include_directories("/usr/local/include") endif () -add_executable(${testsyncengine_NAME} ${testsyncengine_SRCS} - update_detection/file_system_observer/testfolderwatcherlinux.cpp - update_detection/file_system_observer/testfolderwatcherlinux.hpp) +add_executable(${testsyncengine_NAME} ${testsyncengine_SRCS}) set_target_properties(${testsyncengine_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${BIN_OUTPUT_DIRECTORY}) diff --git a/test/libsyncengine/update_detection/file_system_observer/testfolderwatcherlinux.cpp b/test/libsyncengine/update_detection/file_system_observer/testfolderwatcherlinux.cpp index df222fcd2..775c66e34 100644 --- a/test/libsyncengine/update_detection/file_system_observer/testfolderwatcherlinux.cpp +++ b/test/libsyncengine/update_detection/file_system_observer/testfolderwatcherlinux.cpp @@ -23,7 +23,7 @@ namespace KDC { -void TestFolderWatcherLinux::testGetSyncName() { +void TestFolderWatcherLinux::testMakeSyncPath() { CPPUNIT_ASSERT(!FolderWatcher_linux::makeSyncPath("/A/B", "file.txt").filename().empty()); CPPUNIT_ASSERT(!FolderWatcher_linux::makeSyncPath("/A/B", "").filename().empty()); } diff --git a/test/libsyncengine/update_detection/file_system_observer/testfolderwatcherlinux.h b/test/libsyncengine/update_detection/file_system_observer/testfolderwatcherlinux.h index 5170a6912..074f3c6f0 100644 --- a/test/libsyncengine/update_detection/file_system_observer/testfolderwatcherlinux.h +++ b/test/libsyncengine/update_detection/file_system_observer/testfolderwatcherlinux.h @@ -24,10 +24,11 @@ namespace KDC { class TestFolderWatcherLinux final : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(TestFolderWatcherLinux); - CPPUNIT_TEST(testGetSyncName); + CPPUNIT_TEST(testMakeSyncPath); CPPUNIT_TEST_SUITE_END(); - void testGetSyncName(); + private: + void testMakeSyncPath(); }; } // namespace KDC From 56ad8c2e2706ecd99cd4cce28a28e86436f038a1 Mon Sep 17 00:00:00 2001 From: Luc Guyot Date: Tue, 26 Nov 2024 08:36:16 +0100 Subject: [PATCH 158/178] Moves comment about event name where it fits best --- .../file_system_observer/folderwatcher_linux.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libsyncengine/update_detection/file_system_observer/folderwatcher_linux.cpp b/src/libsyncengine/update_detection/file_system_observer/folderwatcher_linux.cpp index 058ccea98..9c4d85d7f 100644 --- a/src/libsyncengine/update_detection/file_system_observer/folderwatcher_linux.cpp +++ b/src/libsyncengine/update_detection/file_system_observer/folderwatcher_linux.cpp @@ -40,9 +40,7 @@ FolderWatcher_linux::FolderWatcher_linux(LocalFileSystemObserverWorker *parent, FolderWatcher_linux::~FolderWatcher_linux() {} SyncPath FolderWatcher_linux::makeSyncPath(const SyncPath &watchedFolderPath, const char *fileName) { - const auto syncName = SyncName(fileName); // `syncName` is empty if for instance the event is a permission change on a watched - // directory (check inotify man page). - + const auto syncName = SyncName(fileName); return syncName.empty() ? watchedFolderPath : watchedFolderPath / syncName; } @@ -96,6 +94,8 @@ void FolderWatcher_linux::startWatching() { if (!skip && !_stop) { if (_watchToPath.contains(event->wd)) { + // `event->name` is empty for instance if the event is a permission change on a watched + // directory (see inotify man page). const SyncPath path = makeSyncPath(_watchToPath[event->wd], event->name); if (ParametersCache::isExtendedLogEnabled()) { LOGW_DEBUG(_logger, From bd3fca51e115e2c4d7b88a2b5ca97c9283422683 Mon Sep 17 00:00:00 2001 From: Luc Guyot Date: Thu, 21 Nov 2024 12:09:33 +0100 Subject: [PATCH 159/178] Adds an option to the Linux Amd64 script builder to deactivate the build of unit tests --- .github/workflows/linux.yml | 2 +- .github/workflows/package.yml | 2 +- .../linux/build-ci-amd64.sh | 74 ++++++++++++++++--- 3 files changed, 65 insertions(+), 13 deletions(-) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index f6e8274b7..f85da6c01 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -34,7 +34,7 @@ jobs: - name: Grant building script execute permission run : chmod +x ./infomaniak-build-tools/linux/build-ci-amd64.sh - name: Build kDrive desktop - run : ./infomaniak-build-tools/linux/build-ci-amd64.sh + run : ./infomaniak-build-tools/linux/build-ci-amd64.sh -u - name: Grant tests script execute permission run : chmod +x ./infomaniak-build-tools/run-tests.sh diff --git a/.github/workflows/package.yml b/.github/workflows/package.yml index 989df0e13..eff96b2c5 100644 --- a/.github/workflows/package.yml +++ b/.github/workflows/package.yml @@ -68,7 +68,7 @@ jobs: - name: Grant building script execute permission run : chmod +x ./infomaniak-build-tools/linux/build-ci-amd64.sh - name: Build kDrive desktop - run : ./infomaniak-build-tools/linux/build-ci-amd64.sh release + run : ./infomaniak-build-tools/linux/build-ci-amd64.sh -t release - name: Grant packaging script execute permission run : chmod +x ./infomaniak-build-tools/linux/package-ci-amd64.sh diff --git a/infomaniak-build-tools/linux/build-ci-amd64.sh b/infomaniak-build-tools/linux/build-ci-amd64.sh index c4446c281..f430321fe 100644 --- a/infomaniak-build-tools/linux/build-ci-amd64.sh +++ b/infomaniak-build-tools/linux/build-ci-amd64.sh @@ -20,16 +20,68 @@ set -xe -BUILDTYPE="Debug" -if [[ $1 == 'release' ]]; then - BUILDTYPE="Release"; +program_name="$(basename "$0")" + +function display_help { + echo "$program_name [-h] [-t build-type] [-u unit-tests]" + echo " Build the desktop-kDrive application for Linux Amd64 with the specified build type ." + echo "where:" + echo "-h Show this help text." + echo "-t " + echo " Set the type of the build. Defaults to 'debug'. The valid values are: 'debug' or 'release'." + echo "-u " + echo " Activate the build of unit tests. Without this flag, unit tests will not be built." +} + + +unit_tests=0 +build_type="debug" + +while : +do + case "$1" in + -t | --build-type) + build_type="$2" + shift 2 + ;; + -u | --unit-tests) + unit_tests=1 + shift 1 + ;; + -h | --help) + display_help + exit 0 + ;; + --) # End of all options + shift + break + ;; + -*) + echo "Error: Unknown option: $1" >&2 + exit 1 + ;; + *) # No more options + break + ;; + esac +done + + +if [[ $build_type == "release" ]]; then + build_type="Release" +elif [[ $build_type == "debug" ]]; then + build_type="Debug" fi +echo "Build type: $build_type" +echo "Unit tests build flag: $unit_tests" + + export QT_BASE_DIR="~/Qt/6.2.3" export QTDIR="$QT_BASE_DIR/gcc_64" export BASEPATH=$PWD export CONTENTDIR="$BASEPATH/build-linux" -export BUILDDIR="$CONTENTDIR/build" +export build_dir="$CONTENTDIR/build" export APPDIR="$CONTENTDIR/app" extract_debug () { @@ -39,7 +91,7 @@ extract_debug () { } mkdir -p $APPDIR -mkdir -p $BUILDDIR +mkdir -p $build_dir export QMAKE=$QTDIR/bin/qmake export PATH=$QTDIR/bin:$QTDIR/libexec:$PATH @@ -50,14 +102,14 @@ export PKG_CONFIG_PATH=$QTDIR/lib/pkgconfig:$PKG_CONFIG_PATH export SUFFIX="" # Build client -cd $BUILDDIR -mkdir -p $BUILDDIR/client +cd $build_dir +mkdir -p $build_dir/client CMAKE_PARAMS=() export KDRIVE_DEBUG=0 -cmake -B$BUILDDIR -H$BASEPATH \ +cmake -B$build_dir -H$BASEPATH \ -DOPENSSL_ROOT_DIR=/usr/local \ -DOPENSSL_INCLUDE_DIR=/usr/local/include \ -DOPENSSL_CRYPTO_LIBRARY=/usr/local/lib64/libcrypto.so \ @@ -66,11 +118,11 @@ cmake -B$BUILDDIR -H$BASEPATH \ -DCMAKE_BUILDTYPE=$BUILDTYPE \ -DCMAKE_PREFIX_PATH=$BASEPATH \ -DCMAKE_INSTALL_PREFIX=/usr \ - -DBIN_INSTALL_DIR=$BUILDDIR/client \ + -DBIN_INSTALL_DIR=$build_dir/client \ -DKDRIVE_VERSION_SUFFIX=$SUFFIX \ -DKDRIVE_THEME_DIR="$BASEPATH/infomaniak" \ -DKDRIVE_VERSION_BUILD="$(date +%Y%m%d)" \ - -DBUILD_UNIT_TESTS=1 \ + -DBUILD_UNIT_TESTS=$unit_tests \ "${CMAKE_PARAMS[@]}" \ make -j$(nproc) @@ -80,4 +132,4 @@ extract_debug ./bin kDrive_client make DESTDIR=$APPDIR install -cp $BASEPATH/sync-exclude-linux.lst $BUILDDIR/bin/sync-exclude.lst +cp $BASEPATH/sync-exclude-linux.lst $build_dir/bin/sync-exclude.lst From 8c57f1fba60295ba98112808ae8d6d8c864f776d Mon Sep 17 00:00:00 2001 From: Herve Eruam Date: Thu, 28 Nov 2024 12:07:03 +0100 Subject: [PATCH 160/178] Add a unit test for cross device link. --- src/libcommon/utility/types.h | 1 + src/libcommonserver/io/iohelper.cpp | 18 +++- src/libcommonserver/io/iohelper.h | 3 +- src/libcommonserver/io/iohelper_win.cpp | 2 + .../jobs/network/API_v2/downloadjob.cpp | 16 ++-- .../jobs/network/testnetworkjobs.cpp | 82 ++++++++++++++----- 6 files changed, 93 insertions(+), 29 deletions(-) diff --git a/src/libcommon/utility/types.h b/src/libcommon/utility/types.h index 3fea8198f..51f2ad459 100644 --- a/src/libcommon/utility/types.h +++ b/src/libcommon/utility/types.h @@ -422,6 +422,7 @@ enum class IoError { MaxDepthExceeded, NoSuchFileOrDirectory, ResultOutOfRange, + CrossDeviceLink, Unknown }; std::string toString(IoError e); diff --git a/src/libcommonserver/io/iohelper.cpp b/src/libcommonserver/io/iohelper.cpp index 821d8b8e8..a7ec3f994 100644 --- a/src/libcommonserver/io/iohelper.cpp +++ b/src/libcommonserver/io/iohelper.cpp @@ -39,6 +39,8 @@ std::function IoHelper::_isDire static_cast(&std::filesystem::is_directory); std::function IoHelper::_isSymlink = static_cast(&std::filesystem::is_symlink); +std::function IoHelper::_rename = + static_cast(std::filesystem::rename); std::function IoHelper::_readSymlink = static_cast(&std::filesystem::read_symlink); std::function IoHelper::_fileSize = @@ -73,6 +75,8 @@ IoError IoHelper::stdError2ioError(int error) noexcept { return IoError::DiskFull; case static_cast(std::errc::permission_denied): return IoError::AccessDenied; + case static_cast(std::errc::cross_device_link): + return IoError::CrossDeviceLink; default: return IoError::Unknown; } @@ -150,6 +154,16 @@ std::string IoHelper::ioError2StdString(IoError ioError) noexcept { } } +void IoHelper::resetStdFunctions() { + _isDirectory = static_cast(&std::filesystem::is_directory); + _isSymlink = static_cast(&std::filesystem::is_symlink); + _rename = static_cast( + std::filesystem::rename); + _readSymlink = static_cast(&std::filesystem::read_symlink); + _fileSize = static_cast(&std::filesystem::file_size); + _tempDirectoryPath = static_cast(&std::filesystem::temp_directory_path); +} + bool IoHelper::openFile(const SyncPath &path, std::ifstream &file, IoError &ioError, int timeOut /*in seconds*/) { int count = 0; if (file.is_open()) file.close(); @@ -172,7 +186,7 @@ bool IoHelper::openFile(const SyncPath &path, std::ifstream &file, IoError &ioEr } LOGW_DEBUG(logger(), L"File is locked, retrying in one second " << Utility::formatSyncPath(path)); - if(count < timeOut) Utility::msleep(1000); + if (count < timeOut) Utility::msleep(1000); } } while (++count < timeOut && !file.is_open()); @@ -843,7 +857,7 @@ bool IoHelper::moveItem(const SyncPath &sourcePath, const SyncPath &destinationP bool IoHelper::renameItem(const SyncPath &sourcePath, const SyncPath &destinationPath, IoError &ioError) noexcept { std::error_code ec; - std::filesystem::rename(sourcePath, destinationPath, ec); + _rename(sourcePath, destinationPath, ec); ioError = stdError2ioError(ec); return ioError == IoError::Success; } diff --git a/src/libcommonserver/io/iohelper.h b/src/libcommonserver/io/iohelper.h index 4f06a0f5e..a44643838 100644 --- a/src/libcommonserver/io/iohelper.h +++ b/src/libcommonserver/io/iohelper.h @@ -404,10 +404,11 @@ struct IoHelper { // They can be modified in tests. static std::function _isDirectory; static std::function _isSymlink; + static std::function _rename; static std::function _readSymlink; static std::function _fileSize; static std::function _tempDirectoryPath; - + static void resetStdFunctions(); #ifdef __APPLE__ // Can be modified in tests. static std::function _readAlias; diff --git a/src/libcommonserver/io/iohelper_win.cpp b/src/libcommonserver/io/iohelper_win.cpp index a87d2c1f2..7afc8ccfd 100644 --- a/src/libcommonserver/io/iohelper_win.cpp +++ b/src/libcommonserver/io/iohelper_win.cpp @@ -68,6 +68,8 @@ IoError dWordError2ioError(DWORD error, log4cplus::Logger logger) noexcept { case ERROR_PATH_NOT_FOUND: case ERROR_INVALID_NAME: return IoError::NoSuchFileOrDirectory; + case ERROR_NOT_SAME_DEVICE: + return IoError::CrossDeviceLink; default: if (Log::isSet()) { LOG_WARN(logger, "Unhandled DWORD error - error=" << error); diff --git a/src/libsyncengine/jobs/network/API_v2/downloadjob.cpp b/src/libsyncengine/jobs/network/API_v2/downloadjob.cpp index 5ec72840c..49d3e7b98 100644 --- a/src/libsyncengine/jobs/network/API_v2/downloadjob.cpp +++ b/src/libsyncengine/jobs/network/API_v2/downloadjob.cpp @@ -513,12 +513,16 @@ bool DownloadJob::moveTmpFile(const SyncPath &tmpPath, bool &restartSync) { while (retry) { retry = false; #endif - std::filesystem::rename(tmpPath, _localpath, ec); -#ifdef _WIN32 - const bool crossDeviceLink = ec.value() == ERROR_NOT_SAME_DEVICE; -#else - const bool crossDeviceLink = ec.value() == (int) std::errc::cross_device_link; -#endif + + IoError ioError = IoError::Success; + IoHelper::moveItem(tmpPath, _localpath, ioError); + const bool crossDeviceLink = ioError == IoError::CrossDeviceLink; + if (ioError != IoError::Success && !crossDeviceLink) { + LOGW_WARN(_logger, L"Failed to move: " << Utility::formatIoError(tmpPath, ioError) << L" to " + << Utility::formatSyncPath(_localpath)); + return false; + } + if (crossDeviceLink) { // The sync might be on a different file system than tmp folder. // In that case, try to copy the file instead. diff --git a/test/libsyncengine/jobs/network/testnetworkjobs.cpp b/test/libsyncengine/jobs/network/testnetworkjobs.cpp index 807f5636e..fa0760c43 100644 --- a/test/libsyncengine/jobs/network/testnetworkjobs.cpp +++ b/test/libsyncengine/jobs/network/testnetworkjobs.cpp @@ -130,8 +130,10 @@ void TestNetworkJobs::tearDown() { ParmsDb::instance()->close(); ParmsDb::reset(); + MockIoHelperTestNetworkJobs::resetStdFunctions(); } + void TestNetworkJobs::testCreateDir() { const RemoteTemporaryDirectory remoteTmpDir(_driveDbId, _remoteDirId, "testCreateDir"); @@ -260,34 +262,74 @@ void TestNetworkJobs::testDelete() { } void TestNetworkJobs::testDownload() { - const LocalTemporaryDirectory temporaryDirectory("testDownload"); - SyncPath localDestFilePath = temporaryDirectory.path() / "test_file.txt"; - DownloadJob job(_driveDbId, testFileRemoteId, localDestFilePath, 0, 0, 0, false); - const ExitCode exitCode = job.runSynchronously(); - CPPUNIT_ASSERT(exitCode == ExitCode::Ok); - - CPPUNIT_ASSERT(std::filesystem::exists(localDestFilePath)); + { + const LocalTemporaryDirectory temporaryDirectory("testDownload"); + SyncPath localDestFilePath = temporaryDirectory.path() / "test_file.txt"; + DownloadJob job(_driveDbId, testFileRemoteId, localDestFilePath, 0, 0, 0, false); + const ExitCode exitCode = job.runSynchronously(); + CPPUNIT_ASSERT(exitCode == ExitCode::Ok); + + CPPUNIT_ASSERT(std::filesystem::exists(localDestFilePath)); + + // Check file content + std::ifstream ifs(localDestFilePath.string().c_str()); + std::string content((std::istreambuf_iterator(ifs)), (std::istreambuf_iterator())); + CPPUNIT_ASSERT(content == "test"); + } - // Check file content - std::ifstream ifs(localDestFilePath.string().c_str()); - std::string content((std::istreambuf_iterator(ifs)), (std::istreambuf_iterator())); - CPPUNIT_ASSERT(content == "test"); + // Cross Device Link + { + const LocalTemporaryDirectory tmpdirectory("testDownloadCrossDeviceLnk_TMP"); + const LocalTemporaryDirectory destDirectory("testDownloadCrossDeviceLnk_TMP"); + SyncPath localDestFilePath = destDirectory.path() / bigFileName; + + std::function MockTempDirectoryPath = [&tmpdirectory](std::error_code &ec) { + ec.clear(); + return tmpdirectory.path(); + }; + std::function MockRename = + [](const SyncPath &srcPath, const SyncPath &destPath, std::error_code &ec) { +#ifdef _WIN32 + ec = std::make_error_code(static_cast(ERROR_NOT_SAME_DEVICE)); +#else + ec = std::make_error_code(std::errc::cross_device_link); +#endif + }; + MockIoHelperTestNetworkJobs::setStdRename(MockRename); + MockIoHelperTestNetworkJobs::setStdTempDirectoryPath(MockTempDirectoryPath); + + DownloadJob job(_driveDbId, testFileRemoteId, localDestFilePath, 0, 0, 0, false); + const ExitCode exitCode = job.runSynchronously(); + CPPUNIT_ASSERT(exitCode == ExitCode::Ok); + + CPPUNIT_ASSERT(std::filesystem::exists(localDestFilePath)); + + // Check that the tmp file has been deleted + CPPUNIT_ASSERT(std::filesystem::is_empty(tmpdirectory.path())); + + // Check file content + std::ifstream ifs(localDestFilePath.string().c_str()); + std::string content((std::istreambuf_iterator(ifs)), (std::istreambuf_iterator())); + CPPUNIT_ASSERT(content == "test"); + } } void TestNetworkJobs::testDownloadAborted() { - const LocalTemporaryDirectory temporaryDirectory("testDownloadAborted"); - SyncPath localDestFilePath = temporaryDirectory.path() / bigFileName; - std::shared_ptr job = - std::make_shared(_driveDbId, testBigFileRemoteId, localDestFilePath, 0, 0, 0, false); - JobManager::instance()->queueAsyncJob(job); + { + const LocalTemporaryDirectory temporaryDirectory("testDownloadAborted"); + SyncPath localDestFilePath = temporaryDirectory.path() / bigFileName; + std::shared_ptr job = + std::make_shared(_driveDbId, testBigFileRemoteId, localDestFilePath, 0, 0, 0, false); + JobManager::instance()->queueAsyncJob(job); - Utility::msleep(1000); // Wait 1sec + Utility::msleep(1000); // Wait 1sec - job->abort(); + job->abort(); - Utility::msleep(1000); // Wait 1sec + Utility::msleep(1000); // Wait 1sec - CPPUNIT_ASSERT(!std::filesystem::exists(localDestFilePath)); + CPPUNIT_ASSERT(!std::filesystem::exists(localDestFilePath)); + } } void TestNetworkJobs::testGetAvatar() { From c2171a542d710afc0316b4d1e8877b9d4f44743b Mon Sep 17 00:00:00 2001 From: Herve Eruam Date: Thu, 28 Nov 2024 12:23:46 +0100 Subject: [PATCH 161/178] Fix tests. --- src/libcommonserver/io/iohelper.cpp | 10 ------- src/libcommonserver/io/iohelper.h | 1 - .../jobs/network/testnetworkjobs.h | 26 +++++++++++++++++-- 3 files changed, 24 insertions(+), 13 deletions(-) diff --git a/src/libcommonserver/io/iohelper.cpp b/src/libcommonserver/io/iohelper.cpp index d3ebd16fd..7511a8a83 100644 --- a/src/libcommonserver/io/iohelper.cpp +++ b/src/libcommonserver/io/iohelper.cpp @@ -153,16 +153,6 @@ std::string IoHelper::ioError2StdString(IoError ioError) noexcept { } } -void IoHelper::resetStdFunctions() { - _isDirectory = static_cast(&std::filesystem::is_directory); - _isSymlink = static_cast(&std::filesystem::is_symlink); - _rename = static_cast( - std::filesystem::rename); - _readSymlink = static_cast(&std::filesystem::read_symlink); - _fileSize = static_cast(&std::filesystem::file_size); - _tempDirectoryPath = static_cast(&std::filesystem::temp_directory_path); -} - bool IoHelper::openFile(const SyncPath &path, std::ifstream &file, IoError &ioError, int timeOut /*in seconds*/) { int count = 0; if (file.is_open()) file.close(); diff --git a/src/libcommonserver/io/iohelper.h b/src/libcommonserver/io/iohelper.h index a44643838..e86c05a8d 100644 --- a/src/libcommonserver/io/iohelper.h +++ b/src/libcommonserver/io/iohelper.h @@ -408,7 +408,6 @@ struct IoHelper { static std::function _readSymlink; static std::function _fileSize; static std::function _tempDirectoryPath; - static void resetStdFunctions(); #ifdef __APPLE__ // Can be modified in tests. static std::function _readAlias; diff --git a/test/libsyncengine/jobs/network/testnetworkjobs.h b/test/libsyncengine/jobs/network/testnetworkjobs.h index d5b2c60ca..51e0a027c 100644 --- a/test/libsyncengine/jobs/network/testnetworkjobs.h +++ b/test/libsyncengine/jobs/network/testnetworkjobs.h @@ -20,13 +20,35 @@ #include "testincludes.h" #include "utility/types.h" +#include "libcommonserver/io/iohelper.h" using namespace CppUnit; namespace KDC { +class MockIoHelperTestNetworkJobs : public IoHelper { + public: + static void setStdRename(std::function rename) { + IoHelper::_rename = rename; + } + static void setStdTempDirectoryPath(std::function tempDirectoryPath) { + IoHelper::_tempDirectoryPath = tempDirectoryPath; + } + static void resetStdFunctions() { + _isDirectory = static_cast(&std::filesystem::is_directory); + _isSymlink = static_cast(&std::filesystem::is_symlink); + _rename = static_cast( + std::filesystem::rename); + _readSymlink = static_cast(&std::filesystem::read_symlink); + _fileSize = static_cast(&std::filesystem::file_size); + _tempDirectoryPath = static_cast(&std::filesystem::temp_directory_path); + } +}; + class TestNetworkJobs : public CppUnit::TestFixture { public: CPPUNIT_TEST_SUITE(TestNetworkJobs); - CPPUNIT_TEST(testCreateDir); + CPPUNIT_TEST(testDownload); + + /* CPPUNIT_TEST(testCreateDir); CPPUNIT_TEST(testCopyToDir); CPPUNIT_TEST(testDelete); CPPUNIT_TEST(testDownload); @@ -56,7 +78,7 @@ class TestNetworkJobs : public CppUnit::TestFixture { CPPUNIT_TEST(testDriveUploadSessionSynchronousAborted); CPPUNIT_TEST(testDriveUploadSessionAsynchronousAborted); CPPUNIT_TEST(testGetAppVersionInfo); - CPPUNIT_TEST(testDirectDownload); + CPPUNIT_TEST(testDirectDownload);*/ CPPUNIT_TEST_SUITE_END(); public: From 2910144628f2b86b268e821e4c261b713a0304ed Mon Sep 17 00:00:00 2001 From: Herve Eruam Date: Thu, 28 Nov 2024 12:26:28 +0100 Subject: [PATCH 162/178] Re enable network tests. --- test/libsyncengine/jobs/network/testnetworkjobs.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/test/libsyncengine/jobs/network/testnetworkjobs.h b/test/libsyncengine/jobs/network/testnetworkjobs.h index 51e0a027c..13bf34837 100644 --- a/test/libsyncengine/jobs/network/testnetworkjobs.h +++ b/test/libsyncengine/jobs/network/testnetworkjobs.h @@ -46,9 +46,7 @@ class MockIoHelperTestNetworkJobs : public IoHelper { class TestNetworkJobs : public CppUnit::TestFixture { public: CPPUNIT_TEST_SUITE(TestNetworkJobs); - CPPUNIT_TEST(testDownload); - - /* CPPUNIT_TEST(testCreateDir); + CPPUNIT_TEST(testCreateDir); CPPUNIT_TEST(testCopyToDir); CPPUNIT_TEST(testDelete); CPPUNIT_TEST(testDownload); @@ -78,7 +76,7 @@ class TestNetworkJobs : public CppUnit::TestFixture { CPPUNIT_TEST(testDriveUploadSessionSynchronousAborted); CPPUNIT_TEST(testDriveUploadSessionAsynchronousAborted); CPPUNIT_TEST(testGetAppVersionInfo); - CPPUNIT_TEST(testDirectDownload);*/ + CPPUNIT_TEST(testDirectDownload); CPPUNIT_TEST_SUITE_END(); public: From 6483daf62ac281fc987f967c3b41168ff8ad7a66 Mon Sep 17 00:00:00 2001 From: Herve Eruam Date: Thu, 28 Nov 2024 12:27:39 +0100 Subject: [PATCH 163/178] Remove useless block. --- .../jobs/network/testnetworkjobs.cpp | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/test/libsyncengine/jobs/network/testnetworkjobs.cpp b/test/libsyncengine/jobs/network/testnetworkjobs.cpp index fa0760c43..d60aac850 100644 --- a/test/libsyncengine/jobs/network/testnetworkjobs.cpp +++ b/test/libsyncengine/jobs/network/testnetworkjobs.cpp @@ -315,21 +315,19 @@ void TestNetworkJobs::testDownload() { } void TestNetworkJobs::testDownloadAborted() { - { - const LocalTemporaryDirectory temporaryDirectory("testDownloadAborted"); - SyncPath localDestFilePath = temporaryDirectory.path() / bigFileName; - std::shared_ptr job = - std::make_shared(_driveDbId, testBigFileRemoteId, localDestFilePath, 0, 0, 0, false); - JobManager::instance()->queueAsyncJob(job); + const LocalTemporaryDirectory temporaryDirectory("testDownloadAborted"); + SyncPath localDestFilePath = temporaryDirectory.path() / bigFileName; + std::shared_ptr job = + std::make_shared(_driveDbId, testBigFileRemoteId, localDestFilePath, 0, 0, 0, false); + JobManager::instance()->queueAsyncJob(job); - Utility::msleep(1000); // Wait 1sec + Utility::msleep(1000); // Wait 1sec - job->abort(); + job->abort(); - Utility::msleep(1000); // Wait 1sec + Utility::msleep(1000); // Wait 1sec - CPPUNIT_ASSERT(!std::filesystem::exists(localDestFilePath)); - } + CPPUNIT_ASSERT(!std::filesystem::exists(localDestFilePath)); } void TestNetworkJobs::testGetAvatar() { From 92f1f9fd7e0eea42de0edce381aaab6466e079db Mon Sep 17 00:00:00 2001 From: Christophe Larchier Date: Fri, 29 Nov 2024 10:14:26 +0100 Subject: [PATCH 164/178] New function added to remove xattrs --- src/libcommonserver/io/iohelper.h | 15 ++++ src/libcommonserver/io/iohelper_mac.cpp | 39 ++++++++- test/libcommonserver/CMakeLists.txt | 2 +- test/libcommonserver/io/testio.h | 2 + test/libcommonserver/io/testremovexattr.cpp | 92 +++++++++++++++++++++ 5 files changed, 147 insertions(+), 3 deletions(-) create mode 100644 test/libcommonserver/io/testremovexattr.cpp diff --git a/src/libcommonserver/io/iohelper.h b/src/libcommonserver/io/iohelper.h index 4f06a0f5e..6721183b1 100644 --- a/src/libcommonserver/io/iohelper.h +++ b/src/libcommonserver/io/iohelper.h @@ -333,6 +333,21 @@ struct IoHelper { */ static bool setXAttrValue(const SyncPath &path, const std::string &attrName, const std::string &value, IoError &ioError) noexcept; + //! Remove the extended attribute with specified name for the item indicated by path. + /*! + \param path is the file system path of the item. + \param attrNames is a vector of the names of the extended attribute to remove. + \param ioError holds the error returned when an underlying OS API call fails. + \return true if no unexpected error occurred, false otherwise. + */ + static bool removeXAttrs(const SyncPath &path, const std::vector &attrNames, IoError &ioError) noexcept; + //! Remove LiteSync extended attribute for the item indicated by path. + /*! + \param path is the file system path of the item. + \param ioError holds the error returned when an underlying OS API call fails. + \return true if no unexpected error occurred, false otherwise. + */ + static bool removeLiteSyncXAttrs(const SyncPath &path, IoError &ioError) noexcept; #endif #ifdef _WIN32 diff --git a/src/libcommonserver/io/iohelper_mac.cpp b/src/libcommonserver/io/iohelper_mac.cpp index 84a37a9ce..a05710cb3 100644 --- a/src/libcommonserver/io/iohelper_mac.cpp +++ b/src/libcommonserver/io/iohelper_mac.cpp @@ -30,6 +30,10 @@ namespace KDC { +static const std::string EXT_ATTR_STATUS = "com.infomaniak.drive.desktopclient.litesync.status"; +static const std::string EXT_ATTR_PIN_STATE = "com.infomaniak.drive.desktopclient.litesync.pinstate"; + + namespace { inline bool _isXAttrValueExpectedError(IoError error) { return (error == IoError::NoSuchFileOrDirectory) || (error == IoError::AttrNotFound) || (error == IoError::AccessDenied); @@ -105,12 +109,43 @@ bool IoHelper::setXAttrValue(const SyncPath &path, const std::string &attrName, return true; } +bool IoHelper::removeXAttrs(const SyncPath &path, const std::vector &attrNames, IoError &ioError) noexcept { + ItemType itemType; + if (!getItemType(path, itemType)) { + LOGW_WARN(logger(), L"Error in IoHelper::getItemType for " << Utility::formatIoError(path, itemType.ioError).c_str()); + ioError = itemType.ioError; + return false; + } + + // The item indicated by `path` doesn't exist. + if (itemType.linkType == LinkType::None && itemType.ioError == IoError::NoSuchFileOrDirectory) { + ioError = IoError::NoSuchFileOrDirectory; + return true; + } + + const bool isSymlink = itemType.linkType == LinkType::Symlink; + + for (const auto &attrName: attrNames) { + if (removexattr(path.native().c_str(), attrName.c_str(), isSymlink ? XATTR_NOFOLLOW : 0) == -1) { + ioError = posixError2ioError(errno); + return _isXAttrValueExpectedError(ioError); + } + } + + // XAttr has been removed + ioError = IoError::Success; + return true; +} + +bool IoHelper::removeLiteSyncXAttrs(const SyncPath &path, IoError &ioError) noexcept { + const std::vector liteSyncAttrName = {EXT_ATTR_STATUS, EXT_ATTR_PIN_STATE}; + return removeXAttrs(path, liteSyncAttrName, ioError); +} + bool IoHelper::checkIfFileIsDehydrated(const SyncPath &itemPath, bool &isDehydrated, IoError &ioError) noexcept { isDehydrated = false; ioError = IoError::Success; - static const std::string EXT_ATTR_STATUS = "com.infomaniak.drive.desktopclient.litesync.status"; - std::string value; const bool result = IoHelper::getXAttrValue(itemPath.native(), EXT_ATTR_STATUS, value, ioError); if (!result) { diff --git a/test/libcommonserver/CMakeLists.txt b/test/libcommonserver/CMakeLists.txt index fdc2ba605..c84bd0154 100644 --- a/test/libcommonserver/CMakeLists.txt +++ b/test/libcommonserver/CMakeLists.txt @@ -23,7 +23,7 @@ set(testcommonserver_SRCS ) if (APPLE) - list(APPEND testcommonserver_SRCS io/testcreatealias.cpp io/testgetxattrvalue.cpp io/testsetxattrvalue.cpp) + list(APPEND testcommonserver_SRCS io/testcreatealias.cpp io/testgetxattrvalue.cpp io/testsetxattrvalue.cpp io/testremovexattr.cpp) endif () if (WIN32) diff --git a/test/libcommonserver/io/testio.h b/test/libcommonserver/io/testio.h index bd141792c..d9c189d2a 100644 --- a/test/libcommonserver/io/testio.h +++ b/test/libcommonserver/io/testio.h @@ -65,6 +65,7 @@ class TestIo : public CppUnit::TestFixture { #endif #if defined(__APPLE__) + CPPUNIT_TEST(testRemoveXAttr); CPPUNIT_TEST(testCreateAlias); #endif #if defined(_WIN32) @@ -103,6 +104,7 @@ class TestIo : public CppUnit::TestFixture { void testSetXAttrValue(void); #endif #if defined(__APPLE__) + void testRemoveXAttr(void); void testCreateAlias(void); #elif defined(_WIN32) void testCreateJunction(void); diff --git a/test/libcommonserver/io/testremovexattr.cpp b/test/libcommonserver/io/testremovexattr.cpp new file mode 100644 index 000000000..46efd9947 --- /dev/null +++ b/test/libcommonserver/io/testremovexattr.cpp @@ -0,0 +1,92 @@ +/* + * Infomaniak kDrive - Desktop + * Copyright (C) 2023-2024 Infomaniak Network SA + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "testio.h" + +#include + +#ifdef _WIN32 +#include +#endif + +using namespace CppUnit; + +namespace KDC { + +void TestIo::testRemoveXAttr() { + // A regular file + { + const LocalTemporaryDirectory temporaryDirectory; + const SyncPath path = temporaryDirectory.path() / "file.txt"; + { + std::ofstream ofs(path); + ofs << "Some content.\n"; + ofs.close(); + } + + IoError ioError = IoError::Success; + CPPUNIT_ASSERT(_testObj->setXAttrValue(path, "status1", "to-be-deleted", ioError)); + CPPUNIT_ASSERT(ioError == IoError::Success); + + CPPUNIT_ASSERT(_testObj->setXAttrValue(path, "status2", "to-be-deleted", ioError)); + CPPUNIT_ASSERT(ioError == IoError::Success); + + CPPUNIT_ASSERT(_testObj->removeXAttrs(path, {"status1", "status2"}, ioError)); + CPPUNIT_ASSERT(ioError == IoError::Success); + + std::string value; + CPPUNIT_ASSERT(_testObj->getXAttrValue(path, "status1", value, ioError)); + CPPUNIT_ASSERT(ioError == IoError::AttrNotFound); + CPPUNIT_ASSERT(value.empty()); + + CPPUNIT_ASSERT(_testObj->getXAttrValue(path, "status2", value, ioError)); + CPPUNIT_ASSERT(ioError == IoError::AttrNotFound); + CPPUNIT_ASSERT(value.empty()); + } + + // A non-existing file + { + const SyncPath path = _localTestDirPath / "non-existing.jpg"; // This file does not exist. + IoError ioError = IoError::Success; + CPPUNIT_ASSERT(_testObj->removeXAttrs(path, {"status"}, ioError)); + CPPUNIT_ASSERT(ioError == IoError::NoSuchFileOrDirectory); + } + + // A regular file missing owner write permission: access denied expected + { + const LocalTemporaryDirectory temporaryDirectory; + const SyncPath path = temporaryDirectory.path() / "permission_less_file.txt"; + { + std::ofstream ofs(path); + ofs << "Some content.\n"; + } + + IoError ioError = IoError::Success; + CPPUNIT_ASSERT(_testObj->setXAttrValue(path, "status", "to-be-deleted", ioError)); + CPPUNIT_ASSERT(ioError == IoError::Success); + + std::filesystem::permissions(path, std::filesystem::perms::owner_write, std::filesystem::perm_options::remove); + + CPPUNIT_ASSERT(_testObj->removeXAttrs(path, {"status"}, ioError)); + CPPUNIT_ASSERT(ioError == IoError::AccessDenied); + + std::filesystem::permissions(path, std::filesystem::perms::owner_read, std::filesystem::perm_options::add); + } +} + +} // namespace KDC From ddc658b48e6633bb171343fae13a387034b94c8a Mon Sep 17 00:00:00 2001 From: Christophe Larchier Date: Fri, 29 Nov 2024 10:16:17 +0100 Subject: [PATCH 165/178] Fix Finder Hydrate/Dehydrate menu items --- src/server/socketapi.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/server/socketapi.cpp b/src/server/socketapi.cpp index 32eee6b38..e311c20bf 100644 --- a/src/server/socketapi.cpp +++ b/src/server/socketapi.cpp @@ -1096,8 +1096,8 @@ void SocketApi::command_GET_MENU_ITEMS(const QString &argument, SocketListener * } if (isSingleFile) { - canHydrate = !isSyncing && !isHydrated; - canDehydrate = !isSyncing && isHydrated; + canHydrate = isPlaceholder && !isSyncing && !isHydrated; + canDehydrate = isPlaceholder && !isSyncing && isHydrated; } } From c9c558a25ef35c89c2ff182edbc6b706f77963f1 Mon Sep 17 00:00:00 2001 From: Christophe Larchier Date: Fri, 29 Nov 2024 10:18:21 +0100 Subject: [PATCH 166/178] macOS - Fix new files converted to placeholders to early --- src/libsyncengine/propagation/executor/executorworker.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/libsyncengine/propagation/executor/executorworker.cpp b/src/libsyncengine/propagation/executor/executorworker.cpp index 6caf2f028..2f47f4cdf 100644 --- a/src/libsyncengine/propagation/executor/executorworker.cpp +++ b/src/libsyncengine/propagation/executor/executorworker.cpp @@ -645,11 +645,14 @@ ExitInfo ExecutorWorker::generateCreateJob(SyncOpPtr syncOp, std::shared_ptraffectedNode()->name())); return exitInfo; } +#endif uint64_t filesize = 0; if (ExitInfo exitInfo = getFileSize(absoluteLocalFilePath, filesize); !exitInfo) { From 7b65216c6c88efbb86d4c5c7e5d22f18a1b297c4 Mon Sep 17 00:00:00 2001 From: Christophe Larchier Date: Fri, 29 Nov 2024 10:20:06 +0100 Subject: [PATCH 167/178] macOS - Reset xattrs of new files --- .../localfilesystemobserverworker.cpp | 222 +++++++++--------- 1 file changed, 116 insertions(+), 106 deletions(-) diff --git a/src/libsyncengine/update_detection/file_system_observer/localfilesystemobserverworker.cpp b/src/libsyncengine/update_detection/file_system_observer/localfilesystemobserverworker.cpp index 7945ec8d9..4fb8ff975 100644 --- a/src/libsyncengine/update_detection/file_system_observer/localfilesystemobserverworker.cpp +++ b/src/libsyncengine/update_detection/file_system_observer/localfilesystemobserverworker.cpp @@ -86,27 +86,44 @@ void LocalFileSystemObserverWorker::changesDetected(const std::listlocalPath(), absolutePath); + IoError ioError = IoError::Success; + bool exists = true; + #ifdef __APPLE__ - // Reset extended attributes of new items if (opTypeFromOS == OperationType::Create) { + // Clear extended attributes of new items + if (!IoHelper::removeLiteSyncXAttrs(absolutePath, ioError)) { + LOGW_SYNCPAL_WARN(_logger, + L"Error in IoHelper::removeLiteSyncXAttrs: " << Utility::formatIoError(absolutePath, ioError)); + invalidateSnapshot(); + return; + } + + if (ioError == IoError::AccessDenied) { + LOGW_SYNCPAL_DEBUG(_logger, L"Item: " << Utility::formatSyncPath(absolutePath) << L" misses search permissions!"); + sendAccessDeniedError(absolutePath); + continue; + } else if (ioError == IoError::NoSuchFileOrDirectory) { + exists = false; + } } #endif - // Check if exists with same nodeId if (opTypeFromOS == OperationType::Delete) { + // Check if exists with same nodeId NodeId prevNodeId = _snapshot->itemId(relativePath); bool existsWithSameId = false; NodeId otherNodeId; - IoError ioError = IoError::Success; + ioError = IoError::Success; if (!prevNodeId.empty()) { if (_syncPal->isTmpBlacklisted(prevNodeId, ReplicaSide::Local)) _syncPal->removeItemFromTmpBlacklist(relativePath); if (IoHelper::checkIfPathExistsWithSameNodeId(absolutePath, prevNodeId, existsWithSameId, otherNodeId, ioError) && !existsWithSameId) { if (_snapshot->removeItem(prevNodeId)) { - LOGW_SYNCPAL_DEBUG(_logger, L"Item removed from local snapshot: " - << Utility::formatSyncPath(absolutePath).c_str() << L" (" - << Utility::s2ws(prevNodeId).c_str() << L")"); + LOGW_SYNCPAL_DEBUG(_logger, L"Item removed from local snapshot: " << Utility::formatSyncPath(absolutePath) + << L" (" << Utility::s2ws(prevNodeId) + << L")"); } continue; } @@ -114,37 +131,37 @@ void LocalFileSystemObserverWorker::changesDetected(const std::listisTmpBlacklisted(nodeId, ReplicaSide::Local)) { - _syncPal->removeItemFromTmpBlacklist(relativePath); - if (opTypeFromOS == OperationType::Edit) { - NodeId itemId = _snapshot->itemId(relativePath); - if (!itemId.empty()) _snapshot->setLastModified(itemId, 0); + if (_syncPal->isTmpBlacklisted(nodeId, ReplicaSide::Local)) { + _syncPal->removeItemFromTmpBlacklist(relativePath); + if (opTypeFromOS == OperationType::Edit) { + NodeId itemId = _snapshot->itemId(relativePath); + if (!itemId.empty()) _snapshot->setLastModified(itemId, 0); + } } - } - bool isLink = false; - if (exists) { ItemType itemType; if (!IoHelper::getItemType(absolutePath, itemType)) { LOGW_SYNCPAL_WARN(_logger, @@ -170,7 +187,7 @@ void LocalFileSystemObserverWorker::changesDetected(const std::listremoveItem(itemId); - LOGW_SYNCPAL_DEBUG(_logger, L"Item removed from sync because it's hidden: " - << Utility::formatSyncPath(absolutePath).c_str()); + LOGW_SYNCPAL_DEBUG(_logger, + L"Item removed from sync because it's hidden: " << Utility::formatSyncPath(absolutePath)); } else { - LOGW_SYNCPAL_DEBUG(_logger, L"Item not processed because it's excluded: " - << Utility::formatSyncPath(absolutePath).c_str()); + LOGW_SYNCPAL_DEBUG(_logger, + L"Item not processed because it's excluded: " << Utility::formatSyncPath(absolutePath)); } if (!_syncPal->vfsExclude( absolutePath)) { // TODO : This class should never set any attribute or change anything on a file - LOGW_SYNCPAL_WARN(_logger, L"Error in vfsExclude: " << Utility::formatSyncPath(absolutePath).c_str()); + LOGW_SYNCPAL_WARN(_logger, L"Error in vfsExclude: " << Utility::formatSyncPath(absolutePath)); } continue; @@ -214,12 +231,11 @@ void LocalFileSystemObserverWorker::changesDetected(const std::listremoveItemFromTmpBlacklist(itemId, ReplicaSide::Local); if (_snapshot->removeItem(itemId)) { - LOGW_SYNCPAL_DEBUG(_logger, L"Item removed from local snapshot: " << Utility::formatSyncPath(absolutePath).c_str() - << L" (" << Utility::s2ws(itemId).c_str() - << L")"); + LOGW_SYNCPAL_DEBUG(_logger, L"Item removed from local snapshot: " << Utility::formatSyncPath(absolutePath) + << L" (" << Utility::s2ws(itemId) << L")"); } else { - LOGW_SYNCPAL_WARN(_logger, L"Fail to remove item: " << Utility::formatSyncPath(absolutePath).c_str() << L" (" - << Utility::s2ws(itemId).c_str() << L")"); + LOGW_SYNCPAL_WARN(_logger, L"Fail to remove item: " << Utility::formatSyncPath(absolutePath) << L" (" + << Utility::s2ws(itemId) << L")"); invalidateSnapshot(); return; } @@ -233,7 +249,7 @@ void LocalFileSystemObserverWorker::changesDetected(const std::list_syncDb->rootNode().nodeIdLocal(); } else { if (!IoHelper::getNodeId(parentPath, parentNodeId)) { - LOGW_SYNCPAL_WARN(_logger, L"Error in IoHelper::getNodeId for " << Utility::formatSyncPath(parentPath).c_str()); + LOGW_SYNCPAL_WARN(_logger, L"Error in IoHelper::getNodeId for " << Utility::formatSyncPath(parentPath)); continue; } } @@ -244,12 +260,11 @@ void LocalFileSystemObserverWorker::changesDetected(const std::listsize(nodeId), _snapshot->lastModified(nodeId), changed, ioError); if (!success) { - LOGW_SYNCPAL_WARN(_logger, L"Error in IoHelper::checkIfFileChanged: " - << Utility::formatIoError(absolutePath, ioError).c_str()); + LOGW_SYNCPAL_WARN(_logger, + L"Error in IoHelper::checkIfFileChanged: " << Utility::formatIoError(absolutePath, ioError)); } if (ioError == IoError::AccessDenied) { - LOGW_SYNCPAL_DEBUG(_logger, - L"Item: " << Utility::formatSyncPath(absolutePath).c_str() << L" misses search permissions!"); + LOGW_SYNCPAL_DEBUG(_logger, L"Item: " << Utility::formatSyncPath(absolutePath) << L" misses search permissions!"); sendAccessDeniedError(absolutePath); } else if (ioError == IoError::NoSuchFileOrDirectory) { continue; @@ -262,14 +277,14 @@ void LocalFileSystemObserverWorker::changesDetected(const std::listvfsStatus(absolutePath, isPlaceholder, isHydrated, isSyncing, progress)) { - LOGW_SYNCPAL_WARN(_logger, L"Error in vfsStatus: " << Utility::formatSyncPath(absolutePath).c_str()); + LOGW_SYNCPAL_WARN(_logger, L"Error in vfsStatus: " << Utility::formatSyncPath(absolutePath)); invalidateSnapshot(); return; } PinState pinstate = PinState::Unspecified; if (!_syncPal->vfsPinState(absolutePath, pinstate)) { - LOGW_SYNCPAL_WARN(_logger, L"Error in vfsPinState: " << Utility::formatSyncPath(absolutePath).c_str()); + LOGW_SYNCPAL_WARN(_logger, L"Error in vfsPinState: " << Utility::formatSyncPath(absolutePath)); invalidateSnapshot(); return; } @@ -280,7 +295,7 @@ void LocalFileSystemObserverWorker::changesDetected(const std::listvfsFileStatusChanged(absolutePath, SyncFileStatus::Syncing)) { LOGW_SYNCPAL_WARN(_logger, L"Error in SyncPal::vfsFileStatusChanged: " - << Utility::formatSyncPath(absolutePath).c_str()); + << Utility::formatSyncPath(absolutePath)); invalidateSnapshot(); return; } @@ -290,8 +305,8 @@ void LocalFileSystemObserverWorker::changesDetected(const std::listitemId(relativePath); if (_snapshot->removeItem(itemId)) { - LOGW_SYNCPAL_DEBUG(_logger, L"Item removed from local snapshot: " - << Utility::formatSyncPath(absolutePath).c_str() << L" (" - << Utility::s2ws(itemId).c_str() << L")"); + LOGW_SYNCPAL_DEBUG(_logger, L"Item removed from local snapshot: " << Utility::formatSyncPath(absolutePath) + << L" (" << Utility::s2ws(itemId) << L")"); } else { - LOGW_SYNCPAL_WARN(_logger, L"Failed to remove item: " << Utility::formatSyncPath(absolutePath).c_str() - << L" (" << Utility::s2ws(itemId).c_str() << L")"); + LOGW_SYNCPAL_WARN(_logger, L"Failed to remove item: " << Utility::formatSyncPath(absolutePath) << L" (" + << Utility::s2ws(itemId) << L")"); invalidateSnapshot(); return; } @@ -323,13 +337,12 @@ void LocalFileSystemObserverWorker::changesDetected(const std::listremoveItem(previousItemId)) { - LOGW_SYNCPAL_DEBUG(_logger, L"Item removed from local snapshot: " - << Utility::formatSyncPath(absolutePath).c_str() << L" (" - << Utility::s2ws(previousItemId).c_str() << L")"); + LOGW_SYNCPAL_DEBUG(_logger, L"Item removed from local snapshot: " << Utility::formatSyncPath(absolutePath) + << L" (" << Utility::s2ws(previousItemId) + << L")"); } else { - LOGW_SYNCPAL_WARN(_logger, L"Failed to delete item: " << Utility::formatSyncPath(absolutePath).c_str() - << L" (" << Utility::s2ws(previousItemId).c_str() - << L")"); + LOGW_SYNCPAL_WARN(_logger, L"Failed to delete item: " << Utility::formatSyncPath(absolutePath) << L" (" + << Utility::s2ws(previousItemId) << L")"); invalidateSnapshot(); return; } @@ -340,16 +353,16 @@ void LocalFileSystemObserverWorker::changesDetected(const std::listupdateItem(item)) { - LOGW_SYNCPAL_WARN(_logger, L"Failed to insert item: " << Utility::formatSyncPath(absolutePath).c_str() << L" (" - << Utility::s2ws(nodeId).c_str() << L")"); + LOGW_SYNCPAL_WARN(_logger, L"Failed to insert item: " << Utility::formatSyncPath(absolutePath) << L" (" + << Utility::s2ws(nodeId) << L")"); invalidateSnapshot(); return; } if (ParametersCache::isExtendedLogEnabled()) { - LOGW_SYNCPAL_DEBUG(_logger, L"Item inserted in local snapshot: " << Utility::formatSyncPath(absolutePath).c_str() - << L" (" << Utility::s2ws(nodeId).c_str() - << L") at " << fileStat.modtime); + LOGW_SYNCPAL_DEBUG(_logger, L"Item inserted in local snapshot: " << Utility::formatSyncPath(absolutePath) << L" (" + << Utility::s2ws(nodeId) << L") at " + << fileStat.modtime); // if (nodeType == NodeType::File) { // if (canComputeChecksum(absolutePath)) { @@ -362,8 +375,8 @@ void LocalFileSystemObserverWorker::changesDetected(const std::list CommonUtility::maxPathLength()) { - LOGW_SYNCPAL_WARN(_logger, L"Ignore item: " << Utility::formatSyncPath(absolutePath).c_str() - << L" because size > " << CommonUtility::maxPathLength()); + LOGW_SYNCPAL_WARN(_logger, L"Ignore item: " << Utility::formatSyncPath(absolutePath) << L" because size > " + << CommonUtility::maxPathLength()); continue; } @@ -401,9 +414,8 @@ void LocalFileSystemObserverWorker::changesDetected(const std::listupdateItem(SnapshotItem(nodeId, parentNodeId, absolutePath.filename().native(), fileStat.creationTime, fileStat.modtime, nodeType, fileStat.size, isLink, true, true))) { if (ParametersCache::isExtendedLogEnabled()) { - LOGW_SYNCPAL_DEBUG(_logger, L"Item: " << Utility::formatSyncPath(absolutePath).c_str() << L" (" - << Utility::s2ws(nodeId).c_str() << L") updated in local snapshot at " - << fileStat.modtime); + LOGW_SYNCPAL_DEBUG(_logger, L"Item: " << Utility::formatSyncPath(absolutePath) << L" (" << Utility::s2ws(nodeId) + << L") updated in local snapshot at " << fileStat.modtime); } if (nodeType == NodeType::File) { @@ -413,8 +425,8 @@ void LocalFileSystemObserverWorker::changesDetected(const std::listvfsStatus(absolutePath, isPlaceholder, isHydrated, isSyncing, progress)) { - LOGW_WARN(_logger, L"Error in vfsStatus: " << Utility::formatSyncPath(absolutePath).c_str()); + LOGW_WARN(_logger, L"Error in vfsStatus: " << Utility::formatSyncPath(absolutePath)); return false; } @@ -555,7 +567,7 @@ ExitCode LocalFileSystemObserverWorker::isEditValid(const NodeId &nodeId, const return ExitCode::DbError; } if (!found) { - LOGW_SYNCPAL_WARN(_logger, L"Node not found in node table for nodeId=" << Utility::s2ws(nodeId).c_str()); + LOGW_SYNCPAL_WARN(_logger, L"Node not found in node table for nodeId=" << Utility::s2ws(nodeId)); return ExitCode::DataError; } @@ -565,7 +577,7 @@ ExitCode LocalFileSystemObserverWorker::isEditValid(const NodeId &nodeId, const return ExitCode::DbError; } if (!found) { - LOGW_SYNCPAL_WARN(_logger, L"Node not found in node table: nodeId=" << Utility::s2ws(nodeId).c_str()); + LOGW_SYNCPAL_WARN(_logger, L"Node not found in node table: nodeId=" << Utility::s2ws(nodeId)); return ExitCode::DataError; } @@ -590,8 +602,7 @@ void LocalFileSystemObserverWorker::sendAccessDeniedError(const SyncPath &absolu const bool success = ExclusionTemplateCache::instance()->checkIfIsExcluded(_syncPal->localPath(), relativePath, isWarning, isExcluded, ioError); if (!success) { - LOGW_WARN(_logger, - L"Error in ExclusionTemplateCache::isExcluded: " << Utility::formatIoError(absolutePath, ioError).c_str()); + LOGW_WARN(_logger, L"Error in ExclusionTemplateCache::isExcluded: " << Utility::formatIoError(absolutePath, ioError)); return; } if (isExcluded) { @@ -607,21 +618,20 @@ ExitInfo LocalFileSystemObserverWorker::exploreDir(const SyncPath &absoluteParen ItemType itemType; if (!IoHelper::getItemType(absoluteParentDirPath, itemType)) { LOGW_WARN(_logger, - L"Error in IoHelper::getItemType: " << Utility::formatIoError(absoluteParentDirPath, itemType.ioError).c_str()); + L"Error in IoHelper::getItemType: " << Utility::formatIoError(absoluteParentDirPath, itemType.ioError)); setExitCause(ExitCause::Unknown); return ExitCode::SystemError; } if (itemType.ioError == IoError::NoSuchFileOrDirectory) { - LOGW_SYNCPAL_WARN(_logger, - L"Sync localpath: " << Utility::formatSyncPath(absoluteParentDirPath).c_str() << L" doesn't exist"); + LOGW_SYNCPAL_WARN(_logger, L"Sync localpath: " << Utility::formatSyncPath(absoluteParentDirPath) << L" doesn't exist"); setExitCause(ExitCause::SyncDirDoesntExist); return {ExitCode::SystemError, ExitCause::SyncDirDoesntExist}; } if (itemType.ioError == IoError::AccessDenied) { - LOGW_SYNCPAL_WARN(_logger, L"Sync localpath: " << Utility::formatSyncPath(absoluteParentDirPath).c_str() - << L" misses read permission"); + LOGW_SYNCPAL_WARN(_logger, + L"Sync localpath: " << Utility::formatSyncPath(absoluteParentDirPath) << L" misses read permission"); setExitCause(ExitCause::SyncDirAccesError); return {ExitCode::SystemError, ExitCause::SyncDirAccesError}; } @@ -706,13 +716,13 @@ ExitInfo LocalFileSystemObserverWorker::exploreDir(const SyncPath &absoluteParen isWarning, isExcluded, ioError); if (!success) { LOGW_SYNCPAL_DEBUG(_logger, L"Error in ExclusionTemplateCache::isExcluded: " - << Utility::formatIoError(absolutePath, ioError).c_str()); + << Utility::formatIoError(absolutePath, ioError)); dirIt.disableRecursionPending(); continue; } if (isExcluded) { - LOGW_SYNCPAL_INFO(_logger, L"Item: " << Utility::formatSyncPath(absolutePath).c_str() - << L" rejected because it's excluded"); + LOGW_SYNCPAL_INFO(_logger, + L"Item: " << Utility::formatSyncPath(absolutePath) << L" rejected because it's excluded"); toExclude = true; } } @@ -722,20 +732,20 @@ ExitInfo LocalFileSystemObserverWorker::exploreDir(const SyncPath &absoluteParen if (!toExclude) { IoError ioError = IoError::Success; if (!IoHelper::getFileStat(absolutePath, &fileStat, ioError)) { - LOGW_SYNCPAL_DEBUG(_logger, L"Error in IoHelper::getFileStat: " - << Utility::formatIoError(absolutePath, ioError).c_str()); + LOGW_SYNCPAL_DEBUG(_logger, + L"Error in IoHelper::getFileStat: " << Utility::formatIoError(absolutePath, ioError)); dirIt.disableRecursionPending(); continue; } if (ioError == IoError::NoSuchFileOrDirectory) { - LOGW_SYNCPAL_DEBUG(_logger, L"Directory entry does not exist anymore: " - << Utility::formatSyncPath(absolutePath).c_str()); + LOGW_SYNCPAL_DEBUG(_logger, + L"Directory entry does not exist anymore: " << Utility::formatSyncPath(absolutePath)); dirIt.disableRecursionPending(); continue; } else if (ioError == IoError::AccessDenied) { - LOGW_SYNCPAL_INFO(_logger, L"Item: " << Utility::formatSyncPath(absolutePath).c_str() - << L" rejected because access is denied"); + LOGW_SYNCPAL_INFO( + _logger, L"Item: " << Utility::formatSyncPath(absolutePath) << L" rejected because access is denied"); sendAccessDeniedError(absolutePath); toExclude = true; } @@ -746,7 +756,7 @@ ExitInfo LocalFileSystemObserverWorker::exploreDir(const SyncPath &absoluteParen if (!denyFullControl) { if (!_syncPal->vfsExclude( absolutePath)) { // TODO : This class should never set any attribute or change anything on a file - LOGW_SYNCPAL_WARN(_logger, L"Error in vfsExclude : " << Utility::formatSyncPath(absolutePath).c_str()); + LOGW_SYNCPAL_WARN(_logger, L"Error in vfsExclude : " << Utility::formatSyncPath(absolutePath)); } } @@ -762,20 +772,20 @@ ExitInfo LocalFileSystemObserverWorker::exploreDir(const SyncPath &absoluteParen FileStat parentFileStat; IoError ioError = IoError::Success; if (!IoHelper::getFileStat(absolutePath.parent_path(), &parentFileStat, ioError)) { - LOGW_WARN(_logger, L"Error in IoHelper::getFileStat: " - << Utility::formatIoError(absolutePath.parent_path(), ioError).c_str()); + LOGW_WARN(_logger, + L"Error in IoHelper::getFileStat: " << Utility::formatIoError(absolutePath.parent_path(), ioError)); setExitCause(ExitCause::FileAccessError); return ExitCode::SystemError; } if (ioError == IoError::NoSuchFileOrDirectory) { - LOGW_SYNCPAL_DEBUG(_logger, L"Directory doesn't exist anymore: " - << Utility::formatSyncPath(absolutePath.parent_path()).c_str()); + LOGW_SYNCPAL_DEBUG( + _logger, L"Directory doesn't exist anymore: " << Utility::formatSyncPath(absolutePath.parent_path())); dirIt.disableRecursionPending(); continue; } else if (ioError == IoError::AccessDenied) { LOGW_SYNCPAL_DEBUG(_logger, L"Directory misses search permission: " - << Utility::formatSyncPath(absolutePath.parent_path()).c_str()); + << Utility::formatSyncPath(absolutePath.parent_path())); dirIt.disableRecursionPending(); sendAccessDeniedError(absolutePath); continue; @@ -785,8 +795,8 @@ ExitInfo LocalFileSystemObserverWorker::exploreDir(const SyncPath &absoluteParen } if (!IoHelper::getItemType(absolutePath, itemType)) { - LOGW_SYNCPAL_DEBUG(_logger, L"Error in IoHelper::getItemType: " - << Utility::formatIoError(absolutePath, itemType.ioError).c_str()); + LOGW_SYNCPAL_DEBUG(_logger, + L"Error in IoHelper::getItemType: " << Utility::formatIoError(absolutePath, itemType.ioError)); dirIt.disableRecursionPending(); continue; } @@ -802,15 +812,15 @@ ExitInfo LocalFileSystemObserverWorker::exploreDir(const SyncPath &absoluteParen if (_snapshot->updateItem(item)) { if (ParametersCache::isExtendedLogEnabled()) { LOGW_SYNCPAL_DEBUG(_logger, L"Item inserted in local snapshot: " - << Utility::formatSyncPath(absolutePath.filename()).c_str() << L" inode:" - << Utility::s2ws(nodeId.c_str()) << L" parent inode:" - << Utility::s2ws(parentNodeId).c_str() << L" createdAt:" - << fileStat.creationTime << L" modtime:" << fileStat.modtime << L" isDir:" + << Utility::formatSyncPath(absolutePath.filename()) << L" inode:" + << Utility::s2ws(nodeId) << L" parent inode:" + << Utility::s2ws(parentNodeId) << L" createdAt:" << fileStat.creationTime + << L" modtime:" << fileStat.modtime << L" isDir:" << (itemType.nodeType == NodeType::Directory) << L" size:" << fileStat.size); } } else { - LOGW_SYNCPAL_WARN(_logger, L"Failed to insert item: " << Utility::formatSyncPath(absolutePath.filename()).c_str() + LOGW_SYNCPAL_WARN(_logger, L"Failed to insert item: " << Utility::formatSyncPath(absolutePath.filename()) << L" into local snapshot!!!"); } } From 3eed929ac5d7f32535c44327f5aec5af1a5433f1 Mon Sep 17 00:00:00 2001 From: Christophe Larchier Date: Fri, 29 Nov 2024 11:03:08 +0100 Subject: [PATCH 168/178] Code improvements --- src/libcommonserver/io/iohelper_mac.cpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/libcommonserver/io/iohelper_mac.cpp b/src/libcommonserver/io/iohelper_mac.cpp index a05710cb3..d8693b6d4 100644 --- a/src/libcommonserver/io/iohelper_mac.cpp +++ b/src/libcommonserver/io/iohelper_mac.cpp @@ -30,9 +30,8 @@ namespace KDC { -static const std::string EXT_ATTR_STATUS = "com.infomaniak.drive.desktopclient.litesync.status"; -static const std::string EXT_ATTR_PIN_STATE = "com.infomaniak.drive.desktopclient.litesync.pinstate"; - +static constexpr std::string_view EXT_ATTR_STATUS("com.infomaniak.drive.desktopclient.litesync.status"); +static constexpr std::string_view EXT_ATTR_PIN_STATE("com.infomaniak.drive.desktopclient.litesync.pinstate"); namespace { inline bool _isXAttrValueExpectedError(IoError error) { @@ -44,7 +43,7 @@ bool IoHelper::getXAttrValue(const SyncPath &path, const std::string &attrName, value = ""; ItemType itemType; if (!getItemType(path, itemType)) { - LOGW_WARN(logger(), L"Error in IoHelper::getItemType for " << Utility::formatIoError(path, itemType.ioError).c_str()); + LOGW_WARN(logger(), L"Error in IoHelper::getItemType for " << Utility::formatIoError(path, itemType.ioError)); ioError = itemType.ioError; return false; } @@ -86,7 +85,7 @@ bool IoHelper::setXAttrValue(const SyncPath &path, const std::string &attrName, IoError &ioError) noexcept { ItemType itemType; if (!getItemType(path, itemType)) { - LOGW_WARN(logger(), L"Error in IoHelper::getItemType for " << Utility::formatIoError(path, itemType.ioError).c_str()); + LOGW_WARN(logger(), L"Error in IoHelper::getItemType for " << Utility::formatIoError(path, itemType.ioError)); ioError = itemType.ioError; return false; } @@ -112,7 +111,7 @@ bool IoHelper::setXAttrValue(const SyncPath &path, const std::string &attrName, bool IoHelper::removeXAttrs(const SyncPath &path, const std::vector &attrNames, IoError &ioError) noexcept { ItemType itemType; if (!getItemType(path, itemType)) { - LOGW_WARN(logger(), L"Error in IoHelper::getItemType for " << Utility::formatIoError(path, itemType.ioError).c_str()); + LOGW_WARN(logger(), L"Error in IoHelper::getItemType for " << Utility::formatIoError(path, itemType.ioError)); ioError = itemType.ioError; return false; } @@ -138,7 +137,7 @@ bool IoHelper::removeXAttrs(const SyncPath &path, const std::vector } bool IoHelper::removeLiteSyncXAttrs(const SyncPath &path, IoError &ioError) noexcept { - const std::vector liteSyncAttrName = {EXT_ATTR_STATUS, EXT_ATTR_PIN_STATE}; + const std::vector liteSyncAttrName = {std::string(EXT_ATTR_STATUS), std::string(EXT_ATTR_PIN_STATE)}; return removeXAttrs(path, liteSyncAttrName, ioError); } @@ -147,7 +146,7 @@ bool IoHelper::checkIfFileIsDehydrated(const SyncPath &itemPath, bool &isDehydra ioError = IoError::Success; std::string value; - const bool result = IoHelper::getXAttrValue(itemPath.native(), EXT_ATTR_STATUS, value, ioError); + const bool result = IoHelper::getXAttrValue(itemPath.native(), std::string(EXT_ATTR_STATUS), value, ioError); if (!result) { return false; } From 12c59d9555ca1ddf1711e1e7fb5a2df63887992c Mon Sep 17 00:00:00 2001 From: Christophe Larchier Date: Mon, 2 Dec 2024 09:41:48 +0100 Subject: [PATCH 169/178] Fix crash --- src/libcommonserver/utility/utility.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/libcommonserver/utility/utility.cpp b/src/libcommonserver/utility/utility.cpp index 98ffda46a..688248eeb 100644 --- a/src/libcommonserver/utility/utility.cpp +++ b/src/libcommonserver/utility/utility.cpp @@ -400,12 +400,12 @@ bool Utility::isEqualInsensitive(const SyncName &a, const SyncName &b) { bool Utility::checkIfSameNormalization(const SyncName &a, const SyncName &b, bool &areSame) { SyncName aNormalized; if (!Utility::normalizedSyncName(a, aNormalized)) { - LOGW_WARN(_logger, L"Error in Utility::normalizedSyncName: " << Utility::formatSyncName(a)); + LOGW_WARN(logger(), L"Error in Utility::normalizedSyncName: " << Utility::formatSyncName(a)); return false; } SyncName bNormalized; if (!Utility::normalizedSyncName(b, bNormalized)) { - LOGW_WARN(_logger, L"Error in Utility::normalizedSyncName: " << Utility::formatSyncName(b)); + LOGW_WARN(logger(), L"Error in Utility::normalizedSyncName: " << Utility::formatSyncName(b)); return false; } areSame = (aNormalized == bNormalized); @@ -415,12 +415,12 @@ bool Utility::checkIfSameNormalization(const SyncName &a, const SyncName &b, boo bool Utility::checkIfSameNormalization(const SyncPath &a, const SyncPath &b, bool &areSame) { SyncPath aNormalized; if (!Utility::normalizedSyncPath(a, aNormalized)) { - LOGW_WARN(_logger, L"Error in Utility::normalizedSyncPath: " << Utility::formatSyncPath(a)); + LOGW_WARN(logger(), L"Error in Utility::normalizedSyncPath: " << Utility::formatSyncPath(a)); return false; } SyncPath bNormalized; if (!Utility::normalizedSyncPath(b, bNormalized)) { - LOGW_WARN(_logger, L"Error in Utility::normalizedSyncPath: " << Utility::formatSyncPath(b)); + LOGW_WARN(logger(), L"Error in Utility::normalizedSyncPath: " << Utility::formatSyncPath(b)); return false; } areSame = (aNormalized == bNormalized); @@ -697,7 +697,7 @@ bool Utility::normalizedSyncPath(const SyncPath &path, SyncPath &normalizedPath) if (segmentIt->lexically_normal() != SyncPath(Str("/")).lexically_normal()) { SyncName normalizedName; if (!Utility::normalizedSyncName(segment, normalizedName)) { - LOGW_WARN(_logger, L"Error in Utility::normalizedSyncName: " << Utility::formatSyncName(segment)); + LOGW_WARN(logger(), L"Error in Utility::normalizedSyncName: " << Utility::formatSyncName(segment)); return false; } segment = normalizedName; @@ -709,7 +709,7 @@ bool Utility::normalizedSyncPath(const SyncPath &path, SyncPath &normalizedPath) if (segmentIt->lexically_normal() != SyncPath(Str("/")).lexically_normal()) { SyncName normalizedName; if (!Utility::normalizedSyncName(*segmentIt, normalizedName)) { - LOGW_WARN(_logger, L"Error in Utility::normalizedSyncName: " << Utility::formatSyncName(*segmentIt)); + LOGW_WARN(logger(), L"Error in Utility::normalizedSyncName: " << Utility::formatSyncName(*segmentIt)); return false; } normalizedPath /= normalizedName; From 21d68d0e4eb9f8c06616b0ae716ab9ae19326532 Mon Sep 17 00:00:00 2001 From: Christophe Larchier Date: Mon, 2 Dec 2024 09:53:13 +0100 Subject: [PATCH 170/178] Address comment --- .../file_system_observer/folderwatcher_mac.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libsyncengine/update_detection/file_system_observer/folderwatcher_mac.cpp b/src/libsyncengine/update_detection/file_system_observer/folderwatcher_mac.cpp index eed0c6fc3..803d74010 100644 --- a/src/libsyncengine/update_detection/file_system_observer/folderwatcher_mac.cpp +++ b/src/libsyncengine/update_detection/file_system_observer/folderwatcher_mac.cpp @@ -90,7 +90,7 @@ static void callback([[maybe_unused]] ConstFSEventStreamRef streamRef, void *cli } void FolderWatcher_mac::startWatching() { - LOGW_DEBUG(_logger, L"Start watching folder: " << Path2WStr(_folder).c_str()); + LOGW_DEBUG(_logger, L"Start watching folder: " << Path2WStr(_folder)); LOG_DEBUG(_logger, "File system format: " << Utility::fileSystemName(_folder).c_str()); CFStringRef path = CFStringCreateWithCString(nullptr, _folder.c_str(), kCFStringEncodingUTF8); @@ -109,7 +109,7 @@ void FolderWatcher_mac::startWatching() { FSEventStreamStart(_stream); CFRunLoopRun(); - LOGW_DEBUG(_logger, L"Folder watching stopped: " << _folder.wstring().c_str()); + LOGW_DEBUG(_logger, L"Folder watching stopped: " << Utility::formatSyncPath(_folder)); } void FolderWatcher_mac::doNotifyParent(const std::list> &changes) { @@ -135,7 +135,7 @@ OperationType FolderWatcher_mac::getOpType(const FSEventStreamEventFlags eventFl void KDC::FolderWatcher_mac::stopWatching() { if (_stream) { - LOGW_DEBUG(_logger, L"Stop watching folder: " << Path2WStr(_folder).c_str()); + LOGW_DEBUG(_logger, L"Stop watching folder: " << Path2WStr(_folder)); FSEventStreamStop(_stream); FSEventStreamInvalidate(_stream); FSEventStreamRelease(_stream); From ade4d5f6933a7372cd1a48d29f2d93349dc99e2c Mon Sep 17 00:00:00 2001 From: Herve Eruam <82284536+herve-er@users.noreply.github.com> Date: Mon, 2 Dec 2024 10:24:00 +0100 Subject: [PATCH 171/178] Update src/libsyncengine/syncpal/syncpal.cpp Co-authored-by: Luc Guyot <162997198+luc-guyot-infomaniak@users.noreply.github.com> --- src/libsyncengine/syncpal/syncpal.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libsyncengine/syncpal/syncpal.cpp b/src/libsyncengine/syncpal/syncpal.cpp index 7e6df0a57..f5961191c 100644 --- a/src/libsyncengine/syncpal/syncpal.cpp +++ b/src/libsyncengine/syncpal/syncpal.cpp @@ -1480,7 +1480,7 @@ ExitInfo SyncPal::handleAccessDeniedItem(const SyncPath &relativePath, ExitCause LOGW_SYNCPAL_DEBUG(_logger, L"Item " << Utility::formatSyncPath(relativePath) << L" (NodeId: " << Utility::s2ws(localNodeId) << L" is blacklisted temporarily because of a denied access."); - NodeId remoteNodeId; + NodeId remoteNodeId = snapshot(ReplicaSide::Remote)->itemId(relativePath); remoteNodeId = snapshot(ReplicaSide::Remote)->itemId(relativePath); if (bool found; remoteNodeId.empty() && !localNodeId.empty() && !_syncDb->correspondingNodeId(ReplicaSide::Local, localNodeId, remoteNodeId, found)) { From b969fedf34098cb7b9c797df1067c17002473a8c Mon Sep 17 00:00:00 2001 From: Christophe Larchier Date: Mon, 2 Dec 2024 10:55:21 +0100 Subject: [PATCH 172/178] Fix Linux build --- .../file_system_observer/folderwatcher_linux.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/libsyncengine/update_detection/file_system_observer/folderwatcher_linux.cpp b/src/libsyncengine/update_detection/file_system_observer/folderwatcher_linux.cpp index 43f1480f0..8ae2d121b 100644 --- a/src/libsyncengine/update_detection/file_system_observer/folderwatcher_linux.cpp +++ b/src/libsyncengine/update_detection/file_system_observer/folderwatcher_linux.cpp @@ -37,6 +37,11 @@ namespace KDC { FolderWatcher_linux::FolderWatcher_linux(LocalFileSystemObserverWorker *parent, const SyncPath &path) : FolderWatcher(parent, path) {} +SyncPath FolderWatcher_linux::makeSyncPath(const SyncPath &watchedFolderPath, const char *fileName) { + const auto syncName = SyncName(fileName); + return syncName.empty() ? watchedFolderPath : watchedFolderPath / syncName; +} + void FolderWatcher_linux::startWatching() { LOG4CPLUS_DEBUG(_logger, L"Start watching folder " << Utility::formatSyncPath(_folder)); LOG4CPLUS_DEBUG(_logger, "File system format: " << Utility::fileSystemName(_folder).c_str()); From b9a414721ac6d3b06eae0fac9521154893a74286 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Kunz?= Date: Tue, 3 Dec 2024 08:56:37 +0100 Subject: [PATCH 173/178] KDESKTOP-1377 - return in case of error --- src/server/updater/abstractupdater.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/server/updater/abstractupdater.cpp b/src/server/updater/abstractupdater.cpp index addd13c2f..4d0bb2112 100644 --- a/src/server/updater/abstractupdater.cpp +++ b/src/server/updater/abstractupdater.cpp @@ -46,6 +46,7 @@ void AbstractUpdater::onAppVersionReceived() { if (!_updateChecker->versionInfo().isValid()) { setState(UpdateState::CheckError); LOG_WARN(Log::instance()->getLogger(), "Error while retrieving latest app version"); + return; } const bool available = From fe6a0fe1634838f0b18cacb1de9e8e71b607b19e Mon Sep 17 00:00:00 2001 From: Christophe Larchier Date: Tue, 3 Dec 2024 10:25:33 +0100 Subject: [PATCH 174/178] Address comments --- src/libcommonserver/io/iohelper_mac.cpp | 17 +------ test/libcommonserver/io/testremovexattr.cpp | 55 +++++++++++++++++++++ 2 files changed, 56 insertions(+), 16 deletions(-) diff --git a/src/libcommonserver/io/iohelper_mac.cpp b/src/libcommonserver/io/iohelper_mac.cpp index d8693b6d4..b93c1bac7 100644 --- a/src/libcommonserver/io/iohelper_mac.cpp +++ b/src/libcommonserver/io/iohelper_mac.cpp @@ -109,23 +109,8 @@ bool IoHelper::setXAttrValue(const SyncPath &path, const std::string &attrName, } bool IoHelper::removeXAttrs(const SyncPath &path, const std::vector &attrNames, IoError &ioError) noexcept { - ItemType itemType; - if (!getItemType(path, itemType)) { - LOGW_WARN(logger(), L"Error in IoHelper::getItemType for " << Utility::formatIoError(path, itemType.ioError)); - ioError = itemType.ioError; - return false; - } - - // The item indicated by `path` doesn't exist. - if (itemType.linkType == LinkType::None && itemType.ioError == IoError::NoSuchFileOrDirectory) { - ioError = IoError::NoSuchFileOrDirectory; - return true; - } - - const bool isSymlink = itemType.linkType == LinkType::Symlink; - for (const auto &attrName: attrNames) { - if (removexattr(path.native().c_str(), attrName.c_str(), isSymlink ? XATTR_NOFOLLOW : 0) == -1) { + if (removexattr(path.native().c_str(), attrName.c_str(), XATTR_NOFOLLOW) == -1) { ioError = posixError2ioError(errno); return _isXAttrValueExpectedError(ioError); } diff --git a/test/libcommonserver/io/testremovexattr.cpp b/test/libcommonserver/io/testremovexattr.cpp index 46efd9947..582ff1e49 100644 --- a/test/libcommonserver/io/testremovexattr.cpp +++ b/test/libcommonserver/io/testremovexattr.cpp @@ -59,6 +59,61 @@ void TestIo::testRemoveXAttr() { CPPUNIT_ASSERT(value.empty()); } + // A symlink + { + const LocalTemporaryDirectory temporaryDirectory; + const SyncPath targetPath = temporaryDirectory.path() / "file.txt"; + { + std::ofstream ofs(targetPath); + ofs << "Some content.\n"; + ofs.close(); + } + + const SyncPath linkPath = temporaryDirectory.path() / "link.txt"; + std::error_code ec; + std::filesystem::create_symlink(targetPath, linkPath, ec); + CPPUNIT_ASSERT(!ec); + + IoError ioError = IoError::Success; + CPPUNIT_ASSERT(_testObj->setXAttrValue(linkPath, "link-status", "to-be-deleted", ioError)); + CPPUNIT_ASSERT(ioError == IoError::Success); + + CPPUNIT_ASSERT(_testObj->removeXAttrs(linkPath, {"link-status"}, ioError)); + CPPUNIT_ASSERT(ioError == IoError::Success); + + std::string value; + CPPUNIT_ASSERT(_testObj->getXAttrValue(linkPath, "link-status", value, ioError)); + CPPUNIT_ASSERT(ioError == IoError::AttrNotFound); + CPPUNIT_ASSERT(value.empty()); + } + + // An alias + { + const LocalTemporaryDirectory temporaryDirectory; + const SyncPath targetPath = temporaryDirectory.path() / "file.txt"; + { + std::ofstream ofs(targetPath); + ofs << "Some content.\n"; + ofs.close(); + } + + const SyncPath aliasPath = temporaryDirectory.path() / "alias.txt"; + IoError ioError = IoError::Success; + CPPUNIT_ASSERT(IoHelper::createAliasFromPath(targetPath, aliasPath, ioError)); + CPPUNIT_ASSERT(ioError == IoError::Success); + + CPPUNIT_ASSERT(_testObj->setXAttrValue(aliasPath, "alias-status", "to-be-deleted", ioError)); + CPPUNIT_ASSERT(ioError == IoError::Success); + + CPPUNIT_ASSERT(_testObj->removeXAttrs(aliasPath, {"alias-status"}, ioError)); + CPPUNIT_ASSERT(ioError == IoError::Success); + + std::string value; + CPPUNIT_ASSERT(_testObj->getXAttrValue(aliasPath, "alias-status", value, ioError)); + CPPUNIT_ASSERT(ioError == IoError::AttrNotFound); + CPPUNIT_ASSERT(value.empty()); + } + // A non-existing file { const SyncPath path = _localTestDirPath / "non-existing.jpg"; // This file does not exist. From 93c4dedb35571cd2e08731916c020a983878dd97 Mon Sep 17 00:00:00 2001 From: Herve Eruam Date: Wed, 4 Dec 2024 08:30:59 +0100 Subject: [PATCH 175/178] Remove a poluting log in ProgressIfnfo. --- src/libsyncengine/progress/progressinfo.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/libsyncengine/progress/progressinfo.cpp b/src/libsyncengine/progress/progressinfo.cpp index 7c08a1102..effdb8594 100644 --- a/src/libsyncengine/progress/progressinfo.cpp +++ b/src/libsyncengine/progress/progressinfo.cpp @@ -119,8 +119,6 @@ bool ProgressInfo::setProgress(const SyncPath &path, const int64_t completed) { const auto it = _currentItems.find(normalizedPath); if (it == _currentItems.end() || it->second.empty()) { - LOGW_INFO(Log::instance()->getLogger(), - L"Item not found in ProgressInfo list (normal for ommited operation): " << Utility::formatSyncPath(path)); return true; } From 9880fe7681a08a32873293a31d8b3fb843e4800a Mon Sep 17 00:00:00 2001 From: Christophe Larchier Date: Wed, 4 Dec 2024 10:36:26 +0100 Subject: [PATCH 176/178] Address comments --- .../file_system_observer/folderwatcher_mac.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libsyncengine/update_detection/file_system_observer/folderwatcher_mac.cpp b/src/libsyncengine/update_detection/file_system_observer/folderwatcher_mac.cpp index 803d74010..0892d24cf 100644 --- a/src/libsyncengine/update_detection/file_system_observer/folderwatcher_mac.cpp +++ b/src/libsyncengine/update_detection/file_system_observer/folderwatcher_mac.cpp @@ -90,7 +90,7 @@ static void callback([[maybe_unused]] ConstFSEventStreamRef streamRef, void *cli } void FolderWatcher_mac::startWatching() { - LOGW_DEBUG(_logger, L"Start watching folder: " << Path2WStr(_folder)); + LOGW_DEBUG(_logger, L"Start watching folder: " << Utility::formatSyncPath(_folder)); LOG_DEBUG(_logger, "File system format: " << Utility::fileSystemName(_folder).c_str()); CFStringRef path = CFStringCreateWithCString(nullptr, _folder.c_str(), kCFStringEncodingUTF8); @@ -135,7 +135,7 @@ OperationType FolderWatcher_mac::getOpType(const FSEventStreamEventFlags eventFl void KDC::FolderWatcher_mac::stopWatching() { if (_stream) { - LOGW_DEBUG(_logger, L"Stop watching folder: " << Path2WStr(_folder)); + LOGW_DEBUG(_logger, L"Stop watching folder: " << Utility::formatSyncPath(_folder)); FSEventStreamStop(_stream); FSEventStreamInvalidate(_stream); FSEventStreamRelease(_stream); From df59b3f3f529a288e88c1637d98d4f988a2184bd Mon Sep 17 00:00:00 2001 From: Christophe Larchier Date: Thu, 5 Dec 2024 07:48:58 +0100 Subject: [PATCH 177/178] Address comments --- src/libcommonserver/io/iohelper.h | 6 +++--- .../localfilesystemobserverworker.cpp | 20 +++++++++---------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/libcommonserver/io/iohelper.h b/src/libcommonserver/io/iohelper.h index 74770b15b..3d818660d 100644 --- a/src/libcommonserver/io/iohelper.h +++ b/src/libcommonserver/io/iohelper.h @@ -333,15 +333,15 @@ struct IoHelper { */ static bool setXAttrValue(const SyncPath &path, const std::string &attrName, const std::string &value, IoError &ioError) noexcept; - //! Remove the extended attribute with specified name for the item indicated by path. + //! Remove the extended attributes with specified names for the item indicated by path. /*! \param path is the file system path of the item. - \param attrNames is a vector of the names of the extended attribute to remove. + \param attrNames is a vector of the names of the extended attributes to remove. \param ioError holds the error returned when an underlying OS API call fails. \return true if no unexpected error occurred, false otherwise. */ static bool removeXAttrs(const SyncPath &path, const std::vector &attrNames, IoError &ioError) noexcept; - //! Remove LiteSync extended attribute for the item indicated by path. + //! Remove the LiteSync extended attributes for the item indicated by path. /*! \param path is the file system path of the item. \param ioError holds the error returned when an underlying OS API call fails. diff --git a/src/libsyncengine/update_detection/file_system_observer/localfilesystemobserverworker.cpp b/src/libsyncengine/update_detection/file_system_observer/localfilesystemobserverworker.cpp index a28ba1d7d..acf47042f 100644 --- a/src/libsyncengine/update_detection/file_system_observer/localfilesystemobserverworker.cpp +++ b/src/libsyncengine/update_detection/file_system_observer/localfilesystemobserverworker.cpp @@ -114,11 +114,12 @@ void LocalFileSystemObserverWorker::changesDetected(const std::listitemId(relativePath); bool existsWithSameId = false; NodeId otherNodeId; - ioError = IoError::Success; if (!prevNodeId.empty()) { if (_syncPal->isTmpBlacklisted(prevNodeId, ReplicaSide::Local)) _syncPal->removeItemFromTmpBlacklist(relativePath); - if (IoHelper::checkIfPathExistsWithSameNodeId(absolutePath, prevNodeId, existsWithSameId, otherNodeId, ioError) && + if (auto checkError = IoError::Success; + IoHelper::checkIfPathExistsWithSameNodeId(absolutePath, prevNodeId, existsWithSameId, otherNodeId, + checkError) && !existsWithSameId) { if (_snapshot->removeItem(prevNodeId)) { LOGW_SYNCPAL_DEBUG(_logger, L"Item removed from local snapshot: " << Utility::formatSyncPath(absolutePath) @@ -204,10 +205,10 @@ void LocalFileSystemObserverWorker::changesDetected(const std::listremoveItem(itemId); LOGW_SYNCPAL_DEBUG(_logger, - L"Item removed from sync because it's hidden: " << Utility::formatSyncPath(absolutePath)); + L"Item removed from sync because it is hidden: " << Utility::formatSyncPath(absolutePath)); } else { LOGW_SYNCPAL_DEBUG(_logger, - L"Item not processed because it's excluded: " << Utility::formatSyncPath(absolutePath)); + L"Item not processed because it is excluded: " << Utility::formatSyncPath(absolutePath)); } if (!_syncPal->vfsExclude( @@ -624,14 +625,13 @@ ExitInfo LocalFileSystemObserverWorker::exploreDir(const SyncPath &absoluteParen } if (itemType.ioError == IoError::NoSuchFileOrDirectory) { - LOGW_SYNCPAL_WARN(_logger, L"Sync localpath: " << Utility::formatSyncPath(absoluteParentDirPath) << L" doesn't exist"); + LOGW_SYNCPAL_WARN(_logger, L"Local " << Utility::formatSyncPath(absoluteParentDirPath) << L" doesn't exist"); setExitCause(ExitCause::SyncDirDoesntExist); return {ExitCode::SystemError, ExitCause::SyncDirDoesntExist}; } if (itemType.ioError == IoError::AccessDenied) { - LOGW_SYNCPAL_WARN(_logger, - L"Sync localpath: " << Utility::formatSyncPath(absoluteParentDirPath) << L" misses read permission"); + LOGW_SYNCPAL_WARN(_logger, L"Local " << Utility::formatSyncPath(absoluteParentDirPath) << L" misses read permission"); setExitCause(ExitCause::SyncDirAccesError); return {ExitCode::SystemError, ExitCause::SyncDirAccesError}; } @@ -651,13 +651,13 @@ ExitInfo LocalFileSystemObserverWorker::exploreDir(const SyncPath &absoluteParen } if (ioError == IoError::NoSuchFileOrDirectory) { - LOGW_SYNCPAL_WARN(_logger, L"Sync localpath: " << Utility::formatIoError(absoluteParentDirPath, ioError)); + LOGW_SYNCPAL_WARN(_logger, L"Local " << Utility::formatIoError(absoluteParentDirPath, ioError)); setExitCause(ExitCause::SyncDirDoesntExist); return {ExitCode::SystemError, ExitCause::SyncDirDoesntExist}; } if (ioError == IoError::AccessDenied) { - LOGW_SYNCPAL_WARN(_logger, L"Sync localpath: " << Utility::formatIoError(absoluteParentDirPath, ioError)); + LOGW_SYNCPAL_WARN(_logger, L"Local " << Utility::formatIoError(absoluteParentDirPath, ioError)); setExitCause(ExitCause::SyncDirAccesError); return {ExitCode::SystemError, ExitCause::SyncDirAccesError}; } @@ -722,7 +722,7 @@ ExitInfo LocalFileSystemObserverWorker::exploreDir(const SyncPath &absoluteParen } if (isExcluded) { LOGW_SYNCPAL_INFO(_logger, - L"Item: " << Utility::formatSyncPath(absolutePath) << L" rejected because it's excluded"); + L"Item: " << Utility::formatSyncPath(absolutePath) << L" rejected because it is excluded"); toExclude = true; } } From 42fce674f7dd58eb42fc9c9b3113dfa32ae95efb Mon Sep 17 00:00:00 2001 From: Herve Eruam <82284536+herve-er@users.noreply.github.com> Date: Fri, 6 Dec 2024 10:00:47 +0100 Subject: [PATCH 178/178] Update src/libsyncengine/syncpal/syncpal.cpp --- src/libsyncengine/syncpal/syncpal.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libsyncengine/syncpal/syncpal.cpp b/src/libsyncengine/syncpal/syncpal.cpp index b2cf3e44d..75f47859a 100644 --- a/src/libsyncengine/syncpal/syncpal.cpp +++ b/src/libsyncengine/syncpal/syncpal.cpp @@ -1492,7 +1492,6 @@ ExitInfo SyncPal::handleAccessDeniedItem(const SyncPath &relativePath, ExitCause << L" is blacklisted temporarily because of a denied access."); NodeId remoteNodeId = snapshot(ReplicaSide::Remote)->itemId(relativePath); - remoteNodeId = snapshot(ReplicaSide::Remote)->itemId(relativePath); if (bool found; remoteNodeId.empty() && !localNodeId.empty() && !_syncDb->correspondingNodeId(ReplicaSide::Local, localNodeId, remoteNodeId, found)) { LOG_SYNCPAL_WARN(_logger, "Error in SyncDb::correspondingNodeId");