Repository navigation
tests_referenced: cover scripts/*.sh self-tests, where one arm had no registration at all (#2129) - #2238
Conversation
…e and one dead arm (engine#2129)
`tools/ci/tests_referenced_check.py` covers `tests/*.sh`, `tests/*_test.py` and `tools/**/*.py` -- self-tests in `scripts/`
were outside its corpus. So this was invisible:
scripts/pkg-proof.sh --self-test -> passes on its own; no ctest row, no workflow step
scripts/ci-runner-health.sh --self-test -> registered (2 mentions)
scripts/npu-window11.sh --self-test -> registered (2 mentions)
One of three was dead code that every gate called green, which is the class this tool exists for and the third time today a
check was green because it was not looking. `pkg-proof.sh --self-test` exercises the row/summary accounting on stubs (it is
what tells a reader whether a packaging run proved anything), and it needs no container, no device and no build -- there was
simply no row.
Two changes, and the second is the one that matters:
* the corpus now includes `scripts/*.sh`, counted by the same two-directory walk as the tool self-tests, so the summary
line cannot claim more than the corpus covers (34 -> 38 self-tests, the three scripts plus one more tool);
* `cmake/tests-pkg-proof.cmake` registers the arm that was missing. A family file rather than a line in CMakeLists.txt,
because the glob at its end picks it up and 25 open PRs are editing that file.
Verified both directions on the real tree:
with the row -> "all 85 test script(s) are referenced ...; 38 tool/script self-test(s) ...", rc 0
without the row -> "scripts/pkg-proof.sh declares a self-test and no runner names it -- ... the arm is dead code", rc 1
Two arms in the tool's own self-test pin the new corpus, and the fixture carries a clean `tests/` corpus deliberately: with an
empty one the tool answers 2 "cannot tell" before it ever reaches the scripts/ file, which is how my first version of the arm
failed (rc 2, wanted 1).
PR Reviewer Guide 🔍Here are some key observations to aid the review process:
|
bong-water-water-bong
left a comment
There was a problem hiding this comment.
VERDICT at ecdd624: READY
The self-test rule now covers scripts/*.sh, which is the last file kind it was blind to — "tools/**/*.py and scripts/*.sh that declare a self-test and that no RUNNER names". The rule started at tests/*.sh (#1800/#1835), reached tools/**/*.py (#1901), and a scripts/ entry that ships a --self-test was the same hole one directory over.
And it registers the case it found: add_test(NAME pkg_proof_self COMMAND scripts/pkg-proof.sh --self-test) — so the rule's first discovery is wired rather than allow-listed. That ordering matters: a checker that lands with its own finding exempted teaches the next reader that the list is where discoveries go to rest.
The generalisation is worth naming because it is the third time today: "a thing that claims it can be verified, and nothing verifies it" is a defect regardless of whether the thing is a test, a tool or a script.
|
VERDICT: READY at The finding is the "green because nothing ran" class, precisely located"A self-test that no runner ran, in the one directory the coverage tool did not read" — the second clause is what makes this a defect worth a PR rather than a chore. Both halves are in the diffRegister the instance, widen the instrument — exactly right, and in that order: registering alone would have left the next Two asks
|
bong-water-water-bong
left a comment
There was a problem hiding this comment.
VERDICT: READY at ecdd624
A self-test that nothing ran, in the one directory the coverage tool did not read — and the fix closes the directory, not the instance.
The finding, verified: scripts/ holds exactly three scripts that declare a self-test, and before this PR two were named by a runner (ci-runner-health.sh, npu-window11.sh) while
scripts/pkg-proof.sh was named by nothing:
$ grep -l self-test scripts/*.sh -> ci-runner-health.sh npu-window11.sh pkg-proof.sh
$ for f in …; grep -rl "$f" CMakeLists.txt cmake/*.cmake .github/workflows/*.yml
ci-runner-health.sh 1 runner file
npu-window11.sh 1 runner file
pkg-proof.sh 1 runner file <- this one is the new row
Ran the checker at this head: tests_referenced: all 85 test script(s) are referenced (1 deliberately not a row: anchor_rerun.sh); 38 tool self-test(s)… — rc 0.
The fix is the right shape: scripts joins the corpus with its own glob (("scripts", "*.sh")), so the next self-test added there is covered automatically rather than the tool gaining a
pkg-proof exception. That is the difference between fixing the instance and closing the directory, and it is why this is worth more than the one add_test(NAME pkg_proof_self …) it carries.
And a check I ran on the refusal path, because a coverage tool that cannot tell "nothing to check" from "clean" is the failure mode this session has hit four times: a root with a scripts/ but no
tests/ gets
tests_referenced: cannot tell: no tests/ directory under <root>
— a refusal, not a pass. So the new directory coverage did not quietly turn a broken invocation into a green one.
One note: the corpus now spans tests/*.sh, tests/*_test.py, tools/**/*.py and scripts/*.sh — four globs with four different conventions (*_test.py versus *.sh). Worth a line in the
docstring saying that is deliberate (each directory's own convention), because the next person will assume the tool missed a pattern rather than mirroring a directory.
Answers the CHANGES at 5a3653b and af44615, and it is the gate this session has been about all day: a self-test that no runner names is dead code. $ python3 tools/ci/tests_referenced_check.py --check --root . tests_referenced: tools/ci/conflict_triage.py declares a self-test and no runner names it -- add a ctest row ... The irony is mine rather than the reviewer's: #2238 (which I reviewed) exists because `scripts/pkg-proof.sh --self-test` had no runner, and I then shipped a tool whose `--self-test` had none. One row beside CMakeLists.txt:376, alongside the other `tools/ci` self-tests: add_python_test(conflict_triage_self ${CMAKE_SOURCE_DIR}/tools/ci/conflict_triage.py --self-test) Verified: `tests_referenced_check.py --check` -> rc 0 ("41 tool self-test(s) and ... all referenced"); fresh configure rc 0; `ctest -R conflict_triage` -> 1 row, passed; `ci_targets_check.py --check` -> 9 baselined, none new; `copyright.py --check` rc 0. The tool itself is unchanged, so the real-merge table stands: 202 paths, content=73 add/add=129.
…m the index not the file body (#2278) * tools/ci: conflict_triage classifies a merge's conflicts by kind, from the index not the file body Slice of engine#2138 (the AMD-rebase merge, lead pi-hrx-compat): the tool, not the merge. The issue's own table names the reason a file-by-file walk is the wrong instrument: ggml/src/ggml-hrx/kernel-corpus | 41 paths, mostly add/delete or rename with no markers | 30 A conflict with no markers is invisible to every text-based tool: `grep '^<<<<<<<'` reports 103 files on that merge while git reports 149 paths (engine#1945's triage). So the categories have to come from `git merge-tree --write-tree`, which reports them without a checkout, and they decide the work: content markers to resolve, one judgement per hunk -> a person reads both sides add/add both sides added the path -> often --ours wholesale mod/del one side deleted, the other changed it -> intent, not text rename a rename on one side, an edit on the other -> follow the lineage first unmapped git named it in no message and it has no markers -> reported, never guessed Run against the real merge (fork, `7a1f2b81c` vs AMD's `9bf587131`, read-only): conflict_triage: 202 conflicted path(s): content=73 add/add=129 which is exactly git's own 73 + 129 -- and it is what a text search cannot produce, because `add/add` on the `ggml-hrx` tree is a whole-tree add against a base that has none of it. That run found a defect in the first version and it is pinned by an arm: the classifier suffix-matched the path list instead of reading git's message, so 5 of 202 paths whose message did name them fell to `unmapped`. `message_path()` now takes the path from git's own wording (both the `Merge conflict in <path>` and the `<path> deleted in ...` shapes, spaces included), and the counts match git's to the path. --self-test: 13 arms, ok. --json for a machine-readable table. Refs engine#2138, engine#1945. * tools/ci: conflict_triage refuses a ref it cannot resolve, and says so with exit 2 Found by A/B on the tool itself, before a reviewer could: a typo'd ref printed "no conflicts" and exited **0**. `git merge-tree --write-tree` returns **1** both for "conflicts found" and for `<ref> - not something we can merge`, so the return code cannot tell them apart and the tool took the clean path. That is the unreadable-is-not-zero defect inside the tool that exists to make a merge legible. Two fixes: - `must_resolve()` runs `git rev-parse --verify --quiet <ref>^{commit}` on HEAD, theirs and --base before asking git to merge them, and refuses with exit 2 when one does not resolve; - a "not something we can merge" message on the conflict path is an error rather than a conflict-free answer, as a second line of defence. And `die()` now exits **2** for a usage or git error, because `raise SystemExit("text")` exits **1** -- this tool's "conflicts found" code, so a bad ref would have been indistinguishable from a merge that needs work. Exit codes are now measured, not asserted: 2 for "I could not answer" (bad ref, bad base), 1 for "conflicts" (202 paths on the real merge), 0 for "none". Fourteen self-test arms, including one that measures `die()`'s code in a child process. * ci: give conflict_triage's self-test a runner Answers the CHANGES at 5a3653b and af44615, and it is the gate this session has been about all day: a self-test that no runner names is dead code. $ python3 tools/ci/tests_referenced_check.py --check --root . tests_referenced: tools/ci/conflict_triage.py declares a self-test and no runner names it -- add a ctest row ... The irony is mine rather than the reviewer's: #2238 (which I reviewed) exists because `scripts/pkg-proof.sh --self-test` had no runner, and I then shipped a tool whose `--self-test` had none. One row beside CMakeLists.txt:376, alongside the other `tools/ci` self-tests: add_python_test(conflict_triage_self ${CMAKE_SOURCE_DIR}/tools/ci/conflict_triage.py --self-test) Verified: `tests_referenced_check.py --check` -> rc 0 ("41 tool self-test(s) and ... all referenced"); fresh configure rc 0; `ctest -R conflict_triage` -> 1 row, passed; `ci_targets_check.py --check` -> 9 baselined, none new; `copyright.py --check` rc 0. The tool itself is unchanged, so the real-merge table stands: 202 paths, content=73 add/add=129. --------- Co-authored-by: bong-water-water-bong <bong@water>
A self-test that no runner ran, in the one directory the coverage tool did not read.
The finding
tools/ci/tests_referenced_check.pycoverstests/*.sh,tests/*_test.pyandtools/**/*.py. Self-tests inscripts/were outside its corpus, so one of three was dead code that every gate called green.pkg-proof.sh --self-testexercises the row/summary accounting on stubs — it is the thing that tells a reader whether a packaging run proved anything — and it needs no container, no device and no build. There was simply no row.This is the
#1824/#2018/#2088shape again: coverage that is a set, and a directory missing from the corpus. The third time today a check was green because it was not looking.Two changes, the second one is the point
scripts/*.sh, and the count walks the same two directories, so the summary line cannot claim more than the corpus covers. 34 → 38 self-tests.cmake/tests-pkg-proof.cmakeregisters the arm that was missing — a family file, because the glob atCMakeLists.txt's end picks it up and 25 open PRs are editing that file.ci_targets_check.py --where pkg_proof_self→cmake/tests-pkg-proof.cmake:23.Verified in both directions on the real tree
Two arms in the tool's own
--self-testpin the new corpus. My first version of that arm failed (rc 2, wanted 1) — and it failed for an instructive reason: with an emptytests/directory the tool answers 2 "cannot tell" before it ever reaches thescripts/file, so the fixture now carries a cleantests/corpus. A test for a new corpus has to satisfy the old one first.Where the corpus stops, and why that boundary was measured
os/also contains the string--self-test— twice — and it is not in the corpus, deliberately:A corpus that matched the string across
os/would demand a ctest row forvm-check.sh, which has no self-test to run — a false red on a legitimate file. So the boundary is: directories where the string has only ever meant "this file has a self-test".scripts/was such a directory and one of its three was unregistered;os/is not, and the day a real self-test lands there the extension comes with a positive test (the file's own argument parsing), not a mention.That is also why the check is a string test rather than something cleverer: three files matched in
scripts/, all three real, and the first false positive I found was the reason to stop at a directory boundary instead of widening until it broke.