feat(swarm): worker agent + fix pre-existing base_repo coverage test
Worker agent (decnet.agent): - mTLS FastAPI service exposing /deploy, /teardown, /status, /health, /mutate. uvicorn enforces CERT_REQUIRED with the DECNET CA pinned. - executor.py offloads the blocking deployer onto asyncio.to_thread so the event loop stays responsive. - server.py refuses to start without an enrolled bundle in ~/.decnet/agent/ — unauthenticated agents are not a supported mode. - docs/openapi disabled on the agent — narrow attack surface. tests/test_base_repo.py: DummyRepo was missing get_attacker_artifacts (pre-existing abstractmethod) and so could not be instantiated. Added the stub + coverage for the new swarm CRUD surface on BaseRepository.
This commit is contained in:
45
tests/swarm/test_agent_app.py
Normal file
45
tests/swarm/test_agent_app.py
Normal file
@@ -0,0 +1,45 @@
|
||||
"""Agent FastAPI app — static/contract checks only.
|
||||
|
||||
We deliberately do NOT spin uvicorn up in-process here: the mTLS layer is
|
||||
enforced by uvicorn itself (via --ssl-cert-reqs 2) and is validated in the
|
||||
VM integration suite. What we CAN assert in unit scope is the route
|
||||
surface + request/response schema.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from decnet.agent.app import app
|
||||
|
||||
|
||||
def test_health_endpoint() -> None:
|
||||
client = TestClient(app)
|
||||
resp = client.get("/health")
|
||||
assert resp.status_code == 200
|
||||
assert resp.json() == {"status": "ok"}
|
||||
|
||||
|
||||
def test_status_when_not_deployed() -> None:
|
||||
client = TestClient(app)
|
||||
resp = client.get("/status")
|
||||
assert resp.status_code == 200
|
||||
body = resp.json()
|
||||
assert "deployed" in body
|
||||
assert "deckies" in body
|
||||
|
||||
|
||||
def test_mutate_is_501() -> None:
|
||||
client = TestClient(app)
|
||||
resp = client.post("/mutate", json={"decky_id": "decky-01", "services": ["ssh"]})
|
||||
assert resp.status_code == 501
|
||||
|
||||
|
||||
def test_deploy_rejects_malformed_body() -> None:
|
||||
client = TestClient(app)
|
||||
resp = client.post("/deploy", json={"not": "a config"})
|
||||
assert resp.status_code == 422 # pydantic validation
|
||||
|
||||
|
||||
def test_route_set() -> None:
|
||||
paths = {r.path for r in app.routes if hasattr(r, "path")}
|
||||
assert {"/health", "/status", "/deploy", "/teardown", "/mutate"} <= paths
|
||||
Reference in New Issue
Block a user