Files
aiturk-hermes-ide/tests/tools/test_process_registry_windows_live.py
T

104 lines
3.7 KiB
Python

"""LIVE Windows E2E for background-executor spawn parity (#70716 / PR salvage).
Runs ONLY on a real Windows host (the on-demand ``windows-venv-e2e.yml``
lane). The systemd cgroup-isolation feature for local background executors
must be a strict no-op on Windows: jobs spawn exactly as before, output is
captured, exit codes are correct, and no systemd code path is ever reached
— even when the process claims gateway identity.
These tests drive the REAL ``ProcessRegistry.spawn_local`` pipe path on the
live Windows process table (real Popen, real Git Bash shell, real reader
thread) — no mocked spawn.
"""
from __future__ import annotations
import os
import sys
import time
import pytest
pytestmark = pytest.mark.skipif(
sys.platform != "win32", reason="live Windows background-executor E2E"
)
@pytest.fixture()
def registry(tmp_path, monkeypatch):
monkeypatch.setenv("HERMES_HOME", str(tmp_path / "hermes-home"))
import tools.process_registry as pr
reg = pr.ProcessRegistry()
yield reg
for sid in list(reg._running):
try:
reg.kill_process(sid)
except Exception:
pass
def _wait_exit(reg, sid, timeout=60):
deadline = time.time() + timeout
while time.time() < deadline:
sess = reg._finished.get(sid) or reg._running.get(sid)
if sess is not None and sess.exited:
return sess
time.sleep(0.2)
raise AssertionError(f"session {sid} did not exit within {timeout}s")
class TestWindowsSpawnParity:
def test_background_job_runs_output_and_exit_code_unchanged(self, registry):
"""Plain background job: spawned, output captured, exit code correct."""
session = registry.spawn_local("echo win-live-parity; exit 7")
done = _wait_exit(registry, session.id)
assert done.exit_code == 7
assert "win-live-parity" in done.output_buffer
# The systemd scope identity must never be recorded on Windows.
assert done.systemd_unit == ""
def test_gateway_identity_never_reaches_systemd_path_on_windows(
self, registry, monkeypatch
):
"""Even with full (faked) gateway identity, the Windows spawn takes
the legacy path: no scope argv is built, no probe runs, and the job
behaves exactly as without the identity."""
import tools.process_registry as pr
monkeypatch.setenv("_HERMES_GATEWAY", "1")
monkeypatch.setattr(
"gateway.status.get_running_pid",
lambda *, cleanup_stale=False: os.getpid(),
)
monkeypatch.setattr(
"gateway.restart.is_gateway_supervisor_process", lambda: True
)
monkeypatch.setattr(pr, "_SYSTEMD_SCOPE_AVAILABLE", None)
scope_builds = []
monkeypatch.setattr(
pr,
"_build_systemd_scope_argv",
lambda *a, **k: scope_builds.append(a) or a[0],
)
session = registry.spawn_local("echo win-live-gateway; exit 3")
done = _wait_exit(registry, session.id)
assert done.exit_code == 3
assert "win-live-gateway" in done.output_buffer
assert done.systemd_unit == ""
assert scope_builds == [], "Windows must never build a systemd scope argv"
# The availability probe must not have flipped to True on Windows.
assert pr._SYSTEMD_SCOPE_AVAILABLE is not True
def test_kill_process_windows_plain_path(self, registry):
"""kill_process on Windows works without any systemd unit cleanup."""
session = registry.spawn_local("sleep 60")
time.sleep(1.0)
result = registry.kill_process(session.id)
assert result.get("status") in {"killed", "already_exited"}
assert session.systemd_unit == ""