From 1f3ed48dec00517daa67713161b5b0f09dc1b7cb Mon Sep 17 00:00:00 2001 From: Herve Eruam Date: Tue, 8 Oct 2024 08:18:19 +0200 Subject: [PATCH 1/5] Change UploadSessionType def. --- src/libcommon/utility/types.cpp | 8 ++++---- src/libcommon/utility/types.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/libcommon/utility/types.cpp b/src/libcommon/utility/types.cpp index 9982d77ee..061291918 100644 --- a/src/libcommon/utility/types.cpp +++ b/src/libcommon/utility/types.cpp @@ -343,10 +343,10 @@ std::string toString(const UploadSessionType e) { switch (e) { case UploadSessionType::Unknown: return "Unknown"; - case UploadSessionType::Standard: - return "Standard"; - case UploadSessionType::LogUpload: - return "LogUpload"; + case UploadSessionType::Drive: + return "Drive"; + case UploadSessionType::Log: + return "Log"; default: return noConversionStr; } diff --git a/src/libcommon/utility/types.h b/src/libcommon/utility/types.h index 8aae3d573..6b61d593b 100644 --- a/src/libcommon/utility/types.h +++ b/src/libcommon/utility/types.h @@ -288,7 +288,7 @@ enum class SyncStatus { }; std::string toString(SyncStatus e); -enum class UploadSessionType { Unknown, Standard, LogUpload }; +enum class UploadSessionType { Unknown, Drive, Log }; std::string toString(UploadSessionType e); enum class SyncNodeType { From ae7bfd70f6a825ab6514526d2ad1ba2d88e70339 Mon Sep 17 00:00:00 2001 From: Herve Eruam Date: Tue, 8 Oct 2024 08:20:44 +0200 Subject: [PATCH 2/5] Apply the UploadSessionType def in code base --- .../upload_session/abstractuploadsessionjob.cpp | 4 ++-- .../API_v2/upload_session/driveuploadsession.cpp | 8 ++++---- .../API_v2/upload_session/loguploadsession.cpp | 12 ++++++------ .../API_v2/upload_session/uploadsessionstartjob.cpp | 4 ++-- src/libsyncengine/syncpal/syncpal.cpp | 2 +- src/server/appserver.cpp | 2 +- 6 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/libsyncengine/jobs/network/API_v2/upload_session/abstractuploadsessionjob.cpp b/src/libsyncengine/jobs/network/API_v2/upload_session/abstractuploadsessionjob.cpp index 76a853ea2..8ea814794 100644 --- a/src/libsyncengine/jobs/network/API_v2/upload_session/abstractuploadsessionjob.cpp +++ b/src/libsyncengine/jobs/network/API_v2/upload_session/abstractuploadsessionjob.cpp @@ -21,10 +21,10 @@ namespace KDC { AbstractUploadSessionJob::AbstractUploadSessionJob(UploadSessionType uploadType, int driveDbId) : - AbstractTokenNetworkJob(uploadType == UploadSessionType::Standard ? ApiType::Drive : ApiType::Desktop, 0, 0, driveDbId, 0) {} + AbstractTokenNetworkJob(uploadType == UploadSessionType::Drive ? ApiType::Drive : ApiType::Desktop, 0, 0, driveDbId, 0) {} AbstractUploadSessionJob::AbstractUploadSessionJob(UploadSessionType uploadType, int driveDbId, const SyncPath &filepath, const std::string &sessionToken) : - AbstractTokenNetworkJob(uploadType == UploadSessionType::Standard ? ApiType::Drive : ApiType::Desktop, 0, 0, driveDbId, 0), + AbstractTokenNetworkJob(uploadType == UploadSessionType::Drive ? ApiType::Drive : ApiType::Desktop, 0, 0, driveDbId, 0), _sessionToken(sessionToken), _filePath(filepath) {} } // namespace KDC diff --git a/src/libsyncengine/jobs/network/API_v2/upload_session/driveuploadsession.cpp b/src/libsyncengine/jobs/network/API_v2/upload_session/driveuploadsession.cpp index bbf574cdd..1e3808a27 100644 --- a/src/libsyncengine/jobs/network/API_v2/upload_session/driveuploadsession.cpp +++ b/src/libsyncengine/jobs/network/API_v2/upload_session/driveuploadsession.cpp @@ -26,7 +26,7 @@ DriveUploadSession::DriveUploadSession(int driveDbId, std::shared_ptr sy bool liteSyncActivated, uint64_t nbParalleleThread /*= 1*/) : AbstractUploadSession(filepath, filename, nbParalleleThread), _driveDbId(driveDbId), _syncDb(syncDb), _modtimeIn(modtime), _remoteParentDirId(remoteParentDirId) { - _uploadSessionType = UploadSessionType::Standard; + _uploadSessionType = UploadSessionType::Drive; } DriveUploadSession::~DriveUploadSession() { @@ -46,17 +46,17 @@ std::shared_ptr DriveUploadSession::createStartJob() { std::shared_ptr DriveUploadSession::createChunkJob(const std::string &chunckContent, uint64_t chunkNb, std::streamsize actualChunkSize) { - return std::make_shared(UploadSessionType::Standard, _driveDbId, getFilePath(), getSessionToken(), + return std::make_shared(UploadSessionType::Drive, _driveDbId, getFilePath(), getSessionToken(), chunckContent, chunkNb, actualChunkSize, jobId()); } std::shared_ptr DriveUploadSession::createFinishJob() { - return std::make_shared(UploadSessionType::Standard, _driveDbId, getFilePath(), getSessionToken(), + return std::make_shared(UploadSessionType::Drive, _driveDbId, getFilePath(), getSessionToken(), getTotalChunkHash(), getTotalChunks(), _modtimeIn); } std::shared_ptr DriveUploadSession::createCancelJob() { - return std::make_shared(UploadSessionType::Standard, _driveDbId, getFilePath(), getSessionToken()); + return std::make_shared(UploadSessionType::Drive, _driveDbId, getFilePath(), getSessionToken()); } bool DriveUploadSession::handleStartJobResult(const std::shared_ptr &StartJob, std::string uploadToken) { diff --git a/src/libsyncengine/jobs/network/API_v2/upload_session/loguploadsession.cpp b/src/libsyncengine/jobs/network/API_v2/upload_session/loguploadsession.cpp index 2a2147ba7..9b0dbf982 100644 --- a/src/libsyncengine/jobs/network/API_v2/upload_session/loguploadsession.cpp +++ b/src/libsyncengine/jobs/network/API_v2/upload_session/loguploadsession.cpp @@ -24,7 +24,7 @@ namespace KDC { LogUploadSession::LogUploadSession(const SyncPath &filepath, uint64_t nbParalleleThread /*= 1*/) : AbstractUploadSession(filepath, filepath.filename(), nbParalleleThread) { - _uploadSessionType = UploadSessionType::LogUpload; + _uploadSessionType = UploadSessionType::Log; } bool LogUploadSession::runJobInit() { @@ -32,12 +32,12 @@ bool LogUploadSession::runJobInit() { } std::shared_ptr LogUploadSession::createStartJob() { - return std::make_shared(UploadSessionType::LogUpload, getFileName(), getFileSize(), getTotalChunks()); + return std::make_shared(UploadSessionType::Log, getFileName(), getFileSize(), getTotalChunks()); } std::shared_ptr LogUploadSession::createChunkJob(const std::string &chunckContent, uint64_t chunkNb, std::streamsize actualChunkSize) { - return std::make_shared(UploadSessionType::LogUpload, getFilePath(), getSessionToken(), chunckContent, + return std::make_shared(UploadSessionType::Log, getFilePath(), getSessionToken(), chunckContent, chunkNb, actualChunkSize, jobId()); } @@ -45,12 +45,12 @@ std::shared_ptr LogUploadSession::createFinishJob() { SyncTime modtimeIn = std::chrono::time_point_cast(std::chrono::system_clock::now()).time_since_epoch().count(); - return std::make_shared(UploadSessionType::LogUpload, getFilePath(), getSessionToken(), + return std::make_shared(UploadSessionType::Log, getFilePath(), getSessionToken(), getTotalChunkHash(), getTotalChunks(), modtimeIn); } std::shared_ptr LogUploadSession::createCancelJob() { - return std::make_shared(UploadSessionType::LogUpload, getSessionToken()); + return std::make_shared(UploadSessionType::Log, getSessionToken()); } bool LogUploadSession::handleStartJobResult(const std::shared_ptr &StartJob, std::string uploadToken) { @@ -60,7 +60,7 @@ bool LogUploadSession::handleStartJobResult(const std::shared_ptr(appStateValue); !logUploadToken.empty()) { - UploadSessionCancelJob cancelJob(UploadSessionType::LogUpload, logUploadToken); + UploadSessionCancelJob cancelJob(UploadSessionType::Log, logUploadToken); if (const ExitCode exitCode = cancelJob.runSynchronously(); exitCode != ExitCode::Ok) { LOG_WARN(getLogger(), "Error in UploadSessionCancelJob::runSynchronously : " << exitCode); } else { diff --git a/src/libsyncengine/jobs/network/API_v2/upload_session/uploadsessionstartjob.cpp b/src/libsyncengine/jobs/network/API_v2/upload_session/uploadsessionstartjob.cpp index b348fafe2..5f460bbe2 100644 --- a/src/libsyncengine/jobs/network/API_v2/upload_session/uploadsessionstartjob.cpp +++ b/src/libsyncengine/jobs/network/API_v2/upload_session/uploadsessionstartjob.cpp @@ -51,7 +51,7 @@ void UploadSessionStartJob::setData(bool &canceled) { auto timestamp = duration_cast(time_point_cast(system_clock::now()).time_since_epoch()); switch (_uploadType) { - case UploadSessionType::Standard: + case UploadSessionType::Drive: if (_fileId.empty()) { json.set("file_name", _filename); json.set("directory_id", _remoteParentDirId); @@ -59,7 +59,7 @@ void UploadSessionStartJob::setData(bool &canceled) { json.set("file_id", _fileId); } break; - case UploadSessionType::LogUpload: + case UploadSessionType::Log: json.set("last_modified_at", timestamp.count()); json.set("file_name", _filename); break; diff --git a/src/libsyncengine/syncpal/syncpal.cpp b/src/libsyncengine/syncpal/syncpal.cpp index c2f8f9376..dd21cefb3 100644 --- a/src/libsyncengine/syncpal/syncpal.cpp +++ b/src/libsyncengine/syncpal/syncpal.cpp @@ -1292,7 +1292,7 @@ ExitCode SyncPal::cleanOldUploadSessionTokens() { for (auto &uploadSessionToken: uploadSessionTokenList) { try { - auto job = std::make_shared(UploadSessionType::Standard, driveDbId(), "", + auto job = std::make_shared(UploadSessionType::Drive, driveDbId(), "", uploadSessionToken.token()); ExitCode exitCode = job->runSynchronously(); if (exitCode != ExitCode::Ok) { diff --git a/src/server/appserver.cpp b/src/server/appserver.cpp index 32575b4c2..7f851b6c4 100644 --- a/src/server/appserver.cpp +++ b/src/server/appserver.cpp @@ -359,7 +359,7 @@ AppServer::AppServer(int &argc, char **argv) : } if (const auto logUploadToken = std::get(appStateValue); !logUploadToken.empty()) { - UploadSessionCancelJob cancelJob(UploadSessionType::LogUpload, logUploadToken); + UploadSessionCancelJob cancelJob(UploadSessionType::Log, logUploadToken); if (const ExitCode exitCode = cancelJob.runSynchronously(); exitCode != ExitCode::Ok) { LOG_WARN(_logger, "Error in UploadSessionCancelJob::runSynchronously : " << exitCode); } else { From 490238e758fa037e9d491909928218d8e58563fd Mon Sep 17 00:00:00 2001 From: Herve Eruam Date: Tue, 8 Oct 2024 08:22:26 +0200 Subject: [PATCH 3/5] Add DriveUploadSession constructor for edits. --- .../network/API_v2/upload_session/driveuploadsession.cpp | 6 ++++++ .../jobs/network/API_v2/upload_session/driveuploadsession.h | 6 ++++++ .../network/API_v2/upload_session/uploadsessionstartjob.h | 2 +- 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/libsyncengine/jobs/network/API_v2/upload_session/driveuploadsession.cpp b/src/libsyncengine/jobs/network/API_v2/upload_session/driveuploadsession.cpp index 1e3808a27..165065c49 100644 --- a/src/libsyncengine/jobs/network/API_v2/upload_session/driveuploadsession.cpp +++ b/src/libsyncengine/jobs/network/API_v2/upload_session/driveuploadsession.cpp @@ -20,6 +20,12 @@ #include "utility/utility.h" namespace KDC { +DriveUploadSession::DriveUploadSession(int driveDbId, std::shared_ptr syncDb, const SyncPath &filepath, + const NodeId &fileId, SyncTime modtime, bool liteSyncActivated, + uint64_t nbParalleleThread /*= 1*/) : + DriveUploadSession(driveDbId, syncDb, filepath, SyncName(), fileId, modtime, liteSyncActivated, nbParalleleThread) { + _fileId = fileId; +} DriveUploadSession::DriveUploadSession(int driveDbId, std::shared_ptr syncDb, const SyncPath &filepath, const SyncName &filename, const NodeId &remoteParentDirId, SyncTime modtime, diff --git a/src/libsyncengine/jobs/network/API_v2/upload_session/driveuploadsession.h b/src/libsyncengine/jobs/network/API_v2/upload_session/driveuploadsession.h index 01c44ca53..99a206424 100644 --- a/src/libsyncengine/jobs/network/API_v2/upload_session/driveuploadsession.h +++ b/src/libsyncengine/jobs/network/API_v2/upload_session/driveuploadsession.h @@ -28,6 +28,12 @@ namespace KDC { class DriveUploadSession : public AbstractUploadSession { public: + // Using file ID, for file edition only. + DriveUploadSession(int driveDbId, std::shared_ptr syncDb, const SyncPath &filepath, const NodeId &fileId, + SyncTime modtime, bool liteSyncActivated, + uint64_t nbParalleleThread = 1); + + // Using file name and parent ID, for file creation only. DriveUploadSession(int driveDbId, std::shared_ptr syncDb, const SyncPath &filepath, const SyncName &filename, const NodeId &remoteParentDirId, SyncTime modtime, bool liteSyncActivated, uint64_t nbParalleleThread = 1); diff --git a/src/libsyncengine/jobs/network/API_v2/upload_session/uploadsessionstartjob.h b/src/libsyncengine/jobs/network/API_v2/upload_session/uploadsessionstartjob.h index e4cebfc6a..0874a8ecb 100644 --- a/src/libsyncengine/jobs/network/API_v2/upload_session/uploadsessionstartjob.h +++ b/src/libsyncengine/jobs/network/API_v2/upload_session/uploadsessionstartjob.h @@ -25,7 +25,7 @@ namespace KDC { class UploadSessionStartJob : public AbstractUploadSessionJob { public: - // Using file name and parent ID, for create or edit + // Using file name and parent ID, for create only UploadSessionStartJob(UploadSessionType uploadType, int driveDbId, const SyncName &filename, uint64_t size, const NodeId &remoteParentDirId, uint64_t totalChunks); // Using file ID, for edit only From d0ac770150b9c1ea104343942a9df9daec755830 Mon Sep 17 00:00:00 2001 From: Herve Eruam Date: Tue, 8 Oct 2024 08:23:25 +0200 Subject: [PATCH 4/5] Use the right DriveUploadSession & UploadSessionStartJob constructor when editing a file in executorWorker. --- .../upload_session/driveuploadsession.cpp | 9 ++++-- .../propagation/executor/executorworker.cpp | 29 +++++++++---------- 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/src/libsyncengine/jobs/network/API_v2/upload_session/driveuploadsession.cpp b/src/libsyncengine/jobs/network/API_v2/upload_session/driveuploadsession.cpp index 165065c49..617baca75 100644 --- a/src/libsyncengine/jobs/network/API_v2/upload_session/driveuploadsession.cpp +++ b/src/libsyncengine/jobs/network/API_v2/upload_session/driveuploadsession.cpp @@ -46,8 +46,13 @@ bool DriveUploadSession::runJobInit() { } std::shared_ptr DriveUploadSession::createStartJob() { - return std::make_shared(UploadSessionType::Standard, _driveDbId, getFileName(), getFileSize(), - _remoteParentDirId, getTotalChunks()); + if (_fileId.empty()) { + return std::make_shared(UploadSessionType::Drive, _driveDbId, getFileName(), getFileSize(), + _remoteParentDirId, getTotalChunks()); + } else { + return std::make_shared(UploadSessionType::Drive, _driveDbId, _fileId, getFileSize(), + getTotalChunks()); + } } std::shared_ptr DriveUploadSession::createChunkJob(const std::string &chunckContent, uint64_t chunkNb, diff --git a/src/libsyncengine/propagation/executor/executorworker.cpp b/src/libsyncengine/propagation/executor/executorworker.cpp index 86719e94a..71a4f2843 100644 --- a/src/libsyncengine/propagation/executor/executorworker.cpp +++ b/src/libsyncengine/propagation/executor/executorworker.cpp @@ -1000,13 +1000,24 @@ bool ExecutorWorker::generateEditJob(SyncOpPtr syncOp, std::shared_ptrcorrespondingNode()->id()) { + // Should not happen + LOGW_SYNCPAL_WARN(_logger, L"Edit operation with empty corresponding node id for " + << Utility::formatSyncPath(absoluteLocalFilePath).c_str()); + _executorExitCode = ExitCode::DataError; + _executorExitCause = ExitCause::Unknown; + SentryHandler::instance()->captureMessage(SentryLevel::Warning, "ExecutorWorker::generateEditJob", + "Edit operation with empty corresponding node id"); + + return false; + } + if (filesize > useUploadSessionThreshold) { try { int uploadSessionParallelJobs = ParametersCache::instance()->parameters().uploadSessionParallelJobs(); job = std::make_shared( - _syncPal->driveDbId(), _syncPal->_syncDb, absoluteLocalFilePath, syncOp->affectedNode()->name(), - syncOp->correspondingNode()->parentNode()->id() ? *syncOp->correspondingNode()->parentNode()->id() - : std::string(), + _syncPal->driveDbId(), _syncPal->_syncDb, absoluteLocalFilePath, + syncOp->correspondingNode()->id() ? *syncOp->correspondingNode()->id() : std::string(), syncOp->affectedNode()->lastmodified() ? *syncOp->affectedNode()->lastmodified() : 0, isLiteSyncActivated(), uploadSessionParallelJobs); } catch (std::exception const &e) { @@ -1017,18 +1028,6 @@ bool ExecutorWorker::generateEditJob(SyncOpPtr syncOp, std::shared_ptrcorrespondingNode()->id()) { - // Should not happen - LOGW_SYNCPAL_WARN(_logger, L"Edit operation with empty corresponding node id for " - << Utility::formatSyncPath(absoluteLocalFilePath).c_str()); - _executorExitCode = ExitCode::DataError; - _executorExitCause = ExitCause::Unknown; - SentryHandler::instance()->captureMessage(SentryLevel::Warning, "ExecutorWorker::generateEditJob", - "Edit operation with empty corresponding node id"); - - return false; - } - try { job = std::make_shared( _syncPal->driveDbId(), absoluteLocalFilePath, From 4b2050c7ee391ee594313c8b91f0541ccde0017c Mon Sep 17 00:00:00 2001 From: Herve Eruam Date: Tue, 8 Oct 2024 11:27:26 +0200 Subject: [PATCH 5/5] Add unit test for UploadSession test in edit case. --- .../jobs/network/testnetworkjobs.cpp | 109 +++++++++++++++--- 1 file changed, 92 insertions(+), 17 deletions(-) diff --git a/test/libsyncengine/jobs/network/testnetworkjobs.cpp b/test/libsyncengine/jobs/network/testnetworkjobs.cpp index ac04d579e..d097fa04b 100644 --- a/test/libsyncengine/jobs/network/testnetworkjobs.cpp +++ b/test/libsyncengine/jobs/network/testnetworkjobs.cpp @@ -37,6 +37,7 @@ #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" @@ -673,37 +674,71 @@ void TestNetworkJobs::testDriveUploadSessionConstructorException() { } void TestNetworkJobs::testDriveUploadSessionSynchronous() { - LOGW_DEBUG(Log::instance()->getLogger(), L"$$$$$ 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; - SyncPath localFilePath = testhelpers::localTestDirPath / bigFileDirName / bigFileName; + IoError ioError = IoError::Unknown; + CPPUNIT_ASSERT( + IoHelper::copyFileOrDirectory(testhelpers::localTestDirPath / bigFileDirName / bigFileName, localFilePath, ioError)); + CPPUNIT_ASSERT_EQUAL(IoError::Success, ioError); - DriveUploadSession driveUploadSessionJob(_driveDbId, nullptr, localFilePath, localFilePath.filename().native(), - remoteTmpDir.id(), 12345, false, 1); - ExitCode exitCode = driveUploadSessionJob.runSynchronously(); - CPPUNIT_ASSERT(exitCode == ExitCode::Ok); + 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(exitCode == ExitCode::Ok); + 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) == driveUploadSessionJob.nodeId()); + 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); } void TestNetworkJobs::testDriveUploadSessionAsynchronous() { - LOGW_DEBUG(Log::instance()->getLogger(), L"$$$$$ 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; - const SyncPath localFilePath = testhelpers::localTestDirPath / bigFileDirName / 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 nodeId; + NodeId newNodeId; + int initialNbParalleleThreads = _nbParalleleThreads; while (_nbParalleleThreads > 0) { LOG_DEBUG(Log::instance()->getLogger(), "$$$$$ testDriveUploadSessionAsynchronous - " << _nbParalleleThreads << " threads"); @@ -711,13 +746,13 @@ void TestNetworkJobs::testDriveUploadSessionAsynchronous() { remoteTmpDir.id(), 12345, false, _nbParalleleThreads); exitCode = driveUploadSessionJob.runSynchronously(); if (exitCode == ExitCode::Ok) { - nodeId = driveUploadSessionJob.nodeId(); + 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 = std::floor(_nbParalleleThreads / 2.0); + _nbParalleleThreads = static_cast(std::floor(_nbParalleleThreads / 2.0)); } else { break; } @@ -725,18 +760,58 @@ void TestNetworkJobs::testDriveUploadSessionAsynchronous() { break; } } - - CPPUNIT_ASSERT(exitCode == ExitCode::Ok); + _nbParalleleThreads = initialNbParalleleThreads; + CPPUNIT_ASSERT_EQUAL(ExitCode::Ok, exitCode); GetFileListJob fileListJob(_driveDbId, remoteTmpDir.id()); exitCode = fileListJob.runSynchronously(); - CPPUNIT_ASSERT(exitCode == ExitCode::Ok); + 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) == nodeId); + 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(_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() {