personal memory agent
0

Configure Feed

Select the types of activity you want to include in your feed.

solstone / tests / test_native_sol_python_manifest.py
3.1 kB 110 lines
1# SPDX-License-Identifier: AGPL-3.0-only 2# Copyright (c) 2026 sol pbc 3from __future__ import annotations 4 5import hashlib 6import subprocess 7import sys 8from pathlib import Path 9 10import pytest 11 12import scripts.check_native_sol_python_manifest as manifest 13 14 15def _git(repo: Path, *args: str) -> str: 16 result = subprocess.run( 17 ["git", *args], 18 cwd=repo, 19 check=True, 20 capture_output=True, 21 text=True, 22 ) 23 return result.stdout.strip() 24 25 26def _fixture_tree(repo: Path, files: dict[str, str]) -> tuple[str, dict[str, str]]: 27 repo.mkdir() 28 _git(repo, "init") 29 blobs: dict[str, str] = {} 30 for rel_path, text in files.items(): 31 path = repo / rel_path 32 path.parent.mkdir(parents=True, exist_ok=True) 33 path.write_text(text, encoding="utf-8") 34 blobs[rel_path] = _git(repo, "hash-object", str(path)) 35 _git(repo, "add", *sorted(files)) 36 tree = _git(repo, "write-tree") 37 return tree, blobs 38 39 40def _digest(blobs: dict[str, str]) -> str: 41 return hashlib.sha256( 42 "".join(f"{path}\t{blob}\n" for path, blob in sorted(blobs.items())).encode( 43 "utf-8" 44 ) 45 ).hexdigest() 46 47 48def _patch_manifest( 49 monkeypatch: pytest.MonkeyPatch, 50 *, 51 repo: Path, 52 tree: str, 53 expected_blobs: dict[str, str], 54) -> None: 55 monkeypatch.setattr(manifest, "REPO_ROOT", repo) 56 monkeypatch.setattr(manifest, "PRE_CUTOVER_COMMIT", tree) 57 monkeypatch.setattr(manifest, "EXPECTED_BLOBS", dict(expected_blobs)) 58 monkeypatch.setattr(manifest, "EXPECTED_SHA256", _digest(expected_blobs)) 59 60 61def _run_manifest_main() -> int: 62 try: 63 return manifest.main() 64 except Exception as error: 65 print(error, file=sys.stderr) 66 return 1 67 68 69def test_manifest_main_fails_visibly_when_baseline_path_is_missing( 70 tmp_path: Path, monkeypatch: pytest.MonkeyPatch, capsys: pytest.CaptureFixture[str] 71) -> None: 72 repo = tmp_path / "repo" 73 tree, blobs = _fixture_tree(repo, {"present.py": "print('present')\n"}) 74 expected_blobs = {**blobs, "missing.py": "0" * 40} 75 _patch_manifest( 76 monkeypatch, 77 repo=repo, 78 tree=tree, 79 expected_blobs=expected_blobs, 80 ) 81 82 exit_code = _run_manifest_main() 83 84 captured = capsys.readouterr() 85 assert exit_code == 1 86 assert "git ls-tree returned 1 entries; missing: missing.py" in captured.err 87 88 89def test_manifest_main_fails_visibly_when_expected_blob_drifts( 90 tmp_path: Path, monkeypatch: pytest.MonkeyPatch, capsys: pytest.CaptureFixture[str] 91) -> None: 92 repo = tmp_path / "repo" 93 tree, blobs = _fixture_tree(repo, {"present.py": "print('present')\n"}) 94 expected_blobs = dict(blobs) 95 expected_blobs["present.py"] = "0" * 40 96 _patch_manifest( 97 monkeypatch, 98 repo=repo, 99 tree=tree, 100 expected_blobs=expected_blobs, 101 ) 102 103 exit_code = _run_manifest_main() 104 105 captured = capsys.readouterr() 106 assert exit_code == 1 107 assert "native sol Python manifest blob drifted" in captured.err 108 assert ( 109 "present.py: expected 0000000000000000000000000000000000000000" in captured.err 110 )