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