Files
ModelForge-Public/backend/tests/test_lab_execution_api.py
T

107 lines
3.7 KiB
Python

from datetime import UTC, datetime
from unittest.mock import Mock
from uuid import uuid4
from fastapi import FastAPI
from fastapi.testclient import TestClient
from modelforge_api.api.authorization import (
Principal,
PrincipalRole,
authenticate_operator_principal,
)
from modelforge_api.api.routes.lab import get_lab_run_service, router
from modelforge_api.domain.lab import LabExecutionRunResponse, LabInputSummary
def start_body() -> dict[str, object]:
return {
"target": {
name: str(uuid4())
for name in (
"deployment_candidate_id",
"artifact_set_id",
"runtime_profile_id",
"compute_node_id",
"execution_approval_id",
)
},
"input": {"capability": "rag.embedding", "payload": {"input": "private-lab-canary"}},
"deployment_id": str(uuid4()),
"experiment_route_id": str(uuid4()),
}
def harness(role: PrincipalRole) -> tuple[TestClient, Mock]:
app = FastAPI()
app.include_router(router)
service = Mock()
service.start.return_value = LabExecutionRunResponse(
id=uuid4(),
status="accepted",
target_snapshot={"deployment_id": str(uuid4())},
input_summary=LabInputSummary(sha256="a" * 64, item_count=1, encoded_bytes=45),
input_payload_expires_at=datetime.now(UTC),
retention_seconds=300,
created_at=datetime.now(UTC),
)
app.dependency_overrides[authenticate_operator_principal] = lambda: Principal(
"operator-one", role, "test"
)
app.dependency_overrides[get_lab_run_service] = lambda: service
return TestClient(app), service
def test_operator_lab_start_route_is_registered_and_returns_accepted_run() -> None:
client, service = harness(PrincipalRole.OPERATOR)
response = client.post(
"/api/v1/lab/runs",
headers={"Idempotency-Key": "start-once"},
json=start_body(),
)
assert response.status_code == 202
payload = response.json()
assert payload["status"] == "accepted"
assert payload["capability"] == "rag.embedding@1"
assert "private-lab-canary" not in response.text
assert response.headers["cache-control"] == "no-store"
service.start.assert_called_once()
assert service.start.call_args.kwargs["actor_subject"] == "operator-one"
assert service.start.call_args.kwargs["idempotency_key"] == "start-once"
def test_lab_run_start_requires_operator_role() -> None:
client, service = harness(PrincipalRole.VIEWER)
response = client.post(
"/api/v1/lab/runs",
headers={"Idempotency-Key": "start-viewer"},
json=start_body(),
)
assert response.status_code == 403
service.start.assert_not_called()
def test_lab_run_status_and_cancel_are_no_store_and_actor_scoped() -> None:
client, service = harness(PrincipalRole.OPERATOR)
run_id = service.start.return_value.id
service.get.return_value = service.start.return_value
service.cancel.return_value = service.start.return_value
status_response = client.get(f"/api/v1/lab/runs/{run_id}")
cancel_response = client.post(f"/api/v1/lab/runs/{run_id}/cancel")
assert status_response.status_code == 200
assert cancel_response.status_code == 200
assert status_response.headers["cache-control"] == "no-store"
assert cancel_response.headers["cache-control"] == "no-store"
assert "payload_reference" not in status_response.text
assert "private-lab-canary" not in status_response.text
assert service.get.call_args.args == (run_id,)
assert service.get.call_args.kwargs == {"actor_subject": "operator-one"}
assert service.cancel.call_args.args == (run_id,)
assert service.cancel.call_args.kwargs == {"actor_subject": "operator-one"}