atlas-iac/testing/tests/test_hermes_hux_runtime_emitters.py

141 lines
6.0 KiB
Python
Raw Normal View History

"""HUX-04/08 post-tool emitters: real files and real web output leave records."""
from __future__ import annotations
import base64
import importlib.util
import sys
from pathlib import Path
from types import SimpleNamespace
ROOT = Path(__file__).resolve().parents[2]
PLUGIN = ROOT / "services" / "hermes" / "plugins" / "hux-runtime"
SPEC = importlib.util.spec_from_file_location("hermes_hux_emitters", PLUGIN / "emitters.py")
assert SPEC and SPEC.loader
emitters = importlib.util.module_from_spec(SPEC)
sys.modules[SPEC.name] = emitters
SPEC.loader.exec_module(emitters)
CALL = SimpleNamespace(conversation_id="conv_" + "c" * 32, project_id="prj_" + "a" * 32)
class Client:
"""Capture every emitter call; scriptable listing and failures."""
def __init__(self, items=None, fail=None):
self.items = items or []
self.fail = fail
self.calls = []
def get(self, path, query=None):
self.calls.append(("GET", path, query, None))
if self.fail == "get":
raise OSError("down")
return SimpleNamespace(body={"items": self.items})
def post(self, path, body, idempotency_key=None):
self.calls.append(("POST", path, body, idempotency_key))
if self.fail == "post":
raise OSError("down")
return SimpleNamespace(body={"id": "art_new0001"})
def request(self, method, path, body=None, *, idempotency_key=None, if_match=None):
self.calls.append((method, path, body, idempotency_key, if_match))
if self.fail == "request":
raise OSError("down")
return SimpleNamespace(body={})
def test_new_text_file_creates_a_typed_artifact(tmp_path):
target = tmp_path / "report.md"
target.write_text("# hello\n")
client = Client()
assert emitters.record_artifact(client, CALL, {"path": str(target)}) == "art_new0001"
method, path, body, key = client.calls[-1]
assert (method, path) == ("POST", "/hux/v1/artifacts")
assert body["type"] == "markdown" and body["title"] == "report.md"
assert body["content"] == "# hello\n" and "content_base64" not in body
assert body["conversation_id"] == CALL.conversation_id
assert key.startswith("artifact-sync:new:")
def test_binary_file_is_base64_and_unknown_suffix_is_code(tmp_path):
target = tmp_path / "tool.bin"
target.write_bytes(b"\xff\xfe\x00binary")
client = Client()
emitters.record_artifact(client, CALL, {"file_path": str(target)})
body = client.calls[-1][2]
assert body["type"] == "code"
assert base64.b64decode(body["content_base64"]) == b"\xff\xfe\x00binary"
assert "content" not in body
def test_existing_title_appends_an_immutable_version(tmp_path):
target = tmp_path / "main.py"
target.write_text("print(2)\n")
existing = {"id": "art_1", "title": "main.py", "revision": 3, "current_version": 3}
client = Client(items=[existing])
assert emitters.record_artifact(client, CALL, {"path": str(target)}) == "art_1"
method, path, body, key, if_match = client.calls[-1]
assert (method, path) == ("POST", "/hux/v1/artifacts/art_1/versions")
assert body["diff_from"] == 3 and body["content"] == "print(2)\n"
assert if_match == 3 and key.startswith("artifact-sync:art_1:")
def test_artifact_emitter_is_bounded_and_fail_open(tmp_path):
client = Client()
# No plausible path, missing file, oversized file, symlink, service down.
assert emitters.record_artifact(client, CALL, {"other": 1}) is None
assert emitters.record_artifact(client, CALL, {"path": str(tmp_path / "gone")}) is None
big = tmp_path / "big.txt"
big.write_bytes(b"x" * (emitters.MAX_ARTIFACT_BYTES + 1))
assert emitters.record_artifact(client, CALL, {"path": str(big)}) is None
target = tmp_path / "real.txt"
target.write_text("ok")
link = tmp_path / "link.txt"
link.symlink_to(target)
assert emitters.record_artifact(client, CALL, {"path": str(link)}) is None
assert emitters.record_artifact(client, CALL, "not-a-dict") is None
assert emitters.record_artifact(Client(fail="get"), CALL, {"path": str(target)}) is None
assert emitters.record_artifact(Client(fail="post"), CALL, {"path": str(target)}) is None
existing = {"id": "art_1", "title": "real.txt", "revision": 1, "current_version": 1}
assert emitters.record_artifact(Client(items=[existing], fail="request"), CALL, {"path": str(target)}) is None
def test_web_sources_are_deduplicated_and_capped():
client = Client()
text = " ".join(
["see https://example.org/a and https://example.org/a again,",
"plus https://example.org/b, https://example.org/c and https://example.org/d"]
)
assert emitters.record_sources(client, text) == emitters.MAX_SOURCES_PER_CALL
posts = [call for call in client.calls if call[0] == "POST"]
assert [c[2]["uri"] for c in posts] == [
"https://example.org/a", "https://example.org/b", "https://example.org/c",
]
assert all(c[2]["kind"] == "web" and c[3].startswith("source-sync:") for c in posts)
def test_source_emitter_handles_bytes_non_text_and_failures():
assert emitters.record_sources(Client(), b"https://example.org/bytes ok") == 1
assert emitters.record_sources(Client(), {"not": "text"}) == 0
assert emitters.record_sources(Client(fail="post"), "https://example.org/x") == 0
assert emitters.record_sources(Client(), "no urls here") == 0
def test_sync_router_dispatches_by_capability(tmp_path):
target = tmp_path / "out.json"
target.write_text("{}")
client = Client()
emitters.sync_after_tool(client, CALL, "write_files", {"path": str(target)}, "ok")
assert any(call[1] == "/hux/v1/artifacts" for call in client.calls)
client = Client()
emitters.sync_after_tool(client, CALL, "network", {}, "https://example.org/z")
assert any(call[1] == "/hux/v1/sources" for call in client.calls)
client = Client()
emitters.sync_after_tool(client, CALL, "shell", {}, "https://example.org/z")
assert client.calls == []
# A broken call scope can never raise into the tool path.
emitters.sync_after_tool(None, None, "write_files", {"path": str(target)}, "ok")