From 9965983322906a739810e0b024e2b75fefaa063b Mon Sep 17 00:00:00 2001 From: codex Date: Tue, 21 Apr 2026 03:44:43 -0300 Subject: [PATCH] test(ariadne): cover VM client edge parsing --- ariadne/services/cluster_state_vm_client.py | 20 +----- .../services/test_cluster_state_vm_domains.py | 63 +++++++++++++++++++ 2 files changed, 66 insertions(+), 17 deletions(-) diff --git a/ariadne/services/cluster_state_vm_client.py b/ariadne/services/cluster_state_vm_client.py index c0ab08b..f6b5eaa 100644 --- a/ariadne/services/cluster_state_vm_client.py +++ b/ariadne/services/cluster_state_vm_client.py @@ -200,10 +200,7 @@ def _vm_baseline_map(expr: str, label_key: str, window: str) -> dict[str, dict[s return baseline -def _baseline_map_to_list( - baseline: dict[str, dict[str, float]], - name_key: str, -) -> list[dict[str, Any]]: +def _baseline_map_to_list(baseline: dict[str, dict[str, float]], name_key: str) -> list[dict[str, Any]]: output: list[dict[str, Any]] = [] for name, stats in baseline.items(): if not isinstance(name, str) or not name: @@ -225,12 +222,7 @@ def _limit_entries(entries: list[dict[str, Any]], limit: int) -> list[dict[str, return entries[:limit] -def _vm_window_series( - expr: str, - label_key: str, - name_key: str, - window: str, -) -> dict[str, list[dict[str, Any]]]: +def _vm_window_series(expr: str, label_key: str, name_key: str, window: str) -> dict[str, list[dict[str, Any]]]: avg = _vector_to_named( _vm_vector(f"avg_over_time(({expr})[{window}])"), label_key, @@ -253,13 +245,7 @@ def _trim_window_series(series: dict[str, list[dict[str, Any]]], limit: int) -> return {key: _limit_entries(entries, limit) for key, entries in series.items()} -def _build_metric_trends( - exprs: dict[str, str], - label_key: str, - name_key: str, - windows: tuple[str, ...], - limit: int, -) -> dict[str, dict[str, dict[str, list[dict[str, Any]]]]]: +def _build_metric_trends(exprs: dict[str, str], label_key: str, name_key: str, windows: tuple[str, ...], limit: int) -> dict[str, dict[str, dict[str, list[dict[str, Any]]]]]: trends: dict[str, dict[str, dict[str, list[dict[str, Any]]]]] = {} for metric, expr in exprs.items(): metric_trends: dict[str, dict[str, list[dict[str, Any]]]] = {} diff --git a/tests/unit/services/test_cluster_state_vm_domains.py b/tests/unit/services/test_cluster_state_vm_domains.py index 0b2847e..d897c6f 100644 --- a/tests/unit/services/test_cluster_state_vm_domains.py +++ b/tests/unit/services/test_cluster_state_vm_domains.py @@ -62,8 +62,28 @@ def test_vm_query_scalar_vector_and_alert_helpers(monkeypatch) -> None: assert vm_client._vm_vector("short") == [] +def test_vm_client_rejects_empty_and_malformed_values(monkeypatch) -> None: + monkeypatch.setattr(vm_client, "_vm_query", lambda _expr: []) + assert vm_client._vm_scalar("empty") is None + + monkeypatch.setattr(vm_client, "_vm_query", lambda _expr: [{"metric": {}, "value": [1, "bad"]}]) + assert vm_client._vm_scalar("bad") is None + + monkeypatch.setattr( + vm_client, + "_vm_query", + lambda _expr: [ + "bad", + {"metric": {"node": "titan-1"}, "value": [1, "not-a-number"]}, + {"metric": {"node": "titan-2"}, "value": [1, "2"]}, + ], + ) + assert vm_client._vm_vector("mixed") == [{"metric": {"node": "titan-2"}, "value": 2.0}] + + def test_vm_client_alerts_and_namespace_filters(monkeypatch) -> None: entries = [ + None, {"metric": {"alertname": "NodeDown", "severity": "critical"}, "value": 2}, {"metric": {"alertname": "", "severity": "warning"}, "value": 1}, ] @@ -80,6 +100,7 @@ def test_vm_client_alerts_and_namespace_filters(monkeypatch) -> None: {"metric": {"namespace": "kube-system"}, "value": 1}, {"metric": {"namespace": "apps"}, "value": 2}, {"metric": {"namespace": ""}, "value": 3}, + "bad", ] ) assert filtered == [{"metric": {"namespace": "apps"}, "value": 2}] @@ -92,6 +113,25 @@ def test_vm_client_alerts_and_namespace_filters(monkeypatch) -> None: assert vm_client._summarize_alerts(alerts)["by_severity"] == {"warning": 1, "critical": 1} +def test_vm_client_alertmanager_success_and_errors(monkeypatch) -> None: + monkeypatch.setattr(vm_client, "settings", SimpleNamespace(alertmanager_url="", cluster_state_vm_timeout_sec=1.0)) + errors: list[str] = [] + assert vm_client._alertmanager_alerts(errors) == [] + assert errors == [] + + _FakeClient.payload = [{"labels": {"alertname": "DiskHot"}}, "bad"] + monkeypatch.setattr(vm_client, "settings", SimpleNamespace(alertmanager_url="http://alertmanager", cluster_state_vm_timeout_sec=1.0)) + monkeypatch.setattr(vm_client.httpx, "Client", _FakeClient) + assert vm_client._alertmanager_alerts(errors) == [{"labels": {"alertname": "DiskHot"}}] + + _FakeClient.payload = RuntimeError("alertmanager down") + assert vm_client._alertmanager_alerts(errors) == [] + assert errors[-1] == "alertmanager: alertmanager down" + + _FakeClient.payload = {"unexpected": "shape"} + assert vm_client._alertmanager_alerts(errors) == [] + + def test_vm_client_topk_baselines_and_window_series(monkeypatch) -> None: monkeypatch.setattr( vm_client, @@ -111,8 +151,31 @@ def test_vm_client_topk_baselines_and_window_series(monkeypatch) -> None: baseline = vm_client._vm_baseline_map("expr", "node", "24h") assert baseline["titan-1"]["avg"] == 9.0 assert vm_client._baseline_map_to_list(baseline, "node")[0]["node"] == "titan-1" + assert vm_client._baseline_map_to_list({"": {"avg": 10.0}, "titan-3": {"avg": 1.0}}, "node") == [ + {"node": "titan-3", "avg": 1.0, "max": None} + ] assert vm_client._limit_entries([{"value": 1}, {"value": 2}], 1) == [{"value": 1}] + assert vm_client._limit_entries([{"value": 1}], 0) == [] + monkeypatch.setattr( + vm_client, + "_vm_vector", + lambda _expr: [ + {"metric": {}, "value": 1.0}, + {"metric": {"node": ""}, "value": 2.0}, + {"metric": {"node": "titan-1"}, "value": 3.0}, + ], + ) + assert vm_client._vm_baseline_map("expr", "node", "24h") == {"titan-1": {"avg": 3.0, "max": 3.0}} + + monkeypatch.setattr( + vm_client, + "_vm_vector", + lambda _expr: [ + {"metric": {"node": "titan-1", "namespace": "apps"}, "value": 9.0}, + {"metric": {"node": "titan-2", "namespace": "apps"}, "value": 4.0}, + ], + ) series = vm_client._vm_window_series("expr", "node", "node", "1h") assert series["avg"][0]["node"] == "titan-1" trends = vm_client._build_metric_trends({"cpu": "expr"}, "node", "node", ("1h",), 2)