Skip to content

Commit 235449a

Browse files
committed
tests/e2e/188: the "did not rerun" assertion could not fail
It read `grep -q "GENERATE" b3.log && FAIL`, on the assumption that ninja's description line for the edge reaches that log. It does not. `mcpp build` passes `--quiet` to ninja whenever it is not `--verbose` and surfaces ninja's captured stdout only on failure, so a from-scratch build -- which unquestionably runs the action -- prints no such line either. The grep never matched, and the check could not fail whether the action reran or not. Found while designing the depfile test, whose first draft copied this convention and would have inherited the same emptiness. The generated file's modification time measures the thing being asserted directly: the action rewrites it whenever it runs. Verified in both directions against the same binary -- unchanged after touching an unrelated source, and the assertion fails naming both timestamps when the touched file is a declared input of the action instead.
1 parent ebcbf78 commit 235449a

1 file changed

Lines changed: 21 additions & 2 deletions

File tree

tests/e2e/188_build_actions.sh

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,10 +122,29 @@ out="$("$MCPP" run 2>&1 | grep '^VALUE=' | tail -1)"
122122
cat b2.log; echo "FAIL: action did not re-run when its input changed: $out"; exit 1; }
123123

124124
# ...and an unrelated rebuild must NOT re-run it (that is the whole point).
125+
#
126+
# THIS ASSERTION USED TO BE VACUOUS, AND THAT IS WORTH THE COMMENT. It read
127+
# `grep -q "GENERATE" b3.log && FAIL`, on the assumption that ninja's
128+
# description line for the edge reaches this log. It does not: `mcpp build`
129+
# passes `--quiet` to ninja whenever it is not `--verbose`, and surfaces
130+
# ninja's captured stdout only on failure. A from-scratch build, which
131+
# unquestionably runs the action, prints no such line either -- so the grep
132+
# never matched and the check could not fail whether the action reran or not.
133+
#
134+
# The generated file's modification time is a direct measurement of the thing
135+
# being asserted: the action rewrites it whenever it runs.
136+
before=$(stat -c %Y "$(find target -name gen.cpp -print -quit)" 2>/dev/null \
137+
|| stat -f %m "$(find target -name gen.cpp -print -quit)")
125138
touch src/main.cpp
139+
sleep 1 # coarser than any filesystem's mtime granularity here
126140
"$MCPP" build > b3.log 2>&1 || { cat b3.log; echo "FAIL: rebuild failed"; exit 1; }
127-
grep -q "GENERATE" b3.log && {
128-
cat b3.log; echo "FAIL: the action re-ran although its inputs were unchanged"; exit 1; }
141+
after=$(stat -c %Y "$(find target -name gen.cpp -print -quit)" 2>/dev/null \
142+
|| stat -f %m "$(find target -name gen.cpp -print -quit)")
143+
[[ -n "$before" && "$before" == "$after" ]] || {
144+
cat b3.log
145+
echo "FAIL: the action re-ran although its inputs were unchanged"
146+
echo " (gen.cpp mtime $before -> $after)"
147+
exit 1; }
129148

130149
# ── 2b. changing the action's COMMAND also takes effect ────────────────────
131150
# Distinct from 2: there the action's declared INPUT changed and ninja noticed.

0 commit comments

Comments
 (0)