check / check (push) Waiting to run
The cost that pushed internal/handlers near its 90s package timeout, and test app starts past fx's 15s start timeout, was every start hashing the admin password at 64 MB; that went with #404. Measured since under the host's real load, the package takes 8.5s and the slowest test app start 0.49s, so neither limit changes. newTestApp now says what its start limit catches and the measurement behind it, and script/test notes that its figures predate that change and gives the current ones. No test changes what it asserts. Model: opus-5-5
81 lines
3.7 KiB
Bash
Executable File
81 lines
3.7 KiB
Bash
Executable File
#!/bin/sh
|
|
# script/test: run the test suite.
|
|
#
|
|
# -timeout is applied by `go test` per package, not to the run as a whole, so
|
|
# it only has to clear the slowest single package. When this budget was set
|
|
# that was internal/handlers, measured in a cache-defeated builder stage on the
|
|
# 48-core shared build host (2026-08-18); load- and host-dependent, not
|
|
# invariants:
|
|
#
|
|
# 16.9s host load 5-20, GOMAXPROCS 48
|
|
# 45.9s / 47.3s / 49.0s three runs at deliberate host load 31-73
|
|
# 30.6s / 39.7s host load 5-20, GOMAXPROCS 6 / 4
|
|
# 67.3s / 97.5s host load 5-20, GOMAXPROCS 2 / 1
|
|
# 67.3s GOMAXPROCS 4 at deliberate host load 52-68
|
|
#
|
|
# The old 30s budget was breached by every loaded run and by every GOMAXPROCS
|
|
# at or below 6; at GOMAXPROCS 4 it failed outright ("panic: test timed out
|
|
# after 30s"), reproduced on 33e4fa4 with no other change.
|
|
#
|
|
# 90s matches the org-wide backstop in REPO_POLICIES.md and is sized here
|
|
# against the figures above: the worst case under native parallelism is 49.0s,
|
|
# and the compound GOMAXPROCS-4-under-load case at 67.3s sits at 75% of it.
|
|
# The one figure above 90s is GOMAXPROCS 1, a synthetic core floor rather than
|
|
# a condition CI runs under. If a CPU-limited runner ever puts a real run near
|
|
# 67s, that is the datum to revisit the org figure with.
|
|
#
|
|
# Those figures predate tests hashing the admin password at 1 MB instead of
|
|
# 64 MB (https://git.eeqj.de/sneak/webhooker/pulls/404). After that change, in
|
|
# a cache-defeated build at host load 44-109 (2026-10-02), internal/handlers
|
|
# took 8.5s and the slowest package was internal/database at 15.8s.
|
|
#
|
|
# -p 4 -parallel 8 keep the run under 2 GB of memory: at most four test
|
|
# binaries build or run at once, each with at most eight parallel tests. Under
|
|
# -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.
|
|
#
|
|
# 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)"
|
|
|
|
main() {
|
|
cd "$ROOT"
|
|
"$ROOT/script/assets"
|
|
|
|
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 "FAIL<tab>package/path<tab>...". 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 "$@"
|