Files
libretro/tests/test_verify_pack_choice.py
T
Abdessamad Derraz a6eda07b8a fix: end --verify-packs on a summary line
The check ended on the last platform's line: a failing pack was named only above its own errors. It now names every failing pack on stderr at the end, as the build path does, or counts the packs found OK.
2026-10-21 10:06:52 +02:00

187 lines
7.1 KiB
Python

"""--verify-packs opens the pack the flags name, by its exact file name.
The check took the first sorted *_BIOS_Pack.zip whose name contained the
platform name. With a full and a regional pack side by side, --region us
judged the full pack against the regional expectation and never opened the
regional one. A pack built with --source truth answered SKIP and exit 0.
"""
from __future__ import annotations
import argparse
import json
import os
import sys
import tempfile
import unittest
from pathlib import Path
from unittest import mock
REPO_ROOT = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(REPO_ROOT / "scripts"))
def _ok_result() -> tuple:
return (True, 0, 0, [], 1, 1, 1, 1, 0)
class VerifyPackChoice(unittest.TestCase):
def setUp(self):
import generate_pack
self.gp = generate_pack
previous = os.getcwd()
os.chdir(REPO_ROOT)
self.addCleanup(os.chdir, previous)
self.tmp = tempfile.TemporaryDirectory(dir=REPO_ROOT / "tmp")
self.addCleanup(self.tmp.cleanup)
self.out = Path(self.tmp.name)
self.db = self.out / "db.json"
self.db.write_text(json.dumps({"files": {}}))
self.stem = generate_pack._platform_pack_stem(
["retroarch"], "retroarch", "platforms"
)
def _args(self, **overrides) -> argparse.Namespace:
values = {
"db": str(self.db),
"platform": "retroarch",
"all": False,
"include_archived": False,
"emulators_dir": "emulators",
"platforms_dir": "platforms",
"output_dir": str(self.out),
"target": None,
"regions": [],
"all_variants": False,
}
values.update(overrides)
return argparse.Namespace(**values)
def _run(self, args) -> list[str]:
checked: list[str] = []
def record(zip_path, platform_name, *a, **kw):
checked.append((platform_name, os.path.basename(zip_path)))
return _ok_result()
with mock.patch.object(self.gp, "verify_pack_against_platform", record):
self.gp._run_verify_packs(args)
return checked
def _touch(self, name: str) -> None:
(self.out / name).write_bytes(b"")
def test_region_opens_the_regional_pack(self):
import region as region_mod
regions = region_mod.parse_requested("us")
tag = self.gp._narrowings("full", regions, None, False, False)[0][0]
self._touch(f"{self.stem}_BIOS_Pack.zip")
self._touch(f"{self.stem}{tag}_BIOS_Pack.zip")
checked = self._run(self._args(regions=regions))
self.assertEqual(checked, [("retroarch", f"{self.stem}{tag}_BIOS_Pack.zip")])
def test_unnarrowed_check_ignores_the_regional_pack(self):
self._touch(f"{self.stem}_AsiaPacific_BIOS_Pack.zip")
self._touch(f"{self.stem}_BIOS_Pack.zip")
checked = self._run(self._args())
self.assertEqual(checked, [("retroarch", f"{self.stem}_BIOS_Pack.zip")])
def test_named_platform_with_only_a_narrowed_pack_fails(self):
self._touch(f"{self.stem}_Truth_BIOS_Pack.zip")
with self.assertRaises(SystemExit) as ctx:
self._run(self._args())
self.assertEqual(ctx.exception.code, 1)
def test_all_variants_names_every_variant_it_built(self):
"""After --all-variants the check opened the full pack only: the five
narrowed packs the same run wrote passed without a line."""
import contextlib
import io
names = []
for source, required in self.gp.ALL_VARIANTS:
tags = "".join(
tag for tag, _ in self.gp._narrowings(source, None, None, False, required)
)
names.append(f"{self.stem}{tags}_BIOS_Pack.zip")
self._touch(names[-1])
out = io.StringIO()
with contextlib.redirect_stdout(out):
checked = self._run(self._args(all_variants=True))
self.assertEqual(checked, [("retroarch", f"{self.stem}_BIOS_Pack.zip")])
printed = out.getvalue()
for name in names[1:]:
self.assertIn(f"[{name}]: hashes checked during the build", printed)
def test_the_run_ends_on_a_summary(self):
"""A failing pack was named only above its own error lines, and the
log ended on the last platform's OK line."""
import contextlib
import io
pack = f"{self.stem}_BIOS_Pack.zip"
self._touch(pack)
out, err = io.StringIO(), io.StringIO()
failed = (False, 0, 0, ["x: missing"], 1, 0, 1, 1, 0)
with mock.patch.object(self.gp, "verify_pack_against_platform",
return_value=failed), \
contextlib.redirect_stdout(out), contextlib.redirect_stderr(err), \
self.assertRaises(SystemExit):
self.gp._run_verify_packs(self._args())
self.assertEqual(
err.getvalue().strip().splitlines()[-1],
f"ERROR: packs failed verification: retroarch ({pack})",
)
out = io.StringIO()
with contextlib.redirect_stdout(out):
self._run(self._args())
self.assertEqual(out.getvalue().strip().splitlines()[-1], "Verified 1 pack: all OK")
def test_include_archived_reaches_the_archived_pack(self):
stem = self.gp._platform_pack_stem(["retropie"], "retropie", "platforms")
self._touch(f"{stem}_BIOS_Pack.zip")
checked = self._run(
self._args(platform=None, all=True, include_archived=True)
)
self.assertIn(("retropie", f"{stem}_BIOS_Pack.zip"), checked)
class GroupRenameKeepsSystemTag(unittest.TestCase):
def test_single_system_pack_does_not_take_the_full_name(self):
import generate_pack as gp
previous = os.getcwd()
os.chdir(REPO_ROOT)
self.addCleanup(os.chdir, previous)
with tempfile.TemporaryDirectory(dir=REPO_ROOT / "tmp") as tmp:
def fake_generate(*a, pack_name=None, **kw):
# The group's name is handed in: nothing is renamed afterwards.
built = Path(tmp) / (
pack_name or f"RetroArch_x_BIOS_Pack{gp._system_tag(['atari-lynx'])}.zip"
)
built.write_bytes(b"")
return str(built)
args = argparse.Namespace(
all_variants=False, source="full", required_only=False,
platforms_dir="platforms", target=None, split=False,
emulators_dir="emulators", regions=[],
one_per_slot=False, offline=True, bios_dir="bios",
output_dir=tmp,
)
with mock.patch.object(gp, "generate_pack", fake_generate), \
mock.patch.object(gp, "verify_and_finalize_packs", return_value=True):
gp._run_platform_packs(
args, [(["retroarch", "lakka"], "retroarch")], {}, {}, {},
{}, {}, ["atari-lynx"],
)
names = os.listdir(tmp)
stem = gp._platform_pack_stem(["retroarch", "lakka"], "retroarch", "platforms")
self.assertEqual(names, [f"{stem}_BIOS_Pack_Lynx.zip"])
if __name__ == "__main__":
unittest.main()