Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/owncloud/client.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorErik Verbruggen <erik@verbruggen.consulting>2022-09-08 18:57:43 +0300
committerErik Verbruggen <Erik.Verbruggen@Me.com>2022-09-22 17:21:51 +0300
commitc60da8be5dfca5b232440f30657098823c822d68 (patch)
tree1bd8b5373c615fc1be26bc49cc2fc96fc284e42c /test
parentfe3136a1b68f5efad414944655c310e2992879de (diff)
Tests: Clean up FileModifier API
- make the default values into static constexpr member fields - remove unused method `modifyByte` - don't rely on on-disk info like file sizes (so it can be used in dehydrated VFS modes)
Diffstat (limited to 'test')
-rw-r--r--test/testallfilesdeleted.cpp20
-rw-r--r--test/testblacklist.cpp7
-rw-r--r--test/testchunkingng.cpp56
-rw-r--r--test/testdownload.cpp5
-rw-r--r--test/testpermissions.cpp4
-rw-r--r--test/testsyncconflict.cpp16
-rw-r--r--test/testsyncengine.cpp21
-rw-r--r--test/testsyncmove.cpp29
-rw-r--r--test/testutils/syncenginetestutils.cpp41
-rw-r--r--test/testutils/syncenginetestutils.h66
10 files changed, 149 insertions, 116 deletions
diff --git a/test/testallfilesdeleted.cpp b/test/testallfilesdeleted.cpp
index bd220457c..7b78749f1 100644
--- a/test/testallfilesdeleted.cpp
+++ b/test/testallfilesdeleted.cpp
@@ -67,9 +67,10 @@ private slots:
});
auto &modifier = deleteOnRemote ? fakeFolder.remoteModifier() : fakeFolder.localModifier();
- const auto &children = fakeFolder.currentRemoteState().children;
- for (auto it = children.cbegin(); it != children.cend(); ++it)
+ const auto children = fakeFolder.currentRemoteState().children; // make sure to take a copy, otherwise it's a use-after-free
+ for (auto it = children.cbegin(); it != children.cend(); ++it) {
modifier.remove(it.key());
+ }
QVERIFY(!fakeFolder.syncOnce()); // Should fail because we cancel the sync
QCOMPARE(aboutToRemoveAllFilesCalled, 1);
@@ -108,9 +109,10 @@ private slots:
});
auto &modifier = deleteOnRemote ? fakeFolder.remoteModifier() : fakeFolder.localModifier();
- const auto &children = fakeFolder.currentRemoteState().children;
- for (auto it = children.cbegin(); it != children.cend(); ++it)
+ const auto children = fakeFolder.currentRemoteState().children; // make sure to take a copy, otherwise it's a use-after-free
+ for (auto it = children.cbegin(); it != children.cend(); ++it) {
modifier.remove(it.key());
+ }
QVERIFY(fakeFolder.syncOnce()); // Should succeed, and all files must then be deleted
@@ -187,18 +189,18 @@ private slots:
}
- void testDataFingetPrint_data()
+ void testDataFingerPrint_data()
{
QTest::addColumn<bool>("hasInitialFingerPrint");
QTest::newRow("initial finger print") << true;
QTest::newRow("no initial finger print") << false;
}
- void testDataFingetPrint()
+ void testDataFingerPrint()
{
QFETCH(bool, hasInitialFingerPrint);
FakeFolder fakeFolder{ FileInfo::A12_B12_C12_S12() };
- fakeFolder.remoteModifier().setContents(QStringLiteral("C/c1"), 'N');
+ fakeFolder.remoteModifier().setContents(QStringLiteral("C/c1"), FileModifier::DefaultFileSize, 'N');
fakeFolder.remoteModifier().setModTime(QStringLiteral("C/c1"), QDateTime::currentDateTimeUtc().addDays(-2));
fakeFolder.remoteModifier().remove(QStringLiteral("C/c2"));
if (hasInitialFingerPrint) {
@@ -234,12 +236,12 @@ private slots:
/* Simulate a backup restoration */
// A/a1 is an old file
- fakeFolder.remoteModifier().setContents(QStringLiteral("A/a1"), 'O');
+ fakeFolder.remoteModifier().setContents(QStringLiteral("A/a1"), FileModifier::DefaultFileSize, 'O');
fakeFolder.remoteModifier().setModTime(QStringLiteral("A/a1"), QDateTime::currentDateTimeUtc().addDays(-2));
// B/b1 did not exist at the time of the backup
fakeFolder.remoteModifier().remove(QStringLiteral("B/b1"));
// B/b2 was uploaded by another user in the mean time.
- fakeFolder.remoteModifier().setContents(QStringLiteral("B/b2"), 'N');
+ fakeFolder.remoteModifier().setContents(QStringLiteral("B/b2"), FileModifier::DefaultFileSize, 'N');
fakeFolder.remoteModifier().setModTime(QStringLiteral("B/b2"), QDateTime::currentDateTimeUtc().addDays(2));
// C/c3 was removed since we made the backup
diff --git a/test/testblacklist.cpp b/test/testblacklist.cpp
index 4c16c0703..2585b1335 100644
--- a/test/testblacklist.cpp
+++ b/test/testblacklist.cpp
@@ -79,8 +79,9 @@ private slots:
QVERIFY(entry._ignoreDuration > 0);
QCOMPARE(entry._requestId, reqId);
- if (remote)
+ if (remote) {
QCOMPARE(journalRecord(fakeFolder, "A")._etag, initialEtag);
+ }
}
cleanup();
@@ -132,6 +133,10 @@ private slots:
}
cleanup();
+ // Try to make sure that the modifications below do are not within the same second as the
+ // previous sync attempt was done, otherwise the changes go undetected.
+ QThread::sleep(1);
+
// When the file changes a retry happens immediately
modifier.appendByte(testFileName);
QVERIFY(!fakeFolder.syncOnce());
diff --git a/test/testchunkingng.cpp b/test/testchunkingng.cpp
index 65f4040bc..bba9329d3 100644
--- a/test/testchunkingng.cpp
+++ b/test/testchunkingng.cpp
@@ -15,6 +15,22 @@ using namespace std::chrono_literals;
using namespace OCC;
namespace {
+
+constexpr unsigned long long operator"" _kb(unsigned long long sz)
+{
+ return sz * 1024;
+}
+
+constexpr unsigned long long operator"" _mb(unsigned long long sz)
+{
+ return operator"" _kb(sz) * 1024;
+}
+
+constexpr unsigned long long operator"" _gb(unsigned long long sz)
+{
+ return operator"" _mb(sz) * 1024;
+}
+
/* Upload a 1/3 of a file of given size.
* fakeFolder needs to be synchronized */
void partialUpload(FakeFolder &fakeFolder, const QString &name, qint64 size)
@@ -52,7 +68,8 @@ void setChunkSize(SyncEngine &engine, qint64 size)
options._minChunkSize = size;
engine.setSyncOptions(options);
}
-}
+
+} // anonymous namespace
class TestChunkingNG : public QObject
{
@@ -367,9 +384,9 @@ private slots:
QCOMPARE(fakeFolder.uploadState().children.count(), 1);
auto chunkingId = fakeFolder.uploadState().children.first().name;
-
- fakeFolder.localModifier().setContents(QStringLiteral("A/a0"), 'B');
- fakeFolder.localModifier().appendByte(QStringLiteral("A/a0"));
+ const auto a0size = fakeFolder.currentLocalState().find("A/a0")->contentSize;
+ fakeFolder.localModifier().setContents(QStringLiteral("A/a0"), a0size, 'B');
+ fakeFolder.localModifier().appendByte(QStringLiteral("A/a0"), 'B');
QVERIFY(fakeFolder.syncOnce());
@@ -408,16 +425,17 @@ private slots:
QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
// Modify the file localy and start the upload
- fakeFolder.localModifier().setContents(QStringLiteral("A/a0"), 'B');
- fakeFolder.localModifier().appendByte(QStringLiteral("A/a0"));
+ fakeFolder.localModifier().setContents(QStringLiteral("A/a0"), size, 'B');
+ fakeFolder.localModifier().appendByte(QStringLiteral("A/a0"), 'B');
// But in the middle of the sync, modify the file on the server
- QMetaObject::Connection con = QObject::connect(&fakeFolder.syncEngine(), &SyncEngine::transmissionProgress,
- [&](const ProgressInfo &progress) {
- if (progress.completedSize() > (progress.totalSize() / 2 )) {
- fakeFolder.remoteModifier().setContents(QStringLiteral("A/a0"), 'C');
- QObject::disconnect(con);
- }
+ QMetaObject::Connection con = QObject::connect(&fakeFolder.syncEngine(), &SyncEngine::transmissionProgress, [&](const ProgressInfo &progress) {
+ qDebug() << progress.completedSize() << progress.totalSize();
+ if (progress.completedSize() > (progress.totalSize() / 2)) {
+ auto a0size = fakeFolder.currentRemoteState().find(QStringLiteral("A/a0"))->contentSize;
+ fakeFolder.remoteModifier().setContents(QStringLiteral("A/a0"), a0size, 'C');
+ QObject::disconnect(con);
+ }
});
QVERIFY(!fakeFolder.syncOnce());
@@ -455,17 +473,17 @@ private slots:
void testModifyLocalFileWhileUploading() {
FakeFolder fakeFolder{FileInfo::A12_B12_C12_S12()};
- const int size = 10 * 1000 * 1000; // 100 MB
- setChunkSize(fakeFolder.syncEngine(), 1 * 1000 * 1000);
+ const int size = 10_mb;
+ setChunkSize(fakeFolder.syncEngine(), 1_mb);
- fakeFolder.localModifier().insert(QStringLiteral("A/a0"), size);
+ fakeFolder.localModifier().insert(QStringLiteral("A/a0"), size, 'A');
// middle of the sync, modify the file
QMetaObject::Connection con = QObject::connect(&fakeFolder.syncEngine(), &SyncEngine::transmissionProgress,
[&](const ProgressInfo &progress) {
if (progress.completedSize() > (progress.totalSize() / 2 )) {
- fakeFolder.localModifier().setContents(QStringLiteral("A/a0"), 'B');
- fakeFolder.localModifier().appendByte(QStringLiteral("A/a0"));
+ fakeFolder.localModifier().setContents(QStringLiteral("A/a0"), size, 'B');
+ fakeFolder.localModifier().appendByte(QStringLiteral("A/a0"), 'B');
QObject::disconnect(con);
}
});
@@ -591,10 +609,10 @@ private slots:
QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
}
- // Test uploading large files (2.5GiB)
+ // Test uploading large files (2 GiB)
void testVeryBigFiles() {
FakeFolder fakeFolder{FileInfo::A12_B12_C12_S12()};
- const qint64 size = 2.5 * 1024 * 1024 * 1024; // 2.5 GiB
+ const qint64 size = 2_gb; // stay under the INT_MAX limit: QByteArray takes a signed int, so bigger sizes will give weird results.
// Partial upload of big files
partialUpload(fakeFolder, QStringLiteral("A/a0"), size);
diff --git a/test/testdownload.cpp b/test/testdownload.cpp
index 492f0ebbe..89add9b06 100644
--- a/test/testdownload.cpp
+++ b/test/testdownload.cpp
@@ -174,8 +174,9 @@ private slots:
FakeFolder fakeFolder{ FileInfo::A12_B12_C12_S12() };
fakeFolder.syncEngine().setIgnoreHiddenFiles(true);
- fakeFolder.remoteModifier().setContents(QStringLiteral("A/a1"), 'A');
- fakeFolder.localModifier().setContents(QStringLiteral("A/a1"), 'B');
+ fakeFolder.account()->setCapabilities(TestUtils::testCapabilities(CheckSums::Algorithm::ADLER32));
+ fakeFolder.remoteModifier().setContents(QStringLiteral("A/a1"), FileModifier::DefaultFileSize, 'A');
+ fakeFolder.localModifier().setContents(QStringLiteral("A/a1"), FileModifier::DefaultFileSize, 'B');
bool propConnected = false;
QString conflictFile;
diff --git a/test/testpermissions.cpp b/test/testpermissions.cpp
index 5340886c1..8e4242078 100644
--- a/test/testpermissions.cpp
+++ b/test/testpermissions.cpp
@@ -313,7 +313,7 @@ private slots:
QVERIFY(fakeFolder.syncOnce());
editReadOnly(QStringLiteral("readonlyDirectory_PERM_M_/cannotBeModified_PERM_DVN_.data"));
- fakeFolder.localModifier().setContents(QStringLiteral("readonlyDirectory_PERM_M_/cannotBeModified_PERM_DVN_.data"), 's');
+ fakeFolder.localModifier().setContents(QStringLiteral("readonlyDirectory_PERM_M_/cannotBeModified_PERM_DVN_.data"), FileModifier::DefaultFileSize, 's');
//do the sync
applyPermissionsFromName(fakeFolder.remoteModifier());
QVERIFY(fakeFolder.syncOnce());
@@ -321,7 +321,7 @@ private slots:
QThread::sleep(1); // make sure changes have different mtime
editReadOnly(QStringLiteral("readonlyDirectory_PERM_M_/cannotBeModified_PERM_DVN_.data"));
- fakeFolder.localModifier().setContents(QStringLiteral("readonlyDirectory_PERM_M_/cannotBeModified_PERM_DVN_.data"), 'd');
+ fakeFolder.localModifier().setContents(QStringLiteral("readonlyDirectory_PERM_M_/cannotBeModified_PERM_DVN_.data"), FileModifier::DefaultFileSize, 'd');
//do the sync
applyPermissionsFromName(fakeFolder.remoteModifier());
diff --git a/test/testsyncconflict.cpp b/test/testsyncconflict.cpp
index fd8f84ee7..b74bf708d 100644
--- a/test/testsyncconflict.cpp
+++ b/test/testsyncconflict.cpp
@@ -86,8 +86,8 @@ private slots:
FakeFolder fakeFolder{ FileInfo::A12_B12_C12_S12() };
QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
- fakeFolder.localModifier().setContents(QStringLiteral("A/a1"), 'L');
- fakeFolder.remoteModifier().setContents(QStringLiteral("A/a1"), 'R');
+ fakeFolder.localModifier().setContents(QStringLiteral("A/a1"), FileModifier::DefaultFileSize, 'L');
+ fakeFolder.remoteModifier().setContents(QStringLiteral("A/a1"), FileModifier::DefaultFileSize, 'R');
fakeFolder.localModifier().appendByte(QStringLiteral("A/a2"));
fakeFolder.remoteModifier().appendByte(QStringLiteral("A/a2"));
fakeFolder.remoteModifier().appendByte(QStringLiteral("A/a2"));
@@ -129,8 +129,8 @@ private slots:
return nullptr;
});
- fakeFolder.localModifier().setContents(QStringLiteral("A/a1"), 'L');
- fakeFolder.remoteModifier().setContents(QStringLiteral("A/a1"), 'R');
+ fakeFolder.localModifier().setContents(QStringLiteral("A/a1"), FileModifier::DefaultFileSize, 'L');
+ fakeFolder.remoteModifier().setContents(QStringLiteral("A/a1"), FileModifier::DefaultFileSize, 'R');
fakeFolder.localModifier().appendByte(QStringLiteral("A/a2"));
fakeFolder.remoteModifier().appendByte(QStringLiteral("A/a2"));
fakeFolder.remoteModifier().appendByte(QStringLiteral("A/a2"));
@@ -200,7 +200,7 @@ private slots:
// Now the user can locally alter the conflict file and it will be uploaded
// as usual.
- fakeFolder.localModifier().setContents(conflictName, 'P');
+ fakeFolder.localModifier().setContents(conflictName, FileModifier::DefaultFileSize + 1, 'P'); // make sure the file sizes are different
QVERIFY(fakeFolder.syncOnce());
QCOMPARE(conflictMap.size(), 1);
QCOMPARE(conflictMap[a1FileId], conflictName);
@@ -208,7 +208,7 @@ private slots:
conflictMap.clear();
// Similarly, remote modifications of conflict files get propagated downwards
- fakeFolder.remoteModifier().setContents(conflictName, 'Q');
+ fakeFolder.remoteModifier().setContents(conflictName, FileModifier::DefaultFileSize + 1, 'Q'); // make sure the file sizes are different
QVERIFY(fakeFolder.syncOnce());
QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
QVERIFY(conflictMap.isEmpty());
@@ -222,8 +222,8 @@ private slots:
QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
QCOMPARE(conflictMap.size(), 1);
QVERIFY(conflictMap.contains(a1ConflictFileId));
- QCOMPARE(fakeFolder.currentRemoteState().find(conflictName)->contentSize, 66);
- QCOMPARE(fakeFolder.currentRemoteState().find(conflictMap[a1ConflictFileId])->contentSize, 65);
+ QCOMPARE(fakeFolder.currentRemoteState().find(conflictName)->contentSize, FileModifier::DefaultFileSize + 3);
+ QCOMPARE(fakeFolder.currentRemoteState().find(conflictMap[a1ConflictFileId])->contentSize, FileModifier::DefaultFileSize + 2);
conflictMap.clear();
}
diff --git a/test/testsyncengine.cpp b/test/testsyncengine.cpp
index cba272515..3d6a0ed91 100644
--- a/test/testsyncengine.cpp
+++ b/test/testsyncengine.cpp
@@ -134,16 +134,16 @@ private slots:
ItemCompletedSpy completeSpy(fakeFolder);
// Touch the file without changing the content, shouldn't upload
- fakeFolder.localModifier().setContents(QStringLiteral("a1.eml"), 'A');
+ fakeFolder.localModifier().setContents(QStringLiteral("a1.eml"), 64, 'A');
// Change the content/size
- fakeFolder.localModifier().setContents(QStringLiteral("a2.eml"), 'B');
- fakeFolder.localModifier().appendByte(QStringLiteral("a3.eml"));
- fakeFolder.localModifier().appendByte(QStringLiteral("b3.txt"));
+ fakeFolder.localModifier().setContents(QStringLiteral("a2.eml"), 64, 'B');
+ fakeFolder.localModifier().appendByte(QStringLiteral("a3.eml"), 'X');
+ fakeFolder.localModifier().appendByte(QStringLiteral("b3.txt"), 'X');
fakeFolder.syncOnce();
QCOMPARE(getDbChecksum("a1.eml"), referenceChecksum);
QCOMPARE(getDbChecksum("a2.eml"), QByteArray("SHA1:84951fc23a4dafd10020ac349da1f5530fa65949"));
- QCOMPARE(getDbChecksum("a3.eml"), QByteArray("SHA1:826b7e7a7af8a529ae1c7443c23bf185c0ad440c"));
+ QCOMPARE(getDbChecksum("a3.eml"), QByteArray("SHA1:c119308d57884896cd86a7050e449aaba24b1fee"));
QCOMPARE(getDbChecksum("b3.eml"), getDbChecksum("a3.txt"));
QVERIFY(!itemDidComplete(completeSpy, "a1.eml"));
@@ -356,11 +356,13 @@ private slots:
auto mtime = QDateTime::currentDateTimeUtc().addDays(-4);
mtime.setMSecsSinceEpoch(mtime.toMSecsSinceEpoch() / 1000 * 1000);
- fakeFolder.localModifier().setContents(QStringLiteral("A/a1"), 'C');
+ const auto a1size = fakeFolder.currentLocalState().find("A/a1")->contentSize;
+ fakeFolder.localModifier().setContents(QStringLiteral("A/a1"), a1size, 'C');
fakeFolder.localModifier().setModTime(QStringLiteral("A/a1"), mtime);
- fakeFolder.remoteModifier().setContents(QStringLiteral("A/a1"), 'C');
- if (!sameMtime)
+ fakeFolder.remoteModifier().setContents(QStringLiteral("A/a1"), a1size, 'C');
+ if (!sameMtime) {
mtime = mtime.addDays(1);
+ }
fakeFolder.remoteModifier().setModTime(QStringLiteral("A/a1"), mtime);
remoteInfo.find("A/a1")->checksums = checksums;
QVERIFY(fakeFolder.syncOnce());
@@ -398,8 +400,7 @@ private slots:
initialFileInfo.setModTime(QStringLiteral("B/b1"), initialMtime);
initialFileInfo.setModTime(QStringLiteral("C/c1"), initialMtime);
- FakeFolder fakeFolder{ initialFileInfo };
-
+ FakeFolder fakeFolder(initialFileInfo);
// upload a
fakeFolder.localModifier().appendByte(QStringLiteral("A/a1"));
diff --git a/test/testsyncmove.cpp b/test/testsyncmove.cpp
index c0c238b07..400b0456a 100644
--- a/test/testsyncmove.cpp
+++ b/test/testsyncmove.cpp
@@ -224,8 +224,9 @@ private slots:
// Move-and-change, content only -- c1 has no checksum, so we fail to detect this!
// NOTE: This is an expected failure.
mtime = fakeFolder.remoteModifier().find("C/c1")->lastModified();
+ auto size = fakeFolder.currentRemoteState().find("C/c1")->contentSize;
fakeFolder.localModifier().rename(QStringLiteral("C/c1"), QStringLiteral("C/c1m"));
- fakeFolder.localModifier().setContents(QStringLiteral("C/c1m"), 'C');
+ fakeFolder.localModifier().setContents(QStringLiteral("C/c1m"), size, 'C');
fakeFolder.localModifier().setModTime(QStringLiteral("C/c1m"), mtime);
QVERIFY(fakeFolder.syncOnce());
QCOMPARE(nPUT, 3);
@@ -244,7 +245,7 @@ private slots:
// Move-and-change, content only, this time while having a checksum
mtime = fakeFolder.remoteModifier().find("C/c3")->lastModified();
fakeFolder.localModifier().rename(QStringLiteral("C/c3"), QStringLiteral("C/c3m"));
- fakeFolder.localModifier().setContents(QStringLiteral("C/c3m"), 'C');
+ fakeFolder.localModifier().setContents(QStringLiteral("C/c3m"), FileModifier::DefaultFileSize, 'C');
fakeFolder.localModifier().setModTime(QStringLiteral("C/c3m"), mtime);
QVERIFY(fakeFolder.syncOnce());
QCOMPARE(nPUT, 5);
@@ -363,9 +364,9 @@ private slots:
// Touch+Move on same side
counter.reset();
local.rename(QStringLiteral("A/a2"), QStringLiteral("A/a2m"));
- local.setContents(QStringLiteral("A/a2m"), 'A');
+ local.setContents(QStringLiteral("A/a2m"), FileModifier::DefaultFileSize, 'A');
remote.rename(QStringLiteral("B/b2"), QStringLiteral("B/b2m"));
- remote.setContents(QStringLiteral("B/b2m"), 'A');
+ remote.setContents(QStringLiteral("B/b2m"), FileModifier::DefaultFileSize, 'A');
QVERIFY(fakeFolder.syncOnce());
QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
QCOMPARE(printDbData(fakeFolder.dbState()), printDbData(fakeFolder.currentRemoteState()));
@@ -379,9 +380,9 @@ private slots:
// Touch+Move on opposite sides
counter.reset();
local.rename(QStringLiteral("A/a1m"), QStringLiteral("A/a1m2"));
- remote.setContents(QStringLiteral("A/a1m"), 'B');
+ remote.setContents(QStringLiteral("A/a1m"), FileModifier::DefaultFileSize, 'B');
remote.rename(QStringLiteral("B/b1m"), QStringLiteral("B/b1m2"));
- local.setContents(QStringLiteral("B/b1m"), 'B');
+ local.setContents(QStringLiteral("B/b1m"), FileModifier::DefaultFileSize, 'B');
QVERIFY(fakeFolder.syncOnce());
QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
QCOMPARE(printDbData(fakeFolder.dbState()), printDbData(fakeFolder.currentRemoteState()));
@@ -496,14 +497,14 @@ private slots:
// Folder move with contents touched on the same side
{
counter.reset();
- local.setContents(QStringLiteral("AM/a2m"), 'C');
+ local.setContents(QStringLiteral("AM/a2m"), FileModifier::DefaultFileSize, 'C');
// We must change the modtime for it is likely that it did not change between sync.
// (Previous version of the client (<=2.5) would not need this because it was always doing
// checksum comparison for all renames. But newer version no longer does it if the file is
// renamed because the parent folder is renamed)
local.setModTime(QStringLiteral("AM/a2m"), QDateTime::currentDateTimeUtc().addDays(3));
local.rename(QStringLiteral("AM"), QStringLiteral("A2"));
- remote.setContents(QStringLiteral("BM/b2m"), 'C');
+ remote.setContents(QStringLiteral("BM/b2m"), FileModifier::DefaultFileSize, 'C');
remote.rename(QStringLiteral("BM"), QStringLiteral("B2"));
ItemCompletedSpy completeSpy(fakeFolder);
QVERIFY(fakeFolder.syncOnce());
@@ -521,12 +522,12 @@ private slots:
// Folder rename with contents touched on the other tree
counter.reset();
- remote.setContents(QStringLiteral("A2/a2m"), 'D');
+ remote.setContents(QStringLiteral("A2/a2m"), FileModifier::DefaultFileSize, 'D');
// setContents alone may not produce updated mtime if the test is fast
// and since we don't use checksums here, that matters.
remote.appendByte(QStringLiteral("A2/a2m"));
local.rename(QStringLiteral("A2"), QStringLiteral("A3"));
- local.setContents(QStringLiteral("B2/b2m"), 'D');
+ local.setContents(QStringLiteral("B2/b2m"), FileModifier::DefaultFileSize, 'D');
local.appendByte(QStringLiteral("B2/b2m"));
remote.rename(QStringLiteral("B2"), QStringLiteral("B3"));
QVERIFY(fakeFolder.syncOnce());
@@ -541,15 +542,15 @@ private slots:
// Folder rename with contents touched on both ends
counter.reset();
- remote.setContents(QStringLiteral("A3/a2m"), 'R');
+ remote.setContents(QStringLiteral("A3/a2m"), FileModifier::DefaultFileSize, 'R');
remote.appendByte(QStringLiteral("A3/a2m"));
- local.setContents(QStringLiteral("A3/a2m"), 'L');
+ local.setContents(QStringLiteral("A3/a2m"), FileModifier::DefaultFileSize, 'L');
local.appendByte(QStringLiteral("A3/a2m"));
local.appendByte(QStringLiteral("A3/a2m"));
local.rename(QStringLiteral("A3"), QStringLiteral("A4"));
- remote.setContents(QStringLiteral("B3/b2m"), 'R');
+ remote.setContents(QStringLiteral("B3/b2m"), FileModifier::DefaultFileSize, 'R');
remote.appendByte(QStringLiteral("B3/b2m"));
- local.setContents(QStringLiteral("B3/b2m"), 'L');
+ local.setContents(QStringLiteral("B3/b2m"), FileModifier::DefaultFileSize, 'L');
local.appendByte(QStringLiteral("B3/b2m"));
local.appendByte(QStringLiteral("B3/b2m"));
remote.rename(QStringLiteral("B3"), QStringLiteral("B4"));
diff --git a/test/testutils/syncenginetestutils.cpp b/test/testutils/syncenginetestutils.cpp
index 0b67f671b..6f853d514 100644
--- a/test/testutils/syncenginetestutils.cpp
+++ b/test/testutils/syncenginetestutils.cpp
@@ -48,7 +48,7 @@ void DiskFileModifier::remove(const QString &relativePath)
QVERIFY(QDir { fi.filePath() }.removeRecursively());
}
-void DiskFileModifier::insert(const QString &relativePath, qint64 size, char contentChar)
+void DiskFileModifier::insert(const QString &relativePath, quint64 size, char contentChar)
{
QFile file { _rootDir.filePath(relativePath) };
QVERIFY(!file.exists());
@@ -64,13 +64,12 @@ void DiskFileModifier::insert(const QString &relativePath, qint64 size, char con
QCOMPARE(file.size(), size);
}
-void DiskFileModifier::setContents(const QString &relativePath, char contentChar)
+void DiskFileModifier::setContents(const QString &relativePath, quint64 newSize, char contentChar)
{
QFile file { _rootDir.filePath(relativePath) };
QVERIFY(file.exists());
- qint64 size = file.size();
file.open(QFile::WriteOnly);
- file.write(QByteArray {}.fill(contentChar, size));
+ file.write(QByteArray {}.fill(contentChar, newSize));
}
void DiskFileModifier::appendByte(const QString &relativePath, char contentChar)
@@ -87,16 +86,6 @@ void DiskFileModifier::appendByte(const QString &relativePath, char contentChar)
file.write(contents);
}
-void DiskFileModifier::modifyByte(const QString &relativePath, quint64 offset, char contentChar)
-{
- QFile file { _rootDir.filePath(relativePath) };
- QVERIFY(file.exists());
- file.open(QFile::ReadWrite);
- file.seek(offset);
- file.write(&contentChar, 1);
- file.close();
-}
-
void DiskFileModifier::mkdir(const QString &relativePath)
{
_rootDir.mkpath(relativePath);
@@ -152,21 +141,25 @@ void FileInfo::remove(const QString &relativePath)
[&pathComponents](const FileInfo &fi) { return fi.name == pathComponents.fileName(); }));
}
-void FileInfo::insert(const QString &relativePath, qint64 size, char contentChar)
+void FileInfo::insert(const QString &relativePath, quint64 size, char contentChar)
{
create(relativePath, size, contentChar);
}
-void FileInfo::setContents(const QString &relativePath, char contentChar)
+void FileInfo::setContents(const QString &relativePath, quint64 newSize, char contentChar)
{
FileInfo *file = findInvalidatingEtags(relativePath);
Q_ASSERT(file);
file->contentChar = contentChar;
+ file->contentSize = newSize;
+ if (!file->isDehydratedPlaceholder) {
+ file->fileSize = newSize;
+ }
}
void FileInfo::appendByte(const QString &relativePath, char contentChar)
{
- Q_UNUSED(contentChar);
+ Q_UNUSED(contentChar)
FileInfo *file = findInvalidatingEtags(relativePath);
Q_ASSERT(file);
if (!file->isDehydratedPlaceholder) {
@@ -175,15 +168,6 @@ void FileInfo::appendByte(const QString &relativePath, char contentChar)
file->fileSize += 1;
}
-void FileInfo::modifyByte(const QString &relativePath, quint64 offset, char contentChar)
-{
- Q_UNUSED(offset);
- Q_UNUSED(contentChar);
- FileInfo *file = findInvalidatingEtags(relativePath);
- Q_ASSERT(file);
- Q_ASSERT(!"unimplemented");
-}
-
void FileInfo::mkdir(const QString &relativePath)
{
createDir(relativePath);
@@ -244,7 +228,7 @@ FileInfo *FileInfo::createDir(const QString &relativePath)
return &child;
}
-FileInfo *FileInfo::create(const QString &relativePath, qint64 size, char contentChar)
+FileInfo *FileInfo::create(const QString &relativePath, quint64 size, char contentChar)
{
const PathComponents pathComponents { relativePath };
FileInfo *parent = findInvalidatingEtags(pathComponents.parentDirComponents());
@@ -1106,9 +1090,10 @@ void FakeFolder::fromDisk(QDir &dir, FileInfo &templateFi)
fi.setLastModified(diskChild.lastModified());
if (fi.isDehydratedPlaceholder) {
fi.contentChar = '\0';
+ fi.contentSize = 0;
} else {
QFile f { diskChild.filePath() };
- f.open(QFile::ReadOnly);
+ OC_ENFORCE(f.open(QFile::ReadOnly));
auto content = f.read(1);
if (content.size() == 0) {
qWarning() << "Empty file at:" << diskChild.filePath();
diff --git a/test/testutils/syncenginetestutils.h b/test/testutils/syncenginetestutils.h
index e06f09bda..a8e445d60 100644
--- a/test/testutils/syncenginetestutils.h
+++ b/test/testutils/syncenginetestutils.h
@@ -78,15 +78,21 @@ public:
QString fileName() const { return last(); }
};
+/**
+ * @brief The FileModifier class defines the interface for both the local on-disk modifier and the
+ * remote in-memory modifier.
+ */
class FileModifier
{
public:
+ static constexpr int DefaultFileSize = 64;
+ static constexpr char DefaultContentChar = 'X';
+
virtual ~FileModifier() { }
virtual void remove(const QString &relativePath) = 0;
- virtual void insert(const QString &relativePath, qint64 size = 64, char contentChar = 'W') = 0;
- virtual void setContents(const QString &relativePath, char contentChar) = 0;
- virtual void appendByte(const QString &relativePath, char contentChar = 0) = 0;
- virtual void modifyByte(const QString &relativePath, quint64 offset, char contentChar) = 0;
+ virtual void insert(const QString &relativePath, quint64 size = DefaultFileSize, char contentChar = DefaultContentChar) = 0;
+ virtual void setContents(const QString &relativePath, quint64 newSize, char contentChar = DefaultContentChar) = 0;
+ virtual void appendByte(const QString &relativePath, char contentChar = DefaultContentChar) = 0;
virtual void mkdir(const QString &relativePath) = 0;
virtual void rename(const QString &relativePath, const QString &relativeDestinationDirectory) = 0;
virtual void setModTime(const QString &relativePath, const QDateTime &modTime) = 0;
@@ -102,10 +108,9 @@ public:
{
}
void remove(const QString &relativePath) override;
- void insert(const QString &relativePath, qint64 size = 64, char contentChar = 'W') override;
- void setContents(const QString &relativePath, char contentChar) override;
- void appendByte(const QString &relativePath, char contentChar) override;
- void modifyByte(const QString &relativePath, quint64 offset, char contentChar) override;
+ void insert(const QString &relativePath, quint64 size = DefaultFileSize, char contentChar = DefaultContentChar) override;
+ void setContents(const QString &relativePath, quint64 newSize, char contentChar = DefaultContentChar) override;
+ void appendByte(const QString &relativePath, char contentChar = DefaultContentChar) override;
void mkdir(const QString &relativePath) override;
void rename(const QString &from, const QString &to) override;
@@ -119,9 +124,17 @@ static inline qint64 defaultLastModified()
return timeInSeconds;
}
-/// FIXME: we should make it explicit in the construtor if we're talking about a hydrated or a dehydrated file!
+/**
+ * @brief The FileInfo class represents the remotely stored (on-server) content. To be able to
+ * modify the content, this class is also the remote \c FileModifier.
+ */
class FileInfo : public FileModifier
{
+ /// FIXME: we should make it explicit in the construtor if we're talking about a hydrated or a dehydrated file!
+ /// FIXME: this class is both a remote folder, as the root folder which in turn is the remote FileModifier.
+ /// This is a mess: unifying remote files/folders is ok, but because it's also the remote root (which
+ /// should implement the FileModifier), this means that each single remote file/folder also implements
+ /// this interface.
public:
static FileInfo A12_B12_C12_S12();
@@ -130,14 +143,14 @@ public:
: name { name }
{
}
- FileInfo(const QString &name, qint64 size)
+ FileInfo(const QString &name, quint64 size)
: name { name }
, isDir { false }
, fileSize(size)
, contentSize { size }
{
}
- FileInfo(const QString &name, qint64 size, char contentChar)
+ FileInfo(const QString &name, quint64 size, char contentChar)
: name { name }
, isDir { false }
, fileSize(size)
@@ -151,13 +164,11 @@ public:
void remove(const QString &relativePath) override;
- void insert(const QString &relativePath, qint64 size = 64, char contentChar = 'W') override;
+ void insert(const QString &relativePath, quint64 size = DefaultFileSize, char contentChar = DefaultContentChar) override;
- void setContents(const QString &relativePath, char contentChar) override;
+ void setContents(const QString &relativePath, quint64 newSize, char contentChar = DefaultContentChar) override;
- void appendByte(const QString &relativePath, char contentChar = 0) override;
-
- void modifyByte(const QString &relativePath, quint64 offset, char contentChar) override;
+ void appendByte(const QString &relativePath, char contentChar = DefaultContentChar) override;
void mkdir(const QString &relativePath) override;
@@ -170,7 +181,7 @@ public:
FileInfo *createDir(const QString &relativePath);
- FileInfo *create(const QString &relativePath, qint64 size, char contentChar);
+ FileInfo *create(const QString &relativePath, quint64 size, char contentChar);
bool operator<(const FileInfo &other) const
{
@@ -230,8 +241,8 @@ public:
QByteArray fileId = generateFileId();
QByteArray checksums;
QByteArray extraDavProperties;
- qint64 fileSize = 0;
- qint64 contentSize = 0;
+ quint64 fileSize = 0;
+ quint64 contentSize = 0;
char contentChar = 'W';
bool isDehydratedPlaceholder = false;
@@ -259,9 +270,10 @@ public:
class FakeReply : public QNetworkReply
{
Q_OBJECT
+
public:
FakeReply(QObject *parent);
- virtual ~FakeReply();
+ virtual ~FakeReply() override;
// useful to be public for testing
using QNetworkReply::setRawHeader;
@@ -270,6 +282,7 @@ public:
class FakePropfindReply : public FakeReply
{
Q_OBJECT
+
public:
QByteArray payload;
@@ -288,7 +301,6 @@ public:
class FakePutReply : public FakeReply
{
Q_OBJECT
- FileInfo *fileInfo;
public:
FakePutReply(FileInfo &remoteRootFileInfo, QNetworkAccessManager::Operation op, const QNetworkRequest &request, const QByteArray &putPayload, QObject *parent);
@@ -299,12 +311,14 @@ public:
void abort() override;
qint64 readData(char *, qint64) override { return 0; }
+
+private:
+ FileInfo *fileInfo;
};
class FakeMkcolReply : public FakeReply
{
Q_OBJECT
- FileInfo *fileInfo;
public:
FakeMkcolReply(FileInfo &remoteRootFileInfo, QNetworkAccessManager::Operation op, const QNetworkRequest &request, QObject *parent);
@@ -313,11 +327,15 @@ public:
void abort() override { }
qint64 readData(char *, qint64) override { return 0; }
+
+private:
+ FileInfo *fileInfo;
};
class FakeDeleteReply : public FakeReply
{
Q_OBJECT
+
public:
FakeDeleteReply(FileInfo &remoteRootFileInfo, QNetworkAccessManager::Operation op, const QNetworkRequest &request, QObject *parent);
@@ -330,6 +348,7 @@ public:
class FakeMoveReply : public FakeReply
{
Q_OBJECT
+
public:
FakeMoveReply(FileInfo &remoteRootFileInfo, QNetworkAccessManager::Operation op, const QNetworkRequest &request, QObject *parent);
@@ -342,6 +361,7 @@ public:
class FakeGetReply : public FakeReply
{
Q_OBJECT
+
public:
enum class State {
Ok,
@@ -551,7 +571,7 @@ public:
FileInfo &remoteModifier() { return _fakeAm->currentRemoteState(); }
FileInfo currentLocalState();
- FileInfo currentRemoteState() { return _fakeAm->currentRemoteState(); }
+ FileInfo &currentRemoteState() { return _fakeAm->currentRemoteState(); }
FileInfo &uploadState() { return _fakeAm->uploadState(); }
FileInfo dbState() const;