Publish curated Unraid-AppOps-Gateway source from c61e0e1e292914893b40354f904f23dd9fd4a958
This commit is contained in:
1 parent
b47ce43436
commit
9b94d8d0f5
18 files changed
+1651
-75
No files matched your search
@@ -1482,3 +1482,42 @@ def test_mcp_sdk_redaction_preserves_schema_valid_calls_and_domain_denials():
|
||||
assert "policy_denied" in denied.content[0].text
|
||||
asyncio.run(exercise())
|
||||
assert calls == [True, False]
|
||||
|
||||
|
||||
def test_public_mcp_acceptance_list_preview_request_and_replay_are_consistent(integration_client, monkeypatch):
|
||||
from backend.app import mcp_server
|
||||
from backend.app.services import deployment_broker
|
||||
from backend.app.db.models import Approval, AuditEvent
|
||||
_, engine = integration_client
|
||||
calls = []
|
||||
def broker(*args, **kwargs):
|
||||
calls.append(kwargs)
|
||||
return {"status": "ready" if kwargs["preflight"] else "quiesced", "revision": "d"*40,
|
||||
"preservedContainers": 18, "private": "Bearer SECRET-CANARY"}
|
||||
monkeypatch.setattr(deployment_broker.DeploymentBrokerClient, "runner_acceptance", broker)
|
||||
async def exercise():
|
||||
async with Client(mcp_server.appops_mcp) as client:
|
||||
listed = (await client.call_tool("get_action_registry", {})).structured_content
|
||||
by_id = {item["id"]: item for item in listed["items"]}
|
||||
for action in ("runner.acceptance.preflight", "runner.acceptance.quiesce"):
|
||||
assert by_id[action]["mcpExecutionMode"] == "direct_typed"
|
||||
assert by_id[action]["manualExecutionMode"] == "governance_only"
|
||||
preview = (await client.call_tool("preview_action", {"action": action, "target": "tower/ci-acceptance-residue"})).structured_content
|
||||
assert preview["mcpExecutionSupported"] is True and preview["executed"] is False
|
||||
args = {"action": action, "target": "tower/ci-acceptance-residue",
|
||||
"reason": "Preserve finite residue. Authorization: Bearer SECRET-CANARY",
|
||||
"idempotencyKey": "public-acceptance-"+action}
|
||||
result = (await client.call_tool("server.operation.request", args)).structured_content
|
||||
assert result["executed"] is True and result["executionSupported"] is True
|
||||
assert result["controllerStatus"] == ("ready" if action.endswith("preflight") else "quiesced")
|
||||
assert result["originalPolicyDecision"] == ("allowed" if action.endswith("preflight") else "approval_required")
|
||||
replay = (await client.call_tool("server.operation.request", args)).structured_content
|
||||
assert replay["idempotentReplay"] is True and replay["jobId"] == result["jobId"]
|
||||
assert "SECRET-CANARY" not in json.dumps(result)
|
||||
denied = (await client.call_tool("preview_action", {"action": "container.stop", "target": "tower/ci-acceptance-residue"})).structured_content
|
||||
assert denied["policyDecision"] == "blocked"
|
||||
asyncio.run(exercise())
|
||||
assert len(calls) == 2
|
||||
with Session(engine) as session:
|
||||
assert session.exec(select(Approval)).all() == []
|
||||
assert "SECRET-CANARY" not in json.dumps([row.model_dump(mode="json") for row in session.exec(select(AuditEvent)).all()])
|
||||
Reference in new issue
Block a user