"""A destination two systems declare with two hashes ships one file. RetroDECK declares bios/disk.rom for pc88 (the N88SUB ROM) and for coco (the CoCo disk ROM), and bios/cdibios.zip for two components with two md5. The pack holds one file per path, but verify resolved each declaration to its own file and counted both OK, so three green tools described a pack whose frontend hashes bios/disk.rom for xroar and finds the PC-88 ROM. """ from __future__ import annotations import hashlib import os import sys import tempfile import unittest from pathlib import Path REPO_ROOT = Path(__file__).resolve().parent.parent sys.path.insert(0, str(REPO_ROOT / "scripts")) import common # noqa: E402 import generate_db # noqa: E402 from verify import verify_platform # noqa: E402 class TwinDeclarations(unittest.TestCase): def setUp(self): self._tmp = tempfile.TemporaryDirectory() self._cwd = os.getcwd() os.chdir(self._tmp.name) files, self.md5 = {}, {} for rel, payload in ( ("bios/NEC/PC-98/N88SUB.ROM", b"pc88 disk rom"), ("bios/Tandy/CoCo/disk.rom", b"coco disk rom"), ): path = Path(rel) path.parent.mkdir(parents=True, exist_ok=True) path.write_bytes(payload) sha1 = hashlib.sha1(payload).hexdigest() self.md5[rel] = hashlib.md5(payload).hexdigest() files[sha1] = { "path": rel, "name": path.name, "size": len(payload), "sha1": sha1, "md5": self.md5[rel], "sha256": hashlib.sha256(payload).hexdigest(), "crc32": "00000001", } self.db = {"files": files, "indexes": generate_db.build_indexes(files, {})} self.emulators = Path(self._tmp.name) / "emulators" self.emulators.mkdir() common._emulator_profiles_cache.clear() def tearDown(self): common._emulator_profiles_cache.clear() os.chdir(self._cwd) self._tmp.cleanup() def test_the_losing_declaration_is_scored_against_the_shipped_file(self): config = { "platform": "Twins", "verification_mode": "md5", "base_destination": "bios", "cores": [], "systems": { "pc88": {"files": [{"name": "N88SUB.ROM", "destination": "disk.rom", "md5": self.md5["bios/NEC/PC-98/N88SUB.ROM"]}]}, "coco": {"files": [{"name": "disk.rom", "destination": "disk.rom", "md5": self.md5["bios/Tandy/CoCo/disk.rom"]}]}, }, } report = verify_platform( config, self.db, str(self.emulators), {} ) by_system = {d["system"]: d for d in report["details"] if d["name"] in ("N88SUB.ROM", "disk.rom")} statuses = sorted(d["status"] for d in by_system.values()) self.assertEqual(statuses.count("ok"), 1, by_system) loser = next(d for d in by_system.values() if d["status"] != "ok") self.assertIn("is not met at the path", loser.get("discrepancy", "")) # The path counts once, for the file it ships. The loser is a detail. self.assertEqual(report["status_counts"], {"ok": 1}) if __name__ == "__main__": unittest.main()