mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-06-13 09:01:54 +00:00
fix(tests): guard against real 'hermes update' subprocess spawns in conftest
Extends _live_system_guard in tests/conftest.py to block any subprocess call that would run 'hermes update' (or 'python -m hermes_cli.main update') against the real checkout. These commands run git fetch origin + git pull, overwriting repo files like pyproject.toml mid-test-run and corrupting every subsequent subprocess that reads them. The spawned process uses setsid / start_new_session=True so it's invisible to pytest's process tree (PPid=1) — the corruption was essentially undetectable without explicit inotify/SHA watchdogs. Root cause of #43703 CI failures: tests in TestUpdateCommandPlatformGate called _handle_update_command() with HERMES_MANAGED='' and no Popen mock, causing the code to fall through and spawn a real 'hermes update --gateway' that overwrote pyproject.toml with origin/main's content (which still had '--timeout=30 --timeout-method=thread' in addopts while the PR had already removed pytest-timeout). The guard covers all three invocation patterns: - 'hermes update' / 'hermes update --gateway' (direct or via setsid bash -c) - 'python -m hermes_cli.main update --gateway' - '.venv/bin/hermes update' (absolute path variant) Does not false-positive on: git update-index, apt-get update, pip install --upgrade, or any command lacking 'hermes'/'hermes_cli'.
This commit is contained in:
parent
c41a6534cf
commit
6ff39c31ad
1 changed files with 35 additions and 0 deletions
|
|
@ -731,6 +731,41 @@ def _live_system_guard(request, monkeypatch):
|
|||
"Mark with @pytest.mark.live_system_guard_bypass if "
|
||||
"intentional."
|
||||
)
|
||||
# Block any subprocess that would run `hermes update` (or the
|
||||
# equivalent `python -m hermes_cli.main update`). These commands
|
||||
# run `git fetch origin + git pull` against the REAL checkout,
|
||||
# overwriting files like pyproject.toml mid-test-run and corrupting
|
||||
# every subsequent subprocess that reads them. The corruption is
|
||||
# especially insidious because the spawned process uses setsid/
|
||||
# start_new_session=True, making it invisible to pytest's process
|
||||
# tree (PPid=1) and nearly impossible to trace without explicit
|
||||
# inotify/SHA watchdogs. Any test that legitimately needs to exercise
|
||||
# the update-spawn path must mock subprocess.Popen explicitly.
|
||||
cmd_str = _cmd_to_string(cmd)
|
||||
low = cmd_str.lower()
|
||||
if "update" in low and (
|
||||
# hermes update / hermes update --gateway / setsid bash -c ... hermes update
|
||||
("hermes" in low and "update" in low.split())
|
||||
or
|
||||
# python -m hermes_cli.main update --gateway
|
||||
("hermes_cli" in low and "update" in low.split())
|
||||
or
|
||||
# venv/bin/hermes update (absolute path variant used in tests)
|
||||
(".venv/bin/hermes" in low and "update" in low)
|
||||
):
|
||||
raise RuntimeError(
|
||||
f"tests/conftest.py live-system guard: blocked "
|
||||
f"subprocess.{name}({cmd!r}) — this command would run "
|
||||
"`hermes update` against the real checkout, fetching "
|
||||
"from origin and overwriting repo files (e.g. "
|
||||
"pyproject.toml) mid-test-run. This corrupts every "
|
||||
"subsequent subprocess in the same runner. "
|
||||
"Mock subprocess.Popen (and subprocess.run if used) "
|
||||
"in the test instead, or mark with "
|
||||
"@pytest.mark.live_system_guard_bypass if genuinely "
|
||||
"needed (e.g. an integration test testing the update "
|
||||
"flow against a dedicated throwaway repo)."
|
||||
)
|
||||
|
||||
def _wrap_subprocess(name, real):
|
||||
def _guarded(cmd, *args, **kwargs):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue