From 7c1c5d396afa884219b6405cbe16903e91671a30 Mon Sep 17 00:00:00 2001 From: rcourtman Date: Thu, 16 Apr 2026 16:00:23 +0100 Subject: [PATCH] Own mock runtime fixtures under monitoring --- .../v6/internal/subsystems/monitoring.md | 31 ++++++++------- .../v6/internal/subsystems/registry.json | 21 ++++++++++ .../canonical_completion_guard_test.py | 1 + .../release_control/subsystem_lookup_test.py | 39 +++++++++++++++++++ .../tests/43-platform-mock-runtime.spec.ts | 8 +++- 5 files changed, 84 insertions(+), 16 deletions(-) diff --git a/docs/release-control/v6/internal/subsystems/monitoring.md b/docs/release-control/v6/internal/subsystems/monitoring.md index 3e2385afd2..1476817791 100644 --- a/docs/release-control/v6/internal/subsystems/monitoring.md +++ b/docs/release-control/v6/internal/subsystems/monitoring.md @@ -291,13 +291,13 @@ request only a subset of canonical chart series, `internal/monitoring/monitor_me must preserve that narrowed metric set through the batch store fallback path instead of querying every metric type for each resource and discarding most of the payload afterward. -That same mock-runtime owner now also owns demo-scenario curation. The -canonical `internal/mock/fixture_graph.go` path may project an authored demo -estate over generic fixture synthesis, but that authored layer must stay -graph-native and runtime-stable so infrastructure, workloads, storage, and -recovery all present the same human-readable platform story instead of a lab -of random names, legacy `mock-cluster` labels, or surface-specific mock -overrides. +That same mock-runtime owner now also owns demo-scenario curation. +`internal/mock/fixture_graph.go`, `internal/mock/platform_fixtures.go`, and +`internal/mock/demo_scenarios.go` may project an authored demo estate over +generic fixture synthesis, but that authored layer must stay graph-native and +runtime-stable so infrastructure, workloads, storage, and recovery all present +the same human-readable platform story instead of a lab of random names, +legacy `mock-cluster` labels, or surface-specific mock overrides. That same chart boundary also owns storage-series identity. Monitoring and `ReadState` consumers must address storage pool and physical-disk history through the resolved unified-resource metrics target, so seeded history, @@ -653,14 +653,15 @@ supplemental ingest, unified read-state, and seeded charts cannot drift from each other when the v6 runtime runs in mock mode. That same fixture authority now also includes legacy snapshot-backed platforms. `internal/monitoring/monitor.go` and -`internal/monitoring/mock_metrics_history.go` must treat the canonical -`internal/mock/fixture_graph.go` runtime graph as the one mock owner for -legacy Proxmox/Docker/Kubernetes/agent/PBS/PMG snapshot state plus -provider-backed TrueNAS and VMware fixtures. Monitoring must not rebuild mock -provider context from standalone defaults, consume partial legacy helper -exports, or mix snapshot state with separate provider fixtures when seeding -read-state or metrics history. The graph and its methods are the canonical -mock runtime API. +`internal/monitoring/mock_metrics_history.go` must treat +`internal/mock/fixture_graph.go`, `internal/mock/platform_fixtures.go`, and +`internal/mock/demo_scenarios.go` as the one canonical mock owner for legacy +Proxmox/Docker/Kubernetes/agent/PBS/PMG snapshot state plus provider-backed +TrueNAS and VMware fixtures. Monitoring must not rebuild mock provider context +from standalone defaults, consume partial legacy helper exports, or mix +snapshot state with separate provider fixtures when seeding read-state or +metrics history. The graph, its platform projections, and its curated demo +scenario layer are the canonical mock runtime API. That same boundary now also owns native disk-history fallback when Pulse's own history is shallow. `internal/truenas/client.go`, `internal/truenas/provider.go`, `internal/monitoring/truenas_poller.go`, and diff --git a/docs/release-control/v6/internal/subsystems/registry.json b/docs/release-control/v6/internal/subsystems/registry.json index 008cba1d6e..8d1475031a 100644 --- a/docs/release-control/v6/internal/subsystems/registry.json +++ b/docs/release-control/v6/internal/subsystems/registry.json @@ -3238,6 +3238,9 @@ "docker-entrypoint.sh", "internal/dockeragent/collect.go", "internal/dockeragent/swarm.go", + "internal/mock/demo_scenarios.go", + "internal/mock/fixture_graph.go", + "internal/mock/platform_fixtures.go", "pkg/proxmox/ceph.go", "pkg/proxmox/zfs.go" ], @@ -3445,6 +3448,24 @@ "scripts/installtests/docker_entrypoint_test.go" ] }, + { + "id": "mock-runtime-fixtures", + "label": "monitoring mock runtime fixture proof", + "match_prefixes": [], + "match_files": [ + "internal/mock/demo_scenarios.go", + "internal/mock/fixture_graph.go", + "internal/mock/platform_fixtures.go" + ], + "allow_same_subsystem_tests": false, + "test_prefixes": [], + "exact_files": [ + "internal/mock/canonical_api_guardrails_test.go", + "internal/mock/demo_scenarios_test.go", + "internal/mock/platform_fixtures_test.go", + "tests/integration/tests/43-platform-mock-runtime.spec.ts" + ] + }, { "id": "monitoring-runtime", "label": "monitoring runtime proof", diff --git a/scripts/release_control/canonical_completion_guard_test.py b/scripts/release_control/canonical_completion_guard_test.py index 09ddf71b13..445af5a4e1 100644 --- a/scripts/release_control/canonical_completion_guard_test.py +++ b/scripts/release_control/canonical_completion_guard_test.py @@ -219,6 +219,7 @@ class CanonicalCompletionGuardTest(unittest.TestCase): "proxmox-zfs-runtime", "proxmox-ceph-runtime", "container-entrypoint-runtime", + "mock-runtime-fixtures", "monitoring-runtime", ], ) diff --git a/scripts/release_control/subsystem_lookup_test.py b/scripts/release_control/subsystem_lookup_test.py index e944ad6c56..9fb05abce8 100644 --- a/scripts/release_control/subsystem_lookup_test.py +++ b/scripts/release_control/subsystem_lookup_test.py @@ -4552,6 +4552,45 @@ class SubsystemLookupTest(unittest.TestCase): ], ) + def test_lookup_paths_assigns_mock_runtime_fixture_authority_to_monitoring(self) -> None: + result = lookup_paths( + [ + "internal/mock/demo_scenarios.go", + "internal/mock/fixture_graph.go", + "internal/mock/platform_fixtures.go", + ] + ) + self.assertEqual(result["unowned_runtime_files"], []) + self.assertEqual( + {item["subsystem"] for item in result["impacted_subsystems"]}, + {"monitoring"}, + ) + for file_entry in result["files"]: + self.assertEqual(file_entry["classification"], "runtime") + self.assertEqual( + {match["subsystem"] for match in file_entry["matches"]}, + {"monitoring"}, + ) + match = file_entry["matches"][0] + self.assertEqual( + match["contract"], + "docs/release-control/v6/internal/subsystems/monitoring.md", + ) + self.assertEqual(match["lane_context"]["lane_id"], "L13") + self.assertEqual( + match["verification_requirement"]["id"], + "mock-runtime-fixtures", + ) + self.assertEqual( + match["verification_requirement"]["exact_files"], + [ + "internal/mock/canonical_api_guardrails_test.go", + "internal/mock/demo_scenarios_test.go", + "internal/mock/platform_fixtures_test.go", + "tests/integration/tests/43-platform-mock-runtime.spec.ts", + ], + ) + def test_lookup_paths_normalizes_absolute_repo_paths(self) -> None: absolute = str(Path(REPO_ROOT, "internal/api/resources.go")) result = lookup_paths([absolute]) diff --git a/tests/integration/tests/43-platform-mock-runtime.spec.ts b/tests/integration/tests/43-platform-mock-runtime.spec.ts index fcc0e6ab79..a8d7432253 100644 --- a/tests/integration/tests/43-platform-mock-runtime.spec.ts +++ b/tests/integration/tests/43-platform-mock-runtime.spec.ts @@ -198,7 +198,13 @@ test.describe.serial('Platform mock runtime', () => { await page.waitForURL(/\/workloads\?type=app-container&platform=truenas&agent=.*truenas-main/); await expect(page.locator('#dashboard-type-filter')).toHaveValue('app-container'); await expect(page.locator('#workloads-platform-filter')).toHaveValue('truenas'); - await expectFirstTableContains(page, ['Nextcloud', 'Immich', 'Paperless-ngx', 'Grafana', 'AdGuard Home']); + await expectFirstTableContains(page, [ + 'client-files', + 'photo-archive', + 'document-hub', + 'ops-dashboards', + 'edge-dns', + ]); await expect(page.getByText('No history yet')).toHaveCount(0); await page.goto('/storage?source=truenas&node=truenas-main', {