From f3cc71ccaefad26b5b98ecfeeba909a49c8f53ab Mon Sep 17 00:00:00 2001 From: sneak Date: Fri, 2 Oct 2026 08:04:19 +0000 Subject: [PATCH] Run script/test quietly with coverage, rerun failed tests verbosely (closes #315) The first run is go test -race -cover without -v, so a green run prints one line per package with its coverage. On failure, the top-level tests named on "--- FAIL:" lines are rerun with -v in the packages that failed, then the script exits 1 whatever the rerun's result. Rerunning only the failed tests keeps a red build log far below the 2 MiB at which the Docker build cuts it off (issue 414). The timeout, -p 4 -parallel 8 and their header comment are unchanged. Model: opus-5-5 --- script/test | 39 ++++++++++++++++++++++++++++++++++----- 1 file changed, 34 insertions(+), 5 deletions(-) diff --git a/script/test b/script/test index 39bfcb7..9095510 100755 --- a/script/test +++ b/script/test @@ -28,10 +28,12 @@ # -race every test binary and every link costs a few hundred MB, so the # defaults (one per core) add up to several GB on a many-core host. # -# No -v: the Docker build cuts each step's log off at 2 MiB, and verbose output -# from the whole suite passes that before a failure is printed. Without it, go -# test prints one result line per package and, for a package that fails, -# everything its tests wrote, application log lines included. +# The first run has no -v: go test then prints one result line per package, +# with its coverage, and for a package that fails, everything its tests wrote, +# application log lines included. Verbose output from the whole suite passes +# the 2 MiB at which the Docker build cuts off each step's log, so on a failure +# only the tests that failed run again, with -v. The script exits 1 after that +# rerun whatever its result: the first run already showed the suite is broken. set -eu ROOT="$(cd "$(dirname "$0")/.." && pwd -P)" @@ -39,7 +41,34 @@ ROOT="$(cd "$(dirname "$0")/.." && pwd -P)" main() { cd "$ROOT" "$ROOT/script/assets" - go test -race -p 4 -parallel 8 -timeout 90s ./... + + log="$(mktemp -t webhooker-test.XXXXXXXX)" + rcfile="$(mktemp -t webhooker-test-rc.XXXXXXXX)" + trap 'rm -f "$log" "$rcfile"' EXIT INT TERM + + # The pipeline's status is tee's, and POSIX sh has no pipefail, so go + # test's status travels via a file. Output still streams live. + { + go test -race -cover -p 4 -parallel 8 -timeout 90s ./... 2>&1 \ + && echo 0 >"$rcfile" || echo $? >"$rcfile" + } | tee "$log" + if [ "$(cat "$rcfile")" -eq 0 ]; then + return + fi + + # go test reports a failed test as a line starting "--- FAIL: TestName" + # (a failed subtest's line is indented, and reruns with its parent), and + # a failed package as "FAILpackage/path...". A failure that + # names no test, such as a build error or a timeout, is already shown in + # full above, so there is nothing to rerun. + tests="$(awk '/^--- FAIL: / { print $3 }' "$log" | paste -s -d '|' -)" + packages="$(awk '/^FAIL\t/ { print $2 }' "$log")" + if [ -n "$tests" ]; then + echo "--- Rerunning the failed tests with -v for details ---" + go test -race -v -p 4 -parallel 8 -timeout 90s \ + -run "^($tests)\$" $packages || true + fi + exit 1 } main "$@"