hermes-agent/tests/tui_gateway/test_compute_host.py
brooklyn! 7d27a31ce7
feat(dashboard): isolate turns in compute host (#65895)
Add the flag-gated compute-host supervisor, delta/control protocol, PPID orphan guard, inline fail-open path, synthetic GIL-heavy turn seam, and AC-4 certify harness.

Verified on current origin/main: 343 focused tests pass; Ruff and diff checks pass; 360s AC-4 run with six heavy lanes passes at 6.11ms serving p99 with zero stalls and valid load.

Co-authored-by: Kyzcreig <9063726+Kyzcreig@users.noreply.github.com>
2026-07-16 15:24:03 -04:00

85 lines
2.5 KiB
Python

import json
import os
import queue
import subprocess
import sys
import threading
from pathlib import Path
def _stdout_queue(proc: subprocess.Popen) -> queue.Queue[dict]:
out: queue.Queue[dict] = queue.Queue()
assert proc.stdout is not None
def drain() -> None:
for line in proc.stdout or []:
out.put(json.loads(line))
threading.Thread(target=drain, daemon=True).start()
return out
def _read_json_line(out: queue.Queue[dict], timeout: float = 2.0) -> dict:
try:
return out.get(timeout=timeout)
except queue.Empty as exc:
raise AssertionError("timed out waiting for compute host JSON") from exc
def test_compute_host_line_json_seed_turn_interrupt():
repo = Path(__file__).resolve().parents[2]
env = dict(os.environ)
env["PYTHONPATH"] = str(repo) + os.pathsep + env.get("PYTHONPATH", "")
proc = subprocess.Popen(
[sys.executable, "-m", "tui_gateway.compute_host"],
cwd=str(repo),
env=env,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True,
bufsize=1,
)
assert proc.stdin is not None
out = _stdout_queue(proc)
try:
hello = _read_json_line(out)
assert hello["type"] == "hello"
assert hello["host_pid"] == proc.pid
proc.stdin.write(json.dumps({"type": "session.seed", "sid": "s1", "request_id": "seed"}) + "\n")
proc.stdin.flush()
assert _read_json_line(out)["type"] == "session.seeded"
proc.stdin.write(
json.dumps(
{
"type": "turn.start",
"sid": "s1",
"request_id": "turn",
"prompt": "hello",
"delta_count": 3,
"delay_s": 0,
}
)
+ "\n"
)
proc.stdin.flush()
seen = []
while True:
frame = _read_json_line(out)
seen.append(frame["type"])
if frame["type"] == "turn.end":
assert frame["history_version"] == 1
assert frame["message_count"] == 2
break
assert seen.count("delta") == 3
proc.stdin.write(json.dumps({"type": "shutdown", "request_id": "stop"}) + "\n")
proc.stdin.flush()
assert _read_json_line(out)["type"] == "shutdown.ack"
proc.wait(timeout=2)
finally:
if proc.poll() is None:
proc.kill()