gabriel / muse public
test_stress_graph.py python
278 lines 10.1 KB
Raw
sha256:b636f72dcba9e190afb980bece906fa5b717fbde014b76ef023df8cb96e01eb9 docs: expand cache plan with all seven testing tiers and do… Sonnet 4.6 131 days ago
1 """Stress tests for the commit DAG and merge-base algorithm.
2
3 Exercises:
4 - Linear chains of 500 commits.
5 - Wide fan-out / fan-in (octopus merge shapes).
6 - Criss-cross merge (ambiguous LCA — should still find *some* ancestor).
7 - Independent histories (no common ancestor → None).
8 - find_merge_base symmetry: find_merge_base(a, b) == find_merge_base(b, a).
9 - Missing commit handles gracefully (None parent pointers in corrupt graphs).
10 - Diamond topology: four-node diamond always finds the root.
11 - Double diamond: two diamonds chained together.
12 - Long parallel branches that converge at a single point.
13 """
14
15 import datetime
16 import pathlib
17
18 import pytest
19
20 from muse.core._types import fake_id
21 from muse.core.merge_engine import find_merge_base
22 from muse.core.snapshot import compute_commit_id, compute_snapshot_id
23 from muse.core.store import CommitRecord, write_commit
24
25
26 # ---------------------------------------------------------------------------
27 # Helpers
28 # ---------------------------------------------------------------------------
29
30 _SNAP_ID: str = compute_snapshot_id({})
31 _BASE_TS: datetime.datetime = datetime.datetime(2026, 1, 1, tzinfo=datetime.timezone.utc)
32
33
34 def _write(
35 root: pathlib.Path,
36 label: str,
37 parent: str | None = None,
38 parent2: str | None = None,
39 ) -> str:
40 """Write a commit with a real content-addressed ID. Returns the commit_id."""
41 parent_ids = [p for p in (parent, parent2) if p is not None]
42 cid = compute_commit_id(
43 repo_id="repo",
44 parent_ids=parent_ids,
45 snapshot_id=_SNAP_ID,
46 message=label,
47 committed_at_iso=_BASE_TS.isoformat(),
48 )
49 write_commit(root, CommitRecord(
50 commit_id=cid,
51 repo_id="repo",
52 created_on_branch="main",
53 snapshot_id=_SNAP_ID,
54 message=label,
55 committed_at=_BASE_TS,
56 parent_commit_id=parent,
57 parent2_commit_id=parent2,
58 ))
59 return cid
60
61
62 @pytest.fixture
63 def repo(tmp_path: pathlib.Path) -> pathlib.Path:
64 muse = tmp_path / ".muse"
65 (muse / "commits").mkdir(parents=True)
66 (muse / "refs" / "heads").mkdir(parents=True)
67 return tmp_path
68
69
70 # ---------------------------------------------------------------------------
71 # Linear chain
72 # ---------------------------------------------------------------------------
73
74
75 class TestLinearChain:
76 def test_chain_of_500_finds_base(self, repo: pathlib.Path) -> None:
77 """LCA of two commits on a 500-long linear chain is the shared ancestor."""
78 prev: str | None = None
79 ids: list[str] = []
80 for i in range(500):
81 cid = _write(repo, f"c{i:04d}", prev)
82 ids.append(cid)
83 prev = cid
84
85 # Branch off at the commit at index 100
86 branch_tip_id = _write(repo, "branch-tip", ids[100])
87
88 base = find_merge_base(repo, ids[499], branch_tip_id)
89 assert base == ids[100]
90
91 def test_lca_of_adjacent_commits_is_parent(self, repo: pathlib.Path) -> None:
92 root_id = _write(repo, "root")
93 child_id = _write(repo, "child", root_id)
94 assert find_merge_base(repo, root_id, child_id) == root_id
95 assert find_merge_base(repo, child_id, root_id) == root_id
96
97 def test_long_chain_lca_symmetry(self, repo: pathlib.Path) -> None:
98 """find_merge_base(a, b) == find_merge_base(b, a) on a long chain."""
99 prev: str | None = None
100 ids: list[str] = []
101 for i in range(100):
102 cid = _write(repo, f"n{i:03d}", prev)
103 ids.append(cid)
104 prev = cid
105
106 left_id = _write(repo, "left", ids[50])
107 right_id = _write(repo, "right", ids[50])
108
109 assert find_merge_base(repo, left_id, right_id) == ids[50]
110 assert find_merge_base(repo, right_id, left_id) == ids[50]
111
112 def test_same_commit_returns_itself(self, repo: pathlib.Path) -> None:
113 solo_id = _write(repo, "solo")
114 assert find_merge_base(repo, solo_id, solo_id) == solo_id
115
116 def test_one_is_ancestor_of_other(self, repo: pathlib.Path) -> None:
117 """When A is a direct ancestor of B, LCA is A."""
118 prev: str | None = None
119 ids: list[str] = []
120 for i in range(20):
121 cid = _write(repo, f"x{i:02d}", prev)
122 ids.append(cid)
123 prev = cid
124 assert find_merge_base(repo, ids[0], ids[19]) == ids[0]
125 assert find_merge_base(repo, ids[19], ids[0]) == ids[0]
126
127
128 # ---------------------------------------------------------------------------
129 # Diamond topology
130 # ---------------------------------------------------------------------------
131
132
133 class TestDiamondTopology:
134 def test_simple_diamond(self, repo: pathlib.Path) -> None:
135 """
136 root
137 / \\
138 L R
139 \\ /
140 M (merge commit, not relevant here — just find LCA of L and R)
141 """
142 root_id = _write(repo, "root")
143 l_id = _write(repo, "L", root_id)
144 r_id = _write(repo, "R", root_id)
145 assert find_merge_base(repo, l_id, r_id) == root_id
146
147 def test_double_diamond(self, repo: pathlib.Path) -> None:
148 """
149 A
150 / \\
151 B C
152 \\ /
153 D
154 / \\
155 E F
156 \\ /
157 G
158 LCA(E, F) should be D.
159 """
160 a_id = _write(repo, "A")
161 b_id = _write(repo, "B", a_id)
162 c_id = _write(repo, "C", a_id)
163 d_id = _write(repo, "D", b_id, c_id)
164 e_id = _write(repo, "E", d_id)
165 f_id = _write(repo, "F", d_id)
166 assert find_merge_base(repo, e_id, f_id) == d_id
167
168 def test_criss_cross_merge(self, repo: pathlib.Path) -> None:
169 """
170 Criss-cross: A and B are each other's ancestor via two different merge paths.
171 X → L1 → M1(L1,R1)
172 X → R1 → M2(R1,L1)
173 LCA of M1 and M2 should be either L1 or R1 (both are valid LCAs).
174 The algorithm must not return None or crash.
175 """
176 x_id = _write(repo, "X")
177 l1_id = _write(repo, "L1", x_id)
178 r1_id = _write(repo, "R1", x_id)
179 m1_id = _write(repo, "M1", l1_id, r1_id)
180 m2_id = _write(repo, "M2", r1_id, l1_id)
181
182 base = find_merge_base(repo, m1_id, m2_id)
183 # Any of X, L1, R1 is a valid common ancestor; None is not acceptable.
184 assert base is not None
185 assert base in {x_id, l1_id, r1_id}
186
187 def test_octopus_three_branch_fan_in(self, repo: pathlib.Path) -> None:
188 """Three branches that all diverged from the same root."""
189 root_id = _write(repo, "root")
190 ba_id = _write(repo, "branch-a", root_id)
191 bb_id = _write(repo, "branch-b", root_id)
192 bc_id = _write(repo, "branch-c", root_id)
193
194 assert find_merge_base(repo, ba_id, bb_id) == root_id
195 assert find_merge_base(repo, ba_id, bc_id) == root_id
196 assert find_merge_base(repo, bb_id, bc_id) == root_id
197
198
199 # ---------------------------------------------------------------------------
200 # Independent histories
201 # ---------------------------------------------------------------------------
202
203
204 class TestDisjointHistories:
205 def test_no_common_ancestor_returns_none(self, repo: pathlib.Path) -> None:
206 island_a_id = _write(repo, "island-a")
207 island_b_id = _write(repo, "island-b")
208 assert find_merge_base(repo, island_a_id, island_b_id) is None
209
210 def test_long_independent_chains_return_none(self, repo: pathlib.Path) -> None:
211 prev_a: str | None = None
212 prev_b: str | None = None
213 last_a = last_b = ""
214 for i in range(20):
215 last_a = _write(repo, f"a{i:02d}", prev_a)
216 last_b = _write(repo, f"b{i:02d}", prev_b)
217 prev_a = last_a
218 prev_b = last_b
219 assert find_merge_base(repo, last_a, last_b) is None
220
221 def test_missing_commit_id_graceful(self, repo: pathlib.Path) -> None:
222 """Asking for an LCA where one commit doesn't exist should return None, not raise."""
223 real_id = _write(repo, "real")
224 result = find_merge_base(repo, real_id, fake_id("ghost-commit-that-does-not-exist"))
225 # The ghost has no ancestors, so no common ancestor found.
226 assert result is None
227
228
229 # ---------------------------------------------------------------------------
230 # Ancestor-set correctness
231 # ---------------------------------------------------------------------------
232
233
234 class TestAncestorCorrectness:
235 def test_merge_commit_has_both_parents_as_ancestors(self, repo: pathlib.Path) -> None:
236 root_id = _write(repo, "root")
237 a_id = _write(repo, "A", root_id)
238 b_id = _write(repo, "B", root_id)
239 merge_id = _write(repo, "merge", a_id, b_id)
240 feature_id = _write(repo, "feature", a_id)
241
242 # LCA of feature and merge: feature branched from A, merge contains A.
243 # So A is the common ancestor.
244 base = find_merge_base(repo, feature_id, merge_id)
245 assert base == a_id
246
247 def test_wide_history_with_shared_root(self, repo: pathlib.Path) -> None:
248 """100 branches diverging from a shared root, pairwise LCA is root."""
249 root_id = _write(repo, "root")
250 branch_ids = [_write(repo, f"br{i:03d}", root_id) for i in range(50)]
251
252 # Check a sampling of pairs
253 for i in range(0, 50, 10):
254 for j in range(i + 1, 50, 10):
255 assert find_merge_base(repo, branch_ids[i], branch_ids[j]) == root_id
256
257 def test_deep_branch_divergence(self, repo: pathlib.Path) -> None:
258 """Branches diverge at root, each has 50 commits. LCA is root."""
259 root_id = _write(repo, "root")
260 prev_a: str | None = root_id
261 prev_b: str | None = root_id
262 last_a = last_b = root_id
263 for i in range(50):
264 last_a = _write(repo, f"da{i:02d}", prev_a)
265 last_b = _write(repo, f"db{i:02d}", prev_b)
266 prev_a = last_a
267 prev_b = last_b
268
269 assert find_merge_base(repo, last_a, last_b) == root_id
270
271 def test_multiple_merge_bases_chain(self, repo: pathlib.Path) -> None:
272 """A → B → C; branch D from B. LCA of C and D is B."""
273 a_id = _write(repo, "A")
274 b_id = _write(repo, "B", a_id)
275 c_id = _write(repo, "C", b_id)
276 d_id = _write(repo, "D", b_id)
277 assert find_merge_base(repo, c_id, d_id) == b_id
278 assert find_merge_base(repo, d_id, c_id) == b_id
File History 3 commits
sha256:b636f72dcba9e190afb980bece906fa5b717fbde014b76ef023df8cb96e01eb9 docs: expand cache plan with all seven testing tiers and do… Sonnet 4.6 131 days ago
sha256:7f9e2ef5286aedad9c1e6011b4c46ca27f39dbdad6e3409357e36b26e46b3b7c docs: docstring sprint for-each-ref→hotspots — idiomatic ru… Sonnet 4.6 patch 138 days ago
sha256:a09b1b4f6838754495547f200aa0ce88e2f56ffc5b20b900f6f0cff2c3cdede9 fix(cursorignore): remove git-ism (.git/worktrees) Human minor 140 days ago