"""Comprehensive tests for muse verify-pack. Coverage: - Unit: TypedDict schemas, _Failure, _VerifyPackResult, _StatResult - Integration: JSON/text formats, --stat, --quiet, --no-local, --file, --json shorthand - Verification: object integrity, snapshot consistency, commit consistency - Security: ANSI sanitization, format error → stderr, no tracebacks, invalid object IDs - Stress: 500-object mpack, 200 sequential verifications, large object hashing """ from __future__ import annotations from collections.abc import Mapping import datetime import io import json import pathlib import msgpack import pytest from tests.cli_test_helper import CliRunner, InvokeResult from muse.cli.commands.verify_pack import ( _Failure, _StatResultJson as _StatResult, _VerifyPackJson as _VerifyPackResult, ) from muse.core.commits import ( CommitRecord, write_commit, ) from muse.core.snapshots import ( SnapshotRecord, write_snapshot, ) from muse.core.types import Manifest, blob_id, long_id, fake_id from muse.core.paths import muse_dir from typing import TypedDict runner = CliRunner() # --------------------------------------------------------------------------- # MPack TypedDicts (mirror the output contract shape) # --------------------------------------------------------------------------- class _ObjectEntry(TypedDict): object_id: str content: bytes class _SnapshotEntry(TypedDict, total=False): snapshot_id: str manifest: Manifest class _CommitEntry(TypedDict): commit_id: str snapshot_id: str type _EnvMap = dict[str, str] type _CommitEntryDict = dict[str, str] type _BadObjectEntry = dict[str, str | bytes] type _BundleDict = dict[str, list[_ObjectEntry] | list[_SnapshotEntry] | list[_CommitEntry]] # --------------------------------------------------------------------------- # Helpers # --------------------------------------------------------------------------- def _init_repo(path: pathlib.Path) -> pathlib.Path: dot_muse = muse_dir(path) (dot_muse / "commits").mkdir(parents=True, exist_ok=True) (dot_muse / "snapshots").mkdir(parents=True, exist_ok=True) (dot_muse / "objects" / "ab").mkdir(parents=True, exist_ok=True) (dot_muse / "refs" / "heads").mkdir(parents=True, exist_ok=True) (dot_muse / "HEAD").write_text("ref: refs/heads/main", encoding="utf-8") (dot_muse / "repo.json").write_text( json.dumps({"repo_id": "test-repo", "domain": "generic"}), encoding="utf-8" ) return path def _env(repo: pathlib.Path) -> _EnvMap: return {"MUSE_REPO_ROOT": str(repo)} def _good_obj(data: bytes = b"hello world") -> _ObjectEntry: return _ObjectEntry(object_id=blob_id(data), content=data) def _bad_hash_obj(data: bytes = b"hello world") -> _ObjectEntry: return _ObjectEntry(object_id=fake_id("bad-hash"), content=data) _FULL_META = { "mode": "full", "base_commits": [], "created_at": "2025-01-01T00:00:00Z", } def _make_bundle( objects: list[_ObjectEntry] | None = None, snapshots: list[_SnapshotEntry] | None = None, commits: list[_CommitEntry] | None = None, meta: Mapping[str, object] | None = None, ) -> bytes: mpack: _BundleDict = { "meta": meta if meta is not None else _FULL_META, "objects": objects or [], "snapshots": snapshots or [], "commits": commits or [], } return msgpack.packb(mpack, use_bin_type=True) def _vp( tmp_path: pathlib.Path, args: list[str], stdin: bytes | None = None, ) -> InvokeResult: """Invoke verify-pack against a freshly initialised repo in tmp_path.""" from muse.cli.app import main as cli _init_repo(tmp_path) return runner.invoke( cli, ["verify-pack"] + args, env=_env(tmp_path), input=stdin, ) # --------------------------------------------------------------------------- # Unit: schemas # --------------------------------------------------------------------------- class TestSchemas: def test_failure_fields(self) -> None: f: _Failure = {"kind": "object", "id": "abc", "error": "hash mismatch"} assert f["kind"] == "object" assert f["id"] == "abc" assert f["error"] == "hash mismatch" def test_verify_pack_result_fields(self) -> None: r: _VerifyPackResult = { "objects_checked": 3, "snapshots_checked": 2, "commits_checked": 1, "all_ok": True, "failures": [], } assert r["all_ok"] is True assert isinstance(r["failures"], list) def test_stat_result_fields(self) -> None: s: _StatResult = {"objects": 10, "snapshots": 5, "commits": 3} assert s["objects"] == 10 # --------------------------------------------------------------------------- # Integration: JSON output — clean bundles # --------------------------------------------------------------------------- class TestJsonOutputClean: def test_empty_bundle(self, tmp_path: pathlib.Path) -> None: bf = tmp_path / "b.muse" bf.write_bytes(_make_bundle()) r = _vp(tmp_path, ["--file", str(bf), "--no-local", "--json"]) assert r.exit_code == 0 d = json.loads(r.output) assert d["all_ok"] is True assert d["failures"] == [] assert d["objects_checked"] == 0 assert d["snapshots_checked"] == 0 assert d["commits_checked"] == 0 def test_single_good_object(self, tmp_path: pathlib.Path) -> None: bf = tmp_path / "b.muse" bf.write_bytes(_make_bundle([_good_obj()])) r = _vp(tmp_path, ["--file", str(bf), "--no-local", "--json"]) assert r.exit_code == 0 d = json.loads(r.output) assert d["all_ok"] is True assert d["objects_checked"] == 1 def test_json_shorthand(self, tmp_path: pathlib.Path) -> None: bf = tmp_path / "b.muse" bf.write_bytes(_make_bundle()) r = _vp(tmp_path, ["--file", str(bf), "--json", "--no-local"]) assert r.exit_code == 0 json.loads(r.output) # must be valid JSON def test_multiple_good_objects(self, tmp_path: pathlib.Path) -> None: objs = [_good_obj(f"content-{i}".encode()) for i in range(10)] bf = tmp_path / "b.muse" bf.write_bytes(_make_bundle(objs)) r = _vp(tmp_path, ["--file", str(bf), "--no-local", "--json"]) assert r.exit_code == 0 d = json.loads(r.output) assert d["objects_checked"] == 10 assert d["all_ok"] is True # --------------------------------------------------------------------------- # Integration: JSON output — hash integrity failures # --------------------------------------------------------------------------- class TestObjectIntegrity: def test_bad_hash_detected(self, tmp_path: pathlib.Path) -> None: bf = tmp_path / "b.muse" bf.write_bytes(_make_bundle([_bad_hash_obj()])) r = _vp(tmp_path, ["--file", str(bf), "--no-local", "--json"]) assert r.exit_code != 0 d = json.loads(r.output) assert d["all_ok"] is False assert d["failures"][0]["kind"] == "object" assert "hash mismatch" in d["failures"][0]["error"] def test_mix_good_and_bad(self, tmp_path: pathlib.Path) -> None: objs = [_good_obj(b"good"), _bad_hash_obj(b"bad")] bf = tmp_path / "b.muse" bf.write_bytes(_make_bundle(objs)) r = _vp(tmp_path, ["--file", str(bf), "--no-local", "--json"]) assert r.exit_code != 0 d = json.loads(r.output) assert d["objects_checked"] == 2 assert len(d["failures"]) == 1 def test_invalid_object_id_format(self, tmp_path: pathlib.Path) -> None: """MPack with non-hex object ID should report a specific format error.""" bad: _BadObjectEntry = { "object_id": f"\x1b[31mmalicious\x1b[0m{'a' * 55}", "content": b"data", } bf = tmp_path / "b.muse" bf.write_bytes(_make_bundle([bad])) r = _vp(tmp_path, ["--file", str(bf), "--no-local", "--json"]) assert r.exit_code != 0 d = json.loads(r.output) assert d["all_ok"] is False assert "not a valid" in d["failures"][0]["error"].lower() or "sha-256" in d["failures"][0]["error"].lower() def test_entry_not_dict(self, tmp_path: pathlib.Path) -> None: mpack = { "meta": _FULL_META, "objects": ["not-a-dict"], "snapshots": [], "commits": [], } bf = tmp_path / "b.muse" bf.write_bytes(msgpack.packb(mpack, use_bin_type=True)) r = _vp(tmp_path, ["--file", str(bf), "--no-local", "--json"]) d = json.loads(r.output) assert d["all_ok"] is False assert "not a dict" in d["failures"][0]["error"] def test_missing_content_field(self, tmp_path: pathlib.Path) -> None: entry: _CommitEntryDict = {"object_id": "a" * 64} # no content bf = tmp_path / "b.muse" bf.write_bytes(_make_bundle([entry])) r = _vp(tmp_path, ["--file", str(bf), "--no-local", "--json"]) d = json.loads(r.output) assert d["all_ok"] is False def test_empty_object_passes(self, tmp_path: pathlib.Path) -> None: """An empty bytes object is valid — its SHA-256 is known.""" obj = _good_obj(b"") bf = tmp_path / "b.muse" bf.write_bytes(_make_bundle([obj])) r = _vp(tmp_path, ["--file", str(bf), "--no-local", "--json"]) d = json.loads(r.output) assert d["all_ok"] is True def test_binary_object_passes(self, tmp_path: pathlib.Path) -> None: obj = _good_obj(bytes(range(256))) bf = tmp_path / "b.muse" bf.write_bytes(_make_bundle([obj])) r = _vp(tmp_path, ["--file", str(bf), "--no-local", "--json"]) d = json.loads(r.output) assert d["all_ok"] is True # --------------------------------------------------------------------------- # Integration: snapshot consistency # --------------------------------------------------------------------------- class TestSnapshotConsistency: def _snap_entry(self, snap_id: str, manifest: Manifest) -> _SnapshotEntry: return _SnapshotEntry(snapshot_id=snap_id, manifest=manifest) def test_snapshot_with_all_objects_present(self, tmp_path: pathlib.Path) -> None: obj = _good_obj(b"snap-obj") snap = self._snap_entry(blob_id(b"snap"), {"file.txt": obj["object_id"]}) bf = tmp_path / "b.muse" bf.write_bytes(_make_bundle(objects=[obj], snapshots=[snap])) r = _vp(tmp_path, ["--file", str(bf), "--no-local", "--json"]) d = json.loads(r.output) assert d["all_ok"] is True assert d["snapshots_checked"] == 1 def test_snapshot_missing_object_fails(self, tmp_path: pathlib.Path) -> None: missing_oid = "b" * 64 snap = self._snap_entry(blob_id(b"snap"), {"file.txt": missing_oid}) bf = tmp_path / "b.muse" bf.write_bytes(_make_bundle(snapshots=[snap])) r = _vp(tmp_path, ["--file", str(bf), "--no-local", "--json"]) d = json.loads(r.output) assert d["all_ok"] is False assert d["failures"][0]["kind"] == "snapshot" assert "missing object" in d["failures"][0]["error"] def test_snapshot_entry_not_dict(self, tmp_path: pathlib.Path) -> None: mpack = { "meta": _FULL_META, "objects": [], "snapshots": ["bad"], "commits": [], } bf = tmp_path / "b.muse" bf.write_bytes(msgpack.packb(mpack, use_bin_type=True)) r = _vp(tmp_path, ["--file", str(bf), "--no-local", "--json"]) d = json.loads(r.output) assert d["all_ok"] is False def test_skip_local_check_allows_missing(self, tmp_path: pathlib.Path) -> None: """--no-local should NOT check the local store; missing objects pass.""" # With --no-local, snapshot references a missing object but no local check. missing_oid = "c" * 64 snap = self._snap_entry(blob_id(b"snap"), {"f.txt": missing_oid}) bf = tmp_path / "b.muse" bf.write_bytes(_make_bundle(snapshots=[snap])) # Without --no-local, this fails (missing locally). r_fail = _vp(tmp_path, ["--file", str(bf)]) assert r_fail.exit_code != 0 # With --no-local, this fails too (not in mpack either). r_nol = _vp(tmp_path, ["--file", str(bf), "--no-local"]) assert r_nol.exit_code != 0 # --------------------------------------------------------------------------- # Integration: commit consistency # --------------------------------------------------------------------------- class TestCommitConsistency: def _commit_entry(self, commit_id: str, snapshot_id: str) -> _CommitEntryDict: return {"commit_id": commit_id, "snapshot_id": snapshot_id} def test_commit_with_bundled_snapshot(self, tmp_path: pathlib.Path) -> None: snap_id = blob_id(b"snap-data") snap = {"snapshot_id": snap_id, "manifest": {}} commit = self._commit_entry(blob_id(b"c1"), snap_id) bf = tmp_path / "b.muse" bf.write_bytes(_make_bundle(snapshots=[snap], commits=[commit])) r = _vp(tmp_path, ["--file", str(bf), "--no-local", "--json"]) d = json.loads(r.output) assert d["all_ok"] is True assert d["commits_checked"] == 1 def test_commit_missing_snapshot_fails(self, tmp_path: pathlib.Path) -> None: # Default (local store enabled): snapshot not in mpack → failure commit = self._commit_entry(blob_id(b"c1"), fake_id("missing-snapshot")) bf = tmp_path / "b.muse" bf.write_bytes(_make_bundle(commits=[commit])) r = _vp(tmp_path, ["--file", str(bf), "--json"]) # local check on by default d = json.loads(r.output) assert d["all_ok"] is False assert d["failures"][0]["kind"] == "commit" def test_commit_entry_not_dict(self, tmp_path: pathlib.Path) -> None: mpack = { "meta": _FULL_META, "objects": [], "snapshots": [], "commits": [42], } bf = tmp_path / "b.muse" bf.write_bytes(msgpack.packb(mpack, use_bin_type=True)) r = _vp(tmp_path, ["--file", str(bf), "--no-local", "--json"]) d = json.loads(r.output) assert d["all_ok"] is False # --------------------------------------------------------------------------- # Integration: text format # --------------------------------------------------------------------------- class TestTextFormat: def test_text_format_clean(self, tmp_path: pathlib.Path) -> None: bf = tmp_path / "b.muse" bf.write_bytes(_make_bundle()) r = _vp(tmp_path, ["--file", str(bf), "--no-local"]) assert r.exit_code == 0 assert "all_ok=True" in r.output def test_text_format_failure_shows_fail(self, tmp_path: pathlib.Path) -> None: bf = tmp_path / "b.muse" bf.write_bytes(_make_bundle([_bad_hash_obj()])) r = _vp(tmp_path, ["--file", str(bf), "--no-local"]) assert r.exit_code != 0 assert "FAIL" in r.output def test_text_format_counts(self, tmp_path: pathlib.Path) -> None: objs = [_good_obj(f"x{i}".encode()) for i in range(5)] bf = tmp_path / "b.muse" bf.write_bytes(_make_bundle(objs)) r = _vp(tmp_path, ["--file", str(bf), "--no-local"]) assert "objects=5" in r.output # --------------------------------------------------------------------------- # Integration: --stat fast-path # --------------------------------------------------------------------------- class TestStatMode: def test_stat_json(self, tmp_path: pathlib.Path) -> None: objs = [_good_obj(f"s{i}".encode()) for i in range(7)] bf = tmp_path / "b.muse" bf.write_bytes(_make_bundle(objs)) r = _vp(tmp_path, ["--file", str(bf), "--stat", "--json"]) assert r.exit_code == 0 d = json.loads(r.output) assert d["objects"] == 7 assert d["snapshots"] == 0 assert d["commits"] == 0 def test_stat_text(self, tmp_path: pathlib.Path) -> None: bf = tmp_path / "b.muse" bf.write_bytes(_make_bundle()) r = _vp(tmp_path, ["--file", str(bf), "--stat"]) assert r.exit_code == 0 assert "objects=0" in r.output def test_stat_does_not_verify_hashes(self, tmp_path: pathlib.Path) -> None: """--stat exits 0 even with a corrupted mpack hash.""" bf = tmp_path / "b.muse" bf.write_bytes(_make_bundle([_bad_hash_obj()])) r = _vp(tmp_path, ["--file", str(bf), "--stat", "--json"]) assert r.exit_code == 0 # no hashing — passes d = json.loads(r.output) assert d["objects"] == 1 def test_stat_counts_all_sections(self, tmp_path: pathlib.Path) -> None: snap_id = blob_id(b"s") snap = {"snapshot_id": snap_id, "manifest": {}} commit = {"commit_id": blob_id(b"c"), "snapshot_id": snap_id} objs = [_good_obj(b"obj")] bf = tmp_path / "b.muse" bf.write_bytes(_make_bundle(objs, [snap], [commit])) r = _vp(tmp_path, ["--file", str(bf), "--stat", "--json"]) d = json.loads(r.output) assert d["objects"] == 1 assert d["snapshots"] == 1 assert d["commits"] == 1 # --------------------------------------------------------------------------- # Integration: --quiet # --------------------------------------------------------------------------- class TestQuietMode: def test_quiet_clean_exits_zero_no_output(self, tmp_path: pathlib.Path) -> None: bf = tmp_path / "b.muse" bf.write_bytes(_make_bundle()) r = _vp(tmp_path, ["--file", str(bf), "--quiet", "--no-local"]) assert r.exit_code == 0 assert r.output.strip() == "" def test_quiet_failure_exits_nonzero_no_output(self, tmp_path: pathlib.Path) -> None: bf = tmp_path / "b.muse" bf.write_bytes(_make_bundle([_bad_hash_obj()])) r = _vp(tmp_path, ["--file", str(bf), "-q", "--no-local"]) assert r.exit_code != 0 assert r.output.strip() == "" # --------------------------------------------------------------------------- # Integration: malformed input # --------------------------------------------------------------------------- class TestMalformedInput: def test_malformed_msgpack(self, tmp_path: pathlib.Path) -> None: bf = tmp_path / "b.muse" bf.write_bytes(b"\xff\xff NOT VALID MSGPACK") r = _vp(tmp_path, ["--file", str(bf)]) assert r.exit_code != 0 def test_msgpack_scalar(self, tmp_path: pathlib.Path) -> None: """msgpack-encoded scalar (not a map) must error cleanly.""" bf = tmp_path / "b.muse" bf.write_bytes(msgpack.packb(42)) r = _vp(tmp_path, ["--file", str(bf)]) assert r.exit_code != 0 assert "error" in r.stderr.lower() or r.exit_code != 0 def test_missing_file(self, tmp_path: pathlib.Path) -> None: r = _vp(tmp_path, ["--file", str(tmp_path / "nonexistent.muse")]) assert r.exit_code != 0 def test_objects_not_a_list(self, tmp_path: pathlib.Path) -> None: mpack = {"meta": _FULL_META, "objects": "bad", "snapshots": [], "commits": []} bf = tmp_path / "b.muse" bf.write_bytes(msgpack.packb(mpack, use_bin_type=True)) r = _vp(tmp_path, ["--file", str(bf), "--no-local"]) assert r.exit_code != 0 # Error goes to stderr assert "objects" in r.stderr.lower() def test_snapshots_not_a_list(self, tmp_path: pathlib.Path) -> None: mpack = {"meta": _FULL_META, "objects": [], "snapshots": 99, "commits": []} bf = tmp_path / "b.muse" bf.write_bytes(msgpack.packb(mpack, use_bin_type=True)) r = _vp(tmp_path, ["--file", str(bf), "--no-local"]) assert r.exit_code != 0 assert "snapshots" in r.stderr.lower() def test_commits_not_a_list(self, tmp_path: pathlib.Path) -> None: mpack = {"meta": _FULL_META, "objects": [], "snapshots": [], "commits": True} bf = tmp_path / "b.muse" bf.write_bytes(msgpack.packb(mpack, use_bin_type=True)) r = _vp(tmp_path, ["--file", str(bf), "--no-local"]) assert r.exit_code != 0 assert "commits" in r.stderr.lower() # --------------------------------------------------------------------------- # Security # --------------------------------------------------------------------------- class TestSecurity: def test_unrecognized_flag_to_stderr(self, tmp_path: pathlib.Path) -> None: bf = tmp_path / "b.muse" bf.write_bytes(_make_bundle()) r = _vp(tmp_path, ["--file", str(bf), "--unknown-flag"]) assert r.exit_code != 0 assert r.stdout_bytes == b"" assert "error" in r.stderr.lower() def test_ansi_in_object_id_sanitized_in_text(self, tmp_path: pathlib.Path) -> None: """ANSI in a mpack object_id must not leak to text output.""" ansi_oid = f"\x1b[31m{'a' * 58}\x1b[0m" bad: _BadObjectEntry = {"object_id": ansi_oid, "content": b"data"} bf = tmp_path / "b.muse" bf.write_bytes(_make_bundle([bad])) r = _vp(tmp_path, ["--file", str(bf), "--no-local"]) # ANSI escape sequences must not appear in text output assert "\x1b" not in r.output def test_no_traceback_on_unrecognized_flag(self, tmp_path: pathlib.Path) -> None: bf = tmp_path / "b.muse" bf.write_bytes(_make_bundle()) r = _vp(tmp_path, ["--file", str(bf), "--not-a-real-flag"]) assert "Traceback" not in r.output assert "Traceback" not in r.stderr def test_no_traceback_on_corrupt_bundle(self, tmp_path: pathlib.Path) -> None: bf = tmp_path / "b.muse" bf.write_bytes(b"\x00\x01\x02garbage") r = _vp(tmp_path, ["--file", str(bf)]) assert "Traceback" not in r.output assert "Traceback" not in r.stderr def test_json_output_encodes_ansi_safely(self, tmp_path: pathlib.Path) -> None: """JSON output must encode ANSI characters, never emit raw escape sequences.""" ansi_oid = f"\x1b[31m{'a' * 58}\x1b[0m" bad: _BadObjectEntry = {"object_id": ansi_oid, "content": b"data"} bf = tmp_path / "b.muse" bf.write_bytes(_make_bundle([bad])) r = _vp(tmp_path, ["--file", str(bf), "--no-local", "--json"]) # JSON output must not contain raw ANSI sequences assert "\x1b" not in r.output # But should still be parseable JSON d = json.loads(r.output) assert d["all_ok"] is False def test_path_traversal_in_bundle_file(self, tmp_path: pathlib.Path) -> None: """Referencing a path-traversal mpack file must fail cleanly.""" r = _vp(tmp_path, ["--file", "/etc/shadow"]) assert r.exit_code != 0 assert "Traceback" not in r.output def test_deeply_nested_msgpack(self, tmp_path: pathlib.Path) -> None: """Deeply nested msgpack should not crash (msgpack raises StackError).""" # Build raw msgpack bytes: 2000 × fixmap(1){"x": …} + nil # Avoids Python-level dict recursion; msgpack may raise StackError on unpack. packed = b"\x81\xa1x" * 2000 + b"\xc0" bf = tmp_path / "b.muse" bf.write_bytes(packed) r = _vp(tmp_path, ["--file", str(bf)]) # Either parses or errors — must never traceback assert "Traceback" not in r.output assert "Traceback" not in r.stderr # --------------------------------------------------------------------------- # Stress # --------------------------------------------------------------------------- class TestStress: def test_500_object_bundle(self, tmp_path: pathlib.Path) -> None: objs = [_good_obj(f"stress-object-{i:05d}".encode()) for i in range(500)] bf = tmp_path / "b.muse" bf.write_bytes(_make_bundle(objs)) r = _vp(tmp_path, ["--file", str(bf), "--no-local", "--json"]) assert r.exit_code == 0 d = json.loads(r.output) assert d["objects_checked"] == 500 assert d["all_ok"] is True def test_500_object_bundle_one_corrupt(self, tmp_path: pathlib.Path) -> None: objs = [_good_obj(f"stress-{i}".encode()) for i in range(499)] objs.append(_bad_hash_obj(b"corrupt")) bf = tmp_path / "b.muse" bf.write_bytes(_make_bundle(objs)) r = _vp(tmp_path, ["--file", str(bf), "--no-local", "--json"]) assert r.exit_code != 0 d = json.loads(r.output) assert d["objects_checked"] == 500 assert d["all_ok"] is False def test_200_sequential_verifications(self, tmp_path: pathlib.Path) -> None: bf = tmp_path / "b.muse" bf.write_bytes(_make_bundle([_good_obj(b"seq")])) for _ in range(200): r = _vp(tmp_path, ["--file", str(bf), "--no-local"]) assert r.exit_code == 0 def test_large_object_hashing(self, tmp_path: pathlib.Path) -> None: """1 MiB object should hash correctly without memory issues.""" large_data = b"X" * (1024 * 1024) obj = _good_obj(large_data) bf = tmp_path / "b.muse" bf.write_bytes(_make_bundle([obj])) r = _vp(tmp_path, ["--file", str(bf), "--no-local", "--json"]) assert r.exit_code == 0 d = json.loads(r.output) assert d["all_ok"] is True def test_stat_on_large_bundle(self, tmp_path: pathlib.Path) -> None: """--stat on a 500-object mpack must complete quickly.""" objs = [_good_obj(f"big-{i}".encode()) for i in range(500)] bf = tmp_path / "b.muse" bf.write_bytes(_make_bundle(objs)) r = _vp(tmp_path, ["--file", str(bf), "--stat", "--json"]) assert r.exit_code == 0 d = json.loads(r.output) assert d["objects"] == 500