From b68754827c2f797cf7d6e059f0faf8c238d8d580 Mon Sep 17 00:00:00 2001 From: Matthieu Gallien Date: Mon, 28 Nov 2022 16:43:29 +0100 Subject: [PATCH 1/3] case clash should not prevent full propagation Signed-off-by: Matthieu Gallien --- src/libsync/owncloudpropagator.cpp | 5 +++-- test/testsyncengine.cpp | 21 +++++++++++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/libsync/owncloudpropagator.cpp b/src/libsync/owncloudpropagator.cpp index cb3734e17a130..e221ac3275ded 100644 --- a/src/libsync/owncloudpropagator.cpp +++ b/src/libsync/owncloudpropagator.cpp @@ -1333,6 +1333,7 @@ void PropagateRootDirectory::slotSubJobsFinished(SyncFileItem::Status status) if (status != SyncFileItem::Success && status != SyncFileItem::Restoration && status != SyncFileItem::BlacklistedError + && status != SyncFileItem::FileNameClash && status != SyncFileItem::Conflict) { if (_state != Finished) { // Synchronously abort @@ -1355,12 +1356,12 @@ void PropagateRootDirectory::slotSubJobsFinished(SyncFileItem::Status status) case SyncFileItem::FileLocked: case SyncFileItem::Restoration: case SyncFileItem::FileNameInvalid: - case SyncFileItem::FileNameClash: case SyncFileItem::DetailError: case SyncFileItem::Success: break; + case SyncFileItem::FileNameClash: case SyncFileItem::BlacklistedError: - _errorStatus = SyncFileItem::BlacklistedError; + _errorStatus = status; break; } } diff --git a/test/testsyncengine.cpp b/test/testsyncengine.cpp index 8a9100a09ba8c..a0b2ae38448ed 100644 --- a/test/testsyncengine.cpp +++ b/test/testsyncengine.cpp @@ -1282,6 +1282,27 @@ private slots: QVERIFY(fileThirdSync); QCOMPARE(fileThirdSync->lastModified.toSecsSinceEpoch(), CURRENT_MTIME); } + + void testFolderRemovalWithCaseClash() + { + FakeFolder fakeFolder{ FileInfo{} }; + fakeFolder.remoteModifier().mkdir("A"); + fakeFolder.remoteModifier().insert("A/file"); + + QVERIFY(fakeFolder.syncOnce()); + QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState()); + + fakeFolder.remoteModifier().insert("A/FILE"); + QVERIFY(!fakeFolder.syncOnce()); + + fakeFolder.remoteModifier().mkdir("B"); + fakeFolder.remoteModifier().rename("A/file", "B/file"); + fakeFolder.remoteModifier().remove("A"); + + QVERIFY(!fakeFolder.syncOnce()); + auto folderA = fakeFolder.currentLocalState().find("A"); + QCOMPARE(folderA, nullptr); + } }; QTEST_GUILESS_MAIN(TestSyncEngine) From af49e1079a854d770e719d425396499b5ae88592 Mon Sep 17 00:00:00 2001 From: Matthieu Gallien Date: Mon, 28 Nov 2022 17:06:57 +0100 Subject: [PATCH 2/3] fix test and code to not stop on case clash errors Signed-off-by: Matthieu Gallien --- src/libsync/propagatorjobs.cpp | 2 +- test/testsyncengine.cpp | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/libsync/propagatorjobs.cpp b/src/libsync/propagatorjobs.cpp index 8002f31e45515..a04dc92c4be28 100644 --- a/src/libsync/propagatorjobs.cpp +++ b/src/libsync/propagatorjobs.cpp @@ -178,7 +178,7 @@ void PropagateLocalMkdir::startLocalMkdir() if (Utility::fsCasePreserving() && propagator()->localFileNameClash(_item->_file)) { qCWarning(lcPropagateLocalMkdir) << "New folder to create locally already exists with different case:" << _item->_file; - done(SyncFileItem::NormalError, tr("Attention, possible case sensitivity clash with %1").arg(newDirStr)); + done(SyncFileItem::FileNameClash, tr("Attention, possible case sensitivity clash with %1").arg(newDirStr)); return; } emit propagator()->touchedFile(newDirStr); diff --git a/test/testsyncengine.cpp b/test/testsyncengine.cpp index a0b2ae38448ed..f3fdd704ea1ce 100644 --- a/test/testsyncengine.cpp +++ b/test/testsyncengine.cpp @@ -1287,20 +1287,20 @@ private slots: { FakeFolder fakeFolder{ FileInfo{} }; fakeFolder.remoteModifier().mkdir("A"); + fakeFolder.remoteModifier().mkdir("toDelete"); fakeFolder.remoteModifier().insert("A/file"); QVERIFY(fakeFolder.syncOnce()); QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState()); fakeFolder.remoteModifier().insert("A/FILE"); - QVERIFY(!fakeFolder.syncOnce()); + QVERIFY(fakeFolder.syncOnce()); - fakeFolder.remoteModifier().mkdir("B"); - fakeFolder.remoteModifier().rename("A/file", "B/file"); - fakeFolder.remoteModifier().remove("A"); + fakeFolder.remoteModifier().mkdir("a"); + fakeFolder.remoteModifier().remove("toDelete"); - QVERIFY(!fakeFolder.syncOnce()); - auto folderA = fakeFolder.currentLocalState().find("A"); + QVERIFY(fakeFolder.syncOnce()); + auto folderA = fakeFolder.currentLocalState().find("toDelete"); QCOMPARE(folderA, nullptr); } }; From 172505534622652c27c0400a9a555ec7866d9495 Mon Sep 17 00:00:00 2001 From: Matthieu Gallien Date: Mon, 28 Nov 2022 17:16:45 +0100 Subject: [PATCH 3/3] a case clash error is a case clash error Signed-off-by: Matthieu Gallien --- src/libsync/propagatorjobs.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libsync/propagatorjobs.cpp b/src/libsync/propagatorjobs.cpp index a04dc92c4be28..531bdd7fe8ead 100644 --- a/src/libsync/propagatorjobs.cpp +++ b/src/libsync/propagatorjobs.cpp @@ -102,7 +102,7 @@ void PropagateLocalRemove::start() qCInfo(lcPropagateLocalRemove) << "Going to delete:" << filename; if (propagator()->localFileNameClash(_item->_file)) { - done(SyncFileItem::NormalError, tr("Could not remove %1 because of a local file name clash").arg(QDir::toNativeSeparators(filename))); + done(SyncFileItem::FileNameClash, tr("Could not remove %1 because of a local file name clash").arg(QDir::toNativeSeparators(filename))); return; } @@ -250,7 +250,7 @@ void PropagateLocalRename::start() // Fixme: the file that is the reason for the clash could be named here, // it would have to come out the localFileNameClash function - done(SyncFileItem::NormalError, + done(SyncFileItem::FileNameClash, tr("File %1 cannot be renamed to %2 because of a local file name clash") .arg(QDir::toNativeSeparators(_item->_file), QDir::toNativeSeparators(_item->_renameTarget))); return;