"""One rule picks the held file that satisfies the emulator. verify credited a variant found through the emulator's hashes while the platform pack only searched by name and kept the platform's md5: the report called ATARIOSB.ROM satisfied while the pack shipped the dump atari800 rejects, and `verify --emulator azahar` credited an otp.bin the emulator pack never swapped in. Both sides now read find_validated_variant. """ from __future__ import annotations import hashlib import os import re import subprocess import sys import tempfile import unittest from pathlib import Path REPO_ROOT = Path(__file__).resolve().parents[1] sys.path.insert(0, str(REPO_ROOT / "scripts")) from validation import find_validated_variant # noqa: E402 class FindValidatedVariant(unittest.TestCase): def setUp(self): self._tmp = tempfile.TemporaryDirectory() self.addCleanup(self._tmp.cleanup) root = Path(self._tmp.name) self.bad = root / "rom.bin" self.bad.write_bytes(b"x" * 8) self.good = root / "other_name.bin" self.good.write_bytes(b"y" * 16) self.alias = root / "v" / "rom.bin" self.alias.parent.mkdir() self.alias.write_bytes(b"z" * 16) def entry(path: Path) -> tuple[str, dict]: data = path.read_bytes() sha1 = hashlib.sha1(data).hexdigest() return sha1, {"path": str(path), "name": path.name, "sha1": sha1, "md5": hashlib.md5(data).hexdigest(), "size": len(data)} self.files = dict(entry(p) for p in (self.bad, self.good, self.alias)) self.good_sha1 = hashlib.sha1(self.good.read_bytes()).hexdigest() self.db = {"files": self.files, "indexes": { "by_name": {"rom.bin": [s for s, e in self.files.items() if e["name"] == "rom.bin"]}, "by_md5": {e["md5"]: s for s, e in self.files.items()}, }} from validation import _build_validation_index self.by_hash = _build_validation_index({"emu": {"files": [ {"name": "rom.bin", "validation": ["size", "sha1"], "size": 16, "sha1": self.good_sha1}]}}) self.by_size = _build_validation_index({"emu": {"files": [ {"name": "rom.bin", "validation": ["size"], "size": 16}]}}) def test_a_dump_held_under_another_name_is_found_by_the_emulator_hash(self): found = find_validated_variant({"name": "rom.bin"}, self.db, str(self.bad), self.by_hash) self.assertEqual(found, str(self.good)) def test_a_digest_platform_only_takes_a_value_its_entry_declares(self): alias_md5 = hashlib.md5(self.alias.read_bytes()).hexdigest() entry = {"name": "rom.bin", "md5": alias_md5} found = find_validated_variant( entry, self.db, str(self.bad), self.by_size, platform_digest="md5") self.assertEqual(found, str(self.alias)) entry = {"name": "rom.bin", "md5": "0" * 32} self.assertIsNone(find_validated_variant( entry, self.db, str(self.bad), self.by_size, platform_digest="md5")) class OneImplementation(unittest.TestCase): """The report and the builders call the same finder and keep no copy.""" def test_no_module_carries_its_own_variant_search(self): for name in ("verify.py", "generate_pack.py", "packresolve.py"): source = (REPO_ROOT / "scripts" / name).read_text(encoding="utf-8") with self.subTest(module=name): self.assertNotRegex(source, r"def _find_best_variant|def _find_candidate_satisfying_both") for name in ("verify.py", "generate_pack.py"): source = (REPO_ROOT / "scripts" / name).read_text(encoding="utf-8") with self.subTest(module=name): # Directly or through validated_choice, the one place that # picks the variant a destination ships. calls = re.findall(r"(?:find_validated_variant|validated_choice)\(", source) self.assertGreaterEqual(len(calls), 2 if name == "generate_pack.py" else 3) _SEEDED = """ import hashlib, sys, tempfile from pathlib import Path sys.path.insert(0, sys.argv[1]) from validation import _build_validation_index, find_validated_variant root = Path(sys.argv[2]) paths = [root / f"ctrl_{i}.rom" for i in range(8)] files = {} for i, path in enumerate(paths): data = bytes([i]) * 16 path.write_bytes(data) files[hashlib.sha1(data).hexdigest()] = {"path": str(path), "name": path.name} bad = root / "MT32_CONTROL.ROM" bad.write_bytes(b"x" * 16) index = _build_validation_index({"emu": {"files": [ {"name": "MT32_CONTROL.ROM", "validation": ["sha1"], "sha1": sha1} for sha1 in files]}}) db = {"files": files, "indexes": {"by_name": {}}} print(find_validated_variant({"name": "MT32_CONTROL.ROM"}, db, str(bad), index)) """ class TheChoiceDoesNotDependOnTheRun(unittest.TestCase): """Eight MT-32 control ROMs pass dosbox_pure's sha1 check. The candidates were walked in set order, which follows the per-process string hash: the manifest named ctrl_mt32_2_07.rom in one run and ctrl_mt32_2_06.rom in the next.""" def test_the_same_variant_under_every_hash_seed(self): chosen = set() for seed in ("1", "2", "3", "4", "5", "6"): with tempfile.TemporaryDirectory() as tmp: out = subprocess.run( [sys.executable, "-c", _SEEDED, str(REPO_ROOT / "scripts"), tmp], env={**os.environ, "PYTHONHASHSEED": seed}, capture_output=True, text=True, check=True, ).stdout.strip() chosen.add(Path(out).name) self.assertEqual(len(chosen), 1, chosen) if __name__ == "__main__": unittest.main()