matter-os / tests /integration /test_api.py
tmepass000's picture
MATTER OS v0.1.0
87b48de verified
Raw History Blame Contribute Delete
7.29 kB
"""Smoke-tests every section-14 API operation through HTTP."""
import pytest
from fastapi.testclient import TestClient
@pytest.fixture(scope="module")
def client(tmp_path_factory):
from apps.api import create_app
home = tmp_path_factory.mktemp("api_home")
return TestClient(create_app(home=str(home)))
def test_all_section14_operations(client):
V = "/api/v1"
assert client.get("/").status_code == 200 and "Mission board" in client.get("/").text
assert client.get("/static/viewer.js").status_code == 200
# Project
p = client.post(f"{V}/projects", json={"name": "api"}).json(); pid = p["project_id"]
assert client.put(f"{V}/projects/{pid}/goal", json={"statement": "g"}).json()["goal"]["statement"] == "g"
assert client.put(f"{V}/projects/{pid}/constraints", json={"allowed_elements": ["Cu"]}).json()["constraints"]
# Candidate
g = client.post(f"{V}/candidates/generate", json={"project_id": pid, "generator": "known_family",
"params": {"kind": "fcc", "element": "Cu", "a": 3.6, "cubic": True}}).json()
cid = g["candidate_id"]
assert client.post(f"{V}/candidates/generate", json={"project_id": pid, "generator": "learned_model"}).json()["status"] == "NOT_SUPPORTED"
t = client.post(f"{V}/candidates/{cid}/transform", json={"operation": "substitute", "params": {"index": 0, "new_symbol": "Ni"}}).json()
assert t["parent_ids"] == [cid]
assert client.post(f"{V}/candidates/validate_schema", json={"bad": 1}).json()["valid"] is False
assert client.get(f"{V}/candidates/compare?a={cid}&b={t['candidate_id']}").json()["same_composition"] is False
assert "Cu" in client.get(f"{V}/candidates/{cid}/export?fmt=xyz").text
imp = client.post(f"{V}/candidates/import?project_id={pid}&fmt=xyz", content="2\n\nH 0 0 0\nH 0 0 0.74\n", headers={"content-type": "text/plain"})
assert imp.status_code == 200 and imp.json()["composition"] == {"H": 2}
assert "unified" in client.get(f"{V}/candidates/{cid}").json()
# Simulation
assert any(s["solver_id"] == "ase_emt" and s["compatible"] for s in client.get(f"{V}/simulation/compatible?candidate_id={cid}&observable=energy").json())
assert client.get(f"{V}/simulation/estimate?candidate_id={cid}&solver_id=ase_emt&observable=energy").json()["compatible"]
run = client.post(f"{V}/simulation/runs", json={"candidate_id": cid, "solver_id": "ase_emt", "observable": "energy"}).json()
assert run["exit_status"] == "SUCCESS"
assert client.get(f"{V}/simulation/jobs/{run['provenance']['job_id']}").json()["status"] == "done"
arts = client.get(f"{V}/simulation/runs/{run['run_id']}/artifacts").json()
assert arts and client.get(f"{V}/artifacts/{arts[0]['artifact_id']}").status_code == 200
assert len(client.get(f"{V}/simulation/solvers").json()) == 15
# Evidence
# a single-point energy has no convergence test ('not_applicable') -> does not satisfy the M2 gate
assert client.post(f"{V}/evidence/{cid}/maturity").json()["level"] == "M1"
client.post(f"{V}/simulation/runs", json={"candidate_id": cid, "solver_id": "ase_emt", "observable": "lattice_constant"})
assert client.post(f"{V}/evidence/{cid}/maturity").json()["level"] == "M2"
cl = client.post(f"{V}/evidence/{cid}/claims", json={"claim_text": "t"}).json(); assert cl["maturity_level"] == "M2"
assert client.post(f"{V}/evidence/compare_sources", json=[{"source": "a", "value": 1.0, "unit": "eV"}, {"source": "b", "value": 1.1, "unit": "eV"}]).json()["comparable"]
# Knowledge
ev = client.post(f"{V}/knowledge/events", json={"subject": "s", "predicate": "p", "object": 1}).json(); assert ev["status"] == "proposed"
assert client.post(f"{V}/knowledge/events/{ev['fact_id']}/verify").status_code == 400
assert client.get(f"{V}/knowledge/search?text={cid}").json()["facts"]
assert client.get(f"{V}/knowledge/lineage/{t['candidate_id']}").json()["ancestors"]
# Resource
assert client.get(f"{V}/resources/capacity").json()["effective_concurrency"] >= 1
a = client.post(f"{V}/resources/allocate?job_id=probe&priority=validation", json={}).json(); assert a["granted"]
client.post(f"{V}/resources/release?job_id=probe")
assert client.post(f"{V}/resources/enforce_quota", json={"wall_time_s": 1e9}).status_code == 429
assert client.post(f"{V}/resources/checkpoint/{run['provenance']['job_id']}").json()["job_id"]
assert client.get(f"{V}/resources/integrity").json()["bad_runs"] == []
# Mission + Agent
m = client.post(f"{V}/missions", json={"project_id": pid, "research_question": "q", "autonomy_mode": "approval-required",
"spec": {"track": "lj_cluster", "n_atoms": 7, "seed": 1, "n_random": 2, "evo_pop": 3, "evo_generations": 1, "n_select": 2}}).json()
mid = m["mission_id"]
assert len(client.post(f"{V}/missions/{mid}/plan").json()["tasks"]) == 13
assert client.post(f"{V}/missions/{mid}/run?background=false").json()["state"] == "awaiting_approval"
client.post(f"{V}/missions/{mid}/approve")
assert client.post(f"{V}/missions/{mid}/run?background=false").json()["state"] == "completed"
assert client.post(f"{V}/missions/{mid}/pause").status_code == 200
assert client.post(f"{V}/missions/{mid}/resume").status_code == 400 # completed missions cannot resume
br = client.post(f"{V}/missions/{mid}/branch", json={"research_question": "b"}).json(); assert br["parent_mission_id"] == mid
assert client.post(f"{V}/missions/{br['mission_id']}/cancel").status_code == 400
assert client.post(f"{V}/missions/{br['mission_id']}/cancel?confirm=true").json()["state"] == "cancelled"
assert len([r for r in client.get(f"{V}/agents").json() if not r["dynamic"]]) == 13
assert client.post(f"{V}/agents/messages", json={"sender": "a", "recipient": "coordinator", "body": {}, "mission_id": mid}).json()["recipient"] == "research_coordinator"
assert client.get(f"{V}/agents/messages?mission_id={mid}").json()
assert client.post(f"{V}/agents/publish_result?role=data_steward&mission_id={mid}", json={"x": 1}).json()["status"] == "proposed"
assert client.post(f"{V}/agents/request_review?requester=a&reviewer=b&mission_id={mid}&question=q").status_code == 200
assert client.post(f"{V}/agents/assign_task?role=wrong&mission_id={mid}&stage=novelty").status_code == 400
assert all(b["passed"] for b in client.post(f"{V}/agents/benchmarks").json())
# Export
assert client.get(f"{V}/export/structure/{cid}?fmt=cif").status_code == 200
assert client.get(f"{V}/export/run/{run['run_id']}").content[:2] == b"\x1f\x8b"
assert client.get(f"{V}/export/report/{mid}").text.startswith("# MATTER OS evidence report")
assert client.get(f"{V}/export/project/{pid}").content[:2] == b"\x1f\x8b"
# dashboard data / viewer
assert "maturity_counts" in client.get(f"{V}/dashboard/summary").json()
v = client.get(f"{V}/viewer/{cid}?run_id={run['run_id']}").json()
assert v["atoms"] and "disclaimer" in v["evidence_state"]
assert client.get(f"{V}/observability/audit?limit=5").json()
assert client.post(f"{V}/projects/{pid}/archive").status_code == 400
assert client.post(f"{V}/projects/{pid}/archive?confirm=true").json()["archived"]