#include "config.h"
#include <syncengine.h>
-#include <cfapi.h>
+#include "vfs/cfapi/cfapiwrapper.h"
-using namespace OCC;
-
-bool isSparseFile(const QString &path)
-{
- auto p = path;
- const auto attributes = GetFileAttributes(reinterpret_cast<wchar_t *>(p.data()));
- return (attributes & FILE_ATTRIBUTE_SPARSE_FILE) != 0;
+namespace cfapi {
+using namespace OCC::CfApiWrapper;
}
-std::unique_ptr<void, void(*)(HANDLE)> handleForPath(const QString &path)
-{
- if (QFileInfo(path).isDir()) {
- HANDLE handle = nullptr;
- const qint64 openResult = CfOpenFileWithOplock(path.toStdWString().data(), CF_OPEN_FILE_FLAG_NONE, &handle);
- if (openResult == S_OK) {
- return {handle, CfCloseHandle};
- }
- } else {
- const auto handle = CreateFile(path.toStdWString().data(), 0, 0, nullptr,
- OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
- if (handle != INVALID_HANDLE_VALUE) {
- return {handle, [](HANDLE h) { CloseHandle(h); }};
- }
- }
-
- return {nullptr, [](HANDLE){}};
-}
+using namespace OCC;
-void setPinState(const QString &path, PinState state, bool recurse = false)
+void setPinState(const QString &path, PinState state, cfapi::SetPinRecurseMode mode)
{
- auto p = QDir::toNativeSeparators(path);
- const auto handle = handleForPath(p);
- Q_ASSERT(handle);
+ Q_ASSERT(mode == cfapi::Recurse || mode == cfapi::NoRecurse);
- auto cfState = CF_PIN_STATE_UNSPECIFIED;
- switch (state) {
- case PinState::AlwaysLocal:
- cfState = CF_PIN_STATE_PINNED;
- break;
- case PinState::Inherited:
- cfState = CF_PIN_STATE_INHERIT;
- break;
- case PinState::OnlineOnly:
- cfState = CF_PIN_STATE_UNPINNED;
- break;
- case PinState::Unspecified:
- cfState = CF_PIN_STATE_UNSPECIFIED;
- break;
- }
+ const auto p = QDir::toNativeSeparators(path);
+ const auto handle = cfapi::handleForPath(p);
+ Q_ASSERT(handle);
- if (recurse) {
- const qint64 result = CfSetPinState(handle.get(), cfState, CF_SET_PIN_FLAG_RECURSE, nullptr);
- Q_ASSERT(result == S_OK);
- } else {
- const qint64 result = CfSetPinState(handle.get(), cfState, CF_SET_PIN_FLAG_NONE, nullptr);
- Q_ASSERT(result == S_OK);
+ const auto result = cfapi::setPinState(handle, state, mode);
+ Q_ASSERT(result);
- const qint64 childrenResult = CfSetPinState(handle.get(), CF_PIN_STATE_INHERIT, CF_SET_PIN_FLAG_RECURSE_ONLY, nullptr);
- Q_ASSERT(childrenResult == S_OK);
+ if (mode == cfapi::NoRecurse) {
+ const auto result = cfapi::setPinState(handle, PinState::Inherited, cfapi::ChildrenOnly);
+ Q_ASSERT(result);
}
}
cfapiVfs.data(), &Vfs::fileStatusChanged);
folder.switchToVfs(cfapiVfs);
- setPinState(folder.localPath(), PinState::Unspecified);
+ setPinState(folder.localPath(), PinState::Unspecified, cfapi::NoRecurse);
return cfapiVfs;
}
auto someDate = QDateTime(QDate(1984, 07, 30), QTime(1,3,2));
fakeFolder.remoteModifier().setModTime("A/a1", someDate);
QVERIFY(fakeFolder.syncOnce());
- QVERIFY(isSparseFile(fakeFolder.localPath() + "A/a1"));
+ QVERIFY(cfapi::isSparseFile(fakeFolder.localPath() + "A/a1"));
QCOMPARE(QFileInfo(fakeFolder.localPath() + "A/a1").size(), 64);
QCOMPARE(QFileInfo(fakeFolder.localPath() + "A/a1").lastModified(), someDate);
QVERIFY(fakeFolder.currentRemoteState().find("A/a1"));
// Another sync doesn't actually lead to changes
QVERIFY(fakeFolder.syncOnce());
- QVERIFY(isSparseFile(fakeFolder.localPath() + "A/a1"));
+ QVERIFY(cfapi::isSparseFile(fakeFolder.localPath() + "A/a1"));
QCOMPARE(QFileInfo(fakeFolder.localPath() + "A/a1").size(), 64);
QCOMPARE(QFileInfo(fakeFolder.localPath() + "A/a1").lastModified(), someDate);
QVERIFY(fakeFolder.currentRemoteState().find("A/a1"));
// Not even when the remote is rediscovered
fakeFolder.syncJournal().forceRemoteDiscoveryNextSync();
QVERIFY(fakeFolder.syncOnce());
- QVERIFY(isSparseFile(fakeFolder.localPath() + "A/a1"));
+ QVERIFY(cfapi::isSparseFile(fakeFolder.localPath() + "A/a1"));
QCOMPARE(QFileInfo(fakeFolder.localPath() + "A/a1").size(), 64);
QCOMPARE(QFileInfo(fakeFolder.localPath() + "A/a1").lastModified(), someDate);
QVERIFY(fakeFolder.currentRemoteState().find("A/a1"));
// Neither does a remote change
fakeFolder.remoteModifier().appendByte("A/a1");
QVERIFY(fakeFolder.syncOnce());
- QVERIFY(isSparseFile(fakeFolder.localPath() + "A/a1"));
+ QVERIFY(cfapi::isSparseFile(fakeFolder.localPath() + "A/a1"));
QCOMPARE(QFileInfo(fakeFolder.localPath() + "A/a1").size(), 65);
QCOMPARE(QFileInfo(fakeFolder.localPath() + "A/a1").lastModified(), someDate);
QVERIFY(fakeFolder.currentRemoteState().find("A/a1"));
fakeFolder.remoteModifier().insert("A/a1", 65);
fakeFolder.remoteModifier().setModTime("A/a1", someDate);
QVERIFY(fakeFolder.syncOnce());
- QVERIFY(isSparseFile(fakeFolder.localPath() + "A/a1"));
+ QVERIFY(cfapi::isSparseFile(fakeFolder.localPath() + "A/a1"));
QCOMPARE(QFileInfo(fakeFolder.localPath() + "A/a1").size(), 65);
QCOMPARE(QFileInfo(fakeFolder.localPath() + "A/a1").lastModified(), someDate);
QVERIFY(fakeFolder.currentRemoteState().find("A/a1"));
fakeFolder.remoteModifier().rename("A/a1", "A/a1m");
QVERIFY(fakeFolder.syncOnce());
QVERIFY(!QFileInfo(fakeFolder.localPath() + "A/a1").exists());
- QVERIFY(isSparseFile(fakeFolder.localPath() + "A/a1m"));
+ QVERIFY(cfapi::isSparseFile(fakeFolder.localPath() + "A/a1m"));
QCOMPARE(QFileInfo(fakeFolder.localPath() + "A/a1m").size(), 65);
QCOMPARE(QFileInfo(fakeFolder.localPath() + "A/a1m").lastModified(), someDate);
QVERIFY(!fakeFolder.currentRemoteState().find("A/a1"));
fakeFolder.remoteModifier().insert("A/a2", 32);
fakeFolder.remoteModifier().insert("A/a3", 33);
QVERIFY(fakeFolder.syncOnce());
- QVERIFY(isSparseFile(fakeFolder.localPath() + "A/a2"));
+ QVERIFY(cfapi::isSparseFile(fakeFolder.localPath() + "A/a2"));
QCOMPARE(QFileInfo(fakeFolder.localPath() + "A/a2").size(), 32);
- QVERIFY(isSparseFile(fakeFolder.localPath() + "A/a3"));
+ QVERIFY(cfapi::isSparseFile(fakeFolder.localPath() + "A/a3"));
QCOMPARE(QFileInfo(fakeFolder.localPath() + "A/a3").size(), 33);
cleanup();
fakeFolder.remoteModifier().remove("A/a3");
fakeFolder.syncEngine().setLocalDiscoveryOptions(LocalDiscoveryStyle::FilesystemOnly);
QVERIFY(fakeFolder.syncOnce());
- QVERIFY(isSparseFile(fakeFolder.localPath() + "A/a2"));
+ QVERIFY(cfapi::isSparseFile(fakeFolder.localPath() + "A/a2"));
QCOMPARE(QFileInfo(fakeFolder.localPath() + "A/a2").size(), 32);
QVERIFY(itemInstruction(completeSpy, "A/a2", CSYNC_INSTRUCTION_UPDATE_METADATA));
QVERIFY(dbRecord(fakeFolder, "A/a2").isValid());
fakeFolder.remoteModifier().mkdir("B");
fakeFolder.remoteModifier().insert("B/b1", 21);
QVERIFY(fakeFolder.syncOnce());
- QVERIFY(isSparseFile(fakeFolder.localPath() + "A/a1"));
- QVERIFY(isSparseFile(fakeFolder.localPath() + "A/a2"));
- QVERIFY(isSparseFile(fakeFolder.localPath() + "B/b1"));
+ QVERIFY(cfapi::isSparseFile(fakeFolder.localPath() + "A/a1"));
+ QVERIFY(cfapi::isSparseFile(fakeFolder.localPath() + "A/a2"));
+ QVERIFY(cfapi::isSparseFile(fakeFolder.localPath() + "B/b1"));
QCOMPARE(QFileInfo(fakeFolder.localPath() + "A/a1").size(), 11);
QCOMPARE(QFileInfo(fakeFolder.localPath() + "A/a2").size(), 12);
QCOMPARE(QFileInfo(fakeFolder.localPath() + "B/b1").size(), 21);
QCOMPARE(fakeFolder.syncJournal().conflictRecordPaths().size(), 2);
// nothing should have the virtual file tag
- QVERIFY(!isSparseFile(fakeFolder.localPath() + "A/a1"));
- QVERIFY(!isSparseFile(fakeFolder.localPath() + "A/a2"));
- QVERIFY(!isSparseFile(fakeFolder.localPath() + "B/b1"));
+ QVERIFY(!cfapi::isSparseFile(fakeFolder.localPath() + "A/a1"));
+ QVERIFY(!cfapi::isSparseFile(fakeFolder.localPath() + "A/a2"));
+ QVERIFY(!cfapi::isSparseFile(fakeFolder.localPath() + "B/b1"));
QCOMPARE(dbRecord(fakeFolder, "A/a1")._type, ItemTypeFile);
QCOMPARE(dbRecord(fakeFolder, "A/a2")._type, ItemTypeFile);
QCOMPARE(dbRecord(fakeFolder, "B/b1")._type, ItemTypeFile);
// New files on the remote create virtual files
fakeFolder.remoteModifier().insert("A/new", 42);
QVERIFY(fakeFolder.syncOnce());
- QVERIFY(isSparseFile(fakeFolder.localPath() + "A/new"));
+ QVERIFY(cfapi::isSparseFile(fakeFolder.localPath() + "A/new"));
QCOMPARE(QFileInfo(fakeFolder.localPath() + "A/new").size(), 42);
QVERIFY(fakeFolder.currentRemoteState().find("A/new"));
QVERIFY(itemInstruction(completeSpy, "A/new", CSYNC_INSTRUCTION_NEW));
fakeFolder.remoteModifier().insert("A/b4");
QVERIFY(fakeFolder.syncOnce());
- QVERIFY(isSparseFile(fakeFolder.localPath() + "A/a1"));
- QVERIFY(isSparseFile(fakeFolder.localPath() + "A/a2"));
- QVERIFY(isSparseFile(fakeFolder.localPath() + "A/a3"));
- QVERIFY(isSparseFile(fakeFolder.localPath() + "A/a4"));
- QVERIFY(isSparseFile(fakeFolder.localPath() + "A/a5"));
- QVERIFY(isSparseFile(fakeFolder.localPath() + "A/a6"));
- QVERIFY(isSparseFile(fakeFolder.localPath() + "A/a7"));
- QVERIFY(isSparseFile(fakeFolder.localPath() + "A/b1"));
- QVERIFY(isSparseFile(fakeFolder.localPath() + "A/b2"));
- QVERIFY(isSparseFile(fakeFolder.localPath() + "A/b3"));
- QVERIFY(isSparseFile(fakeFolder.localPath() + "A/b4"));
+ QVERIFY(cfapi::isSparseFile(fakeFolder.localPath() + "A/a1"));
+ QVERIFY(cfapi::isSparseFile(fakeFolder.localPath() + "A/a2"));
+ QVERIFY(cfapi::isSparseFile(fakeFolder.localPath() + "A/a3"));
+ QVERIFY(cfapi::isSparseFile(fakeFolder.localPath() + "A/a4"));
+ QVERIFY(cfapi::isSparseFile(fakeFolder.localPath() + "A/a5"));
+ QVERIFY(cfapi::isSparseFile(fakeFolder.localPath() + "A/a6"));
+ QVERIFY(cfapi::isSparseFile(fakeFolder.localPath() + "A/a7"));
+ QVERIFY(cfapi::isSparseFile(fakeFolder.localPath() + "A/b1"));
+ QVERIFY(cfapi::isSparseFile(fakeFolder.localPath() + "A/b2"));
+ QVERIFY(cfapi::isSparseFile(fakeFolder.localPath() + "A/b3"));
+ QVERIFY(cfapi::isSparseFile(fakeFolder.localPath() + "A/b4"));
QVERIFY(QFileInfo(fakeFolder.localPath() + "A/a1").exists());
QVERIFY(QFileInfo(fakeFolder.localPath() + "A/a2").exists());
QVERIFY(itemInstruction(completeSpy, "A/b4m", CSYNC_INSTRUCTION_NEW));
QVERIFY(itemInstruction(completeSpy, "A/b4", CSYNC_INSTRUCTION_REMOVE));
- QVERIFY(!isSparseFile(fakeFolder.localPath() + "A/a1"));
- QVERIFY(!isSparseFile(fakeFolder.localPath() + "A/a2"));
+ QVERIFY(!cfapi::isSparseFile(fakeFolder.localPath() + "A/a1"));
+ QVERIFY(!cfapi::isSparseFile(fakeFolder.localPath() + "A/a2"));
QVERIFY(!QFileInfo(fakeFolder.localPath() + "A/a3").exists());
QVERIFY(!QFileInfo(fakeFolder.localPath() + "A/a4").exists());
- QVERIFY(!isSparseFile(fakeFolder.localPath() + "A/a4m"));
- QVERIFY(!isSparseFile(fakeFolder.localPath() + "A/a5"));
- QVERIFY(!isSparseFile(fakeFolder.localPath() + "A/a6"));
- QVERIFY(!isSparseFile(fakeFolder.localPath() + "A/a7"));
- QVERIFY(!isSparseFile(fakeFolder.localPath() + "A/b1"));
- QVERIFY(!isSparseFile(fakeFolder.localPath() + "A/b2"));
+ QVERIFY(!cfapi::isSparseFile(fakeFolder.localPath() + "A/a4m"));
+ QVERIFY(!cfapi::isSparseFile(fakeFolder.localPath() + "A/a5"));
+ QVERIFY(!cfapi::isSparseFile(fakeFolder.localPath() + "A/a6"));
+ QVERIFY(!cfapi::isSparseFile(fakeFolder.localPath() + "A/a7"));
+ QVERIFY(!cfapi::isSparseFile(fakeFolder.localPath() + "A/b1"));
+ QVERIFY(!cfapi::isSparseFile(fakeFolder.localPath() + "A/b2"));
QVERIFY(!QFileInfo(fakeFolder.localPath() + "A/b3").exists());
QVERIFY(!QFileInfo(fakeFolder.localPath() + "A/b4").exists());
- QVERIFY(!isSparseFile(fakeFolder.localPath() + "A/b4m"));
+ QVERIFY(!cfapi::isSparseFile(fakeFolder.localPath() + "A/b4m"));
QCOMPARE(dbRecord(fakeFolder, "A/a1")._type, ItemTypeFile);
QCOMPARE(dbRecord(fakeFolder, "A/a2")._type, ItemTypeFile);
fakeFolder.remoteModifier().mkdir("A");
fakeFolder.remoteModifier().insert("A/a1");
QVERIFY(fakeFolder.syncOnce());
- QVERIFY(isSparseFile(fakeFolder.localPath() + "A/a1"));
+ QVERIFY(cfapi::isSparseFile(fakeFolder.localPath() + "A/a1"));
QVERIFY(QFileInfo(fakeFolder.localPath() + "A/a1").exists());
QCOMPARE(dbRecord(fakeFolder, "A/a1")._type, ItemTypeVirtualFile);
cleanup();
fakeFolder.serverErrorPaths().append("A/a1", 500);
QVERIFY(!fakeFolder.syncOnce());
QVERIFY(itemInstruction(completeSpy, "A/a1", CSYNC_INSTRUCTION_SYNC));
- QVERIFY(isSparseFile(fakeFolder.localPath() + "A/a1"));
+ QVERIFY(cfapi::isSparseFile(fakeFolder.localPath() + "A/a1"));
QVERIFY(QFileInfo(fakeFolder.localPath() + "A/a1").exists());
QCOMPARE(dbRecord(fakeFolder, "A/a1")._type, ItemTypeVirtualFileDownload);
cleanup();
fakeFolder.serverErrorPaths().clear();
QVERIFY(fakeFolder.syncOnce());
QVERIFY(itemInstruction(completeSpy, "A/a1", CSYNC_INSTRUCTION_SYNC));
- QVERIFY(!isSparseFile(fakeFolder.localPath() + "A/a1"));
+ QVERIFY(!cfapi::isSparseFile(fakeFolder.localPath() + "A/a1"));
QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
QCOMPARE(dbRecord(fakeFolder, "A/a1")._type, ItemTypeFile);
}
fakeFolder.remoteModifier().mkdir("A");
fakeFolder.remoteModifier().insert("A/a1");
QVERIFY(fakeFolder.syncOnce());
- QVERIFY(isSparseFile(fakeFolder.localPath() + "A/a1"));
+ QVERIFY(cfapi::isSparseFile(fakeFolder.localPath() + "A/a1"));
QVERIFY(QFileInfo(fakeFolder.localPath() + "A/a1").exists());
QCOMPARE(dbRecord(fakeFolder, "A/a1")._type, ItemTypeVirtualFile);
- setPinState(fakeFolder.localPath(), PinState::AlwaysLocal);
+ setPinState(fakeFolder.localPath(), PinState::AlwaysLocal, cfapi::NoRecurse);
// Create a new remote file, it'll not be virtual
fakeFolder.remoteModifier().insert("A/a2");
QVERIFY(fakeFolder.syncOnce());
- QVERIFY(!isSparseFile(fakeFolder.localPath() + "A/a2"));
+ QVERIFY(!cfapi::isSparseFile(fakeFolder.localPath() + "A/a2"));
QVERIFY(QFileInfo(fakeFolder.localPath() + "A/a2").exists());
QCOMPARE(dbRecord(fakeFolder, "A/a2")._type, ItemTypeFile);
}
fakeFolder.remoteModifier().insert("B/Sub/b2");
QVERIFY(fakeFolder.syncOnce());
- QVERIFY(isSparseFile(fakeFolder.localPath() + "A/a1"));
- QVERIFY(isSparseFile(fakeFolder.localPath() + "A/a2"));
- QVERIFY(isSparseFile(fakeFolder.localPath() + "A/Sub/a3"));
- QVERIFY(isSparseFile(fakeFolder.localPath() + "A/Sub/a4"));
- QVERIFY(isSparseFile(fakeFolder.localPath() + "A/Sub/SubSub/a5"));
- QVERIFY(isSparseFile(fakeFolder.localPath() + "A/Sub2/a6"));
- QVERIFY(isSparseFile(fakeFolder.localPath() + "B/b1"));
- QVERIFY(isSparseFile(fakeFolder.localPath() + "B/Sub/b2"));
+ QVERIFY(cfapi::isSparseFile(fakeFolder.localPath() + "A/a1"));
+ QVERIFY(cfapi::isSparseFile(fakeFolder.localPath() + "A/a2"));
+ QVERIFY(cfapi::isSparseFile(fakeFolder.localPath() + "A/Sub/a3"));
+ QVERIFY(cfapi::isSparseFile(fakeFolder.localPath() + "A/Sub/a4"));
+ QVERIFY(cfapi::isSparseFile(fakeFolder.localPath() + "A/Sub/SubSub/a5"));
+ QVERIFY(cfapi::isSparseFile(fakeFolder.localPath() + "A/Sub2/a6"));
+ QVERIFY(cfapi::isSparseFile(fakeFolder.localPath() + "B/b1"));
+ QVERIFY(cfapi::isSparseFile(fakeFolder.localPath() + "B/Sub/b2"));
QVERIFY(QFileInfo(fakeFolder.localPath() + "A/a1").exists());
QVERIFY(QFileInfo(fakeFolder.localPath() + "A/a2").exists());
QVERIFY(fakeFolder.syncOnce());
- QVERIFY(isSparseFile(fakeFolder.localPath() + "A/a1"));
- QVERIFY(isSparseFile(fakeFolder.localPath() + "A/a2"));
- QVERIFY(!isSparseFile(fakeFolder.localPath() + "A/Sub/a3"));
- QVERIFY(!isSparseFile(fakeFolder.localPath() + "A/Sub/a4"));
- QVERIFY(!isSparseFile(fakeFolder.localPath() + "A/Sub/SubSub/a5"));
- QVERIFY(isSparseFile(fakeFolder.localPath() + "A/Sub2/a6"));
- QVERIFY(isSparseFile(fakeFolder.localPath() + "B/b1"));
- QVERIFY(isSparseFile(fakeFolder.localPath() + "B/Sub/b2"));
+ QVERIFY(cfapi::isSparseFile(fakeFolder.localPath() + "A/a1"));
+ QVERIFY(cfapi::isSparseFile(fakeFolder.localPath() + "A/a2"));
+ QVERIFY(!cfapi::isSparseFile(fakeFolder.localPath() + "A/Sub/a3"));
+ QVERIFY(!cfapi::isSparseFile(fakeFolder.localPath() + "A/Sub/a4"));
+ QVERIFY(!cfapi::isSparseFile(fakeFolder.localPath() + "A/Sub/SubSub/a5"));
+ QVERIFY(cfapi::isSparseFile(fakeFolder.localPath() + "A/Sub2/a6"));
+ QVERIFY(cfapi::isSparseFile(fakeFolder.localPath() + "B/b1"));
+ QVERIFY(cfapi::isSparseFile(fakeFolder.localPath() + "B/Sub/b2"));
QVERIFY(QFileInfo(fakeFolder.localPath() + "A/a1").exists());
QVERIFY(QFileInfo(fakeFolder.localPath() + "A/a2").exists());
fakeFolder.remoteModifier().insert("A/Sub/SubSub/a7");
QVERIFY(fakeFolder.syncOnce());
- QVERIFY(isSparseFile(fakeFolder.localPath() + "A/Sub/SubSub/a7"));
+ QVERIFY(cfapi::isSparseFile(fakeFolder.localPath() + "A/Sub/SubSub/a7"));
QVERIFY(QFileInfo(fakeFolder.localPath() + "A/Sub/SubSub/a7").exists());
QCOMPARE(dbRecord(fakeFolder, "A/Sub/SubSub/a7")._type, ItemTypeVirtualFile);
fakeFolder.syncJournal().markVirtualFileForDownloadRecursively("A");
QVERIFY(fakeFolder.syncOnce());
- QVERIFY(!isSparseFile(fakeFolder.localPath() + "A/a1"));
- QVERIFY(!isSparseFile(fakeFolder.localPath() + "A/a2"));
- QVERIFY(!isSparseFile(fakeFolder.localPath() + "A/Sub/a3"));
- QVERIFY(!isSparseFile(fakeFolder.localPath() + "A/Sub/a4"));
- QVERIFY(!isSparseFile(fakeFolder.localPath() + "A/Sub/SubSub/a5"));
- QVERIFY(!isSparseFile(fakeFolder.localPath() + "A/Sub/SubSub/a7"));
- QVERIFY(!isSparseFile(fakeFolder.localPath() + "A/Sub2/a6"));
- QVERIFY(isSparseFile(fakeFolder.localPath() + "B/b1"));
- QVERIFY(isSparseFile(fakeFolder.localPath() + "B/Sub/b2"));
+ QVERIFY(!cfapi::isSparseFile(fakeFolder.localPath() + "A/a1"));
+ QVERIFY(!cfapi::isSparseFile(fakeFolder.localPath() + "A/a2"));
+ QVERIFY(!cfapi::isSparseFile(fakeFolder.localPath() + "A/Sub/a3"));
+ QVERIFY(!cfapi::isSparseFile(fakeFolder.localPath() + "A/Sub/a4"));
+ QVERIFY(!cfapi::isSparseFile(fakeFolder.localPath() + "A/Sub/SubSub/a5"));
+ QVERIFY(!cfapi::isSparseFile(fakeFolder.localPath() + "A/Sub/SubSub/a7"));
+ QVERIFY(!cfapi::isSparseFile(fakeFolder.localPath() + "A/Sub2/a6"));
+ QVERIFY(cfapi::isSparseFile(fakeFolder.localPath() + "B/b1"));
+ QVERIFY(cfapi::isSparseFile(fakeFolder.localPath() + "B/Sub/b2"));
QVERIFY(QFileInfo(fakeFolder.localPath() + "A/a1").exists());
QVERIFY(QFileInfo(fakeFolder.localPath() + "A/a2").exists());
fakeFolder.remoteModifier().insert("file3", 256, 'C');
QVERIFY(fakeFolder.syncOnce());
- QVERIFY(isSparseFile(fakeFolder.localPath() + "file1"));
- QVERIFY(isSparseFile(fakeFolder.localPath() + "file2"));
- QVERIFY(isSparseFile(fakeFolder.localPath() + "file3"));
+ QVERIFY(cfapi::isSparseFile(fakeFolder.localPath() + "file1"));
+ QVERIFY(cfapi::isSparseFile(fakeFolder.localPath() + "file2"));
+ QVERIFY(cfapi::isSparseFile(fakeFolder.localPath() + "file3"));
QVERIFY(QFileInfo(fakeFolder.localPath() + "file1").exists());
QVERIFY(QFileInfo(fakeFolder.localPath() + "file2").exists());
QVERIFY(!QFileInfo(fakeFolder.localPath() + "file1").exists());
QVERIFY(!dbRecord(fakeFolder, "file1").isValid());
- QVERIFY(isSparseFile(fakeFolder.localPath() + "renamed1"));
+ QVERIFY(cfapi::isSparseFile(fakeFolder.localPath() + "renamed1"));
QVERIFY(QFileInfo(fakeFolder.localPath() + "renamed1").exists());
QCOMPARE(dbRecord(fakeFolder, "renamed1")._type, ItemTypeVirtualFile);
QVERIFY(!QFileInfo(fakeFolder.localPath() + "file2").exists());
QVERIFY(!dbRecord(fakeFolder, "file2").isValid());
- QVERIFY(isSparseFile(fakeFolder.localPath() + "renamed2"));
+ QVERIFY(cfapi::isSparseFile(fakeFolder.localPath() + "renamed2"));
QVERIFY(QFileInfo(fakeFolder.localPath() + "renamed2").exists());
QCOMPARE(dbRecord(fakeFolder, "renamed2")._type, ItemTypeVirtualFile);
QVERIFY(itemInstruction(completeSpy, "renamed2", CSYNC_INSTRUCTION_RENAME));
QVERIFY(itemInstruction(completeSpy, "file3", CSYNC_INSTRUCTION_SYNC));
- QVERIFY(!isSparseFile(fakeFolder.localPath() + "file3"));
+ QVERIFY(!cfapi::isSparseFile(fakeFolder.localPath() + "file3"));
QVERIFY(QFileInfo(fakeFolder.localPath() + "file3").exists());
QVERIFY(dbRecord(fakeFolder, "file3")._type == ItemTypeFile);
cleanup();
triggerDownload(fakeFolder, "case4");
QVERIFY(fakeFolder.syncOnce());
- QVERIFY(isSparseFile(fakeFolder.localPath() + "case3"));
- QVERIFY(!isSparseFile(fakeFolder.localPath() + "case4"));
+ QVERIFY(cfapi::isSparseFile(fakeFolder.localPath() + "case3"));
+ QVERIFY(!cfapi::isSparseFile(fakeFolder.localPath() + "case4"));
QVERIFY(QFileInfo(fakeFolder.localPath() + "case3").exists());
QVERIFY(QFileInfo(fakeFolder.localPath() + "case4").exists());
// Case 3: the rename went though, hydration is forgotten
QVERIFY(!QFileInfo(fakeFolder.localPath() + "case3").exists());
- QVERIFY(isSparseFile(fakeFolder.localPath() + "case3-rename"));
+ QVERIFY(cfapi::isSparseFile(fakeFolder.localPath() + "case3-rename"));
QVERIFY(QFileInfo(fakeFolder.localPath() + "case3-rename").exists());
QVERIFY(!fakeFolder.currentRemoteState().find("case3"));
QVERIFY(fakeFolder.currentRemoteState().find("case3-rename"));
// Case 4: the rename went though, dehydration is forgotten
QVERIFY(!QFileInfo(fakeFolder.localPath() + "case4").exists());
- QVERIFY(!isSparseFile(fakeFolder.localPath() + "case4-rename"));
+ QVERIFY(!cfapi::isSparseFile(fakeFolder.localPath() + "case4-rename"));
QVERIFY(QFileInfo(fakeFolder.localPath() + "case4-rename").exists());
QVERIFY(!fakeFolder.currentRemoteState().find("case4"));
QVERIFY(fakeFolder.currentRemoteState().find("case4-rename"));
QVERIFY(fakeFolder.syncOnce());
auto isDehydrated = [&](const QString &path) {
- return isSparseFile(fakeFolder.localPath() + path)
+ return cfapi::isSparseFile(fakeFolder.localPath() + path)
&& QFileInfo(fakeFolder.localPath() + path).exists();
};
auto hasDehydratedDbEntries = [&](const QString &path) {
QVERIFY(fakeFolder.syncOnce());
- QVERIFY(isSparseFile(fakeFolder.localPath() + "f1"));
- QVERIFY(isSparseFile(fakeFolder.localPath() + "A/a1"));
- QVERIFY(isSparseFile(fakeFolder.localPath() + "A/a3"));
- QVERIFY(isSparseFile(fakeFolder.localPath() + "A/B/b1"));
+ QVERIFY(cfapi::isSparseFile(fakeFolder.localPath() + "f1"));
+ QVERIFY(cfapi::isSparseFile(fakeFolder.localPath() + "A/a1"));
+ QVERIFY(cfapi::isSparseFile(fakeFolder.localPath() + "A/a3"));
+ QVERIFY(cfapi::isSparseFile(fakeFolder.localPath() + "A/B/b1"));
QVERIFY(QFileInfo(fakeFolder.localPath() + "f1").exists());
QVERIFY(QFileInfo(fakeFolder.localPath() + "A/a1").exists());
QVERIFY(fakeFolder.syncOnce());
QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
- setPinState(fakeFolder.localPath() + "local", PinState::AlwaysLocal, true);
- setPinState(fakeFolder.localPath() + "online", PinState::OnlineOnly, true);
- setPinState(fakeFolder.localPath() + "unspec", PinState::Unspecified, true);
+ setPinState(fakeFolder.localPath() + "local", PinState::AlwaysLocal, cfapi::Recurse);
+ setPinState(fakeFolder.localPath() + "online", PinState::OnlineOnly, cfapi::Recurse);
+ setPinState(fakeFolder.localPath() + "unspec", PinState::Unspecified, cfapi::Recurse);
// Test 1: root is Unspecified
fakeFolder.remoteModifier().insert("file1");
fakeFolder.remoteModifier().insert("unspec/file1");
QVERIFY(fakeFolder.syncOnce());
- QVERIFY(isSparseFile(fakeFolder.localPath() + "file1"));
- QVERIFY(isSparseFile(fakeFolder.localPath() + "online/file1"));
- QVERIFY(!isSparseFile(fakeFolder.localPath() + "local/file1"));
- QVERIFY(isSparseFile(fakeFolder.localPath() + "unspec/file1"));
+ QVERIFY(cfapi::isSparseFile(fakeFolder.localPath() + "file1"));
+ QVERIFY(cfapi::isSparseFile(fakeFolder.localPath() + "online/file1"));
+ QVERIFY(!cfapi::isSparseFile(fakeFolder.localPath() + "local/file1"));
+ QVERIFY(cfapi::isSparseFile(fakeFolder.localPath() + "unspec/file1"));
QVERIFY(QFileInfo(fakeFolder.localPath() + "file1").exists());
QVERIFY(QFileInfo(fakeFolder.localPath() + "online/file1").exists());
QCOMPARE(dbRecord(fakeFolder, "unspec/file1")._type, ItemTypeVirtualFile);
// Test 2: change root to AlwaysLocal
- setPinState(fakeFolder.localPath(), PinState::AlwaysLocal, true);
+ setPinState(fakeFolder.localPath(), PinState::AlwaysLocal, cfapi::Recurse);
// Need to force pin state for the subfolders again
- setPinState(fakeFolder.localPath() + "local", PinState::AlwaysLocal, true);
- setPinState(fakeFolder.localPath() + "online", PinState::OnlineOnly, true);
- setPinState(fakeFolder.localPath() + "unspec", PinState::Unspecified, true);
+ setPinState(fakeFolder.localPath() + "local", PinState::AlwaysLocal, cfapi::Recurse);
+ setPinState(fakeFolder.localPath() + "online", PinState::OnlineOnly, cfapi::Recurse);
+ setPinState(fakeFolder.localPath() + "unspec", PinState::Unspecified, cfapi::Recurse);
fakeFolder.remoteModifier().insert("file2");
fakeFolder.remoteModifier().insert("online/file2");
fakeFolder.remoteModifier().insert("unspec/file2");
QVERIFY(fakeFolder.syncOnce());
- QVERIFY(!isSparseFile(fakeFolder.localPath() + "file2"));
- QVERIFY(isSparseFile(fakeFolder.localPath() + "online/file2"));
- QVERIFY(!isSparseFile(fakeFolder.localPath() + "local/file2"));
- QVERIFY(isSparseFile(fakeFolder.localPath() + "unspec/file2"));
+ QVERIFY(!cfapi::isSparseFile(fakeFolder.localPath() + "file2"));
+ QVERIFY(cfapi::isSparseFile(fakeFolder.localPath() + "online/file2"));
+ QVERIFY(!cfapi::isSparseFile(fakeFolder.localPath() + "local/file2"));
+ QVERIFY(cfapi::isSparseFile(fakeFolder.localPath() + "unspec/file2"));
QVERIFY(QFileInfo(fakeFolder.localPath() + "file2").exists());
QVERIFY(QFileInfo(fakeFolder.localPath() + "online/file2").exists());
QCOMPARE(dbRecord(fakeFolder, "unspec/file2")._type, ItemTypeVirtualFile);
// root file1 was hydrated due to its new pin state
- QVERIFY(!isSparseFile(fakeFolder.localPath() + "file1"));
+ QVERIFY(!cfapi::isSparseFile(fakeFolder.localPath() + "file1"));
QVERIFY(QFileInfo(fakeFolder.localPath() + "file1").exists());
QCOMPARE(dbRecord(fakeFolder, "file1")._type, ItemTypeFile);
// file1 is unchanged in the explicitly pinned subfolders
- QVERIFY(isSparseFile(fakeFolder.localPath() + "online/file1"));
- QVERIFY(!isSparseFile(fakeFolder.localPath() + "local/file1"));
- QVERIFY(isSparseFile(fakeFolder.localPath() + "unspec/file1"));
+ QVERIFY(cfapi::isSparseFile(fakeFolder.localPath() + "online/file1"));
+ QVERIFY(!cfapi::isSparseFile(fakeFolder.localPath() + "local/file1"));
+ QVERIFY(cfapi::isSparseFile(fakeFolder.localPath() + "unspec/file1"));
QVERIFY(QFileInfo(fakeFolder.localPath() + "online/file1").exists());
QVERIFY(QFileInfo(fakeFolder.localPath() + "local/file1").exists());
QCOMPARE(dbRecord(fakeFolder, "unspec/file1")._type, ItemTypeVirtualFile);
// Test 3: change root to OnlineOnly
- setPinState(fakeFolder.localPath(), PinState::OnlineOnly, true);
+ setPinState(fakeFolder.localPath(), PinState::OnlineOnly, cfapi::Recurse);
// Need to force pin state for the subfolders again
- setPinState(fakeFolder.localPath() + "local", PinState::AlwaysLocal, true);
- setPinState(fakeFolder.localPath() + "online", PinState::OnlineOnly, true);
- setPinState(fakeFolder.localPath() + "unspec", PinState::Unspecified, true);
+ setPinState(fakeFolder.localPath() + "local", PinState::AlwaysLocal, cfapi::Recurse);
+ setPinState(fakeFolder.localPath() + "online", PinState::OnlineOnly, cfapi::Recurse);
+ setPinState(fakeFolder.localPath() + "unspec", PinState::Unspecified, cfapi::Recurse);
fakeFolder.remoteModifier().insert("file3");
fakeFolder.remoteModifier().insert("online/file3");
fakeFolder.remoteModifier().insert("unspec/file3");
QVERIFY(fakeFolder.syncOnce());
- QVERIFY(isSparseFile(fakeFolder.localPath() + "file3"));
- QVERIFY(isSparseFile(fakeFolder.localPath() + "online/file3"));
- QVERIFY(!isSparseFile(fakeFolder.localPath() + "local/file3"));
- QVERIFY(isSparseFile(fakeFolder.localPath() + "unspec/file3"));
+ QVERIFY(cfapi::isSparseFile(fakeFolder.localPath() + "file3"));
+ QVERIFY(cfapi::isSparseFile(fakeFolder.localPath() + "online/file3"));
+ QVERIFY(!cfapi::isSparseFile(fakeFolder.localPath() + "local/file3"));
+ QVERIFY(cfapi::isSparseFile(fakeFolder.localPath() + "unspec/file3"));
QVERIFY(QFileInfo(fakeFolder.localPath() + "file3").exists());
QVERIFY(QFileInfo(fakeFolder.localPath() + "online/file3").exists());
// root file1 was dehydrated due to its new pin state
- QVERIFY(isSparseFile(fakeFolder.localPath() + "file1"));
+ QVERIFY(cfapi::isSparseFile(fakeFolder.localPath() + "file1"));
QVERIFY(QFileInfo(fakeFolder.localPath() + "file1").exists());
QCOMPARE(dbRecord(fakeFolder, "file1")._type, ItemTypeVirtualFile);
// file1 is unchanged in the explicitly pinned subfolders
- QVERIFY(isSparseFile(fakeFolder.localPath() + "online/file1"));
- QVERIFY(!isSparseFile(fakeFolder.localPath() + "local/file1"));
- QVERIFY(isSparseFile(fakeFolder.localPath() + "unspec/file1"));
+ QVERIFY(cfapi::isSparseFile(fakeFolder.localPath() + "online/file1"));
+ QVERIFY(!cfapi::isSparseFile(fakeFolder.localPath() + "local/file1"));
+ QVERIFY(cfapi::isSparseFile(fakeFolder.localPath() + "unspec/file1"));
QVERIFY(QFileInfo(fakeFolder.localPath() + "online/file1").exists());
QVERIFY(QFileInfo(fakeFolder.localPath() + "local/file1").exists());
QVERIFY(fakeFolder.syncOnce());
QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
- setPinState(fakeFolder.localPath() + "local", PinState::AlwaysLocal, true);
- setPinState(fakeFolder.localPath() + "online", PinState::OnlineOnly, true);
- setPinState(fakeFolder.localPath() + "unspec", PinState::Unspecified, true);
+ setPinState(fakeFolder.localPath() + "local", PinState::AlwaysLocal, cfapi::Recurse);
+ setPinState(fakeFolder.localPath() + "online", PinState::OnlineOnly, cfapi::Recurse);
+ setPinState(fakeFolder.localPath() + "unspec", PinState::Unspecified, cfapi::Recurse);
fakeFolder.remoteModifier().insert("file1");
fakeFolder.remoteModifier().insert("online/file1");
QCOMPARE(*vfs->availability("unspec/file1"), VfsItemAvailability::AllDehydrated);
// Subitem pin states can ruin "pure" availabilities
- setPinState(fakeFolder.localPath() + "local/sub", PinState::OnlineOnly);
+ setPinState(fakeFolder.localPath() + "local/sub", PinState::OnlineOnly, cfapi::NoRecurse);
QCOMPARE(*vfs->availability("local"), VfsItemAvailability::AllHydrated);
- setPinState(fakeFolder.localPath() + "online/sub", PinState::Unspecified);
+ setPinState(fakeFolder.localPath() + "online/sub", PinState::Unspecified, cfapi::NoRecurse);
QCOMPARE(*vfs->availability("online"), VfsItemAvailability::AllDehydrated);
triggerDownload(fakeFolder, "unspec/file1");
- setPinState(fakeFolder.localPath() + "local/file2", PinState::OnlineOnly);
- setPinState(fakeFolder.localPath() + "online/file2", PinState::AlwaysLocal);
+ setPinState(fakeFolder.localPath() + "local/file2", PinState::OnlineOnly, cfapi::NoRecurse);
+ setPinState(fakeFolder.localPath() + "online/file2", PinState::AlwaysLocal, cfapi::NoRecurse);
QVERIFY(fakeFolder.syncOnce());
QCOMPARE(*vfs->availability("unspec"), VfsItemAvailability::AllHydrated);
QVERIFY(fakeFolder.syncOnce());
QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
- setPinState(fakeFolder.localPath() + "local", PinState::AlwaysLocal);
- setPinState(fakeFolder.localPath() + "online", PinState::OnlineOnly);
- setPinState(fakeFolder.localPath() + "unspec", PinState::Unspecified);
+ setPinState(fakeFolder.localPath() + "local", PinState::AlwaysLocal, cfapi::NoRecurse);
+ setPinState(fakeFolder.localPath() + "online", PinState::OnlineOnly, cfapi::NoRecurse);
+ setPinState(fakeFolder.localPath() + "unspec", PinState::Unspecified, cfapi::NoRecurse);
fakeFolder.localModifier().insert("file1");
fakeFolder.localModifier().insert("online/file1");
vfs->setPinState("onlinerenamed2/file1rename", PinState::OnlineOnly);
QVERIFY(fakeFolder.syncOnce());
- QVERIFY(isSparseFile(fakeFolder.localPath() + "onlinerenamed2/file1rename"));
+ QVERIFY(cfapi::isSparseFile(fakeFolder.localPath() + "onlinerenamed2/file1rename"));
QVERIFY(QFileInfo(fakeFolder.localPath() + "onlinerenamed2/file1rename").exists());
QCOMPARE(dbRecord(fakeFolder, "onlinerenamed2/file1rename")._type, ItemTypeVirtualFile);
QVERIFY(fakeFolder.syncOnce());
QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
- setPinState(fakeFolder.localPath() + "local", PinState::AlwaysLocal);
- setPinState(fakeFolder.localPath() + "online", PinState::OnlineOnly);
+ setPinState(fakeFolder.localPath() + "local", PinState::AlwaysLocal, cfapi::NoRecurse);
+ setPinState(fakeFolder.localPath() + "online", PinState::OnlineOnly, cfapi::NoRecurse);
fakeFolder.localModifier().insert("local/file1");
fakeFolder.localModifier().insert("online/file1");
// the sync sets the changed files pin states to unspecified
QVERIFY(fakeFolder.syncOnce());
- QVERIFY(!isSparseFile(fakeFolder.localPath() + "online/file1"));
+ QVERIFY(!cfapi::isSparseFile(fakeFolder.localPath() + "online/file1"));
QVERIFY(QFileInfo(fakeFolder.localPath() + "online/file1").exists());
QCOMPARE(dbRecord(fakeFolder, "online/file1")._type, ItemTypeFile);
- QVERIFY(isSparseFile(fakeFolder.localPath() + "local/file1"));
+ QVERIFY(cfapi::isSparseFile(fakeFolder.localPath() + "local/file1"));
QVERIFY(QFileInfo(fakeFolder.localPath() + "local/file1").exists());
QCOMPARE(dbRecord(fakeFolder, "local/file1")._type, ItemTypeVirtualFile);
// no change on another sync
QVERIFY(fakeFolder.syncOnce());
- QVERIFY(!isSparseFile(fakeFolder.localPath() + "online/file1"));
+ QVERIFY(!cfapi::isSparseFile(fakeFolder.localPath() + "online/file1"));
QVERIFY(QFileInfo(fakeFolder.localPath() + "online/file1").exists());
QCOMPARE(dbRecord(fakeFolder, "online/file1")._type, ItemTypeFile);
- QVERIFY(isSparseFile(fakeFolder.localPath() + "local/file1"));
+ QVERIFY(cfapi::isSparseFile(fakeFolder.localPath() + "local/file1"));
QVERIFY(QFileInfo(fakeFolder.localPath() + "local/file1").exists());
QCOMPARE(dbRecord(fakeFolder, "local/file1")._type, ItemTypeVirtualFile);
}