Download tests/test_endpoints.py from jester1177/cloudnative-devops-debug-env: direct link, hf CLI and curl.
- Browser
- Download file 4.86 kB
-
https://huggingface.co/spaces/jester1177/cloudnative-devops-debug-env/resolve/main/tests/test_endpoints.py
- Command line
-
hf download hf://spaces/jester1177/cloudnative-devops-debug-env/tests/test_endpoints.py
-
curl -L -o test_endpoints.py https://huggingface.co/spaces/jester1177/cloudnative-devops-debug-env/resolve/main/tests/test_endpoints.py
4.86 kB
| """Endpoint tests for the FastAPI server.""" | |
| from fastapi.testclient import TestClient | |
| from server.app import app | |
| client = TestClient(app) | |
| def test_root_landing_page(): | |
| response = client.get("/") | |
| assert response.status_code == 200 | |
| assert "text/html" in response.headers.get("content-type", "") | |
| assert "CI/CD" in response.text | |
| def test_health_endpoint(): | |
| response = client.get("/health") | |
| assert response.status_code == 200 | |
| data = response.json() | |
| assert data["status"] == "healthy" | |
| def test_info_returns_all_tasks(): | |
| info = client.get("/info") | |
| assert info.status_code == 200 | |
| data = info.json() | |
| assert len(data.get("tasks", [])) >= 6 | |
| assert "action_space" in data | |
| assert "observation_space" in data | |
| def test_tasks_endpoint(): | |
| tasks = client.get("/tasks") | |
| assert tasks.status_code == 200 | |
| data = tasks.json() | |
| assert len(data.get("tasks", [])) >= 6 | |
| task_ids = [t["id"] for t in data["tasks"]] | |
| assert "dockerfile_syntax" in task_ids | |
| assert "multi_stage_pipeline_matrix" in task_ids | |
| def test_reset_default(): | |
| resp = client.post("/reset", json={}) | |
| assert resp.status_code == 200 | |
| data = resp.json() | |
| assert "observation" in data | |
| obs = data["observation"] | |
| assert obs["total_issues"] >= 1 | |
| assert obs["step_number"] == 0 | |
| def test_reset_specific_task(): | |
| resp = client.post("/reset", json={"task_id": "dockerfile_syntax", "scenario_id": "typo_filename"}) | |
| assert resp.status_code == 200 | |
| obs = resp.json()["observation"] | |
| assert obs["task_id"] == "dockerfile_syntax" | |
| def test_reset_with_seed(): | |
| resp1 = client.post("/reset", json={"seed": 99}) | |
| resp2 = client.post("/reset", json={"seed": 99}) | |
| assert resp1.json()["observation"]["task_id"] == resp2.json()["observation"]["task_id"] | |
| def test_reset_invalid_task(): | |
| resp = client.post("/reset", json={"task_id": "nonexistent_task"}) | |
| assert resp.status_code == 400 | |
| def test_state_without_reset(): | |
| # Force a fresh app state by not resetting — this test relies on prior reset | |
| # Just verify the endpoint returns 200 (prior test did a reset) | |
| resp = client.get("/state") | |
| assert resp.status_code == 200 | |
| data = resp.json() | |
| assert "observation" in data | |
| assert "episode_reward" in data | |
| def test_step_edit_file(): | |
| client.post("/reset", json={"task_id": "dockerfile_syntax", "scenario_id": "typo_filename"}) | |
| resp = client.post("/step", json={ | |
| "action": { | |
| "action_type": "edit_file", | |
| "edits": [{ | |
| "file_path": "Dockerfile", | |
| "old_content": "COPY requirments.txt .", | |
| "new_content": "COPY requirements.txt .", | |
| }], | |
| } | |
| }) | |
| assert resp.status_code == 200 | |
| data = resp.json() | |
| assert data["reward"] > 0 | |
| assert data["info"]["issues_fixed"] >= 1 | |
| def test_step_submit(): | |
| client.post("/reset", json={"task_id": "dockerfile_syntax"}) | |
| resp = client.post("/step", json={"action": {"action_type": "submit"}}) | |
| assert resp.status_code == 200 | |
| assert resp.json()["done"] is True | |
| def test_step_request_hint(): | |
| client.post("/reset", json={"task_id": "dockerfile_syntax"}) | |
| resp = client.post("/step", json={"action": {"action_type": "request_hint"}}) | |
| assert resp.status_code == 200 | |
| obs = resp.json()["observation"] | |
| assert obs["hints_used"] == 1 | |
| assert "Hint" in (obs.get("last_action_feedback") or "") | |
| def test_grader_endpoint(): | |
| trajectory = [ | |
| {"step": 1, "action": {"action_type": "edit_file", "edits": [{"file_path": "Dockerfile"}]}, | |
| "reward": 0.3, "done": True, "info": {"issues_fixed": 1, "issues_total": 1}}, | |
| ] | |
| resp = client.post("/grader", json={"task_id": "dockerfile_syntax", "trajectory": trajectory}) | |
| assert resp.status_code == 200 | |
| result = resp.json()["result"] | |
| assert result["score"] == 1.0 | |
| def test_grader_empty_trajectory(): | |
| resp = client.post("/grader", json={"task_id": "dockerfile_syntax", "trajectory": []}) | |
| assert resp.status_code == 200 | |
| assert resp.json()["result"]["score"] == 0.0 | |
| def test_full_episode_via_api(): | |
| """Full episode: reset -> edit -> submit -> verify score.""" | |
| client.post("/reset", json={"task_id": "dockerfile_syntax", "scenario_id": "typo_filename"}) | |
| client.post("/step", json={ | |
| "action": { | |
| "action_type": "edit_file", | |
| "edits": [{ | |
| "file_path": "Dockerfile", | |
| "old_content": "COPY requirments.txt .", | |
| "new_content": "COPY requirements.txt .", | |
| }], | |
| } | |
| }) | |
| resp = client.post("/step", json={"action": {"action_type": "submit"}}) | |
| assert resp.json()["done"] is True | |
| state = client.get("/state") | |
| assert state.json()["done"] is True | |
| assert state.json()["episode_reward"] > 0 | |