tests/conftest.py had grown to 2,343 lines, past the 2,000-line gate. Move three self-contained topics out, unchanged: - env_filter.py: the credential / behavioral env-var name tables the hermetic fixture blanks; - live_system_guard.py: the autouse live-system guard fixture, its marks and the protected checkout roots; - platform_gating.py: the platforms() marker evaluation used by the collection hook. conftest imports them instead of listing them in pytest_plugins: it is not the rootdir conftest, and pytest fails a run that loads a non-root conftest carrying pytest_plugins after startup. Imported fixtures register on the conftest module under their old names, so autouse order is unchanged. Tests that reached into the moved symbols now import the new modules.
72 lines
3.7 KiB
Python
72 lines
3.7 KiB
Python
"""A removed live-checkout guard can damage only disposable repositories here."""
|
|
from pathlib import Path
|
|
import shlex
|
|
import subprocess
|
|
|
|
import pytest
|
|
|
|
|
|
@pytest.mark.platforms("posix")
|
|
def test_guard_blocks_native_and_shell_git_mutations_without_touching_checkout(tmp_path, monkeypatch):
|
|
from tests._fixtures import live_system_guard
|
|
|
|
def git(repo, *args):
|
|
result = subprocess.run(["git", "-C", str(repo), *args], capture_output=True, text=True, check=True)
|
|
return result.stdout.strip()
|
|
|
|
protected, ordinary = tmp_path / "protected", tmp_path / "ordinary"
|
|
for repo in (protected, ordinary):
|
|
repo.mkdir()
|
|
git(repo, "init")
|
|
git(repo, "-c", "user.name=Test", "-c", "user.email=test@example.invalid", "commit", "--allow-empty", "-m", "first")
|
|
(repo / "sentinel").write_text("committed", encoding="utf-8")
|
|
git(repo, "add", "sentinel")
|
|
git(repo, "-c", "user.name=Test", "-c", "user.email=test@example.invalid", "commit", "-m", "second")
|
|
monkeypatch.setattr(live_system_guard, "_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"],
|
|
*(["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
|
|
assert not (ordinary / "sentinel").exists()
|
|
|
|
|
|
def test_checkout_guard_covers_write_verbs_without_blocking_queries(tmp_path):
|
|
from tests.git_safety import blocked_git_mutation
|
|
|
|
root = tmp_path / "checkout"
|
|
root.mkdir()
|
|
options = {"cwd": root}
|
|
for argv in (
|
|
["commit", "-am", "change"], ["add", "-A"], ["rm", "-r", "."],
|
|
["config", "url.https://example.invalid/.insteadOf", "git@example.invalid:"],
|
|
["config", "--file", ".git/config", "url.https://example.invalid/.pushInsteadOf", "git@x:"],
|
|
["config", "set", "url.https://example.invalid/.insteadOf", "git@example.invalid:"],
|
|
["update-ref", "refs/heads/main", "abc"], ["branch", "-f", "main"],
|
|
["worktree", "add", "../other"], ["tag", "v1"],
|
|
["tag", "--delete", "--list", "v1"], ["tag", "--list", "--force", "v1"],
|
|
):
|
|
assert blocked_git_mutation(["git", *argv], options, (root,)) == argv[0]
|
|
assert blocked_git_mutation(["git", *argv], {"cwd": tmp_path}, (root,)) is None
|
|
for argv in (["status"], ["config", "--get", "url.x.insteadOf"], ["config", "get", "url.x.insteadOf"],
|
|
["worktree", "list"], ["branch", "--show-current"], ["tag", "-l"],
|
|
["tag", "--merged", "HEAD", "--list", "v[0-9]*"]):
|
|
assert blocked_git_mutation(["git", *argv], options, (root,)) is None
|