Vfs: Don't let new local files start out unpinned #7250
authorChristian Kamm <mail@ckamm.de>
Fri, 21 Jun 2019 07:06:07 +0000 (09:06 +0200)
committerKevin Ottens <kevin.ottens@nextcloud.com>
Tue, 15 Dec 2020 09:58:52 +0000 (10:58 +0100)
If one adds a new file to an online-only folder the previous behavior
was to upload the file in one sync and dehydrate it in the next. Now
these new files get set to Unspecified pin state, making them retain
their data.

src/libsync/propagateupload.cpp
test/testsyncvirtualfiles.cpp

index 2b043f3581a75349a7e804757fa8c14a7d84f7e3..3f3df353eb0d7d8fd0e6f39476dcffdc9f361a1d 100644 (file)
@@ -780,6 +780,17 @@ void PropagateUploadFileCommon::finalize()
         return;
     }
 
+    // Files that were new on the remote shouldn't have online-only pin state
+    // even if their parent folder is online-only.
+    if (_item->_instruction == CSYNC_INSTRUCTION_NEW
+        || _item->_instruction == CSYNC_INSTRUCTION_TYPE_CHANGE) {
+        auto &vfs = propagator()->syncOptions()._vfs;
+        const auto pin = vfs->pinState(_item->_file);
+        if (pin && *pin == PinState::OnlineOnly) {
+            vfs->setPinState(_item->_file, PinState::Unspecified);
+        }
+    }
+
     // Remove from the progress database:
     propagator()->_journal->setUploadInfo(_item->_file, SyncJournalDb::UploadInfo());
     propagator()->_journal->commit("upload file start");
index b13d085fd5ed3aaf0f498a42568667795747d69b..adf0b482255a658a2382a4f0c18f10284ff375b0 100644 (file)
@@ -1090,6 +1090,45 @@ private slots:
         QVERIFY(!r);
         QCOMPARE(r.error(), Vfs::AvailabilityError::NoSuchItem);
     }
+
+    void testPinStateLocals()
+    {
+        FakeFolder fakeFolder{ FileInfo() };
+        auto vfs = setupVfs(fakeFolder);
+        QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
+
+        auto setPin = [&] (const QByteArray &path, PinState state) {
+            fakeFolder.syncJournal().internalPinStates().setForPath(path, state);
+        };
+
+        fakeFolder.remoteModifier().mkdir("local");
+        fakeFolder.remoteModifier().mkdir("online");
+        fakeFolder.remoteModifier().mkdir("unspec");
+        QVERIFY(fakeFolder.syncOnce());
+        QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
+
+        setPin("local", PinState::AlwaysLocal);
+        setPin("online", PinState::OnlineOnly);
+        setPin("unspec", PinState::Unspecified);
+
+        fakeFolder.localModifier().insert("file1");
+        fakeFolder.localModifier().insert("online/file1");
+        fakeFolder.localModifier().insert("online/file2");
+        fakeFolder.localModifier().insert("local/file1");
+        fakeFolder.localModifier().insert("unspec/file1");
+        QVERIFY(fakeFolder.syncOnce());
+        QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
+
+        // root is unspecified
+        QCOMPARE(*vfs->pinState("file1"), PinState::Unspecified);
+        QCOMPARE(*vfs->pinState("local/file1"), PinState::AlwaysLocal);
+        QCOMPARE(*vfs->pinState("online/file1"), PinState::Unspecified);
+        QCOMPARE(*vfs->pinState("unspec/file1"), PinState::Unspecified);
+
+        // Sync again: bad pin states of new local files usually take effect on second sync
+        QVERIFY(fakeFolder.syncOnce());
+        QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
+    }
 };
 
 QTEST_GUILESS_MAIN(TestSyncVirtualFiles)