From 145e0b0a987205803586256a368b50ff22030ea0 Mon Sep 17 00:00:00 2001 From: Travis Herbranson Date: Tue, 12 May 2026 07:51:33 -0400 Subject: [PATCH] tests: fix SIGPIPE under pipefail; use -print -quit instead of | head -1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `set -o pipefail` at the top of tests.sh combined with `find ... | head -1` is a silent-killer pattern. When `find` produces lots of matches (e.g. when uv has installed dozens of third-party packages with test_*.py files under .venv), `head -1` reads its single line and closes the pipe. `find` writes again, gets SIGPIPE, exits 141. pipefail propagates 141. `set -e` fires. tests.sh exits 141 before printing `-- Python (pytest ...) --` or any other output. run-all.sh records `tests: failed` with no indication of WHY. Reproduced directly: bash -c 'set -euo pipefail; x=$(find -name "test_*.py" -o -name "*_test.py" | head -1); echo "got: $x"' exit=141 # "got:" never prints Fix: replace `| head -1` with `-print -quit` so find stops itself after the first match instead of getting cut off mid-write. As a free bonus, also prune the well-known noise dirs (.venv, .git, etc.) so the probe doesn't even consider third-party test files in the first place — this keeps the probe fast on dense trees and avoids matching @pytest.fixture-decorated files in installed packages. Co-Authored-By: Claude Opus 4.7 (1M context) --- validate/tests.sh | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/validate/tests.sh b/validate/tests.sh index cadb2fa..2fd86ed 100755 --- a/validate/tests.sh +++ b/validate/tests.sh @@ -11,8 +11,18 @@ errors=0 echo "=== Test Suite ===" -has_python=$(find "$TARGET" -name "test_*.py" -o -name "*_test.py" | head -1) -has_go=$(find "$TARGET" -name "*_test.go" | head -1) +# Probe for test files. Prune known noise dirs so we don't trip on +# third-party test files installed under .venv, and use -print -quit so +# the probe doesn't SIGPIPE under `set -o pipefail` on dense trees +# (which exits the script silently with status 141 before any stage +# output is printed). +has_python=$(find "$TARGET" \ + \( -path '*/__pycache__' -o -path '*/.venv' -o -path '*/venv' \ + -o -path '*/.git' -o -path '*/node_modules' \) -prune \ + -o \( -name 'test_*.py' -o -name '*_test.py' \) -print -quit) +has_go=$(find "$TARGET" \ + \( -path '*/.git' -o -path '*/vendor' -o -path '*/node_modules' \) -prune \ + -o -name '*_test.go' -print -quit) if [ -z "$has_python" ] && [ -z "$has_go" ]; then printf "${YELLOW}!${NC} No test files found — skipping\n"