diff --git a/CMakeLists.txt b/CMakeLists.txt index ad55708..505c510 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,7 +10,7 @@ set(META_APP_CATEGORIES "System;Utility;Network;FileTransfer") set(META_GUI_OPTIONAL false) set(META_VERSION_MAJOR 0) set(META_VERSION_MINOR 7) -set(META_VERSION_PATCH 1) +set(META_VERSION_PATCH 2) set(META_VERSION_EXACT_SONAME ON) project(${META_PROJECT_NAME}) diff --git a/connector/syncthingconnectionmockhelpers.cpp b/connector/syncthingconnectionmockhelpers.cpp index 468d1c7..5e941d1 100644 --- a/connector/syncthingconnectionmockhelpers.cpp +++ b/connector/syncthingconnectionmockhelpers.cpp @@ -18,6 +18,7 @@ using namespace std; using namespace IoUtilities; using namespace EscapeCodes; using namespace ConversionUtilities; +using namespace TestUtilities; namespace Data { @@ -34,43 +35,56 @@ static string errors; static string folderStatus; static string folderStatus2; static string connections; -static string events; +static string events[6]; } // namespace TestData /*! - * \brief Loads test files for mocked configuration from directory specified via environment variable TESTFILE_PATH. - * - * So TESTFILE_PATH must be set to "$synthingtray_checkout/connector/testfiles" which contains the required files. - * - * \remarks In the error case, the application will be terminated. + * \brief Returns the contents of the specified file and exits with an error message if an error occurs. + */ +string readMockFile(const string &filePath) +{ + try { + return readFile(filePath); + } catch (...) { + const char *const what = catchIoFailure(); + cerr << Phrases::Error << "An IO error occured when reading mock config file \"" << filePath << "\": " << what << Phrases::EndFlush; + exit(-2); + } +} + +/*! + * \brief Loads test files for mocked configuration using TestApplication::testFilePath(). + * \remarks + * - So TEST_FILE_PATH must be set to "$synthingtray_checkout/connector/testfiles" so this function can + * find the required files. + * - In the error case, the application will be terminated. */ void setupTestData() { + // skip if already initialized using namespace TestData; - if (initialized) { return; } - const char *testfilePath = getenv("TESTFILE_PATH"); - if (!testfilePath || !*testfilePath) { - cerr << Phrases::Error << "TESTFILE_PATH is not set; unable to initialize mock config." << Phrases::End << flush; - exit(-1); + // use a TestApplication to locate the test files + const TestApplication testApp(0, nullptr); + + // read mock files for REST-API + const char *const fileNames[] + = { "config", "status", "folderstats", "devicestats", "errors", "folderstatus-01", "folderstatus-02", "connections" }; + const char *const *fileName = fileNames; + for (string *testDataVariable : { &config, &status, &folderStats, &deviceStats, &errors, &folderStatus, &folderStatus2, &connections }) { + *testDataVariable = readMockFile(testApp.testFilePath(argsToString("mocks/", *fileName, ".json"))); + ++fileName; } - const char *const fileNames[] - = { "config", "status", "folderstats", "devicestats", "errors", "folderstatus", "folderstatus2", "connections", "events" }; - const char *const *fileName = fileNames; - for (string *testDataVariable : { &config, &status, &folderStats, &deviceStats, &errors, &folderStatus, &folderStatus2, &connections, &events }) { - const string filePath(argsToString(testfilePath, "/mocks/", *fileName, ".json")); - try { - *testDataVariable = readFile(filePath); - ++fileName; - } catch (...) { - const char *const what = catchIoFailure(); - cerr << "Error: An IO error occured when reading mock config file \"" << filePath << "\": " << what << endl; - exit(-2); - } + // read mock files for Event-API + unsigned int index = 1; + for (string &event : events) { + const char *const pad = index < 10 ? "0" : ""; + event = readMockFile(testApp.testFilePath(argsToString("mocks/events-", pad, index, ".json"))); + ++index; } initialized = true; @@ -82,7 +96,6 @@ MockedReply::MockedReply(const string &buffer, int delay, QObject *parent) , m_pos(buffer.data()) , m_bytesLeft(static_cast(m_buffer.size())) { - delay = 5; setOpenMode(QIODevice::ReadOnly); QTimer::singleShot(delay, this, &MockedReply::emitFinished); } @@ -130,6 +143,8 @@ qint64 MockedReply::readData(char *data, qint64 maxlen) return bytesToRead; } +int MockedReply::s_eventIndex = 0; + MockedReply *MockedReply::forRequest(const QString &method, const QString &path, const QUrlQuery &query, bool rest) { VAR_UNUSED(query) @@ -142,7 +157,7 @@ MockedReply *MockedReply::forRequest(const QString &method, const QString &path, // find the correct buffer for the request static const string emptyBuffer; const string *buffer = &emptyBuffer; - int delay = 0; + int delay = 5; { using namespace TestData; if (method == QLatin1String("GET")) { @@ -166,8 +181,21 @@ MockedReply *MockedReply::forRequest(const QString &method, const QString &path, } else if (path == QLatin1String("system/connections")) { buffer = &connections; } else if (path == QLatin1String("events")) { - buffer = &events; - delay = 5000; + buffer = &events[s_eventIndex]; + // "emit" the first event almost immediately and further events each 2.5 seconds + switch (s_eventIndex) { + case 0: + delay = 200; + ++s_eventIndex; + break; + case 5: + // continue emitting the last event every 10 seconds + delay = 10000; + break; + default: + delay = 2500; + ++s_eventIndex; + } } } } diff --git a/connector/syncthingconnectionmockhelpers.h b/connector/syncthingconnectionmockhelpers.h index 186b52c..abefa25 100644 --- a/connector/syncthingconnectionmockhelpers.h +++ b/connector/syncthingconnectionmockhelpers.h @@ -60,6 +60,7 @@ private: const string &m_buffer; const char *m_pos; qint64 m_bytesLeft; + static int s_eventIndex; }; } // namespace Data diff --git a/connector/testfiles/mocks/events.json b/connector/testfiles/mocks/events-01.json similarity index 98% rename from connector/testfiles/mocks/events.json rename to connector/testfiles/mocks/events-01.json index cee59ff..b1a64fa 100644 --- a/connector/testfiles/mocks/events.json +++ b/connector/testfiles/mocks/events-01.json @@ -23,7 +23,7 @@ "CopiedFromElsewhere": 0, "Pulled": 38, "BytesTotal": 104792064, - "BytesDone": 87883776 + "BytesDone": 47883776 }, "dir\\file2": { "Total": 80, diff --git a/connector/testfiles/mocks/events-02.json b/connector/testfiles/mocks/events-02.json new file mode 100644 index 0000000..40fe29b --- /dev/null +++ b/connector/testfiles/mocks/events-02.json @@ -0,0 +1,63 @@ +[ + { + "id": 4, + "type": "DownloadProgress", + "time": "2018-12-13T00:27:12.9876937Z", + "data": { + "zX8xfl3ygn-": { + "file1": { + "Total": 800, + "Pulling": 2, + "CopiedFromOrigin": 0, + "Reused": 633, + "CopiedFromElsewhere": 0, + "Pulled": 38, + "BytesTotal": 104792064, + "BytesDone": 87883776 + }, + "dir\\file2": { + "Total": 80, + "Pulling": 2, + "CopiedFromOrigin": 0, + "Reused": 0, + "CopiedFromElsewhere": 0, + "Pulled": 32, + "BytesTotal": 10420224, + "BytesDone": 8128768 + } + }, + "GXWxf-3zgnU": { + "file3": { + "Total": 800, + "Pulling": 2, + "CopiedFromOrigin": 0, + "Reused": 633, + "CopiedFromElsewhere": 0, + "Pulled": 38, + "BytesTotal": 104792064, + "BytesDone": 87883776 + }, + "directory1\\directory\\directory3\\directory4\\directory5\\directory3\\directory4\\directory5\\file4": { + "Total": 80, + "Pulling": 2, + "CopiedFromOrigin": 0, + "Reused": 0, + "CopiedFromElsewhere": 0, + "Pulled": 32, + "BytesTotal": 10420224, + "BytesDone": 8128768 + }, + "file4": { + "Total": 80, + "Pulling": 2, + "CopiedFromOrigin": 0, + "Reused": 0, + "CopiedFromElsewhere": 0, + "Pulled": 32, + "BytesTotal": 2048, + "BytesDone": 2000 + } + } + } + } +] diff --git a/connector/testfiles/mocks/events-03.json b/connector/testfiles/mocks/events-03.json new file mode 100644 index 0000000..4900067 --- /dev/null +++ b/connector/testfiles/mocks/events-03.json @@ -0,0 +1,43 @@ +[ + { + "id": 5, + "type": "DownloadProgress", + "time": "2018-12-13T00:30:12.9876937Z", + "data": { + "zX8xfl3ygn-": { + "dir\\file2": { + "Total": 80, + "Pulling": 2, + "CopiedFromOrigin": 0, + "Reused": 0, + "CopiedFromElsewhere": 0, + "Pulled": 32, + "BytesTotal": 10420224, + "BytesDone": 8128768 + } + }, + "GXWxf-3zgnU": { + "file3": { + "Total": 800, + "Pulling": 2, + "CopiedFromOrigin": 0, + "Reused": 633, + "CopiedFromElsewhere": 0, + "Pulled": 38, + "BytesTotal": 104792064, + "BytesDone": 87883776 + }, + "directory1\\directory\\directory3\\directory4\\directory5\\directory3\\directory4\\directory5\\file4": { + "Total": 80, + "Pulling": 2, + "CopiedFromOrigin": 0, + "Reused": 0, + "CopiedFromElsewhere": 0, + "Pulled": 32, + "BytesTotal": 10420224, + "BytesDone": 8128768 + } + } + } + } +] diff --git a/connector/testfiles/mocks/events-04.json b/connector/testfiles/mocks/events-04.json new file mode 100644 index 0000000..438c214 --- /dev/null +++ b/connector/testfiles/mocks/events-04.json @@ -0,0 +1,21 @@ +[ + { + "id": 6, + "type": "DownloadProgress", + "time": "2018-12-13T00:32:12.9876937Z", + "data": { + "zX8xfl3ygn-": { + "dir\\file2": { + "Total": 80, + "Pulling": 2, + "CopiedFromOrigin": 0, + "Reused": 0, + "CopiedFromElsewhere": 0, + "Pulled": 32, + "BytesTotal": 10420224, + "BytesDone": 8128768 + } + } + } + } +] diff --git a/connector/testfiles/mocks/events-05.json b/connector/testfiles/mocks/events-05.json new file mode 100644 index 0000000..7f55a8a --- /dev/null +++ b/connector/testfiles/mocks/events-05.json @@ -0,0 +1,9 @@ +[ + { + "id": 7, + "type": "DownloadProgress", + "time": "2018-12-13T00:33:12.9876937Z", + "data": { + } + } +] diff --git a/connector/testfiles/mocks/events-06.json b/connector/testfiles/mocks/events-06.json new file mode 100644 index 0000000..bd64634 --- /dev/null +++ b/connector/testfiles/mocks/events-06.json @@ -0,0 +1,63 @@ +[ + { + "id": 8, + "type": "DownloadProgress", + "time": "2018-12-13T00:34:12.9876937Z", + "data": { + "zX8xfl3ygn-": { + "file5": { + "Total": 800, + "Pulling": 2, + "CopiedFromOrigin": 0, + "Reused": 633, + "CopiedFromElsewhere": 0, + "Pulled": 38, + "BytesTotal": 104792064, + "BytesDone": 47883776 + }, + "dir\\file7": { + "Total": 80, + "Pulling": 2, + "CopiedFromOrigin": 0, + "Reused": 0, + "CopiedFromElsewhere": 0, + "Pulled": 32, + "BytesTotal": 10420224, + "BytesDone": 4128768 + } + }, + "GXWxf-3zgnU": { + "file25": { + "Total": 800, + "Pulling": 2, + "CopiedFromOrigin": 0, + "Reused": 633, + "CopiedFromElsewhere": 0, + "Pulled": 38, + "BytesTotal": 104792064, + "BytesDone": 87883776 + }, + "directory1\\directory\\directory3\\directory4\\directory5\\directory3\\directory4\\directory5\\file7": { + "Total": 80, + "Pulling": 2, + "CopiedFromOrigin": 0, + "Reused": 0, + "CopiedFromElsewhere": 0, + "Pulled": 32, + "BytesTotal": 10420224, + "BytesDone": 4128768 + }, + "file34": { + "Total": 80, + "Pulling": 2, + "CopiedFromOrigin": 0, + "Reused": 0, + "CopiedFromElsewhere": 0, + "Pulled": 32, + "BytesTotal": 2048, + "BytesDone": 1024 + } + } + } + } +] diff --git a/connector/testfiles/mocks/folderstatus.json b/connector/testfiles/mocks/folderstatus-01.json similarity index 100% rename from connector/testfiles/mocks/folderstatus.json rename to connector/testfiles/mocks/folderstatus-01.json diff --git a/connector/testfiles/mocks/folderstatus2.json b/connector/testfiles/mocks/folderstatus-02.json similarity index 100% rename from connector/testfiles/mocks/folderstatus2.json rename to connector/testfiles/mocks/folderstatus-02.json