forge/testScripts/run.sh
2026-10-06 16:57:52 -05:00

62 lines
2.3 KiB
Bash
Executable file

#!/usr/bin/env bash
# Runs Forge's test scenes headless against a Singe binary and says which passed:
#
# testScripts/run.sh every scene
# testScripts/run.sh 52 58 83 just these
# SINGE=/path/to/Singe testScripts/run.sh
#
# Each runs from a fresh folder holding Forge/ (a copy of forge/) and testScripts/, the way a game
# directory holds a game, with --deterministic so a run is the same every time (scene 94 excepted). A scene fails when
# it prints a FAIL line, its script errors, or it does not quit within the time allowed. Logs and
# screenshots stay in build/tests/<scene>/. Nothing appears on screen.
set -uo pipefail
here=$(cd "$(dirname "$0")/.." && pwd)
singe=${SINGE:-$(ls -t "$here"/../singe/.builddir/Singe-v*-Linux-x86_64 2>/dev/null | head -1)}
out=$here/build/tests
limit=600
if [[ -z $singe || ! -x $singe ]]; then
echo "error: no Singe binary; set SINGE" >&2
exit 1
fi
scenes=("$@")
if [[ ${#scenes[@]} == 0 ]]; then
mapfile -t scenes < <(ls "$here"/testScripts/scene*.singe | sed 's/.*scene\([0-9]*\)\.singe/\1/' | sort -n)
fi
run="$out/run"
rm -rf "$run"
mkdir -p "$run"
cp -r "$here/forge" "$run/Forge"
cp -r "$here/testScripts" "$run/testScripts"
passed=0
failed=()
for n in "${scenes[@]}"; do
log="$out/scene$n"
rm -rf "$log"
mkdir -p "$log"
# The disc each scene wants: the menu's own video, the kit's clip, or none.
disc=()
case $n in
59|68|96|98) disc=(-v Singe/menuBackground.mkv);;
87|88) disc=(-v "$run/Forge/kit/clip.mkv");;
esac
# Scene 94 waits for a clip to finish playing, which only the mixer's own clock says; under
# --deterministic the frames outrun it.
clock=(--deterministic)
if [[ $n == 94 ]]; then
clock=()
fi
(cd "$run" && SDL_VIDEODRIVER=offscreen SDL_AUDIO_DRIVER=disk SDL_DISKAUDIOFILE=/dev/null timeout -k 10 $limit "$singe" -k "${clock[@]}" "${disc[@]}" -d "$log/data" "testScripts/scene$n.singe" > "$log/log.txt" 2>&1)
status=$?
if [[ $status != 0 ]] || grep -q -E 'FAIL|Error running script|Error executing' "$log/log.txt"; then
failed+=("$n")
echo "scene$n FAILED (exit $status): $(grep -m1 -E 'FAIL|Error' "$log/log.txt" | cut -c1-160)"
else
passed=$((passed + 1))
echo "scene$n ok"
fi
done
echo "$passed passed, ${#failed[@]} failed${failed[*]:+: ${failed[*]}}"
[[ ${#failed[@]} == 0 ]]