Files
libretro/tests/test_pack_member_identity.py
T

87 lines
3.4 KiB
Python

"""Every pack member is bytes the collection recognises.
A member whose sha1 and md5 matched nothing was counted `untracked` with
zero errors and the pack passed, so bytes altered while the ZIP was written
went unseen. Archives the builder assembles (MAME clone sets) are
recognised by their members.
"""
from __future__ import annotations
import hashlib
import io
import json
import re
import sys
import tempfile
import unittest
import zipfile
from pathlib import Path
REPO_ROOT = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(REPO_ROOT / "scripts"))
from packverify import verify_pack # noqa: E402
class MembersMustBeKnown(unittest.TestCase):
def test_unknown_bytes_are_an_error_and_assembled_sets_pass(self):
known = b"known rom" * 10
md5 = hashlib.md5(known).hexdigest()
inner = io.BytesIO()
with zipfile.ZipFile(inner, "w") as zf:
zf.writestr("rom.bin", known)
db = {"files": {}, "indexes": {"by_md5": {md5: "s"}, "by_name": {}}}
with tempfile.TemporaryDirectory(dir=REPO_ROOT / "tmp") as tmp:
pack = Path(tmp) / "P_BIOS_Pack.zip"
with zipfile.ZipFile(pack, "w") as zf:
zf.writestr("clone.zip", inner.getvalue())
zf.writestr("garbled.bin", b"no such dump")
ok, manifest = verify_pack(str(pack), db)
statuses = {f["path"]: f["status"] for f in manifest["files"]}
self.assertEqual(statuses["clone.zip"], "verified_members")
self.assertFalse(ok)
self.assertTrue(any("garbled.bin" in e for e in manifest["errors"]))
class DataMembersAreCheckedByContent(unittest.TestCase):
"""A data-directory member was verified by name and size: bytes altered
while the pack was written kept their length and passed."""
def test_same_size_other_bytes_is_an_error(self):
good = b"A" * 64
with tempfile.TemporaryDirectory(dir=REPO_ROOT / "tmp") as tmp:
cache = Path(tmp) / "cache"
(cache / "Sys").mkdir(parents=True)
(cache / "Sys" / "font.bin").write_bytes(good)
registry = {"demo": {"local_cache": str(cache)}}
db = {"files": {}, "indexes": {"by_md5": {}, "by_name": {}}}
pack = Path(tmp) / "P_BIOS_Pack.zip"
with zipfile.ZipFile(pack, "w") as zf:
zf.writestr("system/Sys/font.bin", good)
zf.writestr("system/Sys/other/font.bin", b"B" * 64)
ok, manifest = verify_pack(str(pack), db, registry)
statuses = {f["path"]: f["status"] for f in manifest["files"]}
self.assertEqual(statuses["system/Sys/font.bin"], "verified_data")
self.assertNotEqual(statuses["system/Sys/other/font.bin"], "verified_data")
self.assertFalse(ok)
class SchemaAcceptsEveryStatus(unittest.TestCase):
"""verified_members reached every pack manifest and the schema refused it."""
def test_each_status_packverify_writes_is_in_the_schema(self):
source = (REPO_ROOT / "scripts" / "packverify.py").read_text(encoding="utf-8")
written = set(re.findall(r'status = "([a-z_]+)"', source))
schema = json.loads(
(REPO_ROOT / "schemas" / "pack-manifest.schema.json").read_text(encoding="utf-8")
)
allowed = set(
schema["properties"]["files"]["items"]["properties"]["status"]["enum"]
)
self.assertTrue(written)
self.assertEqual(sorted(written - allowed), [])
if __name__ == "__main__":
unittest.main()