fix: verify applies storage tiers like the pack

The builder never looks up a user_provided entry (it writes instructions in its place) nor an external one (fetched from its URL at build time). verify resolved both by name, so a same-named file in bios/ made it credit a file the pack does not carry.
This commit is contained in:
Abdessamad Derraz committed 2026-10-19 23:02:54 +02:00
1 parent 1ea6b9d070
commit 2bd9f8a264
2 files changed
+66 -2

No files matched your search

+34 -2
View File
@@ -782,6 +782,31 @@ def _mark_unplaced(config: dict, undeclared: list[dict], profiles: dict) -> None
u["omitted"] = _UNPLACED_REASONS[reason]
def _storage_verdict(file_entry: dict, emulator_pack: bool) -> dict | None:
"""The result a storage tier fixes before any lookup, as the builder sees it.
A user_provided entry is never taken from the collection: a platform pack
writes its instructions in the slot and counts it filled, an emulator pack
lists it to provide. An external one is fetched from its URL when the pack
is built, never read from bios/. Resolving either by name credited a
same-named file the pack does not carry.
"""
storage = file_entry.get("storage", "embedded")
base = {"name": file_entry.get("name", ""), "required": file_entry.get("required", True)}
if storage == "user_provided":
if emulator_pack:
stated = file_entry.get("unsourceable")
why = (
stated if isinstance(stated, str) and stated
else file_entry.get("instructions") or "the user provides it"
)
return {**base, "status": Status.MISSING, "unsourceable": why}
return {**base, "status": Status.OK, "user_provided": True}
if storage == "external":
return {**base, "status": Status.MISSING, "reason": "fetched from its URL when the pack is built"}
return None
_HIDDEN_REASONS = {
"case_twin": "a packed file of the same name in another case takes its place",
"path_conflict": "a packed file occupies its directory",
@@ -1064,7 +1089,11 @@ def verify_platform(
destination = sanitize_pack_path(
file_entry.get("destination", file_entry.get("name", ""))
)
if not reads_file_contents(mode):
stored = _storage_verdict(file_entry, emulator_pack=False)
if stored is not None:
result = stored
local_path = None
elif not reads_file_contents(mode):
result = verify_entry_existence(
file_entry,
local_path,
@@ -1795,7 +1824,10 @@ def verify_emulator(
required = file_entry.get("required", True)
hle = file_entry.get("hle_fallback", False)
if not local_path:
stored = _storage_verdict(file_entry, emulator_pack=True)
if stored is not None:
result = stored
elif not local_path:
result = {"name": name, "status": Status.MISSING, "required": required}
# An entry the profile documents as unsourceable is absent by
# design: a per-user key, a slot the user fills, a dump nobody
+32
View File
@@ -242,5 +242,37 @@ class FlatFirmwareFolder(unittest.TestCase):
self.assertEqual([f["dest"] for f in files if f["dest"].count("/") > 1], [])
class UserProvidedIsNeverTakenFromTheCollection(unittest.TestCase):
"""The builder writes instructions for a user_provided entry and never
looks it up. verify resolved it by name, so a same-named file in bios/
made it report 1/1 OK for a pack that holds no such file."""
def test_verify_matches_the_builder(self):
from verify import Status, verify_emulator
with tempfile.TemporaryDirectory() as tmp:
previous = os.getcwd()
os.chdir(tmp)
self.addCleanup(os.chdir, previous)
for d in ("emulators", "bios/Sony"):
Path(d).mkdir(parents=True)
Path("bios/Sony/scph5501.bin").write_bytes(b"psx")
sha1 = hashlib.sha1(b"psx").hexdigest()
files = {sha1: {"path": "bios/Sony/scph5501.bin", "name": "scph5501.bin",
"size": 3, "sha1": sha1, "md5": hashlib.md5(b"psx").hexdigest(),
"sha256": hashlib.sha256(b"psx").hexdigest(), "crc32": "00000001"}}
db = {"files": files, "indexes": generate_db.build_indexes(files, {})}
Path("emulators/fake.yml").write_text(
"emulator: Fake\ntype: libretro\nsystems: [psx]\ncores: [fake]\n"
"files:\n - name: scph5501.bin\n storage: user_provided\n"
)
common._emulator_profiles_cache.clear()
self.addCleanup(common._emulator_profiles_cache.clear)
result = verify_emulator(["fake"], "emulators", db)
statuses = [d["status"] for d in result["details"] if d["name"] == "scph5501.bin"]
self.assertEqual(statuses, [Status.MISSING])
self.assertNotIn(Status.OK, result["status_counts"])
if __name__ == "__main__":
unittest.main()