uce/scripts/test_parallel_precompile.sh

120 lines
5.4 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
cd "$(dirname "$0")/.."
test_name="parallel-precompile-test-$$"
site_directory="site"
bin_directory="/tmp/uce/work"
if [[ -r /etc/uce/settings.cfg ]]; then
configured_precompile=$(awk -F= '/^[[:space:]]*PRECOMPILE_FILES_IN[[:space:]]*=/ {sub(/^[^=]*=/, ""); gsub(/^[[:space:]]+|[[:space:]]+$/, ""); print; exit}' /etc/uce/settings.cfg)
configured_site=$(awk -F= '/^[[:space:]]*SITE_DIRECTORY[[:space:]]*=/ {sub(/^[^=]*=/, ""); gsub(/^[[:space:]]+|[[:space:]]+$/, ""); print; exit}' /etc/uce/settings.cfg)
configured_bin=$(awk -F= '/^[[:space:]]*BIN_DIRECTORY[[:space:]]*=/ {sub(/^[^=]*=/, ""); gsub(/^[[:space:]]+|[[:space:]]+$/, ""); print; exit}' /etc/uce/settings.cfg)
site_directory="${configured_precompile:-${configured_site:-$site_directory}}"
bin_directory="${configured_bin:-$bin_directory}"
fi
source_dir="$site_directory/$test_name"
absolute_source_dir=""
artifact_dir=""
cleanup() {
rm -rf "$source_dir"
if [[ -x bin/uce_fastcgi.linux.bin ]]; then
UCE_PRECOMPILE_JOBS=1 bin/uce_fastcgi.linux.bin --precompile >/dev/null 2>&1 || true
fi
if [[ -n "$artifact_dir" ]]; then
rm -rf "$artifact_dir"
fi
}
trap cleanup EXIT
mkdir -p "$source_dir"
absolute_source_dir=$(realpath "$source_dir")
artifact_dir="$(scripts/unit_cache_directory "$bin_directory")$absolute_source_dir"
write_units() {
local version="$1"
for unit in 0 1 2 3; do
printf 'CLI(Request& context) { print("parallel-precompile-%s-%s"); }\n' "$version" "$unit" >"$source_dir/unit-$unit.uce"
done
}
printf 'CLI(Request& context) { print("parallel-precompile-warmup"); }\n' >"$source_dir/warmup.uce"
UCE_PRECOMPILE_JOBS=1 UCE_WASM_PCH_DIR="$artifact_dir/pch-shared" bin/uce_fastcgi.linux.bin --precompile >/dev/null
rm "$source_dir/warmup.uce"
write_units serial
serial_start=$(date +%s%N)
serial_output=$(UCE_PRECOMPILE_JOBS=1 UCE_WASM_PCH_DIR="$artifact_dir/pch-shared" bin/uce_fastcgi.linux.bin --precompile)
serial_ns=$(( $(date +%s%N) - serial_start ))
if ! grep -Eq 'with 1 job: .* 4 compiled, 0 failed, worker status ok' <<<"$serial_output"; then
echo "serial precompile did not compile the four controlled units" >&2
echo "$serial_output" >&2
exit 1
fi
write_units parallel
parallel_start=$(date +%s%N)
parallel_output=$(UCE_PRECOMPILE_JOBS=2 UCE_WASM_PCH_DIR="$artifact_dir/pch-shared" bin/uce_fastcgi.linux.bin --precompile)
parallel_ns=$(( $(date +%s%N) - parallel_start ))
if [[ $(grep -Ec '^Precompile worker [12]/2:' <<<"$parallel_output") -ne 2 ]]; then
echo "parallel precompile did not report both workers" >&2
echo "$parallel_output" >&2
exit 1
fi
if ! grep -Eq 'with 2 jobs: .* 4 compiled, 0 failed, worker status ok' <<<"$parallel_output"; then
echo "parallel precompile did not compile the four controlled units" >&2
echo "$parallel_output" >&2
exit 1
fi
for unit in 0 1 2 3; do
if [[ ! -s "$artifact_dir/unit-$unit.uce.wasm" || ! -s "$artifact_dir/unit-$unit.uce.cwasm" ]]; then
echo "parallel precompile did not publish wasm and serialized artifacts for unit $unit" >&2
exit 1
fi
done
printf 'CLI(Request& context) { print("parallel-precompile-race-0"); }\n' >"$source_dir/race-0.uce"
printf 'CLI(Request& context) { print("parallel-precompile-race-1"); }\n' >"$source_dir/race-1.uce"
race_output=$(UCE_PRECOMPILE_JOBS=2 UCE_WASM_PCH_DIR="$artifact_dir/pch-race" bin/uce_fastcgi.linux.bin --precompile)
if ! grep -Eq 'with 2 jobs: .* 2 compiled, 0 failed, worker status ok' <<<"$race_output" || \
[[ $(find "$artifact_dir/pch-race" -maxdepth 1 -type f -name '*.pch' | wc -l) -ne 1 ]] || \
find "$artifact_dir/pch-race" -maxdepth 1 -type f -name '*.tmp.*' -print -quit | grep -q .; then
echo "parallel precompile did not publish exactly one clean shared PCH" >&2
echo "$race_output" >&2
exit 1
fi
rm "$source_dir/race-0.uce" "$source_dir/race-1.uce"
printf 'CLI(Request& context) { print(deliberate_parallel_precompile_failure); }\n' >"$source_dir/broken.uce"
set +e
failure_output=$(UCE_PRECOMPILE_JOBS=2 UCE_WASM_PCH_DIR="$artifact_dir/pch-shared" bin/uce_fastcgi.linux.bin --precompile 2>&1)
failure_rc=$?
set -e
if [[ $failure_rc -eq 0 ]] || ! grep -Eq 'with 2 jobs: .* 1 failed, worker status failed' <<<"$failure_output"; then
echo "parallel precompile did not aggregate a controlled worker failure" >&2
echo "$failure_output" >&2
exit 1
fi
set +e
repeat_failure_output=$(UCE_PRECOMPILE_JOBS=2 UCE_WASM_PCH_DIR="$artifact_dir/pch-shared" bin/uce_fastcgi.linux.bin --precompile 2>&1)
repeat_failure_rc=$?
set -e
if [[ $repeat_failure_rc -eq 0 ]] || ! grep -Eq 'with 2 jobs: .* 1 failed, worker status failed' <<<"$repeat_failure_output"; then
echo "parallel precompile accepted a persisted current compile failure" >&2
echo "$repeat_failure_output" >&2
exit 1
fi
rm "$source_dir/broken.uce"
negative_jobs_output=$(UCE_PRECOMPILE_JOBS=-1 bin/uce_fastcgi.linux.bin --precompile)
malformed_jobs_output=$(UCE_PRECOMPILE_JOBS=invalid bin/uce_fastcgi.linux.bin --precompile)
oversized_jobs_output=$(UCE_PRECOMPILE_JOBS=17 bin/uce_fastcgi.linux.bin --precompile)
if ! grep -q 'with 1 job:' <<<"$negative_jobs_output" || ! grep -q 'with 2 jobs:' <<<"$malformed_jobs_output" || ! grep -q 'with 16 jobs:' <<<"$oversized_jobs_output"; then
echo "precompile job bounds did not map negative/malformed/oversized input to 1/2/16" >&2
exit 1
fi
printf 'parallel precompile passed: serial %.3fs, parallel %.3fs\n' \
"$(awk -v ns="$serial_ns" 'BEGIN { print ns / 1000000000 }')" \
"$(awk -v ns="$parallel_ns" 'BEGIN { print ns / 1000000000 }')"