atlas-iac/dockerfiles/hermes_execution_regression_support.py

133 lines
4.3 KiB
Python

"""Shared isolated database fixture for Hermes execution-safety regressions."""
from __future__ import annotations
import json
import os
import sys
import tempfile
import unittest
from pathlib import Path
from types import SimpleNamespace
from unittest import mock
_HERMES_HOME = tempfile.TemporaryDirectory(prefix="hermes-execution-test-home-")
os.environ["HERMES_HOME"] = _HERMES_HOME.name
_LANE_SOURCE = Path(
os.environ.get("HERMES_CLI_LANE_SOURCE", "/tmp/hermes-lane-regression")
)
sys.path.insert(0, str(_LANE_SOURCE))
from agent import auxiliary_client # noqa: E402
from cli_lane_config import TerminalIdentity # noqa: E402
from cli_lane_finalization import _finalize_document_db # noqa: E402
from hermes_cli import kanban_db # noqa: E402
from hermes_cli import kanban_decompose # noqa: E402
__all__ = ("ExecutionSafetyTestCase", "TerminalIdentity", "_finalize_document_db")
class _FakeCompletions:
def __init__(self, payload: dict, before_response=None) -> None:
self.payload = payload
self.before_response = before_response
self.calls = 0
def create(self, **_kwargs):
self.calls += 1
if self.before_response is not None:
self.before_response()
return SimpleNamespace(
choices=[
SimpleNamespace(
message=SimpleNamespace(content=json.dumps(self.payload))
)
]
)
class _FakeClient:
def __init__(self, completions: _FakeCompletions) -> None:
self.chat = SimpleNamespace(completions=completions)
class ExecutionSafetyTestCase(unittest.TestCase):
"""Exercise patched upstream APIs against an isolated real database."""
def setUp(self) -> None:
self.connection = kanban_db.connect()
self.patches = [
mock.patch.object(
kanban_decompose,
"_build_roster",
return_value=([], {"default"}),
),
mock.patch.object(
kanban_decompose,
"_load_config",
return_value={"kanban": {"auto_promote_children": True}},
),
mock.patch.object(
auxiliary_client,
"get_auxiliary_extra_body",
return_value={},
),
]
for patch in self.patches:
patch.start()
def tearDown(self) -> None:
for patch in reversed(self.patches):
patch.stop()
self.connection.close()
def _client(self, payload: dict, before_response=None) -> _FakeCompletions:
completions = _FakeCompletions(payload, before_response)
client = _FakeClient(completions)
patch = mock.patch.object(
auxiliary_client,
"get_text_auxiliary_client",
return_value=(client, "test-decomposer"),
)
patch.start()
self.addCleanup(patch.stop)
return completions
def _status(self, task_id: str) -> str:
task = kanban_db.get_task(self.connection, task_id)
self.assertIsNotNone(task)
return task.status
def _route_executed_task_to_triage(self) -> str:
task_id = kanban_db.create_task(
self.connection,
title="already implemented parent",
)
for attempt in range(kanban_db.BLOCK_RECURRENCE_LIMIT):
if attempt:
self.assertTrue(kanban_db.unblock_task(self.connection, task_id))
self.assertIsNotNone(kanban_db.claim_task(self.connection, task_id))
self.assertTrue(
kanban_db.block_task(
self.connection,
task_id,
reason="same unavailable capability",
kind="capability",
)
)
self.assertEqual(self._status(task_id), "triage")
self.assertEqual(
len(kanban_db.list_runs(self.connection, task_id)),
kanban_db.BLOCK_RECURRENCE_LIMIT,
)
return task_id
def _insert_run(self, task_id: str) -> None:
with kanban_db.connect_closing() as connection:
kanban_db._synthesize_ended_run(
connection,
task_id,
outcome="reclaimed",
summary="concurrent execution evidence",
)