Tests: Add db checks to rename/move tests
authorChristian Kamm <mail@ckamm.de>
Sat, 9 Feb 2019 16:04:42 +0000 (17:04 +0100)
committerKevin Ottens <kevin.ottens@nextcloud.com>
Tue, 15 Dec 2020 09:58:41 +0000 (10:58 +0100)
For moves it's relevant that the old db entry is removed and the new one
is created at the right location.

test/syncenginetestutils.h
test/testsyncmove.cpp

index 66f9717f6ac03b0412bdbca0c5a53b657391bf33..157e32b4dc3c3863895ec25a3b8a860c2011bef5 100644 (file)
@@ -12,6 +12,7 @@
 #include "filesystem.h"
 #include "syncengine.h"
 #include "common/syncjournaldb.h"
+#include "common/syncjournalfilerecord.h"
 #include "common/vfs.h"
 #include "csync_exclude.h"
 
@@ -228,17 +229,19 @@ public:
 
     FileInfo *find(PathComponents pathComponents, const bool invalidateEtags = false) {
         if (pathComponents.isEmpty()) {
-            if (invalidateEtags)
+            if (invalidateEtags) {
                 etag = generateEtag();
+            }
             return this;
         }
         QString childName = pathComponents.pathRoot();
         auto it = children.find(childName);
         if (it != children.end()) {
             auto file = it->find(std::move(pathComponents).subComponents(), invalidateEtags);
-            if (file && invalidateEtags)
+            if (file && invalidateEtags) {
                 // Update parents on the way back
                 etag = file->etag;
+            }
             return file;
         }
         return nullptr;
@@ -977,6 +980,7 @@ public:
 
     FileInfo currentRemoteState() { return _fakeQnam->currentRemoteState(); }
     FileInfo &uploadState() { return _fakeQnam->uploadState(); }
+    FileInfo dbState() const;
 
     struct ErrorList {
         FakeQNAM *_qnam;
@@ -1072,6 +1076,42 @@ private:
     }
 };
 
+static FileInfo &findOrCreateDirs(FileInfo &base, PathComponents components)
+{
+    if (components.isEmpty())
+        return base;
+    auto childName = components.pathRoot();
+    auto it = base.children.find(childName);
+    if (it != base.children.end()) {
+        return findOrCreateDirs(*it, components.subComponents());
+    }
+    auto &newDir = base.children[childName] = FileInfo{childName};
+    newDir.parentPath = base.path();
+    return findOrCreateDirs(newDir, components.subComponents());
+}
+
+inline FileInfo FakeFolder::dbState() const
+{
+    FileInfo result;
+    _journalDb->getFilesBelowPath("", [&](const OCC::SyncJournalFileRecord &record) {
+        auto components = PathComponents(QString::fromUtf8(record._path));
+        auto &parentDir = findOrCreateDirs(result, components.parentDirComponents());
+        auto name = components.fileName();
+        auto &item = parentDir.children[name];
+        item.name = name;
+        item.parentPath = parentDir.path();
+        item.size = record._fileSize;
+        item.isDir = record._type == ItemTypeDirectory;
+        item.permissions = record._remotePerm;
+        item.etag = record._etag;
+        item.lastModified = OCC::Utility::qDateTimeFromTime_t(record._modtime);
+        item.fileId = record._fileId;
+        item.checksums = record._checksumHeader;
+        // item.contentChar can't be set from the db
+    });
+    return result;
+}
+
 /* Return the FileInfo for a conflict file for the specified relative filename */
 inline const FileInfo *findConflict(FileInfo &dir, const QString &filename)
 {
@@ -1114,3 +1154,32 @@ inline char *toString(const FileInfo &fi)
         addFiles(files, fi);
     return QTest::toString(QString("FileInfo with %1 files(%2)").arg(files.size()).arg(files.join(", ")));
 }
