gabriel / muse public
test_stress_query_engine.py python
361 lines 13.6 KB
Raw
sha256:660fcac1df3ab28f61862e961890bd2ca8b754fa0242079d93ca1e25037ec8a6 chore(tests): add docstring to tests/__init__.py so rc14 tr… Human 26 days ago
1 """Stress tests for the generic query engine and code query DSL.
2
3 Covers:
4 - walk_history on linear chains of 100+ commits.
5 - CommitEvaluator with correct 3-arg signature.
6 - format_matches output format.
7 - Code query DSL: all field types, all operators, AND/OR composition.
8 - Code query DSL: unknown field raises ValueError.
9 - Query against large history (200 commits).
10 - Branch-scoped queries.
11 """
12
13 import datetime
14 import pathlib
15
16 import pytest
17
18 from muse.core.query_engine import CommitEvaluator, QueryMatch, format_matches, walk_history
19 from muse.core.snapshot import compute_commit_id, compute_snapshot_id
20 from muse.core.store import CommitRecord, write_commit
21 from muse.domain import SemVerBump
22 from muse.plugins.code._code_query import build_evaluator
23 from muse.core._types import Manifest
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 _now() -> datetime.datetime:
35 return datetime.datetime.now(datetime.timezone.utc)
36
37
38 def _write(
39 root: pathlib.Path,
40 label: str,
41 branch: str = "main",
42 parent: str | None = None,
43 author: str = "alice",
44 agent_id: str = "",
45 model_id: str = "",
46 sem_ver_bump: SemVerBump = "none",
47 message: str = "",
48 ) -> CommitRecord:
49 """Write a commit with a real content-addressed ID. Returns the CommitRecord."""
50 msg = message or f"commit {label}"
51 cid = compute_commit_id(
52 parent_ids=[parent] if parent else [],
53 snapshot_id=_SNAP_ID,
54 message=msg,
55 committed_at_iso=_BASE_TS.isoformat(),
56 )
57 c = CommitRecord(
58 commit_id=cid,
59 repo_id="repo",
60 branch=branch,
61 snapshot_id=_SNAP_ID,
62 message=msg,
63 committed_at=_BASE_TS,
64 parent_commit_id=parent,
65 author=author,
66 agent_id=agent_id,
67 model_id=model_id,
68 sem_ver_bump=sem_ver_bump,
69 )
70 write_commit(root, c)
71 ref = root / ".muse" / "refs" / "heads" / branch
72 ref.write_text(cid)
73 return c
74
75
76 def _make_match(commit: CommitRecord) -> QueryMatch:
77 return QueryMatch(
78 commit_id=commit.commit_id,
79 author=commit.author,
80 committed_at=commit.committed_at.isoformat(),
81 branch=commit.branch,
82 detail=f"matched commit {commit.commit_id}",
83 )
84
85
86 @pytest.fixture
87 def repo(tmp_path: pathlib.Path) -> pathlib.Path:
88 muse = tmp_path / ".muse"
89 (muse / "commits").mkdir(parents=True)
90 (muse / "refs" / "heads").mkdir(parents=True)
91 return tmp_path
92
93
94 # ===========================================================================
95 # walk_history — basic
96 # ===========================================================================
97
98
99 class TestWalkHistoryBasic:
100 def test_empty_history_no_matches(self, repo: pathlib.Path) -> None:
101 def ev(commit: CommitRecord, manifest: Manifest, root: pathlib.Path) -> list[QueryMatch]:
102 return [_make_match(commit)]
103 result = walk_history(repo, "nonexistent-branch", ev)
104 assert result == []
105
106 def test_single_commit_matches(self, repo: pathlib.Path) -> None:
107 c = _write(repo, "only", branch="main")
108 def ev(commit: CommitRecord, manifest: Manifest, root: pathlib.Path) -> list[QueryMatch]:
109 return [_make_match(commit)]
110 result = walk_history(repo, "main", ev)
111 assert len(result) == 1
112 assert result[0]["commit_id"] == c.commit_id
113
114 def test_single_commit_no_match(self, repo: pathlib.Path) -> None:
115 _write(repo, "only", branch="main")
116 def ev(commit: CommitRecord, manifest: Manifest, root: pathlib.Path) -> list[QueryMatch]:
117 return []
118 result = walk_history(repo, "main", ev)
119 assert result == []
120
121 def test_linear_chain_all_match(self, repo: pathlib.Path) -> None:
122 prev: str | None = None
123 for i in range(10):
124 c = _write(repo, f"c{i:03d}", parent=prev)
125 prev = c.commit_id
126 def ev(commit: CommitRecord, manifest: Manifest, root: pathlib.Path) -> list[QueryMatch]:
127 return [_make_match(commit)]
128 result = walk_history(repo, "main", ev)
129 assert len(result) == 10
130
131 def test_linear_chain_filtered(self, repo: pathlib.Path) -> None:
132 prev: str | None = None
133 for i in range(10):
134 author = "alice" if i % 2 == 0 else "bob"
135 c = _write(repo, f"c{i:03d}", parent=prev, author=author)
136 prev = c.commit_id
137
138 def ev(commit: CommitRecord, manifest: Manifest, root: pathlib.Path) -> list[QueryMatch]:
139 if commit.author == "alice":
140 return [_make_match(commit)]
141 return []
142
143 result = walk_history(repo, "main", ev)
144 assert len(result) == 5
145
146 def test_max_commits_limits_walk(self, repo: pathlib.Path) -> None:
147 prev: str | None = None
148 for i in range(50):
149 c = _write(repo, f"c{i:03d}", parent=prev)
150 prev = c.commit_id
151 def ev(commit: CommitRecord, manifest: Manifest, root: pathlib.Path) -> list[QueryMatch]:
152 return [_make_match(commit)]
153 result = walk_history(repo, "main", ev, max_commits=10)
154 assert len(result) == 10
155
156 def test_matches_include_commit_id_and_branch(self, repo: pathlib.Path) -> None:
157 c = _write(repo, "abc123", branch="main", author="alice")
158 def ev(commit: CommitRecord, manifest: Manifest, root: pathlib.Path) -> list[QueryMatch]:
159 return [_make_match(commit)]
160 result = walk_history(repo, "main", ev)
161 assert result[0]["commit_id"] == c.commit_id
162 assert result[0]["branch"] == "main"
163 assert result[0]["author"] == "alice"
164
165
166 # ===========================================================================
167 # walk_history — large history
168 # ===========================================================================
169
170
171 class TestWalkHistoryLarge:
172 def test_200_commit_chain_full_scan(self, repo: pathlib.Path) -> None:
173 prev: str | None = None
174 for i in range(200):
175 c = _write(repo, f"large-{i:04d}", parent=prev, agent_id="bot" if i % 3 == 0 else "")
176 prev = c.commit_id
177
178 def bot_only(commit: CommitRecord, manifest: Manifest, root: pathlib.Path) -> list[QueryMatch]:
179 if commit.agent_id == "bot":
180 return [_make_match(commit)]
181 return []
182
183 result = walk_history(repo, "main", bot_only)
184 # 200 commits, every 3rd is bot: indices 0, 3, 6, ..., 198 → 67 commits.
185 assert len(result) == 67
186
187 def test_query_by_agent_across_100_commits(self, repo: pathlib.Path) -> None:
188 prev: str | None = None
189 for i in range(100):
190 agent = f"agent-{i % 5}"
191 c = _write(repo, f"agent-test-{i:04d}", parent=prev, agent_id=agent)
192 prev = c.commit_id
193
194 def agent_0_only(commit: CommitRecord, manifest: Manifest, root: pathlib.Path) -> list[QueryMatch]:
195 if commit.agent_id == "agent-0":
196 return [_make_match(commit)]
197 return []
198
199 result = walk_history(repo, "main", agent_0_only)
200 assert len(result) == 20 # 100 / 5 = 20
201
202
203 # ===========================================================================
204 # format_matches
205 # ===========================================================================
206
207
208 class TestFormatMatches:
209 def test_empty_matches_produces_output(self) -> None:
210 out = format_matches([])
211 assert isinstance(out, str)
212
213 def test_single_match_includes_commit_id(self) -> None:
214 match = QueryMatch(
215 commit_id="a" * 64,
216 branch="main",
217 author="alice",
218 committed_at=_now().isoformat(),
219 detail="test match",
220 )
221 out = format_matches([match])
222 assert "aaaaaaaa" in out
223
224 def test_multiple_matches_all_present(self) -> None:
225 matches = [
226 QueryMatch(
227 commit_id=f"id{i:04d}",
228 branch="main",
229 author="alice",
230 committed_at=_now().isoformat(),
231 detail="matched",
232 )
233 for i in range(5)
234 ]
235 out = format_matches(matches)
236 for i in range(5):
237 assert f"id{i:04d}" in out
238
239
240 # ===========================================================================
241 # Code query DSL — build_evaluator
242 # ===========================================================================
243
244
245 class TestCodeQueryDSL:
246 # --- author field ---
247
248 def test_author_equals(self, repo: pathlib.Path) -> None:
249 c1 = _write(repo, "a1", author="alice")
250 _write(repo, "a2", author="bob", parent=c1.commit_id)
251 evaluator = build_evaluator("author == 'alice'")
252 result = walk_history(repo, "main", evaluator)
253 assert any(m["commit_id"] == c1.commit_id for m in result)
254 assert not any(m["author"] == "bob" and m["commit_id"] == c1.commit_id for m in result)
255
256 def test_author_not_equals(self, repo: pathlib.Path) -> None:
257 c1 = _write(repo, "b1", author="alice")
258 _write(repo, "b2", author="bob", parent=c1.commit_id)
259 evaluator = build_evaluator("author != 'alice'")
260 result = walk_history(repo, "main", evaluator)
261 assert all(m["author"] != "alice" for m in result)
262
263 def test_author_contains(self, repo: pathlib.Path) -> None:
264 c1 = _write(repo, "c1", author="alice-smith")
265 _write(repo, "c2", author="bob-jones", parent=c1.commit_id)
266 evaluator = build_evaluator("author contains 'alice'")
267 result = walk_history(repo, "main", evaluator)
268 assert len(result) == 1
269 assert "alice" in result[0]["author"]
270
271 def test_author_startswith(self, repo: pathlib.Path) -> None:
272 c1 = _write(repo, "d1", author="agent-claude")
273 _write(repo, "d2", author="human-alice", parent=c1.commit_id)
274 evaluator = build_evaluator("author startswith 'agent'")
275 result = walk_history(repo, "main", evaluator)
276 assert len(result) == 1
277 assert result[0]["author"].startswith("agent")
278
279 # --- agent_id field ---
280
281 def test_agent_id_equals(self, repo: pathlib.Path) -> None:
282 c1 = _write(repo, "e1", agent_id="claude-v4")
283 _write(repo, "e2", agent_id="gpt-4o", parent=c1.commit_id)
284 evaluator = build_evaluator("agent_id == 'claude-v4'")
285 result = walk_history(repo, "main", evaluator)
286 assert len(result) == 1
287 assert result[0]["commit_id"] == c1.commit_id
288
289 # --- sem_ver_bump field ---
290
291 def test_sem_ver_bump_major(self, repo: pathlib.Path) -> None:
292 c1 = _write(repo, "f1", sem_ver_bump="major")
293 c2 = _write(repo, "f2", sem_ver_bump="minor", parent=c1.commit_id)
294 _write(repo, "f3", sem_ver_bump="patch", parent=c2.commit_id)
295 evaluator = build_evaluator("sem_ver_bump == 'major'")
296 result = walk_history(repo, "main", evaluator)
297 assert len(result) == 1
298
299 # --- model_id field ---
300
301 def test_model_id_contains(self, repo: pathlib.Path) -> None:
302 c1 = _write(repo, "g1", model_id="claude-3-5-sonnet-20241022")
303 _write(repo, "g2", model_id="gpt-4o-2024-08-06", parent=c1.commit_id)
304 evaluator = build_evaluator("model_id contains 'claude'")
305 result = walk_history(repo, "main", evaluator)
306 assert len(result) == 1
307
308 # --- AND composition ---
309
310 def test_and_composition(self, repo: pathlib.Path) -> None:
311 c1 = _write(repo, "h1", author="alice", agent_id="bot-1")
312 c2 = _write(repo, "h2", author="alice", agent_id="bot-2", parent=c1.commit_id)
313 _write(repo, "h3", author="bob", agent_id="bot-1", parent=c2.commit_id)
314 evaluator = build_evaluator("author == 'alice' and agent_id == 'bot-1'")
315 result = walk_history(repo, "main", evaluator)
316 assert len(result) == 1
317 assert result[0]["commit_id"] == c1.commit_id
318
319 # --- OR composition ---
320
321 def test_or_composition(self, repo: pathlib.Path) -> None:
322 c1 = _write(repo, "i1", author="alice")
323 c2 = _write(repo, "i2", author="bob", parent=c1.commit_id)
324 _write(repo, "i3", author="charlie", parent=c2.commit_id)
325 evaluator = build_evaluator("author == 'alice' or author == 'bob'")
326 result = walk_history(repo, "main", evaluator)
327 assert len(result) == 2
328
329 # --- complex nested AND OR ---
330
331 def test_complex_and_or(self, repo: pathlib.Path) -> None:
332 c1 = _write(repo, "j1", author="alice", sem_ver_bump="major")
333 c2 = _write(repo, "j2", author="bob", sem_ver_bump="minor", parent=c1.commit_id)
334 _write(repo, "j3", author="alice", sem_ver_bump="patch", parent=c2.commit_id)
335 evaluator = build_evaluator(
336 "sem_ver_bump == 'major' or sem_ver_bump == 'minor'"
337 )
338 result = walk_history(repo, "main", evaluator)
339 assert len(result) == 2
340
341 # --- error cases ---
342
343 def test_unknown_field_raises_value_error(self) -> None:
344 with pytest.raises(ValueError):
345 build_evaluator("unknown_field == 'something'")
346
347 def test_unknown_operator_raises_value_error(self) -> None:
348 with pytest.raises(ValueError):
349 build_evaluator("author REGEX 'alice'")
350
351 def test_empty_query_raises(self) -> None:
352 with pytest.raises((ValueError, IndexError)):
353 build_evaluator("")
354
355 # --- branch field ---
356
357 def test_branch_field_matches_correctly(self, repo: pathlib.Path) -> None:
358 _write(repo, "k1", branch="main", author="alice")
359 evaluator = build_evaluator("branch == 'main'")
360 result = walk_history(repo, "main", evaluator)
361 assert all(m["branch"] == "main" for m in result)
File History 5 commits
sha256:660fcac1df3ab28f61862e961890bd2ca8b754fa0242079d93ca1e25037ec8a6 chore(tests): add docstring to tests/__init__.py so rc14 tr… Human 26 days ago
sha256:d8316ffae901be06347e16ab55be11868eb519dd16ade3e8aa16a99e662f7e62 baseline: rc14 re-baseline after rc3 store corruption recovery Human patch 26 days ago
sha256:50d413a635f57761c3fce1f70251b957b6423821525bf330747ef4007339222e Merge branch 'dev' into main Human 29 days ago
sha256:fb67fed5a4d3e40de84bdd163de94ef1386570bef1dd1a020a732c8a038962ce Merge branch 'dev' into main Human 48 days ago
sha256:1c4b3e3a9a1f300774c3ee662b572a698d5fd405bf765a71e6011a2e9c3eaaaa feat: Muse — version control for the agent era Human 100 days ago