Private
Public Access
Keep the compile-time generic marker as *. Update the compiler, stdlib, fixtures, documentation and editor grammars without a dynamic type alias. Preserve native identifiers and historical work and patch records. Replace the port_spawn environment argument with cwd/env options. Report failed directory changes through EXIT 127 with cwd_failed. Compile every API example and add a complete Pi RPC service example. Service examples compile without execution or output blocks. Update ABI versions and audited golden artifacts.
124 lines
4.1 KiB
Bash
Executable File
124 lines
4.1 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
cd "$(dirname "$0")/.."
|
|
|
|
test_name="component-resolution-ttl-test-$$"
|
|
site_directory="${BEARER_TEST_SITE_DIRECTORY:-site}"
|
|
worker_count="${BEARER_TEST_WORKER_COUNT:-4}"
|
|
if [[ -r /etc/bearer/settings.cfg ]]; then
|
|
if [[ -z "${BEARER_TEST_SITE_DIRECTORY:-}" ]]; then
|
|
configured_site_directory=$(awk -F= '/^[[:space:]]*SITE_DIRECTORY[[:space:]]*=/ {gsub(/^[[:space:]]+|[[:space:]]+$/, "", $2); print $2; exit}' /etc/bearer/settings.cfg)
|
|
site_directory="${configured_site_directory:-$site_directory}"
|
|
fi
|
|
if [[ -z "${BEARER_TEST_WORKER_COUNT:-}" ]]; then
|
|
configured_worker_count=$(awk -F= '/^[[:space:]]*WORKER_COUNT[[:space:]]*=/ {gsub(/^[[:space:]]+|[[:space:]]+$/, "", $2); print $2; exit}' /etc/bearer/settings.cfg)
|
|
worker_count="${configured_worker_count:-$worker_count}"
|
|
fi
|
|
fi
|
|
http_host="${BEARER_TEST_HTTP_HOST:-bearer.openfu.com}"
|
|
source_dir="$site_directory/$test_name"
|
|
bin_directory="${BIN_DIRECTORY:-}"
|
|
if [[ -z "$bin_directory" && -r /etc/bearer/settings.cfg ]]; then
|
|
bin_directory=$(awk -F= '/^[[:space:]]*BIN_DIRECTORY[[:space:]]*=/ {gsub(/^[[:space:]]+|[[:space:]]+$/, "", $2); print $2; exit}' /etc/bearer/settings.cfg)
|
|
fi
|
|
bin_directory="${bin_directory:-/tmp/bearer/work}"
|
|
cache_dir=""
|
|
|
|
cleanup() {
|
|
rm -rf "$source_dir"
|
|
if [[ -n "$cache_dir" ]]; then
|
|
rm -rf "$cache_dir"
|
|
fi
|
|
}
|
|
trap cleanup EXIT
|
|
mkdir -p "$source_dir"
|
|
cache_dir="$(scripts/unit_cache_directory "$bin_directory")$(realpath "$source_dir")"
|
|
|
|
cat >"$source_dir/parent.capy" <<'EOF'
|
|
function RENDER(request : any) {
|
|
var perf := runtime_perf()
|
|
print("parent:", string(perf.worker_pid), ":", component("chosen"))
|
|
}
|
|
EOF
|
|
printf '%s\n' 'function COMPONENT(request : any) { print("a") }' >"$source_dir/a.capy"
|
|
printf '%s\n' 'function COMPONENT(request : any) { print("b") }' >"$source_dir/b.capy"
|
|
ln -s a.capy "$source_dir/chosen.capy"
|
|
|
|
declare -A seen
|
|
collect_workers() {
|
|
local method="$1"
|
|
local marker="$2"
|
|
local path="${3:-parent.capy}"
|
|
local deadline=$((SECONDS + 30))
|
|
seen=()
|
|
while (( SECONDS < deadline && ${#seen[@]} < worker_count )); do
|
|
local response status body pid
|
|
response=$(curl -sS --max-time 10 -X "$method" -H "Host: $http_host" -w $'\n%{http_code}' "http://127.0.0.1/$test_name/$path")
|
|
status=${response##*$'\n'}
|
|
body=${response%$'\n'*}
|
|
if [[ "$status" == "503" ]]; then
|
|
sleep 0.1
|
|
continue
|
|
fi
|
|
if [[ "$status" != "200" || "$body" != parent:*":$marker" ]]; then
|
|
echo "component resolution TTL probe failed: method=$method status=$status expected=$marker body=$body" >&2
|
|
exit 1
|
|
fi
|
|
pid=${body#parent:}
|
|
pid=${pid%%:*}
|
|
seen["$pid"]=1
|
|
done
|
|
if (( ${#seen[@]} != worker_count )); then
|
|
echo "component resolution TTL probe reached ${#seen[@]}/$worker_count workers" >&2
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
collect_missing_workers() {
|
|
local deadline=$((SECONDS + 30))
|
|
seen=()
|
|
while (( SECONDS < deadline && ${#seen[@]} < worker_count )); do
|
|
local response status body pid
|
|
response=$(curl -sS --max-time 10 -H "Host: $http_host" -w $'\n%{http_code}' "http://127.0.0.1/$test_name/missing.capy")
|
|
status=${response##*$'\n'}
|
|
body=${response%$'\n'*}
|
|
if [[ "$status" == "503" ]]; then
|
|
sleep 0.1
|
|
continue
|
|
fi
|
|
if [[ "$status" != "500" || "$body" != parent:* ]]; then
|
|
echo "missing component TTL probe failed: status=$status body=$body" >&2
|
|
exit 1
|
|
fi
|
|
pid=${body#parent:}
|
|
pid=${pid%%:*}
|
|
seen["$pid"]=1
|
|
done
|
|
if (( ${#seen[@]} != worker_count )); then
|
|
echo "missing component TTL probe reached ${#seen[@]}/$worker_count workers" >&2
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
collect_workers GET a
|
|
sleep 10.2
|
|
collect_workers GET a
|
|
ln -sfn b.capy "$source_dir/chosen.capy"
|
|
# The site watch invalidates cached resolution on rename. TTL applies without inotify.
|
|
collect_workers GET b
|
|
collect_workers POST b
|
|
sleep 10.2
|
|
collect_workers GET b
|
|
|
|
cat >"$source_dir/missing.capy" <<'EOF'
|
|
function RENDER(request : any) {
|
|
var perf := runtime_perf()
|
|
print("parent:", string(perf.worker_pid), ":", component("later"))
|
|
}
|
|
EOF
|
|
collect_missing_workers
|
|
printf '%s\n' 'function COMPONENT(request : any) { print("created") }' >"$source_dir/later.capy"
|
|
collect_workers GET created missing.capy
|
|
|
|
echo "component resolution TTL passed"
|