dragonflight/deploy/api-smoke.sh
claude 7700548dee test: deploy/api-smoke.sh — exercises every API surface
Walks GET endpoints for auth, projects, assets, recorders, jobs, bins,
users, groups, cluster, settings, metrics, schedules, sdk, and the
freshly added comments routes. Deep-links one asset + one recorder by
ID so per-asset endpoints (stream, thumbnail, comments) get coverage.

Prints HTTP codes inline and exits non-zero on any failure. Treats
2xx/3xx as pass; 400/401 also pass since they indicate the route
exists and auth/validation is working as designed.

Usage:
  deploy/api-smoke.sh                      # localhost:47432
  API=http://10.0.0.25:47432 deploy/api-smoke.sh

NewRecorderModal: hardened ZAMPP_DATA hydration with defensive
defaults so first-load timing doesn't blow up the modal.
2026-05-23 04:24:10 +00:00

104 lines
3.6 KiB
Bash
Executable file

#!/usr/bin/env bash
# Dragonflight MAM API smoke test
#
# Hits every read-only endpoint and a handful of safe write endpoints
# against a running mam-api. Reports per-endpoint HTTP code + a one-line
# pass/fail. Exits non-zero on any failure.
#
# Usage:
# deploy/api-smoke.sh # against http://localhost:47432
# API=http://10.0.0.25:47432 deploy/api-smoke.sh
set -u
API="${API:-http://localhost:47432}"
PASS=0
FAIL=0
# Per-endpoint check. Args: METHOD PATH EXPECTED_HTTP_CODE [BODY]
# Treats anything < 500 as OK by default; auth-gated endpoints typically
# return 401 with AUTH_ENABLED, also acceptable.
hit() {
local method="$1" path="$2" expect="${3:-2..}" body="${4:-}"
local args=(-s -o /dev/null -w '%{http_code}' -X "$method" "${API}${path}")
if [ -n "$body" ]; then args+=(-H 'Content-Type: application/json' -d "$body"); fi
local code
code=$(curl "${args[@]}" 2>/dev/null || echo "000")
if [[ "$code" =~ ^(2|3|401|400)[0-9][0-9]$ ]]; then
printf " %s %-40s %s OK\n" "$method" "$path" "$code"
PASS=$((PASS + 1))
else
printf " %s %-40s %s FAIL\n" "$method" "$path" "$code"
FAIL=$((FAIL + 1))
fi
}
echo "Dragonflight API smoke test — target ${API}"
echo ""
echo "── auth ──────────────────────────────────────────"
hit GET /api/v1/auth/me
echo ""
echo "── core lists ────────────────────────────────────"
hit GET /api/v1/projects
hit GET /api/v1/assets
hit GET /api/v1/assets?limit=5
hit GET /api/v1/recorders
hit GET /api/v1/jobs
hit GET /api/v1/bins
hit GET /api/v1/users
hit GET /api/v1/groups
hit GET /api/v1/cluster
hit GET /api/v1/cluster/containers
hit GET /api/v1/cluster/devices/blackmagic
echo ""
echo "── settings ──────────────────────────────────────"
hit GET /api/v1/settings/s3
hit GET /api/v1/settings/transcoding
hit GET /api/v1/settings/growing
hit GET /api/v1/settings/ampp
hit GET /api/v1/settings/hardware
hit GET /api/v1/settings/capture-service
echo ""
echo "── feature endpoints ─────────────────────────────"
hit GET /api/v1/metrics/home
hit GET /api/v1/metrics/home?hours=1
hit GET /api/v1/schedules
hit GET /api/v1/schedules?status=upcoming
hit GET /api/v1/sdk
echo ""
echo "── deep-link sanity (one asset) ──────────────────"
ASSET_ID=$(curl -s "${API}/api/v1/assets?limit=1" 2>/dev/null \
| sed -n 's/.*"id":"\([0-9a-f-]\{36\}\)".*/\1/p' | head -1)
if [ -n "$ASSET_ID" ]; then
echo " using asset_id=$ASSET_ID"
hit GET "/api/v1/assets/$ASSET_ID"
hit GET "/api/v1/assets/$ASSET_ID/comments"
hit GET "/api/v1/assets/$ASSET_ID/stream"
hit GET "/api/v1/assets/$ASSET_ID/thumbnail"
else
echo " (no assets to deep-link; skipping per-asset endpoints)"
fi
echo ""
echo "── deep-link sanity (one recorder) ───────────────"
REC_ID=$(curl -s "${API}/api/v1/recorders" 2>/dev/null \
| sed -n 's/.*"id":"\([0-9a-f-]\{36\}\)".*/\1/p' | head -1)
if [ -n "$REC_ID" ]; then
echo " using recorder_id=$REC_ID"
hit GET "/api/v1/recorders/$REC_ID"
hit GET "/api/v1/recorders/$REC_ID/status"
else
echo " (no recorders to deep-link)"
fi
echo ""
echo "── summary ───────────────────────────────────────"
echo " PASS: $PASS"
echo " FAIL: $FAIL"
[ "$FAIL" -eq 0 ]