diff --git a/ci/test_core.sh b/ci/test_core.sh index f3aabe73..82997848 100755 --- a/ci/test_core.sh +++ b/ci/test_core.sh @@ -1,13 +1,17 @@ #!/usr/bin/env bash # ci/test_core.sh — run the Flutter-free core Dart tests. # -# Covers `test/` at the repo root (IPC, daemon, PTY). Wraps `dart test` -# in a hard timeout + process-group kill so a hanging test (typically -# one holding a native fd open) can't wedge CI or pre-push. +# Covers `test/` at the repo root (IPC, daemon, PTY, git, panes, files, +# editor, pql). Each pass runs under `dart test --timeout` so a hanging +# test (typically one holding a native fd open) fails fast instead of +# wedging CI or the pre-push gate — the same portable mechanism ci/test.sh +# uses for the Flutter suite. No external `timeout`/`setsid` wrapper: those +# are GNU coreutils and absent on macOS, where their failure silently +# skipped the whole suite. # # Rationale: D-030 makes tests client-side only; a hang here is always # local — either a real bug or a bad test. Either way we'd rather fail -# loudly at 120s than block a pre-push indefinitely. +# loudly at the per-test timeout than block a pre-push indefinitely. set -euo pipefail @@ -20,32 +24,21 @@ if ! command -v dart >/dev/null; then exit 2 fi -# Hard timeout (seconds). The PTY tests should finish in <5s; IPC/daemon -# tests are faster still. 120s is generous for CI warmup, tiny for a -# hang. -TIMEOUT_SECONDS=${TIMEOUT_SECONDS:-120} +# Per-test hard timeout. The PTY tests should finish in <5s; IPC/daemon +# tests are faster still. 60s is generous for CI warmup, tiny for a hang. +# Matches ci/test.sh's --timeout 60s. +TEST_TIMEOUT="${TEST_TIMEOUT:-60s}" # failures-only: print failing tests + a final count, not one line per test. # Override with TEST_REPORTER=expanded when debugging. (T-242) REPORTER="${TEST_REPORTER:-failures-only}" -# Run dart test in its own process group so we can kill descendants on -# timeout. `setsid` starts a new session; `timeout --kill-after` SIGKILLs -# after SIGTERM if the test ignores it. CORE_DIRS="test/ipc test/pty test/daemon test/git test/panes test/files test/editor test/pql" -# Run a `dart test` pass under the hard timeout + process-group kill. +# Run a `dart test` pass under the per-test timeout. set -e propagates a +# failing pass (including a --timeout-induced failure) with dart's exit code. run_pass() { - if ! timeout --kill-after=5s "${TIMEOUT_SECONDS}s" \ - setsid --wait dart test -r "$REPORTER" "$@" ; then - rc=$? - if [[ $rc -eq 124 ]]; then - echo "test-core: TIMEOUT — killing descendants" >&2 - pkill -9 -f "dart test" 2>/dev/null || true - exit 1 - fi - exit $rc - fi + dart test -r "$REPORTER" --timeout "$TEST_TIMEOUT" "$@" } # Some core tests must not share the parallel pool: @@ -58,10 +51,10 @@ run_pass() { # record_id migration.) # Run both in one --concurrency=1 pass (matching ci/test.sh's serial handling), # then everything else in parallel. -echo "test-core: dart test (pty + serial; --concurrency=1) (timeout ${TIMEOUT_SECONDS}s)" +echo "test-core: dart test (pty + serial; --concurrency=1) (timeout ${TEST_TIMEOUT})" run_pass --concurrency=1 --tags "pty || serial" $CORE_DIRS -echo "test-core: dart test (rest; parallel, excludes pty + serial) (timeout ${TIMEOUT_SECONDS}s)" +echo "test-core: dart test (rest; parallel, excludes pty + serial) (timeout ${TEST_TIMEOUT})" run_pass --exclude-tags "pty || serial" $CORE_DIRS echo "test-core: ok"