+
+inline void addFilesDbData(QStringList &dest, const FileInfo &fi)
+{
+    // could include etag, permissions etc, but would need extra work
+    if (fi.isDir) {
+        dest += QString("%1 - %2 %3 %4").arg(
+            fi.name,
+            fi.isDir ? "dir" : "file",
+            QString::number(fi.lastModified.toSecsSinceEpoch()),
+            fi.fileId);
+        foreach (const FileInfo &fi, fi.children)
+            addFilesDbData(dest, fi);
+    } else {
+        dest += QString("%1 - %2 %3 %4 %5").arg(
+            fi.name,
+            fi.isDir ? "dir" : "file",
+            QString::number(fi.size),
+            QString::number(fi.lastModified.toSecsSinceEpoch()),
+            fi.fileId);
+    }
+}
+
+inline char *printDbData(const FileInfo &fi)
+{
+    QStringList files;
+    foreach (const FileInfo &fi, fi.children)
+        addFilesDbData(files, fi);
+    return QTest::toString(QString("FileInfo with %1 files(%2)").arg(files.size()).arg(files.join(", ")));
+}
index 7933039e6d4418be2686f4e357fcb2b105c2a984..66968afcad14380f798a68c7b027cb290abca3ec 100644 (file)
@@ -197,6 +197,7 @@ private slots:
         fakeFolder.localModifier().rename("A/a1", "A/a1m");
         QVERIFY(fakeFolder.syncOnce());
         QCOMPARE(fakeFolder.currentLocalState(), remoteInfo);
+        QCOMPARE(printDbData(fakeFolder.dbState()), printDbData(remoteInfo));
         QCOMPARE(nPUT, 0);
 
         // Move-and-change, causing a upload and delete
@@ -204,6 +205,7 @@ private slots:
         fakeFolder.localModifier().appendByte("A/a2m");
         QVERIFY(fakeFolder.syncOnce());
         QCOMPARE(fakeFolder.currentLocalState(), remoteInfo);
+        QCOMPARE(printDbData(fakeFolder.dbState()), printDbData(remoteInfo));
         QCOMPARE(nPUT, 1);
         QCOMPARE(nDELETE, 1);
 
@@ -212,6 +214,7 @@ private slots:
         fakeFolder.localModifier().setContents("B/b1m", 'C');
         QVERIFY(fakeFolder.syncOnce());
         QCOMPARE(fakeFolder.currentLocalState(), remoteInfo);
+        QCOMPARE(printDbData(fakeFolder.dbState()), printDbData(remoteInfo));
         QCOMPARE(nPUT, 2);
         QCOMPARE(nDELETE, 2);
 
@@ -222,6 +225,7 @@ private slots:
         fakeFolder.localModifier().setModTime("B/b2m", mtime);
         QVERIFY(fakeFolder.syncOnce());
         QCOMPARE(fakeFolder.currentLocalState(), remoteInfo);
+        QCOMPARE(printDbData(fakeFolder.dbState()), printDbData(remoteInfo));
         QCOMPARE(nPUT, 3);
         QCOMPARE(nDELETE, 3);
 
@@ -241,6 +245,7 @@ private slots:
         fakeFolder.localModifier().insert("C/c3");
         QVERIFY(fakeFolder.syncOnce());
         QCOMPARE(fakeFolder.currentLocalState(), remoteInfo);
+        QCOMPARE(printDbData(fakeFolder.dbState()), printDbData(remoteInfo));
         QCOMPARE(nPUT, 4);
         QCOMPARE(nDELETE, 4);
 
@@ -253,6 +258,7 @@ private slots:
         QCOMPARE(nPUT, 5);
         QCOMPARE(nDELETE, 5);
         QCOMPARE(fakeFolder.currentLocalState(), remoteInfo);
+        QCOMPARE(printDbData(fakeFolder.dbState()), printDbData(remoteInfo));
     }
 
     void testDuplicateFileId_data()
@@ -360,6 +366,7 @@ private slots:
         remote.setContents("B/b2m", 'A');
         QVERIFY(fakeFolder.syncOnce());
         QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
+        QCOMPARE(printDbData(fakeFolder.dbState()), printDbData(fakeFolder.currentRemoteState()));
         QCOMPARE(counter.nGET, 1);
         QCOMPARE(counter.nPUT, 1);
         QCOMPARE(counter.nMOVE, 0);
@@ -375,6 +382,7 @@ private slots:
         local.setContents("B/b1m", 'B');
         QVERIFY(fakeFolder.syncOnce());
         QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
+        QCOMPARE(printDbData(fakeFolder.dbState()), printDbData(fakeFolder.currentRemoteState()));
         QCOMPARE(counter.nGET, 2);
         QCOMPARE(counter.nPUT, 2);
         QCOMPARE(counter.nMOVE, 0);
