aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md20
-rw-r--r--src/zen/cmds/service_cmd.cpp1
-rw-r--r--src/zenserver-test/cache-tests.cpp20
-rw-r--r--src/zenserver-test/projectstore-tests.cpp2
-rw-r--r--src/zenserver-test/workspace-tests.cpp10
-rw-r--r--src/zenserver-test/zenserver-test.cpp20
-rw-r--r--src/zenserver-test/zenserver-test.h4
-rw-r--r--src/zenutil/include/zenutil/zenserverprocess.h35
-rw-r--r--src/zenutil/zenserverprocess.cpp118
9 files changed, 177 insertions, 53 deletions
diff --git a/README.md b/README.md
index de65348a2..0bc708ff6 100644
--- a/README.md
+++ b/README.md
@@ -51,13 +51,14 @@ from a Command Prompt window or a Terminal instance
### Building with xmake on the command line
-* configure xmake: `xmake config -m debug|release -a x64`
+* configure xmake: `xmake config -m debug`
* build zenserver: `xmake build zenserver`
* build all targets at once: `xmake`
-Compiled binaries are located in the `build` directory
+Compiled binaries end up in the `build` directory. xmake uses the `.xmake` directory to store
+project specific state. For more tips on working with xmake, see [xmake notes](docs/xmake.md)
-#### Installing pre-commit (optional)
+### Installing pre-commit (optional but recommended)
This is necessary to run pre-commit locally, which is useful in particular to run clang-format prior to
commit.
@@ -65,7 +66,12 @@ commit.
* Make sure python3 is installed. Version 3.11 or later should work
* You can install using `winget install python3`
* Run `pip install pre-commit==3.2.0` (later versions may or may not work)
-* If you want the pre-commit steps to be run at commit time you can run `pre-commit install` within your local repo.
+* If you want the pre-commit steps to be run at commit time (which is recommended) you can
+ run `pre-commit install` within your local repo.
+
+Once you have pre-commit installed, it's convenient to use the provided xmake task to trigger it
+manually to apply clang-format rules. You can do this by running `xmake precommit` on the command
+line.
## Building on Linux
@@ -163,7 +169,11 @@ brew install pkgconfig
# Implementation Notes
* The implementation currently depends only on a few libraries including the C++ standard library
-* It uses exceptions for certain types of unexpected error conditions
+ * In a few places we also use EASTL, mostly to eliminate memory allocations by using the excellent
+ `eastl::fixed_vector` et al containers which contain an embedded memory buffer which is used
+ until capacity is exceeded at which point it switches to the heap
+* It uses exceptions for certain types of unexpected error conditions. Exceptions should not be
+ used for other flow control.
# Contributing Code
diff --git a/src/zen/cmds/service_cmd.cpp b/src/zen/cmds/service_cmd.cpp
index aa6bfb436..a781dc340 100644
--- a/src/zen/cmds/service_cmd.cpp
+++ b/src/zen/cmds/service_cmd.cpp
@@ -13,6 +13,7 @@
# include <zencore/windows.h>
# include <shellapi.h>
# include <Shlwapi.h>
+# pragma comment(lib, "Shlwapi.lib")
#endif
#if ZEN_PLATFORM_LINUX || ZEN_PLATFORM_MAC
diff --git a/src/zenserver-test/cache-tests.cpp b/src/zenserver-test/cache-tests.cpp
index 854590987..0272d3797 100644
--- a/src/zenserver-test/cache-tests.cpp
+++ b/src/zenserver-test/cache-tests.cpp
@@ -35,7 +35,7 @@ TEST_CASE("zcache.basic")
{
ZenServerInstance Instance1(TestEnv);
- Instance1.SetTestDir(TestDir);
+ Instance1.SetDataDir(TestDir);
const uint16_t PortNumber = Instance1.SpawnServerAndWaitUntilReady();
const std::string BaseUri = fmt::format("http://localhost:{}/z$", PortNumber);
@@ -91,7 +91,7 @@ TEST_CASE("zcache.basic")
{
ZenServerInstance Instance1(TestEnv);
- Instance1.SetTestDir(TestDir);
+ Instance1.SetDataDir(TestDir);
const uint16_t PortNumber = Instance1.SpawnServerAndWaitUntilReady();
const std::string BaseUri = fmt::format("http://localhost:{}/z$", PortNumber);
@@ -167,7 +167,7 @@ TEST_CASE("zcache.cbpackage")
std::filesystem::path TestDir = TestEnv.CreateNewTestDir();
ZenServerInstance Instance1(TestEnv);
- Instance1.SetTestDir(TestDir);
+ Instance1.SetDataDir(TestDir);
const uint16_t PortNumber = Instance1.SpawnServerAndWaitUntilReady();
const std::string BaseUri = fmt::format("http://localhost:{}/z$", PortNumber);
@@ -203,11 +203,11 @@ TEST_CASE("zcache.cbpackage")
std::filesystem::path RemoteDataDir = TestEnv.CreateNewTestDir();
ZenServerInstance RemoteInstance(TestEnv);
- RemoteInstance.SetTestDir(RemoteDataDir);
+ RemoteInstance.SetDataDir(RemoteDataDir);
const uint16_t RemotePortNumber = RemoteInstance.SpawnServerAndWaitUntilReady();
ZenServerInstance LocalInstance(TestEnv);
- LocalInstance.SetTestDir(LocalDataDir);
+ LocalInstance.SetDataDir(LocalDataDir);
LocalInstance.SpawnServer(TestEnv.GetNewPortNumber(),
fmt::format("--upstream-thread-count=0 --upstream-zen-url=http://localhost:{}", RemotePortNumber));
const uint16_t LocalPortNumber = LocalInstance.WaitUntilReady();
@@ -261,11 +261,11 @@ TEST_CASE("zcache.cbpackage")
std::filesystem::path RemoteDataDir = TestEnv.CreateNewTestDir();
ZenServerInstance RemoteInstance(TestEnv);
- RemoteInstance.SetTestDir(RemoteDataDir);
+ RemoteInstance.SetDataDir(RemoteDataDir);
const uint16_t RemotePortNumber = RemoteInstance.SpawnServerAndWaitUntilReady();
ZenServerInstance LocalInstance(TestEnv);
- LocalInstance.SetTestDir(LocalDataDir);
+ LocalInstance.SetDataDir(LocalDataDir);
LocalInstance.SpawnServer(TestEnv.GetNewPortNumber(),
fmt::format("--upstream-thread-count=0 --upstream-zen-url=http://localhost:{}", RemotePortNumber));
const uint16_t LocalPortNumber = LocalInstance.WaitUntilReady();
@@ -756,7 +756,7 @@ TEST_CASE("zcache.rpc")
std::filesystem::path TestDir = TestEnv.CreateNewTestDir();
ZenServerInstance Inst(TestEnv);
- Inst.SetTestDir(TestDir);
+ Inst.SetDataDir(TestDir);
const uint16_t BasePort = Inst.SpawnServerAndWaitUntilReady();
const std::string BaseUri = fmt::format("http://localhost:{}/z$", BasePort);
@@ -786,7 +786,7 @@ TEST_CASE("zcache.rpc")
std::filesystem::path TestDir = TestEnv.CreateNewTestDir();
ZenServerInstance Inst(TestEnv);
- Inst.SetTestDir(TestDir);
+ Inst.SetDataDir(TestDir);
const uint16_t BasePort = Inst.SpawnServerAndWaitUntilReady();
const std::string BaseUri = fmt::format("http://localhost:{}/z$", BasePort);
@@ -1239,7 +1239,7 @@ TEST_CASE("zcache.rpc")
std::filesystem::path TestDir = TestEnv.CreateNewTestDir();
ZenServerInstance Inst(TestEnv);
- Inst.SetTestDir(TestDir);
+ Inst.SetDataDir(TestDir);
const uint16_t BasePort = Inst.SpawnServerAndWaitUntilReady();
const std::string BaseUri = fmt::format("http://localhost:{}/z$", BasePort);
diff --git a/src/zenserver-test/projectstore-tests.cpp b/src/zenserver-test/projectstore-tests.cpp
index c8c96dbbb..735aef159 100644
--- a/src/zenserver-test/projectstore-tests.cpp
+++ b/src/zenserver-test/projectstore-tests.cpp
@@ -34,7 +34,7 @@ TEST_CASE("project.basic")
std::filesystem::path TestDir = TestEnv.CreateNewTestDir();
ZenServerInstance Instance1(TestEnv);
- Instance1.SetTestDir(TestDir);
+ Instance1.SetDataDir(TestDir);
const uint16_t PortNumber = Instance1.SpawnServerAndWaitUntilReady();
diff --git a/src/zenserver-test/workspace-tests.cpp b/src/zenserver-test/workspace-tests.cpp
index f299b6dcf..7595d790a 100644
--- a/src/zenserver-test/workspace-tests.cpp
+++ b/src/zenserver-test/workspace-tests.cpp
@@ -81,7 +81,7 @@ TEST_CASE("workspaces.create")
std::filesystem::path TestDir = TestEnv.CreateNewTestDir();
ZenServerInstance Instance(TestEnv);
- Instance.SetTestDir(TestDir);
+ Instance.SetDataDir(TestDir);
const uint16_t PortNumber = Instance.SpawnServerAndWaitUntilReady(
fmt::format("--workspaces-enabled --workspaces-allow-changes --system-dir {}", SystemRootPath));
CHECK(PortNumber != 0);
@@ -214,7 +214,7 @@ TEST_CASE("workspaces.restricted")
std::filesystem::path TestDir = TestEnv.CreateNewTestDir();
ZenServerInstance Instance(TestEnv);
- Instance.SetTestDir(TestDir);
+ Instance.SetDataDir(TestDir);
const uint16_t PortNumber = Instance.SpawnServerAndWaitUntilReady(fmt::format("--workspaces-enabled --system-dir {}", SystemRootPath));
CHECK(PortNumber != 0);
@@ -319,7 +319,7 @@ TEST_CASE("workspaces.lifetimes")
{
std::filesystem::path TestDir = TestEnv.CreateNewTestDir();
ZenServerInstance Instance(TestEnv);
- Instance.SetTestDir(TestDir);
+ Instance.SetDataDir(TestDir);
const uint16_t PortNumber = Instance.SpawnServerAndWaitUntilReady(
fmt::format("--workspaces-enabled --workspaces-allow-changes --system-dir {}", SystemRootPath));
CHECK(PortNumber != 0);
@@ -343,7 +343,7 @@ TEST_CASE("workspaces.lifetimes")
{
std::filesystem::path TestDir = TestEnv.CreateNewTestDir();
ZenServerInstance Instance(TestEnv);
- Instance.SetTestDir(TestDir);
+ Instance.SetDataDir(TestDir);
const uint16_t PortNumber =
Instance.SpawnServerAndWaitUntilReady(fmt::format("--workspaces-enabled --system-dir {}", SystemRootPath));
CHECK(PortNumber != 0);
@@ -362,7 +362,7 @@ TEST_CASE("workspaces.lifetimes")
{
std::filesystem::path TestDir = TestEnv.CreateNewTestDir();
ZenServerInstance Instance(TestEnv);
- Instance.SetTestDir(TestDir);
+ Instance.SetDataDir(TestDir);
const uint16_t PortNumber =
Instance.SpawnServerAndWaitUntilReady(fmt::format("--workspaces-enabled --system-dir {}", SystemRootPath));
CHECK(PortNumber != 0);
diff --git a/src/zenserver-test/zenserver-test.cpp b/src/zenserver-test/zenserver-test.cpp
index 418fc7978..6f207b184 100644
--- a/src/zenserver-test/zenserver-test.cpp
+++ b/src/zenserver-test/zenserver-test.cpp
@@ -122,7 +122,7 @@ TEST_CASE("default.single")
{
std::filesystem::path TestDir = TestEnv.CreateNewTestDir();
ZenServerInstance Instance(TestEnv);
- Instance.SetTestDir(TestDir);
+ Instance.SetDataDir(TestDir);
const uint16_t PortNumber = Instance.SpawnServerAndWaitUntilReady();
std::atomic<uint64_t> RequestCount{0};
@@ -172,7 +172,7 @@ TEST_CASE("default.loopback")
std::filesystem::path TestDir = TestEnv.CreateNewTestDir();
ZenServerInstance Instance(TestEnv);
- Instance.SetTestDir(TestDir);
+ Instance.SetDataDir(TestDir);
const uint16_t PortNumber = Instance.SpawnServerAndWaitUntilReady("--http-forceloopback");
ZEN_INFO("Running loopback server test...");
@@ -200,12 +200,12 @@ TEST_CASE("multi.basic")
{
ZenServerInstance Instance1(TestEnv);
std::filesystem::path TestDir1 = TestEnv.CreateNewTestDir();
- Instance1.SetTestDir(TestDir1);
+ Instance1.SetDataDir(TestDir1);
Instance1.SpawnServer();
ZenServerInstance Instance2(TestEnv);
std::filesystem::path TestDir2 = TestEnv.CreateNewTestDir();
- Instance2.SetTestDir(TestDir2);
+ Instance2.SetDataDir(TestDir2);
Instance2.SpawnServer();
ZEN_INFO("Waiting...");
@@ -336,14 +336,14 @@ TEST_CASE("lifetime.owner")
ZenServerInstance Zen1(TestEnv);
std::filesystem::path TestDir1 = TestEnv.CreateNewTestDir();
- Zen1.SetTestDir(TestDir1);
+ Zen1.SetDataDir(TestDir1);
Zen1.SpawnServer(PortNumber);
Zen1.WaitUntilReady();
Zen1.Detach();
ZenServerInstance Zen2(TestEnv);
std::filesystem::path TestDir2 = TestEnv.CreateNewTestDir();
- Zen2.SetTestDir(TestDir2);
+ Zen2.SetDataDir(TestDir2);
Zen2.SpawnServer(PortNumber);
Zen2.WaitUntilReady();
Zen2.Detach();
@@ -362,24 +362,24 @@ TEST_CASE("lifetime.owner.2")
std::filesystem::path TestDir2 = TestEnv.CreateNewTestDir();
ZenServerInstance Zen1(TestEnv);
- Zen1.SetTestDir(TestDir1);
+ Zen1.SetDataDir(TestDir1);
Zen1.SpawnServer(PortNumber);
Zen1.WaitUntilReady();
ZenServerInstance Zen2(TestEnv);
- Zen2.SetTestDir(TestDir2);
+ Zen2.SetDataDir(TestDir2);
Zen2.SetOwnerPid(Zen1.GetPid());
Zen2.SpawnServer(PortNumber + 1);
Zen2.Detach();
ZenServerInstance Zen3(TestEnv);
- Zen3.SetTestDir(TestDir2);
+ Zen3.SetDataDir(TestDir2);
Zen3.SetOwnerPid(Zen1.GetPid());
Zen3.SpawnServer(PortNumber + 1);
Zen3.Detach();
ZenServerInstance Zen4(TestEnv);
- Zen4.SetTestDir(TestDir2);
+ Zen4.SetDataDir(TestDir2);
Zen4.SetOwnerPid(Zen1.GetPid());
Zen4.SpawnServer(PortNumber + 1);
Zen4.Detach();
diff --git a/src/zenserver-test/zenserver-test.h b/src/zenserver-test/zenserver-test.h
index e7cee3f94..8d83285e6 100644
--- a/src/zenserver-test/zenserver-test.h
+++ b/src/zenserver-test/zenserver-test.h
@@ -82,7 +82,7 @@ namespace utils {
void Spawn(ZenServerInstance& Inst)
{
- Inst.SetTestDir(DataDir);
+ Inst.SetDataDir(DataDir);
Inst.SpawnServer(Port, Args);
const uint16_t InstancePort = Inst.WaitUntilReady();
CHECK_MESSAGE(InstancePort != 0, Inst.GetLogOutput());
@@ -163,7 +163,7 @@ public:
{
auto& Instance = m_Instances[i];
Instance = std::make_unique<ZenServerInstance>(TestEnv);
- Instance->SetTestDir(TestEnv.CreateNewTestDir());
+ Instance->SetDataDir(TestEnv.CreateNewTestDir());
}
for (int i = 0; i < m_ServerCount; ++i)
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/zenserverprocess.cpp b/src/zenutil/zenserverprocess.cpp
index 6a93f0c63..b56df400d 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()
@@ -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