mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-10-23 12:19:13 -05:00
fix: list what the emulator pack writes
verify --emulator listed only OK destinations, while the emulator pack also writes a copy whose hash the profile contradicts, loose or archive. pack_destinations now records the paths the replay places, and both branches resolve through packresolve.resolve_file as the pack does.
This commit is contained in:
1 parent
4ceca6acc5
commit
084dff84f4
2 files changed
+54
-5
No files matched your search
+17
-5
@@ -1816,6 +1816,7 @@ def verify_emulator(
|
||||
`system_ids` keeps the entries of those systems, as the system pack does.
|
||||
"""
|
||||
from packextras import expand_agnostic_entries
|
||||
from packresolve import resolve_file
|
||||
from packpaths import (
|
||||
_archive_destination,
|
||||
_register_path,
|
||||
@@ -1846,6 +1847,10 @@ def verify_emulator(
|
||||
file_severity: dict[str, str] = {}
|
||||
dest_to_name: dict[str, str] = {}
|
||||
data_dir_notices: list[str] = []
|
||||
# The paths the emulator pack writes a profile file to. A copy whose hash
|
||||
# the profile contradicts is written too (UNTESTED here, a DISCREPANCY in
|
||||
# the pack), so the status alone does not say what the pack holds.
|
||||
packed_dests: set[str] = set()
|
||||
|
||||
# The emulator pack withdraws these, and the report withdraws the same.
|
||||
region_drops: set[str] = set()
|
||||
@@ -1936,11 +1941,13 @@ def verify_emulator(
|
||||
archive = file_entry.get("archive")
|
||||
if archive and archive not in seen_archives:
|
||||
seen_archives.add(archive)
|
||||
local_path, resolve_status = resolve_local_file(
|
||||
local_path, resolve_status = resolve_file(
|
||||
archive_entry(archive, files),
|
||||
db,
|
||||
DEFAULT_BIOS_DIR,
|
||||
zip_contents,
|
||||
data_dir_registry=data_registry,
|
||||
offline=True,
|
||||
)
|
||||
required = any(
|
||||
f.get("archive") == archive and f.get("required", True)
|
||||
@@ -1997,6 +2004,7 @@ def verify_emulator(
|
||||
)
|
||||
elif local_path:
|
||||
occupy(dest, local_path, emu_name)
|
||||
packed_dests.add(dest)
|
||||
dest_to_name[dest] = archive
|
||||
cur = result["status"]
|
||||
prev = file_status.get(dest)
|
||||
@@ -2023,13 +2031,18 @@ def verify_emulator(
|
||||
continue
|
||||
|
||||
dest_hint = file_entry.get("path", "")
|
||||
local_path, resolve_status = resolve_local_file(
|
||||
# The emulator pack's resolution, release assets included.
|
||||
local_path, resolve_status = resolve_file(
|
||||
{**with_archive_members(file_entry, files), "source_profile": emu_name},
|
||||
db,
|
||||
DEFAULT_BIOS_DIR,
|
||||
zip_contents,
|
||||
dest_hint=dest_hint,
|
||||
data_dir_registry=data_registry,
|
||||
offline=True,
|
||||
)
|
||||
if resolve_status in ("not_found", "user_provided", "external"):
|
||||
local_path = None
|
||||
name = file_entry.get("name", "")
|
||||
required = file_entry.get("required", True)
|
||||
hle = file_entry.get("hle_fallback", False)
|
||||
@@ -2159,6 +2172,7 @@ def verify_emulator(
|
||||
block_reason = f"the pack holds {owner}'s {other_dest} at this path"
|
||||
elif not block and packed is not None:
|
||||
occupy(dest, packed, emu_name)
|
||||
packed_dests.add(dest)
|
||||
for result, required, hle in alternatives:
|
||||
if block_reason and result["status"] != Status.MISSING:
|
||||
result["status"] = Status.MISSING
|
||||
@@ -2226,9 +2240,7 @@ def verify_emulator(
|
||||
"total_files": total,
|
||||
# The paths the emulator pack fills with the profile's files, for the
|
||||
# pipeline's comparison with the pack built in memory.
|
||||
"pack_destinations": sorted(
|
||||
dest for dest, status in file_status.items() if status == Status.OK
|
||||
),
|
||||
"pack_destinations": sorted(packed_dests),
|
||||
"severity_counts": counts,
|
||||
"status_counts": status_counts,
|
||||
"details": details,
|
||||
|
||||
@@ -52,6 +52,23 @@ def _db(path: Path, name: str) -> dict:
|
||||
}
|
||||
|
||||
|
||||
def _pack_files(root: Path, emulators: Path, db: dict) -> set[str]:
|
||||
"""The paths the emulator pack writes, built in memory as the pipeline does."""
|
||||
import generate_pack
|
||||
|
||||
record = generate_pack.PackRecord()
|
||||
cwd = os.getcwd()
|
||||
os.chdir(root)
|
||||
try:
|
||||
generate_pack.generate_emulator_pack(
|
||||
["demo"], str(emulators), db, "bios", "", False, {}, offline=True,
|
||||
record=record,
|
||||
)
|
||||
finally:
|
||||
os.chdir(cwd)
|
||||
return set(record.files)
|
||||
|
||||
|
||||
class HashMismatchIsNotCoverage(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self._tmp = tempfile.TemporaryDirectory()
|
||||
@@ -113,6 +130,17 @@ class HashMismatchIsNotCoverage(unittest.TestCase):
|
||||
self.assertIn("reason", detail)
|
||||
self.assertIn("hash", detail["reason"].lower())
|
||||
|
||||
def test_the_contradicted_copy_the_pack_writes_is_a_pack_destination(self):
|
||||
"""The pack writes it with a DISCREPANCY, so verify's list of what
|
||||
the pack holds names it too: step 5 compared the two and failed."""
|
||||
self._profile("f" * 32)
|
||||
result = self._run()
|
||||
self.assertEqual(result["pack_destinations"], ["shared.rom"])
|
||||
self.assertEqual(
|
||||
set(result["pack_destinations"]),
|
||||
_pack_files(self.root, self.emulators, self.db),
|
||||
)
|
||||
|
||||
def test_a_matching_hash_is_still_ok(self):
|
||||
self._profile(hashlib.md5(self.rom.read_bytes()).hexdigest())
|
||||
detail = next(
|
||||
@@ -230,6 +258,15 @@ class ArchiveHashMismatchIsNotCoverage(unittest.TestCase):
|
||||
"an archive whose bytes contradict its declared hash counted as covered",
|
||||
)
|
||||
|
||||
def test_the_contradicted_archive_the_pack_writes_is_a_pack_destination(self):
|
||||
self._profile("f" * 32)
|
||||
result = self._run()
|
||||
self.assertEqual(result["pack_destinations"], ["romset.zip"])
|
||||
self.assertEqual(
|
||||
set(result["pack_destinations"]),
|
||||
_pack_files(self.root, self.emulators, self.db),
|
||||
)
|
||||
|
||||
def test_a_matching_container_hash_is_still_ok(self):
|
||||
self._profile(hashlib.md5(self.archive.read_bytes()).hexdigest())
|
||||
self.assertEqual(set(self._statuses(self._run())), {verify.Status.OK})
|
||||
|
||||
Reference in new issue
Block a user