diff options
author | Christian Kamm <mail@ckamm.de> | 2017-10-27 11:29:31 +0300 |
---|---|---|
committer | Christian Kamm <mail@ckamm.de> | 2017-10-27 11:29:31 +0300 |
commit | 05c1bfb6cf5a890572de41a59da5e719d7c0432c (patch) | |
tree | 52407f7a203fd90239ae029305b255daf063c1a9 /test/testsyncengine.cpp | |
parent | 17126de5c703e935d2de9285a880211f0a120e35 (diff) | |
parent | 2d2ec2a57639c47f05d2534c5043b130a50fb673 (diff) |
Merge remote-tracking branch 'origin/2.4'
Diffstat (limited to 'test/testsyncengine.cpp')
-rw-r--r-- | test/testsyncengine.cpp | 220 |
1 files changed, 67 insertions, 153 deletions
diff --git a/test/testsyncengine.cpp b/test/testsyncengine.cpp index 139fbf42b..e68fed8bb 100644 --- a/test/testsyncengine.cpp +++ b/test/testsyncengine.cpp @@ -16,7 +16,7 @@ bool itemDidComplete(const QSignalSpy &spy, const QString &path) for(const QList<QVariant> &args : spy) { auto item = args[0].value<SyncFileItemPtr>(); if (item->destination() == path) - return true; + return item->_instruction != CSYNC_INSTRUCTION_NONE && item->_instruction != CSYNC_INSTRUCTION_UPDATE_METADATA; } return false; } @@ -141,98 +141,6 @@ private slots: QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState()); } - void testRemoteChangeInMovedFolder() { - // issue #5192 - FakeFolder fakeFolder{FileInfo{ QString(), { - FileInfo { QStringLiteral("folder"), { - FileInfo{ QStringLiteral("folderA"), { { QStringLiteral("file.txt"), 400 } } }, - QStringLiteral("folderB") - } - }}}}; - - QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState()); - - // Edit a file in a moved directory. - fakeFolder.remoteModifier().setContents("folder/folderA/file.txt", 'a'); - fakeFolder.remoteModifier().rename("folder/folderA", "folder/folderB/folderA"); - fakeFolder.syncOnce(); - QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState()); - auto oldState = fakeFolder.currentLocalState(); - QVERIFY(oldState.find("folder/folderB/folderA/file.txt")); - QVERIFY(!oldState.find("folder/folderA/file.txt")); - - // This sync should not remove the file - fakeFolder.syncOnce(); - QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState()); - QCOMPARE(fakeFolder.currentLocalState(), oldState); - - } - - void testSelectiveSyncModevFolder() { - // issue #5224 - FakeFolder fakeFolder{FileInfo{ QString(), { - FileInfo { QStringLiteral("parentFolder"), { - FileInfo{ QStringLiteral("subFolderA"), { { QStringLiteral("fileA.txt"), 400 } } }, - FileInfo{ QStringLiteral("subFolderB"), { { QStringLiteral("fileB.txt"), 400 } } } - } - }}}}; - - QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState()); - auto expectedServerState = fakeFolder.currentRemoteState(); - - // Remove subFolderA with selectiveSync: - fakeFolder.syncEngine().journal()->setSelectiveSyncList(SyncJournalDb::SelectiveSyncBlackList, - {"parentFolder/subFolderA/"}); - fakeFolder.syncEngine().journal()->avoidReadFromDbOnNextSync(QByteArrayLiteral("parentFolder/subFolderA/")); - - fakeFolder.syncOnce(); - - { - // Nothing changed on the server - QCOMPARE(fakeFolder.currentRemoteState(), expectedServerState); - // The local state should not have subFolderA - auto remoteState = fakeFolder.currentRemoteState(); - remoteState.remove("parentFolder/subFolderA"); - QCOMPARE(fakeFolder.currentLocalState(), remoteState); - } - - // Rename parentFolder on the server - fakeFolder.remoteModifier().rename("parentFolder", "parentFolderRenamed"); - expectedServerState = fakeFolder.currentRemoteState(); - fakeFolder.syncOnce(); - - { - QCOMPARE(fakeFolder.currentRemoteState(), expectedServerState); - auto remoteState = fakeFolder.currentRemoteState(); - // The subFolderA should still be there on the server. - QVERIFY(remoteState.find("parentFolderRenamed/subFolderA/fileA.txt")); - // But not on the client because of the selective sync - remoteState.remove("parentFolderRenamed/subFolderA"); - QCOMPARE(fakeFolder.currentLocalState(), remoteState); - } - - // Rename it again, locally this time. - fakeFolder.localModifier().rename("parentFolderRenamed", "parentThirdName"); - fakeFolder.syncOnce(); - - { - auto remoteState = fakeFolder.currentRemoteState(); - // The subFolderA should still be there on the server. - QVERIFY(remoteState.find("parentThirdName/subFolderA/fileA.txt")); - // But not on the client because of the selective sync - remoteState.remove("parentThirdName/subFolderA"); - QCOMPARE(fakeFolder.currentLocalState(), remoteState); - - expectedServerState = fakeFolder.currentRemoteState(); - QSignalSpy completeSpy(&fakeFolder.syncEngine(), SIGNAL(itemCompleted(const SyncFileItemPtr &))); - fakeFolder.syncOnce(); // This sync should do nothing - QCOMPARE(completeSpy.count(), 0); - - QCOMPARE(fakeFolder.currentRemoteState(), expectedServerState); - QCOMPARE(fakeFolder.currentLocalState(), remoteState); - } - } - void testSelectiveSyncBug() { // issue owncloud/enterprise#1965: files from selective-sync ignored // folders are uploaded anyway is some circumstances. @@ -536,82 +444,88 @@ private slots: QCOMPARE(n507, 3); } - void testLocalMove() + // Checks whether downloads with bad checksums are accepted + void testChecksumValidation() { FakeFolder fakeFolder{ FileInfo::A12_B12_C12_S12() }; + QObject parent; - int nPUT = 0; - int nDELETE = 0; - fakeFolder.setServerOverride([&](QNetworkAccessManager::Operation op, const QNetworkRequest &) { - if (op == QNetworkAccessManager::PutOperation) - ++nPUT; - if (op == QNetworkAccessManager::DeleteOperation) - ++nDELETE; + QByteArray checksumValue; + QByteArray contentMd5Value; + + fakeFolder.setServerOverride([&](QNetworkAccessManager::Operation op, const QNetworkRequest &request) -> QNetworkReply * { + if (op == QNetworkAccessManager::GetOperation) { + auto reply = new FakeGetReply(fakeFolder.remoteModifier(), op, request, &parent); + if (!checksumValue.isNull()) + reply->setRawHeader("OC-Checksum", checksumValue); + if (!contentMd5Value.isNull()) + reply->setRawHeader("Content-MD5", contentMd5Value); + return reply; + } return nullptr; }); - // For directly editing the remote checksum - FileInfo &remoteInfo = fakeFolder.remoteModifier(); - - // Simple move causing a remote rename - fakeFolder.localModifier().rename("A/a1", "A/a1m"); + // Basic case + fakeFolder.remoteModifier().create("A/a3", 16, 'A'); QVERIFY(fakeFolder.syncOnce()); - QCOMPARE(fakeFolder.currentLocalState(), remoteInfo); - QCOMPARE(nPUT, 0); + QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState()); + + // Bad OC-Checksum + checksumValue = "SHA1:bad"; + fakeFolder.remoteModifier().create("A/a4", 16, 'A'); + QVERIFY(!fakeFolder.syncOnce()); - // Move-and-change, causing a upload and delete - fakeFolder.localModifier().rename("A/a2", "A/a2m"); - fakeFolder.localModifier().appendByte("A/a2m"); + // Good OC-Checksum + checksumValue = "SHA1:19b1928d58a2030d08023f3d7054516dbc186f20"; // printf 'A%.0s' {1..16} | sha1sum - QVERIFY(fakeFolder.syncOnce()); - QCOMPARE(fakeFolder.currentLocalState(), remoteInfo); - QCOMPARE(nPUT, 1); - QCOMPARE(nDELETE, 1); + QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState()); + checksumValue = QByteArray(); + + // Bad Content-MD5 + contentMd5Value = "bad"; + fakeFolder.remoteModifier().create("A/a5", 16, 'A'); + QVERIFY(!fakeFolder.syncOnce()); - // Move-and-change, mtime+content only - fakeFolder.localModifier().rename("B/b1", "B/b1m"); - fakeFolder.localModifier().setContents("B/b1m", 'C'); + // Good Content-MD5 + contentMd5Value = "d8a73157ce10cd94a91c2079fc9a92c8"; // printf 'A%.0s' {1..16} | md5sum - QVERIFY(fakeFolder.syncOnce()); - QCOMPARE(fakeFolder.currentLocalState(), remoteInfo); - QCOMPARE(nPUT, 2); - QCOMPARE(nDELETE, 2); - - // Move-and-change, size+content only - auto mtime = fakeFolder.remoteModifier().find("B/b2")->lastModified; - fakeFolder.localModifier().rename("B/b2", "B/b2m"); - fakeFolder.localModifier().appendByte("B/b2m"); - fakeFolder.localModifier().setModTime("B/b2m", mtime); + QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState()); + + // OC-Checksum has preference + checksumValue = "garbage"; + // contentMd5Value is still good + fakeFolder.remoteModifier().create("A/a6", 16, 'A'); + QVERIFY(!fakeFolder.syncOnce()); + } + + // Tests the behavior of invalid filename detection + void testInvalidFilenameRegex() + { + FakeFolder fakeFolder{ FileInfo::A12_B12_C12_S12() }; + + // For current servers, no characters are forbidden + fakeFolder.syncEngine().account()->setServerVersion("10.0.0"); + fakeFolder.localModifier().insert("A/\\:?*\"<>|.txt"); QVERIFY(fakeFolder.syncOnce()); - QCOMPARE(fakeFolder.currentLocalState(), remoteInfo); - QCOMPARE(nPUT, 3); - QCOMPARE(nDELETE, 3); - - // Move-and-change, content only -- c1 has no checksum, so we fail to detect this! - mtime = fakeFolder.remoteModifier().find("C/c1")->lastModified; - fakeFolder.localModifier().rename("C/c1", "C/c1m"); - fakeFolder.localModifier().setContents("C/c1m", 'C'); - fakeFolder.localModifier().setModTime("C/c1m", mtime); + QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState()); + + // For legacy servers, some characters were forbidden by the client + fakeFolder.syncEngine().account()->setServerVersion("8.0.0"); + fakeFolder.localModifier().insert("B/\\:?*\"<>|.txt"); QVERIFY(fakeFolder.syncOnce()); - QCOMPARE(nPUT, 3); - QCOMPARE(nDELETE, 3); - QVERIFY(!(fakeFolder.currentLocalState() == remoteInfo)); + QVERIFY(!fakeFolder.currentRemoteState().find("B/\\:?*\"<>|.txt")); - // cleanup, and upload a file that will have a checksum in the db - fakeFolder.localModifier().remove("C/c1m"); - fakeFolder.localModifier().insert("C/c3"); + // We can override that by setting the capability + fakeFolder.syncEngine().account()->setCapabilities({ { "dav", QVariantMap{ { "invalidFilenameRegex", "" } } } }); QVERIFY(fakeFolder.syncOnce()); - QCOMPARE(fakeFolder.currentLocalState(), remoteInfo); - QCOMPARE(nPUT, 4); - QCOMPARE(nDELETE, 4); - - // Move-and-change, content only, this time while having a checksum - mtime = fakeFolder.remoteModifier().find("C/c3")->lastModified; - fakeFolder.localModifier().rename("C/c3", "C/c3m"); - fakeFolder.localModifier().setContents("C/c3m", 'C'); - fakeFolder.localModifier().setModTime("C/c3m", mtime); + QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState()); + + // Check that new servers also accept the capability + fakeFolder.syncEngine().account()->setServerVersion("10.0.0"); + fakeFolder.syncEngine().account()->setCapabilities({ { "dav", QVariantMap{ { "invalidFilenameRegex", "my[fgh]ile" } } } }); + fakeFolder.localModifier().insert("C/myfile.txt"); QVERIFY(fakeFolder.syncOnce()); - QCOMPARE(nPUT, 5); - QCOMPARE(nDELETE, 5); - QCOMPARE(fakeFolder.currentLocalState(), remoteInfo); + QVERIFY(!fakeFolder.currentRemoteState().find("C/myfile.txt")); } // Check correct behavior when local discovery is partially drawn from the db |