Files
hermes-agent/tests/hermes_cli/test_git_trampoline_windows_live.py
ethernet 59624b7ace tests: replace every bare host skipif with platforms()
The OS lanes are marker-driven: list_os_marked_tests.py picks the files
a lane imports from their platforms() specs and the lane selects with
-m platforms. A test gated with skipif(sys.platform != "win32") is
therefore never imported on the Windows lane and skipped everywhere else
— it runs on no host. skipif(sys.platform == "win32") tests were merely
invisible to the lane bookkeeping, but the rule the tree now follows is
one host marker, never a bare skipif.

Mechanical mapping, semantics preserved: skip-on-Windows → "posix",
skip-off-Windows → "windows", skip-off-Linux → "linux", skip-on-macOS →
"not macos". The former skip reasons stay as trailing comments. A
non-host condition (os.geteuid() == 0) stays a separate skipif beside
the marker, spelled getattr(os, "geteuid", ...) so the decorator still
imports on Windows.

Where the conversion would stack two platforms() marks on one test (the
conftest rejects that at collection) the narrower mark wins:
- test_update_wedged_gateway: the class is already platforms("linux");
  its per-test "needs UNIX sockets" marks were redundant and are gone.
- test_process_registry.TestSystemdCgroupIsolation: the class-level
  skip-on-Windows moves onto the 11 methods that had no host mark; the
  11 platforms("linux") methods keep theirs.
- test_file_ops_single_roundtrip: the two fifo tests drop their
  platforms("linux") in favour of the module's "posix" (mkfifo exists on
  macOS; both tests already skip when it does not).
- test_linux_desktop_entry / test_gateway_job_teardown_live: duplicate
  or wider marks removed.
2026-09-21 19:18:15 -04:00

94 lines
3.5 KiB
Python

"""Live Windows E2E for the Git-for-Windows trampoline self-heal (#87876).
Runs ONLY on a real windows-latest runner (wine2e/** on-demand lane). No
mocked subprocess anywhere: the probes drive the REAL
``_git_is_trampoline`` / ``_locate_real_git`` / ``_ensure_non_trampoline_git``
helpers against the runner's genuine Git-for-Windows install plus a real
broken-trampoline stand-in (a .bat that reproduces the launcher's
"BUG (fork bomb)" guard output and refuses to run).
windows-latest ships full Git for Windows at ``C:\\Program Files\\Git`` with
the real ``mingw64\\libexec\\git-core\\git.exe`` — exactly the layout the
locator targets — so the swap path is exercised end to end.
"""
from __future__ import annotations
import subprocess
import sys
from pathlib import Path
import pytest
pytestmark = pytest.mark.platforms("windows") # live Windows trampoline E2E
_FORK_BOMB_BAT = (
"@echo off\r\n"
"echo BUG (fork bomb): tried to spawn itself, check your PATH 1>&2\r\n"
"exit /b 1\r\n"
)
def _make_broken_trampoline(tmp_path: Path) -> Path:
bat = tmp_path / "git.bat"
bat.write_text(_FORK_BOMB_BAT, encoding="utf-8")
return bat
class TestGitTrampolineLive:
def test_runner_git_is_not_a_trampoline(self):
from hermes_cli import update_cmd
# Healthy PATH git on the runner: probe must report False and the
# probe itself must actually run git (sanity: git exists here).
version = subprocess.run(
["git", "--version"], capture_output=True, text=True, timeout=30
)
assert version.returncode == 0, version.stderr
assert update_cmd._git_is_trampoline(["git"]) is False
def test_broken_trampoline_detected_live(self, tmp_path):
from hermes_cli import update_cmd
bat = _make_broken_trampoline(tmp_path)
assert update_cmd._git_is_trampoline([str(bat)]) is True
def test_locate_real_git_finds_runner_git_core(self):
from hermes_cli import update_cmd
real = update_cmd._locate_real_git()
# windows-latest ships Git for Windows under Program Files with the
# canonical git-core layout the locator searches first.
assert real is not None, "expected git-core git.exe on windows-latest"
assert real.exists()
assert real.name == "git.exe"
probe = subprocess.run(
[str(real), "--version"], capture_output=True, text=True, timeout=30
)
assert probe.returncode == 0
assert "git version" in probe.stdout.lower()
def test_ensure_non_trampoline_git_swaps_live(self, tmp_path, capsys):
from hermes_cli import update_cmd
bat = _make_broken_trampoline(tmp_path)
broken_cmd = [str(bat), "-c", "windows.appendAtomically=false"]
healed = update_cmd._ensure_non_trampoline_git(broken_cmd)
assert healed != broken_cmd, "broken trampoline must be swapped"
assert healed[1:] == broken_cmd[1:], "git config args must survive"
real = Path(healed[0])
assert real.exists() and real.name == "git.exe"
# The healed command must actually work.
result = subprocess.run(
healed[:1] + ["--version"], capture_output=True, text=True, timeout=30
)
assert result.returncode == 0
assert "switching to real git" in capsys.readouterr().out
def test_healthy_git_command_untouched_live(self):
from hermes_cli import update_cmd
git_cmd = ["git", "-c", "windows.appendAtomically=false"]
assert update_cmd._ensure_non_trampoline_git(git_cmd) == git_cmd