cloudnative-devops-debug-env / tests /test_endpoints.py
Krishna1107's picture
ready for first submission, fixed openenv and multi mode deployment errors
498f684
Raw History Blame Contribute Delete
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