From 8c5fd3f89a5cff209d8d5b590b7a2dc9be826cad Mon Sep 17 00:00:00 2001 From: InderdeepBajwa Date: Sat, 25 Apr 2026 07:29:36 -0400 Subject: [PATCH 1/2] feat: add reason-code hygiene registry Adds a map-based registry of known API-facing reason codes to the schema package. This improves observability hygiene by ensuring emitted reason codes in responses use allowed prefixes and match registered constants. --- .../internal/domain/validate_launch_test.go | 62 +++++++++++++++ .../pkg/schema/constants.go | 16 +++- schedune-control-plane/pkg/schema/registry.go | 79 +++++++++++++++++++ .../pkg/schema/registry_test.go | 51 ++++++++++++ 4 files changed, 204 insertions(+), 4 deletions(-) create mode 100644 schedune-control-plane/pkg/schema/registry.go create mode 100644 schedune-control-plane/pkg/schema/registry_test.go diff --git a/schedune-control-plane/internal/domain/validate_launch_test.go b/schedune-control-plane/internal/domain/validate_launch_test.go index 1369d6b..3ff24f3 100644 --- a/schedune-control-plane/internal/domain/validate_launch_test.go +++ b/schedune-control-plane/internal/domain/validate_launch_test.go @@ -5,6 +5,7 @@ import ( "testing" "time" + "github.com/TechnologyTailors/Schedune/schedune-control-plane/pkg/schema" "github.com/TechnologyTailors/Schedune/schedune-control-plane/pkg/schema/launch" ) @@ -606,3 +607,64 @@ func TestValidateLaunch_SecurityContextRequiresNamespaces(t *testing.T) { t.Errorf("expected validation to pass even when namespaces capability is missing, because dropping capabilities does not require full namespace support, got false: %v", result.BlockingReasonCodes) } } + +func TestValidateLaunch_ReasonCodeRegistryHygiene(t *testing.T) { + // Pick a few representative fixtures that test different validation failure modes + fixtures := []string{ + "cloudhypervisor_binary_missing.json", + "firecracker_partial_fail.json", + "missing_kvm_x86.json", + "missing_qemu_binary.json", + "healthy_unsupported_compatibility.json", + "healthy_x86_kvm_openable.json", + "stale_telemetry.json", + } + + for _, fname := range fixtures { + env := readFixture(t, fname) + node := ProjectEnvelope(env) + + spec := launch.LaunchSpec{ + SchemaVersion: "v1alpha1", + WorkloadID: "wl-test", + TenantID: "tenant-1", + NodeID: node.ID, + RuntimeClass: "VirtualMachine", + Architecture: "x86_64", + LaunchMode: "DryRun", + Vcpu: 2, + MemoryMB: 1024, + } + + res := ValidateLaunch(spec, node) + + for _, code := range res.BlockingReasonCodes { + if !schema.IsKnownReasonCode(code) { + t.Errorf("fixture %s produced unregistered blocking reason code: %q", fname, code) + } + } + + for _, code := range res.Warnings { + if !schema.IsKnownReasonCode(code) { + t.Errorf("fixture %s produced unregistered warning reason code: %q", fname, code) + } + } + + for _, reason := range res.RejectedBackends { + // Backend rejection reasons can contain capabilities inside them, + // but we know they are usually formatted as REASON_CODE or REASON_CODE [CAPABILITY_CODE] + // Let's parse it out simply or just ensure if it's an exact code, it is registered. + // For simplicity, we just check if any registered code is a substring, + // or if we can extract it. + words := strings.Split(reason, " ") + for _, w := range words { + w = strings.Trim(w, "[]") + if strings.HasPrefix(w, "ERR_") || strings.HasPrefix(w, "CAP_") { + if !schema.IsKnownReasonCode(w) { + t.Errorf("fixture %s produced unregistered backend rejection code in message %q: %q", fname, reason, w) + } + } + } + } + } +} diff --git a/schedune-control-plane/pkg/schema/constants.go b/schedune-control-plane/pkg/schema/constants.go index 7655d3c..92e5050 100644 --- a/schedune-control-plane/pkg/schema/constants.go +++ b/schedune-control-plane/pkg/schema/constants.go @@ -112,10 +112,13 @@ const ( ReasonErrTermSignalFailed = "ERR_TERM_SIGNAL_FAILED" // Readiness / Reconciliation - ReasonErrReadyProbeFailed = "ERR_READY_PROBE_FAILED" - ReasonErrReadyTimeout = "ERR_READY_TIMEOUT" - ReasonErrReconcileProcessMissing = "ERR_RECONCILE_PROCESS_MISSING" - ReasonErrReconcileStatusUnreadable = "ERR_RECONCILE_STATUS_UNREADABLE" + ReasonErrReadyProbeFailed = "ERR_READY_PROBE_FAILED" + ReasonErrReadyTimeout = "ERR_READY_TIMEOUT" + ReasonErrReadyQemuSocketTimeout = "ERR_READY_QEMU_SOCKET_TIMEOUT" + ReasonErrReadyCloudHypervisorSocketTimeout = "ERR_READY_CLOUDHYPERVISOR_SOCKET_TIMEOUT" + ReasonErrReadyBackendUnsupported = "ERR_READY_BACKEND_UNSUPPORTED" + ReasonErrReconcileProcessMissing = "ERR_RECONCILE_PROCESS_MISSING" + ReasonErrReconcileStatusUnreadable = "ERR_RECONCILE_STATUS_UNREADABLE" // Recovery ReasonErrRecoveryExecutionMissing = "ERR_RECOVERY_EXECUTION_MISSING" @@ -124,4 +127,9 @@ const ( ReasonErrRecoveryStaleHandle = "ERR_RECOVERY_STALE_HANDLE" ReasonRecoveryConfirmed = "RECOVERY_CONFIRMED" ReasonRecoveryTerminatedMissing = "RECOVERY_TERMINATED_MISSING" + + // Orphans + ReasonErrOrphanPossibleScheduneProcess = "ERR_ORPHAN_POSSIBLE_SCHEDUNE_PROCESS" + ReasonErrOrphanStaleArtifactState = "ERR_ORPHAN_STALE_ARTIFACT_STATE" + ReasonErrOrphanUnmanagedBackendProcess = "ERR_ORPHAN_UNMANAGED_BACKEND_PROCESS" ) diff --git a/schedune-control-plane/pkg/schema/registry.go b/schedune-control-plane/pkg/schema/registry.go new file mode 100644 index 0000000..4481f71 --- /dev/null +++ b/schedune-control-plane/pkg/schema/registry.go @@ -0,0 +1,79 @@ +package schema + +var knownReasonCodes = map[string]struct{}{ + ReasonCapKvmOpenable: {}, + ReasonCapKvmMissing: {}, + ReasonCapKvmNotOpenablePerms: {}, + ReasonCapQemuBinaryPresent: {}, + ReasonCapQemuBinaryMissing: {}, + ReasonCapQemuUnsupportedArch: {}, + ReasonCapCloudHypervisorBinaryPresent: {}, + ReasonCapCloudHypervisorBinaryMissing: {}, + ReasonCapCloudHypervisorReady: {}, + ReasonCapCloudHypervisorPrereqsMissing: {}, + ReasonCapFirecrackerBinaryPresent: {}, + ReasonCapFirecrackerBinaryMissing: {}, + ReasonCapFirecrackerTunReady: {}, + ReasonCapFirecrackerTunMissing: {}, + ReasonCapFirecrackerCgroupsReady: {}, + ReasonCapFirecrackerCgroupsMissing: {}, + ReasonCapFirecrackerReady: {}, + ReasonCapFirecrackerPrereqsMissing: {}, + ReasonRejectArchitectureMismatch: {}, + ReasonRejectCompatibilityClassMismatch: {}, + ReasonRejectMissingKVM: {}, + ReasonRejectMissingTPM: {}, + ReasonRejectNodeUnhealthy: {}, + ReasonRejectTelemetryStale: {}, + ReasonRejectForbiddenConstraintPrefix: {}, + ReasonErrLaunchArchMismatch: {}, + ReasonErrLaunchBackendNotSupported: {}, + ReasonErrLaunchMissingArtifact: {}, + ReasonErrLaunchInvalidStorageFormat: {}, + ReasonErrLaunchInvalidFirecrackerArtifactModel: {}, + ReasonErrLaunchMissingCapabilityCloudHypervisor: {}, + ReasonErrLaunchMissingCapabilityChBinary: {}, + ReasonErrLaunchMissingCapabilityFcBinary: {}, + ReasonErrLaunchMissingCapabilityFcTun: {}, + ReasonErrLaunchMissingCapabilityFcCgroups: {}, + ReasonErrLaunchMissingCapabilityKvmQemu: {}, + ReasonErrLaunchMissingCapabilityQemuBinary: {}, + ReasonErrLaunchMissingCapabilitySeccomp: {}, + ReasonErrLaunchMissingCapabilityNamespaces: {}, + ReasonWarnDeprecatedImageReference: {}, + ReasonWarnDeprecatedNetworkAttachments: {}, + ReasonErrPreparationFailed: {}, + ReasonErrNodeNotFound: {}, + ReasonErrValidationFailed: {}, + ReasonErrExecRuntimeSpawnFailed: {}, + ReasonErrExecRuntimeCrashed: {}, + ReasonErrExecRuntimeExitedEarly: {}, + ReasonErrTermSignalFailed: {}, + ReasonErrReadyProbeFailed: {}, + ReasonErrReadyTimeout: {}, + ReasonErrReadyQemuSocketTimeout: {}, + ReasonErrReadyCloudHypervisorSocketTimeout: {}, + ReasonErrReadyBackendUnsupported: {}, + ReasonErrReconcileProcessMissing: {}, + ReasonErrReconcileStatusUnreadable: {}, + ReasonErrRecoveryExecutionMissing: {}, + ReasonErrRecoveryReassociationAmbiguous: {}, + ReasonErrRecoveryRehydrateFailed: {}, + ReasonErrRecoveryStaleHandle: {}, + ReasonRecoveryConfirmed: {}, + ReasonRecoveryTerminatedMissing: {}, + ReasonErrOrphanPossibleScheduneProcess: {}, + ReasonErrOrphanStaleArtifactState: {}, + ReasonErrOrphanUnmanagedBackendProcess: {}, +} + +// KnownReasonCodes returns a map of all registered reason codes. +func KnownReasonCodes() map[string]struct{} { + return knownReasonCodes +} + +// IsKnownReasonCode checks if a given reason code is registered. +func IsKnownReasonCode(code string) bool { + _, exists := knownReasonCodes[code] + return exists +} diff --git a/schedune-control-plane/pkg/schema/registry_test.go b/schedune-control-plane/pkg/schema/registry_test.go new file mode 100644 index 0000000..df42dba --- /dev/null +++ b/schedune-control-plane/pkg/schema/registry_test.go @@ -0,0 +1,51 @@ +package schema_test + +import ( + "strings" + "testing" + + "github.com/TechnologyTailors/Schedune/schedune-control-plane/pkg/schema" +) + +func TestReasonCodeRegistry_Constraints(t *testing.T) { + codes := schema.KnownReasonCodes() + + allowedPrefixes := []string{"CAP_", "REJECT_", "ERR_", "WARN_", "RECOVERY_"} + + for code := range codes { + if code == "" { + t.Errorf("found empty reason code") + } + + hasPrefix := false + for _, prefix := range allowedPrefixes { + if strings.HasPrefix(code, prefix) { + hasPrefix = true + break + } + } + + if !hasPrefix { + t.Errorf("reason code %q does not start with an allowed prefix: %v", code, allowedPrefixes) + } + } +} + +func TestReasonCodeRegistry_RepresentativeCodes(t *testing.T) { + // Verify representative lifecycle/readiness/recovery codes + expectedCodes := []string{ + schema.ReasonErrLaunchArchMismatch, + schema.ReasonErrLaunchMissingCapabilitySeccomp, + schema.ReasonRejectArchitectureMismatch, + schema.ReasonRecoveryConfirmed, + schema.ReasonErrReadyProbeFailed, + schema.ReasonErrReconcileProcessMissing, + schema.ReasonErrExecRuntimeCrashed, + } + + for _, expected := range expectedCodes { + if !schema.IsKnownReasonCode(expected) { + t.Errorf("expected representative code %q to be registered", expected) + } + } +} From 0884b1fc9ae056baddcbf39e9d5e325e1b636be5 Mon Sep 17 00:00:00 2001 From: Inderdeep Bajwa Date: Sat, 25 Apr 2026 17:19:10 -0400 Subject: [PATCH 2/2] Fix reason-code registry hygiene tests and immutability Signed-off-by: Inderdeep Bajwa --- schedune-agent/src/fixtures_test.rs | 26 ++++++++++++----- .../internal/domain/projector_test.go | 8 ++--- .../internal/domain/validate_launch_test.go | 29 ++++++++++++------- schedune-control-plane/pkg/schema/registry.go | 6 +++- .../pkg/schema/registry_test.go | 19 ++++++++++++ .../cloudhypervisor_binary_missing.json | 4 +-- .../fixtures/cloudhypervisor_ready_arm.json | 4 +-- .../fixtures/firecracker_cgroups_missing.json | 4 +-- testdata/fixtures/firecracker_host_ready.json | 4 +-- .../fixtures/firecracker_partial_fail.json | 6 ++-- .../fixtures/firecracker_tun_missing.json | 4 +-- testdata/fixtures/healthy_arm_production.json | 6 ++-- .../healthy_unsupported_compatibility.json | 6 ++-- .../fixtures/healthy_x86_kvm_openable.json | 6 ++-- .../fixtures/kvm_exists_not_openable.json | 6 ++-- testdata/fixtures/missing_kvm_x86.json | 6 ++-- testdata/fixtures/missing_qemu_binary.json | 4 +-- testdata/fixtures/missing_seccomp.json | 4 +-- testdata/fixtures/stale_telemetry.json | 6 ++-- 19 files changed, 100 insertions(+), 58 deletions(-) diff --git a/schedune-agent/src/fixtures_test.rs b/schedune-agent/src/fixtures_test.rs index 14edc36..7b654c5 100644 --- a/schedune-agent/src/fixtures_test.rs +++ b/schedune-agent/src/fixtures_test.rs @@ -15,7 +15,17 @@ mod tests { fs::create_dir_all(&path).unwrap(); path.push(name); - let json = serde_json::to_string_pretty(envelope).unwrap(); + let json_temp = serde_json::to_string(envelope).unwrap(); + let mut cloned: SchedulerEnvelope = serde_json::from_str(&json_temp).unwrap(); + + let hash = name.bytes().fold(0u64, |acc, b| acc.wrapping_add(b as u64)); + cloned.collection_id = format!("11111111-2222-3333-4444-{:012x}", hash); + if cloned.timestamp_sec > 1700000000 { + cloned.timestamp_sec = 1777086729; + } + + let mut json = serde_json::to_string_pretty(&cloned).unwrap(); + json.push('\n'); fs::write(path, json).unwrap(); } @@ -45,7 +55,7 @@ mod tests { feature: "kvm_vm_launch".to_string(), state: SupportState::Supported, provenance: Provenance::Observed, - reason_code: Some("KVM_OPENABLE".to_string()), + reason_code: Some("CAP_KVM_OPENABLE".to_string()), version: None, observed_at_sec: 1776978000, stale_after_sec: Some(1776978300), @@ -139,7 +149,7 @@ mod tests { feature: "kvm_vm_launch".to_string(), state: SupportState::Unsupported, provenance: Provenance::Observed, - reason_code: Some("KVM_MISSING".to_string()), + reason_code: Some("CAP_KVM_MISSING".to_string()), version: None, observed_at_sec: 1776978000, stale_after_sec: Some(1776978300), @@ -224,7 +234,7 @@ mod tests { feature: "kvm_vm_launch".to_string(), state: SupportState::Supported, provenance: Provenance::Observed, - reason_code: Some("KVM_OPENABLE".to_string()), + reason_code: Some("CAP_KVM_OPENABLE".to_string()), version: None, observed_at_sec: 1000000000, // Very old stale_after_sec: Some(1000000300), @@ -301,7 +311,7 @@ mod tests { feature: "kvm_vm_launch".to_string(), state: SupportState::Supported, provenance: Provenance::Observed, - reason_code: Some("KVM_OPENABLE".to_string()), + reason_code: Some("CAP_KVM_OPENABLE".to_string()), version: None, observed_at_sec: 1776978000, stale_after_sec: Some(1776978300), @@ -373,7 +383,7 @@ mod tests { feature: "kvm_vm_launch".to_string(), state: SupportState::Unavailable, provenance: Provenance::Observed, - reason_code: Some("KVM_NOT_OPENABLE_PERMS".to_string()), + reason_code: Some("CAP_KVM_NOT_OPENABLE_PERMS".to_string()), version: None, observed_at_sec: 1776978000, stale_after_sec: Some(1776978300), @@ -453,7 +463,7 @@ mod tests { feature: "kvm_vm_launch".to_string(), state: SupportState::Supported, provenance: Provenance::Observed, - reason_code: Some("KVM_OPENABLE".to_string()), + reason_code: Some("CAP_KVM_OPENABLE".to_string()), version: None, observed_at_sec: 1776978000, stale_after_sec: Some(1776978300), @@ -528,7 +538,7 @@ mod tests { feature: "kvm_vm_launch".to_string(), state: SupportState::Unsupported, provenance: Provenance::Observed, - reason_code: Some("KVM_MISSING".to_string()), + reason_code: Some("CAP_KVM_MISSING".to_string()), version: None, observed_at_sec: 1776978000, stale_after_sec: Some(1776978300), diff --git a/schedune-control-plane/internal/domain/projector_test.go b/schedune-control-plane/internal/domain/projector_test.go index c5d1ec2..ed413b4 100644 --- a/schedune-control-plane/internal/domain/projector_test.go +++ b/schedune-control-plane/internal/domain/projector_test.go @@ -45,8 +45,8 @@ func TestProjectEnvelope_HealthyArmProduction(t *testing.T) { if cap.State != "Supported" { t.Errorf("expected 'Supported', got %s", cap.State) } - if cap.ReasonCode != "KVM_OPENABLE" { - t.Errorf("expected 'KVM_OPENABLE', got %s", cap.ReasonCode) + if cap.ReasonCode != "CAP_KVM_OPENABLE" { + t.Errorf("expected 'CAP_KVM_OPENABLE', got %s", cap.ReasonCode) } if cap.Version != "" { t.Errorf("expected empty Version for kvm_vm_launch, got %s", cap.Version) @@ -114,8 +114,8 @@ func TestProjectEnvelope_KvmExistsNotOpenable(t *testing.T) { } cap := record.Capabilities["kvm_vm_launch"] - if cap.State != "Unavailable" || cap.ReasonCode != "KVM_NOT_OPENABLE_PERMS" { - t.Errorf("expected Unavailable/KVM_NOT_OPENABLE_PERMS, got %s/%s", cap.State, cap.ReasonCode) + if cap.State != "Unavailable" || cap.ReasonCode != "CAP_KVM_NOT_OPENABLE_PERMS" { + t.Errorf("expected Unavailable/CAP_KVM_NOT_OPENABLE_PERMS, got %s/%s", cap.State, cap.ReasonCode) } } diff --git a/schedune-control-plane/internal/domain/validate_launch_test.go b/schedune-control-plane/internal/domain/validate_launch_test.go index 3ff24f3..dd30b0e 100644 --- a/schedune-control-plane/internal/domain/validate_launch_test.go +++ b/schedune-control-plane/internal/domain/validate_launch_test.go @@ -166,7 +166,7 @@ func TestValidateLaunch_MissingKvmX86(t *testing.T) { t.Errorf("expected ERR_LAUNCH_BACKEND_NOT_SUPPORTED blocker, got %v", result.BlockingReasonCodes) } - if result.RejectedBackends["kvm_qemu"] != "ERR_LAUNCH_MISSING_CAPABILITY_KVM_QEMU (KVM_MISSING)" { + if result.RejectedBackends["kvm_qemu"] != "ERR_LAUNCH_MISSING_CAPABILITY_KVM_QEMU (CAP_KVM_MISSING)" { t.Errorf("expected rejected backend kvm_qemu with CAP_KVM_MISSING, got %v", result.RejectedBackends) } } @@ -299,7 +299,7 @@ func TestValidateLaunch_KvmExistsNotOpenable(t *testing.T) { t.Errorf("expected ERR_LAUNCH_BACKEND_NOT_SUPPORTED blocker, got %v", result.BlockingReasonCodes) } - if result.RejectedBackends["kvm_qemu"] != "ERR_LAUNCH_MISSING_CAPABILITY_KVM_QEMU (KVM_NOT_OPENABLE_PERMS)" { + if result.RejectedBackends["kvm_qemu"] != "ERR_LAUNCH_MISSING_CAPABILITY_KVM_QEMU (CAP_KVM_NOT_OPENABLE_PERMS)" { t.Errorf("expected rejected backend kvm_qemu, got %v", result.RejectedBackends) } @@ -308,8 +308,8 @@ func TestValidateLaunch_KvmExistsNotOpenable(t *testing.T) { for _, tr := range result.ValidationTrace { traceStr += tr + " " } - if !strings.Contains(traceStr, "KVM_NOT_OPENABLE_PERMS") { - t.Errorf("expected trace to contain KVM_NOT_OPENABLE_PERMS, got %s", traceStr) + if !strings.Contains(traceStr, "CAP_KVM_NOT_OPENABLE_PERMS") { + t.Errorf("expected trace to contain CAP_KVM_NOT_OPENABLE_PERMS, got %s", traceStr) } } @@ -650,15 +650,24 @@ func TestValidateLaunch_ReasonCodeRegistryHygiene(t *testing.T) { } } + for _, ev := range res.BackendRejectionEvidence { + if !schema.IsKnownReasonCode(ev.ReasonCode) { + t.Errorf("fixture %s produced unregistered structured reason code: %q", fname, ev.ReasonCode) + } + if ev.CapabilityReasonCode != nil && *ev.CapabilityReasonCode != "" { + if !schema.IsKnownReasonCode(*ev.CapabilityReasonCode) { + t.Errorf("fixture %s produced unregistered structured capability reason code: %q", fname, *ev.CapabilityReasonCode) + } + } + } + for _, reason := range res.RejectedBackends { - // Backend rejection reasons can contain capabilities inside them, - // but we know they are usually formatted as REASON_CODE or REASON_CODE [CAPABILITY_CODE] - // Let's parse it out simply or just ensure if it's an exact code, it is registered. - // For simplicity, we just check if any registered code is a substring, - // or if we can extract it. + if reason == "" { + t.Errorf("fixture %s produced an empty rejected backend reason", fname) + } words := strings.Split(reason, " ") for _, w := range words { - w = strings.Trim(w, "[]") + w = strings.Trim(w, "()[]") if strings.HasPrefix(w, "ERR_") || strings.HasPrefix(w, "CAP_") { if !schema.IsKnownReasonCode(w) { t.Errorf("fixture %s produced unregistered backend rejection code in message %q: %q", fname, reason, w) diff --git a/schedune-control-plane/pkg/schema/registry.go b/schedune-control-plane/pkg/schema/registry.go index 4481f71..bd930f5 100644 --- a/schedune-control-plane/pkg/schema/registry.go +++ b/schedune-control-plane/pkg/schema/registry.go @@ -69,7 +69,11 @@ var knownReasonCodes = map[string]struct{}{ // KnownReasonCodes returns a map of all registered reason codes. func KnownReasonCodes() map[string]struct{} { - return knownReasonCodes + copied := make(map[string]struct{}, len(knownReasonCodes)) + for k, v := range knownReasonCodes { + copied[k] = v + } + return copied } // IsKnownReasonCode checks if a given reason code is registered. diff --git a/schedune-control-plane/pkg/schema/registry_test.go b/schedune-control-plane/pkg/schema/registry_test.go index df42dba..fa9b03e 100644 --- a/schedune-control-plane/pkg/schema/registry_test.go +++ b/schedune-control-plane/pkg/schema/registry_test.go @@ -49,3 +49,22 @@ func TestReasonCodeRegistry_RepresentativeCodes(t *testing.T) { } } } + +func TestReasonCodeRegistry_Immutability(t *testing.T) { + codes := schema.KnownReasonCodes() + + codes["DUMMY_MUTATION_TEST"] = struct{}{} + + if schema.IsKnownReasonCode("DUMMY_MUTATION_TEST") { + t.Errorf("registry was mutated by caller") + } +} + +func TestReasonCodeRegistry_Uniqueness(t *testing.T) { + // The registry is implemented as a map literal, which guarantees uniqueness + // of keys at compile-time/runtime. We simply verify the map isn't empty. + codes := schema.KnownReasonCodes() + if len(codes) == 0 { + t.Errorf("expected non-empty registry") + } +} diff --git a/testdata/fixtures/cloudhypervisor_binary_missing.json b/testdata/fixtures/cloudhypervisor_binary_missing.json index a341191..027f555 100644 --- a/testdata/fixtures/cloudhypervisor_binary_missing.json +++ b/testdata/fixtures/cloudhypervisor_binary_missing.json @@ -1,7 +1,7 @@ { "schema_version": "v1alpha1", "agent_version": "0.1.0", - "collection_id": "473b2b19-f761-4225-a8fd-17e6720bb4ad", + "collection_id": "11111111-2222-3333-4444-000000000e97", "timestamp_sec": 1777086729, "node_id": "arm-ch-fail-01", "compatibility": { @@ -65,4 +65,4 @@ "active_alarms": [] }, "collector_statuses": [] -} \ No newline at end of file +} diff --git a/testdata/fixtures/cloudhypervisor_ready_arm.json b/testdata/fixtures/cloudhypervisor_ready_arm.json index 4f3bbce..85c6c4f 100644 --- a/testdata/fixtures/cloudhypervisor_ready_arm.json +++ b/testdata/fixtures/cloudhypervisor_ready_arm.json @@ -1,7 +1,7 @@ { "schema_version": "v1alpha1", "agent_version": "0.1.0", - "collection_id": "f16c4743-df30-4c3a-810f-c879934204ec", + "collection_id": "11111111-2222-3333-4444-000000000c6d", "timestamp_sec": 1777086729, "node_id": "arm-ch-01", "compatibility": { @@ -65,4 +65,4 @@ "active_alarms": [] }, "collector_statuses": [] -} \ No newline at end of file +} diff --git a/testdata/fixtures/firecracker_cgroups_missing.json b/testdata/fixtures/firecracker_cgroups_missing.json index cd98ddd..e735faa 100644 --- a/testdata/fixtures/firecracker_cgroups_missing.json +++ b/testdata/fixtures/firecracker_cgroups_missing.json @@ -1,7 +1,7 @@ { "schema_version": "v1alpha1", "agent_version": "0.1.0", - "collection_id": "69524b96-3edc-4999-a52d-769dac1e2133", + "collection_id": "11111111-2222-3333-4444-000000000d24", "timestamp_sec": 1777086729, "node_id": "x86-fc-fail-cgroups", "compatibility": { @@ -81,4 +81,4 @@ "active_alarms": [] }, "collector_statuses": [] -} \ No newline at end of file +} diff --git a/testdata/fixtures/firecracker_host_ready.json b/testdata/fixtures/firecracker_host_ready.json index 986bb6c..1d11572 100644 --- a/testdata/fixtures/firecracker_host_ready.json +++ b/testdata/fixtures/firecracker_host_ready.json @@ -1,7 +1,7 @@ { "schema_version": "v1alpha1", "agent_version": "0.1.0", - "collection_id": "34e75e68-f3ba-4c83-b744-2640c4ffea1c", + "collection_id": "11111111-2222-3333-4444-000000000afa", "timestamp_sec": 1777086729, "node_id": "x86-fc-01", "compatibility": { @@ -81,4 +81,4 @@ "active_alarms": [] }, "collector_statuses": [] -} \ No newline at end of file +} diff --git a/testdata/fixtures/firecracker_partial_fail.json b/testdata/fixtures/firecracker_partial_fail.json index 3c07e7a..c88a57b 100644 --- a/testdata/fixtures/firecracker_partial_fail.json +++ b/testdata/fixtures/firecracker_partial_fail.json @@ -1,7 +1,7 @@ { "schema_version": "v1alpha1", "agent_version": "0.1.0", - "collection_id": "adb1cc20-ccbc-47f5-a98f-596af5e4970c", + "collection_id": "11111111-2222-3333-4444-000000000bb0", "timestamp_sec": 1777086729, "node_id": "arm-fc-fail-01", "compatibility": { @@ -30,7 +30,7 @@ "feature": "kvm_vm_launch", "state": "Supported", "provenance": "Observed", - "reason_code": "KVM_OPENABLE", + "reason_code": "CAP_KVM_OPENABLE", "observed_at_sec": 1776978000, "stale_after_sec": 1776978300 }, @@ -64,4 +64,4 @@ "error_message": null } ] -} \ No newline at end of file +} diff --git a/testdata/fixtures/firecracker_tun_missing.json b/testdata/fixtures/firecracker_tun_missing.json index 0516087..18398a0 100644 --- a/testdata/fixtures/firecracker_tun_missing.json +++ b/testdata/fixtures/firecracker_tun_missing.json @@ -1,7 +1,7 @@ { "schema_version": "v1alpha1", "agent_version": "0.1.0", - "collection_id": "94deadb3-6db4-4169-addf-bb1f32f3784d", + "collection_id": "11111111-2222-3333-4444-000000000b78", "timestamp_sec": 1777086729, "node_id": "x86-fc-fail-tun", "compatibility": { @@ -81,4 +81,4 @@ "active_alarms": [] }, "collector_statuses": [] -} \ No newline at end of file +} diff --git a/testdata/fixtures/healthy_arm_production.json b/testdata/fixtures/healthy_arm_production.json index a9fab68..6029baf 100644 --- a/testdata/fixtures/healthy_arm_production.json +++ b/testdata/fixtures/healthy_arm_production.json @@ -1,7 +1,7 @@ { "schema_version": "v1alpha1", "agent_version": "0.1.0", - "collection_id": "f0644c83-682e-47a1-bd83-7eca359e9e16", + "collection_id": "11111111-2222-3333-4444-000000000b1c", "timestamp_sec": 1777086729, "node_id": "arm-prod-01", "compatibility": { @@ -30,7 +30,7 @@ "feature": "kvm_vm_launch", "state": "Supported", "provenance": "Observed", - "reason_code": "KVM_OPENABLE", + "reason_code": "CAP_KVM_OPENABLE", "observed_at_sec": 1776978000, "stale_after_sec": 1776978300 }, @@ -80,4 +80,4 @@ "error_message": null } ] -} \ No newline at end of file +} diff --git a/testdata/fixtures/healthy_unsupported_compatibility.json b/testdata/fixtures/healthy_unsupported_compatibility.json index 574d28b..19a2973 100644 --- a/testdata/fixtures/healthy_unsupported_compatibility.json +++ b/testdata/fixtures/healthy_unsupported_compatibility.json @@ -1,7 +1,7 @@ { "schema_version": "v1alpha1", "agent_version": "0.1.0", - "collection_id": "9de8f3e2-5d3f-450b-b096-581b0aceadc3", + "collection_id": "11111111-2222-3333-4444-000000000fd8", "timestamp_sec": 1777086729, "node_id": "x86-storage-only-01", "compatibility": { @@ -31,7 +31,7 @@ "feature": "kvm_vm_launch", "state": "Unsupported", "provenance": "Observed", - "reason_code": "KVM_MISSING", + "reason_code": "CAP_KVM_MISSING", "observed_at_sec": 1776978000, "stale_after_sec": 1776978300 }, @@ -65,4 +65,4 @@ "error_message": null } ] -} \ No newline at end of file +} diff --git a/testdata/fixtures/healthy_x86_kvm_openable.json b/testdata/fixtures/healthy_x86_kvm_openable.json index df82408..02633c9 100644 --- a/testdata/fixtures/healthy_x86_kvm_openable.json +++ b/testdata/fixtures/healthy_x86_kvm_openable.json @@ -1,7 +1,7 @@ { "schema_version": "v1alpha1", "agent_version": "0.1.0", - "collection_id": "cc6d39d1-2dc8-4f33-9c44-9b9e11ff3e16", + "collection_id": "11111111-2222-3333-4444-000000000b6e", "timestamp_sec": 1777086729, "node_id": "x86-pool-01", "compatibility": { @@ -30,7 +30,7 @@ "feature": "kvm_vm_launch", "state": "Supported", "provenance": "Observed", - "reason_code": "KVM_OPENABLE", + "reason_code": "CAP_KVM_OPENABLE", "observed_at_sec": 1776978000, "stale_after_sec": 1776978300 }, @@ -64,4 +64,4 @@ "error_message": null } ] -} \ No newline at end of file +} diff --git a/testdata/fixtures/kvm_exists_not_openable.json b/testdata/fixtures/kvm_exists_not_openable.json index 9cc3988..2e157aa 100644 --- a/testdata/fixtures/kvm_exists_not_openable.json +++ b/testdata/fixtures/kvm_exists_not_openable.json @@ -1,7 +1,7 @@ { "schema_version": "v1alpha1", "agent_version": "0.1.0", - "collection_id": "bc4a69ee-b411-417e-bafb-8c34055a6f1b", + "collection_id": "11111111-2222-3333-4444-000000000b8a", "timestamp_sec": 1777086729, "node_id": "x86-perms-fail-01", "compatibility": { @@ -30,7 +30,7 @@ "feature": "kvm_vm_launch", "state": "Unavailable", "provenance": "Observed", - "reason_code": "KVM_NOT_OPENABLE_PERMS", + "reason_code": "CAP_KVM_NOT_OPENABLE_PERMS", "observed_at_sec": 1776978000, "stale_after_sec": 1776978300 }, @@ -72,4 +72,4 @@ "error_message": null } ] -} \ No newline at end of file +} diff --git a/testdata/fixtures/missing_kvm_x86.json b/testdata/fixtures/missing_kvm_x86.json index 15277ba..5b59ecd 100644 --- a/testdata/fixtures/missing_kvm_x86.json +++ b/testdata/fixtures/missing_kvm_x86.json @@ -1,7 +1,7 @@ { "schema_version": "v1alpha1", "agent_version": "0.1.0", - "collection_id": "df283061-3405-47b6-b5e5-9a8e71cf77bf", + "collection_id": "11111111-2222-3333-4444-0000000007d4", "timestamp_sec": 1777086729, "node_id": "x86-storage-01", "compatibility": { @@ -30,7 +30,7 @@ "feature": "kvm_vm_launch", "state": "Unsupported", "provenance": "Observed", - "reason_code": "KVM_MISSING", + "reason_code": "CAP_KVM_MISSING", "observed_at_sec": 1776978000, "stale_after_sec": 1776978300 }, @@ -72,4 +72,4 @@ "error_message": null } ] -} \ No newline at end of file +} diff --git a/testdata/fixtures/missing_qemu_binary.json b/testdata/fixtures/missing_qemu_binary.json index 9babb1e..a91f88d 100644 --- a/testdata/fixtures/missing_qemu_binary.json +++ b/testdata/fixtures/missing_qemu_binary.json @@ -1,7 +1,7 @@ { "schema_version": "v1alpha1", "agent_version": "0.1.0", - "collection_id": "dc387c06-2c1d-49d7-adba-b940a47e1f2d", + "collection_id": "11111111-2222-3333-4444-0000000009dd", "timestamp_sec": 1777086729, "node_id": "x86-no-qemu-01", "compatibility": { @@ -72,4 +72,4 @@ "error_message": null } ] -} \ No newline at end of file +} diff --git a/testdata/fixtures/missing_seccomp.json b/testdata/fixtures/missing_seccomp.json index 2c09ccd..bb8173b 100644 --- a/testdata/fixtures/missing_seccomp.json +++ b/testdata/fixtures/missing_seccomp.json @@ -1,7 +1,7 @@ { "schema_version": "v1alpha1", "agent_version": "0.1.0", - "collection_id": "13b6ff73-5723-4759-9008-196a0de9019e", + "collection_id": "11111111-2222-3333-4444-00000000082b", "timestamp_sec": 1777086729, "node_id": "x86-no-seccomp-01", "compatibility": { @@ -72,4 +72,4 @@ "error_message": null } ] -} \ No newline at end of file +} diff --git a/testdata/fixtures/stale_telemetry.json b/testdata/fixtures/stale_telemetry.json index 854ad32..cebcc2b 100644 --- a/testdata/fixtures/stale_telemetry.json +++ b/testdata/fixtures/stale_telemetry.json @@ -1,7 +1,7 @@ { "schema_version": "v1alpha1", "agent_version": "0.1.0", - "collection_id": "6b7ba1b9-7739-4549-a116-1061f08e0028", + "collection_id": "11111111-2222-3333-4444-00000000083b", "timestamp_sec": 1000000300, "node_id": "stale-arm-01", "compatibility": { @@ -30,7 +30,7 @@ "feature": "kvm_vm_launch", "state": "Supported", "provenance": "Observed", - "reason_code": "KVM_OPENABLE", + "reason_code": "CAP_KVM_OPENABLE", "observed_at_sec": 1000000000, "stale_after_sec": 1000000300 }, @@ -64,4 +64,4 @@ "error_message": "Connection timeout" } ] -} \ No newline at end of file +}