repo-manager/tests/test_fleet_snapshot.py
tegwick 3e2726f5f1 feat: export pinned offline fleet work-record inputs
Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a15374-f59f-7a31-86d2-d23b5d2ed181
2026-10-19 14:45:11 +02:00

92 lines
3.4 KiB
Python

import hashlib
import json
import subprocess
import pytest
from repo_manager.fleet_snapshot import export_snapshot
def git(repo, *args):
return subprocess.check_output(["git", "-C", str(repo), *args]).decode().strip()
@pytest.fixture
def source(tmp_path):
repo = tmp_path / "source"
repo.mkdir()
git(repo, "init", "-q")
git(repo, "config", "user.name", "Fixture")
git(repo, "config", "user.email", "fixture@example.invalid")
for path, content in {"workplans/active.md": "committed work", "decisions/one.md": "accepted",
"private.txt": "excluded", "workplans/archived/old.md": "done"}.items():
file = repo / path
file.parent.mkdir(parents=True, exist_ok=True)
file.write_text(content)
git(repo, "add", ".")
git(repo, "commit", "-qm", "fixture")
return repo
def request(source):
return {"observed_at": "2026-10-19T10:00:00Z", "repositories": [
{"slug": "example", "path": str(source), "commit": git(source, "rev-parse", "HEAD")}]}
def test_exact_committed_bytes_allowlist_and_manifest(source, tmp_path):
req = request(source)
(source / "workplans/active.md").write_text("dirty excluded")
out = tmp_path / "snapshot"
manifest = export_snapshot(req, out)
assert (out / "example/workplans/active.md").read_text() == "committed work"
assert not (out / "example/private.txt").exists()
assert not (out / "example/.git").exists()
assert len(manifest["repositories"][0]["files"]) == 3
assert manifest["freshness_verified"] is False
assert (out / "COMPLETE").read_text().strip() == hashlib.sha256((out / "manifest.json").read_bytes()).hexdigest()
assert json.loads((out / "manifest.json").read_text()) == manifest
def test_no_overwrite(source, tmp_path):
out = tmp_path / "snapshot"
out.mkdir()
with pytest.raises(ValueError, match="exists"):
export_snapshot(request(source), out)
assert not list(out.iterdir())
@pytest.mark.parametrize("change", ["slug", "commit", "timestamp", "duplicate"])
def test_invalid_request_is_not_published(source, tmp_path, change):
req = request(source)
if change == "slug":
req["repositories"][0]["slug"] = "../outside"
elif change == "commit":
req["repositories"][0]["commit"] = "HEAD"
elif change == "timestamp":
req["observed_at"] = "2026-10-19T10:00:00"
else:
req["repositories"].append(dict(req["repositories"][0]))
with pytest.raises(ValueError):
export_snapshot(req, tmp_path / "snapshot")
assert not (tmp_path / "snapshot").exists()
def test_record_symlink_refused(source, tmp_path):
(source / "workplans/link.md").symlink_to("../private.txt")
git(source, "add", ".")
git(source, "commit", "-qm", "symlink")
with pytest.raises(ValueError, match="unsafe"):
export_snapshot(request(source), tmp_path / "snapshot")
assert not (tmp_path / "snapshot").exists()
def test_symlink_parent_refused(source, tmp_path):
(tmp_path / "alias").symlink_to(source, target_is_directory=True)
with pytest.raises(ValueError, match="symlinks"):
export_snapshot(request(source), tmp_path / "alias/snapshot")
def test_size_limit_refused(source, tmp_path, monkeypatch):
monkeypatch.setattr("repo_manager.fleet_snapshot.MAX_FILE_BYTES", 1)
with pytest.raises(ValueError, match="size"):
export_snapshot(request(source), tmp_path / "snapshot")