feat(ACTIVITY-WP-0029): inventory callers, retarget sweep, bound execution
Map every State Hub/core-hub caller to a post-retirement owner. Keep the 15-minute sweep schedule here and point the engine at repo-manager (State Hub dual-run by default, REPO_MANAGER_URL when present). Publish GET /execution/semantics and 410 workplan launch routes so State Hub /execution/* is not re-homed as a task database. T03 still waits on HUB-WP-0004.
This commit is contained in:
parent
df3330f165
commit
f6cfc28c33
12 changed files with 359 additions and 12 deletions
39
tests/test_execution_api.py
Normal file
39
tests/test_execution_api.py
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from fastapi import FastAPI
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from activity_core.execution_api import router
|
||||
|
||||
|
||||
def _client() -> TestClient:
|
||||
app = FastAPI()
|
||||
app.include_router(router)
|
||||
return TestClient(app)
|
||||
|
||||
|
||||
def test_execution_semantics_names_boundary() -> None:
|
||||
client = _client()
|
||||
response = client.get("/execution/semantics")
|
||||
assert response.status_code == 200
|
||||
body = response.json()
|
||||
assert body["port"] == "port.schedule"
|
||||
assert any("ops_run" in item for item in body["activity_core_owns"])
|
||||
assert any("workplan" in item.lower() for item in body["activity_core_does_not_own"])
|
||||
assert body["replacements"]["GET /execution/launch-requests"] == "GET /ops-runs"
|
||||
|
||||
|
||||
def test_execution_workplan_routes_are_gone() -> None:
|
||||
client = _client()
|
||||
gone = [
|
||||
client.get("/execution/launch-requests"),
|
||||
client.post("/execution/launch-requests", json={"workplan_id": "x"}),
|
||||
client.get("/execution/workplan-stack"),
|
||||
client.patch("/execution/workplans/abc/intent", json={}),
|
||||
client.patch("/execution/workstreams/abc/intent", json={}),
|
||||
]
|
||||
for response in gone:
|
||||
assert response.status_code == 410
|
||||
payload = response.json()
|
||||
assert "replacement_ref" in payload
|
||||
assert "execution-queue-boundary" in payload["document"]
|
||||
|
|
@ -553,6 +553,9 @@ def test_consistency_sweep_remote_all_posts_batch(monkeypatch) -> None:
|
|||
)
|
||||
|
||||
monkeypatch.setenv("STATE_HUB_URL", "http://state-hub.test/")
|
||||
monkeypatch.delenv("REPO_MANAGER_URL", raising=False)
|
||||
monkeypatch.delenv("CONSISTENCY_SWEEP_URL", raising=False)
|
||||
monkeypatch.delenv("CONSISTENCY_SWEEP_PATH", raising=False)
|
||||
monkeypatch.setattr(httpx, "post", fake_post)
|
||||
|
||||
result = StateHubContextResolver().resolve(
|
||||
|
|
@ -563,6 +566,9 @@ def test_consistency_sweep_remote_all_posts_batch(monkeypatch) -> None:
|
|||
|
||||
assert result["exit_code"] == 0
|
||||
assert result["repos_processed"][0]["repo_slug"] == "state-hub"
|
||||
assert result["engine_owner"] == "repo-manager"
|
||||
assert result["adapter"] == "state-hub-dual-run"
|
||||
assert result["sweep_url"] == "http://state-hub.test/consistency/sweep/remote-all"
|
||||
assert calls == [
|
||||
{
|
||||
"url": "http://state-hub.test/consistency/sweep/remote-all",
|
||||
|
|
@ -572,6 +578,37 @@ def test_consistency_sweep_remote_all_posts_batch(monkeypatch) -> None:
|
|||
]
|
||||
|
||||
|
||||
def test_consistency_sweep_uses_repo_manager_url(monkeypatch) -> None:
|
||||
calls: list[dict[str, Any]] = []
|
||||
|
||||
def fake_post(url: str, **kwargs: Any) -> DummyResponse:
|
||||
calls.append({"url": url, **kwargs})
|
||||
return DummyResponse(
|
||||
{
|
||||
"exit_code": 0,
|
||||
"lock_skipped": False,
|
||||
"repos_processed": [],
|
||||
}
|
||||
)
|
||||
|
||||
monkeypatch.setenv("STATE_HUB_URL", "http://state-hub.test/")
|
||||
monkeypatch.setenv("REPO_MANAGER_URL", "http://repo-manager.test")
|
||||
monkeypatch.setenv("CONSISTENCY_SWEEP_PATH", "/v1/consistency/sweep/remote-all")
|
||||
monkeypatch.setattr(httpx, "post", fake_post)
|
||||
|
||||
result = StateHubContextResolver().resolve(
|
||||
"consistency_sweep_remote_all",
|
||||
None,
|
||||
{"max_seconds": 300},
|
||||
)
|
||||
|
||||
assert result["adapter"] == "repo-manager"
|
||||
assert result["engine_owner"] == "repo-manager"
|
||||
assert calls[0]["url"] == (
|
||||
"http://repo-manager.test/v1/consistency/sweep/remote-all"
|
||||
)
|
||||
|
||||
|
||||
def test_consistency_sweep_remote_all_failure_bubbles(monkeypatch) -> None:
|
||||
def fake_post(url: str, **kwargs: Any) -> DummyResponse:
|
||||
raise httpx.ConnectError("offline")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue