Download fastapi_app/test_analysis_api.py from JavideuS/Spooky: direct link, hf CLI and curl.
- Browser
- Download file 3.8 kB
-
https://huggingface.co/spaces/JavideuS/Spooky/resolve/main/fastapi_app/test_analysis_api.py
- Command line
-
hf download hf://spaces/JavideuS/Spooky/fastapi_app/test_analysis_api.py
-
curl -L -o test_analysis_api.py https://huggingface.co/spaces/JavideuS/Spooky/resolve/main/fastapi_app/test_analysis_api.py
3.8 kB
| """ | |
| Smoke coverage for the read-only /v1/analysis/* endpoints (analysis_api.py). | |
| These need at least one aggregatable sweep under SPOOKY_BENCHMARKS_DIR | |
| (default <repo>/results/sweeps). That tree isn't committed, so every test | |
| skips cleanly when it's absent rather than failing on a fresh checkout / CI. | |
| """ | |
| import pytest | |
| from fastapi.testclient import TestClient | |
| from api import app | |
| from analysis_api import _sweep_dir_map | |
| def _first_sweep_id(): | |
| ids = list(_sweep_dir_map().keys()) | |
| if not ids: | |
| pytest.skip("no sweeps under SPOOKY_BENCHMARKS_DIR") | |
| # newest-first, matching the /sweeps ordering | |
| with TestClient(app) as client: | |
| return client.get("/v1/analysis/sweeps").json()["sweeps"][0]["sweep_id"] | |
| def test_list_sweeps_shape(): | |
| with TestClient(app) as client: | |
| body = client.get("/v1/analysis/sweeps").json() | |
| assert "sweeps" in body and body["sweep_count"] == len(body["sweeps"]) | |
| for entry in body["sweeps"]: | |
| assert entry["sweep_id"] | |
| assert set(entry) >= {"solvers", "grid_sizes", "n_completed", "git_commit"} | |
| def test_summary_and_recommend_agree_on_solvers(): | |
| sweep_id = _first_sweep_id() | |
| with TestClient(app) as client: | |
| summary = client.get(f"/v1/analysis/sweeps/{sweep_id}/summary") | |
| assert summary.status_code == 200, summary.text | |
| assert isinstance(summary.json()["statistical_tests"], list) | |
| rec = client.get(f"/v1/analysis/sweeps/{sweep_id}/recommend") | |
| assert rec.status_code == 200, rec.text | |
| body = rec.json() | |
| assert body["solvers"], "recommend returned no solvers for the whole sweep" | |
| # sorted best-first: success rate descending | |
| rates = [s["success_rate"] for s in body["solvers"]] | |
| assert rates == sorted(rates, reverse=True) | |
| assert body["verdict"] | |
| def test_plots_return_plotly_json(): | |
| sweep_id = _first_sweep_id() | |
| with TestClient(app) as client: | |
| for name in ("scaling", "success_rate", "variable_reduction"): | |
| res = client.get(f"/v1/analysis/sweeps/{sweep_id}/plots/{name}") | |
| assert res.status_code == 200, (name, res.text) | |
| assert "data" in res.json() | |
| assert ( | |
| client.get(f"/v1/analysis/sweeps/{sweep_id}/plots/bogus").status_code == 404 | |
| ) | |
| def test_by_instance_and_filtered_plot(): | |
| sweep_id = _first_sweep_id() | |
| with TestClient(app) as client: | |
| grids = client.get("/v1/analysis/sweeps").json()["sweeps"][0]["grid_sizes"] | |
| assert grids, "sweep has no grid sizes" | |
| grid = grids[0] | |
| rows = client.get( | |
| f"/v1/analysis/sweeps/{sweep_id}/by-instance?grid_size={grid}" | |
| ) | |
| assert rows.status_code == 200, rows.text | |
| body = rows.json() | |
| assert body["row_count"] == len(body["rows"]) > 0 | |
| for row in body["rows"]: | |
| assert row["grid_size"] == grid | |
| assert 0.0 <= row["success_rate"] <= 1.0 | |
| assert isinstance(row["failure_causes"], dict) | |
| # a filterable plot honours grid_size; scaling ignores it (still 200) | |
| assert ( | |
| client.get( | |
| f"/v1/analysis/sweeps/{sweep_id}/plots/success_rate?grid_size={grid}" | |
| ).status_code | |
| == 200 | |
| ) | |
| assert ( | |
| client.get( | |
| f"/v1/analysis/sweeps/{sweep_id}/plots/scaling?grid_size={grid}" | |
| ).status_code | |
| == 200 | |
| ) | |
| assert ( | |
| client.get( | |
| f"/v1/analysis/sweeps/{sweep_id}/by-instance?grid_size=999x999" | |
| ).status_code | |
| == 404 | |
| ) | |
| def test_unknown_sweep_404(): | |
| with TestClient(app) as client: | |
| assert ( | |
| client.get("/v1/analysis/sweeps/does_not_exist/summary").status_code == 404 | |
| ) | |