aboutsummaryrefslogtreecommitdiff
path: root/src/zenserver-test/hub-tests.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/zenserver-test/hub-tests.cpp')
-rw-r--r--src/zenserver-test/hub-tests.cpp137
1 files changed, 134 insertions, 3 deletions
diff --git a/src/zenserver-test/hub-tests.cpp b/src/zenserver-test/hub-tests.cpp
index 11531e30f..9c1669256 100644
--- a/src/zenserver-test/hub-tests.cpp
+++ b/src/zenserver-test/hub-tests.cpp
@@ -19,6 +19,8 @@
# include <zenutil/zenserverprocess.h>
# include <zenhttp/httpclient.h>
# include <zenutil/consul.h>
+# include <zencore/thread.h>
+# include <zencore/timer.h>
namespace zen::tests::hub {
@@ -230,12 +232,33 @@ TEST_CASE("hub.lifecycle.children")
}
}
-TEST_CASE("hub.consul.lifecycle" * doctest::skip())
+static bool
+WaitForConsulService(consul::ConsulClient& Client, std::string_view ServiceId, bool ExpectedState, int TimeoutMs)
{
- zen::consul::ConsulProcess ConsulProc;
+ Stopwatch Timer;
+ uint64_t Index = 0;
+ while (Timer.GetElapsedTimeMs() < static_cast<uint64_t>(TimeoutMs))
+ {
+ uint64_t RemainingMs = static_cast<uint64_t>(TimeoutMs) - Timer.GetElapsedTimeMs();
+ int WaitSeconds = std::max(1, static_cast<int>(RemainingMs / 1000));
+ if (Client.WatchService(ServiceId, Index, WaitSeconds) == ExpectedState)
+ {
+ return true;
+ }
+ if (Index == 0)
+ {
+ Sleep(100); // error path only: avoid tight loop on persistent connection failure
+ }
+ }
+ return Client.HasService(ServiceId) == ExpectedState;
+}
+
+TEST_CASE("hub.consul.kv")
+{
+ consul::ConsulProcess ConsulProc;
ConsulProc.SpawnConsulAgent();
- zen::consul::ConsulClient Client("http://localhost:8500/");
+ consul::ConsulClient Client("http://localhost:8500/");
Client.SetKeyValue("zen/hub/testkey", "testvalue");
std::string RetrievedValue = Client.GetKeyValue("zen/hub/testkey");
@@ -246,6 +269,114 @@ TEST_CASE("hub.consul.lifecycle" * doctest::skip())
ConsulProc.StopConsulAgent();
}
+TEST_CASE("hub.consul.hub.registration")
+{
+ consul::ConsulProcess ConsulProc;
+ ConsulProc.SpawnConsulAgent();
+
+ ZenServerInstance Instance(TestEnv, ZenServerInstance::ServerMode::kHubServer);
+ const uint16_t PortNumber =
+ Instance.SpawnServerAndWaitUntilReady("--consul-endpoint=http://localhost:8500/ --instance-id=test-instance");
+ REQUIRE(PortNumber != 0);
+
+ consul::ConsulClient Client("http://localhost:8500/");
+
+ REQUIRE(WaitForConsulService(Client, "zen-hub-test-instance", true, 5000));
+
+ Instance.Shutdown();
+
+ CHECK(!Client.HasService("zen-hub-test-instance"));
+
+ ConsulProc.StopConsulAgent();
+}
+
+TEST_CASE("hub.consul.provision.registration")
+{
+ consul::ConsulProcess ConsulProc;
+ ConsulProc.SpawnConsulAgent();
+
+ ZenServerInstance Instance(TestEnv, ZenServerInstance::ServerMode::kHubServer);
+ const uint16_t PortNumber =
+ Instance.SpawnServerAndWaitUntilReady("--consul-endpoint=http://localhost:8500/ --instance-id=test-instance");
+ REQUIRE(PortNumber != 0);
+
+ consul::ConsulClient Client("http://localhost:8500/");
+
+ REQUIRE(WaitForConsulService(Client, "zen-hub-test-instance", true, 5000));
+
+ HttpClient HubClient(Instance.GetBaseUri() + "/hub/");
+
+ HttpClient::Response Result = HubClient.Post("modules/testmod/provision");
+ REQUIRE(Result);
+
+ CHECK(Client.HasService("testmod"));
+ {
+ const uint16_t ModulePort = Result.AsObject()["port"].AsUInt16(0);
+ REQUIRE(ModulePort != 0);
+
+ std::string JsonError;
+ CbFieldIterator ServicesRoot = LoadCompactBinaryFromJson(Client.GetAgentServicesJson(), JsonError);
+ REQUIRE(JsonError.empty());
+
+ CbObjectView ServicesMap;
+ for (CbFieldView F : ServicesRoot)
+ {
+ if (F.IsObject())
+ {
+ ServicesMap = F.AsObjectView();
+ }
+ }
+ REQUIRE(ServicesMap);
+
+ // Verify fields registered by OnProvisioned
+ {
+ CbObjectView ModService = ServicesMap["testmod"].AsObjectView();
+ CHECK_EQ(ModService["ID"sv].AsString(), "testmod"sv);
+ CHECK_EQ(ModService["Service"sv].AsString(), "zen-storage"sv);
+ CHECK_EQ(ModService["Port"sv].AsDouble(0), double(ModulePort));
+ bool FoundModuleTag = false;
+ bool FoundHubTag = false;
+ bool FoundVersionTag = false;
+ for (CbFieldView Tag : ModService["Tags"].AsArrayView())
+ {
+ std::string_view TagStr = Tag.AsString();
+ if (TagStr == "module:testmod"sv)
+ {
+ FoundModuleTag = true;
+ }
+ else if (TagStr == "zen-hub:zen-hub-test-instance"sv)
+ {
+ FoundHubTag = true;
+ }
+ else if (TagStr.substr(0, 8) == "version:"sv)
+ {
+ FoundVersionTag = true;
+ }
+ }
+ CHECK(FoundModuleTag);
+ CHECK(FoundHubTag);
+ CHECK(FoundVersionTag);
+ }
+
+ // Verify fields registered by InitializeConsulRegistration
+ {
+ CbObjectView HubService = ServicesMap["zen-hub-test-instance"].AsObjectView();
+ CHECK_EQ(HubService["ID"sv].AsString(), "zen-hub-test-instance"sv);
+ CHECK_EQ(HubService["Service"sv].AsString(), "zen-hub"sv);
+ CHECK_EQ(HubService["Port"sv].AsDouble(0), double(PortNumber));
+ }
+ }
+
+ Result = HubClient.Post("modules/testmod/deprovision");
+ REQUIRE(Result);
+
+ CHECK(!Client.HasService("testmod"));
+
+ Instance.Shutdown();
+
+ ConsulProc.StopConsulAgent();
+}
+
TEST_SUITE_END();
} // namespace zen::tests::hub