fix(tests): make test_update_stale_dashboard immune to hermes_cli.main reload (#17881)

Six tests in this file failed in CI (-n auto) after #17832 landed because
other tests on the same xdist worker reload hermes_cli.main:

  tests/hermes_cli/test_env_loader.py:85-86
    sys.modules.pop('hermes_cli.main', None)
    importlib.import_module('hermes_cli.main')

  tests/hermes_cli/test_skills_subparser.py:24-25
    del sys.modules['hermes_cli.main']

When either ran first on a worker, our top-of-file
'from hermes_cli.main import _kill_stale_dashboard_processes' captured a
stale function object whose __globals__ points at the old module dict.
patch('hermes_cli.main._find_stale_dashboard_pids', ...) then patched the
new module, but the stale function resolved the dependency via its stale
__globals__, so every patch became a no-op: pids=[] → early return → no
signals, no output, assertions failed.

Fix: add an autouse fixture that rebinds the three module-level names to
whatever is currently live in sys.modules['hermes_cli.main'] before each
test runs. The pollutants in the other two files are load-bearing for
their own tests, so fixing it on the consumer side is correct.

Repro: pytest tests/hermes_cli/test_env_loader.py tests/hermes_cli/test_update_stale_dashboard.py
This commit is contained in:
Teknium 2026-04-30 02:46:56 -07:00 committed by GitHub
parent 0da968e521
commit 2662bfb756
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -13,6 +13,7 @@ History:
from __future__ import annotations
import importlib
import os
import sys
from unittest.mock import patch, MagicMock, call
@ -26,6 +27,38 @@ from hermes_cli.main import (
)
@pytest.fixture(autouse=True)
def _refresh_bindings_against_live_module():
"""Rebind module-level names to the *current* ``hermes_cli.main``.
Other tests in the suite (notably ``test_env_loader.py`` and
``test_skills_subparser.py``) reload or delete ``hermes_cli.main`` from
``sys.modules``. When that happens on the same xdist worker before we
run, our top-of-file ``from hermes_cli.main import ...`` bindings end
up pointing at the *old* module object. ``patch(\"hermes_cli.main.X\")``
then patches the *new* module, but the function we call still resolves
``_find_stale_dashboard_pids`` via its stale ``__globals__``, so every
patch becomes a no-op and the kill path silently returns early.
Refreshing the bindings (and the patch target) to the live module
object and keeping them consistent makes the tests immune to
ordering within the worker. The fix lives in the test module because
the two pollutants above are load-bearing for their own tests.
"""
global _find_stale_dashboard_pids
global _kill_stale_dashboard_processes
global _warn_stale_dashboard_processes
live = sys.modules.get("hermes_cli.main")
if live is None:
live = importlib.import_module("hermes_cli.main")
_find_stale_dashboard_pids = live._find_stale_dashboard_pids
_kill_stale_dashboard_processes = live._kill_stale_dashboard_processes
_warn_stale_dashboard_processes = live._warn_stale_dashboard_processes
yield
def _ps_line(pid: int, cmd: str) -> str:
"""Format a line as it would appear in ``ps -A -o pid=,command=`` output."""
return f"{pid:>7} {cmd}"