Files
elmprodvpn/tests/vpn_locations_swr.sh

92 lines
2.4 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
API_URL="${API_URL:-http://127.0.0.1:8080}"
TMP_DIR="$(mktemp -d)"
trap 'rm -rf "$TMP_DIR"' EXIT
req_json() {
local path="$1"
local out_file="$2"
local code
local total
local metrics
metrics="$(curl -sS --max-time 6 -o "$out_file" -w "%{http_code} %{time_total}" "${API_URL}${path}")"
code="${metrics%% *}"
total="${metrics#* }"
if [[ "$code" != "200" ]]; then
echo "[vpn_locations] ${path} -> HTTP ${code}" >&2
cat "$out_file" >&2 || true
return 1
fi
printf "%s\n" "$total"
}
echo "[vpn_locations] API_URL=${API_URL}"
# Trigger background refresh (handler must respond immediately from cache/SWR path).
t1="$(req_json "/api/v1/vpn/locations?refresh=1" "$TMP_DIR/refresh.json")"
echo "[vpn_locations] refresh request time=${t1}s"
# Read current state snapshot.
t2="$(req_json "/api/v1/vpn/locations" "$TMP_DIR/state.json")"
echo "[vpn_locations] snapshot request time=${t2}s"
python3 - "$TMP_DIR/state.json" <<'PY'
import json
import sys
path = sys.argv[1]
with open(path, "r", encoding="utf-8") as f:
data = json.load(f)
required = ("locations", "stale", "refresh_in_progress")
for k in required:
if k not in data:
raise SystemExit(f"[vpn_locations] missing key: {k}")
if not isinstance(data["locations"], list):
raise SystemExit("[vpn_locations] locations must be array")
if not isinstance(data["stale"], bool):
raise SystemExit("[vpn_locations] stale must be bool")
if not isinstance(data["refresh_in_progress"], bool):
raise SystemExit("[vpn_locations] refresh_in_progress must be bool")
print(
"[vpn_locations] keys OK:",
f"count={len(data['locations'])}",
f"stale={data['stale']}",
f"refresh_in_progress={data['refresh_in_progress']}",
)
PY
# Poll short window: refresh should eventually finish or provide retry metadata.
ok=0
for _ in $(seq 1 12); do
req_json "/api/v1/vpn/locations" "$TMP_DIR/poll.json" >/dev/null
if python3 - "$TMP_DIR/poll.json" <<'PY'
import json
import sys
with open(sys.argv[1], "r", encoding="utf-8") as f:
data = json.load(f)
if not data.get("refresh_in_progress", False):
raise SystemExit(0)
if data.get("next_retry_at"):
raise SystemExit(0)
raise SystemExit(1)
PY
then
ok=1
break
fi
sleep 1
done
if [[ "$ok" != "1" ]]; then
echo "[vpn_locations] refresh state did not settle in expected window" >&2
cat "$TMP_DIR/poll.json" >&2 || true
exit 1
fi
echo "[vpn_locations] SWR checks passed"