From 979767977ea385f0a2e8ae7211efb7a48b223ff6 Mon Sep 17 00:00:00 2001 From: Teknium <127238744+teknium1@users.noreply.github.com> Date: Mon, 7 Sep 2026 04:16:22 -0700 Subject: [PATCH] test: isolate updater fixtures from the live runtime fleet --- tests/hermes_cli/conftest.py | 33 +++++++++++++++++++++++- tests/hermes_cli/test_cmd_update.py | 18 +++---------- tests/hermes_cli/test_update_yes_flag.py | 13 ++++++++++ 3 files changed, 48 insertions(+), 16 deletions(-) diff --git a/tests/hermes_cli/conftest.py b/tests/hermes_cli/conftest.py index 2848a8a9aa..60728cdc8d 100644 --- a/tests/hermes_cli/conftest.py +++ b/tests/hermes_cli/conftest.py @@ -1,4 +1,4 @@ -"""Fixtures shared across hermes_cli kanban tests.""" +"""Fixtures shared across hermes_cli tests.""" from __future__ import annotations @@ -54,3 +54,34 @@ def _suppress_concurrent_hermes_gate(request, monkeypatch): lambda *_a, **_k: [], raising=False, ) + + +@pytest.fixture +def isolated_update_runtime(monkeypatch, tmp_path, request): + """Keep mocked updater flows off the host checkout and runtime fleet.""" + from hermes_cli import gateway, main, update_cmd, update_cmd_fleet + from hermes_cli import update_inventory, update_receipt + + checkout = tmp_path / "isolated-update-checkout" + (checkout / ".git").mkdir(parents=True) + (checkout / "apps" / "desktop").mkdir(parents=True) + monkeypatch.setattr(main, "PROJECT_ROOT", checkout) + if hasattr(request.module, "PROJECT_ROOT"): + monkeypatch.setattr(request.module, "PROJECT_ROOT", checkout) + + # A real purge would discard the module objects patched below. + monkeypatch.setattr(main, "_purge_stale_hermes_modules", lambda: None) + monkeypatch.setattr(gateway, "find_gateway_pids", lambda *a, **k: []) + monkeypatch.setattr(gateway, "find_profile_gateway_processes", lambda *a, **k: []) + monkeypatch.setattr(gateway, "_get_service_pids", lambda *a, **k: set()) + monkeypatch.setattr(gateway, "supports_systemd_services", lambda: False) + monkeypatch.setattr(main, "_pause_windows_gateways_for_update", lambda: None) + monkeypatch.setattr(main, "_resume_windows_gateways_after_update", lambda *a, **k: None) + monkeypatch.setattr(main, "_detect_venv_python_processes", lambda: []) + monkeypatch.setattr(main, "_restore_active_tool_dependencies", lambda *a, **k: None) + monkeypatch.setattr(update_cmd, "_clear_windows_venv_holders_or_exit", lambda *a, **k: None) + monkeypatch.setattr(update_cmd, "_finish_dashboard_update_cleanup", lambda *a, **k: None) + monkeypatch.setattr(update_cmd, "_apply_pending_fleet_restart_catchup", lambda *a, **k: None) + monkeypatch.setattr(update_cmd_fleet, "_restart_macos_launchd_gateways", lambda *a, **k: None) + monkeypatch.setattr(update_inventory, "collect_runtime_inventory", lambda: None) + monkeypatch.setattr(update_receipt, "collect_fleet_versions", lambda *a, **k: []) diff --git a/tests/hermes_cli/test_cmd_update.py b/tests/hermes_cli/test_cmd_update.py index a17c13595a..d91a8482cc 100644 --- a/tests/hermes_cli/test_cmd_update.py +++ b/tests/hermes_cli/test_cmd_update.py @@ -79,21 +79,8 @@ def _patch_managed_uv(request): @pytest.fixture(autouse=True) -def _patch_gateway_discovery(): - """Keep cmd_update's gateway auto-restart phase off this machine's gateways. - - The restart phase used to swallow every exception at debug level, so these - end-to-end tests never noticed it touching real gateway discovery. Since - the phase is surfaced (#78574: an aborted restart now fails the update), - an unmocked ``find_gateway_pids`` on a box with a live gateway reaches the - conftest live-system guard and turns into a spurious ``sys.exit(1)``. - Discovery returning nothing makes the phase a clean no-op for every test - in this module (none of them assert on gateway restarts). - """ - with patch("hermes_cli.gateway.find_gateway_pids", return_value=[]), \ - patch("hermes_cli.gateway.supports_systemd_services", return_value=False), \ - patch("hermes_cli.gateway.find_profile_gateway_processes", return_value=[]): - yield +def _patch_gateway_discovery(isolated_update_runtime): + pass class TestCmdUpdateNpmLockfileCache: @@ -1134,6 +1121,7 @@ class TestNodeRuntimeNpmResolution: from hermes_cli import update_cmd desktop_dir = PROJECT_ROOT / "apps" / "desktop" + (desktop_dir / "package.json").write_text("{}", encoding="utf-8") packaged_exe = desktop_dir / "release" / "win-unpacked" / "Hermes.exe" build_ok = subprocess.CompletedProcess([], 0, stdout="", stderr="") diff --git a/tests/hermes_cli/test_update_yes_flag.py b/tests/hermes_cli/test_update_yes_flag.py index ef5a031859..84058bee17 100644 --- a/tests/hermes_cli/test_update_yes_flag.py +++ b/tests/hermes_cli/test_update_yes_flag.py @@ -12,9 +12,22 @@ import subprocess from types import SimpleNamespace from unittest.mock import patch +import pytest + from hermes_cli.main import cmd_update +@pytest.fixture(autouse=True) +def _isolate_update(isolated_update_runtime, monkeypatch): + import shutil + from hermes_cli import managed_uv, update_cmd + + monkeypatch.setattr(managed_uv, "resolve_uv", lambda **kw: shutil.which("uv")) + monkeypatch.setattr(managed_uv, "ensure_uv", lambda **kw: shutil.which("uv")) + monkeypatch.setattr(managed_uv, "update_managed_uv", lambda **kw: None) + monkeypatch.setattr(update_cmd, "_post_update_sqlite_runtime_status", lambda: (True, None)) + + def _make_run_side_effect( branch="main", verify_ok=True, commit_count="1", dirty=False ):