mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-10-15 07:53:23 -05:00
fix: group region candidates once for both sides
The builder and the coverage report each grouped their own candidates before asking which regional alternatives to withdraw. The builder grouped the platform files and the core extras; the report grouped the platform files alone, and keyed them on an unsanitized destination. So a region run withdrew 73 files from a recalbox pack while the report withdrew 14, and described the other 59 as covered by a pack that would not carry them. platform_region_groups builds the grouping once and both sides read it. The extras it returns are keyed by emulator, name and path: Dolphin declares three IPL.bin that differ by path alone, and a name-keyed map withdraws the wrong one. Manifests are byte-identical before and after.
This commit is contained in:
1 parent
7a84764348
commit
b33d045175
4 files changed
+267
-118
No files matched your search
@@ -5,6 +5,7 @@ from __future__ import annotations
|
||||
import os
|
||||
import sys
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "scripts"))
|
||||
|
||||
@@ -450,5 +451,119 @@ class TestVerifyModesHonourRegion(unittest.TestCase):
|
||||
self.assertNotEqual(plain, filtered)
|
||||
|
||||
|
||||
class TestReportAndBuilderNarrowTogether(unittest.TestCase):
|
||||
"""A region run must withdraw the same files from report and pack.
|
||||
|
||||
The two sides grouped their candidates separately: the builder grouped the
|
||||
platform files and the core extras, the report only the platform files.
|
||||
So the report kept every core extra a region run withdraws from the pack
|
||||
-on recalbox --region us, 59 files it described as covered.
|
||||
"""
|
||||
|
||||
def _fixture(self):
|
||||
import hashlib
|
||||
import tempfile
|
||||
|
||||
tmp = tempfile.TemporaryDirectory()
|
||||
root = Path(tmp.name)
|
||||
(root / "emulators").mkdir()
|
||||
db = {"files": {}, "indexes": {
|
||||
"by_name": {}, "by_md5": {}, "by_sha256": {},
|
||||
"by_crc32": {}, "by_path_suffix": {},
|
||||
}}
|
||||
# Two regional alternatives of one system, both held locally.
|
||||
for fname, tag in (("us.bin", b"US BYTES"), ("jp.bin", b"JP BYTES")):
|
||||
blob = root / fname
|
||||
blob.write_bytes(tag)
|
||||
sha1 = hashlib.sha1(tag).hexdigest()
|
||||
db["files"][sha1] = {
|
||||
"path": str(blob), "name": fname, "size": len(tag),
|
||||
"sha1": sha1, "md5": hashlib.md5(tag).hexdigest(),
|
||||
"sha256": hashlib.sha256(tag).hexdigest(), "crc32": "00000000",
|
||||
}
|
||||
db["indexes"]["by_name"][fname] = [sha1]
|
||||
db["indexes"]["by_md5"][db["files"][sha1]["md5"]] = sha1
|
||||
(root / "emulators" / "demo.yml").write_text(
|
||||
"emulator: demo\n"
|
||||
"type: libretro\n"
|
||||
"display_name: Demo\n"
|
||||
"systems: [demo-system]\n"
|
||||
"cores: [demo]\n"
|
||||
"files:\n"
|
||||
" - name: us.bin\n"
|
||||
" system: demo-system\n"
|
||||
" region: [north-america]\n"
|
||||
" required: true\n"
|
||||
" - name: jp.bin\n"
|
||||
" system: demo-system\n"
|
||||
" region: [japan]\n"
|
||||
" required: true\n"
|
||||
)
|
||||
config = {
|
||||
"platform": "Demo",
|
||||
"verification_mode": "existence",
|
||||
"cores": ["demo"],
|
||||
"base_destination": "",
|
||||
"systems": {},
|
||||
}
|
||||
return tmp, root, db, config
|
||||
|
||||
def test_the_report_withdraws_what_the_builder_withdraws(self):
|
||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "scripts"))
|
||||
import common
|
||||
import generate_pack as builder
|
||||
import verify as reporter
|
||||
|
||||
tmp, root, db, config = self._fixture()
|
||||
try:
|
||||
common._emulator_profiles_cache.clear()
|
||||
profiles = common.load_emulator_profiles(str(root / "emulators"))
|
||||
groups, extra_dests = builder.platform_region_groups(
|
||||
config, config["systems"], str(root / "emulators"),
|
||||
db, "", profiles,
|
||||
)
|
||||
drops = region.resolve_region_drops(
|
||||
groups, region.build_region_index(profiles), ["north-america"]
|
||||
)
|
||||
self.assertEqual(
|
||||
{d for d in drops}, {"jp.bin"},
|
||||
"the builder must drop the Japanese alternative, not the US one",
|
||||
)
|
||||
|
||||
plain = reporter.verify_platform(
|
||||
config, db, str(root / "emulators"), profiles,
|
||||
supplemental_names=set(),
|
||||
)
|
||||
narrowed = reporter.verify_platform(
|
||||
config, db, str(root / "emulators"), profiles,
|
||||
supplemental_names=set(), regions=["north-america"],
|
||||
)
|
||||
before = {u["name"] for u in plain["undeclared_files"]}
|
||||
after = {u["name"] for u in narrowed["undeclared_files"]}
|
||||
self.assertEqual(before, {"us.bin", "jp.bin"})
|
||||
self.assertEqual(
|
||||
before - after,
|
||||
{d for d in drops},
|
||||
"the report must withdraw exactly the builder's drop set",
|
||||
)
|
||||
finally:
|
||||
common._emulator_profiles_cache.clear()
|
||||
tmp.cleanup()
|
||||
|
||||
def test_one_grouping_pass_serves_both_sides(self):
|
||||
"""A second hand-rolled grouping is how the two drifted apart."""
|
||||
scripts = Path(__file__).resolve().parent.parent / "scripts"
|
||||
hand_rolled = 0
|
||||
for name in ("generate_pack.py", "verify.py"):
|
||||
for line in (scripts / name).read_text().splitlines():
|
||||
if "region_groups.setdefault(" in line:
|
||||
hand_rolled += 1
|
||||
self.assertLessEqual(
|
||||
hand_rolled, 2,
|
||||
"platform region grouping belongs to platform_region_groups; "
|
||||
"the only other pass is the per-emulator pack shape",
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in new issue
Block a user