File size: 2,351 Bytes
551b309
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
"""Integrity guard: matching manifest passes, any change bricks."""

# Credit: @paparichens

from __future__ import annotations

import json
from pathlib import Path

import pytest

from affix_huggingface.integrity import (
    MANIFEST_NAME,
    IntegrityError,
    build_manifest,
    verify_tree,
)


def _package(root: Path) -> Path:
    pkg = root / "pkg"
    pkg.mkdir()
    (pkg / "__init__.py").write_text("VALUE = 1\n", encoding="utf-8")
    (pkg / "core.py").write_text("def run():\n    return True\n", encoding="utf-8")
    (pkg / "py.typed").write_text("\n", encoding="utf-8")
    return pkg


def _write_manifest(pkg: Path) -> None:
    manifest = build_manifest(pkg)
    (pkg / MANIFEST_NAME).write_text(json.dumps(manifest), encoding="utf-8")


def test_unbuilt_tree_without_manifest_is_not_enforced(tmp_path: Path) -> None:
    pkg = _package(tmp_path)
    verify_tree(pkg)  # no manifest, no raise


def test_matching_manifest_passes(tmp_path: Path) -> None:
    pkg = _package(tmp_path)
    _write_manifest(pkg)
    verify_tree(pkg)


def test_editing_a_file_bricks(tmp_path: Path) -> None:
    pkg = _package(tmp_path)
    _write_manifest(pkg)
    (pkg / "core.py").write_text("def run():\n    return False\n", encoding="utf-8")
    with pytest.raises(IntegrityError, match="modified"):
        verify_tree(pkg)


def test_adding_a_file_bricks(tmp_path: Path) -> None:
    pkg = _package(tmp_path)
    _write_manifest(pkg)
    (pkg / "extra.py").write_text("x = 1\n", encoding="utf-8")
    with pytest.raises(IntegrityError, match="unexpected"):
        verify_tree(pkg)


def test_removing_a_file_bricks(tmp_path: Path) -> None:
    pkg = _package(tmp_path)
    _write_manifest(pkg)
    (pkg / "core.py").unlink()
    with pytest.raises(IntegrityError, match="missing"):
        verify_tree(pkg)


def test_corrupt_manifest_bricks(tmp_path: Path) -> None:
    pkg = _package(tmp_path)
    (pkg / MANIFEST_NAME).write_text("{ not json", encoding="utf-8")
    with pytest.raises(IntegrityError, match="malformed"):
        verify_tree(pkg)


def test_manifest_excludes_itself_and_pyc(tmp_path: Path) -> None:
    pkg = _package(tmp_path)
    _write_manifest(pkg)
    cache = pkg / "__pycache__"
    cache.mkdir()
    (cache / "core.cpython-312.pyc").write_bytes(b"\x00\x01")
    verify_tree(pkg)  # bytecode and manifest are ignored