Skip to content

fix(tools): reject dangling test graph targets - #11668

Merged
adriadam10 merged 1 commit into
boykopovar:mainfrom
StoneDC:fix/select-test-graph-closures
Oct 28, 2026
Merged

adriadam10 merged 1 commit into
boykopovar:mainfrom
StoneDC:fix/select-test-graph-closures

Conversation

@StoneDC

@StoneDC StoneDC commented Oct 27, 2026

Copy link
Copy Markdown
Contributor

What

A test graph could refer to a non-null build target absent from its closure map. Selection then silently treated that missing target as an empty closure and could omit relevant tests. Reject the dangling target while loading the graph, identifying the test entry and target. Null targets, explicit empty closures and an empty graph remain valid.

Basis: the graph producer/consumer contract in tools/select_tests.py: every non-null target consumed by selection needs a closure entry. Regressions exercise production loading and real --explain CLI selection, rather than duplicating the validator.

The existing aggregate select_tests suite approached the 30-second limit under competing work. Preserve all 17 original SelectTests method bodies and distribute them across four classes, then register all 12 test classes separately without increasing a timeout. The original literal add_test(NAME select_tests ...) registration remains; only that CTest entry sets ANYPS5_SELECT_TEST_CLASS=SelectTests. Running the file normally without that environment variable still runs the whole suite. Other CTest entries pass explicit class names; CMake tracks the test source as a configure dependency.

Integration: no prerequisite PR. The original registration anchors are retained to accommodate #11062. Recorded-head tool projections with #10619, #11486 and #11062 were tested below. Each preserves both sets of production behavior/tests; no merge ordering is required. Legacy shared-file comparisons are described below rather than asserted to be whole-PR merges.

Limits: this validates target-to-closure references, not every possible graph semantic error. Windows and Linux executed the registered groups; macOS and an older Python runtime remain untested.

Tested

Base: c831db72df8d3236a910661c3fc37507fc646a33. Tested PR head: dcb1013c482aaeddc84ec8c366e35d987c807ee2.

Windows: Python 3.14.3, MinGW GCC 15.2.0, CMake 4.3.1, Ninja. Ubuntu 26.04 under WSL: Python 3.14.4, GCC 15.2.0, CMake 4.2.3, Ninja; 8 logical CPUs.

  • windows: 12 registered CTest group(s), 38 unittest cases reported, 1 inner skip(s), 0 failures; slowest group 11.21s. Skips are not counted as executed passes.
  • linux: 12 registered CTest group(s), 38 unittest cases reported, 1 inner skip(s), 0 failures; slowest group 6.91s. Skips are not counted as executed passes.

Windows skips the existing non-ASCII ANSI-path case; Linux skips the Windows-only chunk-size case.

Configured with cmake -S <source> -B <build> -G Ninja -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=ON -DANYPS5_RELINKER_ONLY=ON. Ran ctest --test-dir <build> -R '^select_tests($|_)' --parallel 4 -V --output-junit <report> on Windows, --parallel 8 on WSL; XML skip-policy checks passed.

CTest JSON listing proves one registration per test class, including the legacy entry environment. AST comparison proves all 17 original method bodies are unchanged. Test-registration audit: 196 scripts each registered or run by a workflow.

Negative control: replaying the final regression tests with the unmodified production tools from c831db72df8d3236a910661c3fc37507fc646a33 reproduces the target assertion failures. Missing imports/modules were not used as regression evidence. Current-main conventions, git diff --check and Python 3.9 grammar parsing passed. An older Python runtime was not run.

Seven-project local integration on the earlier recorded base 27ad7244d22153ebfd576e04e3c4d63e0b92264b: combined commit e3fd69f3840131bc4300f109dfcd99dd157578f1; 19 registered groups passed on each platform (251 unittest cases reported; 2 Windows inner skips and 1 Linux inner skip). Linux validates fresh Git archive snapshots of the recorded source; its local snapshot commit IDs differ from the PR commits.

Related tool-only integration contexts, each applied independently on that earlier seven-project combined tree and tested on Windows and WSL:

