kt-template-online-api/scripts/bangdream-render-smoke-matrix.sh

168 lines
4.1 KiB
Bash
Executable File

#!/usr/bin/env bash
set -Eeuo pipefail
SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)
PROJECT_ROOT=$(cd -- "$SCRIPT_DIR/.." && pwd -P)
NODE_RUNNER="$SCRIPT_DIR/bangdream-render-smoke-matrix.cjs"
out_dir=".kt-workspace/bangdream-smoke/matrix"
timeout_seconds=240
skip_external_player=false
child_pid=""
# Prints command usage without performing render or network work.
print_help() {
cat <<'EOF'
Usage: bangdream-render-smoke-matrix.sh [options]
Run the bounded BangDream render matrix and write its JSON summary.
Options:
--out-dir PATH Matrix output directory
--timeout-seconds SECONDS Whole-process timeout (default: 240)
--skip-external-player Skip the external player lookup case
-h, --help Show this help
EOF
}
# Reports an invalid invocation and exits with the standard usage status.
usage_error() {
printf 'Error: %s\n\n' "$1" >&2
print_help >&2
exit 2
}
# Returns success when a value is an integer greater than zero.
is_positive_integer() {
[[ $1 =~ ^[1-9][0-9]*$ ]]
}
# Stops the matrix child started by this script and reaps it.
cleanup_child() {
if [[ -n ${child_pid:-} ]] && kill -0 "$child_pid" 2>/dev/null; then
kill -TERM "$child_pid" 2>/dev/null || true
for _ in {1..20}; do
if ! kill -0 "$child_pid" 2>/dev/null; then
break
fi
sleep 0.1
done
if kill -0 "$child_pid" 2>/dev/null; then
kill -KILL "$child_pid" 2>/dev/null || true
fi
wait "$child_pid" 2>/dev/null || true
fi
child_pid=""
}
# Converts an interrupt signal into a deterministic exit after cleanup.
# shellcheck disable=SC2317 # Invoked indirectly by trap.
handle_interrupt() {
cleanup_child
exit 130
}
# Converts a termination signal into a deterministic exit after cleanup.
# shellcheck disable=SC2317 # Invoked indirectly by trap.
handle_termination() {
cleanup_child
exit 143
}
# Replays captured output while preserving stdout and stderr separation.
print_logs() {
[[ -f $stdout_log ]] && cat -- "$stdout_log"
[[ -f $stderr_log ]] && cat -- "$stderr_log" >&2
}
while (($# > 0)); do
case "$1" in
--out-dir)
(($# >= 2)) || usage_error "--out-dir requires a value"
out_dir=$2
shift 2
;;
--timeout-seconds)
(($# >= 2)) || usage_error "--timeout-seconds requires a value"
timeout_seconds=$2
shift 2
;;
--skip-external-player)
skip_external_player=true
shift
;;
-h|--help)
print_help
exit 0
;;
--)
shift
(($# == 0)) || usage_error "unexpected positional argument: $1"
;;
*)
usage_error "unknown argument: $1"
;;
esac
done
[[ -n $out_dir ]] || usage_error "--out-dir cannot be empty"
is_positive_integer "$timeout_seconds" || usage_error "--timeout-seconds must be a positive integer"
if [[ $out_dir = /* ]]; then
resolved_out_dir=$out_dir
else
resolved_out_dir="$PROJECT_ROOT/$out_dir"
fi
mkdir -p -- "$resolved_out_dir"
stdout_log="$resolved_out_dir/matrix.out.log"
stderr_log="$resolved_out_dir/matrix.err.log"
summary_file="$resolved_out_dir/matrix-summary.json"
rm -f -- "$stdout_log" "$stderr_log" "$summary_file"
trap cleanup_child EXIT
trap handle_interrupt INT
trap handle_termination TERM
cd -- "$PROJECT_ROOT"
TS_NODE_TRANSPILE_ONLY=true \
BANGDREAM_MATRIX_OUT_DIR=$resolved_out_dir \
BANGDREAM_MATRIX_SKIP_EXTERNAL_PLAYER=$skip_external_player \
node -r ts-node/register -r tsconfig-paths/register "$NODE_RUNNER" \
>"$stdout_log" 2>"$stderr_log" &
child_pid=$!
deadline=$((SECONDS + timeout_seconds))
timed_out=false
while kill -0 "$child_pid" 2>/dev/null; do
if ((SECONDS >= deadline)); then
timed_out=true
cleanup_child
break
fi
sleep 0.5
done
if [[ $timed_out == true ]]; then
printf 'BangDream smoke matrix timed out after %s seconds and its process was killed.\n' "$timeout_seconds"
print_logs
exit 124
fi
process_status=0
if [[ -n $child_pid ]]; then
if wait "$child_pid"; then
process_status=0
else
process_status=$?
fi
child_pid=""
fi
print_logs
if [[ ! -f $summary_file ]]; then
printf 'BangDream smoke matrix did not produce a summary file.\n'
exit 1
fi
exit "$process_status"