diff options
author | Christian Kamm <mail@ckamm.de> | 2018-03-28 12:04:58 +0300 |
---|---|---|
committer | Roeland Jago Douma <roeland@famdouma.nl> | 2018-06-11 15:50:01 +0300 |
commit | 16ba0cf47ea95a38a25a8d3419ad43c6eba2d821 (patch) | |
tree | 33b23f37da145a6199cbb7c1e511491fe3937c8d /test | |
parent | d304fcbda7e9fc96684d4036c12ba3749a9e76f4 (diff) |
Blacklist: Add unittest #6411
Diffstat (limited to 'test')
-rw-r--r-- | test/CMakeLists.txt | 1 | ||||
-rw-r--r-- | test/testblacklist.cpp | 187 |
2 files changed, 188 insertions, 0 deletions
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 5f36690a7..bb184412b 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -48,6 +48,7 @@ owncloud_add_test(SyncFileStatusTracker "syncenginetestutils.h") owncloud_add_test(ChunkingNg "syncenginetestutils.h") owncloud_add_test(UploadReset "syncenginetestutils.h") owncloud_add_test(AllFilesDeleted "syncenginetestutils.h") +owncloud_add_test(Blacklist "syncenginetestutils.h") owncloud_add_test(FolderWatcher "${FolderWatcher_SRC}") if( UNIX AND NOT APPLE ) diff --git a/test/testblacklist.cpp b/test/testblacklist.cpp new file mode 100644 index 000000000..f571affa4 --- /dev/null +++ b/test/testblacklist.cpp @@ -0,0 +1,187 @@ +/* + * This software is in the public domain, furnished "as is", without technical + * support, and with no warranty, express or implied, as to its usefulness for + * any purpose. + * + */ + +#include <QtTest> +#include "syncenginetestutils.h" +#include <syncengine.h> + +using namespace OCC; + +SyncFileItemPtr findItem(const QSignalSpy &spy, const QString &path) +{ + for (const QList<QVariant> &args : spy) { + auto item = args[0].value<SyncFileItemPtr>(); + if (item->destination() == path) + return item; + } + return SyncFileItemPtr(new SyncFileItem); +} + +SyncJournalFileRecord journalRecord(FakeFolder &folder, const QByteArray &path) +{ + SyncJournalFileRecord rec; + folder.syncJournal().getFileRecord(path, &rec); + return rec; +} + +class TestBlacklist : public QObject +{ + Q_OBJECT + +private slots: + void testBlacklistBasic_data() + { + QTest::addColumn<bool>("remote"); + QTest::newRow("remote") << true; + QTest::newRow("local") << false; + } + + void testBlacklistBasic() + { + QFETCH(bool, remote); + + FakeFolder fakeFolder{ FileInfo::A12_B12_C12_S12() }; + QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState()); + QSignalSpy completeSpy(&fakeFolder.syncEngine(), SIGNAL(itemCompleted(const SyncFileItemPtr &))); + + auto &modifier = remote ? fakeFolder.remoteModifier() : fakeFolder.localModifier(); + + int counter = 0; + fakeFolder.setServerOverride([&](QNetworkAccessManager::Operation op, const QNetworkRequest &, QIODevice *) -> QNetworkReply * { + if (!remote && op == QNetworkAccessManager::PutOperation) + ++counter; + if (remote && op == QNetworkAccessManager::GetOperation) + ++counter; + return nullptr; + }); + + auto cleanup = [&]() { + completeSpy.clear(); + }; + + auto initialEtag = journalRecord(fakeFolder, "A")._etag; + QVERIFY(!initialEtag.isEmpty()); + + // The first sync and the download will fail - the item will be blacklisted + modifier.insert("A/new"); + fakeFolder.serverErrorPaths().append("A/new", 500); // will be blacklisted + QVERIFY(!fakeFolder.syncOnce()); + { + auto it = findItem(completeSpy, "A/new"); + QVERIFY(it); + QCOMPARE(it->_status, SyncFileItem::NormalError); // initial error visible + QCOMPARE(it->_instruction, CSYNC_INSTRUCTION_NEW); + + auto entry = fakeFolder.syncJournal().errorBlacklistEntry("A/new"); + QVERIFY(entry.isValid()); + QCOMPARE(entry._errorCategory, SyncJournalErrorBlacklistRecord::Normal); + QCOMPARE(entry._retryCount, 1); + QCOMPARE(counter, 1); + QVERIFY(entry._ignoreDuration > 0); + + if (remote) + QCOMPARE(journalRecord(fakeFolder, "A")._etag, initialEtag); + } + cleanup(); + + // Ignored during the second run - but soft errors are also errors + QVERIFY(!fakeFolder.syncOnce()); + { + auto it = findItem(completeSpy, "A/new"); + QVERIFY(it); + QCOMPARE(it->_status, SyncFileItem::BlacklistedError); + QCOMPARE(it->_instruction, CSYNC_INSTRUCTION_IGNORE); // no retry happened! + + auto entry = fakeFolder.syncJournal().errorBlacklistEntry("A/new"); + QVERIFY(entry.isValid()); + QCOMPARE(entry._errorCategory, SyncJournalErrorBlacklistRecord::Normal); + QCOMPARE(entry._retryCount, 1); + QCOMPARE(counter, 1); + QVERIFY(entry._ignoreDuration > 0); + + if (remote) + QCOMPARE(journalRecord(fakeFolder, "A")._etag, initialEtag); + } + cleanup(); + + // Let's expire the blacklist entry to verify it gets retried + { + auto entry = fakeFolder.syncJournal().errorBlacklistEntry("A/new"); + entry._ignoreDuration = 1; + entry._lastTryTime -= 1; + fakeFolder.syncJournal().setErrorBlacklistEntry(entry); + } + QVERIFY(!fakeFolder.syncOnce()); + { + auto it = findItem(completeSpy, "A/new"); + QVERIFY(it); + QCOMPARE(it->_status, SyncFileItem::BlacklistedError); // blacklisted as it's just a retry + QCOMPARE(it->_instruction, CSYNC_INSTRUCTION_NEW); // retry! + + auto entry = fakeFolder.syncJournal().errorBlacklistEntry("A/new"); + QVERIFY(entry.isValid()); + QCOMPARE(entry._errorCategory, SyncJournalErrorBlacklistRecord::Normal); + QCOMPARE(entry._retryCount, 2); + QCOMPARE(counter, 2); + QVERIFY(entry._ignoreDuration > 0); + + if (remote) + QCOMPARE(journalRecord(fakeFolder, "A")._etag, initialEtag); + } + cleanup(); + + // When the file changes a retry happens immediately + modifier.appendByte("A/new"); + QVERIFY(!fakeFolder.syncOnce()); + { + auto it = findItem(completeSpy, "A/new"); + QVERIFY(it); + QCOMPARE(it->_status, SyncFileItem::BlacklistedError); + QCOMPARE(it->_instruction, CSYNC_INSTRUCTION_NEW); // retry! + + auto entry = fakeFolder.syncJournal().errorBlacklistEntry("A/new"); + QVERIFY(entry.isValid()); + QCOMPARE(entry._errorCategory, SyncJournalErrorBlacklistRecord::Normal); + QCOMPARE(entry._retryCount, 3); + QCOMPARE(counter, 3); + QVERIFY(entry._ignoreDuration > 0); + + if (remote) + QCOMPARE(journalRecord(fakeFolder, "A")._etag, initialEtag); + } + cleanup(); + + // When the error goes away and the item is retried, the sync succeeds + fakeFolder.serverErrorPaths().clear(); + { + auto entry = fakeFolder.syncJournal().errorBlacklistEntry("A/new"); + entry._ignoreDuration = 1; + entry._lastTryTime -= 1; + fakeFolder.syncJournal().setErrorBlacklistEntry(entry); + } + QVERIFY(fakeFolder.syncOnce()); + { + auto it = findItem(completeSpy, "A/new"); + QVERIFY(it); + QCOMPARE(it->_status, SyncFileItem::Success); + QCOMPARE(it->_instruction, CSYNC_INSTRUCTION_NEW); + + auto entry = fakeFolder.syncJournal().errorBlacklistEntry("A/new"); + QVERIFY(!entry.isValid()); + QCOMPARE(counter, 4); + + if (remote) + QCOMPARE(journalRecord(fakeFolder, "A")._etag, fakeFolder.currentRemoteState().find("A")->etag.toUtf8()); + } + cleanup(); + + QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState()); + } +}; + +QTEST_GUILESS_MAIN(TestBlacklist) +#include "testblacklist.moc" |