|
| 1 | +#!/usr/bin/env bash |
| 2 | +# run-all-tests.sh — aggregate entry for every fixture suite under |
| 3 | +# scripts/tests/*/test.sh (#217). This is the missing enforcement link for the |
| 4 | +# repo's drift-guard hard locks: suites existed but nothing ran them |
| 5 | +# automatically (#214 R2 DA finding 15). |
| 6 | +# |
| 7 | +# Behavior: |
| 8 | +# - runs EVERY suite (no fail-fast) and prints a per-suite summary table |
| 9 | +# - per-suite timeout (default 180s, IDD_SUITE_TIMEOUT to override) so a |
| 10 | +# hung suite (FIFO writer class, #117 incident) cannot wedge CI |
| 11 | +# - exit 0 iff every suite passed; 1 otherwise |
| 12 | +# |
| 13 | +# Env: |
| 14 | +# IDD_TESTS_DIR override the suites dir (aggregator self-tests use this) |
| 15 | +# IDD_SUITE_TIMEOUT per-suite seconds (default 180) |
| 16 | + |
| 17 | +set -u |
| 18 | + |
| 19 | +HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" |
| 20 | +TESTS_DIR="${IDD_TESTS_DIR:-$HERE/tests}" |
| 21 | +SUITE_TIMEOUT="${IDD_SUITE_TIMEOUT:-180}" |
| 22 | + |
| 23 | +if [ ! -d "$TESTS_DIR" ]; then |
| 24 | + echo "✗ tests dir not found: $TESTS_DIR" >&2 |
| 25 | + exit 2 |
| 26 | +fi |
| 27 | + |
| 28 | +run_with_timeout() { # seconds cmd... — portable watchdog (macOS has no coreutils timeout) |
| 29 | + local secs="$1"; shift |
| 30 | + if command -v timeout >/dev/null 2>&1; then |
| 31 | + timeout "$secs" "$@" |
| 32 | + return $? |
| 33 | + fi |
| 34 | + "$@" & |
| 35 | + local pid=$! |
| 36 | + ( sleep "$secs"; kill -TERM "$pid" 2>/dev/null ) & |
| 37 | + local wd=$! |
| 38 | + wait "$pid" 2>/dev/null |
| 39 | + local rc=$? |
| 40 | + kill -TERM "$wd" 2>/dev/null; wait "$wd" 2>/dev/null |
| 41 | + return $rc |
| 42 | +} |
| 43 | + |
| 44 | +TOTAL=0; FAILED=0 |
| 45 | +declare -a ROWS=() |
| 46 | +shopt -s nullglob |
| 47 | +for t in "$TESTS_DIR"/*/test.sh; do |
| 48 | + name="$(basename "$(dirname "$t")")" |
| 49 | + TOTAL=$((TOTAL + 1)) |
| 50 | + start=$(date +%s) |
| 51 | + if run_with_timeout "$SUITE_TIMEOUT" bash "$t" > /tmp/idd-suite-"$name".log 2>&1; then |
| 52 | + rc=0; verdict="PASS" |
| 53 | + else |
| 54 | + rc=$?; FAILED=$((FAILED + 1)) |
| 55 | + if [ "$rc" -ge 124 ]; then verdict="TIMEOUT(${SUITE_TIMEOUT}s)"; else verdict="FAIL(rc=$rc)"; fi |
| 56 | + fi |
| 57 | + dur=$(( $(date +%s) - start )) |
| 58 | + ROWS+=("$(printf '%-32s %-14s %3ss' "$name" "$verdict" "$dur")") |
| 59 | + # surface the tail of failing suites immediately (CI log ergonomics) |
| 60 | + [ "$rc" -ne 0 ] && { echo "── $name output tail ──"; tail -15 /tmp/idd-suite-"$name".log; echo; } |
| 61 | +done |
| 62 | +shopt -u nullglob |
| 63 | + |
| 64 | +echo "══════ run-all-tests summary ══════" |
| 65 | +printf '%s\n' "${ROWS[@]:-"(no suites found)"}" |
| 66 | +echo "───────────────────────────────────" |
| 67 | +echo "suites: $TOTAL, failed: $FAILED" |
| 68 | +[ "$TOTAL" -gt 0 ] && [ "$FAILED" -eq 0 ] |
0 commit comments