"""Regression tests for algo-prefixed filesystem glob patterns. After the algo-prefix sprint every content-addressed store path gained an algorithm directory segment and moved to the unified object store: objects/sha256// (was: commits/.msgpack, snapshots/.msgpack) Any glob that scans only the top level of the commits/ or snapshots/ dir silently returns an empty list. These tests catch that class of bug by writing real records through the store, then asserting that every listing and prefix-resolution function returns them. Covered functions ----------------- muse.core.store get_all_commits _find_commit_by_prefix find_commits_by_prefix muse.cli.commands.snapshot_cmd _list_all_snapshots (internal listing helper) _resolve_snapshot (full-id + prefix-scan paths) muse.cli.commands.snapshot_diff _resolve_snapshot_prefix (short sha256: prefix resolution) _resolve_to_snapshot_id (end-to-end resolver) """ from __future__ import annotations import datetime import json import pathlib import pytest from muse.core.types import NULL_COMMIT_ID, fake_id, long_id, short_id from muse.core.ids import hash_commit, hash_snapshot from muse.core.paths import muse_dir from muse.core.commits import ( CommitRecord, find_commits_by_prefix, get_all_commits, write_commit, ) from muse.core.snapshots import ( SnapshotRecord, write_snapshot, ) from muse.core.commits import _find_commit_by_prefix # --------------------------------------------------------------------------- # Helpers # --------------------------------------------------------------------------- _REPO_ID = fake_id("repo") _NOW = datetime.datetime.now(datetime.timezone.utc) def _init_repo(path: pathlib.Path) -> pathlib.Path: dot_muse = muse_dir(path) (dot_muse / "refs" / "heads").mkdir(parents=True) (dot_muse / "HEAD").write_text("ref: refs/heads/main", encoding="utf-8") (dot_muse / "repo.json").write_text( json.dumps({"repo_id": _REPO_ID, "domain": "code"}), encoding="utf-8" ) return path def _make_snapshot(repo: pathlib.Path, seed: str) -> SnapshotRecord: manifest = {f"{seed}.py": fake_id("obj")} sid = hash_snapshot(manifest) snap = SnapshotRecord( snapshot_id=sid, manifest=manifest, directories=[], created_at=_NOW, note=None, ) write_snapshot(repo, snap) return snap def _make_commit( repo: pathlib.Path, snap: SnapshotRecord, msg: str, parent: str | None = None, agent_id: str | None = None, ) -> CommitRecord: parents = [parent] if parent else [] cid = hash_commit( parent_ids=parents, snapshot_id=snap.snapshot_id, message=msg, committed_at_iso=_NOW.isoformat(), ) c = CommitRecord( commit_id=cid, branch="main", snapshot_id=snap.snapshot_id, message=msg, committed_at=_NOW, parent_commit_id=parent, agent_id=agent_id, ) write_commit(repo, c) return c # --------------------------------------------------------------------------- # store.get_all_commits # --------------------------------------------------------------------------- class TestGetAllCommits: def test_returns_written_commit(self, tmp_path: pathlib.Path) -> None: repo = _init_repo(tmp_path) snap = _make_snapshot(repo, "alpha") c = _make_commit(repo, snap, "first") commits = get_all_commits(repo) ids = [x.commit_id for x in commits] assert c.commit_id in ids def test_returns_all_written_commits(self, tmp_path: pathlib.Path) -> None: repo = _init_repo(tmp_path) snap_a = _make_snapshot(repo, "file_a") snap_b = _make_snapshot(repo, "file_b") snap_c = _make_snapshot(repo, "file_c") c1 = _make_commit(repo, snap_a, "one") c2 = _make_commit(repo, snap_b, "two", parent=c1.commit_id) c3 = _make_commit(repo, snap_c, "three", parent=c2.commit_id) commits = get_all_commits(repo) ids = {x.commit_id for x in commits} assert {c1.commit_id, c2.commit_id, c3.commit_id} == ids def test_empty_repo_returns_empty_list(self, tmp_path: pathlib.Path) -> None: repo = _init_repo(tmp_path) assert get_all_commits(repo) == [] def test_missing_commits_dir_returns_empty_list(self, tmp_path: pathlib.Path) -> None: repo = _init_repo(tmp_path) assert get_all_commits(repo) == [] # --------------------------------------------------------------------------- # store._find_commit_by_prefix / find_commits_by_prefix # --------------------------------------------------------------------------- class TestCommitPrefixScan: def test_find_by_bare_hex_prefix(self, tmp_path: pathlib.Path) -> None: repo = _init_repo(tmp_path) snap = _make_snapshot(repo, "prefix_test") c = _make_commit(repo, snap, "prefix commit") bare_hex = long_id(c.commit_id, strip=True) prefix = bare_hex[:12] found = _find_commit_by_prefix(repo, prefix) assert found is not None assert found.commit_id == c.commit_id def test_find_commits_by_prefix_returns_list(self, tmp_path: pathlib.Path) -> None: repo = _init_repo(tmp_path) snap = _make_snapshot(repo, "prefix_multi") c = _make_commit(repo, snap, "multi prefix") bare_hex = long_id(c.commit_id, strip=True) results = find_commits_by_prefix(repo, bare_hex[:8]) assert any(x.commit_id == c.commit_id for x in results) def test_no_match_returns_none(self, tmp_path: pathlib.Path) -> None: repo = _init_repo(tmp_path) assert _find_commit_by_prefix(repo, NULL_COMMIT_ID) is None def test_find_commits_by_prefix_no_match_returns_empty( self, tmp_path: pathlib.Path ) -> None: repo = _init_repo(tmp_path) assert find_commits_by_prefix(repo, NULL_COMMIT_ID) == [] # --------------------------------------------------------------------------- # snapshot_cmd._list_all_snapshots (internal listing helper) # --------------------------------------------------------------------------- class TestGetAllSnapshots: def test_returns_written_snapshot(self, tmp_path: pathlib.Path) -> None: from muse.cli.commands.snapshot_cmd import _list_all_snapshots repo = _init_repo(tmp_path) snap = _make_snapshot(repo, "listed") results = _list_all_snapshots(repo) ids = [s.snapshot_id for s in results] assert snap.snapshot_id in ids def test_returns_all_written_snapshots(self, tmp_path: pathlib.Path) -> None: from muse.cli.commands.snapshot_cmd import _list_all_snapshots repo = _init_repo(tmp_path) s1 = _make_snapshot(repo, "snap_one") s2 = _make_snapshot(repo, "snap_two") s3 = _make_snapshot(repo, "snap_three") results = _list_all_snapshots(repo) ids = {s.snapshot_id for s in results} assert {s1.snapshot_id, s2.snapshot_id, s3.snapshot_id} == ids def test_empty_repo_returns_empty_list(self, tmp_path: pathlib.Path) -> None: from muse.cli.commands.snapshot_cmd import _list_all_snapshots repo = _init_repo(tmp_path) assert _list_all_snapshots(repo) == [] # --------------------------------------------------------------------------- # snapshot_cmd._resolve_snapshot — full ID path # --------------------------------------------------------------------------- class TestResolveSnapshotFullId: def test_full_prefixed_id_resolves(self, tmp_path: pathlib.Path) -> None: from muse.cli.commands.snapshot_cmd import _resolve_snapshot repo = _init_repo(tmp_path) snap = _make_snapshot(repo, "full_resolve") result = _resolve_snapshot(repo, snap.snapshot_id) assert result is not None assert result.snapshot_id == snap.snapshot_id def test_unknown_id_returns_none(self, tmp_path: pathlib.Path) -> None: from muse.cli.commands.snapshot_cmd import _resolve_snapshot repo = _init_repo(tmp_path) _make_snapshot(repo, "some_snap") result = _resolve_snapshot(repo, fake_id("f")) assert result is None # --------------------------------------------------------------------------- # snapshot_cmd._resolve_snapshot — prefix-scan path (short sha256: prefix) # --------------------------------------------------------------------------- class TestResolveSnapshotShortPrefix: def test_short_prefixed_id_resolves(self, tmp_path: pathlib.Path) -> None: from muse.cli.commands.snapshot_cmd import _resolve_snapshot repo = _init_repo(tmp_path) snap = _make_snapshot(repo, "short_prefix") short = short_id(snap.snapshot_id) # sha256:<12hex> result = _resolve_snapshot(repo, short) assert result is not None, f"prefix {short!r} must resolve; got None" assert result.snapshot_id == snap.snapshot_id def test_unrecognized_prefix_returns_none(self, tmp_path: pathlib.Path) -> None: from muse.cli.commands.snapshot_cmd import _resolve_snapshot repo = _init_repo(tmp_path) _make_snapshot(repo, "exists") result = _resolve_snapshot(repo, "sha256:000000000000") assert result is None # --------------------------------------------------------------------------- # snapshot_diff._resolve_snapshot_prefix # --------------------------------------------------------------------------- class TestResolveDiffSnapshotPrefix: def test_short_prefixed_id_resolves(self, tmp_path: pathlib.Path) -> None: from muse.cli.commands.snapshot_diff import _resolve_snapshot_prefix repo = _init_repo(tmp_path) snap = _make_snapshot(repo, "diff_prefix") short = short_id(snap.snapshot_id) # sha256:<12hex> result = _resolve_snapshot_prefix(repo, short) assert result is not None, f"prefix {short!r} must resolve; got None" assert result == snap.snapshot_id def test_bare_hex_rejected(self, tmp_path: pathlib.Path) -> None: from muse.cli.commands.snapshot_diff import _resolve_snapshot_prefix repo = _init_repo(tmp_path) snap = _make_snapshot(repo, "bare_hex") bare = long_id(snap.snapshot_id, strip=True)[:12] result = _resolve_snapshot_prefix(repo, bare) assert result is None, "bare hex without sha256: prefix must be rejected" def test_unknown_prefix_returns_none(self, tmp_path: pathlib.Path) -> None: from muse.cli.commands.snapshot_diff import _resolve_snapshot_prefix repo = _init_repo(tmp_path) _make_snapshot(repo, "some_snap") result = _resolve_snapshot_prefix(repo, "sha256:000000000000") assert result is None # --------------------------------------------------------------------------- # snapshot_diff._resolve_to_snapshot_id — end-to-end via short prefix # --------------------------------------------------------------------------- class TestResolveToSnapshotId: def test_short_prefixed_snapshot_id_resolves( self, tmp_path: pathlib.Path ) -> None: from muse.cli.commands.snapshot_diff import _resolve_to_snapshot_id repo = _init_repo(tmp_path) snap = _make_snapshot(repo, "e2e_short") short = short_id(snap.snapshot_id) result = _resolve_to_snapshot_id(repo, short) assert result == snap.snapshot_id def test_full_snapshot_id_resolves(self, tmp_path: pathlib.Path) -> None: from muse.cli.commands.snapshot_diff import _resolve_to_snapshot_id repo = _init_repo(tmp_path) snap = _make_snapshot(repo, "e2e_full") result = _resolve_to_snapshot_id(repo, snap.snapshot_id) assert result == snap.snapshot_id