diff options
| author | Per Larsson <[email protected]> | 2021-12-14 12:34:47 +0100 |
|---|---|---|
| committer | Per Larsson <[email protected]> | 2021-12-14 12:34:47 +0100 |
| commit | b6c6568e1618f10d2160d836b65e35586e3c740f (patch) | |
| tree | f6a929cf918850bbba87d0ee67cd3482b2d50e24 /zenserver-test/zenserver-test.cpp | |
| parent | Fixed bug in z$ service returning partial cache records and enable small obje... (diff) | |
| parent | Partial revert b363c5b (diff) | |
| download | zen-b6c6568e1618f10d2160d836b65e35586e3c740f.tar.xz zen-b6c6568e1618f10d2160d836b65e35586e3c740f.zip | |
Merged main.
Diffstat (limited to 'zenserver-test/zenserver-test.cpp')
| -rw-r--r-- | zenserver-test/zenserver-test.cpp | 133 |
1 files changed, 77 insertions, 56 deletions
diff --git a/zenserver-test/zenserver-test.cpp b/zenserver-test/zenserver-test.cpp index ad467753c..2266e5305 100644 --- a/zenserver-test/zenserver-test.cpp +++ b/zenserver-test/zenserver-test.cpp @@ -41,16 +41,19 @@ ZEN_THIRD_PARTY_INCLUDES_START #undef GetObject ZEN_THIRD_PARTY_INCLUDES_END -#include <ppl.h> #include <atomic> #include <filesystem> #include <map> #include <random> #include <span> +#include <thread> #include <unordered_map> -#include <atlbase.h> -#include <process.h> +#if ZEN_PLATFORM_WINDOWS +# include <ppl.h> +# include <atlbase.h> +# include <process.h> +#endif #include <asio.hpp> @@ -71,6 +74,25 @@ ZEN_THIRD_PARTY_INCLUDES_END using namespace fmt::literals; using namespace std::literals; +#if ZEN_PLATFORM_LINUX || ZEN_PLATFORM_MAC +struct Concurrency +{ + template<typename... T> + static void parallel_invoke(T&&... t) + { + constexpr size_t NumTs = sizeof...(t); + std::thread Threads[NumTs] = { + std::thread(std::forward<T>(t))..., + }; + + for (std::thread& Thread : Threads) + { + Thread.join(); + } + } +}; +#endif + /* ___ ___ _________ _________ ________ ________ ___ ___ _______ ________ _________ @@ -143,7 +165,17 @@ public: private: void Reset() {} - void OnError(const std::error_code& Error) { ZEN_ERROR("HTTP client error! '{}'", Error.message()); } + void OnError(const asio::error_code& Error) + { + // Let EOF errors proceed. They're raised when sockets close. + if (Error == asio::error::eof) + { + return; + } + + using namespace fmt::literals; + zen::ThrowLastError("HTTP client error! '{}'"_format(Error.message())); + } int OnHeader(const char* Data, size_t Bytes) { @@ -185,7 +217,7 @@ private: // Send initial request payload asio::async_write(m_Socket, asio::const_buffer(m_RequestBody.data(), m_RequestBody.size()), - [this](const std::error_code& Error, size_t Bytes) { + [this](const asio::error_code& Error, size_t Bytes) { ZEN_UNUSED(Bytes); if (Error) { @@ -198,7 +230,7 @@ private: void OnRequestWritten() { - asio::async_read(m_Socket, m_ResponseBuffer, asio::transfer_at_least(1), [this](const std::error_code& Error, size_t Bytes) { + asio::async_read(m_Socket, m_ResponseBuffer, asio::transfer_at_least(1), [this](const asio::error_code& Error, size_t Bytes) { if (Error) { return OnError(Error); @@ -229,7 +261,7 @@ private: asio::async_read(m_Socket, m_ResponseBuffer, asio::transfer_at_least(1), - [this](const std::error_code& Error, size_t Bytes) { + [this](const asio::error_code& Error, size_t Bytes) { if (Error) { return OnError(Error); @@ -312,6 +344,8 @@ HttpConnectionPool::~HttpConnectionPool() std::unique_ptr<HttpClientConnection> HttpConnectionPool::GetConnection() { + using namespace fmt::literals; + zen::RwLock::ExclusiveLockScope ScopedLock(m_Lock); if (m_AvailableConnections.empty()) @@ -321,13 +355,13 @@ HttpConnectionPool::GetConnection() asio::ip::tcp::resolver Resolver{m_Context}; - std::error_code ErrCode; - auto it = Resolver.resolve(m_HostName, Service, ErrCode); - auto itEnd = asio::ip::tcp::resolver::iterator(); + asio::error_code ErrCode; + auto it = Resolver.resolve(m_HostName, Service, ErrCode); + auto itEnd = asio::ip::tcp::resolver::iterator(); if (ErrCode) { - return nullptr; + zen::ThrowLastError("Unabled to resolve '{}'"_format(m_HostName)); } asio::ip::tcp::socket Socket{m_Context}; @@ -335,7 +369,7 @@ HttpConnectionPool::GetConnection() if (ErrCode) { - return nullptr; + zen::ThrowLastError("Failed connecting '{}:{}'"_format(m_HostName, m_Port)); } return std::make_unique<HttpClientConnection>(m_Context, this, std::move(Socket)); @@ -343,7 +377,7 @@ HttpConnectionPool::GetConnection() std::unique_ptr<HttpClientConnection> Connection{m_AvailableConnections.back()}; m_AvailableConnections.pop_back(); - return std::move(Connection); + return Connection; } void @@ -742,7 +776,7 @@ TEST_CASE("default.single") auto IssueTestRequests = [&] { const uint64_t BatchNo = BatchCounter.fetch_add(1); - const DWORD ThreadId = GetCurrentThreadId(); + const int ThreadId = zen::GetCurrentThreadId(); ZEN_INFO("query batch {} started (thread {})", BatchNo, ThreadId); cpr::Session cli; @@ -756,22 +790,8 @@ TEST_CASE("default.single") ZEN_INFO("query batch {} ended (thread {})", BatchNo, ThreadId); }; - auto fun10 = [&] { - Concurrency::parallel_invoke(IssueTestRequests, - IssueTestRequests, - IssueTestRequests, - IssueTestRequests, - IssueTestRequests, - IssueTestRequests, - IssueTestRequests, - IssueTestRequests, - IssueTestRequests, - IssueTestRequests); - }; - zen::Stopwatch timer; - // Concurrency::parallel_invoke(fun10, fun10, fun, fun, fun, fun, fun, fun, fun, fun); Concurrency::parallel_invoke(IssueTestRequests, IssueTestRequests, IssueTestRequests, @@ -810,7 +830,7 @@ TEST_CASE("multi.basic") auto IssueTestRequests = [&](int PortNumber) { const uint64_t BatchNo = BatchCounter.fetch_add(1); - const DWORD ThreadId = GetCurrentThreadId(); + const int ThreadId = zen::GetCurrentThreadId(); ZEN_INFO("query batch {} started (thread {}) for port {}", BatchNo, ThreadId, PortNumber); @@ -962,6 +982,10 @@ TEST_CASE("project.basic") zen::StringBuilder<64> BaseUri; BaseUri << "http://localhost:{}/prj/test"_format(PortNumber); + std::filesystem::path BinPath = zen::GetRunningExecutablePath(); + std::filesystem::path RootPath = BinPath.parent_path().parent_path(); + BinPath = BinPath.lexically_relative(RootPath); + SUBCASE("build store init") { { @@ -969,8 +993,7 @@ TEST_CASE("project.basic") zen::CbObjectWriter Body; Body << "id" << "test"; - Body << "root" - << "/zooom"; + Body << "root" << RootPath.c_str(); Body << "project" << "/zooom"; Body << "engine" @@ -990,7 +1013,7 @@ TEST_CASE("project.basic") zen::CbObjectView ResponseObject = zen::CbFieldView(Response.text.data()).AsObjectView(); CHECK(ResponseObject["id"].AsString() == "test"sv); - CHECK(ResponseObject["root"].AsString() == "/zooom"sv); + CHECK(ResponseObject["root"].AsString() == PathToUtf8(RootPath.c_str())); } } @@ -1032,13 +1055,12 @@ TEST_CASE("project.basic") "00010000"}; auto FileOid = zen::Oid::FromHexString(ChunkId); - std::filesystem::path ReliablePath = zen::GetRunningExecutablePath(); - OpWriter.BeginArray("files"); OpWriter.BeginObject(); OpWriter << "id" << FileOid; - OpWriter << "clientpath" << ReliablePath.c_str(); - OpWriter << "serverpath" << ReliablePath.c_str(); + OpWriter << "clientpath" + << "/{engine}/client/side/path"; + OpWriter << "serverpath" << BinPath.c_str(); OpWriter.EndObject(); OpWriter.EndArray(); @@ -1353,14 +1375,13 @@ TEST_CASE("zcache.cbpackage") ZenServerInstance RemoteInstance(TestEnv); RemoteInstance.SetTestDir(RemoteDataDir); RemoteInstance.SpawnServer(RemotePortNumber); + RemoteInstance.WaitUntilReady(); ZenServerInstance LocalInstance(TestEnv); LocalInstance.SetTestDir(LocalDataDir); LocalInstance.SpawnServer(LocalPortNumber, "--upstream-thread-count=0 --upstream-zen-url=http://localhost:{}"_format(RemotePortNumber)); - LocalInstance.WaitUntilReady(); - RemoteInstance.WaitUntilReady(); const std::string_view Bucket = "mosdef"sv; zen::IoHash Key; @@ -1417,14 +1438,13 @@ TEST_CASE("zcache.cbpackage") ZenServerInstance RemoteInstance(TestEnv); RemoteInstance.SetTestDir(RemoteDataDir); RemoteInstance.SpawnServer(RemotePortNumber); + RemoteInstance.WaitUntilReady(); ZenServerInstance LocalInstance(TestEnv); LocalInstance.SetTestDir(LocalDataDir); LocalInstance.SpawnServer(LocalPortNumber, "--upstream-thread-count=0 --upstream-zen-url=http://localhost:{}"_format(RemotePortNumber)); - LocalInstance.WaitUntilReady(); - RemoteInstance.WaitUntilReady(); const std::string_view Bucket = "mosdef"sv; zen::IoHash Key; @@ -1810,6 +1830,8 @@ TEST_CASE("zcache.policy") const bool Ok = Package.TryLoad(Body); CHECK(Ok); + CHECK(Ok); + CbObject CacheRecord = Package.GetObject(); std::vector<IoHash> AttachmentKeys; @@ -1830,6 +1852,7 @@ TEST_CASE("zcache.policy") const bool Ok = Package.TryLoad(Body); CHECK(Ok); + CHECK(Ok); CHECK(Package.GetAttachments().size() != 0); } } @@ -1951,7 +1974,7 @@ TEST_CASE("zcache.rpc") for (uint32_t Key = 1; Key <= Num; ++Key) { - const zen::CacheKey CacheKey = zen::CacheKey::Create(Bucket, zen::IoHash::HashBuffer(&Key, sizeof uint32_t)); + const zen::CacheKey CacheKey = zen::CacheKey::Create(Bucket, zen::IoHash::HashBuffer(&Key, sizeof(uint32_t))); CbPackage CacheRecord = CreateCacheRecord(CacheKey, PayloadSize); OutKeys.push_back(CacheKey); @@ -2018,8 +2041,6 @@ TEST_CASE("zcache.rpc") for (CbFieldView RecordView : ResponseObject["Result"]) { - ExtendableStringBuilder<256> Tmp; - auto JSON = RecordView.AsObjectView().ToJson(Tmp).ToView(); OutResult.Records.push_back(RecordView); } @@ -2108,7 +2129,6 @@ TEST_CASE("zcache.rpc") { const CacheKey& ExpectedKey = ExistingKeys[KeyIndex++]; CbObjectView RecordObj = RecordView.AsObjectView(); - CbObjectView KeyObj = RecordObj["CacheKey"sv].AsObjectView(); zen::CacheKey Key = LoadKey(RecordObj["CacheKey"sv]); const IoHash AttachmentHash = RecordObj["Data"sv].AsHash(); const CbAttachment* Attachment = Result.Response.FindAttachment(AttachmentHash); @@ -2143,10 +2163,9 @@ TEST_CASE("zcache.rpc") { const CacheKey& ExpectedKey = Keys[Index++]; - CbObjectView RecordObj = RecordView.AsObjectView(); - CbObjectView KeyObj = RecordObj["CacheKey"sv].AsObjectView(); - const CacheKey Key = CacheKey::Create(KeyObj["Bucket"sv].AsString(), KeyObj["Hash"].AsHash()); - const IoHash AttachmentHash = RecordObj["Data"sv].AsHash(); + CbObjectView RecordObj = RecordView.AsObjectView(); + CbObjectView KeyObj = RecordObj["CacheKey"sv].AsObjectView(); + const CacheKey Key = CacheKey::Create(KeyObj["Bucket"sv].AsString(), KeyObj["Hash"].AsHash()); CHECK(Key == ExpectedKey); } @@ -2232,7 +2251,7 @@ struct RemoteExecutionRequest for (const auto& Kv : m_Visit.m_Files) { PrepReq.BeginObject(); - PrepReq << "file" << zen::WideToUtf8(Kv.first) << "size" << Kv.second.Size << "hash" << Kv.second.Hash; + PrepReq << "file" << zen::PathToUtf8(Kv.first) << "size" << Kv.second.Size << "hash" << Kv.second.Hash; PrepReq.EndObject(); } PrepReq.EndArray(); @@ -2255,7 +2274,7 @@ struct RemoteExecutionRequest if (auto It = m_Visit.m_HashToFile.find(NeedHash); It != m_Visit.m_HashToFile.end()) { - zen::IoBuffer FileData = zen::IoBufferBuilder::MakeFromFile(It->second.c_str()); + zen::IoBuffer FileData = zen::IoBufferBuilder::MakeFromFile(It->second); cpr::Response CasResponse = cpr::Post(cpr::Url(m_CasUri), cpr::Body((const char*)FileData.Data(), FileData.Size())); @@ -2293,7 +2312,7 @@ private: Visitor(const std::filesystem::path& RootPath) : m_RootPath(RootPath) {} - virtual void VisitFile(const std::filesystem::path& Parent, const std::wstring_view& FileName, uint64_t FileSize) override + virtual void VisitFile(const std::filesystem::path& Parent, const path_view& FileName, uint64_t FileSize) override { std::filesystem::path FullPath = Parent / FileName; @@ -2301,8 +2320,8 @@ private: zen::ScanFile(FullPath, 64 * 1024, [&](const void* Data, size_t Size) { Ios.Append(Data, Size); }); zen::IoHash Hash = Ios.GetHash(); - std::wstring RelativePath = FullPath.lexically_relative(m_RootPath).native(); - // ZEN_INFO("File: {:32} => {} ({})", zen::WideToUtf8(RelativePath), Hash, FileSize); + auto RelativePath = FullPath.lexically_relative(m_RootPath).native(); + // ZEN_INFO("File: {:32} => {} ({})", zen::PathToUtf8(RelativePath), Hash, FileSize); FileEntry& Entry = m_Files[RelativePath]; Entry.Hash = Hash; @@ -2311,11 +2330,11 @@ private: m_HashToFile[Hash] = FullPath; } - virtual bool VisitDirectory(const std::filesystem::path& Parent, const std::wstring_view& DirectoryName) override + virtual bool VisitDirectory(const std::filesystem::path& Parent, const path_view& DirectoryName) override { std::filesystem::path FullPath = Parent / DirectoryName; - if (DirectoryName.starts_with(L".")) + if (DirectoryName.starts_with('.')) { return false; } @@ -2329,7 +2348,7 @@ private: zen::IoHash Hash; }; - std::map<std::wstring, FileEntry> m_Files; + std::map<std::filesystem::path::string_type, FileEntry> m_Files; std::unordered_map<zen::IoHash, std::filesystem::path, zen::IoHash::Hasher> m_HashToFile; }; @@ -2344,6 +2363,7 @@ private: TEST_CASE("exec.basic") { +# if ZEN_WITH_COMPUTE_SERVICES using namespace std::literals; std::filesystem::path TestDir = TestEnv.CreateNewTestDir(); @@ -2374,6 +2394,7 @@ TEST_CASE("exec.basic") CHECK(Result["exitcode"sv].AsInt32(-1) == 1); } +# endif // ZEN_WITH_COMPUTE_SERVICES } TEST_CASE("mesh.basic") |