These projections cover the listed tool/CMake/test files, not whole external PR builds, GPU execution or hosted CI. Exact file blobs and Linux snapshot hashes are retained in the local verification record.

The subsequent rebase to the tested base changed none of the seven production/test blobs or the relevant main tool, root-CMake and repository-rule inputs. Independent Windows/WSL focused suites and negative controls were rerun at the final heads; earlier combined/projection runs are reported with their actual historical commits above. Upstream continued merging unrelated native-code changes during publication: the push gate fetches main, verifies unchanged tools/root CMake/cmake/rules/template inputs and checks the actual merge tree preserves every changed blob. Local test and native-build claims refer to the explicit base/head above, not to later native-code merges.

Publication overlap check: the repository pr_overlap.py --branch CLI was run at this exact branch head. It reported incomplete CMake comparisons for #674, #1835, #3786, #5021, #7201, #8588, #9508 and #11366 because those PRs conflict with base. Manual exact-revision per-file three-way merges are clean for six; #8588 and #11366 already have conflicts with current main and their conflict chunks are byte-identical after adding this branch. None implements this dangling-target fix. This is not a claim that those whole PRs are mergeable.

Not run: hosted CI (pending after publication), macOS runtime, older Python runtime, full system-library build, game/PS5 execution or GPU validation. Host-tool changes do not require an inferred PS5 ABI/layout or graphics/performance evidence; none is claimed.

Checklist

  • Based on current main; no other open PR implements the same functions
  • One topic per PR; follow-ups go in a new PR
  • No comments in code except technical debt
  • Unimplemented paths throw (NotImplemented_nid_no_patch); silent stubs are listed under Silent stubs in their library's technical debt file
  • No notes, investigation .md files or images added to the repository (attach them to this PR)
  • New third-party code is a submodule built from source
  • Generic behaviour, not specific to one title
  • Depends on: none
  • Fixes: none
  • Unblocks: none
  • GPUs tested: n/a (host tools only)
  • AI-assisted: yes

@github-actions

github-actions Bot commented Oct 27, 2026 •

Copy link
Copy Markdown

Some comparisons could not be completed because a pull request conflicts with the base branch. Review these shared files manually before concluding that there is no overlap.

Pull request Shared files not compared
PR 674 CMakeLists.txt
PR 1835 CMakeLists.txt
PR 3786 CMakeLists.txt
PR 5021 CMakeLists.txt
PR 9508 CMakeLists.txt
PR 9539 CMakeLists.txt
PR 10897 CMakeLists.txt

@THEMANnt THEMANnt left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed dcb1013c482aaeddc84ec8c366e35d987c807ee2. Approve: graph loading rejects a non-null test target with no closure, while null targets, explicit empty closures and empty graphs remain valid. The graph producer creates a closure for every selected executable target.

Windows/Python 3.11.9: all 38 selector tests passed, including temporary CMake/Ninja builds. The submitted graph-control test against disposable production from author merge base c831db72 fails because the old CLI exits 0 with an empty selection for a dangling target; the candidate reports the invalid graph instead. An initial control omitted an imported helper; after adding the unchanged baseline helper, it produced that behavioral result.

Hosted Windows, Linux and both macOS relinker jobs ran all 12 split selector registrations on merges containing this head; product jobs were skipped. This covers test selection and registration rather than a full product build.

@adriadam10 adriadam10 self-assigned this Oct 27, 2026
@github-actions github-actions Bot added the build label Oct 27, 2026
@adriadam10
adriadam10 merged commit ce10709 into boykopovar:main Oct 28, 2026
13 checks passed
@adriadam10

Copy link
Copy Markdown
Collaborator

Checked load_graph against the null/empty-closure/empty-graph cases, the explain CLI path (exit 2, no traceback), the class split (method bodies unchanged, one CTest entry per class, legacy select_tests entry kept) and the new tests (the CLI one fails on main, which exits 0 with an empty selection). The earlier Windows red was guest_raise_exception (0xc0000409), a known flake in code this tools-only diff does not touch; rerun. THEMANnt's Windows run confirms the 38 selector tests; merged.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants