"""Two-phase probe driven by the Docker runner around a real backend restart.""" import asyncio import json import os from pathlib import Path import sys import time import uuid sys.path.insert(0, "/test/backend") sys.path.insert(0, "/test/tests") from integration.test_mcp import connect, call, options, read_service from mcp_api.store import Store STATE = Path("/tmp/firegex-mcp-restart.json") URL = "http://127.0.0.1:4444/" async def prepare(): store = Store(os.environ["FIREGEX_MCP_TEST_DB"]) store.open() credential = store.token_create("restart-probe", "admin", 1) store.close() async with connect(URL, credential) as client: name = "restart-" + uuid.uuid4().hex[:12] spec = {"name": name, "addresses": [{"ip_int": "127.0.0.1", "port": 23456}]} opts = options() service = await call(client, "fgx_service_apply", spec=spec, options=opts) before = (await call(client, "fgx_firewall_get"))["data"] change = await call(client, "fgx_firewall_apply", patch={"settings": {"allow_icmp": not before["settings"]["allow_icmp"]}}, options=options(before["revision"], confirm_within_seconds=5)) STATE.write_text(json.dumps({"credential": credential, "service": service, "spec": spec, "options": opts, "revision": before["revision"], "change_id": change["change"]["id"]})) STATE.chmod(0o600) print("Prepared an unconfirmed change and a retry receipt", flush=True) async def verify(): saved = json.loads(STATE.read_text()) async with connect(URL, saved["credential"]) as client: change = await call(client, "fgx_change_get", change_id=saved["change_id"]) assert change["data"]["status"] == "rolled_back", change current = (await call(client, "fgx_firewall_get"))["data"] assert current["revision"] == saved["revision"] replay = await call(client, "fgx_service_apply", spec=saved["spec"], options=saved["options"]) assert replay["change"]["id"] == saved["service"]["change"]["id"] sid = replay["data"]["service_id"] current = await read_service(client, sid) await call(client, "fgx_service_delete", service=sid, options=options(current["revision"])) store = Store(os.environ["FIREGEX_MCP_TEST_DB"]) store.open() store.token_revoke(saved["credential"]["id"]) store.close() STATE.unlink() print("PASS: expired lease recovered and identical request replayed after restart", flush=True) if __name__ == "__main__": asyncio.run(prepare() if sys.argv[1] == "prepare" else verify())