|
|
|
@ -1,6 +1,6 @@
|
|
|
|
"""Tests for the RT-OSS HTTP server.
|
|
|
|
"""Tests for the RT-OSS HTTP server.
|
|
|
|
|
|
|
|
|
|
|
|
Covers: auth, inference lifecycle (without SDR/ONNX hardware), orchestrator
|
|
|
|
Covers: auth, inference lifecycle (without SDR/ONNX hardware), conductor
|
|
|
|
lifecycle (with mocked executor), and state helpers.
|
|
|
|
lifecycle (with mocked executor), and state helpers.
|
|
|
|
|
|
|
|
|
|
|
|
``start_inference`` and ``_inference_loop`` require real SDR hardware and an
|
|
|
|
``start_inference`` and ``_inference_loop`` require real SDR hardware and an
|
|
|
|
@ -286,17 +286,17 @@ class TestInferenceStop:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
|
|
# ---------------------------------------------------------------------------
|
|
|
|
# POST /orchestrator/deploy
|
|
|
|
# POST /conductor/deploy
|
|
|
|
# ---------------------------------------------------------------------------
|
|
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class TestOrchestratorDeploy:
|
|
|
|
class TestConductorDeploy:
|
|
|
|
def test_deploy_422_on_invalid_config(self, client):
|
|
|
|
def test_deploy_422_on_invalid_config(self, client):
|
|
|
|
with patch(
|
|
|
|
with patch(
|
|
|
|
"ria_toolkit_oss.server.routers.orchestrator.CampaignConfig.from_dict",
|
|
|
|
"ria_toolkit_oss.server.routers.conductor.CampaignConfig.from_dict",
|
|
|
|
side_effect=ValueError("missing required field 'name'"),
|
|
|
|
side_effect=ValueError("missing required field 'name'"),
|
|
|
|
):
|
|
|
|
):
|
|
|
|
resp = client.post("/orchestrator/deploy", json={"config": {}})
|
|
|
|
resp = client.post("/conductor/deploy", json={"config": {}})
|
|
|
|
assert resp.status_code == 422
|
|
|
|
assert resp.status_code == 422
|
|
|
|
|
|
|
|
|
|
|
|
def test_deploy_returns_campaign_id(self, client):
|
|
|
|
def test_deploy_returns_campaign_id(self, client):
|
|
|
|
@ -307,10 +307,10 @@ class TestOrchestratorDeploy:
|
|
|
|
mock_executor.return_value.run.return_value = MagicMock(to_dict=lambda: {})
|
|
|
|
mock_executor.return_value.run.return_value = MagicMock(to_dict=lambda: {})
|
|
|
|
|
|
|
|
|
|
|
|
with (
|
|
|
|
with (
|
|
|
|
patch("ria_toolkit_oss.server.routers.orchestrator.CampaignConfig.from_dict", return_value=mock_cfg),
|
|
|
|
patch("ria_toolkit_oss.server.routers.conductor.CampaignConfig.from_dict", return_value=mock_cfg),
|
|
|
|
patch("ria_toolkit_oss.server.routers.orchestrator.CampaignExecutor", mock_executor),
|
|
|
|
patch("ria_toolkit_oss.server.routers.conductor.CampaignExecutor", mock_executor),
|
|
|
|
):
|
|
|
|
):
|
|
|
|
resp = client.post("/orchestrator/deploy", json={"config": {"name": "test_campaign"}})
|
|
|
|
resp = client.post("/conductor/deploy", json={"config": {"name": "test_campaign"}})
|
|
|
|
|
|
|
|
|
|
|
|
assert resp.status_code == 200
|
|
|
|
assert resp.status_code == 200
|
|
|
|
body = resp.json()
|
|
|
|
body = resp.json()
|
|
|
|
@ -325,23 +325,23 @@ class TestOrchestratorDeploy:
|
|
|
|
mock_executor.return_value.run.return_value = MagicMock(to_dict=lambda: {})
|
|
|
|
mock_executor.return_value.run.return_value = MagicMock(to_dict=lambda: {})
|
|
|
|
|
|
|
|
|
|
|
|
with (
|
|
|
|
with (
|
|
|
|
patch("ria_toolkit_oss.server.routers.orchestrator.CampaignConfig.from_dict", return_value=mock_cfg),
|
|
|
|
patch("ria_toolkit_oss.server.routers.conductor.CampaignConfig.from_dict", return_value=mock_cfg),
|
|
|
|
patch("ria_toolkit_oss.server.routers.orchestrator.CampaignExecutor", mock_executor),
|
|
|
|
patch("ria_toolkit_oss.server.routers.conductor.CampaignExecutor", mock_executor),
|
|
|
|
):
|
|
|
|
):
|
|
|
|
resp = client.post("/orchestrator/deploy", json={"config": {}})
|
|
|
|
resp = client.post("/conductor/deploy", json={"config": {}})
|
|
|
|
|
|
|
|
|
|
|
|
campaign_id = resp.json()["campaign_id"]
|
|
|
|
campaign_id = resp.json()["campaign_id"]
|
|
|
|
assert state_module._campaigns.get(campaign_id) is not None
|
|
|
|
assert state_module._campaigns.get(campaign_id) is not None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
|
|
# ---------------------------------------------------------------------------
|
|
|
|
# GET /orchestrator/status/{campaign_id}
|
|
|
|
# GET /conductor/status/{campaign_id}
|
|
|
|
# ---------------------------------------------------------------------------
|
|
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class TestOrchestratorStatus:
|
|
|
|
class TestConductorStatus:
|
|
|
|
def test_status_404_for_unknown_id(self, client):
|
|
|
|
def test_status_404_for_unknown_id(self, client):
|
|
|
|
resp = client.get("/orchestrator/status/nonexistent-id")
|
|
|
|
resp = client.get("/conductor/status/nonexistent-id")
|
|
|
|
assert resp.status_code == 404
|
|
|
|
assert resp.status_code == 404
|
|
|
|
|
|
|
|
|
|
|
|
def test_status_returns_campaign_state(self, client):
|
|
|
|
def test_status_returns_campaign_state(self, client):
|
|
|
|
@ -357,7 +357,7 @@ class TestOrchestratorStatus:
|
|
|
|
)
|
|
|
|
)
|
|
|
|
state_module._campaigns["abc-123"] = state
|
|
|
|
state_module._campaigns["abc-123"] = state
|
|
|
|
|
|
|
|
|
|
|
|
resp = client.get("/orchestrator/status/abc-123")
|
|
|
|
resp = client.get("/conductor/status/abc-123")
|
|
|
|
assert resp.status_code == 200
|
|
|
|
assert resp.status_code == 200
|
|
|
|
body = resp.json()
|
|
|
|
body = resp.json()
|
|
|
|
assert body["campaign_id"] == "abc-123"
|
|
|
|
assert body["campaign_id"] == "abc-123"
|
|
|
|
@ -367,13 +367,13 @@ class TestOrchestratorStatus:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
|
|
# ---------------------------------------------------------------------------
|
|
|
|
# POST /orchestrator/cancel/{campaign_id}
|
|
|
|
# POST /conductor/cancel/{campaign_id}
|
|
|
|
# ---------------------------------------------------------------------------
|
|
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class TestOrchestratorCancel:
|
|
|
|
class TestConductorCancel:
|
|
|
|
def test_cancel_404_for_unknown_id(self, client):
|
|
|
|
def test_cancel_404_for_unknown_id(self, client):
|
|
|
|
resp = client.post("/orchestrator/cancel/no-such-id")
|
|
|
|
resp = client.post("/conductor/cancel/no-such-id")
|
|
|
|
assert resp.status_code == 404
|
|
|
|
assert resp.status_code == 404
|
|
|
|
|
|
|
|
|
|
|
|
def test_cancel_sets_cancel_event(self, client):
|
|
|
|
def test_cancel_sets_cancel_event(self, client):
|
|
|
|
@ -387,7 +387,7 @@ class TestOrchestratorCancel:
|
|
|
|
)
|
|
|
|
)
|
|
|
|
state_module._campaigns["camp-to-cancel"] = state
|
|
|
|
state_module._campaigns["camp-to-cancel"] = state
|
|
|
|
|
|
|
|
|
|
|
|
resp = client.post("/orchestrator/cancel/camp-to-cancel")
|
|
|
|
resp = client.post("/conductor/cancel/camp-to-cancel")
|
|
|
|
assert resp.status_code == 200
|
|
|
|
assert resp.status_code == 200
|
|
|
|
assert resp.json()["cancelled"] is True
|
|
|
|
assert resp.json()["cancelled"] is True
|
|
|
|
assert cancel_event.is_set()
|
|
|
|
assert cancel_event.is_set()
|
|
|
|
@ -403,7 +403,7 @@ class TestOrchestratorCancel:
|
|
|
|
)
|
|
|
|
)
|
|
|
|
state_module._campaigns["done"] = state
|
|
|
|
state_module._campaigns["done"] = state
|
|
|
|
|
|
|
|
|
|
|
|
resp = client.post("/orchestrator/cancel/done")
|
|
|
|
resp = client.post("/conductor/cancel/done")
|
|
|
|
assert resp.status_code == 200
|
|
|
|
assert resp.status_code == 200
|
|
|
|
assert resp.json()["cancelled"] is False
|
|
|
|
assert resp.json()["cancelled"] is False
|
|
|
|
assert not cancel_event.is_set()
|
|
|
|
assert not cancel_event.is_set()
|
|
|
|
|