test_muse_git_mirror.py
python
sha256:4671b7f787ddbe63ced31c895b688c77ab495653b65a730b423329f26b3c1439
feat: K1-P1 complete — agent provenance, build-verification…
Sonnet 4.6
patch
55 days ago
| 1 | """Unit tests for muse+git-mirror adapter fail-closed branches.""" |
| 2 | |
| 3 | from __future__ import annotations |
| 4 | |
| 5 | from pathlib import Path |
| 6 | |
| 7 | from adapters.errors import ReadError |
| 8 | from tests.support import adapter_for, fail, make_runner, ok |
| 9 | |
| 10 | |
| 11 | def _bridge_toml(from_sha: str = "aaa111", export_sha: str = "bbb222") -> str: |
| 12 | return f"""[last_import] |
| 13 | git_sha = "{from_sha}" |
| 14 | |
| 15 | [last_export] |
| 16 | git_sha = "{export_sha}" |
| 17 | """ |
| 18 | |
| 19 | |
| 20 | def test_status_reads_both_histories(muse_git_mirror_config, repo_root) -> None: |
| 21 | root = str(repo_root) |
| 22 | runner = make_runner( |
| 23 | { |
| 24 | f"muse -C {root} rev-parse --abbrev-ref HEAD": ok("main"), |
| 25 | f"muse -C {root} status --json": ok('{"dirty": false}'), |
| 26 | f"muse -C {root} status --porcelain": ok(""), |
| 27 | "git rev-parse": ok("main"), |
| 28 | "git status": ok(" M file"), |
| 29 | } |
| 30 | ) |
| 31 | adapter = adapter_for(muse_git_mirror_config, repo_root, runner) |
| 32 | result = adapter.status() |
| 33 | assert result.dirty is True |
| 34 | assert "sd-14" in result.notes[2] |
| 35 | |
| 36 | |
| 37 | def test_read_canonical_anchor_from_bridge(muse_git_mirror_config, repo_root) -> None: |
| 38 | bridge = repo_root / ".muse" |
| 39 | bridge.mkdir(parents=True) |
| 40 | (bridge / "git-bridge.toml").write_text(_bridge_toml(), encoding="utf-8") |
| 41 | adapter = adapter_for(muse_git_mirror_config, repo_root, make_runner({})) |
| 42 | result = adapter.read_canonical_anchor() |
| 43 | assert result.anchor_sha == "bbb222" |
| 44 | assert "last_export" in result.source |
| 45 | |
| 46 | |
| 47 | def test_read_canonical_anchor_fails_without_bridge(muse_git_mirror_config, repo_root) -> None: |
| 48 | runner = make_runner({"git rev-parse": fail("unknown ref")}) |
| 49 | adapter = adapter_for(muse_git_mirror_config, repo_root, runner) |
| 50 | result = adapter.read_canonical_anchor() |
| 51 | assert isinstance(result, ReadError) |
| 52 | |
| 53 | |
| 54 | def test_realign_dry_run_counts_commits(muse_git_mirror_config, repo_root) -> None: |
| 55 | bridge = repo_root / ".muse" |
| 56 | bridge.mkdir(parents=True) |
| 57 | (bridge / "git-bridge.toml").write_text(_bridge_toml(from_sha="aaa"), encoding="utf-8") |
| 58 | runner = make_runner( |
| 59 | { |
| 60 | "git rev-parse": ok("ccc333"), |
| 61 | "git rev-list": ok("3"), |
| 62 | } |
| 63 | ) |
| 64 | adapter = adapter_for(muse_git_mirror_config, repo_root, runner) |
| 65 | result = adapter.realign(dry_run=True, max_commits=50) |
| 66 | assert result.would_import == 3 |
| 67 | assert result.applied is False |
| 68 | assert result.reason == "dry-run" |
| 69 | |
| 70 | |
| 71 | def test_realign_refuses_over_max_commits(muse_git_mirror_config, repo_root) -> None: |
| 72 | bridge = repo_root / ".muse" |
| 73 | bridge.mkdir(parents=True) |
| 74 | (bridge / "git-bridge.toml").write_text(_bridge_toml(), encoding="utf-8") |
| 75 | runner = make_runner( |
| 76 | { |
| 77 | "git rev-parse": ok("ccc333"), |
| 78 | "git rev-list": ok("99"), |
| 79 | } |
| 80 | ) |
| 81 | adapter = adapter_for(muse_git_mirror_config, repo_root, runner) |
| 82 | result = adapter.realign(dry_run=False, max_commits=50) |
| 83 | assert result.would_import == 99 |
| 84 | assert result.applied is False |
| 85 | assert "max_commits" in (result.reason or "") |
| 86 | |
| 87 | |
| 88 | def test_realign_apply_invokes_git_import(muse_git_mirror_config, repo_root) -> None: |
| 89 | bridge = repo_root / ".muse" |
| 90 | bridge.mkdir(parents=True) |
| 91 | (bridge / "git-bridge.toml").write_text(_bridge_toml(), encoding="utf-8") |
| 92 | root = str(repo_root) |
| 93 | runner = make_runner( |
| 94 | { |
| 95 | "git rev-parse": ok("ccc333"), |
| 96 | "git rev-list": ok("2"), |
| 97 | f"muse -C {root} bridge": ok("imported"), |
| 98 | } |
| 99 | ) |
| 100 | adapter = adapter_for(muse_git_mirror_config, repo_root, runner) |
| 101 | result = adapter.realign(dry_run=False, max_commits=50) |
| 102 | assert result.applied is True |
| 103 | assert any("git-import" in call[0] for call in runner.calls) |
| 104 | |
| 105 | |
| 106 | def test_mirror_dry_run_reports_delta(muse_git_mirror_config, repo_root) -> None: |
| 107 | root = str(repo_root) |
| 108 | runner = make_runner({f"muse -C {root} bridge": ok("2 commits ahead")}) |
| 109 | adapter = adapter_for(muse_git_mirror_config, repo_root, runner) |
| 110 | result = adapter.mirror(dry_run=True) |
| 111 | assert result.diff_summary == "2 commits ahead" |
| 112 | assert result.pushed is False |
| 113 | |
| 114 | |
| 115 | def test_mirror_requires_operator_before_push(muse_git_mirror_config, repo_root) -> None: |
| 116 | root = str(repo_root) |
| 117 | runner = make_runner({f"muse -C {root} bridge": ok("ready")}) |
| 118 | adapter = adapter_for(muse_git_mirror_config, repo_root, runner) |
| 119 | result = adapter.mirror(dry_run=False) |
| 120 | assert result.pushed is False |
| 121 | assert result.reason == "operator-authorization-required" |
| 122 | |
| 123 | |
| 124 | def test_commit_feature_uses_rev_parse_for_branch_probe(muse_git_mirror_config, repo_root) -> None: |
| 125 | """muse 0.2.0rc15 lacks ``muse log --format=%H``; use ``rev-parse`` + JSON ``commit_id``.""" |
| 126 | root = str(repo_root) |
| 127 | runner = make_runner( |
| 128 | { |
| 129 | f"muse -C {root} checkout": ok(""), |
| 130 | f"muse -C {root} rev-parse --abbrev-ref HEAD": ok("feat/k7"), |
| 131 | f"muse -C {root} commit": ok(""), |
| 132 | f"muse -C {root} rev-parse HEAD": ok('{"commit_id": "sha256:abc"}'), |
| 133 | } |
| 134 | ) |
| 135 | adapter = adapter_for(muse_git_mirror_config, repo_root, runner) |
| 136 | result = adapter.commit_feature(branch="feat/k7", message="test", paths=[]) |
| 137 | assert result.committed is True |
| 138 | assert any("rev-parse --abbrev-ref HEAD" in call[0] for call in runner.calls) |
| 139 | assert not any("log -1 --format" in call[0] for call in runner.calls) |
File History
1 commit
sha256:4671b7f787ddbe63ced31c895b688c77ab495653b65a730b423329f26b3c1439
feat: K1-P1 complete — agent provenance, build-verification…
Sonnet 4.6
patch
55 days ago