@@ -402,6 +410,7 @@ private slots:
             QVERIFY(expectAndWipeConflict(local, fakeFolder.currentLocalState(), "A/a1mt"));
             QVERIFY(expectAndWipeConflict(local, fakeFolder.currentLocalState(), "B/b1mt"));
             QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
+            QCOMPARE(printDbData(fakeFolder.dbState()), printDbData(fakeFolder.currentRemoteState()));
             QCOMPARE(counter.nGET, 3);
             QCOMPARE(counter.nPUT, 1);
             QCOMPARE(counter.nMOVE, 0);
@@ -424,6 +433,7 @@ private slots:
             QVERIFY(expectAndWipeConflict(local, fakeFolder.currentLocalState(), "A/a1N"));
             QVERIFY(expectAndWipeConflict(local, fakeFolder.currentLocalState(), "B/b1N"));
             QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
+            QCOMPARE(printDbData(fakeFolder.dbState()), printDbData(fakeFolder.currentRemoteState()));
             QCOMPARE(counter.nGET, 2);
             QCOMPARE(counter.nPUT, 0);
             QCOMPARE(counter.nMOVE, 0);
@@ -441,6 +451,7 @@ private slots:
         QVERIFY(fakeFolder.syncOnce());
         // end up with both files
         QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
+        QCOMPARE(printDbData(fakeFolder.dbState()), printDbData(fakeFolder.currentRemoteState()));
         QCOMPARE(counter.nGET, 1);
         QCOMPARE(counter.nPUT, 1);
         QCOMPARE(counter.nMOVE, 0);
@@ -453,6 +464,7 @@ private slots:
         QVERIFY(fakeFolder.syncOnce());
         // End up with both folders
         QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
+        QCOMPARE(printDbData(fakeFolder.dbState()), printDbData(fakeFolder.currentRemoteState()));
         QCOMPARE(counter.nGET, 3); // 3 files in C
         QCOMPARE(counter.nPUT, 3);
         QCOMPARE(counter.nMOVE, 0);
@@ -466,6 +478,7 @@ private slots:
             QSignalSpy completeSpy(&fakeFolder.syncEngine(), SIGNAL(itemCompleted(const SyncFileItemPtr &)));
             QVERIFY(fakeFolder.syncOnce());
             QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
+            QCOMPARE(printDbData(fakeFolder.dbState()), printDbData(fakeFolder.currentRemoteState()));
             QCOMPARE(counter.nGET, 0);
             QCOMPARE(counter.nPUT, 0);
             QCOMPARE(counter.nMOVE, 1);
@@ -489,6 +502,7 @@ private slots:
             QSignalSpy completeSpy(&fakeFolder.syncEngine(), SIGNAL(itemCompleted(const SyncFileItemPtr &)));
             QVERIFY(fakeFolder.syncOnce());
             QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
+            QCOMPARE(printDbData(fakeFolder.dbState()), printDbData(fakeFolder.currentRemoteState()));
             QCOMPARE(counter.nGET, 1);
             QCOMPARE(counter.nPUT, 1);
             QCOMPARE(counter.nMOVE, 1);
@@ -511,6 +525,7 @@ private slots:
         remote.rename("B2", "B3");
         QVERIFY(fakeFolder.syncOnce());
         QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
+        QCOMPARE(printDbData(fakeFolder.dbState()), printDbData(fakeFolder.currentRemoteState()));
         QCOMPARE(counter.nGET, 1);
         QCOMPARE(counter.nPUT, 1);
         QCOMPARE(counter.nMOVE, 1);
@@ -547,6 +562,7 @@ private slots:
             local.remove(c);
         }
         QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
+        QCOMPARE(printDbData(fakeFolder.dbState()), printDbData(fakeFolder.currentRemoteState()));
         QCOMPARE(counter.nGET, 2);
         QCOMPARE(counter.nPUT, 0);
         QCOMPARE(counter.nMOVE, 1);
@@ -562,6 +578,7 @@ private slots:
         remote.rename("B4", "B5");
         QVERIFY(fakeFolder.syncOnce());
         QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
+        QCOMPARE(printDbData(fakeFolder.dbState()), printDbData(fakeFolder.currentRemoteState()));
         QCOMPARE(counter.nGET, 0);
         QCOMPARE(counter.nPUT, 0);
         QCOMPARE(counter.nMOVE, 2);