diff options
Diffstat (limited to 'src/zenutil')
| -rw-r--r-- | src/zenutil/commandlineoptions.cpp | 27 | ||||
| -rw-r--r-- | src/zenutil/consul/consul.cpp | 140 | ||||
| -rw-r--r-- | src/zenutil/include/zenutil/commandlineoptions.h | 13 | ||||
| -rw-r--r-- | src/zenutil/include/zenutil/consul.h | 47 | ||||
| -rw-r--r-- | src/zenutil/include/zenutil/logging/rotatingfilesink.h | 3 | ||||
| -rw-r--r-- | src/zenutil/include/zenutil/zenserverprocess.h | 35 | ||||
| -rw-r--r-- | src/zenutil/service.cpp | 54 | ||||
| -rw-r--r-- | src/zenutil/zenserverprocess.cpp | 120 |
8 files changed, 385 insertions, 54 deletions
diff --git a/src/zenutil/commandlineoptions.cpp b/src/zenutil/commandlineoptions.cpp index 81699361b..d94564843 100644 --- a/src/zenutil/commandlineoptions.cpp +++ b/src/zenutil/commandlineoptions.cpp @@ -2,7 +2,11 @@ #include <zenutil/commandlineoptions.h> +#include <zencore/string.h> #include <filesystem> + +#include <zencore/windows.h> + #if ZEN_WITH_TESTS # include <zencore/testing.h> #endif // ZEN_WITH_TESTS @@ -160,6 +164,29 @@ RemoveQuotes(const std::string_view& Arg) return Arg; } +CommandLineConverter::CommandLineConverter(int& argc, char**& argv) +{ +#if ZEN_PLATFORM_WINDOWS + LPWSTR RawCommandLine = GetCommandLineW(); + std::string CommandLine = WideToUtf8(RawCommandLine); + Args = ParseCommandLine(CommandLine); +#else + Args.reserve(argc); + for (int I = 0; I < argc; I++) + { + std::string Arg(argv[I]); + if ((!Arg.empty()) && (Arg != " ")) + { + Args.emplace_back(std::move(Arg)); + } + } +#endif + RawArgs = StripCommandlineQuotes(Args); + + argc = static_cast<int>(RawArgs.size()); + argv = RawArgs.data(); +} + #if ZEN_WITH_TESTS void diff --git a/src/zenutil/consul/consul.cpp b/src/zenutil/consul/consul.cpp new file mode 100644 index 000000000..6ddebf97a --- /dev/null +++ b/src/zenutil/consul/consul.cpp @@ -0,0 +1,140 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +#include <zenutil/consul.h> + +#include <zencore/except_fmt.h> +#include <zencore/fmtutils.h> +#include <zencore/logging.h> +#include <zencore/process.h> +#include <zencore/string.h> +#include <zencore/timer.h> + +#include <fmt/format.h> + +namespace zen::consul { + +////////////////////////////////////////////////////////////////////////// + +struct ConsulProcess::Impl +{ + Impl(std::string_view BaseUri) : m_HttpClient(BaseUri) {} + ~Impl() = default; + + void SpawnConsulAgent() + { + if (m_ProcessHandle.IsValid()) + { + return; + } + + CreateProcOptions Options; + Options.Flags |= CreateProcOptions::Flag_Windows_NewProcessGroup; + + CreateProcResult Result = CreateProc("consul" ZEN_EXE_SUFFIX_LITERAL, "consul" ZEN_EXE_SUFFIX_LITERAL " agent -dev", Options); + + if (Result) + { + m_ProcessHandle.Initialize(Result); + + Stopwatch Timer; + + // Poll to check when the agent is ready + + do + { + Sleep(100); + HttpClient::Response Resp = m_HttpClient.Get("v1/status/leader"); + if (Resp) + { + ZEN_INFO("Consul agent started successfully (waited {})", NiceTimeSpanMs(Timer.GetElapsedTimeMs())); + + return; + } + } while (Timer.GetElapsedTimeMs() < 10000); + } + + // Report failure! + + ZEN_WARN("Consul agent failed to start within timeout period"); + } + + void StopConsulAgent() + { + if (!m_ProcessHandle.IsValid()) + { + return; + } + + // This waits for the process to exit and also resets the handle + m_ProcessHandle.Kill(); + } + +private: + ProcessHandle m_ProcessHandle; + HttpClient m_HttpClient; +}; + +ConsulProcess::ConsulProcess() : m_Impl(std::make_unique<Impl>("http://localhost:8500/")) +{ +} + +ConsulProcess::~ConsulProcess() +{ +} + +void +ConsulProcess::SpawnConsulAgent() +{ + m_Impl->SpawnConsulAgent(); +} + +void +ConsulProcess::StopConsulAgent() +{ + m_Impl->StopConsulAgent(); +} + +////////////////////////////////////////////////////////////////////////// + +ConsulClient::ConsulClient(std::string_view BaseUri) : m_HttpClient(BaseUri) +{ +} + +ConsulClient::~ConsulClient() +{ +} + +void +ConsulClient::SetKeyValue(std::string_view Key, std::string_view Value) +{ + IoBuffer ValueBuffer = IoBufferBuilder::MakeFromMemory(MakeMemoryView(Value)); + HttpClient::Response Result = + m_HttpClient.Put(fmt::format("v1/kv/{}", Key), ValueBuffer, {{"Content-Type", "text/plain"}, {"Accept", "application/json"}}); + if (!Result) + { + throw runtime_error("ConsulClient::SetKeyValue() failed to set key '{}' ({})", Key, Result.ErrorMessage("")); + } +} + +std::string +ConsulClient::GetKeyValue(std::string_view Key) +{ + HttpClient::Response Result = m_HttpClient.Get(fmt::format("v1/kv/{}?raw", Key)); + if (!Result) + { + throw runtime_error("ConsulClient::GetKeyValue() failed to get key '{}' ({})", Key, Result.ErrorMessage("")); + } + return Result.ToText(); +} + +void +ConsulClient::DeleteKey(std::string_view Key) +{ + HttpClient::Response Result = m_HttpClient.Delete(fmt::format("v1/kv/{}", Key)); + if (!Result) + { + throw runtime_error("ConsulClient::DeleteKey() failed to delete key '{}' ({})", Key, Result.ErrorMessage("")); + } +} + +} // namespace zen::consul diff --git a/src/zenutil/include/zenutil/commandlineoptions.h b/src/zenutil/include/zenutil/commandlineoptions.h index d6a171242..01cceedb1 100644 --- a/src/zenutil/include/zenutil/commandlineoptions.h +++ b/src/zenutil/include/zenutil/commandlineoptions.h @@ -22,6 +22,19 @@ std::vector<char*> StripCommandlineQuotes(std::vector<std::string>& InOutArgs) std::filesystem::path StringToPath(const std::string_view& Path); std::string_view RemoveQuotes(const std::string_view& Arg); +class CommandLineConverter +{ +public: + CommandLineConverter(int& argc, char**& argv); + + int ArgC = 0; + char** ArgV = nullptr; + +private: + std::vector<std::string> Args; + std::vector<char*> RawArgs; +}; + void commandlineoptions_forcelink(); // internal } // namespace zen diff --git a/src/zenutil/include/zenutil/consul.h b/src/zenutil/include/zenutil/consul.h new file mode 100644 index 000000000..08871fa66 --- /dev/null +++ b/src/zenutil/include/zenutil/consul.h @@ -0,0 +1,47 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include <zenbase/zenbase.h> +#include <zenhttp/httpclient.h> + +#include <string> +#include <string_view> + +namespace zen::consul { + +class ConsulClient +{ +public: + ConsulClient(std::string_view BaseUri); + ~ConsulClient(); + + ConsulClient(const ConsulClient&) = delete; + ConsulClient& operator=(const ConsulClient&) = delete; + + void SetKeyValue(std::string_view Key, std::string_view Value); + std::string GetKeyValue(std::string_view Key); + void DeleteKey(std::string_view Key); + +private: + HttpClient m_HttpClient; +}; + +class ConsulProcess +{ +public: + ConsulProcess(); + ~ConsulProcess(); + + ConsulProcess(const ConsulProcess&) = delete; + ConsulProcess& operator=(const ConsulProcess&) = delete; + + void SpawnConsulAgent(); + void StopConsulAgent(); + +private: + struct Impl; + std::unique_ptr<Impl> m_Impl; +}; + +} // namespace zen::consul diff --git a/src/zenutil/include/zenutil/logging/rotatingfilesink.h b/src/zenutil/include/zenutil/logging/rotatingfilesink.h index 4d10f3794..8901b7779 100644 --- a/src/zenutil/include/zenutil/logging/rotatingfilesink.h +++ b/src/zenutil/include/zenutil/logging/rotatingfilesink.h @@ -11,6 +11,7 @@ ZEN_THIRD_PARTY_INCLUDES_START #include <spdlog/sinks/sink.h> ZEN_THIRD_PARTY_INCLUDES_END +#include <atomic> #include <filesystem> namespace zen::logging { @@ -248,7 +249,7 @@ private: const std::size_t m_MaxSize; const std::size_t m_MaxFiles; BasicFile m_CurrentFile; - bool m_NeedFlush = false; + std::atomic<bool> m_NeedFlush = false; }; } // namespace zen::logging diff --git a/src/zenutil/include/zenutil/zenserverprocess.h b/src/zenutil/include/zenutil/zenserverprocess.h index 0da63285b..d0402640b 100644 --- a/src/zenutil/include/zenutil/zenserverprocess.h +++ b/src/zenutil/include/zenutil/zenserverprocess.h @@ -34,8 +34,10 @@ public: void Initialize(std::filesystem::path ProgramBaseDir); void InitializeForTest(std::filesystem::path ProgramBaseDir, std::filesystem::path TestBaseDir, std::string_view ServerClass = ""); + void InitializeForHub(std::filesystem::path ProgramBaseDir, std::filesystem::path TestBaseDir, std::string_view ServerClass = ""); std::filesystem::path CreateNewTestDir(); + std::filesystem::path CreateChildDir(std::string_view ChildName); std::filesystem::path ProgramBaseDir() const { return m_ProgramBaseDir; } std::filesystem::path GetTestRootDir(std::string_view Path); inline bool IsInitialized() const { return m_IsInitialized; } @@ -43,11 +45,18 @@ public: inline std::string_view GetServerClass() const { return m_ServerClass; } inline uint16_t GetNewPortNumber() { return m_NextPortNumber.fetch_add(1); } + // The defaults will work for a single root process only. For hierarchical + // setups (e.g., hub managing storage servers), we need to be able to + // allocate distinct child IDs and ports to avoid overlap/conflicts. + static void SetBaseChildId(int InitialValue); + void SetNextPortNumber(uint16_t NewValue) { m_NextPortNumber = NewValue; } + private: std::filesystem::path m_ProgramBaseDir; - std::filesystem::path m_TestBaseDir; + std::filesystem::path m_ChildProcessBaseDir; bool m_IsInitialized = false; bool m_IsTestInstance = false; + bool m_IsHubInstance = false; std::string m_ServerClass; std::atomic_uint16_t m_NextPortNumber{20000}; }; @@ -60,10 +69,19 @@ private: Especially useful for automated testing but can also be used for management tools. + This is also used by zenserver in hub mode, for managing storage + server instances. + */ struct ZenServerInstance { - ZenServerInstance(ZenServerEnvironment& TestEnvironment); + enum class ServerMode + { + kStorageServer, // default + kHubServer, + }; + + ZenServerInstance(ZenServerEnvironment& TestEnvironment, ServerMode Mode = ServerMode::kStorageServer); ~ZenServerInstance(); int Shutdown(); @@ -72,6 +90,7 @@ struct ZenServerInstance [[nodiscard]] bool WaitUntilReady(int Timeout); [[nodiscard]] bool WaitUntilExited(int Timeout, std::error_code& OutEc); void EnableTermination() { m_Terminate = true; } + void EnableShutdownOnDestroy() { m_ShutdownOnDestroy = true; } void DisableShutdownOnDestroy() { m_ShutdownOnDestroy = false; } void Detach(); inline int GetPid() const { return m_Process.Pid(); } @@ -81,7 +100,11 @@ struct ZenServerInstance bool Terminate(); std::string GetLogOutput() const; - void SetTestDir(std::filesystem::path TestDir); + inline ServerMode GetServerMode() const { return m_ServerMode; } + + inline void SetServerExecutablePath(std::filesystem::path ExecutablePath) { m_ServerExecutablePath = ExecutablePath; } + + void SetDataDir(std::filesystem::path TestDir); inline void SpawnServer(std::string_view AdditionalServerArgs = std::string_view()) { @@ -117,11 +140,13 @@ private: std::unique_ptr<NamedEvent> m_ShutdownEvent; bool m_Terminate = false; bool m_ShutdownOnDestroy = true; - std::filesystem::path m_TestDir; - uint16_t m_BasePort = 0; + std::filesystem::path m_DataDir; + uint16_t m_BasePort = 0; + ServerMode m_ServerMode = ServerMode::kStorageServer; std::optional<int> m_OwnerPid; std::string m_Name; std::filesystem::path m_OutputCapturePath; + std::filesystem::path m_ServerExecutablePath; void CreateShutdownEvent(int BasePort); void SpawnServer(int BasePort, std::string_view AdditionalServerArgs, int WaitTimeoutMs); diff --git a/src/zenutil/service.cpp b/src/zenutil/service.cpp index 103fdaa2f..f2a925e61 100644 --- a/src/zenutil/service.cpp +++ b/src/zenutil/service.cpp @@ -229,12 +229,13 @@ namespace { std::filesystem::path GetPListPath(const std::string& DaemonName) { - const std::filesystem::path PListFolder = "/Library/LaunchDaemons"; + char* HomeDir = getenv("HOME"); + std::filesystem::path PListFolder = HomeDir; + PListFolder /= "Library/LaunchAgents"; return PListFolder / (DaemonName + ".plist"); } - std::string BuildPlist(std::string_view ServiceName, - const std::filesystem::path& ExecutablePath, + std::string BuildPlist(const std::filesystem::path& ExecutablePath, std::string_view CommandLineOptions, std::string_view DaemonName, bool Debug) @@ -265,14 +266,8 @@ namespace { " <key>RunAtLoad</key>\n" " <true/>\n" " \n" - // " <key>KeepAlive</key>\n" - // " <true/>\n" - // " \n" - " <key>StandardOutPath</key>\n" - " <string>/var/log/{}.log</string>\n" - " \n" - " <key>StandardErrorPath</key>\n" - " <string>/var/log/{}.err.log</string>\n" + " <key>KeepAlive</key>\n" + " <true/>\n" " \n" " <key>Debug</key>\n" " <{}/>\n" @@ -282,22 +277,7 @@ namespace { DaemonName, ExecutablePath, ProgramArguments.ToView(), - ServiceName, - ServiceName, Debug ? "true"sv : "false"sv); - - // "<key>Sockets</key>" - // "<dict>" - // "<key>Listeners</key>" - // "<dict>" - // "<key>SockServiceName</key>" - // "<string>{}</string>" // Listen socket - // "<key>SockType</key>" - // "<string>tcp</string>" - // "<key>SockFamily</key>" - // "<string>IPv4</string>" - // "</dict>" - // "</dict>" } #endif // ZEN_PLATFORM_MAC @@ -752,9 +732,8 @@ StopService(std::string_view ServiceName) std::error_code InstallService(std::string_view ServiceName, const ServiceSpec& Spec) { - // TODO: Do we need to create a separate user for the service or is running as the default service user OK? const std::string DaemonName = GetDaemonName(ServiceName); - std::string PList = BuildPlist(ServiceName, Spec.ExecutablePath, Spec.CommandLineOptions, DaemonName, true); + std::string PList = BuildPlist(Spec.ExecutablePath, Spec.CommandLineOptions, DaemonName, true); const std::filesystem::path PListPath = GetPListPath(DaemonName); ZEN_INFO("Writing launchd plist to {}", PListPath.string()); @@ -910,8 +889,14 @@ StartService(std::string_view ServiceName) { const std::string DaemonName = GetDaemonName(ServiceName); const std::filesystem::path PListPath = GetPListPath(DaemonName); + std::pair<int, std::string> User = ExecuteProgram("id -u"); + + if (User.first != 0) + { + return MakeErrorCode(User.first); + } - std::pair<int, std::string> Res = ExecuteProgram(fmt::format("launchctl bootstrap system {}", PListPath)); + std::pair<int, std::string> Res = ExecuteProgram(fmt::format("launchctl bootstrap gui/{} {}", User.second, PListPath)); if (Res.first != 0) { return MakeErrorCode(Res.first); @@ -926,13 +911,18 @@ StopService(std::string_view ServiceName) const std::string DaemonName = GetDaemonName(ServiceName); const std::filesystem::path PListPath = GetPListPath(DaemonName); - /* - std::pair<int, std::string> Res = ExecuteProgram(fmt::format("launchctl bootout system ", PListPath.)); + std::pair<int, std::string> User = ExecuteProgram("id -u"); + + if (User.first != 0) + { + return MakeErrorCode(User.first); + } + + std::pair<int, std::string> Res = ExecuteProgram(fmt::format("launchctl bootout gui/{} {}", User.second, PListPath)); if (Res.first != 0) { return MakeErrorCode(Res.first); } - */ return {}; } diff --git a/src/zenutil/zenserverprocess.cpp b/src/zenutil/zenserverprocess.cpp index 6a93f0c63..ef2a4fda5 100644 --- a/src/zenutil/zenserverprocess.cpp +++ b/src/zenutil/zenserverprocess.cpp @@ -31,6 +31,19 @@ namespace zen { +// this needs to key off the current process child-id, in order to avoid conflicts +// in situations where we have a tree of zenserver child processes (such as in hub +// tests) + +std::atomic<int> ChildIdCounter{0}; + +void +ZenServerEnvironment::SetBaseChildId(int InitialValue) +{ + ZEN_ASSERT(ChildIdCounter == 0); + ChildIdCounter = InitialValue; +} + namespace zenutil { #if ZEN_PLATFORM_WINDOWS class SecurityAttributes @@ -507,8 +520,8 @@ ZenServerEnvironment::InitializeForTest(std::filesystem::path ProgramBaseDir, { using namespace std::literals; - m_ProgramBaseDir = ProgramBaseDir; - m_TestBaseDir = TestBaseDir; + m_ProgramBaseDir = ProgramBaseDir; + m_ChildProcessBaseDir = TestBaseDir; ZEN_INFO("Program base dir is '{}'", ProgramBaseDir); ZEN_INFO("Cleaning test base dir '{}'", TestBaseDir); @@ -536,6 +549,59 @@ ZenServerEnvironment::InitializeForTest(std::filesystem::path ProgramBaseDir, } } +void +ZenServerEnvironment::InitializeForHub(std::filesystem::path ProgramBaseDir, + std::filesystem::path ChildBaseDir, + std::string_view ServerClass) +{ + using namespace std::literals; + + m_ProgramBaseDir = ProgramBaseDir; + m_ChildProcessBaseDir = ChildBaseDir; + + ZEN_INFO("Program base dir is '{}'", m_ProgramBaseDir); + ZEN_INFO("Cleaning child base dir '{}'", m_ChildProcessBaseDir); + DeleteDirectories(m_ChildProcessBaseDir.c_str()); + + m_IsHubInstance = true; + m_IsInitialized = true; + + if (ServerClass.empty()) + { +#if ZEN_WITH_HTTPSYS + if (!zen::windows::IsRunningOnWine()) + { + m_ServerClass = "httpsys"sv; + + return; + } +#endif + + m_ServerClass = "asio"sv; + } + else + { + m_ServerClass = ServerClass; + } +} + +std::filesystem::path +ZenServerEnvironment::CreateChildDir(std::string_view ChildName) +{ + using namespace std::literals; + + std::filesystem::path ChildPath = m_ChildProcessBaseDir / ChildName; + + if (!IsDir(ChildPath)) + { + ZEN_INFO("Creating new test dir @ '{}'", ChildPath); + + CreateDirectories(ChildPath); + } + + return ChildPath; +} + std::filesystem::path ZenServerEnvironment::CreateNewTestDir() { @@ -544,7 +610,7 @@ ZenServerEnvironment::CreateNewTestDir() ExtendableWideStringBuilder<256> TestDir; TestDir << "test"sv << int64_t(ZenServerTestCounter.fetch_add(1)); - std::filesystem::path TestPath = m_TestBaseDir / TestDir.c_str(); + std::filesystem::path TestPath = m_ChildProcessBaseDir / TestDir.c_str(); ZEN_ASSERT(!IsDir(TestPath)); ZEN_INFO("Creating new test dir @ '{}'", TestPath); @@ -566,11 +632,11 @@ ZenServerEnvironment::GetTestRootDir(std::string_view Path) ////////////////////////////////////////////////////////////////////////// -std::atomic<int> ChildIdCounter{0}; - -ZenServerInstance::ZenServerInstance(ZenServerEnvironment& TestEnvironment) : m_Env(TestEnvironment) +ZenServerInstance::ZenServerInstance(ZenServerEnvironment& TestEnvironment, ServerMode Mode) : m_Env(TestEnvironment), m_ServerMode(Mode) { ZEN_ASSERT(TestEnvironment.IsInitialized()); + + m_ServerMode = Mode; } ZenServerInstance::~ZenServerInstance() @@ -632,7 +698,7 @@ ZenServerInstance::Shutdown() { Stopwatch Timer; ZEN_DEBUG("Waiting for zenserver process {} ({}) to shut down", m_Name, m_Process.Pid()); - while (!m_Process.Wait(1000)) + while (!m_Process.Wait(2000)) { if (!m_Process.IsValid()) { @@ -710,6 +776,22 @@ ZenServerInstance::SpawnServer(std::string_view ServerArgs, bool OpenConsole, in SpawnServerInternal(ChildId, ServerArgs, OpenConsole, WaitTimeoutMs); } +std::string_view +ToString(ZenServerInstance::ServerMode Mode) +{ + using namespace std::literals; + + switch (Mode) + { + case ZenServerInstance::ServerMode::kStorageServer: + return "storage"sv; + case ZenServerInstance::ServerMode::kHubServer: + return "hub"sv; + default: + return "invalid"sv; + } +} + void ZenServerInstance::SpawnServerInternal(int ChildId, std::string_view ServerArgs, bool OpenConsole, int WaitTimeoutMs) { @@ -721,6 +803,12 @@ ZenServerInstance::SpawnServerInternal(int ChildId, std::string_view ServerArgs, ExtendableStringBuilder<512> CommandLine; CommandLine << "zenserver" ZEN_EXE_SUFFIX_LITERAL; // see CreateProc() call for actual binary path + + if (m_ServerMode == ServerMode::kHubServer) + { + CommandLine << " hub"; + } + CommandLine << " --child-id " << ChildEventName; if (!ServerArgs.empty()) @@ -730,7 +818,7 @@ ZenServerInstance::SpawnServerInternal(int ChildId, std::string_view ServerArgs, std::filesystem::path CurrentDirectory = std::filesystem::current_path(); - ZEN_DEBUG("Spawning server '{}'", m_Name); + ZEN_DEBUG("Spawning {} server '{}'", ToString(m_ServerMode), m_Name); uint32_t CreationFlags = 0; if (OpenConsole) @@ -738,8 +826,9 @@ ZenServerInstance::SpawnServerInternal(int ChildId, std::string_view ServerArgs, CreationFlags |= CreateProcOptions::Flag_NewConsole; } - const std::filesystem::path BaseDir = m_Env.ProgramBaseDir(); - const std::filesystem::path Executable = BaseDir / "zenserver" ZEN_EXE_SUFFIX_LITERAL; + const std::filesystem::path BaseDir = m_Env.ProgramBaseDir(); + const std::filesystem::path Executable = + m_ServerExecutablePath.empty() ? (BaseDir / "zenserver" ZEN_EXE_SUFFIX_LITERAL) : m_ServerExecutablePath; const std::filesystem::path OutputPath = OpenConsole ? std::filesystem::path{} : std::filesystem::temp_directory_path() / ("zenserver_" + m_Name + ".log"); CreateProcOptions CreateOptions = {.WorkingDirectory = &CurrentDirectory, .Flags = CreationFlags, .StdoutFile = OutputPath}; @@ -799,8 +888,7 @@ ZenServerInstance::SpawnServer(int BasePort, std::string_view AdditionalServerAr const int ChildId = AssignName(); ExtendableStringBuilder<512> CommandLine; - - const bool IsTest = m_Env.IsTestEnvironment(); + const bool IsTest = m_Env.IsTestEnvironment(); if (IsTest) { @@ -835,10 +923,10 @@ ZenServerInstance::SpawnServer(int BasePort, std::string_view AdditionalServerAr m_BasePort = gsl::narrow_cast<uint16_t>(BasePort); } - if (!m_TestDir.empty()) + if (!m_DataDir.empty()) { CommandLine << " --data-dir "; - PathToUtf8(m_TestDir.c_str(), CommandLine); + PathToUtf8(m_DataDir.c_str(), CommandLine); } if (!AdditionalServerArgs.empty()) @@ -1028,10 +1116,10 @@ ZenServerInstance::GetBaseUri() const } void -ZenServerInstance::SetTestDir(std::filesystem::path TestDir) +ZenServerInstance::SetDataDir(std::filesystem::path TestDir) { ZEN_ASSERT(!m_Process.IsValid()); - m_TestDir = TestDir; + m_DataDir = TestDir; } bool |