aboutsummaryrefslogtreecommitdiff
path: root/src/zencompute
diff options
context:
space:
mode:
Diffstat (limited to 'src/zencompute')
-rw-r--r--src/zencompute/cloudmetadata.cpp18
-rw-r--r--src/zencompute/include/zencompute/cloudmetadata.h12
-rw-r--r--src/zencompute/include/zencompute/mockimds.h100
-rw-r--r--src/zencompute/testing/mockimds.cpp205
4 files changed, 6 insertions, 329 deletions
diff --git a/src/zencompute/cloudmetadata.cpp b/src/zencompute/cloudmetadata.cpp
index 65bac895f..eb4c05f9f 100644
--- a/src/zencompute/cloudmetadata.cpp
+++ b/src/zencompute/cloudmetadata.cpp
@@ -23,22 +23,6 @@ static constexpr std::string_view kImdsEndpoint = "http://169.254.169.254";
// is a local service on the hypervisor so 200ms is generous for actual cloud VMs.
static constexpr auto kImdsTimeout = std::chrono::milliseconds{200};
-std::string_view
-ToString(CloudProvider Provider)
-{
- switch (Provider)
- {
- case CloudProvider::AWS:
- return "AWS";
- case CloudProvider::Azure:
- return "Azure";
- case CloudProvider::GCP:
- return "GCP";
- default:
- return "None";
- }
-}
-
CloudMetadata::CloudMetadata(std::filesystem::path DataDir) : CloudMetadata(std::move(DataDir), std::string(kImdsEndpoint))
{
}
@@ -610,7 +594,7 @@ CloudMetadata::PollGCPTermination()
#if ZEN_WITH_TESTS
-# include <zencompute/mockimds.h>
+# include <zenutil/cloud/mockimds.h>
# include <zencore/filesystem.h>
# include <zencore/testing.h>
diff --git a/src/zencompute/include/zencompute/cloudmetadata.h b/src/zencompute/include/zencompute/cloudmetadata.h
index a5bc5a34d..3b9642ac3 100644
--- a/src/zencompute/include/zencompute/cloudmetadata.h
+++ b/src/zencompute/include/zencompute/cloudmetadata.h
@@ -2,6 +2,8 @@
#pragma once
+#include <zenutil/cloud/cloudprovider.h>
+
#include <zencore/compactbinarybuilder.h>
#include <zencore/logging.h>
#include <zencore/thread.h>
@@ -13,16 +15,6 @@
namespace zen::compute {
-enum class CloudProvider
-{
- None,
- AWS,
- Azure,
- GCP
-};
-
-std::string_view ToString(CloudProvider Provider);
-
/** Snapshot of detected cloud instance properties. */
struct CloudInstanceInfo
{
diff --git a/src/zencompute/include/zencompute/mockimds.h b/src/zencompute/include/zencompute/mockimds.h
index 521722e63..704306913 100644
--- a/src/zencompute/include/zencompute/mockimds.h
+++ b/src/zencompute/include/zencompute/mockimds.h
@@ -1,102 +1,6 @@
// Copyright Epic Games, Inc. All Rights Reserved.
+// Moved to zenutil — this header is kept for backward compatibility.
#pragma once
-#include <zencompute/cloudmetadata.h>
-#include <zenhttp/httpserver.h>
-
-#include <string>
-
-#if ZEN_WITH_TESTS
-
-namespace zen::compute {
-
-/**
- * Mock IMDS (Instance Metadata Service) for testing CloudMetadata.
- *
- * Implements an HttpService that responds to the same URL paths as the real
- * cloud provider metadata endpoints (AWS IMDSv2, Azure IMDS, GCP metadata).
- * Tests configure which provider is "active" and set the desired response
- * values, then pass the mock server's address as the ImdsEndpoint to the
- * CloudMetadata constructor.
- *
- * When a request arrives for a provider that is not the ActiveProvider, the
- * mock returns 404, causing CloudMetadata to write a sentinel file and move
- * on to the next provider — exactly like a failed probe on bare metal.
- *
- * All config fields are public and can be mutated between poll cycles to
- * simulate state changes (e.g. a spot interruption appearing mid-run).
- *
- * Usage:
- * MockImdsService Mock;
- * Mock.ActiveProvider = CloudProvider::AWS;
- * Mock.Aws.InstanceId = "i-test";
- * // ... stand up ASIO server, register Mock, create CloudMetadata with endpoint
- */
-class MockImdsService : public HttpService
-{
-public:
- /** AWS IMDSv2 response configuration. */
- struct AwsConfig
- {
- std::string Token = "mock-aws-token-v2";
- std::string InstanceId = "i-0123456789abcdef0";
- std::string AvailabilityZone = "us-east-1a";
- std::string LifeCycle = "on-demand"; // "spot" or "on-demand"
-
- // Empty string → endpoint returns 404 (instance not in an ASG).
- // Non-empty → returned as the response body. "InService" means healthy;
- // anything else (e.g. "Terminated:Wait") triggers termination detection.
- std::string AutoscalingState;
-
- // Empty string → endpoint returns 404 (no spot interruption).
- // Non-empty → returned as the response body, signalling a spot reclaim.
- std::string SpotAction;
- };
-
- /** Azure IMDS response configuration. */
- struct AzureConfig
- {
- std::string VmId = "vm-12345678-1234-1234-1234-123456789abc";
- std::string Location = "eastus";
- std::string Priority = "Regular"; // "Spot" or "Regular"
-
- // Empty → instance is not in a VM Scale Set (no autoscaling).
- std::string VmScaleSetName;
-
- // Empty → no scheduled events. Set to "Preempt", "Terminate", or
- // "Reboot" to simulate a termination-class event.
- std::string ScheduledEventType;
- std::string ScheduledEventStatus = "Scheduled";
- };
-
- /** GCP metadata response configuration. */
- struct GcpConfig
- {
- std::string InstanceId = "1234567890123456789";
- std::string Zone = "projects/123456/zones/us-central1-a";
- std::string Preemptible = "FALSE"; // "TRUE" or "FALSE"
- std::string MaintenanceEvent = "NONE"; // "NONE" or event description
- };
-
- /** Which provider's endpoints respond successfully.
- * Requests targeting other providers receive 404.
- */
- CloudProvider ActiveProvider = CloudProvider::None;
-
- AwsConfig Aws;
- AzureConfig Azure;
- GcpConfig Gcp;
-
- const char* BaseUri() const override;
- void HandleRequest(HttpServerRequest& Request) override;
-
-private:
- void HandleAwsRequest(HttpServerRequest& Request);
- void HandleAzureRequest(HttpServerRequest& Request);
- void HandleGcpRequest(HttpServerRequest& Request);
-};
-
-} // namespace zen::compute
-
-#endif // ZEN_WITH_TESTS
+#include <zenutil/cloud/mockimds.h>
diff --git a/src/zencompute/testing/mockimds.cpp b/src/zencompute/testing/mockimds.cpp
index dd09312df..5415f48f3 100644
--- a/src/zencompute/testing/mockimds.cpp
+++ b/src/zencompute/testing/mockimds.cpp
@@ -1,205 +1,2 @@
// Copyright Epic Games, Inc. All Rights Reserved.
-
-#include <zencompute/mockimds.h>
-
-#include <zencore/fmtutils.h>
-
-#if ZEN_WITH_TESTS
-
-namespace zen::compute {
-
-const char*
-MockImdsService::BaseUri() const
-{
- return "/";
-}
-
-void
-MockImdsService::HandleRequest(HttpServerRequest& Request)
-{
- std::string_view Uri = Request.RelativeUri();
-
- // AWS endpoints live under /latest/
- if (Uri.starts_with("latest/"))
- {
- if (ActiveProvider == CloudProvider::AWS)
- {
- HandleAwsRequest(Request);
- return;
- }
- Request.WriteResponse(HttpResponseCode::NotFound);
- return;
- }
-
- // Azure endpoints live under /metadata/
- if (Uri.starts_with("metadata/"))
- {
- if (ActiveProvider == CloudProvider::Azure)
- {
- HandleAzureRequest(Request);
- return;
- }
- Request.WriteResponse(HttpResponseCode::NotFound);
- return;
- }
-
- // GCP endpoints live under /computeMetadata/
- if (Uri.starts_with("computeMetadata/"))
- {
- if (ActiveProvider == CloudProvider::GCP)
- {
- HandleGcpRequest(Request);
- return;
- }
- Request.WriteResponse(HttpResponseCode::NotFound);
- return;
- }
-
- Request.WriteResponse(HttpResponseCode::NotFound);
-}
-
-// ---------------------------------------------------------------------------
-// AWS
-// ---------------------------------------------------------------------------
-
-void
-MockImdsService::HandleAwsRequest(HttpServerRequest& Request)
-{
- std::string_view Uri = Request.RelativeUri();
-
- // IMDSv2 token acquisition (PUT only)
- if (Uri == "latest/api/token" && Request.RequestVerb() == HttpVerb::kPut)
- {
- Request.WriteResponse(HttpResponseCode::OK, HttpContentType::kText, Aws.Token);
- return;
- }
-
- // Instance identity
- if (Uri == "latest/meta-data/instance-id")
- {
- Request.WriteResponse(HttpResponseCode::OK, HttpContentType::kText, Aws.InstanceId);
- return;
- }
-
- if (Uri == "latest/meta-data/placement/availability-zone")
- {
- Request.WriteResponse(HttpResponseCode::OK, HttpContentType::kText, Aws.AvailabilityZone);
- return;
- }
-
- if (Uri == "latest/meta-data/instance-life-cycle")
- {
- Request.WriteResponse(HttpResponseCode::OK, HttpContentType::kText, Aws.LifeCycle);
- return;
- }
-
- // Autoscaling lifecycle state — 404 when not in an ASG
- if (Uri == "latest/meta-data/autoscaling/target-lifecycle-state")
- {
- if (Aws.AutoscalingState.empty())
- {
- Request.WriteResponse(HttpResponseCode::NotFound);
- return;
- }
- Request.WriteResponse(HttpResponseCode::OK, HttpContentType::kText, Aws.AutoscalingState);
- return;
- }
-
- // Spot interruption notice — 404 when no interruption pending
- if (Uri == "latest/meta-data/spot/instance-action")
- {
- if (Aws.SpotAction.empty())
- {
- Request.WriteResponse(HttpResponseCode::NotFound);
- return;
- }
- Request.WriteResponse(HttpResponseCode::OK, HttpContentType::kText, Aws.SpotAction);
- return;
- }
-
- Request.WriteResponse(HttpResponseCode::NotFound);
-}
-
-// ---------------------------------------------------------------------------
-// Azure
-// ---------------------------------------------------------------------------
-
-void
-MockImdsService::HandleAzureRequest(HttpServerRequest& Request)
-{
- std::string_view Uri = Request.RelativeUri();
-
- // Instance metadata (single JSON document)
- if (Uri == "metadata/instance")
- {
- std::string Json = fmt::format(R"({{"compute":{{"vmId":"{}","location":"{}","priority":"{}","vmScaleSetName":"{}"}}}})",
- Azure.VmId,
- Azure.Location,
- Azure.Priority,
- Azure.VmScaleSetName);
-
- Request.WriteResponse(HttpResponseCode::OK, HttpContentType::kText, Json);
- return;
- }
-
- // Scheduled events for termination monitoring
- if (Uri == "metadata/scheduledevents")
- {
- std::string Json;
- if (Azure.ScheduledEventType.empty())
- {
- Json = R"({"Events":[]})";
- }
- else
- {
- Json = fmt::format(R"({{"Events":[{{"EventType":"{}","EventStatus":"{}"}}]}})",
- Azure.ScheduledEventType,
- Azure.ScheduledEventStatus);
- }
-
- Request.WriteResponse(HttpResponseCode::OK, HttpContentType::kText, Json);
- return;
- }
-
- Request.WriteResponse(HttpResponseCode::NotFound);
-}
-
-// ---------------------------------------------------------------------------
-// GCP
-// ---------------------------------------------------------------------------
-
-void
-MockImdsService::HandleGcpRequest(HttpServerRequest& Request)
-{
- std::string_view Uri = Request.RelativeUri();
-
- if (Uri == "computeMetadata/v1/instance/id")
- {
- Request.WriteResponse(HttpResponseCode::OK, HttpContentType::kText, Gcp.InstanceId);
- return;
- }
-
- if (Uri == "computeMetadata/v1/instance/zone")
- {
- Request.WriteResponse(HttpResponseCode::OK, HttpContentType::kText, Gcp.Zone);
- return;
- }
-
- if (Uri == "computeMetadata/v1/instance/scheduling/preemptible")
- {
- Request.WriteResponse(HttpResponseCode::OK, HttpContentType::kText, Gcp.Preemptible);
- return;
- }
-
- if (Uri == "computeMetadata/v1/instance/maintenance-event")
- {
- Request.WriteResponse(HttpResponseCode::OK, HttpContentType::kText, Gcp.MaintenanceEvent);
- return;
- }
-
- Request.WriteResponse(HttpResponseCode::NotFound);
-}
-
-} // namespace zen::compute
-
-#endif // ZEN_WITH_TESTS
+// Moved to zenutil/cloud/mockimds.cpp