incident_commander / scripts /test-local.py
Rohith9059's picture
Expand local validation coverage
502e16d
Raw History Blame Contribute Delete
4.1 kB
from __future__ import annotations
import json
import os
import sys
from typing import List
import requests
BASE_URL = os.getenv("ENV_URL", "http://localhost:7860")
TASKS: List[str] = ["easy", "medium", "hard", "longhaul", "blackout"]
def _assert(condition: bool, message: str) -> None:
if not condition:
raise AssertionError(message)
def _post(path: str, **kwargs):
response = requests.post(f"{BASE_URL}{path}", timeout=20, **kwargs)
response.raise_for_status()
return response.json()
def _get(path: str, **kwargs):
response = requests.get(f"{BASE_URL}{path}", timeout=20, **kwargs)
response.raise_for_status()
return response.json()
def run() -> None:
health = _get("/health")
_assert(health.get("status") == "ok", "health endpoint failed")
tasks = _get("/tasks").get("tasks", [])
task_ids = sorted(task["id"] for task in tasks)
_assert(task_ids == sorted(TASKS), f"task list mismatch: {task_ids}")
for task_id in TASKS:
reset_a = _post("/reset", params={"task_id": task_id, "seed": 123})
obs_a = reset_a["observation"]
reset_b = _post("/reset", params={"task_id": task_id, "seed": 123})
obs_b = reset_b["observation"]
_assert(obs_a == obs_b, f"reset determinism failed for {task_id}")
step_payload = {
"action_type": "scale_up_replicas",
"target_service": "frontend",
"delta_instances": 1,
"fallback_service": None,
"note": "test step",
}
step = _post("/step", params={"task_id": task_id}, json=step_payload)
_assert("observation" in step and "reward" in step and "done" in step, f"step response invalid for {task_id}")
grade = _get("/grade", params={"task_id": task_id})
score = float(grade.get("score", -1))
_assert(0.0 <= score <= 1.0, f"grade out of range for {task_id}: {score}")
metrics = _get("/metrics", params={"task_id": task_id})
for key in ["uptime_score", "latency_score", "sla_score", "cost_score", "recovery_score", "action_discipline_score"]:
value = float(metrics.get(key, -1))
_assert(0.0 <= value <= 1.0, f"metric out of range for {task_id}:{key}={value}")
trace = metrics.get("reward_trace", [])
_assert(isinstance(trace, list), f"reward_trace must be list for {task_id}")
metrics_with_trace = _get("/metrics", params={"task_id": task_id, "include_trace": "true"})
_assert(isinstance(metrics_with_trace.get("reward_trace", None), list), f"reward_trace should be present when include_trace=true for {task_id}")
metrics_no_trace = _get("/metrics", params={"task_id": task_id, "include_trace": "false"})
_assert("reward_trace" not in metrics_no_trace, f"reward_trace should be omitted when include_trace=false for {task_id}")
viz = _get("/visualize", params={"task_id": task_id})
_assert(viz.get("task_id") == task_id, f"visualize task mismatch for {task_id}")
_assert("ascii" in viz and isinstance(viz["ascii"], str) and len(viz["ascii"]) > 0, f"visualize ascii missing for {task_id}")
baseline = _get("/baseline", params={"task_id": task_id, "episodes": 2})
_assert(baseline.get("task_id") == task_id, f"baseline task mismatch for {task_id}")
_assert(int(baseline.get("episodes", 0)) == 2, f"baseline episodes mismatch for {task_id}")
baseline_avg = float(baseline.get("avg_score", -1))
_assert(0.0 <= baseline_avg <= 1.0, f"baseline avg score out of range for {task_id}: {baseline_avg}")
baseline_scores = baseline.get("scores", [])
_assert(isinstance(baseline_scores, list) and len(baseline_scores) == 2, f"baseline scores malformed for {task_id}")
print(json.dumps({"status": "ok", "checked_tasks": TASKS}))
if __name__ == "__main__":
try:
run()
except Exception as exc:
print(f"test-local failed: {exc}")
print("hint: start the server first, e.g. `python -m uvicorn app.main:app --host 0.0.0.0 --port 7860`")
sys.exit(1)