Skip to content

Commit ab84126

Browse files
committed
test(e2e): harden first-line extraction against EPIPE (sed -n 1p, not head -1)
Smell-audited: 0: clean — a mechanical robustness sweep of one fragile shell idiom, no behaviour change The 13e6334 push CI failed e2e_phase14_system_members on a heavily loaded x86_64-linux runner (rerun green — a flake, not a regression): `got=$("$BIN" … 2>&1 | head -1)` under `set -eo pipefail` dies WITHOUT printing FAIL when head's early pipe close EPIPEs the binary's later write (the -e echo / final flush). sed -n 1p reads to EOF, so the writer never sees a closed pipe. Hardened the four direct-binary sites (system_members in_read, pr_newline x3, phase3_cli --help); the variable-fed `printf | head -1` sites are single-write-safe and stay.
1 parent 13e6334 commit ab84126

3 files changed

Lines changed: 15 additions & 5 deletions

File tree

‎test/e2e/phase14_system_members.sh‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,11 @@ got_err=$("$BIN" -e '(.println System/err "e2")' 2>&1 >/dev/null)
7474
[[ "$got_out" == "nil" && "$got_err" == "e2" ]] || fail "err_channel: out='$got_out' err='$got_err'"
7575
echo "PASS err_channel"
7676
# System/in reads piped bytes ("h"=104, "i"=105), then EOF -1
77-
got=$(echo "hi" | "$BIN" -e '(prn [(.read System/in) (.read System/in) (.read System/in) (.read System/in) (.read System/in)])' 2>&1 | head -1)
77+
# `sed -n 1p`, NOT `head -1`: head exits after line 1 and closes the pipe, so
78+
# cljw's later write (the -e nil echo / final flush) can hit EPIPE on a loaded
79+
# host → cljw exits non-zero → under `set -eo pipefail` the assignment dies
80+
# WITHOUT printing FAIL (the 2026-07-29 CI-runner flake). sed reads to EOF.
81+
got=$(echo "hi" | "$BIN" -e '(prn [(.read System/in) (.read System/in) (.read System/in) (.read System/in) (.read System/in)])' 2>&1 | sed -n '1p')
7882
[[ "$got" == '[104 105 10 -1 -1]' ]] || fail "in_read: got '$got'"
7983
echo "PASS in_read"
8084

‎test/e2e/phase15_pr_newline.sh‎

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,23 @@ BIN="zig-out/bin/cljw"
1111
fail() { echo "FAIL $1" >&2; exit 1; }
1212
assert_eq() { local n="$1" g="$2" w="$3"; [[ "$g" == "$w" ]] || fail "$n: got '$g' want '$w'"; echo "PASS $n -> $w"; }
1313

14+
# First-line extraction is `sed -n 1p`, NOT `head -1`: head's early pipe close
15+
# can EPIPE cljw's later write on a loaded host → non-zero exit → pipefail
16+
# kills the assignment without a FAIL line (the 2026-07-29 CI-runner flake).
17+
1418
# pr renders a string in READABLE (quoted) form, no trailing newline
1519
assert_eq 'pr-string-quoted' \
16-
"$("$BIN" -e '(pr "hi")' 2>&1 | head -1)" \
20+
"$("$BIN" -e '(pr "hi")' 2>&1 | sed -n '1p')" \
1721
'"hi"nil'
1822

1923
# print renders the same string UNQUOTED (contrast with pr)
2024
assert_eq 'print-string-unquoted' \
21-
"$("$BIN" -e '(print "hi")' 2>&1 | head -1)" \
25+
"$("$BIN" -e '(print "hi")' 2>&1 | sed -n '1p')" \
2226
'hinil'
2327

2428
# pr on a keyword / number is the readable form, no newline
2529
assert_eq 'pr-keyword' \
26-
"$("$BIN" -e '(pr :a)' 2>&1 | head -1)" \
30+
"$("$BIN" -e '(pr :a)' 2>&1 | sed -n '1p')" \
2731
':anil'
2832

2933
# newline emits a line break (single (do …) form, so the echo lands once at

‎test/e2e/phase3_cli.sh‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,9 @@ got=$("$BIN" --version 2>&1) || fail "--version: non-zero exit"
297297
echo " ✓ --version → $got"
298298

299299
# --- Case 32: --help leads with the version banner line (ADR-0117) ---
300-
got=$("$BIN" --help 2>&1 | head -1) || fail "--help: non-zero exit"
300+
# sed -n 1p, not head -1: --help is multi-line, and head's early pipe close
301+
# can EPIPE the still-writing binary on a loaded host (2026-07-29 CI flake class).
302+
got=$("$BIN" --help 2>&1 | sed -n '1p') || fail "--help: non-zero exit"
301303
[[ "$got" == ClojureWasm\ v* ]] || fail "--help banner: want 'ClojureWasm v<ver>', got '$got'"
302304
echo " ✓ --help banner → $got"
303305

0 commit comments

Comments
 (0)