mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-10-20 18:59:07 -05:00
feat: mark files a core finds by content
DuckStation identifies its BIOS by MD5 in a folder it scans (bios.cpp:208), so its entries' names are labels. The export wrote them into Batocera's and ROCKNIX's lists as files to hold: a user with only scph5501.bin read 104 missing BIOS where DuckStation boots. Labels also lent their md5 to a name another core opens, and paired by name they replaced System.dat's scph5000.bin hashes. found_by: name | content, on a profile or a file and keyed by build like load_from. The truth records which cores open each name (_named_by). A label pairs with a platform entry by hash only, is never added, merges with an opened name only on a shared hash, and is counted in the export report rather than listed as missing.
This commit is contained in:
1 parent
eaf6d1859d
commit
e5174a07bf
8 files changed
+182
-6
No files matched your search
@@ -330,6 +330,49 @@ class Reconciliation(unittest.TestCase):
|
||||
scraped_sys = {"files": [{"name": "scph1001.bin", "md5": "b" * 32}]}
|
||||
self.assertNotIn("hash_mismatch", _diff_system(truth_sys, scraped_sys))
|
||||
|
||||
def test_a_label_is_never_added(self):
|
||||
"""A name only a content-scanning core gives is no file to hold."""
|
||||
truth = {"systems": {"sony-playstation": {"files": [
|
||||
{"name": "scph1001_v20.bin", "md5": "a" * 32,
|
||||
"_cores": ["duckstation"], "_named_by": []},
|
||||
{"name": "scph5903.bin", "md5": "c" * 32,
|
||||
"_cores": ["beetle_psx"], "_named_by": ["beetle_psx"]},
|
||||
]}}}
|
||||
scraped = {"systems": {"sony-playstation": {"native_id": "psx", "files": [
|
||||
{"name": "scph5501.bin", "destination": "scph5501.bin",
|
||||
"native_system": "psx", "md5": "d" * 32}]}}}
|
||||
systems, report = build_native_model(truth, scraped)
|
||||
self.assertEqual([fe.name for fe in systems["psx"].files],
|
||||
["scph5501.bin", "scph5903.bin"])
|
||||
self.assertEqual(report.files_added, 1)
|
||||
|
||||
def test_a_label_pairs_by_content_only(self):
|
||||
"""DuckStation's and rustation's scph5000.bin labels carried another
|
||||
dump's md5 and, paired by name, replaced System.dat's scph5000.bin."""
|
||||
truth = {"systems": {"sony-playstation": {"files": [
|
||||
{"name": "scph5000.bin", "md5": "a" * 32,
|
||||
"_cores": ["duckstation"], "_named_by": []},
|
||||
{"name": "other_label.bin", "md5": "e" * 32, "sha256": "f" * 64,
|
||||
"_cores": ["duckstation"], "_named_by": []},
|
||||
]}}}
|
||||
scraped = {"systems": {"sony-playstation": {"native_id": "psx", "files": [
|
||||
{"name": "scph5000.bin", "destination": "scph5000.bin",
|
||||
"native_system": "psx", "md5": "b" * 32},
|
||||
{"name": "scph7001.bin", "destination": "scph7001.bin",
|
||||
"native_system": "psx", "md5": "e" * 32},
|
||||
]}}}
|
||||
systems, report = build_native_model(truth, scraped)
|
||||
scph5000, scph7001 = systems["psx"].files
|
||||
self.assertIsNone(scph5000.truth)
|
||||
self.assertEqual(scph7001.truth["name"], "other_label.bin")
|
||||
self.assertEqual(report.hashes_corrected, [])
|
||||
|
||||
def test_the_diff_names_no_missing_label(self):
|
||||
from truth import _diff_system
|
||||
truth_sys = {"files": [{"name": "scph1001_v20.bin", "md5": "a" * 32,
|
||||
"_cores": ["duckstation"], "_named_by": []}]}
|
||||
self.assertNotIn("missing", _diff_system(truth_sys, {"files": []}))
|
||||
|
||||
def test_the_diff_pairs_by_the_same_rule(self):
|
||||
"""diff_truth reads the same pairing, or it names a mismatch the
|
||||
export does not correct."""
|
||||
|
||||
@@ -294,5 +294,50 @@ class ASizeOutsideARangeIsAnotherFile(unittest.TestCase):
|
||||
self.assertEqual(len(system["files"]), 2)
|
||||
|
||||
|
||||
class TruthRecordsWhoOpensByName(unittest.TestCase):
|
||||
"""DuckStation finds its BIOS by MD5 in a folder it scans (bios.cpp:208,
|
||||
397-427): its names are labels. The export wrote them into Batocera's
|
||||
list as files to hold, and a user with only scph5501.bin read 104
|
||||
missing BIOS where DuckStation boots."""
|
||||
|
||||
DUCK = {"type": "libretro", "systems": ["sony-playstation"], "found_by": "content",
|
||||
"files": [{"name": "scph1001_v20.bin", "md5": "a" * 32},
|
||||
{"name": "scph1001.bin", "md5": "b" * 32}]}
|
||||
PCSX = {"type": "libretro", "systems": ["sony-playstation"],
|
||||
"files": [{"name": "scph1001.bin", "size": 524288}]}
|
||||
|
||||
def truth(self, profiles: dict) -> dict:
|
||||
config = {"cores": list(profiles), "systems": {"sony-playstation": {"files": []}}}
|
||||
return generate_platform_truth("p", config, {}, profiles)
|
||||
|
||||
def entries(self, truth: dict) -> list[dict]:
|
||||
return truth["systems"]["sony-playstation"]["files"]
|
||||
|
||||
def test_a_content_scanning_core_names_nothing(self):
|
||||
truth = self.truth({"duckstation": self.DUCK})
|
||||
self.assertEqual({f["name"]: f["_named_by"] for f in self.entries(truth)},
|
||||
{"scph1001_v20.bin": [], "scph1001.bin": []})
|
||||
|
||||
def test_a_label_lends_no_hash_to_a_name_another_core_opens(self):
|
||||
"""pcsx_rearmed opens scph1001.bin by name, with no hash: it took the
|
||||
md5 of DuckStation's label of that name."""
|
||||
truth = self.truth({"duckstation": self.DUCK, "pcsx": self.PCSX})
|
||||
named = [f for f in self.entries(truth) if f["_named_by"] == ["pcsx"]]
|
||||
self.assertEqual(len(named), 1)
|
||||
self.assertNotIn("md5", named[0])
|
||||
|
||||
def test_the_build_decides(self):
|
||||
ymir = {"type": "standalone + libretro", "systems": ["sega-saturn"],
|
||||
"found_by": {"standalone": "content"},
|
||||
"files": [{"name": "sega_101.bin", "md5": "c" * 32}]}
|
||||
config = {"cores": ["ymir"], "standalone_cores": [],
|
||||
"systems": {"sega-saturn": {"files": []}}}
|
||||
libretro = generate_platform_truth("p", config, {}, {"ymir": ymir})
|
||||
self.assertEqual(libretro["systems"]["sega-saturn"]["files"][0]["_named_by"], ["ymir"])
|
||||
config["standalone_cores"] = ["ymir"]
|
||||
standalone = generate_platform_truth("p", config, {}, {"ymir": ymir})
|
||||
self.assertEqual(standalone["systems"]["sega-saturn"]["files"][0]["_named_by"], [])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in new issue
Block a user