fix: count a core's release asset as packed

verify replayed the core extras offline: a release asset an online
build fetched and packed took no path in its report (finding 2).
This commit is contained in:
Abdessamad Derraz committed 2026-11-05 11:55:53 +01:00
1 parent 71020c3974
commit dde6229775
3 files changed
+68 -2

No files matched your search

+14 -1
View File
@@ -244,6 +244,7 @@ class ExtraResolver:
offline: bool | None = True,
*,
profiles: dict,
pending_assets: bool = False,
) -> None:
self.profiles = profiles
self.db = db
@@ -253,10 +254,13 @@ class ExtraResolver:
self.validation_index = validation_index
self.validation_owners = validation_owners
self.offline = offline
# verify's replay: never downloads, and counts the release asset an
# online build fetches, as it does for a platform entry.
self.pending_assets = pending_assets
def resolve(self, fe: dict, dest: str) -> tuple[str | None, str, str]:
"""(local copy or None, resolver status, the core's disagreement)."""
from packresolve import resolve_file
from packresolve import pending_release_asset, resolve_file, run_is_offline
from validation import core_size_refusal, extra_alternatives, validated_choice
local_path, status = resolve_file(
@@ -264,6 +268,15 @@ class ExtraResolver:
dest_hint=fe.get("destination", ""),
data_dir_registry=self.data_registry, offline=self.offline,
)
if (
self.pending_assets and status in ("not_found", "hash_mismatch")
and not run_is_offline()
):
# The asset the online builder fetches in resolve_file. Its record
# answers the declaration, and there are no bytes on disk to check.
asset = pending_release_asset(fe, self.db)
if asset:
return asset, "release_asset", ""
if status in ("not_found", "external", "user_provided") or not local_path:
return None, status, ""
local_path, disagreement = validated_choice(
+1 -1
View File
@@ -1463,7 +1463,7 @@ def verify_platform(
region_drops, report_for_builder,
ExtraResolver(
db, DEFAULT_BIOS_DIR, zip_contents, data_dir_registry, validation_index,
validation_owners, profiles=profiles,
validation_owners, profiles=profiles, pending_assets=True,
),
placed_kind,
system_filter,
+53
View File
@@ -123,6 +123,59 @@ class ReleaseAssetNotCachedMd5(ReleaseAssetNotCached):
mode = "md5"
class CoreExtraReleaseAssetNotCached(ReleaseAssetNotCached):
"""The same asset read by a core and declared by no platform entry: the
builder fetched and packed it online, verify's replay of the extras
resolved it offline and left its path out of the pack."""
def setUp(self):
super().setUp()
self.config["systems"]["sys"]["files"] = []
self.config["cores"] = ["bigcore"]
Path("platforms/big.yml").write_text(yaml.dump(self.config))
self.profiles = {"bigcore": {
"emulator": "Big Core", "type": "libretro", "systems": ["sys"],
"files": [{"name": "big.bin", "required": True, "sha1": SHA1}],
}}
Path("emulators/bigcore.yml").write_text(yaml.dump(self.profiles["bigcore"]))
common._platform_config_cache.clear()
common._emulator_profiles_cache.clear()
def _report(self) -> dict:
return verify_platform(self.config, self.db, "emulators", self.profiles)
def test_counted_as_fetched_when_the_pack_is_built(self):
report = self._report()
self.assertIn("big.bin", report["pack_destinations"])
self.assertEqual(report["packed_extras"]["bios"], 1)
def test_its_path_is_a_pack_destination(self):
cache = Path("cache/big.bin")
cache.parent.mkdir()
cache.write_bytes(PAYLOAD)
with mock.patch.object(
packresolve, "fetch_large_file", return_value=str(cache)
):
zip_path = builder.generate_pack(
"big", "platforms", self.db, "bios", "out",
emulators_dir="emulators", emu_profiles=self.profiles, offline=False,
)
with zipfile.ZipFile(zip_path) as zf:
packed = {n for n in zf.namelist() if not n.endswith("/")}
self.assertIn("big.bin", packed)
self.assertIn("big.bin", self._report()["pack_destinations"])
def test_offline_counts_it_missing(self):
packresolve.set_offline(True)
self.assertNotIn("big.bin", self._report()["pack_destinations"])
def test_an_asset_with_other_content_is_not_counted(self):
self.profiles["bigcore"]["files"][0]["sha1"] = "0" * 40
self.assertNotIn("big.bin", self._report()["pack_destinations"])
test_the_online_build_packs_it = None
class OfflinePipelineVerifiesOffline(unittest.TestCase):
"""The offline pipeline builds packs without release assets: its verify
step has to count them the same way, or step 5 compares two answers."""