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