mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-05-18 04:41:56 +00:00
fix(test_gateway): stop run_gateway() tests from rewriting the dev's installed systemd unit (#22900)
run_gateway() calls refresh_systemd_unit_if_needed() on every invocation so restart settings stay current after exit-code-75 respawns. The user-scope unit path resolves under Path.home() (NOT sandboxed by conftest, only HERMES_HOME is), and generate_systemd_unit() bakes the current HERMES_HOME into the unit's Environment= line. Result: any test that exercises run_gateway() end-to-end on a real Linux dev box silently rewrites the developer's installed ~/.config/systemd/user/hermes-gateway.service with a polluted HERMES_HOME pointing at /tmp/pytest-of-<user>/.../hermes_test. On the next reboot, systemd loads that unit, the gateway starts looking at an empty tmp dir, and Telegram/Discord/etc. all show as 'No messaging platforms enabled' even though the user's real config is fine. Three tests in tests/hermes_cli/test_gateway.py hit this path: test_run_gateway_exits_cleanly_on_keyboard_interrupt, test_run_gateway_exits_nonzero_when_start_gateway_reports_failure, and test_run_gateway_root_guard_has_escape_hatch. Two-layer fix: 1. _install_fake_gateway_run helper (covers all four run_gateway() call sites in test_gateway.py and any future ones) now also stubs supports_systemd_services and refresh_systemd_unit_if_needed. 2. refresh_systemd_unit_if_needed() itself sniffs the generated unit body for /pytest-of- and /hermes_test markers and refuses to write when present. Defense in depth so a future test that bypasses the helper still can't corrupt the dev's gateway. Tests that legitimately exercise the refresh flow (test_run_gateway_refreshes_outdated_unit_on_boot) patch generate_systemd_unit to return synthetic content that doesn't carry those markers, so they keep working. Adds test_refresh_refuses_to_bake_pytest_tmpdir_into_real_user_unit as a regression test for the source-side guard.
This commit is contained in:
parent
4f8d8ad912
commit
2ffef15675
3 changed files with 93 additions and 1 deletions
|
|
@ -2230,7 +2230,30 @@ def refresh_systemd_unit_if_needed(system: bool = False) -> bool:
|
|||
return False
|
||||
|
||||
expected_user = _read_systemd_user_from_unit(unit_path) if system else None
|
||||
unit_path.write_text(generate_systemd_unit(system=system, run_as_user=expected_user), encoding="utf-8")
|
||||
new_unit = generate_systemd_unit(system=system, run_as_user=expected_user)
|
||||
|
||||
# ── Test-environment safety belt ─────────────────────────────────────
|
||||
# The user-scope unit path resolves under ``Path.home()``, which is NOT
|
||||
# sandboxed by the test conftest (only HERMES_HOME is). If a test
|
||||
# exercises ``run_gateway()`` with a pytest-tmp HERMES_HOME, the freshly
|
||||
# generated unit bakes that ``/tmp/pytest-of-.../hermes_test`` path into
|
||||
# ``Environment="HERMES_HOME=..."``. Writing that to the developer's
|
||||
# real user systemd unit file silently breaks their gateway on the next
|
||||
# reboot (systemd loads the polluted env, the gateway looks at an empty
|
||||
# tmp dir, and Telegram/Discord/etc. all show as "not configured").
|
||||
# Refuse to write when the generated unit references a pytest tmpdir.
|
||||
# Detection sniffs the unit body — tests that legitimately exercise the
|
||||
# refresh flow patch ``generate_systemd_unit`` to return synthetic
|
||||
# content (``"new unit\n"``) which doesn't contain these markers and
|
||||
# still works.
|
||||
if not system and (
|
||||
"/pytest-of-" in new_unit
|
||||
or "/hermes_test\"" in new_unit
|
||||
or "/hermes_test/" in new_unit
|
||||
):
|
||||
return False
|
||||
|
||||
unit_path.write_text(new_unit, encoding="utf-8")
|
||||
_run_systemctl(["daemon-reload"], system=system, check=True, timeout=30)
|
||||
print(f"↻ Updated gateway {_service_scope_label(system)} service definition to match the current Hermes install")
|
||||
return True
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue