from pathlib import Path import pytest from fastapi import HTTPException from investibook.api.files import _allowed_metric_chart_path, _focused_metric_chart, _metric_chart_query_ref def test_focused_metric_chart_returns_full_group_with_avg_series(): payload = { "metrics": [ { "name": "TiKV CPU", "metric_group_id": "tikv_cpu:db", "instance": "db-tikv-19", "peak": 28.8, "mean": 20.1, "unit": "cores", "chart_data": { "promql": "rate(process_cpu_seconds_total[1m])", "series": [ {"instance": "db-tikv-19", "values": [[100, "1.0"], [200, "2.0"]]}, ], }, }, { "name": "TiKV CPU", "metric_group_id": "tikv_cpu:db", "instance": "db-tikv-24", "peak": 28.7, "mean": 21.2, "unit": "cores", "chart_data": { "promql": "rate(process_cpu_seconds_total[1m])", "series": [ {"instance": "db-tikv-24", "values": [[100, "3.0"], [200, "4.0"]]}, ], }, }, { "name": "TiDB CPU", "metric_group_id": "tidb_cpu:db", "instance": "db-tidb-0", "chart_data": { "promql": "rate(process_cpu_seconds_total[1m])", "series": [ {"instance": "db-tidb-0", "values": [[100, "9.0"]]}, ], }, }, ], } chart = _focused_metric_chart(payload, "tikv_cpu:db") assert chart["key"] == "tikv_cpu:db" assert chart["title"] == "TiKV CPU" assert chart["timeRange"] == [100.0, 200.0] assert set(chart["data"]) == {"db-tikv-19", "db-tikv-24", "avg(all instances)"} assert chart["data"]["db-tikv-24"][0] == { "timestamp": 100.0, "value": 3.0, "instance": "db-tikv-24", } assert chart["data"]["avg(all instances)"][0] == { "timestamp": 100.0, "value": 2.0, "instance": "avg(all instances)", } assert [row["instance"] for row in chart["metrics"]] == ["db-tikv-19", "db-tikv-24"] assert chart["metrics"][0]["mean"] == 20.1 def test_focused_metric_chart_preserves_label_only_series(): payload = { "metrics": [ { "name": "tidb_qps_total", "metric_group_id": "tidb_qps_total", "chart_data": { "promql": "sum(rate(tidb_server_query_total[2m])) by (type)", "series": [ {"metric": {"type": "Query"}, "values": [[100, "450"], [200, "500"]]}, {"metric": {"type": "Ping"}, "values": [[100, "0"], [200, "0"]]}, ], }, }, ], } chart = _focused_metric_chart(payload, "tidb_qps_total") assert set(chart["data"]) == {"Query", "Ping", "avg(all instances)"} assert chart["data"]["Query"][0] == { "timestamp": 100.0, "value": 450.0, "instance": "Query", } assert chart["data"]["Ping"][0] == { "timestamp": 100.0, "value": 0.0, "instance": "Ping", } assert chart["data"]["avg(all instances)"][0]["value"] == 225.0 def test_focused_metric_chart_404s_when_metric_ref_missing(): with pytest.raises(HTTPException) as exc_info: _focused_metric_chart({"metrics": []}, "tikv_cpu:db") assert exc_info.value.status_code == 404 def test_metric_chart_query_ref_falls_back_to_report_metadata(): rows = [ { "name": "TiDB Total QPS", "metric_group_id": "tidb_total_qps", "promql": "sum(rate(tidb_server_query_total[1m]))", } ] ref = _metric_chart_query_ref( rows, { "cluster_id": "c1", "time_range": {"start": 100, "end": 200, "step": "60s"}, }, ) assert ref == { "promql": "sum(rate(tidb_server_query_total[1m]))", "cluster_id": "c1", "start": 100.0, "end": 200.0, "step": "60s", } def test_allowed_metric_chart_path_accepts_workspace_evidence_metrics_json(): assert _allowed_metric_chart_path("evidences/metrics.json", Path("evidences/metrics.json"))