gabriel / muse public
test_mpack_cmd_verify.py python
645 lines 25.3 KB
Raw
sha256:b636f72dcba9e190afb980bece906fa5b717fbde014b76ef023df8cb96e01eb9 docs: expand cache plan with all seven testing tiers and do… Sonnet 4.6 132 days ago
1 """Comprehensive tests for muse verify-pack.
2
3 Coverage:
4 - Unit: TypedDict schemas, _Failure, _VerifyPackResult, _StatResult
5 - Integration: JSON/text formats, --stat, --quiet, --no-local, --file, --json shorthand
6 - Verification: object integrity, snapshot consistency, commit consistency
7 - Security: ANSI sanitization, format error → stderr, no tracebacks, invalid object IDs
8 - Stress: 500-object bundle, 200 sequential verifications, large object hashing
9 """
10
11 from __future__ import annotations
12 from collections.abc import Mapping
13
14 import datetime
15 import io
16 import json
17 import pathlib
18 import uuid
19
20 import msgpack
21 import pytest
22 from tests.cli_test_helper import CliRunner, InvokeResult
23
24 from muse.cli.commands.verify_pack import (
25 _Failure,
26 _StatResultJson as _StatResult,
27 _VerifyPackJson as _VerifyPackResult,
28 )
29 from muse.core.store import CommitRecord, SnapshotRecord, write_commit, write_snapshot
30 from muse.core._types import Manifest, blob_id, long_id, fake_id
31 from typing import TypedDict
32
33 runner = CliRunner()
34
35
36 # ---------------------------------------------------------------------------
37 # Bundle TypedDicts (mirror the output contract shape)
38 # ---------------------------------------------------------------------------
39
40 class _ObjectEntry(TypedDict):
41 object_id: str
42 content: bytes
43
44
45 class _SnapshotEntry(TypedDict, total=False):
46 snapshot_id: str
47 manifest: Manifest
48
49
50 class _CommitEntry(TypedDict):
51 commit_id: str
52 snapshot_id: str
53
54
55 type _EnvMap = dict[str, str]
56 type _CommitEntryDict = dict[str, str]
57 type _BadObjectEntry = dict[str, str | bytes]
58 type _BundleDict = dict[str, list[_ObjectEntry] | list[_SnapshotEntry] | list[_CommitEntry]]
59
60
61 # ---------------------------------------------------------------------------
62 # Helpers
63 # ---------------------------------------------------------------------------
64
65 def _init_repo(path: pathlib.Path) -> pathlib.Path:
66 muse = path / ".muse"
67 (muse / "commits").mkdir(parents=True, exist_ok=True)
68 (muse / "snapshots").mkdir(parents=True, exist_ok=True)
69 (muse / "objects" / "ab").mkdir(parents=True, exist_ok=True)
70 (muse / "refs" / "heads").mkdir(parents=True, exist_ok=True)
71 (muse / "HEAD").write_text("ref: refs/heads/main", encoding="utf-8")
72 (muse / "repo.json").write_text(
73 json.dumps({"repo_id": "test-repo", "domain": "generic"}), encoding="utf-8"
74 )
75 return path
76
77
78 def _env(repo: pathlib.Path) -> _EnvMap:
79 return {"MUSE_REPO_ROOT": str(repo)}
80
81
82 def _sha(data: bytes) -> str:
83 return blob_id(data)
84
85
86 def _good_obj(data: bytes = b"hello world") -> _ObjectEntry:
87 return _ObjectEntry(object_id=_sha(data), content=data)
88
89
90 def _bad_hash_obj(data: bytes = b"hello world") -> _ObjectEntry:
91 return _ObjectEntry(object_id=fake_id("bad-hash"), content=data)
92
93
94 _FULL_META = {
95 "mode": "full",
96 "base_commits": [],
97 "created_at": "2025-01-01T00:00:00Z",
98 }
99
100
101 def _make_bundle(
102 objects: list[_ObjectEntry] | None = None,
103 snapshots: list[_SnapshotEntry] | None = None,
104 commits: list[_CommitEntry] | None = None,
105 meta: Mapping[str, object] | None = None,
106 ) -> bytes:
107 bundle: _BundleDict = {
108 "meta": meta if meta is not None else _FULL_META,
109 "objects": objects or [],
110 "snapshots": snapshots or [],
111 "commits": commits or [],
112 }
113 return msgpack.packb(bundle, use_bin_type=True)
114
115
116 def _vp(
117 tmp_path: pathlib.Path,
118 args: list[str],
119 stdin: bytes | None = None,
120 ) -> InvokeResult:
121 """Invoke verify-pack against a freshly initialised repo in tmp_path."""
122 from muse.cli.app import main as cli
123 _init_repo(tmp_path)
124 return runner.invoke(
125 cli,
126 ["verify-pack"] + args,
127 env=_env(tmp_path),
128 input=stdin,
129 )
130
131
132 # ---------------------------------------------------------------------------
133 # Unit: schemas
134 # ---------------------------------------------------------------------------
135
136 class TestSchemas:
137 def test_failure_fields(self) -> None:
138 f: _Failure = {"kind": "object", "id": "abc", "error": "hash mismatch"}
139 assert f["kind"] == "object"
140 assert f["id"] == "abc"
141 assert f["error"] == "hash mismatch"
142
143 def test_verify_pack_result_fields(self) -> None:
144 r: _VerifyPackResult = {
145 "objects_checked": 3,
146 "snapshots_checked": 2,
147 "commits_checked": 1,
148 "all_ok": True,
149 "failures": [],
150 }
151 assert r["all_ok"] is True
152 assert isinstance(r["failures"], list)
153
154 def test_stat_result_fields(self) -> None:
155 s: _StatResult = {"objects": 10, "snapshots": 5, "commits": 3}
156 assert s["objects"] == 10
157
158
159 # ---------------------------------------------------------------------------
160 # Integration: JSON output — clean bundles
161 # ---------------------------------------------------------------------------
162
163 class TestJsonOutputClean:
164 def test_empty_bundle(self, tmp_path: pathlib.Path) -> None:
165 bf = tmp_path / "b.muse"
166 bf.write_bytes(_make_bundle())
167 r = _vp(tmp_path, ["--file", str(bf), "--no-local", "--json"])
168 assert r.exit_code == 0
169 d = json.loads(r.output)
170 assert d["all_ok"] is True
171 assert d["failures"] == []
172 assert d["objects_checked"] == 0
173 assert d["snapshots_checked"] == 0
174 assert d["commits_checked"] == 0
175
176 def test_single_good_object(self, tmp_path: pathlib.Path) -> None:
177 bf = tmp_path / "b.muse"
178 bf.write_bytes(_make_bundle([_good_obj()]))
179 r = _vp(tmp_path, ["--file", str(bf), "--no-local", "--json"])
180 assert r.exit_code == 0
181 d = json.loads(r.output)
182 assert d["all_ok"] is True
183 assert d["objects_checked"] == 1
184
185 def test_json_shorthand(self, tmp_path: pathlib.Path) -> None:
186 bf = tmp_path / "b.muse"
187 bf.write_bytes(_make_bundle())
188 r = _vp(tmp_path, ["--file", str(bf), "--json", "--no-local"])
189 assert r.exit_code == 0
190 json.loads(r.output) # must be valid JSON
191
192 def test_multiple_good_objects(self, tmp_path: pathlib.Path) -> None:
193 objs = [_good_obj(f"content-{i}".encode()) for i in range(10)]
194 bf = tmp_path / "b.muse"
195 bf.write_bytes(_make_bundle(objs))
196 r = _vp(tmp_path, ["--file", str(bf), "--no-local", "--json"])
197 assert r.exit_code == 0
198 d = json.loads(r.output)
199 assert d["objects_checked"] == 10
200 assert d["all_ok"] is True
201
202
203 # ---------------------------------------------------------------------------
204 # Integration: JSON output — hash integrity failures
205 # ---------------------------------------------------------------------------
206
207 class TestObjectIntegrity:
208 def test_bad_hash_detected(self, tmp_path: pathlib.Path) -> None:
209 bf = tmp_path / "b.muse"
210 bf.write_bytes(_make_bundle([_bad_hash_obj()]))
211 r = _vp(tmp_path, ["--file", str(bf), "--no-local", "--json"])
212 assert r.exit_code != 0
213 d = json.loads(r.output)
214 assert d["all_ok"] is False
215 assert d["failures"][0]["kind"] == "object"
216 assert "hash mismatch" in d["failures"][0]["error"]
217
218 def test_mix_good_and_bad(self, tmp_path: pathlib.Path) -> None:
219 objs = [_good_obj(b"good"), _bad_hash_obj(b"bad")]
220 bf = tmp_path / "b.muse"
221 bf.write_bytes(_make_bundle(objs))
222 r = _vp(tmp_path, ["--file", str(bf), "--no-local", "--json"])
223 assert r.exit_code != 0
224 d = json.loads(r.output)
225 assert d["objects_checked"] == 2
226 assert len(d["failures"]) == 1
227
228 def test_invalid_object_id_format(self, tmp_path: pathlib.Path) -> None:
229 """Bundle with non-hex object ID should report a specific format error."""
230 bad: _BadObjectEntry = {
231 "object_id": "\x1b[31mmalicious\x1b[0m" + "a" * 55,
232 "content": b"data",
233 }
234 bf = tmp_path / "b.muse"
235 bf.write_bytes(_make_bundle([bad]))
236 r = _vp(tmp_path, ["--file", str(bf), "--no-local", "--json"])
237 assert r.exit_code != 0
238 d = json.loads(r.output)
239 assert d["all_ok"] is False
240 assert "not a valid" in d["failures"][0]["error"].lower() or "sha-256" in d["failures"][0]["error"].lower()
241
242 def test_entry_not_dict(self, tmp_path: pathlib.Path) -> None:
243 bundle = {
244 "meta": _FULL_META,
245 "objects": ["not-a-dict"],
246 "snapshots": [],
247 "commits": [],
248 }
249 bf = tmp_path / "b.muse"
250 bf.write_bytes(msgpack.packb(bundle, use_bin_type=True))
251 r = _vp(tmp_path, ["--file", str(bf), "--no-local", "--json"])
252 d = json.loads(r.output)
253 assert d["all_ok"] is False
254 assert "not a dict" in d["failures"][0]["error"]
255
256 def test_missing_content_field(self, tmp_path: pathlib.Path) -> None:
257 entry: _CommitEntryDict = {"object_id": "a" * 64} # no content
258 bf = tmp_path / "b.muse"
259 bf.write_bytes(_make_bundle([entry]))
260 r = _vp(tmp_path, ["--file", str(bf), "--no-local", "--json"])
261 d = json.loads(r.output)
262 assert d["all_ok"] is False
263
264 def test_empty_object_passes(self, tmp_path: pathlib.Path) -> None:
265 """An empty bytes object is valid — its SHA-256 is known."""
266 obj = _good_obj(b"")
267 bf = tmp_path / "b.muse"
268 bf.write_bytes(_make_bundle([obj]))
269 r = _vp(tmp_path, ["--file", str(bf), "--no-local", "--json"])
270 d = json.loads(r.output)
271 assert d["all_ok"] is True
272
273 def test_binary_object_passes(self, tmp_path: pathlib.Path) -> None:
274 obj = _good_obj(bytes(range(256)))
275 bf = tmp_path / "b.muse"
276 bf.write_bytes(_make_bundle([obj]))
277 r = _vp(tmp_path, ["--file", str(bf), "--no-local", "--json"])
278 d = json.loads(r.output)
279 assert d["all_ok"] is True
280
281
282 # ---------------------------------------------------------------------------
283 # Integration: snapshot consistency
284 # ---------------------------------------------------------------------------
285
286 class TestSnapshotConsistency:
287 def _snap_entry(self, snap_id: str, manifest: Manifest) -> _SnapshotEntry:
288 return _SnapshotEntry(snapshot_id=snap_id, manifest=manifest)
289
290 def test_snapshot_with_all_objects_present(self, tmp_path: pathlib.Path) -> None:
291 obj = _good_obj(b"snap-obj")
292 snap = self._snap_entry(_sha(b"snap"), {"file.txt": obj["object_id"]})
293 bf = tmp_path / "b.muse"
294 bf.write_bytes(_make_bundle(objects=[obj], snapshots=[snap]))
295 r = _vp(tmp_path, ["--file", str(bf), "--no-local", "--json"])
296 d = json.loads(r.output)
297 assert d["all_ok"] is True
298 assert d["snapshots_checked"] == 1
299
300 def test_snapshot_missing_object_fails(self, tmp_path: pathlib.Path) -> None:
301 missing_oid = "b" * 64
302 snap = self._snap_entry(_sha(b"snap"), {"file.txt": missing_oid})
303 bf = tmp_path / "b.muse"
304 bf.write_bytes(_make_bundle(snapshots=[snap]))
305 r = _vp(tmp_path, ["--file", str(bf), "--no-local", "--json"])
306 d = json.loads(r.output)
307 assert d["all_ok"] is False
308 assert d["failures"][0]["kind"] == "snapshot"
309 assert "missing object" in d["failures"][0]["error"]
310
311 def test_snapshot_entry_not_dict(self, tmp_path: pathlib.Path) -> None:
312 bundle = {
313 "meta": _FULL_META,
314 "objects": [],
315 "snapshots": ["bad"],
316 "commits": [],
317 }
318 bf = tmp_path / "b.muse"
319 bf.write_bytes(msgpack.packb(bundle, use_bin_type=True))
320 r = _vp(tmp_path, ["--file", str(bf), "--no-local", "--json"])
321 d = json.loads(r.output)
322 assert d["all_ok"] is False
323
324 def test_skip_local_check_allows_missing(self, tmp_path: pathlib.Path) -> None:
325 """--no-local should NOT check the local store; missing objects pass."""
326 # With --no-local, snapshot references a missing object but no local check.
327 missing_oid = "c" * 64
328 snap = self._snap_entry(_sha(b"snap"), {"f.txt": missing_oid})
329 bf = tmp_path / "b.muse"
330 bf.write_bytes(_make_bundle(snapshots=[snap]))
331 # Without --no-local, this fails (missing locally).
332 r_fail = _vp(tmp_path, ["--file", str(bf)])
333 assert r_fail.exit_code != 0
334 # With --no-local, this fails too (not in bundle either).
335 r_nol = _vp(tmp_path, ["--file", str(bf), "--no-local"])
336 assert r_nol.exit_code != 0
337
338
339 # ---------------------------------------------------------------------------
340 # Integration: commit consistency
341 # ---------------------------------------------------------------------------
342
343 class TestCommitConsistency:
344 def _commit_entry(self, commit_id: str, snapshot_id: str) -> _CommitEntryDict:
345 return {"commit_id": commit_id, "snapshot_id": snapshot_id}
346
347 def test_commit_with_bundled_snapshot(self, tmp_path: pathlib.Path) -> None:
348 snap_id = _sha(b"snap-data")
349 snap = {"snapshot_id": snap_id, "manifest": {}}
350 commit = self._commit_entry(_sha(b"c1"), snap_id)
351 bf = tmp_path / "b.muse"
352 bf.write_bytes(_make_bundle(snapshots=[snap], commits=[commit]))
353 r = _vp(tmp_path, ["--file", str(bf), "--no-local", "--json"])
354 d = json.loads(r.output)
355 assert d["all_ok"] is True
356 assert d["commits_checked"] == 1
357
358 def test_commit_missing_snapshot_fails(self, tmp_path: pathlib.Path) -> None:
359 # Default (local store enabled): snapshot not in bundle → failure
360 commit = self._commit_entry(_sha(b"c1"), "d" * 64)
361 bf = tmp_path / "b.muse"
362 bf.write_bytes(_make_bundle(commits=[commit]))
363 r = _vp(tmp_path, ["--file", str(bf), "--json"]) # local check on by default
364 d = json.loads(r.output)
365 assert d["all_ok"] is False
366 assert d["failures"][0]["kind"] == "commit"
367
368 def test_commit_entry_not_dict(self, tmp_path: pathlib.Path) -> None:
369 bundle = {
370 "meta": _FULL_META,
371 "objects": [],
372 "snapshots": [],
373 "commits": [42],
374 }
375 bf = tmp_path / "b.muse"
376 bf.write_bytes(msgpack.packb(bundle, use_bin_type=True))
377 r = _vp(tmp_path, ["--file", str(bf), "--no-local", "--json"])
378 d = json.loads(r.output)
379 assert d["all_ok"] is False
380
381
382 # ---------------------------------------------------------------------------
383 # Integration: text format
384 # ---------------------------------------------------------------------------
385
386 class TestTextFormat:
387 def test_text_format_clean(self, tmp_path: pathlib.Path) -> None:
388 bf = tmp_path / "b.muse"
389 bf.write_bytes(_make_bundle())
390 r = _vp(tmp_path, ["--file", str(bf), "--no-local"])
391 assert r.exit_code == 0
392 assert "all_ok=True" in r.output
393
394 def test_text_format_failure_shows_fail(self, tmp_path: pathlib.Path) -> None:
395 bf = tmp_path / "b.muse"
396 bf.write_bytes(_make_bundle([_bad_hash_obj()]))
397 r = _vp(tmp_path, ["--file", str(bf), "--no-local"])
398 assert r.exit_code != 0
399 assert "FAIL" in r.output
400
401 def test_text_format_counts(self, tmp_path: pathlib.Path) -> None:
402 objs = [_good_obj(f"x{i}".encode()) for i in range(5)]
403 bf = tmp_path / "b.muse"
404 bf.write_bytes(_make_bundle(objs))
405 r = _vp(tmp_path, ["--file", str(bf), "--no-local"])
406 assert "objects=5" in r.output
407
408
409 # ---------------------------------------------------------------------------
410 # Integration: --stat fast-path
411 # ---------------------------------------------------------------------------
412
413 class TestStatMode:
414 def test_stat_json(self, tmp_path: pathlib.Path) -> None:
415 objs = [_good_obj(f"s{i}".encode()) for i in range(7)]
416 bf = tmp_path / "b.muse"
417 bf.write_bytes(_make_bundle(objs))
418 r = _vp(tmp_path, ["--file", str(bf), "--stat", "--json"])
419 assert r.exit_code == 0
420 d = json.loads(r.output)
421 assert d["objects"] == 7
422 assert d["snapshots"] == 0
423 assert d["commits"] == 0
424
425 def test_stat_text(self, tmp_path: pathlib.Path) -> None:
426 bf = tmp_path / "b.muse"
427 bf.write_bytes(_make_bundle())
428 r = _vp(tmp_path, ["--file", str(bf), "--stat"])
429 assert r.exit_code == 0
430 assert "objects=0" in r.output
431
432 def test_stat_does_not_verify_hashes(self, tmp_path: pathlib.Path) -> None:
433 """--stat exits 0 even with a corrupted bundle hash."""
434 bf = tmp_path / "b.muse"
435 bf.write_bytes(_make_bundle([_bad_hash_obj()]))
436 r = _vp(tmp_path, ["--file", str(bf), "--stat", "--json"])
437 assert r.exit_code == 0 # no hashing — passes
438 d = json.loads(r.output)
439 assert d["objects"] == 1
440
441 def test_stat_counts_all_sections(self, tmp_path: pathlib.Path) -> None:
442 snap_id = _sha(b"s")
443 snap = {"snapshot_id": snap_id, "manifest": {}}
444 commit = {"commit_id": _sha(b"c"), "snapshot_id": snap_id}
445 objs = [_good_obj(b"obj")]
446 bf = tmp_path / "b.muse"
447 bf.write_bytes(_make_bundle(objs, [snap], [commit]))
448 r = _vp(tmp_path, ["--file", str(bf), "--stat", "--json"])
449 d = json.loads(r.output)
450 assert d["objects"] == 1
451 assert d["snapshots"] == 1
452 assert d["commits"] == 1
453
454
455 # ---------------------------------------------------------------------------
456 # Integration: --quiet
457 # ---------------------------------------------------------------------------
458
459 class TestQuietMode:
460 def test_quiet_clean_exits_zero_no_output(self, tmp_path: pathlib.Path) -> None:
461 bf = tmp_path / "b.muse"
462 bf.write_bytes(_make_bundle())
463 r = _vp(tmp_path, ["--file", str(bf), "--quiet", "--no-local"])
464 assert r.exit_code == 0
465 assert r.output.strip() == ""
466
467 def test_quiet_failure_exits_nonzero_no_output(self, tmp_path: pathlib.Path) -> None:
468 bf = tmp_path / "b.muse"
469 bf.write_bytes(_make_bundle([_bad_hash_obj()]))
470 r = _vp(tmp_path, ["--file", str(bf), "-q", "--no-local"])
471 assert r.exit_code != 0
472 assert r.output.strip() == ""
473
474
475 # ---------------------------------------------------------------------------
476 # Integration: malformed input
477 # ---------------------------------------------------------------------------
478
479 class TestMalformedInput:
480 def test_malformed_msgpack(self, tmp_path: pathlib.Path) -> None:
481 bf = tmp_path / "b.muse"
482 bf.write_bytes(b"\xff\xff NOT VALID MSGPACK")
483 r = _vp(tmp_path, ["--file", str(bf)])
484 assert r.exit_code != 0
485
486 def test_msgpack_scalar(self, tmp_path: pathlib.Path) -> None:
487 """msgpack-encoded scalar (not a map) must error cleanly."""
488 bf = tmp_path / "b.muse"
489 bf.write_bytes(msgpack.packb(42))
490 r = _vp(tmp_path, ["--file", str(bf)])
491 assert r.exit_code != 0
492 assert "error" in r.stderr.lower() or r.exit_code != 0
493
494 def test_missing_file(self, tmp_path: pathlib.Path) -> None:
495 r = _vp(tmp_path, ["--file", str(tmp_path / "nonexistent.muse")])
496 assert r.exit_code != 0
497
498 def test_objects_not_a_list(self, tmp_path: pathlib.Path) -> None:
499 bundle = {"meta": _FULL_META, "objects": "bad", "snapshots": [], "commits": []}
500 bf = tmp_path / "b.muse"
501 bf.write_bytes(msgpack.packb(bundle, use_bin_type=True))
502 r = _vp(tmp_path, ["--file", str(bf), "--no-local"])
503 assert r.exit_code != 0
504 # Error goes to stderr
505 assert "objects" in r.stderr.lower()
506
507 def test_snapshots_not_a_list(self, tmp_path: pathlib.Path) -> None:
508 bundle = {"meta": _FULL_META, "objects": [], "snapshots": 99, "commits": []}
509 bf = tmp_path / "b.muse"
510 bf.write_bytes(msgpack.packb(bundle, use_bin_type=True))
511 r = _vp(tmp_path, ["--file", str(bf), "--no-local"])
512 assert r.exit_code != 0
513 assert "snapshots" in r.stderr.lower()
514
515 def test_commits_not_a_list(self, tmp_path: pathlib.Path) -> None:
516 bundle = {"meta": _FULL_META, "objects": [], "snapshots": [], "commits": True}
517 bf = tmp_path / "b.muse"
518 bf.write_bytes(msgpack.packb(bundle, use_bin_type=True))
519 r = _vp(tmp_path, ["--file", str(bf), "--no-local"])
520 assert r.exit_code != 0
521 assert "commits" in r.stderr.lower()
522
523
524 # ---------------------------------------------------------------------------
525 # Security
526 # ---------------------------------------------------------------------------
527
528 class TestSecurity:
529 def test_unrecognized_flag_to_stderr(self, tmp_path: pathlib.Path) -> None:
530 bf = tmp_path / "b.muse"
531 bf.write_bytes(_make_bundle())
532 r = _vp(tmp_path, ["--file", str(bf), "--unknown-flag"])
533 assert r.exit_code != 0
534 assert r.stdout_bytes == b""
535 assert "error" in r.stderr.lower()
536
537 def test_ansi_in_object_id_sanitized_in_text(self, tmp_path: pathlib.Path) -> None:
538 """ANSI in a bundle object_id must not leak to text output."""
539 ansi_oid = "\x1b[31m" + "a" * 58 + "\x1b[0m"
540 bad: _BadObjectEntry = {"object_id": ansi_oid, "content": b"data"}
541 bf = tmp_path / "b.muse"
542 bf.write_bytes(_make_bundle([bad]))
543 r = _vp(tmp_path, ["--file", str(bf), "--no-local"])
544 # ANSI escape sequences must not appear in text output
545 assert "\x1b" not in r.output
546
547 def test_no_traceback_on_unrecognized_flag(self, tmp_path: pathlib.Path) -> None:
548 bf = tmp_path / "b.muse"
549 bf.write_bytes(_make_bundle())
550 r = _vp(tmp_path, ["--file", str(bf), "--not-a-real-flag"])
551 assert "Traceback" not in r.output
552 assert "Traceback" not in r.stderr
553
554 def test_no_traceback_on_corrupt_bundle(self, tmp_path: pathlib.Path) -> None:
555 bf = tmp_path / "b.muse"
556 bf.write_bytes(b"\x00\x01\x02garbage")
557 r = _vp(tmp_path, ["--file", str(bf)])
558 assert "Traceback" not in r.output
559 assert "Traceback" not in r.stderr
560
561 def test_json_output_encodes_ansi_safely(self, tmp_path: pathlib.Path) -> None:
562 """JSON output must encode ANSI characters, never emit raw escape sequences."""
563 ansi_oid = "\x1b[31m" + "a" * 58 + "\x1b[0m"
564 bad: _BadObjectEntry = {"object_id": ansi_oid, "content": b"data"}
565 bf = tmp_path / "b.muse"
566 bf.write_bytes(_make_bundle([bad]))
567 r = _vp(tmp_path, ["--file", str(bf), "--no-local", "--json"])
568 # JSON output must not contain raw ANSI sequences
569 assert "\x1b" not in r.output
570 # But should still be parseable JSON
571 d = json.loads(r.output)
572 assert d["all_ok"] is False
573
574 def test_path_traversal_in_bundle_file(self, tmp_path: pathlib.Path) -> None:
575 """Referencing a path-traversal bundle file must fail cleanly."""
576 r = _vp(tmp_path, ["--file", "/etc/shadow"])
577 assert r.exit_code != 0
578 assert "Traceback" not in r.output
579
580 def test_deeply_nested_msgpack(self, tmp_path: pathlib.Path) -> None:
581 """Deeply nested msgpack should not crash (msgpack raises StackError)."""
582 # Build raw msgpack bytes: 2000 × fixmap(1){"x": …} + nil
583 # Avoids Python-level dict recursion; msgpack may raise StackError on unpack.
584 packed = b"\x81\xa1x" * 2000 + b"\xc0"
585 bf = tmp_path / "b.muse"
586 bf.write_bytes(packed)
587 r = _vp(tmp_path, ["--file", str(bf)])
588 # Either parses or errors — must never traceback
589 assert "Traceback" not in r.output
590 assert "Traceback" not in r.stderr
591
592
593 # ---------------------------------------------------------------------------
594 # Stress
595 # ---------------------------------------------------------------------------
596
597 class TestStress:
598 def test_500_object_bundle(self, tmp_path: pathlib.Path) -> None:
599 objs = [_good_obj(f"stress-object-{i:05d}".encode()) for i in range(500)]
600 bf = tmp_path / "b.muse"
601 bf.write_bytes(_make_bundle(objs))
602 r = _vp(tmp_path, ["--file", str(bf), "--no-local", "--json"])
603 assert r.exit_code == 0
604 d = json.loads(r.output)
605 assert d["objects_checked"] == 500
606 assert d["all_ok"] is True
607
608 def test_500_object_bundle_one_corrupt(self, tmp_path: pathlib.Path) -> None:
609 objs = [_good_obj(f"stress-{i}".encode()) for i in range(499)]
610 objs.append(_bad_hash_obj(b"corrupt"))
611 bf = tmp_path / "b.muse"
612 bf.write_bytes(_make_bundle(objs))
613 r = _vp(tmp_path, ["--file", str(bf), "--no-local", "--json"])
614 assert r.exit_code != 0
615 d = json.loads(r.output)
616 assert d["objects_checked"] == 500
617 assert d["all_ok"] is False
618
619 def test_200_sequential_verifications(self, tmp_path: pathlib.Path) -> None:
620 bf = tmp_path / "b.muse"
621 bf.write_bytes(_make_bundle([_good_obj(b"seq")]))
622 for _ in range(200):
623 r = _vp(tmp_path, ["--file", str(bf), "--no-local"])
624 assert r.exit_code == 0
625
626 def test_large_object_hashing(self, tmp_path: pathlib.Path) -> None:
627 """1 MiB object should hash correctly without memory issues."""
628 large_data = b"X" * (1024 * 1024)
629 obj = _good_obj(large_data)
630 bf = tmp_path / "b.muse"
631 bf.write_bytes(_make_bundle([obj]))
632 r = _vp(tmp_path, ["--file", str(bf), "--no-local", "--json"])
633 assert r.exit_code == 0
634 d = json.loads(r.output)
635 assert d["all_ok"] is True
636
637 def test_stat_on_large_bundle(self, tmp_path: pathlib.Path) -> None:
638 """--stat on a 500-object bundle must complete quickly."""
639 objs = [_good_obj(f"big-{i}".encode()) for i in range(500)]
640 bf = tmp_path / "b.muse"
641 bf.write_bytes(_make_bundle(objs))
642 r = _vp(tmp_path, ["--file", str(bf), "--stat", "--json"])
643 assert r.exit_code == 0
644 d = json.loads(r.output)
645 assert d["objects"] == 500
File History 2 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