guanghu/.chunk/run-playwright-shards.sh

147 lines
3.6 KiB
Bash
Raw Permalink Normal View History

#!/usr/bin/env bash
set -euo pipefail
total_shards="${1:-${PLAYWRIGHT_SHARDS:-8}}"
concurrency="${PLAYWRIGHT_CONCURRENCY:-$total_shards}"
log_dir="${TMPDIR:-/tmp}/tolaria-playwright-shards-$$"
batch_pids=()
shared_server="${PLAYWRIGHT_SHARED_SERVER:-1}"
server_port="${PLAYWRIGHT_SMOKE_PORT:-41741}"
base_url="${BASE_URL:-http://127.0.0.1:${server_port}}"
server_port="$(node -e 'console.log(new URL(process.argv[1]).port || "41741")' "$base_url")"
server_pid=""
if [[ ! "$total_shards" =~ ^[1-9][0-9]*$ ]]; then
printf 'Usage: %s [total-shards]\n' "$0" >&2
exit 2
fi
if [[ ! "$concurrency" =~ ^[1-9][0-9]*$ ]]; then
printf 'PLAYWRIGHT_CONCURRENCY must be a positive integer\n' >&2
exit 2
fi
mkdir -p "$log_dir"
stop_shared_server() {
if [[ -z "$server_pid" ]]; then
return
fi
kill -TERM "$server_pid" 2>/dev/null || true
sleep 2
kill -KILL "$server_pid" 2>/dev/null || true
server_pid=""
}
cleanup() {
local status=$?
trap - EXIT INT TERM
for pid in "${batch_pids[@]:-}"; do
kill -TERM "$pid" 2>/dev/null || true
done
sleep 2
for pid in "${batch_pids[@]:-}"; do
kill -KILL "$pid" 2>/dev/null || true
done
stop_shared_server
exit "$status"
}
trap cleanup EXIT INT TERM
wait_for_shared_server() {
local deadline=$((SECONDS + 30))
until curl -fsS "$base_url" >/dev/null 2>&1; do
if [[ -n "$server_pid" ]] && ! kill -0 "$server_pid" 2>/dev/null; then
printf '[chunk-playwright] shared server exited before becoming ready\n' >&2
sed 's/^/[shared-server] /' "${log_dir}/shared-server.log" >&2 || true
return 1
fi
if [[ "$SECONDS" -ge "$deadline" ]]; then
printf '[chunk-playwright] shared server did not become ready at %s\n' "$base_url" >&2
sed 's/^/[shared-server] /' "${log_dir}/shared-server.log" >&2 || true
return 1
fi
sleep 1
done
}
start_shared_server() {
if [[ "$shared_server" != "1" ]]; then
return
fi
printf '[chunk-playwright] starting shared server at %s\n' "$base_url"
TOLARIA_VITE_CACHE_DIR="${TOLARIA_VITE_CACHE_DIR:-${TMPDIR:-/tmp}/tolaria-vite-smoke-shared}" \
node scripts/playwright-smoke-server.mjs "$server_port" >"${log_dir}/shared-server.log" 2>&1 &
server_pid="$!"
wait_for_shared_server
}
run_batch() {
local first_shard="$1"
local failures=0
local names=()
local shard="$first_shard"
batch_pids=()
while [[ "$shard" -le "$total_shards" && "${#batch_pids[@]}" -lt "$concurrency" ]]; do
local name="smoke-${shard}-${total_shards}"
local log_file="${log_dir}/${name}.log"
printf '[chunk-playwright] starting %s\n' "$name"
if [[ "$shared_server" == "1" ]]; then
BASE_URL="$base_url" PLAYWRIGHT_REUSE_SERVER=1 PLAYWRIGHT_SMOKE_PORT="$server_port" \
bash .chunk/run-playwright-smoke.sh "${shard}/${total_shards}" >"$log_file" 2>&1 &
else
bash .chunk/run-playwright-smoke.sh "${shard}/${total_shards}" >"$log_file" 2>&1 &
fi
batch_pids+=("$!")
names+=("$name")
shard=$((shard + 1))
done
for index in "${!batch_pids[@]}"; do
local pid="${batch_pids[$index]}"
local name="${names[$index]}"
local log_file="${log_dir}/${name}.log"
if wait "$pid"; then
printf '[chunk-playwright] %s passed\n' "$name"
else
failures=1
printf '[chunk-playwright] %s failed\n' "$name"
fi
sed "s/^/[${name}] /" "$log_file"
done
batch_pids=()
return "$failures"
}
next_shard=1
failed=0
start_shared_server
while [[ "$next_shard" -le "$total_shards" ]]; do
if ! run_batch "$next_shard"; then
failed=1
fi
next_shard=$((next_shard + concurrency))
done
stop_shared_server
exit "$failed"