from __future__ import annotations from datetime import datetime, timezone import ariadne.services.cluster_state as cluster_state class DummyStorage: def __init__(self) -> None: self.snapshot = None self.keep = None def record_cluster_state(self, snapshot): # type: ignore[no-untyped-def] self.snapshot = snapshot def prune_cluster_state(self, keep: int) -> None: self.keep = keep def test_collect_cluster_state(monkeypatch) -> None: def fake_get_json(path: str): if path.endswith("/nodes"): return { "items": [ { "metadata": {"name": "node-a", "labels": {"kubernetes.io/arch": "arm64"}}, "status": { "conditions": [{"type": "Ready", "status": "True"}], "nodeInfo": {"architecture": "arm64"}, "addresses": [{"type": "InternalIP", "address": "10.0.0.1"}], }, }, { "metadata": { "name": "node-b", "labels": {"kubernetes.io/arch": "amd64"}, "creationTimestamp": "2026-01-01T00:00:00Z", }, "spec": { "taints": [ {"key": "node-role.kubernetes.io/control-plane", "effect": "NoSchedule"} ] }, "status": { "conditions": [{"type": "Ready", "status": "False"}], "nodeInfo": {"architecture": "amd64"}, }, }, ] } if path.startswith("/api/v1/pods"): return { "items": [ { "metadata": { "name": "jellyfin-0", "namespace": "media", "labels": {"app": "jellyfin"}, }, "spec": {"nodeName": "node-a"}, "status": {"phase": "Running"}, } ] } if path.startswith("/api/v1/events"): return {"items": []} if path.startswith("/apis/apps/v1/deployments"): return { "items": [ { "metadata": {"name": "api", "namespace": "apps"}, "spec": {"replicas": 2}, "status": {"readyReplicas": 1, "availableReplicas": 1, "updatedReplicas": 1}, } ] } if path.startswith("/apis/apps/v1/statefulsets"): return { "items": [ { "metadata": {"name": "db", "namespace": "apps"}, "spec": {"replicas": 1}, "status": {"readyReplicas": 1, "currentReplicas": 1, "updatedReplicas": 1}, } ] } if path.startswith("/apis/apps/v1/daemonsets"): return { "items": [ { "metadata": {"name": "agent", "namespace": "apps"}, "status": {"desiredNumberScheduled": 3, "numberReady": 3, "updatedNumberScheduled": 3}, } ] } return { "items": [ { "metadata": {"name": "apps", "namespace": "flux-system"}, "spec": {"suspend": False}, "status": {"conditions": [{"type": "Ready", "status": "True"}]}, }, { "metadata": {"name": "broken", "namespace": "flux-system"}, "spec": {"suspend": False}, "status": {"conditions": [{"type": "Ready", "status": "False", "reason": "Fail"}]}, }, ] } monkeypatch.setattr(cluster_state, "get_json", fake_get_json) monkeypatch.setattr(cluster_state, "_vm_scalar", lambda _expr: 5.0) monkeypatch.setattr(cluster_state, "_vm_vector", lambda _expr: []) snapshot, summary = cluster_state.collect_cluster_state() assert snapshot["nodes"]["total"] == 2 assert snapshot["nodes"]["ready"] == 1 assert snapshot["flux"]["not_ready"] == 1 assert snapshot["nodes_summary"]["total"] == 2 assert snapshot["nodes_summary"]["ready"] == 1 assert "pressure_nodes" in snapshot["nodes_summary"] assert snapshot["nodes_detail"] assert snapshot["nodes_detail"][1]["age_hours"] is not None assert snapshot["nodes_detail"][1]["taints"] assert snapshot["workloads"] assert snapshot["namespace_pods"] assert snapshot["namespace_pods"][0]["namespace"] == "media" assert snapshot["namespace_nodes"] assert snapshot["node_pods"] assert "pod_issues" in snapshot assert "workloads_health" in snapshot assert snapshot["workloads_health"]["deployments"]["total"] == 1 assert snapshot["workloads_health"]["deployments"]["not_ready"] == 1 assert snapshot["events"]["warnings_total"] == 0 assert "node_usage_stats" in snapshot["metrics"] assert snapshot["metrics"]["namespace_cpu_top"] == [] assert snapshot["metrics"]["namespace_mem_top"] == [] assert snapshot["metrics"]["namespace_cpu_requests_top"] == [] assert snapshot["metrics"]["namespace_mem_requests_top"] == [] assert snapshot["metrics"]["namespace_net_top"] == [] assert snapshot["metrics"]["namespace_io_top"] == [] assert snapshot["metrics"]["pod_cpu_top"] == [] assert snapshot["metrics"]["pod_mem_top"] == [] assert snapshot["metrics"]["job_failures_24h"] == [] assert snapshot["metrics"]["pvc_usage_top"] == [] assert summary.nodes_total == 2 assert summary.nodes_ready == 1 assert summary.pods_running == 5.0 def test_run_cluster_state_records(monkeypatch) -> None: dummy = DummyStorage() snapshot = {"collected_at": datetime.now(timezone.utc).isoformat()} summary = cluster_state.ClusterStateSummary(1, 1, 1.0, 0, 0) monkeypatch.setattr(cluster_state, "collect_cluster_state", lambda: (snapshot, summary)) result = cluster_state.run_cluster_state(dummy) assert result == summary assert dummy.snapshot == snapshot assert dummy.keep == cluster_state.settings.cluster_state_keep