diff --git a/SiaDrive.Api/SiaCommon.h b/SiaDrive.Api/SiaCommon.h index 7f5e1be..3d0f0a7 100644 --- a/SiaDrive.Api/SiaCommon.h +++ b/SiaDrive.Api/SiaCommon.h @@ -112,7 +112,8 @@ inline Hastings CalculateAverageUploadPrice(const std::vector& hosts) return CalculateAveragePrice(hosts, [](const IHost& host)->Hastings { return host.GetUploadPrice(); }); } -static String& ReplaceStringInPlace(String& subject, const String& search, const String& replace) +template +static T& ReplaceStringInPlace(T& subject, const T& search, const T& replace) { size_t pos = 0; while ((pos = subject.find(search, pos)) != std::string::npos) @@ -124,4 +125,17 @@ static String& ReplaceStringInPlace(String& subject, const String& search, const return subject; } + +template +static T& ReplaceStringInPlace(T& subject, typename T::value_type* search, const T& replace) +{ + return ReplaceStringInPlace(subject, T(search), replace); +} + +template +static T& ReplaceStringInPlace(T& subject, typename T::value_type* search, typename T::value_type* replace) +{ + return ReplaceStringInPlace(subject, T(search), T(replace)); +} + NS_END(2) \ No newline at end of file diff --git a/SiaDrive.Api/UploadManager.cpp b/SiaDrive.Api/UploadManager.cpp index d4a6fa4..7987ae9 100644 --- a/SiaDrive.Api/UploadManager.cpp +++ b/SiaDrive.Api/UploadManager.cpp @@ -11,7 +11,7 @@ using namespace Sia::Api; #define QUERY_UPLOADS_BY_STATUS "select id, sia_path, status from upload_table where status=@status order by id desc limit 1;" #define QUERY_UPLOADS_BY_2_STATUS "select id, sia_path, status from upload_table where (status=@status1 or status=@status2) order by id desc limit 1;" #define QUERY_UPLOADS_BY_SIA_PATH "select id, sia_path, status from upload_table where sia_path=@sia_path order by id desc limit 1;" -#define QUERY_UPLOADS_BY_SIA_PATH_AND_2_STATUS "select id, sia_path, status from upload_table where sia_path=@sia_path (status=@status1 or status=@status2) order by id desc limit 1;" +#define QUERY_UPLOADS_BY_SIA_PATH_AND_2_STATUS "select id, sia_path, status from upload_table where sia_path=@sia_path and (status=@status1 or status=@status2) order by id desc limit 1;" template String fmt(const String &fmt, Ts... vs) diff --git a/UnitTests/MockSiad.cpp b/UnitTests/MockSiad.cpp index 02042f1..08196d6 100644 --- a/UnitTests/MockSiad.cpp +++ b/UnitTests/MockSiad.cpp @@ -1,8 +1,16 @@ #include "stdafx.h" #include "MockSiad.h" +#include +#include +using namespace Sia::Api; class CMockClient { +private: + const std::string SUCESS_RESPONSE_JSON = "HTTP/1.1 200 OK\r\nConnection: close\r\nContent-Length: {ContentLength}\r\nContent-Type: application/json\r\n\r\n{Content}"; + const std::string NOT_FOUND_RESPONSE = "HTTP/1.1 404 Not Found\r\nConnection: close\r\nContent-Length: 17\r\nContent-Type: application/json\r\n\r\n{\"message\":\"404\"}"; + const std::string SERVER_VERSION_SUCCESS_CONTENT = "{\"version\": \"1.1.0\"}"; + public: CMockClient(SOCKET socket, std::function removedCallback) : _socket(socket), @@ -28,7 +36,6 @@ private: void Run() { bool connected = true; - bool active; while (connected && (::WaitForSingleObject(_stopEvent, 1) == WAIT_TIMEOUT)) { timeval tv = { 1, 0 }; @@ -56,11 +63,20 @@ private: std::string header = tmp.substr(0, position); if (header == "GET /daemon/version HTTP/1.1") { - response = "HTTP/1.1 404 Not Found\r\nConnection: close\r\n\r\n"; + response = SUCESS_RESPONSE_JSON; + response = ReplaceStringInPlace(ReplaceStringInPlace(response, "{ContentLength}", std::to_string(SERVER_VERSION_SUCCESS_CONTENT.length())), "{Content}", SERVER_VERSION_SUCCESS_CONTENT); + } + else + { + response = NOT_FOUND_RESPONSE; } } } + } + + if (response.size()) + { ::send(_socket, &response[0], response.length(), 0); } @@ -113,8 +129,11 @@ void CMockSiad::Start(const SiadTestType& testType) { if (!_serverThread) { - _serverThread.reset(new std::thread([this]() + HANDLE startedEvent = ::CreateEvent(nullptr, false, false, nullptr); + + _serverThread.reset(new std::thread([this,&startedEvent]() { + bool started = false; bool active; std::mutex clientMutex; std::vector connected; @@ -141,6 +160,12 @@ void CMockSiad::Start(const SiadTestType& testType) bool listening = ((listenSocket != INVALID_SOCKET) && (::bind(listenSocket, reinterpret_cast(&sockAddr), sizeof(sockAddr)) != SOCKET_ERROR)) && (::listen(listenSocket, 1) != SOCKET_ERROR); while (listening && ((active = (::WaitForSingleObject(_stopEvent, 1) == WAIT_TIMEOUT)))) { + if (!started) + { + ::SetEvent(startedEvent); + started = true; + } + ClearDisconnected(); timeval tv = { 1, 0 }; @@ -189,9 +214,12 @@ void CMockSiad::Start(const SiadTestType& testType) } } } while (active); - + ClearDisconnected(); })); + + ::WaitForSingleObject(startedEvent, INFINITE); + ::CloseHandle(startedEvent); } } diff --git a/UnitTests/UploadManagerTest.cpp b/UnitTests/UploadManagerTest.cpp index 33607ba..a72ac4a 100644 --- a/UnitTests/UploadManagerTest.cpp +++ b/UnitTests/UploadManagerTest.cpp @@ -14,7 +14,7 @@ namespace UnitTests { private: const SiaHostConfig hostConfig = { L"localhost", 19980, L"1.1.0" }; - std::unique_ptr siad; + static std::unique_ptr siad; public: TEST_METHOD_INITIALIZE(Initialize) @@ -22,7 +22,12 @@ namespace UnitTests siad.reset(new CMockSiad(hostConfig)); } - TEST_METHOD_CLEANUP(Cleanup) + TEST_METHOD_CLEANUP(DestroyTest) + { + siad->Stop(); + } + + TEST_CLASS_CLEANUP(DestroyClass) { siad->Stop(); } @@ -30,11 +35,24 @@ namespace UnitTests TEST_METHOD(TestMethod1) { siad->Start(SiadTestType::UploadFile); - Sleep(2000); - CSiaDriveConfig driveConfig; - CSiaCurl siaCurl(hostConfig); - siaCurl.GetServerVersion(); - CUploadManager uploadManager(siaCurl, &driveConfig); + try + { + CSiaDriveConfig driveConfig; + CSiaCurl siaCurl(hostConfig); + String version = siaCurl.GetServerVersion(); + + CUploadManager uploadManager(siaCurl, &driveConfig); + uploadManager.AddOrUpdate(L"/test1/test.txt", L"./test1/test.txt"); + } + catch (SQLite::Exception e) + { + siad->Stop(); + throw; + } + + siad->Stop(); } }; + + std::unique_ptr UnitTests::siad; } \ No newline at end of file