#!/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 }')"