tests: register every offline-tool unit test and make the registration guard scan tools/ and tests/

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Matthew Stanley
2026-09-26 07:36:33 -07:00
parent 199cfe01bc
commit ab5d63e1f1
4 changed files with 95 additions and 8 deletions
+54 -6
View File
@@ -619,12 +619,16 @@ if(BUILD_TESTING)
COMMAND ${Python3_EXECUTABLE}
${CMAKE_CURRENT_SOURCE_DIR}/../tools/tests/test_overlay_guard_bytes_declaration.py
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/..)
if(Python3_VERSION VERSION_GREATER_EQUAL "3.11")
add_test(
NAME aot_overlay_methods
COMMAND ${Python3_EXECUTABLE}
${CMAKE_CURRENT_SOURCE_DIR}/../tools/tests/test_aot_overlay_pipeline.py
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/..)
# The pipeline reads mod manifests with tomllib (Python 3.11+). An
# older interpreter keeps the test registered but DISABLED, so it is
# reported as not run instead of silently missing from `ctest -N`.
add_test(
NAME aot_overlay_methods
COMMAND ${Python3_EXECUTABLE}
${CMAKE_CURRENT_SOURCE_DIR}/../tools/tests/test_aot_overlay_pipeline.py
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/..)
if(Python3_VERSION VERSION_LESS "3.11")
set_tests_properties(aot_overlay_methods PROPERTIES DISABLED TRUE)
endif()
# --static must walk the whole of compile_overlays.main() and exit 0:
# a DLL-only reconciliation at its tail once read an unbound cache_dir
@@ -692,6 +696,50 @@ if(BUILD_TESTING)
${CMAKE_CURRENT_SOURCE_DIR}/../tools/tests/test_stall_report.py
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/..)
# ---- offline tool unit tests (tools/tests, tools/, tests/) -----------
# Pure-Python unit tests of the offline tools: no built target and no
# generated BIOS, so they belong in this BIOS-free tree. They had no
# add_test() entry and were only run by whoever remembered to invoke
# pytest by hand. check_test_registration.cmake now globs these
# directories too, so a new one fails configure until it is listed.
# test_psx_chd skips its decode cases unless a shared libchdr is found
# (PSXRECOMP_LIBCHDR); its container/selection cases always run.
foreach(_t IN ITEMS
aligned_lzss_banks
cursor_writers
disc_companion
duckstation_oracle
gpu_frame
menu_scan
mips_tagged_relocations
overlay_widescreen_callbacks
pad_delivery
pad_trace
psx_chd
sbi_registry
static_fragment_variant_keys)
add_test(
NAME ${_t}
COMMAND ${Python3_EXECUTABLE}
${CMAKE_CURRENT_SOURCE_DIR}/../tools/tests/test_${_t}.py
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/..)
endforeach()
add_test(
NAME compile_overlays_static_split
COMMAND ${Python3_EXECUTABLE}
${CMAKE_CURRENT_SOURCE_DIR}/../tools/test_compile_overlays_static_split.py
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/..)
add_test(
NAME aot_overlay_spike_coverage_report
COMMAND ${Python3_EXECUTABLE}
${CMAKE_CURRENT_SOURCE_DIR}/../tools/aot_overlay_spike/test_coverage_report.py
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/..)
add_test(
NAME disc_inventory
COMMAND ${Python3_EXECUTABLE}
${CMAKE_CURRENT_SOURCE_DIR}/../tests/test_disc_inventory.py
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/..)
# ---- codegen tests that were written but never registered -----------
# These existed in recompiler/tests/ with no add_test() entry, so they
# had no way to run and no way to fail. Each was executed manually
+9 -1
View File
@@ -88,12 +88,20 @@ function(psxrecomp_check_all_tests_registered)
# CONFIGURE_DEPENDS matters more than usual here: without it, ADDING a test
# file would not re-run configure, so this check would sleep through the
# exact event it exists to catch.
# The offline tools' unit tests live beside the tools (tools/tests,
# tools/, one level of tools/<package>/) and in the top-level tests/. They
# are registered in recompiler/CMakeLists.txt, the BIOS-free tree.
file(GLOB _found CONFIGURE_DEPENDS
"${_root}/runtime/tests/test_*.c"
"${_root}/runtime/tests/test_*.cpp"
"${_root}/runtime/tests/test_*.py"
"${_root}/recompiler/tests/*_test.cpp"
"${_root}/recompiler/tests/test_*.py")
"${_root}/recompiler/tests/test_*.py"
"${_root}/tools/tests/test_*.py"
"${_root}/tools/test_*.py"
"${_root}/tools/*/test_*.py"
"${_root}/tests/test_*.py")
list(REMOVE_DUPLICATES _found)
# ---- diff -------------------------------------------------------------
set(_orphans "")
@@ -13,9 +13,14 @@ check before doing anything else. CTest passes it the same way the other
overlay codegen tests get it.
Usage: test_compile_overlays_static_tail.py --recompiler <psxrecomp-game>
The recompiler may also come from PSXRECOMP_GAME_RECOMPILER, or be found in a
framework build directory, so a plain unittest/pytest collection runs the test
instead of handing subprocess a None path (the old failure mode: TypeError).
"""
import argparse
import json
import os
from pathlib import Path
import subprocess
import sys
@@ -24,11 +29,33 @@ import unittest
TOOLS = Path(__file__).resolve().parents[1]
ROOT = TOOLS.parent
RECOMPILER_ENV = "PSXRECOMP_GAME_RECOMPILER"
RECOMPILER = None
def find_recompiler():
"""--recompiler, then the environment, then a framework build tree."""
if RECOMPILER:
return RECOMPILER
env = os.environ.get(RECOMPILER_ENV, "").strip()
if env:
return env
names = ("psxrecomp-game.exe", "psxrecomp-game")
for build in sorted(ROOT.glob("build*")) + sorted((ROOT / "recompiler").glob("build*")):
for name in names:
candidate = build / name
if candidate.is_file():
return str(candidate)
return None
class StaticTailTest(unittest.TestCase):
def test_static_run_with_no_captures_exits_zero(self):
recompiler = find_recompiler()
self.assertTrue(recompiler and Path(recompiler).is_file(),
f"psxrecomp-game not found: pass --recompiler, set "
f"{RECOMPILER_ENV}, or build the recompiler under "
f"{ROOT}/build*")
with tempfile.TemporaryDirectory() as tmp:
tmp = Path(tmp)
caps = tmp / "captures.json"
@@ -43,7 +70,7 @@ class StaticTailTest(unittest.TestCase):
"--captures", str(caps),
"--out-dir", str(out),
"--game-toml", str(toml),
"--recompiler", RECOMPILER,
"--recompiler", recompiler,
"--runtime-include", str(ROOT / "runtime" / "include")],
capture_output=True, text=True, timeout=120)
detail = proc.stdout[-1500:] + proc.stderr[-1500:]
+4
View File
@@ -180,3 +180,7 @@ class PerPressVerdictTest(unittest.TestCase):
w(0x8004A5F5, 7, 6, "0xB", seq=3, frame=500),
w(0x8004A5F5, 6, 5, "0xC", seq=4, frame=500)]
self.assertEqual(cw.verdict(ws, 0x8004A5F5)[0], "two_paths")
if __name__ == "__main__":
unittest.main()