Six test runner scripts at tests/: run-rust, run-godot, run-ipc-fixtures, run-ipc-protocol, run-ipc-integration, run-all. Plus run-ipc-benchmark for Layer 3 timing. All produce structured JSON stdout, support --filter, and exit 0/non-zero. Makefile targets updated to delegate to scripts. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
89 lines
3.1 KiB
Bash
Executable File
89 lines
3.1 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# tests/run-godot: Run Godot client test suite via gdUnit4 (D-030)
|
|
# Exit: 0 = all pass, non-zero = failure
|
|
# Stdout: {"suite":"godot","total":N,"passed":N,"failed":N,"duration_ms":N}
|
|
#
|
|
# --filter: accepts a test filename stem (e.g. "test_protocol" → runs test_protocol.gd only)
|
|
set -euo pipefail
|
|
|
|
FILTER=""
|
|
while [[ $# -gt 0 ]]; do
|
|
case "$1" in
|
|
--filter) FILTER="${2:-}"; shift 2 ;;
|
|
--filter=*) FILTER="${1#--filter=}"; shift ;;
|
|
*) echo "Unknown argument: $1" >&2; exit 2 ;;
|
|
esac
|
|
done
|
|
|
|
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
|
|
GODOT=$(command -v godot4 2>/dev/null || command -v godot 2>/dev/null || echo "")
|
|
if [[ -z "$GODOT" ]]; then
|
|
printf '{"suite":"godot","total":0,"passed":0,"failed":0,"duration_ms":0,"error":"godot not found in PATH"}\n'
|
|
exit 1
|
|
fi
|
|
|
|
# Resolve the test target: directory or specific file
|
|
if [[ -n "$FILTER" ]]; then
|
|
# Support bare name (test_protocol) or full path (test_protocol.gd)
|
|
if [[ "$FILTER" == res://* ]]; then
|
|
TEST_TARGET="$FILTER"
|
|
elif [[ "$FILTER" == *.gd ]]; then
|
|
TEST_TARGET="res://tests/$FILTER"
|
|
else
|
|
TEST_TARGET="res://tests/${FILTER}.gd"
|
|
fi
|
|
else
|
|
TEST_TARGET="res://tests/"
|
|
fi
|
|
|
|
START_MS=$(date +%s%3N)
|
|
TMPOUT=$(mktemp)
|
|
|
|
set +e
|
|
"$GODOT" --headless --path "$REPO_ROOT/client" \
|
|
-s res://addons/gdUnit4/bin/GdUnitCmdTool.gd \
|
|
--ignoreHeadlessMode \
|
|
-c \
|
|
-a "$TEST_TARGET" \
|
|
2>&1 | tee "$TMPOUT" >&2
|
|
EXIT_CODE=${PIPESTATUS[0]}
|
|
set -e
|
|
|
|
END_MS=$(date +%s%3N)
|
|
DURATION_MS=$((END_MS - START_MS))
|
|
|
|
_extract_num() {
|
|
local haystack="$1" pattern="$2"
|
|
echo "$haystack" | grep -oiE "[0-9]+ $pattern" | grep -oE '^[0-9]+' || echo 0
|
|
}
|
|
|
|
# gdUnit4 outputs per-suite statistics: "N test cases | X errors | Y failures | ..."
|
|
# and a summary: "Executed test cases : (X/N)" or "Executed test cases : (X/N), Z skipped"
|
|
TOTAL=0; PASSED=0; FAILED=0
|
|
|
|
# Sum errors + failures across all suite statistics lines
|
|
STATS_LINES=$(grep -oE "[0-9]+ test cases \| [0-9]+ errors \| [0-9]+ failures" "$TMPOUT" || true)
|
|
if [[ -n "$STATS_LINES" ]]; then
|
|
TOTAL=$(echo "$STATS_LINES" | grep -oE '^[0-9]+' | awk '{s+=$1} END {print s}')
|
|
ERRORS=$(echo "$STATS_LINES" | grep -oE '[0-9]+ errors' | grep -oE '^[0-9]+' | awk '{s+=$1} END {print s}')
|
|
FAILURES=$(echo "$STATS_LINES" | grep -oE '[0-9]+ failures' | grep -oE '^[0-9]+' | awk '{s+=$1} END {print s}')
|
|
FAILED=$(( ${ERRORS:-0} + ${FAILURES:-0} ))
|
|
PASSED=$(( TOTAL - FAILED ))
|
|
fi
|
|
|
|
# Fallback: parse "Executed test cases : (X/N)" for total if stats parse failed
|
|
if [[ "$TOTAL" -eq 0 ]]; then
|
|
EXEC_LINE=$(grep -oE "Executed test cases : \([0-9]+/[0-9]+\)" "$TMPOUT" | tail -1 || true)
|
|
if [[ -n "$EXEC_LINE" ]]; then
|
|
TOTAL=$(echo "$EXEC_LINE" | grep -oE '/[0-9]+\)' | grep -oE '[0-9]+')
|
|
PASSED=$(echo "$EXEC_LINE" | grep -oE '\([0-9]+/' | grep -oE '[0-9]+')
|
|
FAILED=$(( TOTAL - PASSED ))
|
|
fi
|
|
fi
|
|
|
|
rm -f "$TMPOUT"
|
|
printf '{"suite":"godot","total":%d,"passed":%d,"failed":%d,"duration_ms":%d}\n' \
|
|
"${TOTAL:-0}" "${PASSED:-0}" "${FAILED:-0}" "$DURATION_MS"
|
|
exit $EXIT_CODE
|