test: prove checkout mutations and guarded tmp roots stay isolated

This commit is contained in:
ethernet
2026-09-24 09:05:44 -04:00
parent e8a5e0978c
commit 8826e32b9c
2 changed files with 28 additions and 2 deletions

View File

@@ -25,12 +25,23 @@ def test_guard_blocks_native_and_shell_git_mutations_without_touching_checkout(t
monkeypatch.setattr(conftest, "_LIVE_GUARD_PROTECTED_GIT_ROOTS", (protected,))
head = git(protected, "rev-parse", "HEAD")
(protected / "sentinel").write_bytes(b"uncommitted user data")
for command in (["git", "-C", str(protected), "reset", "--hard", "HEAD~1"],
["sh", "-c", f"git -C {shlex.quote(str(protected))} checkout -- sentinel"]):
for command in (
["git", "-C", str(protected), "reset", "--hard", "HEAD~1"],
["sh", "-c", f"git -C {shlex.quote(str(protected))} checkout -- sentinel"],
*(["git", "-C", str(protected), *args] for args in (
("commit", "-am", "overwrite"), ("add", "-A"), ("rm", "-r", "."),
("config", "url.https://example.invalid/.insteadOf", "git@example.invalid:"),
("update-ref", "refs/heads/main", head), ("branch", "-f", "main", head),
("worktree", "add", str(tmp_path / "new-worktree")), ("tag", "unsafe-tag"),
)),
):
with pytest.raises(RuntimeError, match="live-system guard"):
subprocess.run(command, check=True)
assert git(protected, "rev-parse", "HEAD") == head
assert (protected / "sentinel").read_bytes() == b"uncommitted user data"
assert not (tmp_path / "new-worktree").exists()
assert git(protected, "tag", "--list", "unsafe-tag") == ""
assert "url.https://example.invalid/.insteadof" not in git(protected, "config", "--local", "--list")
old = git(ordinary, "rev-parse", "HEAD~1")
git(ordinary, "reset", "--hard", old)
assert git(ordinary, "rev-parse", "HEAD") == old

View File

@@ -78,3 +78,18 @@ def test_custom_home_tmpdir_is_relocated_before_pytest_uses_it(tmp_path):
env=env, capture_output=True, text=True, check=True,
)
assert not result.stdout.strip().startswith(str(home))
def test_default_home_unmarked_tmpdir_is_relocated_before_pytest_uses_it(tmp_path):
# Model the operator's default root with a disposable HOME, not ~/.hermes.
operator_home = tmp_path / "operator"
scratch = operator_home / ".hermes" / "cache" / "scratch"
scratch.mkdir(parents=True)
env = dict(os.environ, HOME=str(operator_home), TMPDIR=str(scratch))
env.pop("HERMES_HOME", None)
env.pop("HERMES_SCRATCH_DIR", None)
result = subprocess.run(
[sys.executable, "-c", "import tempfile, tests.conftest; print(tempfile.gettempdir())"],
env=env, capture_output=True, text=True, check=True,
)
assert not result.stdout.strip().startswith(str(operator_home / ".hermes"))