Files
hermes-agent/tests/tools/test_git_consumer_environment.py
ethernet 02f9a241d3 Let PM own Git environments and Matrix dependency preparation
Delete consumer-side Git discovery caches and layout reconstruction. Share the selected environment while preserving PM acquisition policy, system Git fallback and downstream config isolation. Route Matrix binding through its existing dependency operation and explicit setup through sync_venv.

Real Git regression tests cover absent ambient PATH, changed selection, unsupported target and failed acquisition. Independent final review: 100 focused tests pass, including malicious Git config and Matrix setup contracts. Native Windows execution was not run.
2026-09-12 19:03:39 -04:00

92 lines
3.5 KiB
Python

"""Git consumers use the selected package environment without owning its layout."""
import importlib
import shutil
import subprocess
import pytest
import pm
from tools import checkpoint_manager, working_diff
@pytest.mark.platforms("posix")
def test_checkpoint_and_diff_follow_selected_git_environment(tmp_path, monkeypatch):
git = shutil.which("git")
assert git is not None
selected = tmp_path / "selected-tools"
selected.mkdir()
observed = tmp_path / "git-environment"
wrapper = selected / "git"
import shlex
wrapper.write_text(
'#!/bin/sh\n'
'test "$HERMES_GIT_HELPER" = "selected" || exit 77\n'
f'printf "%s\\n" selected >> {shlex.quote(str(observed))}\n'
f'exec {shlex.quote(git)} "$@"\n',
encoding="utf-8",
)
wrapper.chmod(0o755)
repo = tmp_path / "repo"
repo.mkdir()
subprocess.run([git, "init", str(repo)], check=True, capture_output=True)
(repo / "new.txt").write_text("new content\n", encoding="utf-8")
def selected_git(name, *, base_env):
assert name == "git"
return pm.Runner(name, {
**base_env, "PATH": str(selected), "HERMES_GIT_HELPER": "selected"
})
monkeypatch.setattr(pm, "ensure", selected_git)
monkeypatch.setenv("PATH", str(tmp_path / "missing-path"))
monkeypatch.setattr(checkpoint_manager, "CHECKPOINT_BASE", tmp_path / "checkpoints")
manager = checkpoint_manager.CheckpointManager(enabled=True)
assert manager.ensure_checkpoint(str(repo)) is True
result = working_diff.collect_working_diff(str(repo))
assert result["success"] is True
assert "+new content" in result["diff"]
assert observed.read_text(encoding="utf-8").splitlines()
# A changed PM selection must affect this same process, not a cached command.
monkeypatch.setattr(pm, "ensure", lambda name, *, base_env: pm.Runner(name, {
**base_env, "PATH": str(tmp_path / "missing-path")
}))
assert working_diff.collect_working_diff(str(repo))["success"] is False
manager.new_turn()
assert manager.ensure_checkpoint(str(repo)) is False
@pytest.mark.parametrize("consumer", ["checkpoint", "diff"])
@pytest.mark.parametrize("failure", ["unsupported-target", "acquisition"])
def test_git_consumers_fall_back_to_system_git(tmp_path, monkeypatch, consumer, failure):
git = shutil.which("git")
assert git is not None
repo = tmp_path / "repo"
subprocess.run([git, "init", str(repo)], check=True, capture_output=True)
(repo / "new.txt").write_text("system git content\n", encoding="utf-8")
# Fail at the PM boundary reached by both ensure and env_for, without
# pretending this interpreter is running on a different host OS/CPU.
resolver = importlib.import_module("pm.ensure")
calls = []
def unavailable(*args, **kwargs):
calls.append(True)
if failure == "unsupported-target":
raise RuntimeError("unsupported architecture")
raise pm.InstallError("git", "managed Git unavailable")
boundary = "current_target" if failure == "unsupported-target" else "_installed_location"
monkeypatch.setattr(resolver, boundary, unavailable)
monkeypatch.setattr(checkpoint_manager, "CHECKPOINT_BASE", tmp_path / "checkpoints")
if consumer == "checkpoint":
manager = checkpoint_manager.CheckpointManager(enabled=True)
assert manager.ensure_checkpoint(str(repo)) is True
else:
result = working_diff.collect_working_diff(str(repo))
assert result["success"] is True
assert "+system git content" in result["diff"]
assert calls