diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index f03c3b5ad..09907c7ea 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -65,6 +65,7 @@ jobs: ./infomaniak-build-tools/run-tests.ps1 - name: Compute code coverage + if: false run : | rm -Force -ErrorAction SilentlyContinue BullseyeCoverageExclusions echo "exclude folder 3rdparty/\nexclude folder ../" >> BullseyeCoverageExclusions @@ -74,11 +75,13 @@ jobs: & "covxml.exe" "-f" "$env:COVFILE" "-o" "coverage.xml" - name: Install sonar-scanner + if: false uses: SonarSource/sonarcloud-github-c-cpp@v3 env: SONAR_HOST_URL: https://sonarcloud.io - name: Run sonar-scanner + if: false env: GITHUB_TOKEN: ${{ github.token }} SONAR_TOKEN: ${{ secrets.SONAR_DESKTOP_KDRIVE_TOKEN }} diff --git a/infomaniak-build-tools/translate_release_notes.py b/infomaniak-build-tools/translate_release_notes.py index 3d0c58bfb..6021e98c7 100755 --- a/infomaniak-build-tools/translate_release_notes.py +++ b/infomaniak-build-tools/translate_release_notes.py @@ -22,6 +22,7 @@ import deepl import errno import os +from pathlib import Path import re import shutil import subprocess @@ -54,18 +55,23 @@ def version_regex(arg_value, pattern=re.compile(r'^(\d+\.)?(\d+\.)?(\*|\d+)')): parser.add_argument('-d', '--date', metavar="", type=int, help='The planned release date (defaults to today)', default=datetime.date.today().strftime('%Y%m%d')) args = parser.parse_args() -if not os.path.isfile(f"kDrive-template.html"): - sys.exit("Unable to find kDrive-template.html."); +if not os.path.isfile("kDrive-template.html"): + sys.exit("Unable to find 'kDrive-template.html'.") fullName = f"kDrive-{args.version}.{args.date}" -dirPath = f"../release_notes/{fullName}" +dirPath = Path(__file__).parent.parent / "release_notes" + +if not dirPath.exists(): + sys.exit(f"Release notes path does not exist: '{dirPath}'. \nAborting.") + +dirPath = dirPath / Path(fullName) deepl_key = os.getenv("DEEPL_AUTH_KEY") if not deepl_key: - sys.exit("error: The DeepL API key is not set in env"); + sys.exit("error: The DeepL API key is not set in env") translator = deepl.Translator(deepl_key) -target_lang = [ +target_languages = [ 'FR', 'DE', 'ES', @@ -78,16 +84,15 @@ def version_regex(arg_value, pattern=re.compile(r'^(\d+\.)?(\d+\.)?(\*|\d+)')): 'macOS' ] -def split_os(lang): - lang_ext = f"-{lang.lower()}" if lang != 'en' else "" +def split_os(lang, fullName): + lang_ext = lang.lower() for os_name in os_list: - os_ext = f"-{os_name.lower()}" if os_name != 'macOS' else "" - if os_name != 'macOS': - shutil.copyfile(f"{fullName}{lang_ext}.html", f"{fullName}{os_ext}{lang_ext}.html") - with open(f"{fullName}{os_ext}{lang_ext}.html", "r") as f: + os_ext = os_name.lower() + shutil.copyfile(f"{fullName}-{lang_ext}.html", f"{fullName}-{os_ext}-{lang_ext}.html") + with open(f"{fullName}-{os_ext}-{lang_ext}.html", "r") as f: lines = f.readlines() - with open(f"{fullName}{os_ext}{lang_ext}.html", "w") as f: + with open(f"{fullName}-{os_ext}-{lang_ext}.html", "w") as f: for line in lines: if any(os_note in line for os_note in os_list): if (f"
  • {os_name}" in line): @@ -96,29 +101,26 @@ def split_os(lang): f.write(line) print(f"Generating Release Notes for kDrive-{args.version}.{args.date}") +Path(dirPath).mkdir(mode=0o755, exist_ok=True) -try: - os.mkdir(dirPath, mode = 0o755) -except OSError as exc: - if exc.errno != errno.EEXIST: - raise - pass - -shutil.copyfile("kDrive-template.html", f"{dirPath}/{fullName}.html") +shutil.copyfile("kDrive-template.html", f"{dirPath}/{fullName}-en.html") os.chdir(dirPath) try: - for lang in target_lang: + for target_lang in target_languages: + print(f" - Notes for language {target_lang}") translator.translate_document_from_filepath( - f"{fullName}.html", - f"{fullName}-{lang.lower()}.html", - target_lang=lang, + f"{fullName}-en.html", + f"{fullName}-{target_lang.lower()}.html", + target_lang=target_lang, ) - split_os(lang) + split_os(target_lang, fullName) + Path(f"{fullName}-{target_lang.lower()}.html").unlink() except Exception as e: print(e) -split_os('en') +split_os('en', fullName) +Path(f"{fullName}-en.html").unlink() # Remove english template subprocess.run(['../../infomaniak-build-tools/encode.sh'], shell=True) diff --git a/src/libcommon/utility/utility.cpp b/src/libcommon/utility/utility.cpp index 3a537a24b..f99c4513d 100644 --- a/src/libcommon/utility/utility.cpp +++ b/src/libcommon/utility/utility.cpp @@ -655,8 +655,8 @@ size_t CommonUtility::maxPathLength() { // For folders in short path mode, it is MAX_PATH - 12 // (https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation?tabs=registry) // We decided to apply this rule for files too. We could else encounter issues. - // If the path length of a folder is > MAX_PATH - 12 and the path length of a file in this folder is between MAX_PATH - 12 and MAX_PATH. - // It would lead to a synced file in a folder that is not synced (hence excluded because of its path length). + // If the path length of a folder is > MAX_PATH - 12 and the path length of a file in this folder is between MAX_PATH - 12 and + // MAX_PATH. It would lead to a synced file in a folder that is not synced (hence excluded because of its path length). return (_maxPathWin == MAX_PATH_LENGTH_WIN_LONG) ? MAX_PATH_LENGTH_WIN_LONG : MAX_PATH_LENGTH_WIN_SHORT - 12; #elif defined(__APPLE__) return MAX_PATH_LENGTH_MAC; @@ -728,7 +728,8 @@ bool CommonUtility::isVersionLower(const std::string ¤tVersion, const std: return false; // Should not happen } - return std::ranges::lexicographical_compare(currTabVersion, targetTabVersion); + return std::lexicographical_compare(currTabVersion.begin(), currTabVersion.end(), targetTabVersion.begin(), + targetTabVersion.end()); } static std::string tmpDirName = "kdrive_" + CommonUtility::generateRandomStringAlphaNum(); diff --git a/src/libsyncengine/db/syncdb.cpp b/src/libsyncengine/db/syncdb.cpp index 161f81c1e..47dd7268d 100644 --- a/src/libsyncengine/db/syncdb.cpp +++ b/src/libsyncengine/db/syncdb.cpp @@ -2393,8 +2393,6 @@ bool SyncDb::reinstateEncodingOfLocalNames(const std::string &dbFromVersionNumbe LOG_DEBUG(_logger, "Upgrade < 3.6.7 Sync DB"); - normalizeRemoteNames(); - Sync sync; bool found = false; ParmsDb::instance()->selectSync(_dbPath, sync, found); @@ -2405,6 +2403,21 @@ bool SyncDb::reinstateEncodingOfLocalNames(const std::string &dbFromVersionNumbe const SyncPath &localDrivePath = sync.localPath(); + bool exists = false; + IoError existenceCheckError = IoError::Success; + if (!IoHelper::checkIfPathExists(localDrivePath, exists, existenceCheckError)) { + LOGW_WARN(_logger, + L"Error in IoHelper::checkIfPathExists" << Utility::formatIoError(localDrivePath, existenceCheckError)); + return false; + } + if (!exists) { + LOGW_INFO(_logger, L"The synchronisation folder " << Utility::formatSyncPath(localDrivePath) + << L" does not exist anymore. No Sync DB upgrade to do."); + return true; + } + + if (!normalizeRemoteNames()) return false; + NamedNodeMap namedNodeMap; if (!selectNamesWithDistinctEncodings(namedNodeMap)) return false; @@ -2412,8 +2425,8 @@ bool SyncDb::reinstateEncodingOfLocalNames(const std::string &dbFromVersionNumbe IoError ioError = IoError::Success; IoHelper::getDirectoryIterator(localDrivePath, true, ioError, dir); if (ioError != IoError::Success) { - LOGW_WARN(_logger, L"Error in DirectoryIterator: " << Utility::formatIoError(localDrivePath, ioError).c_str()); - return false; + LOGW_WARN(_logger, L"Error in DirectoryIterator: " << Utility::formatIoError(localDrivePath, ioError)); + return (ioError == IoError::NoSuchFileOrDirectory) || (ioError == IoError::AccessDenied); } SyncNameMap localNames; diff --git a/src/libsyncengine/progress/progressinfo.cpp b/src/libsyncengine/progress/progressinfo.cpp index 7fdd08ede..4359637f7 100644 --- a/src/libsyncengine/progress/progressinfo.cpp +++ b/src/libsyncengine/progress/progressinfo.cpp @@ -21,8 +21,7 @@ namespace KDC { -ProgressInfo::ProgressInfo(std::shared_ptr syncPal) : - _syncPal(syncPal), _totalSizeOfCompletedJobs(0), _maxFilesPerSecond(0), _maxBytesPerSecond(0), _update(false) { +ProgressInfo::ProgressInfo(std::shared_ptr syncPal) : _syncPal(syncPal) { reset(); } @@ -77,35 +76,34 @@ void ProgressInfo::updateEstimates() { } void ProgressInfo::initProgress(const SyncFileItem &item) { - SyncPath path = item.newPath().has_value() ? item.newPath().value() : item.path(); + const SyncPath path = item.newPath().has_value() ? item.newPath().value() : item.path(); ProgressItem progressItem; progressItem.setItem(item); progressItem.progress().setTotal(item.size()); progressItem.progress().setCompleted(0); - _currentItems[path].push(progressItem); + _currentItems[Utility::normalizedSyncPath(path)].push(progressItem); _fileProgress.setTotal(_fileProgress.total() + 1); _sizeProgress.setTotal(_sizeProgress.total() + item.size()); } bool ProgressInfo::getSyncFileItem(const SyncPath &path, SyncFileItem &item) { - auto it = _currentItems.find(path); - if (_currentItems.find(path) == _currentItems.end() || it->second.empty()) { + const auto it = _currentItems.find(Utility::normalizedSyncPath(path)); + if (it == _currentItems.end() || it->second.empty()) { return false; } item = it->second.front().item(); return true; } -void ProgressInfo::setProgress(const SyncPath &path, int64_t completed) { - auto it = _currentItems.find(path); +void ProgressInfo::setProgress(const SyncPath &path, const int64_t completed) { + const auto it = _currentItems.find(Utility::normalizedSyncPath(path)); if (it == _currentItems.end() || it->second.empty()) { return; } - SyncFileItem &item = it->second.front().item(); - if (!shouldCountProgress(item)) { + if (const SyncFileItem &item = it->second.front().item(); !shouldCountProgress(item)) { return; } @@ -113,8 +111,8 @@ void ProgressInfo::setProgress(const SyncPath &path, int64_t completed) { recomputeCompletedSize(); } -void ProgressInfo::setProgressComplete(const SyncPath &path, SyncFileStatus status) { - auto it = _currentItems.find(path); +void ProgressInfo::setProgressComplete(const SyncPath &path, const SyncFileStatus status) { + const auto it = _currentItems.find(Utility::normalizedSyncPath(path)); if (it == _currentItems.end() || it->second.empty()) { return; } @@ -135,7 +133,7 @@ void ProgressInfo::setProgressComplete(const SyncPath &path, SyncFileStatus stat it->second.pop(); if (it->second.empty()) { - _currentItems.erase(path); + _currentItems.erase(Utility::normalizedSyncPath(path)); } recomputeCompletedSize(); } @@ -183,15 +181,6 @@ bool ProgressInfo::trustEta() const { return totalProgress().estimatedEta() < 100 * optimisticEta(); } -Estimates ProgressInfo::fileProgress(const SyncFileItem &item) { - auto it = _currentItems.find(item.path()); - if (it == _currentItems.end() || it->second.empty()) { - return Estimates(); - } - - return it->second.front().progress().estimates(); -} - void ProgressInfo::recomputeCompletedSize() { int64_t r = _totalSizeOfCompletedJobs; for (auto &itemElt: _currentItems) { diff --git a/src/libsyncengine/progress/progressinfo.h b/src/libsyncengine/progress/progressinfo.h index dd488c316..0ee93cdf1 100644 --- a/src/libsyncengine/progress/progressinfo.h +++ b/src/libsyncengine/progress/progressinfo.h @@ -34,24 +34,24 @@ class SyncPal; class ProgressInfo { public: - ProgressInfo(std::shared_ptr syncPal); + explicit ProgressInfo(std::shared_ptr syncPal); ~ProgressInfo(); void reset(); - inline void setUpdate(bool value) { _update = value; } - inline bool update() const { return _update; } + void setUpdate(bool value) { _update = value; } + [[nodiscard]] bool update() const { return _update; } void updateEstimates(); void initProgress(const SyncFileItem &item); void setProgress(const SyncPath &path, int64_t completed); void setProgressComplete(const SyncPath &path, SyncFileStatus status); bool getSyncFileItem(const SyncPath &path, SyncFileItem &item); - inline int64_t totalFiles() const { return _fileProgress.total(); } - inline int64_t completedFiles() const { return _fileProgress.completed(); } - inline int64_t totalSize() const { return _sizeProgress.total(); } - inline int64_t completedSize() const { return _sizeProgress.completed(); } - inline int64_t currentFile() const { return completedFiles(); } - Estimates totalProgress() const; + [[nodiscard]] int64_t totalFiles() const { return _fileProgress.total(); } + [[nodiscard]] int64_t completedFiles() const { return _fileProgress.completed(); } + [[nodiscard]] int64_t totalSize() const { return _sizeProgress.total(); } + [[nodiscard]] int64_t completedSize() const { return _sizeProgress.completed(); } + [[nodiscard]] int64_t currentFile() const { return completedFiles(); } + [[nodiscard]] Estimates totalProgress() const; private: std::shared_ptr _syncPal; @@ -60,16 +60,15 @@ class ProgressInfo { // DELETE a file and CREATE a directory with exact same name) Progress _sizeProgress; Progress _fileProgress; - int64_t _totalSizeOfCompletedJobs; - double _maxFilesPerSecond; - double _maxBytesPerSecond; - bool _update; + int64_t _totalSizeOfCompletedJobs{0}; + double _maxFilesPerSecond{0.0}; + double _maxBytesPerSecond{0.0}; + bool _update{false}; - int64_t optimisticEta() const; - bool trustEta() const; - Estimates fileProgress(const SyncFileItem &item); + [[nodiscard]] int64_t optimisticEta() const; + [[nodiscard]] bool trustEta() const; void recomputeCompletedSize(); - bool isSizeDependent(const SyncFileItem &item) const; + [[nodiscard]] bool isSizeDependent(const SyncFileItem &item) const; }; } // namespace KDC diff --git a/src/libsyncengine/progress/syncfileitem.h b/src/libsyncengine/progress/syncfileitem.h index c00372c67..a55e18430 100644 --- a/src/libsyncengine/progress/syncfileitem.h +++ b/src/libsyncengine/progress/syncfileitem.h @@ -74,6 +74,8 @@ class SyncFileItem { inline bool isDirectory() const { return _type == NodeType::Directory; } + bool operator==(const SyncFileItem &) const = default; + private: NodeType _type{NodeType::Unknown}; SyncPath _path; // Sync folder relative filesystem path diff --git a/src/libsyncengine/reconciliation/conflict_resolver/conflictresolverworker.cpp b/src/libsyncengine/reconciliation/conflict_resolver/conflictresolverworker.cpp index 28dd37f1d..13dbb6ecd 100644 --- a/src/libsyncengine/reconciliation/conflict_resolver/conflictresolverworker.cpp +++ b/src/libsyncengine/reconciliation/conflict_resolver/conflictresolverworker.cpp @@ -342,12 +342,12 @@ bool ConflictResolverWorker::generateConflictedName(const std::shared_ptr bool isOrphanNode /*= false*/) const { SyncPath absoluteLocalFilePath = _syncPal->localPath() / node->getPath(); newName = PlatformInconsistencyCheckerUtility::instance()->generateNewValidName( - absoluteLocalFilePath, isOrphanNode ? PlatformInconsistencyCheckerUtility::SuffixTypeOrphan - : PlatformInconsistencyCheckerUtility::SuffixTypeConflict); + absoluteLocalFilePath, isOrphanNode ? PlatformInconsistencyCheckerUtility::SuffixType::Orphan + : PlatformInconsistencyCheckerUtility::SuffixType::Conflict); // Check path size size_t pathSize = absoluteLocalFilePath.parent_path().native().size() + 1 + newName.size(); - if (PlatformInconsistencyCheckerUtility::instance()->checkPathLength(pathSize)) { + if (PlatformInconsistencyCheckerUtility::instance()->isPathTooLong(pathSize)) { // Path is now too long, file needs to be moved to root directory return false; } diff --git a/src/libsyncengine/reconciliation/platform_inconsistency_checker/platforminconsistencycheckerutility.cpp b/src/libsyncengine/reconciliation/platform_inconsistency_checker/platforminconsistencycheckerutility.cpp index c2fb028c0..af9985b97 100644 --- a/src/libsyncengine/reconciliation/platform_inconsistency_checker/platforminconsistencycheckerutility.cpp +++ b/src/libsyncengine/reconciliation/platform_inconsistency_checker/platforminconsistencycheckerutility.cpp @@ -40,7 +40,7 @@ static const char forbiddenFilenameChars[] = {'/', '\0'}; #endif #endif -#define MAX_NAME_LENGTH 255 +static const int maxNameLengh = 255; // Max filename length is uniformized to 255 characters for all platforms and backends namespace KDC { @@ -62,7 +62,7 @@ std::shared_ptr PlatformInconsistencyChecke SyncName PlatformInconsistencyCheckerUtility::generateNewValidName(const SyncPath &name, SuffixType suffixType) { SyncName suffix = generateSuffix(suffixType); - SyncName sub = name.stem().native().substr(0, MAX_NAME_LENGTH - suffix.size() - name.extension().native().size()); + const SyncName sub = name.stem().native().substr(0, maxNameLengh - suffix.size() - name.extension().native().size()); #ifdef _WIN32 SyncName nameStr(name.native()); @@ -90,7 +90,7 @@ ExitCode PlatformInconsistencyCheckerUtility::renameLocalFile(const SyncPath &ab return moveJob.exitCode(); } -bool PlatformInconsistencyCheckerUtility::checkNameForbiddenChars(const SyncPath &name) { +bool PlatformInconsistencyCheckerUtility::nameHasForbiddenChars(const SyncPath &name) { for (auto c: forbiddenFilenameChars) { if (name.native().find(c) != std::string::npos) { return true; @@ -131,12 +131,8 @@ bool PlatformInconsistencyCheckerUtility::fixNameWithBackslash(const SyncName &n } #endif -bool PlatformInconsistencyCheckerUtility::checkNameSize(const SyncName &name) { - if (name.size() > MAX_NAME_LENGTH) { - return true; - } - - return false; +bool PlatformInconsistencyCheckerUtility::isNameTooLong(const SyncName &name) const { + return name.size() > maxNameLengh; } // return false if the file name is ok @@ -171,7 +167,7 @@ bool PlatformInconsistencyCheckerUtility::checkReservedNames(const SyncName &nam return false; } -bool PlatformInconsistencyCheckerUtility::checkPathLength(size_t pathSize) { +bool PlatformInconsistencyCheckerUtility::isPathTooLong(size_t pathSize) { return pathSize > _maxPathLength; } @@ -189,7 +185,7 @@ void PlatformInconsistencyCheckerUtility::setMaxPath() { _maxPathLength = CommonUtility::maxPathLength(); } -SyncName PlatformInconsistencyCheckerUtility::generateSuffix(SuffixType suffixType /*= SuffixTypeRename*/) { +SyncName PlatformInconsistencyCheckerUtility::generateSuffix(SuffixType suffixType) { std::time_t now = std::time(nullptr); std::tm tm = *std::localtime(&now); @@ -198,16 +194,13 @@ SyncName PlatformInconsistencyCheckerUtility::generateSuffix(SuffixType suffixTy ss << std::put_time(&tm, Str("%Y%m%d_%H%M%S")); switch (suffixType) { - case SuffixTypeRename: - suffix = Str("_renamed_"); - break; - case SuffixTypeConflict: + case SuffixType::Conflict: suffix = Str("_conflict_"); break; - case SuffixTypeOrphan: + case SuffixType::Orphan: suffix = Str("_orphan_"); break; - case SuffixTypeBlacklisted: + case SuffixType::Blacklisted: suffix = Str("_blacklisted_"); break; } diff --git a/src/libsyncengine/reconciliation/platform_inconsistency_checker/platforminconsistencycheckerutility.h b/src/libsyncengine/reconciliation/platform_inconsistency_checker/platforminconsistencycheckerutility.h index 70914d787..89ae3bdc6 100644 --- a/src/libsyncengine/reconciliation/platform_inconsistency_checker/platforminconsistencycheckerutility.h +++ b/src/libsyncengine/reconciliation/platform_inconsistency_checker/platforminconsistencycheckerutility.h @@ -28,28 +28,27 @@ namespace KDC { class PlatformInconsistencyCheckerUtility { public: - typedef enum { SuffixTypeRename, SuffixTypeConflict, SuffixTypeOrphan, SuffixTypeBlacklisted } SuffixType; + enum class SuffixType { Conflict, Orphan, Blacklisted }; public: static std::shared_ptr instance(); - SyncName generateNewValidName(const SyncPath &name, SuffixType suffixType); - static ExitCode renameLocalFile(const SyncPath &absoluteLocalPath, SuffixType suffixType, SyncPath *newPathPtr = nullptr); + bool isNameTooLong(const SyncName &name) const; + bool isPathTooLong(size_t pathSize); + bool nameHasForbiddenChars(const SyncPath &name); - bool checkNameForbiddenChars(const SyncPath &name); #ifdef _WIN32 bool fixNameWithBackslash(const SyncName &name, SyncName &newName); #endif - bool checkNameSize(const SyncName &name); bool checkReservedNames(const SyncName &name); - bool checkPathLength(size_t pathSize); - + SyncName generateNewValidName(const SyncPath &name, SuffixType suffixType); + static ExitCode renameLocalFile(const SyncPath &absoluteLocalPath, SuffixType suffixType, SyncPath *newPathPtr = nullptr); private: PlatformInconsistencyCheckerUtility(); SyncName charToHex(unsigned int c); void setMaxPath(); - SyncName generateSuffix(SuffixType suffixType = SuffixTypeRename); + SyncName generateSuffix(SuffixType suffixType); static std::shared_ptr _instance; static size_t _maxPathLength; diff --git a/src/libsyncengine/reconciliation/platform_inconsistency_checker/platforminconsistencycheckerworker.cpp b/src/libsyncengine/reconciliation/platform_inconsistency_checker/platforminconsistencycheckerworker.cpp index df4875abb..b04efac8c 100644 --- a/src/libsyncengine/reconciliation/platform_inconsistency_checker/platforminconsistencycheckerworker.cpp +++ b/src/libsyncengine/reconciliation/platform_inconsistency_checker/platforminconsistencycheckerworker.cpp @@ -36,8 +36,8 @@ void PlatformInconsistencyCheckerWorker::execute() { _idsToBeRemoved.clear(); - ExitCode exitCode = checkTree(_syncPal->updateTree(ReplicaSide::Remote)->rootNode(), - _syncPal->updateTree(ReplicaSide::Remote)->rootNode()->name()); + checkTree(ReplicaSide::Remote); + checkTree(ReplicaSide::Local); for (const auto &idItem: _idsToBeRemoved) { if (!idItem.remoteId.empty() && !_syncPal->updateTree(ReplicaSide::Remote)->deleteNode(idItem.remoteId)) { @@ -53,20 +53,39 @@ void PlatformInconsistencyCheckerWorker::execute() { _syncPal->updateTree(ReplicaSide::Remote)->setInconsistencyCheckDone(); - setDone(exitCode); + setDone(ExitCode::Ok); LOG_SYNCPAL_DEBUG(_logger, "Worker stopped: name=" << name().c_str()); } -ExitCode PlatformInconsistencyCheckerWorker::checkTree(std::shared_ptr remoteNode, const SyncPath &parentPath) { +ExitCode PlatformInconsistencyCheckerWorker::checkTree(ReplicaSide side) { + std::shared_ptr node = _syncPal->updateTree(side)->rootNode(); + const SyncPath &parentPath = node->name(); + assert(side == ReplicaSide::Remote || + side == ReplicaSide::Local && "Invalid side in PlatformInconsistencyCheckerWorker::checkTree"); + + ExitCode exitCode = ExitCode::Unknown; + if (side == ReplicaSide::Remote) { + exitCode = checkRemoteTree(node, parentPath); + } else if (side == ReplicaSide::Local) { + exitCode = checkLocalTree(node, parentPath); + } + + if (exitCode != ExitCode::Ok) { + LOG_SYNCPAL_WARN(_logger, + "PlatformInconsistencyCheckerWorker::check" << side << "Tree partially failed, ExitCode=" << exitCode); + } + + return exitCode; +} + +ExitCode PlatformInconsistencyCheckerWorker::checkRemoteTree(std::shared_ptr remoteNode, const SyncPath &parentPath) { if (remoteNode->hasChangeEvent(OperationType::Delete)) { return ExitCode::Ok; } - if (remoteNode->hasChangeEvent(OperationType::Create) || remoteNode->hasChangeEvent(OperationType::Move)) { - if (!checkPathAndName(remoteNode)) { - // Item has been blacklisted - return ExitCode::Ok; - } + if (pathChanged(remoteNode) && !checkPathAndName(remoteNode)) { + // Item has been blacklisted + return ExitCode::Ok; } bool checkAgainstSiblings = false; @@ -87,11 +106,11 @@ ExitCode PlatformInconsistencyCheckerWorker::checkTree(std::shared_ptr rem std::shared_ptr currentChildNode = it->second; - if (currentChildNode->hasChangeEvent(OperationType::Create) || currentChildNode->hasChangeEvent(OperationType::Move)) { + if (pathChanged(currentChildNode)) { checkAgainstSiblings = true; } - ExitCode exitCode = checkTree(currentChildNode, parentPath / remoteNode->name()); + ExitCode exitCode = checkRemoteTree(currentChildNode, parentPath / remoteNode->name()); if (exitCode != ExitCode::Ok) { return exitCode; } @@ -104,66 +123,92 @@ ExitCode PlatformInconsistencyCheckerWorker::checkTree(std::shared_ptr rem return ExitCode::Ok; } -void PlatformInconsistencyCheckerWorker::blacklistNode(const std::shared_ptr remoteNode, const SyncPath &relativePath, +ExitCode PlatformInconsistencyCheckerWorker::checkLocalTree(std::shared_ptr localNode, const SyncPath &parentPath) { + if (localNode->hasChangeEvent(OperationType::Delete)) { + return ExitCode::Ok; + } + if (pathChanged(localNode) && PlatformInconsistencyCheckerUtility::instance()->isNameTooLong(localNode->name())) { + blacklistNode(localNode, InconsistencyType::NameLength); + return ExitCode::Ok; + } + + auto childIt = localNode->children().begin(); + for (; childIt != localNode->children().end(); childIt++) { + if (stopAsked()) { + return ExitCode::Ok; + } + + while (pauseAsked() || isPaused()) { + if (!isPaused()) { + setPauseDone(); + } + + Utility::msleep(LOOP_PAUSE_SLEEP_PERIOD); + } + + const ExitCode exitCode = checkLocalTree(childIt->second, parentPath / localNode->name()); + if (exitCode != ExitCode::Ok) { + return exitCode; + } + } + return ExitCode::Ok; +} + +void PlatformInconsistencyCheckerWorker::blacklistNode(const std::shared_ptr node, const InconsistencyType inconsistencyType) { // Local node needs to be excluded before call to blacklistTemporarily because // we need the DB entry to retrieve the corresponding node NodeIdPair nodeIDs; + const std::shared_ptr localNode = node->side() == ReplicaSide::Local ? node : correspondingNodeDirect(node); + const std::shared_ptr remoteNode = node->side() == ReplicaSide::Remote ? node : correspondingNodeDirect(node); - if (const auto localNode = correspondingNodeDirect(remoteNode); localNode) { - // Also exclude local node by adding "conflict" suffix + if (localNode) { const SyncPath absoluteLocalPath = _syncPal->localPath() / localNode->getPath(); - LOGW_SYNCPAL_INFO(_logger, - L"Excluding also local item with " << Utility::formatSyncPath(absoluteLocalPath).c_str() << L"."); - PlatformInconsistencyCheckerUtility::renameLocalFile(absoluteLocalPath, - PlatformInconsistencyCheckerUtility::SuffixTypeConflict); + LOGW_SYNCPAL_INFO(_logger, L"Excluding local item with " << Utility::formatSyncPath(absoluteLocalPath) << L"."); + PlatformInconsistencyCheckerUtility::renameLocalFile( + absoluteLocalPath, node->side() == ReplicaSide::Remote + ? PlatformInconsistencyCheckerUtility::SuffixType::Conflict + : PlatformInconsistencyCheckerUtility::SuffixType::Blacklisted); + + if (node->side() == ReplicaSide::Local) { + removeLocalNodeFromDb(localNode); + } + } - if (localNode->id().has_value()) nodeIDs.localId = *localNode->id(); + if (node->side() == ReplicaSide::Remote) { + _syncPal->blacklistTemporarily(remoteNode->id().value(), remoteNode->getPath(), remoteNode->side()); } - _syncPal->blacklistTemporarily(remoteNode->id().value(), relativePath, remoteNode->side()); - Error error(_syncPal->syncDbId(), "", remoteNode->id().value(), remoteNode->type(), relativePath, ConflictType::None, + Error error(_syncPal->syncDbId(), "", node->id().value(), node->type(), node->getPath(), ConflictType::None, inconsistencyType); _syncPal->addError(error); - std::wstring causeStr; - switch (inconsistencyType) { - case InconsistencyType::Case: - causeStr = L"of a name clash"; - break; - case InconsistencyType::ForbiddenChar: - causeStr = L"of a forbidden character"; - break; - case InconsistencyType::ReservedName: - causeStr = L"the name is reserved on this OS"; - break; - case InconsistencyType::NameLength: - causeStr = L"the name is too long"; - break; - default: - break; - } - LOGW_SYNCPAL_INFO(_logger, L"Blacklisting remote item with " << Utility::formatSyncPath(relativePath).c_str() << L" because " - << causeStr.c_str() << L"."); - - nodeIDs.remoteId = *remoteNode->id(); + LOGW_SYNCPAL_INFO(_logger, L"Blacklisting " << node->side() << L" item with " << Utility::formatSyncPath(node->getPath()) + << L" because " << inconsistencyType << L"."); + + auto safeNodeId = [](const std::shared_ptr &unsafeNodePtr) { + return (unsafeNodePtr && unsafeNodePtr->id().has_value()) ? *unsafeNodePtr->id() : NodeId(); + }; + nodeIDs.remoteId = safeNodeId(remoteNode); + nodeIDs.localId = safeNodeId(localNode); + _idsToBeRemoved.emplace_back(nodeIDs); } bool PlatformInconsistencyCheckerWorker::checkPathAndName(std::shared_ptr remoteNode) { const SyncPath relativePath = remoteNode->getPath(); - if (PlatformInconsistencyCheckerUtility::instance()->checkNameForbiddenChars(remoteNode->name())) { - blacklistNode(remoteNode, relativePath, InconsistencyType::ForbiddenChar); + if (PlatformInconsistencyCheckerUtility::instance()->nameHasForbiddenChars(remoteNode->name())) { + blacklistNode(remoteNode, InconsistencyType::ForbiddenChar); return false; } if (PlatformInconsistencyCheckerUtility::instance()->checkReservedNames(remoteNode->name())) { - blacklistNode(remoteNode, relativePath, InconsistencyType::ReservedName); + blacklistNode(remoteNode, InconsistencyType::ReservedName); return false; } - if (PlatformInconsistencyCheckerUtility::instance()->checkNameSize(remoteNode->name())) { - blacklistNode(remoteNode, relativePath, InconsistencyType::NameLength); + if (PlatformInconsistencyCheckerUtility::instance()->isNameTooLong(remoteNode->name())) { + blacklistNode(remoteNode, InconsistencyType::NameLength); return false; } @@ -201,9 +246,9 @@ void PlatformInconsistencyCheckerWorker::checkNameClashAgainstSiblings(const std // Some software save their files by deleting and re-creating them (Delete-Create), or by deleting the original file // and renaming a temporary file that contains the latest version (Delete-Move) In those cases, we should not check // for name clash, it is ok to have 2 children with the same name - const auto oneNodeIsDeleted = [](const std::shared_ptr &node, const std::shared_ptr &prevNode) -> bool { - return node->hasChangeEvent(OperationType::Move | OperationType::Create) && - prevNode->hasChangeEvent(OperationType::Delete); + const auto oneNodeIsDeleted = [this](const std::shared_ptr &node, + const std::shared_ptr &prevNode) -> bool { + return pathChanged(node) && prevNode->hasChangeEvent(OperationType::Delete); }; if (oneNodeIsDeleted(currentChildNode, prevChildNode) || oneNodeIsDeleted(prevChildNode, currentChildNode)) { @@ -212,11 +257,11 @@ void PlatformInconsistencyCheckerWorker::checkNameClashAgainstSiblings(const std if (currentChildNode->hasChangeEvent() && !isSpecialFolder) { // Blacklist the new one - blacklistNode(currentChildNode, currentChildNode->getPath(), InconsistencyType::Case); + blacklistNode(currentChildNode, InconsistencyType::Case); continue; } else { // Blacklist the previously discovered child - blacklistNode(prevChildNode, prevChildNode->getPath(), InconsistencyType::Case); + blacklistNode(prevChildNode, InconsistencyType::Case); continue; } } @@ -226,4 +271,32 @@ void PlatformInconsistencyCheckerWorker::checkNameClashAgainstSiblings(const std #endif } +bool PlatformInconsistencyCheckerWorker::pathChanged(std::shared_ptr node) const { + return node->hasChangeEvent(OperationType::Create) || node->hasChangeEvent(OperationType::Move); +} + +void PlatformInconsistencyCheckerWorker::removeLocalNodeFromDb(std::shared_ptr localNode) { + if (localNode && localNode->side() == ReplicaSide::Local) { + bool found = false; + DbNodeId dbId = -1; + const SyncPath absoluteLocalPath = _syncPal->localPath() / localNode->getPath(); + if (!_syncPal->syncDb()->dbId(ReplicaSide::Local, *localNode->id(), dbId, found)) { + LOGW_WARN(_logger, L"Failed to retrieve dbId for local node: " << Utility::formatSyncPath(absoluteLocalPath)); + } + if (found && !_syncPal->syncDb()->deleteNode(dbId, found)) { + // Remove node (and childs by cascade) from DB if it exists (else ignore as it is already not in DB) + LOGW_WARN(_logger, L"Failed to delete node from DB: " << Utility::formatSyncPath(absoluteLocalPath)); + } + + if (!_syncPal->vfsFileStatusChanged(absoluteLocalPath, SyncFileStatus::Error)) { + LOGW_SYNCPAL_WARN(_logger, L"Error in SyncPal::vfsFileStatusChanged: " << Utility::formatSyncPath(absoluteLocalPath)); + } + } else { + LOG_WARN(_logger, localNode + ? "Invalid side in PlatformInconsistencyCheckerWorker::removeLocalNodeFromDb" + : "localNode should not be null in PlatformInconsistencyCheckerWorker::removeLocalNodeFromDb"); + assert(false); + } +} + } // namespace KDC diff --git a/src/libsyncengine/reconciliation/platform_inconsistency_checker/platforminconsistencycheckerworker.h b/src/libsyncengine/reconciliation/platform_inconsistency_checker/platforminconsistencycheckerworker.h index 6be741b57..d9080e70a 100644 --- a/src/libsyncengine/reconciliation/platform_inconsistency_checker/platforminconsistencycheckerworker.h +++ b/src/libsyncengine/reconciliation/platform_inconsistency_checker/platforminconsistencycheckerworker.h @@ -31,13 +31,16 @@ class PlatformInconsistencyCheckerWorker : public OperationProcessor { void execute() override; private: - ExitCode checkTree(std::shared_ptr remoteNode, const SyncPath &parentPath); + ExitCode checkTree(ReplicaSide side); + ExitCode checkRemoteTree(std::shared_ptr remoteNode, const SyncPath &parentPath); + ExitCode checkLocalTree(std::shared_ptr localNode, const SyncPath &parentPath); - void blacklistNode(const std::shared_ptr remoteNode, const SyncPath &relativePath, - const InconsistencyType inconsistencyType); + void blacklistNode(const std::shared_ptr node, const InconsistencyType inconsistencyType); bool checkPathAndName(std::shared_ptr remoteNode); void checkNameClashAgainstSiblings(const std::shared_ptr &remoteParentNode); + bool pathChanged(std::shared_ptr node) const; + void removeLocalNodeFromDb(std::shared_ptr localNode); struct NodeIdPair { NodeId remoteId; NodeId localId; // Optional, only required if the file is already synchronized. diff --git a/src/libsyncengine/syncpal/syncpal.cpp b/src/libsyncengine/syncpal/syncpal.cpp index 8fd343c9e..1d6e0b16b 100644 --- a/src/libsyncengine/syncpal/syncpal.cpp +++ b/src/libsyncengine/syncpal/syncpal.cpp @@ -1036,8 +1036,7 @@ bool SyncPal::existOnServer(const SyncPath &path) const { bool SyncPal::canShareItem(const SyncPath &path) const { // Path is normalized on server side const SyncPath normalizedPath = Utility::normalizedSyncPath(path); - const NodeId nodeId = _remoteSnapshot->itemId(path); - if (!nodeId.empty()) { + if (const NodeId nodeId = _remoteSnapshot->itemId(normalizedPath); !nodeId.empty()) { return _remoteSnapshot->canShare(nodeId); } return false; @@ -1127,7 +1126,7 @@ ExitCode SyncPal::fixCorruptedFile(const std::unordered_map &l for (const auto &localFileInfo: localFileMap) { SyncPath destPath; if (ExitCode exitCode = PlatformInconsistencyCheckerUtility::renameLocalFile( - localFileInfo.second, PlatformInconsistencyCheckerUtility::SuffixTypeConflict, &destPath); + localFileInfo.second, PlatformInconsistencyCheckerUtility::SuffixType::Conflict, &destPath); exitCode != ExitCode::Ok) { LOGW_SYNCPAL_WARN(_logger, L"Fail to rename " << Path2WStr(localFileInfo.second).c_str() << L" into " << Path2WStr(destPath).c_str()); diff --git a/src/libsyncengine/update_detection/blacklist_changes_propagator/blacklistpropagator.cpp b/src/libsyncengine/update_detection/blacklist_changes_propagator/blacklistpropagator.cpp index 7f5009d87..5b6fb2a7a 100644 --- a/src/libsyncengine/update_detection/blacklist_changes_propagator/blacklistpropagator.cpp +++ b/src/libsyncengine/update_detection/blacklist_changes_propagator/blacklistpropagator.cpp @@ -246,7 +246,7 @@ ExitCode BlacklistPropagator::removeItem(const NodeId &localNodeId, const NodeId SyncPath destPath; PlatformInconsistencyCheckerUtility::renameLocalFile( - absolutePath, PlatformInconsistencyCheckerUtility::SuffixTypeBlacklisted, &destPath); + absolutePath, PlatformInconsistencyCheckerUtility::SuffixType::Blacklisted, &destPath); Error err(_syncPal->syncDbId(), "", "", NodeType::Directory, absolutePath, ConflictType::None, InconsistencyType::None, CancelType::MoveToBinFailed, destPath); diff --git a/src/libsyncengine/update_detection/file_system_observer/computefsoperationworker.cpp b/src/libsyncengine/update_detection/file_system_observer/computefsoperationworker.cpp index d5a44c1ae..52ce8171d 100644 --- a/src/libsyncengine/update_detection/file_system_observer/computefsoperationworker.cpp +++ b/src/libsyncengine/update_detection/file_system_observer/computefsoperationworker.cpp @@ -182,7 +182,7 @@ ExitCode ComputeFSOperationWorker::inferChangeFromDbNode(const ReplicaSide side, // Do not propagate delete if the path is too long. const size_t pathSize = localPath.native().size(); - if (PlatformInconsistencyCheckerUtility::instance()->checkPathLength(pathSize)) { + if (PlatformInconsistencyCheckerUtility::instance()->isPathTooLong(pathSize)) { LOGW_SYNCPAL_WARN(_logger, L"Path length too long (" << pathSize << L" characters) for item with " << Utility::formatSyncPath(localPath).c_str() << L". Item is ignored."); @@ -778,7 +778,7 @@ bool ComputeFSOperationWorker::isTooBig(const std::shared_ptr re bool ComputeFSOperationWorker::isPathTooLong(const SyncPath &path, const NodeId &nodeId, NodeType type) const { const SyncPath absolutePath = _syncPal->localPath() / path; const size_t pathSize = absolutePath.native().size(); - if (PlatformInconsistencyCheckerUtility::instance()->checkPathLength(pathSize)) { + if (PlatformInconsistencyCheckerUtility::instance()->isPathTooLong(pathSize)) { LOGW_SYNCPAL_WARN(_logger, L"Path length too long (" << pathSize << L" characters) for item with " << Utility::formatSyncPath(absolutePath).c_str() << L". Item is ignored."); 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 4c6d08264..23509e9e2 100644 --- a/src/libsyncengine/update_detection/file_system_observer/snapshot/snapshot.cpp +++ b/src/libsyncengine/update_detection/file_system_observer/snapshot/snapshot.cpp @@ -497,10 +497,11 @@ bool Snapshot::checkIntegrityRecursively(const NodeId &parentId) { auto result = names.insert(_items[*childId].name()); if (!result.second) { - LOG_ERROR(Log::instance()->getLogger(), - "Snapshot integrity check failed, the folder named: \"" - << SyncName2Str(parentItem.name()).c_str() << "\"(" << parentItem.id().c_str() << ") contains: \"" - << SyncName2Str(_items[*childId].name()).c_str() << "\" twice with two differents NodeId"); + 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() + << L"\" twice with two differents NodeId"); return false; } } diff --git a/src/libsyncengine/update_detection/update_detector/node.cpp b/src/libsyncengine/update_detection/update_detector/node.cpp index 80c967016..18cc1d69f 100644 --- a/src/libsyncengine/update_detection/update_detector/node.cpp +++ b/src/libsyncengine/update_detection/update_detector/node.cpp @@ -35,6 +35,12 @@ Node::Node(const std::optional &idb, const ReplicaSide &side, const Sy setParentNode(parentNode); } +Node::Node(const ReplicaSide &side, const SyncName &name, NodeType type, OperationType changeEvents, + const std::optional &id, std::optional createdAt, std::optional lastmodified, int64_t size, + std::shared_ptr parentNode, std::optional moveOrigin, std::optional moveOriginParentDbId) : + Node(std::nullopt, side, name, type, changeEvents, id, createdAt, lastmodified, size, parentNode, moveOrigin, + moveOriginParentDbId) {} + Node::Node(const ReplicaSide &side, const SyncName &name, NodeType type, std::shared_ptr parentNode) : _side(side), _name(name), _type(type), _isTmp(true) { _id = "tmp_" + CommonUtility::generateRandomStringAlphaNum(); diff --git a/src/libsyncengine/update_detection/update_detector/node.h b/src/libsyncengine/update_detection/update_detector/node.h index eb0786f06..d88687914 100644 --- a/src/libsyncengine/update_detection/update_detector/node.h +++ b/src/libsyncengine/update_detection/update_detector/node.h @@ -37,6 +37,11 @@ class Node { std::optional lastmodified, int64_t size, std::shared_ptr parentNode, std::optional moveOrigin = std::nullopt, std::optional moveOriginParentDbId = std::nullopt); + Node(const ReplicaSide &side, const SyncName &name, NodeType type, + OperationType changeEvents, const std::optional &id, std::optional createdAt, + std::optional lastmodified, int64_t size, std::shared_ptr parentNode, + std::optional moveOrigin = std::nullopt, std::optional moveOriginParentDbId = std::nullopt); + /** * @brief Node * diff --git a/src/server/vfs/mac/vfs_mac.cpp b/src/server/vfs/mac/vfs_mac.cpp index 1161dfbd9..40b705f92 100644 --- a/src/server/vfs/mac/vfs_mac.cpp +++ b/src/server/vfs/mac/vfs_mac.cpp @@ -53,17 +53,21 @@ VfsMac::VfsMac(KDC::VfsSetupParams &vfsSetupParams, QObject *parent) : throw std::runtime_error("Error getting LiteSyncExtConnector instance!"); } - // 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/libsyncengine/db/testsyncdb.cpp b/test/libsyncengine/db/testsyncdb.cpp index ffa656cc5..db221883f 100644 --- a/test/libsyncengine/db/testsyncdb.cpp +++ b/test/libsyncengine/db/testsyncdb.cpp @@ -277,6 +277,15 @@ void TestSyncDb::testUpgradeTo3_6_5() { ParmsDb::reset(); } +void TestSyncDb::testUpgradeTo3_6_7() { + createParmsDb(_testObj->dbPath(), SyncPath("local_sync_dir_does_not_exist")); + + CPPUNIT_ASSERT(_testObj->upgrade("3.6.4", "3.6.7")); + + ParmsDb::instance()->close(); + ParmsDb::reset(); +} + void TestSyncDb::testInit3_6_4() { SyncDbMock testDb(_testObj->dbPath().string(), "3.6.4"); const LocalTemporaryDirectory localTmpDir("testUpgradeTo3_6_5"); diff --git a/test/libsyncengine/db/testsyncdb.h b/test/libsyncengine/db/testsyncdb.h index 83ac05f74..9bc7dc7eb 100644 --- a/test/libsyncengine/db/testsyncdb.h +++ b/test/libsyncengine/db/testsyncdb.h @@ -40,6 +40,7 @@ class TestSyncDb : public CppUnit::TestFixture { CPPUNIT_TEST(testSyncNodes); CPPUNIT_TEST(testCorrespondingNodeId); CPPUNIT_TEST(testUpdateLocalName); + CPPUNIT_TEST(testUpgradeTo3_6_7); CPPUNIT_TEST(testUpgradeTo3_6_5CheckNodeMap); CPPUNIT_TEST(testUpgradeTo3_6_5); CPPUNIT_TEST(testInit3_6_4); @@ -54,6 +55,7 @@ class TestSyncDb : public CppUnit::TestFixture { void testSyncNodes(); void testCorrespondingNodeId(); void testUpdateLocalName(); + void testUpgradeTo3_6_7(); void testUpgradeTo3_6_5(); void testUpgradeTo3_6_5CheckNodeMap(); void testInit3_6_4(); diff --git a/test/libsyncengine/propagation/operation_sorter/testoperationsorterworker.cpp b/test/libsyncengine/propagation/operation_sorter/testoperationsorterworker.cpp index 74b3fe99a..19aca9f4d 100644 --- a/test/libsyncengine/propagation/operation_sorter/testoperationsorterworker.cpp +++ b/test/libsyncengine/propagation/operation_sorter/testoperationsorterworker.cpp @@ -53,15 +53,15 @@ void TestOperationSorterWorker::tearDown() { } void TestOperationSorterWorker::testMoveFirstAfterSecond() { - const auto node1 = std::make_shared(std::nullopt, ReplicaSide::Local, Str("1"), NodeType::Directory, + const auto node1 = std::make_shared(ReplicaSide::Local, Str("1"), NodeType::Directory, OperationType::None, std::nullopt, 0, 0, 12345, nullptr); - const auto node2 = std::make_shared(std::nullopt, ReplicaSide::Local, Str("2"), NodeType::Directory, + const auto node2 = std::make_shared(ReplicaSide::Local, Str("2"), NodeType::Directory, OperationType::None, std::nullopt, 0, 0, 12345, nullptr); - const auto node3 = std::make_shared(std::nullopt, ReplicaSide::Local, Str("3"), NodeType::Directory, + const auto node3 = std::make_shared(ReplicaSide::Local, Str("3"), NodeType::Directory, OperationType::None, std::nullopt, 0, 0, 12345, nullptr); - const auto node4 = std::make_shared(std::nullopt, ReplicaSide::Local, Str("4"), NodeType::Directory, + const auto node4 = std::make_shared(ReplicaSide::Local, Str("4"), NodeType::Directory, OperationType::None, std::nullopt, 0, 0, 12345, nullptr); - const auto node5 = std::make_shared(std::nullopt, ReplicaSide::Local, Str("5"), NodeType::Directory, + const auto node5 = std::make_shared(ReplicaSide::Local, Str("5"), NodeType::Directory, OperationType::None, std::nullopt, 0, 0, 12345, nullptr); const auto op1 = std::make_shared(); const auto op2 = std::make_shared(); diff --git a/test/libsyncengine/reconciliation/conflict_finder/testconflictfinderworker.cpp b/test/libsyncengine/reconciliation/conflict_finder/testconflictfinderworker.cpp index 1e62745b2..eb8192db1 100644 --- a/test/libsyncengine/reconciliation/conflict_finder/testconflictfinderworker.cpp +++ b/test/libsyncengine/reconciliation/conflict_finder/testconflictfinderworker.cpp @@ -521,7 +521,8 @@ void TestConflictFinderWorker::testCase55b() { _syncPal->updateTree(ReplicaSide::Remote)->insertNode(rNodeA); // Conflict Situation - nodeA->setChangeEvents(OperationType::Move | OperationType::Edit); + nodeA->setChangeEvents( + OperationType::Edit); nodeA->setMoveOrigin("A"); nodeA->setName(Str("B")); rNodeA->setChangeEvents(OperationType::Edit); diff --git a/test/libsyncengine/reconciliation/conflict_resolver/testconflictresolverworker.cpp b/test/libsyncengine/reconciliation/conflict_resolver/testconflictresolverworker.cpp index 0237a4970..e7183a0cd 100644 --- a/test/libsyncengine/reconciliation/conflict_resolver/testconflictresolverworker.cpp +++ b/test/libsyncengine/reconciliation/conflict_resolver/testconflictresolverworker.cpp @@ -138,7 +138,7 @@ void TestConflictResolverWorker::testCreateCreate() { std::shared_ptr rNodeAA = _syncPal->updateTree(ReplicaSide::Remote)->getNodeById("rAA"); std::shared_ptr rNodeAAB = - std::make_shared(std::nullopt, _syncPal->updateTree(ReplicaSide::Remote)->side(), Str("AAB.txt"), + std::make_shared(_syncPal->updateTree(ReplicaSide::Remote)->side(), Str("AAB.txt"), NodeType::File, OperationType::Create, "rAAB", testhelpers::defaultTime, testhelpers::defaultTime, testhelpers::defaultFileSize, rNodeAA); CPPUNIT_ASSERT(rNodeAA->insertChildren(rNodeAAB)); @@ -610,7 +610,7 @@ void TestConflictResolverWorker::testMoveMoveSource() { void TestConflictResolverWorker::testMoveMoveSourceWithOrphanNodes() { // Initial state : Node AAA is orphan. const SyncName orphanName = PlatformInconsistencyCheckerUtility::instance()->generateNewValidName( - "AAA", PlatformInconsistencyCheckerUtility::SuffixTypeOrphan); + "AAA", PlatformInconsistencyCheckerUtility::SuffixType::Orphan); std::shared_ptr lNodeAAA = _syncPal->updateTree(ReplicaSide::Local)->getNodeById("lAAA"); lNodeAAA->setName(orphanName); diff --git a/test/libsyncengine/reconciliation/platform_inconsistency_checker/testplatforminconsistencycheckerworker.cpp b/test/libsyncengine/reconciliation/platform_inconsistency_checker/testplatforminconsistencycheckerworker.cpp index 238e462e6..cbc98beea 100644 --- a/test/libsyncengine/reconciliation/platform_inconsistency_checker/testplatforminconsistencycheckerworker.cpp +++ b/test/libsyncengine/reconciliation/platform_inconsistency_checker/testplatforminconsistencycheckerworker.cpp @@ -81,47 +81,47 @@ void TestPlatformInconsistencyCheckerWorker::tearDown() { void TestPlatformInconsistencyCheckerWorker::testFixNameSize() { SyncName shortName = Str("1234567890"); - CPPUNIT_ASSERT(!PlatformInconsistencyCheckerUtility::instance()->checkNameSize(shortName)); + CPPUNIT_ASSERT(!PlatformInconsistencyCheckerUtility::instance()->isNameTooLong(shortName)); SyncName longName = Str( "12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456" "78901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012" "3456789012345678901234567890"); - CPPUNIT_ASSERT(PlatformInconsistencyCheckerUtility::instance()->checkNameSize(longName)); + CPPUNIT_ASSERT(PlatformInconsistencyCheckerUtility::instance()->isNameTooLong(longName)); } void TestPlatformInconsistencyCheckerWorker::testCheckNameForbiddenChars() { SyncName allowedName = Str("test-test"); - CPPUNIT_ASSERT(!PlatformInconsistencyCheckerUtility::instance()->checkNameForbiddenChars(allowedName)); + CPPUNIT_ASSERT(!PlatformInconsistencyCheckerUtility::instance()->nameHasForbiddenChars(allowedName)); SyncName forbiddenName = Str("test/test"); - CPPUNIT_ASSERT(PlatformInconsistencyCheckerUtility::instance()->checkNameForbiddenChars(forbiddenName)); + CPPUNIT_ASSERT(PlatformInconsistencyCheckerUtility::instance()->nameHasForbiddenChars(forbiddenName)); #if defined(WIN32) forbiddenName = Str("test\\test"); - CPPUNIT_ASSERT(PlatformInconsistencyCheckerUtility::instance()->checkNameForbiddenChars(forbiddenName)); + CPPUNIT_ASSERT(PlatformInconsistencyCheckerUtility::instance()->nameHasForbiddenChars(forbiddenName)); forbiddenName = Str("test:test"); - CPPUNIT_ASSERT(PlatformInconsistencyCheckerUtility::instance()->checkNameForbiddenChars(forbiddenName)); + CPPUNIT_ASSERT(PlatformInconsistencyCheckerUtility::instance()->nameHasForbiddenChars(forbiddenName)); forbiddenName = Str("test*test"); - CPPUNIT_ASSERT(PlatformInconsistencyCheckerUtility::instance()->checkNameForbiddenChars(forbiddenName)); + CPPUNIT_ASSERT(PlatformInconsistencyCheckerUtility::instance()->nameHasForbiddenChars(forbiddenName)); forbiddenName = Str("test?test"); - CPPUNIT_ASSERT(PlatformInconsistencyCheckerUtility::instance()->checkNameForbiddenChars(forbiddenName)); + CPPUNIT_ASSERT(PlatformInconsistencyCheckerUtility::instance()->nameHasForbiddenChars(forbiddenName)); forbiddenName = Str("test\"test"); - CPPUNIT_ASSERT(PlatformInconsistencyCheckerUtility::instance()->checkNameForbiddenChars(forbiddenName)); + CPPUNIT_ASSERT(PlatformInconsistencyCheckerUtility::instance()->nameHasForbiddenChars(forbiddenName)); forbiddenName = Str("testcheckNameForbiddenChars(forbiddenName)); + CPPUNIT_ASSERT(PlatformInconsistencyCheckerUtility::instance()->nameHasForbiddenChars(forbiddenName)); forbiddenName = Str("test>test"); - CPPUNIT_ASSERT(PlatformInconsistencyCheckerUtility::instance()->checkNameForbiddenChars(forbiddenName)); + CPPUNIT_ASSERT(PlatformInconsistencyCheckerUtility::instance()->nameHasForbiddenChars(forbiddenName)); forbiddenName = Str("test|test"); - CPPUNIT_ASSERT(PlatformInconsistencyCheckerUtility::instance()->checkNameForbiddenChars(forbiddenName)); + CPPUNIT_ASSERT(PlatformInconsistencyCheckerUtility::instance()->nameHasForbiddenChars(forbiddenName)); forbiddenName = Str("test\ntest"); - CPPUNIT_ASSERT(PlatformInconsistencyCheckerUtility::instance()->checkNameForbiddenChars(forbiddenName)); + CPPUNIT_ASSERT(PlatformInconsistencyCheckerUtility::instance()->nameHasForbiddenChars(forbiddenName)); forbiddenName = Str("test "); - CPPUNIT_ASSERT(PlatformInconsistencyCheckerUtility::instance()->checkNameForbiddenChars(forbiddenName)); + CPPUNIT_ASSERT(PlatformInconsistencyCheckerUtility::instance()->nameHasForbiddenChars(forbiddenName)); #elif defined(__unix__) && !defined(__APPLE__) forbiddenName = std::string("test"); forbiddenName.append(1, '\0'); - CPPUNIT_ASSERT(PlatformInconsistencyCheckerUtility::instance()->checkNameForbiddenChars(forbiddenName)); + CPPUNIT_ASSERT(PlatformInconsistencyCheckerUtility::instance()->nameHasForbiddenChars(forbiddenName)); #endif } @@ -145,14 +145,14 @@ void TestPlatformInconsistencyCheckerWorker::testCheckReservedNames() { } void TestPlatformInconsistencyCheckerWorker::testNameClash() { - const auto parentNode = std::make_shared(std::nullopt, _syncPal->updateTree(ReplicaSide::Remote)->side(), - Str("parentNode"), NodeType::Directory, OperationType::Create, "parentID", 0, - 0, 12345, _syncPal->updateTree(ReplicaSide::Remote)->rootNode()); + const auto parentNode = std::make_shared(_syncPal->updateTree(ReplicaSide::Remote)->side(), Str("parentNode"), + NodeType::Directory, OperationType::Create, "parentID", 0, 0, 12345, + _syncPal->updateTree(ReplicaSide::Remote)->rootNode()); - const auto nodeLower = std::make_shared(std::nullopt, _syncPal->updateTree(ReplicaSide::Remote)->side(), Str("a"), - NodeType::File, OperationType::Create, "a", 0, 0, 12345, parentNode); - const auto nodeUpper = std::make_shared(std::nullopt, _syncPal->updateTree(ReplicaSide::Remote)->side(), Str("A"), - NodeType::File, OperationType::Create, "A", 0, 0, 12345, parentNode); + const auto nodeLower = std::make_shared(_syncPal->updateTree(ReplicaSide::Remote)->side(), Str("a"), NodeType::File, + OperationType::Create, "a", 0, 0, 12345, parentNode); + const auto nodeUpper = std::make_shared(_syncPal->updateTree(ReplicaSide::Remote)->side(), Str("A"), NodeType::File, + OperationType::Create, "A", 0, 0, 12345, parentNode); CPPUNIT_ASSERT(parentNode->insertChildren(nodeLower)); CPPUNIT_ASSERT(parentNode->insertChildren(nodeUpper)); @@ -242,14 +242,14 @@ void TestPlatformInconsistencyCheckerWorker::testNameClashAfterRename() { } void TestPlatformInconsistencyCheckerWorker::testExecute() { - const auto parentNode = std::make_shared(std::nullopt, _syncPal->updateTree(ReplicaSide::Remote)->side(), - Str("parentNode"), NodeType::Directory, OperationType::Create, "parentID", 0, - 0, 12345, _syncPal->updateTree(ReplicaSide::Remote)->rootNode()); + const auto parentNode = std::make_shared(_syncPal->updateTree(ReplicaSide::Remote)->side(), Str("parentNode"), + NodeType::Directory, OperationType::Create, "parentID", 0, 0, 12345, + _syncPal->updateTree(ReplicaSide::Remote)->rootNode()); - const auto nodeLower = std::make_shared(std::nullopt, ReplicaSide::Remote, Str("a"), NodeType::File, - OperationType::Create, "a", 0, 0, 12345, parentNode); - const auto nodeUpper = std::make_shared(std::nullopt, ReplicaSide::Remote, Str("A"), NodeType::File, - OperationType::Create, "A", 0, 0, 12345, parentNode); + const auto nodeLower = std::make_shared(ReplicaSide::Remote, Str("a"), NodeType::File, OperationType::Create, "a", 0, 0, + 12345, parentNode); + const auto nodeUpper = std::make_shared(ReplicaSide::Remote, Str("A"), NodeType::File, OperationType::Create, "A", 0, 0, + 12345, parentNode); CPPUNIT_ASSERT(_syncPal->updateTree(ReplicaSide::Remote)->rootNode()->insertChildren(parentNode)); CPPUNIT_ASSERT(parentNode->insertChildren(nodeLower)); @@ -265,7 +265,14 @@ void TestPlatformInconsistencyCheckerWorker::testExecute() { !_syncPal->updateTree(ReplicaSide::Remote)->exists(*nodeLower->id())) || (!_syncPal->updateTree(ReplicaSide::Remote)->exists(*nodeUpper->id()) && _syncPal->updateTree(ReplicaSide::Remote)->exists(*nodeLower->id())); - + LOG_DEBUG(Log::instance()->getLogger(), + "TestPlatformInconsistencyCheckerWorker::testExecute()" + "Upper Node exists: " + << _syncPal->updateTree(ReplicaSide::Remote)->exists(*nodeUpper->id())); + LOG_DEBUG(Log::instance()->getLogger(), + "TestPlatformInconsistencyCheckerWorker::testExecute()" + "Lower Node exists: " + << _syncPal->updateTree(ReplicaSide::Remote)->exists(*nodeLower->id())); CPPUNIT_ASSERT(_syncPal->updateTree(ReplicaSide::Remote)->exists(*parentNode->id())); #if defined(WIN32) || defined(__APPLE__) @@ -276,4 +283,83 @@ void TestPlatformInconsistencyCheckerWorker::testExecute() { #endif } +void TestPlatformInconsistencyCheckerWorker::testNameSizeLocalTree() { + initUpdateTree(ReplicaSide::Local); + + _syncPal->_platformInconsistencyCheckerWorker->execute(); + + CPPUNIT_ASSERT(_syncPal->updateTree(ReplicaSide::Local)->exists("testNode")); + CPPUNIT_ASSERT(_syncPal->updateTree(ReplicaSide::Local)->exists("aNode")); + CPPUNIT_ASSERT(_syncPal->updateTree(ReplicaSide::Local)->exists("ANode")); + CPPUNIT_ASSERT(!_syncPal->updateTree(ReplicaSide::Local)->exists("longNameANode")); + CPPUNIT_ASSERT(!_syncPal->updateTree(ReplicaSide::Local)->exists("testNode2")); + CPPUNIT_ASSERT(!_syncPal->updateTree(ReplicaSide::Local)->exists("bNode")); + CPPUNIT_ASSERT(!_syncPal->updateTree(ReplicaSide::Local)->exists("BNode")); +} + +void TestPlatformInconsistencyCheckerWorker::initUpdateTree(ReplicaSide side) { + /* Initial tree structure: + * | + * +-- /test (dir) CREATE + * | | + * | +-- a.txt (file) CREATE + * | +-- A.txt (file) CREATE + * | +-- aaaaaaaaaaaaaaaaaaaa...aaaaaaaaaaaaaaaaaa.txt (file) [maxNameLengh +1] CREATE + * | + * +-- /testDiraaaaaaaaaaaaaaa...aaaaaaaaaaaaaaaaa (dir) [maxNameLengh +1] MOVE + * | | + * | +-- b.txt (file) NONE + * | +-- B.txt (file) NONE + */ + + const auto testNode = + std::make_shared(_syncPal->updateTree(side)->side(), Str2SyncName("test"), NodeType::Directory, + OperationType::Create, "testNode", 0, 0, 12345, _syncPal->updateTree(side)->rootNode()); + + const auto aNode = std::make_shared(_syncPal->updateTree(side)->side(), Str2SyncName("a.txt"), NodeType::File, + OperationType::Create, "aNode", 0, 0, 12345, testNode); + + const auto ANode = std::make_shared(_syncPal->updateTree(side)->side(), Str2SyncName("A.txt"), NodeType::File, + OperationType::Create, "ANode", 0, 0, 12345, testNode); + + const auto longNameANode = std::make_shared( + std::nullopt, _syncPal->updateTree(side)->side(), + Str2SyncName("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.txt"), + NodeType::File, OperationType::Create, "longNameANode", 0, 0, 12345, testNode); + + const auto testNode2 = std::make_shared( + std::nullopt, _syncPal->updateTree(side)->side(), + Str2SyncName("testDiraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"), + NodeType::Directory, OperationType::Move, "testNode2", 0, 0, 12345, _syncPal->updateTree(side)->rootNode()); + + const auto bNode = std::make_shared(_syncPal->updateTree(side)->side(), Str2SyncName("b.txt"), NodeType::File, + OperationType::None, "bNode", 0, 0, 12345, testNode2); + + const auto BNode = std::make_shared(_syncPal->updateTree(side)->side(), Str2SyncName("B.txt"), NodeType::File, + OperationType::None, "BNode", 0, 0, 12345, testNode2); + + + CPPUNIT_ASSERT(_syncPal->updateTree(side)->rootNode()->insertChildren(testNode)); + CPPUNIT_ASSERT(testNode->insertChildren(aNode)); + CPPUNIT_ASSERT(testNode->insertChildren(ANode)); + CPPUNIT_ASSERT(testNode->insertChildren(longNameANode)); + CPPUNIT_ASSERT(_syncPal->updateTree(side)->rootNode()->insertChildren(testNode2)); + CPPUNIT_ASSERT(testNode2->insertChildren(bNode)); + CPPUNIT_ASSERT(testNode2->insertChildren(BNode)); + + _syncPal->updateTree(side)->insertNode(testNode); + _syncPal->updateTree(side)->insertNode(aNode); + _syncPal->updateTree(side)->insertNode(ANode); + _syncPal->updateTree(side)->insertNode(longNameANode); + _syncPal->updateTree(side)->insertNode(testNode2); + _syncPal->updateTree(side)->insertNode(bNode); + _syncPal->updateTree(side)->insertNode(BNode); +} + } // namespace KDC diff --git a/test/libsyncengine/reconciliation/platform_inconsistency_checker/testplatforminconsistencycheckerworker.h b/test/libsyncengine/reconciliation/platform_inconsistency_checker/testplatforminconsistencycheckerworker.h index dc2bda874..8402ddc87 100644 --- a/test/libsyncengine/reconciliation/platform_inconsistency_checker/testplatforminconsistencycheckerworker.h +++ b/test/libsyncengine/reconciliation/platform_inconsistency_checker/testplatforminconsistencycheckerworker.h @@ -34,6 +34,7 @@ class TestPlatformInconsistencyCheckerWorker : public CppUnit::TestFixture { CPPUNIT_TEST(testNameClash); CPPUNIT_TEST(testNameClashAfterRename); CPPUNIT_TEST(testExecute); + CPPUNIT_TEST(testNameSizeLocalTree); CPPUNIT_TEST_SUITE_END(); public: @@ -47,10 +48,12 @@ class TestPlatformInconsistencyCheckerWorker : public CppUnit::TestFixture { void testNameClash(); void testNameClashAfterRename(); void testExecute(); + void testNameSizeLocalTree(); private: std::shared_ptr _syncPal{nullptr}; LocalTemporaryDirectory _tempDir{"testNameClashAfterRename"}; + void initUpdateTree(ReplicaSide side); }; } // namespace KDC diff --git a/test/libsyncengine/syncpal/testsyncpal.cpp b/test/libsyncengine/syncpal/testsyncpal.cpp index a0d3ad3a4..2bd94831b 100644 --- a/test/libsyncengine/syncpal/testsyncpal.cpp +++ b/test/libsyncengine/syncpal/testsyncpal.cpp @@ -152,6 +152,53 @@ void TestSyncPal::testCopySnapshots() { CPPUNIT_ASSERT(_syncPal->snapshot(ReplicaSide::Local, true)->isValid() != _syncPal->snapshot(ReplicaSide::Local, false)->isValid()); } +void TestSyncPal::testSyncFileItem() { + _syncPal->_progressInfo = std::make_shared(_syncPal); + + CPPUNIT_ASSERT_EQUAL(static_cast(0), _syncPal->_progressInfo->completedSize()); + CPPUNIT_ASSERT_EQUAL(static_cast(0), _syncPal->_progressInfo->completedFiles()); + CPPUNIT_ASSERT_EQUAL(static_cast(0), _syncPal->_progressInfo->totalSize()); + CPPUNIT_ASSERT_EQUAL(static_cast(0), _syncPal->_progressInfo->totalFiles()); + + const SyncPath nfcPath = SyncPath(Str("/") + testhelpers::makeNfcSyncName() + Str("/test.txt")).native(); + const SyncPath nfdPath = SyncPath(Str("/") + testhelpers::makeNfdSyncName() + Str("/test.txt")).native(); + SyncFileItem initItem; + initItem.setType(NodeType::File); + initItem.setPath(nfcPath); + initItem.setLocalNodeId("l123"); + initItem.setDirection(SyncDirection::Up); + initItem.setInstruction(SyncFileInstruction::Put); + initItem.setSize(testhelpers::defaultFileSize); + initItem.setModTime(testhelpers::defaultTime); + _syncPal->initProgress(initItem); + + SyncFileItem testItem; + CPPUNIT_ASSERT(_syncPal->getSyncFileItem(nfcPath, testItem)); + CPPUNIT_ASSERT(testItem == initItem); + CPPUNIT_ASSERT(_syncPal->getSyncFileItem(nfdPath, testItem)); + CPPUNIT_ASSERT(testItem == initItem); + + CPPUNIT_ASSERT_EQUAL(static_cast(0), _syncPal->_progressInfo->completedSize()); + CPPUNIT_ASSERT_EQUAL(static_cast(0), _syncPal->_progressInfo->completedFiles()); + CPPUNIT_ASSERT_EQUAL(testhelpers::defaultFileSize, _syncPal->_progressInfo->totalSize()); + CPPUNIT_ASSERT_EQUAL(static_cast(1), _syncPal->_progressInfo->totalFiles()); + + constexpr int64_t progress = 15; + _syncPal->setProgress(nfdPath, progress); + CPPUNIT_ASSERT(_syncPal->getSyncFileItem(nfdPath, testItem)); + + CPPUNIT_ASSERT_EQUAL(progress, _syncPal->_progressInfo->completedSize()); + CPPUNIT_ASSERT_EQUAL(static_cast(0), _syncPal->_progressInfo->completedFiles()); + CPPUNIT_ASSERT_EQUAL(testhelpers::defaultFileSize, _syncPal->_progressInfo->totalSize()); + CPPUNIT_ASSERT_EQUAL(static_cast(1), _syncPal->_progressInfo->totalFiles()); + + _syncPal->setProgressComplete(nfdPath, SyncFileStatus::Success); + + CPPUNIT_ASSERT_EQUAL(testhelpers::defaultFileSize, _syncPal->_progressInfo->completedSize()); + CPPUNIT_ASSERT_EQUAL(static_cast(1), _syncPal->_progressInfo->completedFiles()); + CPPUNIT_ASSERT_EQUAL(testhelpers::defaultFileSize, _syncPal->_progressInfo->totalSize()); + CPPUNIT_ASSERT_EQUAL(static_cast(1), _syncPal->_progressInfo->totalFiles()); +} void TestSyncPal::testAll() { // Start sync diff --git a/test/libsyncengine/syncpal/testsyncpal.h b/test/libsyncengine/syncpal/testsyncpal.h index 33a6cb05a..3cf550aa2 100644 --- a/test/libsyncengine/syncpal/testsyncpal.h +++ b/test/libsyncengine/syncpal/testsyncpal.h @@ -30,6 +30,7 @@ class TestSyncPal : public CppUnit::TestFixture { CPPUNIT_TEST(testSnapshot); CPPUNIT_TEST(testCopySnapshots); CPPUNIT_TEST(testOperationSet); + CPPUNIT_TEST(testSyncFileItem); CPPUNIT_TEST_SUITE_END(); public: @@ -50,6 +51,8 @@ class TestSyncPal : public CppUnit::TestFixture { void testOperationSet(); void testCopySnapshots(); + void testSyncFileItem(); + void testAll(); void testConflictQueue(); bool exec_case_6_4(); diff --git a/test/libsyncengine/update_detection/update_detector/testupdatetree.cpp b/test/libsyncengine/update_detection/update_detector/testupdatetree.cpp index 80a11b9bf..5a4d57a58 100644 --- a/test/libsyncengine/update_detection/update_detector/testupdatetree.cpp +++ b/test/libsyncengine/update_detection/update_detector/testupdatetree.cpp @@ -69,12 +69,12 @@ void TestUpdateTree::testConstructors() { void TestUpdateTree::testInsertionOfFileNamesWithDifferentEncodings() { CPPUNIT_ASSERT(_myTree->_nodes.empty()); - auto node1 = std::make_shared(std::nullopt, _myTree->side(), Str("Dir 1"), NodeType::Directory, OperationType::None, + auto node1 = std::make_shared(_myTree->side(), Str("Dir 1"), NodeType::Directory, OperationType::None, "l1", 0, 0, 12345, _myTree->rootNode()); - const auto node2 = std::make_shared(std::nullopt, _myTree->side(), testhelpers::makeNfcSyncName(), NodeType::Directory, + const auto node2 = std::make_shared(_myTree->side(), testhelpers::makeNfcSyncName(), NodeType::Directory, OperationType::None, "l2", 0, 0, 12345, node1); - const auto node3 = std::make_shared(std::nullopt, _myTree->side(), testhelpers::makeNfdSyncName(), NodeType::Directory, + const auto node3 = std::make_shared(_myTree->side(), testhelpers::makeNfdSyncName(), NodeType::Directory, OperationType::None, "l3", 0, 0, 12345, node1); CPPUNIT_ASSERT_EQUAL(SyncPath("Dir 1") / testhelpers::makeNfcSyncName(), node2->getPath()); @@ -83,31 +83,31 @@ void TestUpdateTree::testInsertionOfFileNamesWithDifferentEncodings() { void TestUpdateTree::testAll() { CPPUNIT_ASSERT(_myTree->_nodes.empty()); - auto node1 = std::make_shared(std::nullopt, _myTree->side(), Str("Dir 1"), NodeType::Directory, OperationType::None, + auto node1 = std::make_shared(_myTree->side(), Str("Dir 1"), NodeType::Directory, OperationType::None, "l1", 0, 0, 12345, _myTree->rootNode()); _myTree->insertNode(node1); CPPUNIT_ASSERT(_myTree->_nodes.size() == 1); - auto node2 = std::make_shared(std::nullopt, _myTree->side(), Str("Dir 2"), NodeType::Directory, OperationType::None, + auto node2 = std::make_shared(_myTree->side(), Str("Dir 2"), NodeType::Directory, OperationType::None, "l2", 0, 0, 12345, _myTree->rootNode()); - auto node3 = std::make_shared(std::nullopt, _myTree->side(), Str("Dir 3"), NodeType::Directory, OperationType::None, + auto node3 = std::make_shared(_myTree->side(), Str("Dir 3"), NodeType::Directory, OperationType::None, "l3", 0, 0, 12345, _myTree->rootNode()); - auto node4 = std::make_shared(std::nullopt, _myTree->side(), Str("Dir 4"), NodeType::Directory, OperationType::None, + auto node4 = std::make_shared(_myTree->side(), Str("Dir 4"), NodeType::Directory, OperationType::None, "l4", 0, 0, 12345, _myTree->rootNode()); - auto node11 = std::make_shared(std::nullopt, _myTree->side(), Str("Dir 1.1"), NodeType::Directory, OperationType::None, + auto node11 = std::make_shared(_myTree->side(), Str("Dir 1.1"), NodeType::Directory, OperationType::None, "l11", 0, 0, 12345, node1); - auto node111 = std::make_shared(std::nullopt, _myTree->side(), Str("Dir 1.1.1"), NodeType::Directory, + auto node111 = std::make_shared(_myTree->side(), Str("Dir 1.1.1"), NodeType::Directory, OperationType::None, "l111", 0, 0, 12345, node11); - auto node1111 = std::make_shared(std::nullopt, _myTree->side(), Str("File 1.1.1.1"), NodeType::File, + auto node1111 = std::make_shared(_myTree->side(), Str("File 1.1.1.1"), NodeType::File, OperationType::None, "l1111", 0, 0, 12345, node111); - auto node31 = std::make_shared(std::nullopt, _myTree->side(), Str("Dir 3.1"), NodeType::Directory, OperationType::None, + auto node31 = std::make_shared(_myTree->side(), Str("Dir 3.1"), NodeType::Directory, OperationType::None, "l31", 0, 0, 12345, node3); - auto node41 = std::make_shared(std::nullopt, _myTree->side(), Str("Dir 4.1"), NodeType::Directory, OperationType::None, + auto node41 = std::make_shared(_myTree->side(), Str("Dir 4.1"), NodeType::Directory, OperationType::None, "l41", 0, 0, 12345, node4); - auto node411 = std::make_shared(std::nullopt, _myTree->side(), Str("Dir 4.1.1"), NodeType::Directory, + auto node411 = std::make_shared(_myTree->side(), Str("Dir 4.1.1"), NodeType::Directory, OperationType::None, "l411", 0, 0, 12345, node41); - auto node4111 = std::make_shared(std::nullopt, _myTree->side(), Str("File 4.1.1.1"), NodeType::File, + auto node4111 = std::make_shared(_myTree->side(), Str("File 4.1.1.1"), NodeType::File, OperationType::None, "l4111", 0, 0, 12345, node411); CPPUNIT_ASSERT(_myTree->rootNode()->insertChildren(node1)); @@ -142,22 +142,22 @@ void TestUpdateTree::testAll() { } void TestUpdateTree::testChangeEvents() { - std::shared_ptr node = std::make_shared(std::nullopt, _myTree->side(), Str("Dir 0"), NodeType::Directory, + std::shared_ptr node = std::make_shared(_myTree->side(), Str("Dir 0"), NodeType::Directory, OperationType::None, "0", 0, 0, 12345, _myTree->rootNode()); const std::shared_ptr nodeCreate = - std::make_shared(std::nullopt, _myTree->side(), Str("Dir 1"), NodeType::Directory, OperationType::Create, "l1", + std::make_shared(_myTree->side(), Str("Dir 1"), NodeType::Directory, OperationType::Create, "l1", 0, 0, 12345, _myTree->rootNode()); const std::shared_ptr nodeEdit = - std::make_shared(std::nullopt, _myTree->side(), Str("Dir 2"), NodeType::Directory, OperationType::Edit, "l2", 0, + std::make_shared(_myTree->side(), Str("Dir 2"), NodeType::Directory, OperationType::Edit, "l2", 0, 0, 12345, _myTree->rootNode()); const std::shared_ptr nodeMove = - std::make_shared(std::nullopt, _myTree->side(), Str("Dir 3"), NodeType::Directory, OperationType::Move, "l3", 0, + std::make_shared(_myTree->side(), Str("Dir 3"), NodeType::Directory, OperationType::Move, "l3", 0, 0, 12345, _myTree->rootNode()); const std::shared_ptr nodeDelete = - std::make_shared(std::nullopt, _myTree->side(), Str("Dir 4"), NodeType::Directory, OperationType::Delete, "l4", + std::make_shared(_myTree->side(), Str("Dir 4"), NodeType::Directory, OperationType::Delete, "l4", 0, 0, 12345, _myTree->rootNode()); const std::shared_ptr nodeMoveEdit = - std::make_shared(std::nullopt, _myTree->side(), Str("Dir 5"), NodeType::Directory, + std::make_shared(_myTree->side(), Str("Dir 5"), NodeType::Directory, OperationType::Move | OperationType::Edit, "l5", 0, 0, 12345, _myTree->rootNode()); CPPUNIT_ASSERT(!node->hasChangeEvent()); diff --git a/test/server/workers/testworkers.cpp b/test/server/workers/testworkers.cpp index a40b2dcee..e7bb3dc85 100644 --- a/test/server/workers/testworkers.cpp +++ b/test/server/workers/testworkers.cpp @@ -174,7 +174,7 @@ void TestWorkers::testCreatePlaceholder() { CPPUNIT_ASSERT_EQUAL(exitInfo.code(), ExitCode::Ok); CPPUNIT_ASSERT_EQUAL(exitInfo.cause(), ExitCause::Unknown); -#if defined(__APPLE__) && defined(__WIN32) +#if defined(__APPLE__) || defined(__WIN32) // Folder already exists exitInfo = _syncPal->_executorWorker->createPlaceholder(relativeFolderPath); CPPUNIT_ASSERT_EQUAL(exitInfo.code(), ExitCode::DataError); @@ -191,7 +191,7 @@ void TestWorkers::testCreatePlaceholder() { 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) && @@ -211,7 +211,7 @@ void TestWorkers::testCreatePlaceholder() { CPPUNIT_ASSERT_EQUAL(exitInfo.code(), ExitCode::Ok); CPPUNIT_ASSERT_EQUAL(exitInfo.cause(), ExitCause::Unknown); -#if defined(__APPLE__) && defined(__WIN32) +#if defined(__APPLE__) || defined(__WIN32) // File already exists exitInfo = _syncPal->_executorWorker->createPlaceholder(relativeFilePath); CPPUNIT_ASSERT_EQUAL(exitInfo.code(), ExitCode::DataError); @@ -239,7 +239,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 exitInfo = _syncPal->_executorWorker->convertToPlaceholder(relativeFolderPath, true); CPPUNIT_ASSERT_EQUAL(exitInfo.code(), ExitCode::DataError); @@ -264,7 +264,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) &&