diff options
author | Christian Kamm <mail@ckamm.de> | 2017-06-14 13:14:46 +0300 |
---|---|---|
committer | Christian Kamm <mail@ckamm.de> | 2017-06-15 14:54:16 +0300 |
commit | 816096311027bac0f391ea97d0b61b4175e9b8f9 (patch) | |
tree | 7ad93c6ac77711d82ff2453366bf3144385ed94f /test/testsyncengine.cpp | |
parent | d50d8b86cf135dff833679b073406e4bdd6deae6 (diff) |
Compare the hash of files with identical mtime/size #5589
* For conflicts where mtime and size are identical:
a) If there's no remote checksum, skip (unchanged)
b) If there's a remote checksum that's a useful hash, create a
PropagateDownload job and compute the local hash. If the hashes
are identical, don't download the file and just update metadata.
* Avoid exposing the existence of checksumTypeId beyond the database
layer. This makes handling checksums easier in general because they
can usually be treated as a single blob.
This change was prompted by the difficulty of producing file_stat_t
entries uniformly from PROPFINDs and the database.
Diffstat (limited to 'test/testsyncengine.cpp')
-rw-r--r-- | test/testsyncengine.cpp | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/test/testsyncengine.cpp b/test/testsyncengine.cpp index 4200d5e1b..1f48931da 100644 --- a/test/testsyncengine.cpp +++ b/test/testsyncengine.cpp @@ -321,6 +321,70 @@ private slots: } } + void testFakeConflict() + { + FakeFolder fakeFolder{ FileInfo::A12_B12_C12_S12() }; + + int nGET = 0; + fakeFolder.setServerOverride([&](QNetworkAccessManager::Operation op, const QNetworkRequest &) { + if (op == QNetworkAccessManager::GetOperation) + ++nGET; + return nullptr; + }); + + // For directly editing the remote checksum + FileInfo &remoteInfo = dynamic_cast<FileInfo &>(fakeFolder.remoteModifier()); + + // Base mtime with no ms content (filesystem is seconds only) + auto mtime = QDateTime::currentDateTime().addDays(-4); + mtime.setMSecsSinceEpoch(mtime.toMSecsSinceEpoch() / 1000 * 1000); + + // Conflict: Same content, mtime, but no server checksum + // -> ignored in reconcile + fakeFolder.localModifier().setContents("A/a1", 'C'); + fakeFolder.localModifier().setModTime("A/a1", mtime); + fakeFolder.remoteModifier().setContents("A/a1", 'C'); + fakeFolder.remoteModifier().setModTime("A/a1", mtime); + QVERIFY(fakeFolder.syncOnce()); + QCOMPARE(nGET, 0); + + // Conflict: Same content, mtime, but weak server checksum + // -> ignored in reconcile + mtime = mtime.addDays(1); + fakeFolder.localModifier().setContents("A/a1", 'D'); + fakeFolder.localModifier().setModTime("A/a1", mtime); + fakeFolder.remoteModifier().setContents("A/a1", 'D'); + fakeFolder.remoteModifier().setModTime("A/a1", mtime); + remoteInfo.find("A/a1")->checksums = "Adler32:bad"; + QVERIFY(fakeFolder.syncOnce()); + QCOMPARE(nGET, 0); + + // Conflict: Same content, mtime, but server checksum differs + // -> downloaded + mtime = mtime.addDays(1); + fakeFolder.localModifier().setContents("A/a1", 'W'); + fakeFolder.localModifier().setModTime("A/a1", mtime); + fakeFolder.remoteModifier().setContents("A/a1", 'W'); + fakeFolder.remoteModifier().setModTime("A/a1", mtime); + remoteInfo.find("A/a1")->checksums = "SHA1:bad"; + QVERIFY(fakeFolder.syncOnce()); + QCOMPARE(nGET, 1); + + // Conflict: Same content, mtime, matching checksums + // -> PropagateDownload, but it skips the download + mtime = mtime.addDays(1); + fakeFolder.localModifier().setContents("A/a1", 'C'); + fakeFolder.localModifier().setModTime("A/a1", mtime); + fakeFolder.remoteModifier().setContents("A/a1", 'C'); + fakeFolder.remoteModifier().setModTime("A/a1", mtime); + remoteInfo.find("A/a1")->checksums = "SHA1:56900fb1d337cf7237ff766276b9c1e8ce507427"; + QVERIFY(fakeFolder.syncOnce()); + QCOMPARE(nGET, 1); + + // Extra sync reads from db, no difference + QVERIFY(fakeFolder.syncOnce()); + QCOMPARE(nGET, 1); + } }; QTEST_GUILESS_MAIN(TestSyncEngine) |