permanence / tests /test_mock_git.py
chane35's picture
PERMANENCE training: 4-stage SFT -> gate -> GRPO -> eval pipeline
21c24ae verified
"""Tests for permanence.world.git — reversibility + isolation."""
from __future__ import annotations
import socket
import subprocess
from unittest.mock import patch
from permanence.world.git import MockGitRepo
def test_initial_commit_and_log_are_r1_r2():
repo = MockGitRepo()
res = repo.commit("add feature", {"src/main.py": b"print(1)"})
assert res.ok and res.r_level == 2
log_res = repo.log()
assert log_res.ok and log_res.r_level == 1
def test_reset_hard_is_r3_via_reflog():
repo = MockGitRepo()
repo.commit("a", {"a": b"1"})
repo.commit("b", {"a": b"1", "b": b"2"})
res = repo.reset_hard(1)
assert res.ok and res.r_level == 3
assert len(res.orphaned_commits) == 1
def test_reset_hard_after_reflog_expired_is_r4():
repo = MockGitRepo()
repo.commit("a", {"a": b"1"})
repo.commit("b", {"a": b"1", "b": b"2"})
repo.reflog_expire_all()
res = repo.reset_hard(1)
assert res.ok and res.r_level == 4
def test_branch_delete_with_reflog_is_r3():
repo = MockGitRepo()
repo.checkout_branch("feature", create=True)
repo.commit("feature work", {"x": b"1"})
repo.checkout_branch("main")
res = repo.delete_branch("feature")
assert res.ok and res.r_level == 3
assert len(res.orphaned_commits) == 1
def test_push_is_r2_and_force_push_preserved_elsewhere_is_r4():
repo = MockGitRepo()
# Make two local commits then push normally
repo.commit("a", {"a": b"1"})
repo.commit("b", {"a": b"1", "b": b"2"})
push = repo.push()
assert push.ok and push.r_level == 2
# Now rewrite history locally (reset past the second commit)
repo.reset_hard(1)
# The previous commit b is preserved on someone else's clone (modeled)
remote_tip = repo.remote_branches["main"]
repo.other_clones_have_commits.add(remote_tip)
res = repo.push_force()
assert res.ok and res.r_level == 4
def test_force_push_without_preservation_is_r5():
repo = MockGitRepo()
repo.commit("a", {"a": b"1"})
repo.commit("b", {"a": b"1", "b": b"2"})
repo.push()
repo.reset_hard(1) # Drop commit b locally
# Nobody has b anywhere
res = repo.push_force()
assert res.ok and res.r_level == 5
assert len(res.orphaned_commits) >= 1
def test_reflog_expire_all_with_orphans_is_r5():
repo = MockGitRepo()
repo.commit("a", {"a": b"1"})
repo.commit("b", {"a": b"1", "b": b"2"})
repo.reset_hard(1) # b now only lives in reflog
res = repo.reflog_expire_all()
assert res.ok and res.r_level == 5
def test_filter_branch_rewrites_history_r4():
repo = MockGitRepo()
repo.commit("add secrets", {"src/main.py": b"x", "secrets.env": b"KEY=abc"})
repo.commit("more work", {"src/main.py": b"y", "secrets.env": b"KEY=abc"})
res = repo.filter_branch_drop("secrets.env")
assert res.ok and res.r_level == 4
# Every new commit's files should lack secrets.env
tip = repo.branches["main"]
assert "secrets.env" not in repo.commits[tip].files
def test_mock_git_never_shells_out_or_hits_network():
"""Same isolation guarantee as the mock FS."""
with patch.object(subprocess, "run") as mock_run, patch.object(
subprocess, "Popen"
) as mock_popen, patch.object(socket, "socket") as mock_sock:
repo = MockGitRepo()
repo.commit("x", {"a": b"1"})
repo.checkout_branch("feat", create=True)
repo.commit("y", {"a": b"2"})
repo.checkout_branch("main")
repo.delete_branch("feat")
repo.push()
repo.reset_hard(1)
repo.push_force()
assert mock_run.call_count == 0
assert mock_popen.call_count == 0
assert mock_sock.call_count == 0