docs: describe short md5 handling as the code does

No platform YAML holds an md5 shorter than 32 characters: the Batocera scraper completes one when a single collection md5 starts with it. The pages said some entries carry 29 characters and that scrapers store them as-is.
This commit is contained in:
Abdessamad Derraz committed 2026-10-21 09:54:57 +02:00
1 parent a6d37e40ae
commit d8e9ad23d3
8 files changed
+44 -15

No files matched your search

+26
View File
@@ -497,5 +497,31 @@ class EmulatorVerboseSample(unittest.TestCase):
self.assertIn(line, printed)
class ShortMd5Handling(unittest.TestCase):
"""Three pages said some Batocera entries carry 29-character MD5s and show
as untested. No platform YAML holds one, since the Batocera scraper
completes them, and adding-a-scraper.md said to store them as-is."""
def test_no_page_claims_short_md5_entries(self):
offenders = [
page.name for page in PUBLISHED
if re.search(r"(?i)29[- ]char|truncated md5 hashes in some entries|store the hash as-is",
page.read_text(encoding="utf-8"))
]
self.assertEqual(offenders, [])
def test_the_page_names_what_the_code_does(self):
import common
from scraper import batocera_scraper
scraper = inspect.getsource(batocera_scraper)
self.assertIn("md5 = _resolve_truncated_md5(", scraper)
resolver = inspect.getsource(common.resolve_local_file)
self.assertIn("if len(md5_candidate) < 32:", resolver)
self.assertIn("_md5_name_ok(path)", resolver)
section = _section(_page("verification-modes.md"), "MD5 shorter than 32 characters (Batocera)")
self.assertIn("_resolve_truncated_md5", section)
if __name__ == "__main__":
unittest.main()
+2 -2
View File
@@ -265,7 +265,7 @@ class TestE2E(unittest.TestCase):
).hexdigest() # sorted: a.rom, b.rom
multi_wrong = "0000000000000000000000000000000"
multi_right = f["multi.zip"]["inner_md5s"]["rom.bin"]
truncated_md5 = f["truncated.bin"]["md5"][:29] # Batocera 29-char
truncated_md5 = f["truncated.bin"]["md5"][:29] # shorter than 32 characters
config = {
"platform": "TestMD5",
@@ -347,7 +347,7 @@ class TestE2E(unittest.TestCase):
"zipped_file": "rom.bin",
"required": True,
},
# Truncated MD5 (Batocera 29 chars)
# MD5 shorter than 32 characters
{
"name": "truncated.bin",
"destination": "truncated.bin",
+1 -1
View File
@@ -86,7 +86,7 @@ class DeclaredHashVerdict(unittest.TestCase):
)
def test_a_truncated_md5_still_decides(self):
"""Batocera publishes 29-character prefixes, which are still evidence."""
"""An MD5 shorter than 32 characters is still evidence, by prefix."""
self.assertEqual(
self.verdict(self.right, md5_list=[self.d["md5"][:29]]),
"data_dir_hash_exact",
+1 -1
View File
@@ -118,7 +118,7 @@ class ShippedFilesSatisfyTheirDeclaration(unittest.TestCase):
digests["md5"].append(common.md5_composite(str(blob_path)))
except (zipfile.BadZipFile, OSError):
pass
# Batocera publishes 29-character prefixes, so compare by prefix.
# A declared MD5 can be shorter than 32 characters: compare by prefix.
satisfied = any(
all(
any(