Files
elmprodvpn/tests/api_sanity.sh

76 lines
2.6 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
check_json_get() {
local path="$1"
local keys_csv="$2"
local out_file="$TMP_DIR/out.json"
local code
code="$(curl -sS --max-time 15 -o "$out_file" -w "%{http_code}" "${API_URL}${path}")"
if [[ "$code" != "200" ]]; then
echo "[sanity] ${path} -> HTTP ${code}" >&2
cat "$out_file" >&2 || true
return 1
fi
python3 - "$out_file" "$keys_csv" "$path" <<'PY'
import json
import sys
file_path, keys_csv, path = sys.argv[1], sys.argv[2], sys.argv[3]
keys = [k for k in keys_csv.split(",") if k]
with open(file_path, "r", encoding="utf-8") as f:
data = json.load(f)
for key in keys:
if key not in data:
print(f"[sanity] {path}: missing key '{key}'", file=sys.stderr)
sys.exit(1)
print(f"[sanity] {path}: OK")
PY
}
echo "[sanity] API_URL=${API_URL}"
check_json_get "/healthz" "status,time"
check_json_get "/api/v1/status" "timestamp,iface,table"
check_json_get "/api/v1/routes/status" "timestamp,iface,table"
check_json_get "/api/v1/traffic/mode" "mode,healthy,message"
check_json_get "/api/v1/traffic/interfaces" "interfaces,preferred_iface,active_iface"
check_json_get "/api/v1/dns/status" "mode,smartdns_addr,via_smartdns"
check_json_get "/api/v1/vpn/status" "status_word,unit_state"
check_json_get "/api/v1/vpn/autoloop-status" "status_word,raw_text"
check_json_get "/api/v1/routes/timer" "enabled"
# Method check: POST-only endpoint should reject GET.
code="$(curl -sS --max-time 10 -o /dev/null -w "%{http_code}" "${API_URL}/api/v1/routes/update")"
if [[ "$code" != "405" ]]; then
echo "[sanity] /api/v1/routes/update GET expected 405, got ${code}" >&2
exit 1
fi
echo "[sanity] method guard OK (/api/v1/routes/update GET => 405)"
# Quick stream availability: open SSE briefly; timeout is expected.
headers_file="$TMP_DIR/events.headers"
set +e
http_code="$(curl -sS --max-time 2 -D "$headers_file" -o /dev/null -w "%{http_code}" "${API_URL}/api/v1/events/stream")"
curl_rc=$?
set -e
if [[ "$http_code" != "200" ]]; then
echo "[sanity] /api/v1/events/stream -> HTTP ${http_code}" >&2
cat "$headers_file" >&2 || true
exit 1
fi
if [[ $curl_rc -ne 0 && $curl_rc -ne 28 ]]; then
echo "[sanity] unexpected curl rc=${curl_rc} for events stream" >&2
exit 1
fi
if ! grep -qi '^Content-Type: text/event-stream' "$headers_file"; then
echo "[sanity] /api/v1/events/stream missing text/event-stream content-type" >&2
cat "$headers_file" >&2 || true
exit 1
fi
echo "[sanity] events stream headers OK (curl rc=${curl_rc})"
echo "[sanity] all checks passed"