From ce0e2d0b887a987c77334fb72b62bd25f9d5d340 Mon Sep 17 00:00:00 2001 From: Christian Kamm Date: Wed, 7 Feb 2018 13:05:41 +0100 Subject: SyncJournal: Don't use LIKE with paths Paths can contain the wildcards % and _ and that would lead to odd behavior. This patch also clarifies the behavior of avoidReadFromDbOnNextSync() which previously dependend on whether "foo/bar" or "foo/bar/" was passed as input. Possibly affects #6322 --- test/testsyncengine.cpp | 8 ++++ test/testsyncjournaldb.cpp | 115 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 123 insertions(+) (limited to 'test') diff --git a/test/testsyncengine.cpp b/test/testsyncengine.cpp index ff291cc39..6ac5ed549 100644 --- a/test/testsyncengine.cpp +++ b/test/testsyncengine.cpp @@ -172,6 +172,14 @@ private slots: fakeFolder.syncEngine().journal()->setSelectiveSyncList(SyncJournalDb::SelectiveSyncBlackList, {"parentFolder/subFolderA/"}); fakeFolder.syncEngine().journal()->avoidReadFromDbOnNextSync(QByteArrayLiteral("parentFolder/subFolderA/")); + auto getEtag = [&](const QByteArray &file) { + SyncJournalFileRecord rec; + fakeFolder.syncJournal().getFileRecord(file, &rec); + return rec._etag; + }; + QVERIFY(getEtag("parentFolder") == "_invalid_"); + QVERIFY(getEtag("parentFolder/subFolderA") == "_invalid_"); + QVERIFY(getEtag("parentFolder/subFolderA/subsubFolder") != "_invalid_"); // But touch local file before the next sync, such that the local folder // can't be removed diff --git a/test/testsyncjournaldb.cpp b/test/testsyncjournaldb.cpp index 389330ffa..612af2f03 100644 --- a/test/testsyncjournaldb.cpp +++ b/test/testsyncjournaldb.cpp @@ -205,6 +205,121 @@ private slots: QVERIFY(!_db.conflictRecord(record.path).isValid()); } + void testAvoidReadFromDbOnNextSync() + { + auto invalidEtag = QByteArray("_invalid_"); + auto initialEtag = QByteArray("etag"); + auto makeEntry = [&](const QByteArray &path, int type) { + SyncJournalFileRecord record; + record._path = path; + record._type = type; + record._etag = initialEtag; + _db.setFileRecord(record); + }; + auto getEtag = [&](const QByteArray &path) { + SyncJournalFileRecord record; + _db.getFileRecord(path, &record); + return record._etag; + }; + + makeEntry("foodir", 2); + makeEntry("otherdir", 2); + makeEntry("foo%", 2); // wildcards don't apply + makeEntry("foodi_", 2); // wildcards don't apply + makeEntry("foodir/file", 0); + makeEntry("foodir/subdir", 2); + makeEntry("foodir/subdir/file", 0); + makeEntry("foodir/otherdir", 2); + makeEntry("fo", 2); // prefix, but does not match + makeEntry("foodir/sub", 2); // prefix, but does not match + makeEntry("foodir/subdir/subsubdir", 2); + makeEntry("foodir/subdir/subsubdir/file", 0); + makeEntry("foodir/subdir/otherdir", 2); + + _db.avoidReadFromDbOnNextSync(QByteArray("foodir/subdir")); + + // Direct effects of parent directories being set to _invalid_ + QCOMPARE(getEtag("foodir"), invalidEtag); + QCOMPARE(getEtag("foodir/subdir"), invalidEtag); + QCOMPARE(getEtag("foodir/subdir/subsubdir"), initialEtag); + + QCOMPARE(getEtag("foodir/file"), initialEtag); + QCOMPARE(getEtag("foodir/subdir/file"), initialEtag); + QCOMPARE(getEtag("foodir/subdir/subsubdir/file"), initialEtag); + + QCOMPARE(getEtag("fo"), initialEtag); + QCOMPARE(getEtag("foo%"), initialEtag); + QCOMPARE(getEtag("foodi_"), initialEtag); + QCOMPARE(getEtag("otherdir"), initialEtag); + QCOMPARE(getEtag("foodir/otherdir"), initialEtag); + QCOMPARE(getEtag("foodir/sub"), initialEtag); + QCOMPARE(getEtag("foodir/subdir/otherdir"), initialEtag); + + // Indirect effects: setFileRecord() calls filter etags + initialEtag = "etag2"; + + makeEntry("foodir", 2); + QCOMPARE(getEtag("foodir"), invalidEtag); + makeEntry("foodir/subdir", 2); + QCOMPARE(getEtag("foodir/subdir"), invalidEtag); + makeEntry("foodir/subdir/subsubdir", 2); + QCOMPARE(getEtag("foodir/subdir/subsubdir"), initialEtag); + makeEntry("fo", 2); + QCOMPARE(getEtag("fo"), initialEtag); + makeEntry("foodir/sub", 2); + QCOMPARE(getEtag("foodir/sub"), initialEtag); + } + + void testRecursiveDelete() + { + auto makeEntry = [&](const QByteArray &path) { + SyncJournalFileRecord record; + record._path = path; + _db.setFileRecord(record); + }; + + QByteArrayList elements; + elements + << "foo" + << "foo/file" + << "bar" + << "moo" + << "moo/file" + << "foo%bar" + << "foo bla bar/file" + << "fo_" + << "fo_/file"; + for (auto elem : elements) + makeEntry(elem); + + auto checkElements = [&]() { + bool ok = true; + for (auto elem : elements) { + SyncJournalFileRecord record; + _db.getFileRecord(elem, &record); + if (!record.isValid()) { + qWarning() << "Missing record: " << elem; + ok = false; + } + } + return ok; + }; + + _db.deleteFileRecord("moo", true); + elements.removeAll("moo"); + elements.removeAll("moo/file"); + QVERIFY(checkElements()); + + _db.deleteFileRecord("fo_", true); + elements.removeAll("fo_"); + elements.removeAll("fo_/file"); + QVERIFY(checkElements()); + + _db.deleteFileRecord("foo%bar", true); + elements.removeAll("foo%bar"); + QVERIFY(checkElements()); + } + private: SyncJournalDb _db; }; -- cgit v1.2.3