76 lines
2.6 KiB
Bash
Executable File
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"
|