fix: keep the md5 a mister entry already holds

A BiosDB entry is one record: md5, size and url describe one dump. The
first md5 the truth accepts replaced an accepted one with no change
reported. The exporter now writes record_hash, as RomM and System.dat do.
This commit is contained in:
Abdessamad Derraz committed 2026-11-05 11:41:18 +01:00
1 parent 0418df5337
commit 4e5b48ddbe
2 files changed
+31 -4

No files matched your search

+10 -4
View File
@@ -86,8 +86,14 @@ class Exporter(BaseExporter):
return super().states(fe, field_name)
def written(self, fe: NativeFile, field_name: str) -> str:
"""An entry is checked against one md5, the first accepted."""
return fe.hash(field_name)
"""An entry is one record: its md5, size and url describe one dump.
The first value the truth accepts replaced MiSTer's own accepted
md5 while the url still served MiSTer's dump, which the Downloader
then refused (fetch_file_worker.py:127), and the report said
nothing. record_hash keeps the platform's value when it is accepted.
"""
return fe.record_hash(field_name)
def _by_path(self, systems: dict[str, NativeSystem]) -> dict[str, object]:
indexed: dict[str, object] = {}
@@ -119,7 +125,7 @@ class Exporter(BaseExporter):
fe = indexed.get(path)
if fe is None:
continue
md5 = fe.hash("md5")
md5 = self.written(fe, "md5")
if not md5:
# The record is checked by its md5: where the truth takes the
# entry without one, a new size beside the old hash describes
@@ -185,7 +191,7 @@ class Exporter(BaseExporter):
indexed = self._by_path(systems)
for path, fe in indexed.items():
declared = files.get(path)
md5 = fe.hash("md5")
md5 = self.written(fe, "md5")
if (
declared is not None and md5 and declared.get("hash") != md5
and path not in getattr(self, "_unsized", [])
+21
View File
@@ -1849,6 +1849,27 @@ class MisterDatabaseComesBackAsWritten(unittest.TestCase):
self.assertEqual(len(exporter.withheld()), 1)
self.assertEqual(exporter.validate(systems, produced), [])
def test_an_accepted_hash_is_not_swapped_for_another(self):
"""The url serves MiSTer's dump, and the truth accepts it among two.
The first accepted md5 went in its place with no change reported,
and the Downloader refused every install of the file."""
database = {"db_id": "bios_db", "files": {
"games/X/boot.rom": {"hash": "b" * 32, "size": 10, "url": "u"},
}}
original = json.dumps(database)
scraped = {"systems": {"x": {"files": [{
"name": "boot.rom", "destination": "X/boot.rom", "md5": "b" * 32, "size": 10,
}]}}}
truth = {"systems": {"x": {"files": [{
"name": "boot.rom", "path": "X/boot.rom", "md5": ["a" * 32, "b" * 32],
"size": 10, "_cores": ["x"],
}]}}}
exporter = discover_exporters()["misterfpga"]()
systems, report = build_native_model(truth, scraped)
produced = exporter.render(systems, report, {"bios_db.json": original}, scraped)
self.assertEqual(produced["bios_db.json"], original)
self.assertEqual(exporter.validate(systems, produced), [])
def test_an_empty_truth_hands_back_the_database(self):
archive = UPSTREAM_CACHE / "misterfpga" / "bios_db.json.zip"
if not archive.exists():