mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-11-11 12:33:53 -06:00
tests/__init__.py keeps a run offline, its scratch under tmp/ and its installer cache its own, but only discover -s tests -t . imported it. discover tests ran with RETROBIOS_OFFLINE unset, scratch on the /tmp tmpfs and the user's real installer cache, the setting in which e2e fixtures had written into the shared .cache/large. Every test module now imports the package first, and a test fails on a module that does not. test_verify_listing.py took its line with the previous commit.
269 lines
12 KiB
Python
269 lines
12 KiB
Python
"""EmuELEC's images differ by device, and only its metapackage says how.
|
|
|
|
packages/sx05re/emuelec/package.mk (v4.8) builds the S922X cores, Dolphin
|
|
and the MAME core only on Amlogic-ng, Amlogic-no, RK356x and OdroidM1, and
|
|
takes DuckStation out on the two handhelds with a sed that replaces the
|
|
first match only. With no target list, an OdroidGoAdvance pack carried the
|
|
firmware of cores its image never had.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import tests # noqa: F401 offline, scratch under tmp/, the suite's own cache
|
|
|
|
import json
|
|
import sys
|
|
import unittest
|
|
from pathlib import Path
|
|
|
|
REPO_ROOT = Path(__file__).resolve().parents[1]
|
|
sys.path.insert(0, str(REPO_ROOT / "scripts"))
|
|
|
|
from scraper.targets import emuelec_targets_scraper as scraper # noqa: E402
|
|
|
|
# packages/sx05re/emuelec/package.mk:8-77 at v4.8, PKG_EMUS and
|
|
# PKG_EXPERIMENTAL shortened.
|
|
PACKAGE_MK = """PKG_DEPENDS_TARGET="toolchain ${OPENGLES} emuelec-emulationstation retroarch"
|
|
PKG_EXPERIMENTAL="nestopiaCV quasi88 yabasanshiroSA_1_11 yabasanshiroSA_1_5 fbneoSA"
|
|
PKG_EMUS="${LIBRETRO_CORES} advancemame duckstation pcsx_rearmed flycastsa"
|
|
PKG_DEPENDS_TARGET+=" emuelec-tools ${PKG_EMUS} ${PKG_EXPERIMENTAL}"
|
|
|
|
if [ "${DEVICE}" == "Amlogic-ng" ] || [ "${DEVICE}" == "Amlogic-no" ] || [ "${DEVICE}" == "RK356x" ] || [ "${DEVICE}" == "OdroidM1" ]; then
|
|
\tPKG_DEPENDS_TARGET+=" ${LIBRETRO_S922X_CORES}"
|
|
fi
|
|
|
|
if [ "${DEVICE}" == "OdroidGoAdvance" ] || [ "${DEVICE}" == "GameForce" ]; then
|
|
\tPKG_DEPENDS_TARGET+=" kmscon odroidgoa-utils"
|
|
\tfor discore in duckstation mesen-s virtualjaguar quicknes MC; do
|
|
\t\tPKG_DEPENDS_TARGET=$(echo ${PKG_DEPENDS_TARGET} | sed "s|${discore} | |")
|
|
\tdone
|
|
\tPKG_DEPENDS_TARGET+=" yabasanshiro"
|
|
else
|
|
\tPKG_DEPENDS_TARGET+=" fbterm"
|
|
fi
|
|
|
|
if [ "${ARCH}" == "aarch64" ]; then
|
|
for discore in quicknes parallel-n64 pcsx_rearmed; do
|
|
\t\tPKG_DEPENDS_TARGET=$(echo ${PKG_DEPENDS_TARGET} | sed "s|${discore}| |")
|
|
\tdone
|
|
|
|
PKG_DEPENDS_TARGET+=" swanstation \\
|
|
lib32-essential \\
|
|
lib32-pcsx_rearmed \\
|
|
lib32-parallel-n64
|
|
lib32-libusb"
|
|
|
|
if [ "${DEVICE}" == "Amlogic-ng" ] || [ "${DEVICE}" == "Amlogic-no" ] || [ "${DEVICE}" == "RK356x" ] || [ "${DEVICE}" == "OdroidM1" ]; then
|
|
PKG_DEPENDS_TARGET+=" dolphinSA"
|
|
fi
|
|
|
|
if [ "${DEVICE}" == "Amlogic-old" ]; then
|
|
for discore in yabasanshiroSA_1_11 yabasanshiroSA_1_5 yabasanshiro same_cdi duckstation; do
|
|
PKG_DEPENDS_TARGET=$(echo ${PKG_DEPENDS_TARGET} | sed "s|${discore} | |")
|
|
done
|
|
fi
|
|
fi
|
|
|
|
if [ "${DEVICE}" == "Amlogic-ng" ] || [ "${DEVICE}" == "Amlogic-no" ] || [ "${DEVICE}" == "RK356x" ] || [ "${DEVICE}" == "OdroidM1" ]; then
|
|
\tPKG_DEPENDS_TARGET+=" mame"
|
|
fi
|
|
|
|
if [ "${DEVICE}" == "RK356x" ] || [ "${DEVICE}" == "OdroidM1" ]; then
|
|
for discore in flycast-dojo; do
|
|
\t\tPKG_DEPENDS_TARGET=$(echo ${PKG_DEPENDS_TARGET} | sed "s|${discore}| |")
|
|
\tdone
|
|
fi
|
|
"""
|
|
|
|
# distributions/EmuELEC/options:274-373 at v4.8, shortened.
|
|
OPTIONS = """LIBRETRO_CORES="mgba \\
|
|
parallel-n64 \\
|
|
pcsx_rearmed \\
|
|
flycast"
|
|
|
|
LIBRETRO_S922X_CORES="beetle-saturn \\
|
|
mesen \\
|
|
quicknes \\
|
|
virtualjaguar"
|
|
"""
|
|
|
|
# packages/sx05re/emuelec-emulationstation/package.mk:114-143 at v4.8.
|
|
ES_MK = """CORESFILE="${INSTALL}/usr/config/emulationstation/es_systems.cfg"
|
|
|
|
if [[ "${DEVICE}" != "Amlogic-ng" || "${DEVICE}" != "Amlogic-ne" || "${DEVICE}" != "Amlogic-no" ]]; then
|
|
if [[ ${DEVICE} == "OdroidGoAdvance" || "${DEVICE}" == "GameForce" ]]; then
|
|
remove_cores="mesen-s quicknes mame2016 mesen"
|
|
elif [ "${DEVICE}" == "Amlogic-old" ]; then
|
|
remove_cores="mesen-s quicknes mame2016 mesen yabasanshiroSA yabasanshiro"
|
|
xmlstarlet ed -L -P -d "/systemList/system[name='saturn']" ${CORESFILE}
|
|
xmlstarlet ed -L -P -d "/systemList/system[name='phillips-cdi']" ${CORESFILE}
|
|
xmlstarlet ed -L -P -d "/systemList/system/emulators/emulator[@name='Duckstation']" ${CORESFILE}
|
|
fi
|
|
for discore in ${remove_cores}; do
|
|
sed -i "s|<core>${discore}</core>||g" ${CORESFILE}
|
|
sed -i '/^[[:space:]]*$/d' ${CORESFILE}
|
|
done
|
|
fi
|
|
|
|
if [[ ${DEVICE} != "OdroidGoAdvance" ]] && [[ "${DEVICE}" != "GameForce" ]]; then
|
|
\txmlstarlet ed -L -P -d "/systemList/system/emulators/emulator[@name='retrorun']" ${CORESFILE}
|
|
else
|
|
\txmlstarlet ed -L -P -d "/systemList/system/emulators/emulator[@name='Duckstation']" ${CORESFILE}
|
|
fi
|
|
"""
|
|
|
|
|
|
def _system(name: str, *emulators: tuple[str, list[dict]]) -> dict:
|
|
return {"name": name, "emulators": [{"name": e, "cores": c} for e, c in emulators]}
|
|
|
|
|
|
ES_JSON = json.dumps({"systems": [
|
|
_system("nes", ("libretro", [{"name": "mesen", "default": True}])),
|
|
_system("snes", ("libretro", [{"name": "snes9x", "default": True}, {"name": "mesen-s"}])),
|
|
_system("psx",
|
|
("libretro", [{"name": "pcsx_rearmed", "default": True},
|
|
{"name": "pcsx_rearmed_32b"}, {"name": "swanstation"}]),
|
|
("Duckstation", [{"name": "Duckstation"}]),
|
|
("retrorun", [{"name": "pcsx_rearmed_32b"}])),
|
|
_system("n64", ("libretro", [{"name": "parallel_n64_32b"}])),
|
|
]})
|
|
|
|
ARCHS = {"mesen": "", "duckstation": "aarch64", "pcsx_rearmed": "any",
|
|
"lib32-pcsx_rearmed": "aarch64", "swanstation": "any",
|
|
"lib32-parallel-n64": "aarch64"}
|
|
|
|
ASSETS = [
|
|
"EmuELEC-Amlogic-ng.aarch64-4.8-Generic.img.gz",
|
|
"EmuELEC-Amlogic-ng.aarch64-4.8.tar",
|
|
"EmuELEC-GameForce.aarch64-4.8-chi.img.gz.sha256",
|
|
"EmuELEC-OdroidGoAdvance.aarch64-4.8-odroidgo2.tar",
|
|
"EmuELEC-OdroidM1.aarch64-4.8.img.gz",
|
|
]
|
|
|
|
|
|
class TheMetapackageDecidesEachDevice(unittest.TestCase):
|
|
def setUp(self):
|
|
self.meta = scraper.read_metapackage(PACKAGE_MK, OPTIONS)
|
|
|
|
def test_devices_are_the_images_the_release_publishes(self):
|
|
self.assertEqual(scraper.release_devices(ASSETS), {
|
|
"Amlogic-ng": "aarch64", "GameForce": "aarch64",
|
|
"OdroidGoAdvance": "aarch64", "OdroidM1": "aarch64",
|
|
})
|
|
|
|
def test_the_lists_the_rules_work_on(self):
|
|
self.assertEqual(self.meta.emus, ["mgba", "parallel-n64", "pcsx_rearmed", "flycast",
|
|
"advancemame", "duckstation", "pcsx_rearmed",
|
|
"flycastsa"])
|
|
self.assertEqual(self.meta.lib32, ["swanstation", "lib32-essential",
|
|
"lib32-pcsx_rearmed", "lib32-parallel-n64",
|
|
"lib32-libusb"])
|
|
|
|
def test_the_big_devices_build_the_s922x_cores_dolphin_and_mame(self):
|
|
packages = scraper.device_packages(self.meta, "Amlogic-ng", "aarch64")
|
|
for package in ("beetle-saturn", "mesen", "virtualjaguar", "dolphinSA", "mame",
|
|
"duckstation", "fbterm"):
|
|
self.assertIn(package, packages)
|
|
# quicknes is added, then the aarch64 loop takes it out.
|
|
self.assertNotIn("quicknes", packages)
|
|
|
|
def test_the_handhelds_lose_duckstation_and_gain_their_tools(self):
|
|
packages = scraper.device_packages(self.meta, "OdroidGoAdvance", "aarch64")
|
|
for package in ("duckstation", "mesen", "beetle-saturn", "dolphinSA", "mame", "fbterm"):
|
|
self.assertNotIn(package, packages)
|
|
self.assertEqual(packages[-1:], ["lib32-libusb"])
|
|
self.assertIn("kmscon", packages)
|
|
self.assertIn("yabasanshiro", packages)
|
|
|
|
def test_sed_takes_out_the_first_match_only(self):
|
|
# pcsx_rearmed is written twice, in LIBRETRO_CORES and in PKG_EMUS:
|
|
# the aarch64 loop removes the first and the 64-bit core is built.
|
|
for device in ("Amlogic-ng", "OdroidGoAdvance"):
|
|
packages = scraper.device_packages(self.meta, device, "aarch64")
|
|
self.assertEqual(packages.count("pcsx_rearmed"), 1, device)
|
|
self.assertNotIn("parallel-n64", packages, device)
|
|
|
|
def test_a_pattern_with_a_trailing_space_misses_the_last_word(self):
|
|
self.assertEqual(scraper._sed_first("a duckstation", "duckstation "), "a duckstation")
|
|
self.assertEqual(scraper._sed_first("a duckstation b", "duckstation "), "a b")
|
|
# Without the space, the pattern takes a word's tail too.
|
|
self.assertEqual(scraper._sed_first("lib32-pcsx_rearmed", "pcsx_rearmed"), "lib32- ")
|
|
|
|
def test_a_changed_rule_stops_the_scrape(self):
|
|
changed = PACKAGE_MK.replace("duckstation mesen-s virtualjaguar quicknes MC",
|
|
"duckstation mesen-s")
|
|
with self.assertRaises(RuntimeError):
|
|
scraper.read_metapackage(changed, OPTIONS)
|
|
|
|
|
|
class EachPackageBuildsWhereItsArchAllows(unittest.TestCase):
|
|
def test_pkg_arch(self):
|
|
self.assertTrue(scraper.arch_builds("", "aarch64"))
|
|
self.assertTrue(scraper.arch_builds("any", "aarch64"))
|
|
self.assertTrue(scraper.arch_builds("aarch64 arm", "aarch64"))
|
|
# mupen64plus and uae4arm say PKG_ARCH="arm": skipped on aarch64.
|
|
self.assertFalse(scraper.arch_builds("arm", "aarch64"))
|
|
self.assertFalse(scraper.arch_builds("any !aarch64", "aarch64"))
|
|
|
|
def test_every_cited_install_line_is_read(self):
|
|
install = scraper.PROVIDERS["mgba"][0]
|
|
text = f'PKG_ARCH="any"\nmakeinstall_target() {{\n {install.line}\n}}\n'
|
|
with self.assertRaises(RuntimeError):
|
|
scraper._require(text.replace("mgba_libretro", "mgba2_libretro"),
|
|
(install.line,), install.path)
|
|
scraper._require(text, (install.line,), install.path)
|
|
|
|
|
|
class TheFrontendOffersWhatTheDeviceKeeps(unittest.TestCase):
|
|
def test_handhelds_drop_bare_cores_and_duckstation(self):
|
|
systems = scraper.es_systems_for(ES_JSON, ES_MK, "GameForce")
|
|
# mesen is the nes default: written with an attribute, sed misses it.
|
|
self.assertEqual(systems["nes"], [("libretro", ["mesen"])])
|
|
self.assertEqual(systems["snes"], [("libretro", ["snes9x"])])
|
|
self.assertEqual([e for e, _ in systems["psx"]], ["libretro", "retrorun"])
|
|
|
|
def test_other_devices_drop_retrorun(self):
|
|
systems = scraper.es_systems_for(ES_JSON, ES_MK, "Amlogic-ng")
|
|
self.assertEqual([e for e, _ in systems["psx"]], ["libretro", "Duckstation"])
|
|
self.assertEqual(systems["snes"], [("libretro", ["snes9x", "mesen-s"])])
|
|
|
|
def test_a_device_keeps_what_it_builds_and_offers(self):
|
|
meta = scraper.read_metapackage(PACKAGE_MK, OPTIONS)
|
|
archs = {**dict.fromkeys(scraper.PROVIDERS, "any"), **ARCHS}
|
|
cores = {}
|
|
for device in ("Amlogic-ng", "OdroidGoAdvance"):
|
|
packages = [p for p in scraper.device_packages(meta, device, "aarch64")
|
|
if p in scraper.PROVIDERS or p in scraper.NO_ES_CORE]
|
|
systems = scraper.es_systems_for(ES_JSON, ES_MK, device)
|
|
cores[device] = scraper.device_cores(packages, "aarch64", archs, systems)
|
|
self.assertEqual(cores["Amlogic-ng"], ["Duckstation", "mesen", "parallel_n64_32b",
|
|
"pcsx_rearmed", "pcsx_rearmed_32b",
|
|
"swanstation"])
|
|
self.assertEqual(cores["OdroidGoAdvance"], ["parallel_n64_32b", "pcsx_rearmed",
|
|
"pcsx_rearmed_32b", "swanstation"])
|
|
|
|
def test_a_package_never_read_stops_the_scrape(self):
|
|
archs = dict.fromkeys(scraper.PROVIDERS, "any")
|
|
with self.assertRaises(RuntimeError):
|
|
scraper.device_cores(["mgba", "newcore"], "aarch64", archs, {})
|
|
|
|
|
|
class TheCommittedListFollowsTheRules(unittest.TestCase):
|
|
def test_the_handhelds_list_no_core_they_do_not_build(self):
|
|
import yaml # noqa: PLC0415
|
|
|
|
targets = yaml.safe_load((REPO_ROOT / "platforms" / "targets" / "emuelec.yml")
|
|
.read_text(encoding="utf-8"))["targets"]
|
|
self.assertEqual(set(targets), {"amlogic-ng", "gameforce", "odroidgoadvance", "odroidm1"})
|
|
big = set(targets["amlogic-ng"]["cores"])
|
|
for device in ("gameforce", "odroidgoadvance"):
|
|
self.assertEqual(big - set(targets[device]["cores"]), {
|
|
"Duckstation", "dolphin", "mame", "mednafen_saturn", "mesen", "mesen-s",
|
|
"virtualjaguar",
|
|
})
|
|
self.assertEqual(targets["odroidm1"]["cores"], targets["amlogic-ng"]["cores"])
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|