Files
aiturk-hermes-ide/tests/hermes_cli/test_git_trampoline_windows_live.py
T

96 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.skipif(
sys.platform != "win32", reason="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