Files
hermes-agent/tests/gateway/test_drain_active_work_report.py
teknium1 21c698b7df test: purge low-value tests, lane py06 (309 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

76 lines
3.1 KiB
Python

"""A draining gateway names the work it is waiting on, and the updater's wait prints it.
Before: ``hermes update`` printed "draining (up to 1875s)..." and then nothing for up to 30 minutes
while the gateway waited on one cron job; neither surface said WHAT was being waited on.
"""
import json
import time
import cron.scheduler as sched
from gateway.run import GatewayRunner
from gateway.session_state import SessionState
from hermes_cli.update_cmd_drain_report import drain_progress_reporter
from gateway.status import flush_runtime_status
class _FakeAgent:
model = "test/model"
def get_activity_summary(self):
return {"current_tool": "terminal", "seconds_since_activity": 1.0}
def _runner():
runner = object.__new__(GatewayRunner)
runner._restart_requested = True
runner.adapters = {}
return runner
def test_draining_status_names_chat_and_cron_units_and_clears_when_running(tmp_path, monkeypatch):
monkeypatch.setenv("HERMES_HOME", str(tmp_path))
runner = _runner()
state = SessionState()
state.turn.agent = _FakeAgent()
state.turn.started_ts = time.time() - 10
runner._sessions_map()["telegram:dm:1"] = state
assert sched.try_register_running_job("job-a")
try:
with sched._running_lock:
sched._running_worker_pids[sched._inflight_key("job-a")] = 4242
runner._update_runtime_status("draining")
flush_runtime_status()
record = json.loads((tmp_path / "gateway_state.json").read_text())
by_kind = {unit["kind"]: unit for unit in record["active_work"]}
assert by_kind["chat"]["session"] == "telegram:dm:1" and by_kind["chat"]["current_tool"] == "terminal"
assert by_kind["cron"]["job_id"] == "job-a" and by_kind["cron"]["pid"] == 4242 and by_kind["cron"]["external"]
assert record["active_agents"] == len(record["active_work"])
finally:
sched.release_running_job("job-a")
assert sched.get_running_job_details() == []
runner._update_runtime_status("running")
flush_runtime_status()
assert json.loads((tmp_path / "gateway_state.json").read_text())["active_work"] is None
def test_drain_progress_reporter_prints_holder_and_config_knob(tmp_path, monkeypatch):
monkeypatch.setenv("HERMES_HOME", str(tmp_path))
(tmp_path / "cron").mkdir()
(tmp_path / "cron" / "jobs.json").write_text(json.dumps({"jobs": [{"id": "job-a", "name": "nightly-scout"}]}))
(tmp_path / "gateway_state.json").write_text(json.dumps({
"pid": 1, "gateway_state": "draining",
"active_work": [{"kind": "cron", "job_id": "job-a", "pid": 4242, "external": True, "elapsed_s": 95}],
}))
out = []
tick = drain_progress_reporter(tmp_path, budget_s=600, interval_s=0.0, emit=out.append)
tick()
report = out[0]
assert "nightly-scout" in report and "job-a" in report and "4242" in report
# Pre-fix gateway (no active_work field): the wait still explains itself instead of going silent.
(tmp_path / "gateway_state.json").write_text(json.dumps({"pid": 1, "gateway_state": "draining"}))
out.clear()
tick()
assert out and out[0].strip()