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.
46 lines
1.4 KiB
Python
46 lines
1.4 KiB
Python
"""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
|