mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-10-11 14:03:23 -05:00
118 lines
4.7 KiB
Python
118 lines
4.7 KiB
Python
"""A custom pack built from hashes follows the emulator it names, or refuses.
|
|
|
|
`--from-md5 --emulator` accepted any name: an unknown one produced a generic
|
|
pack in the layout of no emulator, rc 0, where `--emulator` alone refuses it.
|
|
With a known one and `--standalone`, a profile without pack_structure kept
|
|
the bare file names under a pack called Standalone.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
import subprocess
|
|
import sys
|
|
import tempfile
|
|
import unittest
|
|
import zipfile
|
|
from pathlib import Path
|
|
|
|
REPO_ROOT = Path(__file__).resolve().parent.parent
|
|
|
|
|
|
def _pack(*options: str) -> tuple[subprocess.CompletedProcess, list[str]]:
|
|
with tempfile.TemporaryDirectory(dir=REPO_ROOT / "tmp") as out:
|
|
proc = subprocess.run(
|
|
[sys.executable, "scripts/generate_pack.py", *options, "--offline",
|
|
"--output-dir", out],
|
|
cwd=REPO_ROOT, capture_output=True, text=True, timeout=600, check=False,
|
|
)
|
|
names = []
|
|
for archive in Path(out).glob("*.zip"):
|
|
with zipfile.ZipFile(archive) as zf:
|
|
names.extend(zf.namelist())
|
|
return proc, names
|
|
|
|
|
|
class TheEmulatorContextIsChecked(unittest.TestCase):
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
db_path = REPO_ROOT / "database.json"
|
|
if not db_path.exists():
|
|
raise unittest.SkipTest("database.json is not built")
|
|
(REPO_ROOT / "tmp").mkdir(exist_ok=True)
|
|
cls.db = json.loads(db_path.read_text(encoding="utf-8"))
|
|
|
|
def test_an_unknown_emulator_is_refused(self):
|
|
md5 = next(iter(self.db["files"].values()))["md5"]
|
|
proc, names = _pack("--from-md5", md5, "--emulator", "no_such_core")
|
|
self.assertNotEqual(proc.returncode, 0, proc.stdout)
|
|
self.assertIn("not found", proc.stderr)
|
|
self.assertEqual(names, [])
|
|
|
|
|
|
def test_the_standalone_layout_reaches_a_profile_without_structure(self):
|
|
"""BBKEmu has no pack_structure; its A4980 8.BIN goes to
|
|
system/BBKEmu/A4980/ standalone. The hash pack kept the bare name,
|
|
then, once laid out, sent it to the A4988 folder whose entry shares
|
|
the name."""
|
|
md5 = "ddfc001a6859d63ed46368ea7fe9f20c"
|
|
if not any(record.get("md5") == md5 for record in self.db["files"].values()):
|
|
self.skipTest("the A4980 8.BIN is not collected")
|
|
proc, names = _pack("--from-md5", md5, "--emulator", "bbkemu", "--standalone")
|
|
self.assertEqual(proc.returncode, 0, proc.stderr)
|
|
self.assertEqual(names, ["system/BBKEmu/A4980/8.BIN"])
|
|
|
|
|
|
class SystemAndEmulatorPacksKeepTheirNames(unittest.TestCase):
|
|
"""`--system sega-triforce` and `--emulator triforce` both wrote
|
|
Triforce_BIOS_Pack.zip: whichever ran second replaced the other."""
|
|
|
|
def test_the_two_selections_write_two_files(self):
|
|
import hashlib
|
|
|
|
import yaml
|
|
|
|
sys.path.insert(0, str(REPO_ROOT / "scripts"))
|
|
import common
|
|
import generate_db
|
|
import generate_pack as gp
|
|
|
|
with tempfile.TemporaryDirectory(dir=REPO_ROOT / "tmp") as directory:
|
|
root = Path(directory)
|
|
(root / "bios").mkdir()
|
|
(root / "emulators").mkdir()
|
|
out = root / "dist"
|
|
payload = b"triforce bios"
|
|
(root / "bios" / "segaboot.gcm").write_bytes(payload)
|
|
sha1 = hashlib.sha1(payload).hexdigest()
|
|
files = {sha1: {
|
|
"path": str(root / "bios" / "segaboot.gcm"), "name": "segaboot.gcm",
|
|
"size": len(payload), "sha1": sha1,
|
|
"md5": hashlib.md5(payload).hexdigest(),
|
|
"sha256": hashlib.sha256(payload).hexdigest(), "crc32": "0",
|
|
}}
|
|
db = {"files": files, "indexes": generate_db.build_indexes(files, {})}
|
|
(root / "emulators" / "triforce.yml").write_text(yaml.dump({
|
|
"emulator": "Triforce", "type": "libretro", "cores": ["triforce"],
|
|
"systems": ["sega-triforce"],
|
|
"files": [{"name": "segaboot.gcm", "required": True}],
|
|
}))
|
|
common._emulator_profiles_cache.clear()
|
|
try:
|
|
emulator_pack = gp.generate_emulator_pack(
|
|
["triforce"], str(root / "emulators"), db, str(root / "bios"),
|
|
str(out), offline=True,
|
|
)
|
|
system_pack = gp.generate_system_pack(
|
|
["sega-triforce"], str(root / "emulators"), db,
|
|
str(root / "bios"), str(out), offline=True,
|
|
)
|
|
finally:
|
|
common._emulator_profiles_cache.clear()
|
|
self.assertNotEqual(Path(emulator_pack).name, Path(system_pack).name)
|
|
self.assertTrue(Path(emulator_pack).exists())
|
|
self.assertTrue(Path(system_pack).exists())
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|