Files
hermes-agent/tests/tui_gateway/test_entry_inline_handler_error.py
teknium1 1693fca97a test: purge low-value tests, lane py20 (206 removed)
Change-detectors, tautologies, source-reading tests, redundant duplicates,
mock-echo tests and dead/unrunnable tests. Per-test rationale in the lane
ledger (category + reason for every removal).
2026-09-23 03:15:26 -07:00

51 lines
2.2 KiB
Python

"""Regression coverage for stdio inline-handler failures (#112816).
``entry.main()`` used to call ``dispatch(req)`` bare, so an exception from an
inline (non-pool) handler unwound the read loop and killed the gateway child,
losing the in-flight reply and wedging the TUI until a restart.
"""
from __future__ import annotations
import io
import json
from tui_gateway import entry
def test_main_reports_inline_handler_error_and_keeps_reading(monkeypatch):
"""A failed inline request must not prevent the next request from replying."""
replies: list[dict] = []
breadcrumbs: list[str] = []
stdin_text = "".join(json.dumps(req) + "\n" for req in (
{"jsonrpc": "2.0", "id": "broken", "method": "clipboard.save"},
{"jsonrpc": "2.0", "id": "next", "method": "ping"},
))
monkeypatch.setattr(entry, "_install_sidecar_publisher", lambda: None)
monkeypatch.setattr(entry, "ensure_mcp_discovery_started", lambda: None)
monkeypatch.setattr(entry, "resolve_skin", lambda: "default")
monkeypatch.setattr(entry.server, "_start_backend_heartbeat_refresher", lambda: None)
monkeypatch.setattr(entry.server, "_schedule_startup_orphan_sweep", lambda: None)
monkeypatch.setattr(entry.server, "_ensure_skin_watcher", lambda: None)
monkeypatch.setattr(entry, "handle_spurious_eof", lambda *_args: False)
monkeypatch.setattr(entry, "write_json", lambda payload: replies.append(payload) or True)
monkeypatch.setattr(entry, "_append_crash_log", lambda header, dump=None: breadcrumbs.append(header))
monkeypatch.setattr(entry.sys, "stdin", io.StringIO(stdin_text))
def dispatch(req):
if req["id"] == "broken":
raise NameError("clipboard backend is unavailable")
return {"jsonrpc": "2.0", "id": req["id"], "result": {"ok": True}}
monkeypatch.setattr(entry, "dispatch", dispatch)
entry.main()
assert replies[1]["id"] == "broken"
assert replies[1]["error"]["code"] == -32000
assert "clipboard backend is unavailable" in replies[1]["error"]["message"]
assert replies[2] == {"jsonrpc": "2.0", "id": "next", "result": {"ok": True}}
# Forensics: the survived crash leaves the same crash-log trail a fatal one would.
assert len(breadcrumbs) == 1 and "clipboard.save" in breadcrumbs[0]