test_muse_git_mirror.py python
139 lines 5.2 KB
Raw
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