gomcp/tests/bench/bench.sh

116 lines
5 KiB
Bash

#!/usr/bin/env bash
# ═══════════════════════════════════════════════════════
# SENTINEL SOC — Performance Baseline (wrk2 / vegeta)
# ═══════════════════════════════════════════════════════
# Usage:
# ./bench.sh [SOC_URL] (default: http://localhost:9100)
#
# Requires: wrk2 or vegeta + jq
# pprof: SOC_PPROF=true go run ./cmd/soc/
# ═══════════════════════════════════════════════════════
set -euo pipefail
SOC="${1:-http://localhost:9100}"
DURATION="30s"
RATE=500 # requests/sec target
CONNECTIONS=10
echo "═══════════════════════════════════════════════════"
echo " SENTINEL SOC — Performance Benchmark"
echo " Target: $SOC"
echo " Duration: $DURATION | Rate: ${RATE} rps"
echo "═══════════════════════════════════════════════════"
# ── Health check ──
echo -e "\n[0] Health check..."
curl -sf "${SOC}/healthz" | jq . || { echo "FAIL: server not running"; exit 1; }
# ── Seed test data ──
echo -e "\n[1] Seeding test events..."
for i in $(seq 1 100); do
curl -sf -X POST "${SOC}/api/soc/events" \
-H "Content-Type: application/json" \
-d "{
\"source\": \"bench-sensor-$((i % 5))\",
\"severity\": \"MEDIUM\",
\"category\": \"prompt_injection\",
\"description\": \"Benchmark test event $i\",
\"confidence\": 0.$((RANDOM % 100))
}" > /dev/null 2>&1 || true
done
echo " Seeded 100 events"
# ── Benchmark: Read Events (GET) ──
echo -e "\n[2] GET /api/soc/events (read throughput)..."
if command -v wrk2 &>/dev/null; then
wrk2 -t2 -c${CONNECTIONS} -d${DURATION} -R${RATE} \
--latency "${SOC}/api/soc/events?limit=50"
elif command -v vegeta &>/dev/null; then
echo "GET ${SOC}/api/soc/events?limit=50" | \
vegeta attack -duration=${DURATION} -rate=${RATE}/1s -workers=${CONNECTIONS} | \
vegeta report
else
echo " [fallback] Using curl loop (install wrk2 or vegeta for proper benchmarks)"
START=$(date +%s%N)
for i in $(seq 1 500); do
curl -sf "${SOC}/api/soc/events?limit=50" > /dev/null 2>&1
done
END=$(date +%s%N)
ELAPSED=$(( (END - START) / 1000000 ))
echo " 500 requests in ${ELAPSED}ms ($(( 500000 / ELAPSED )) rps)"
fi
# ── Benchmark: Ingest Events (POST) ──
echo -e "\n[3] POST /api/soc/events (ingest throughput)..."
PAYLOAD='{"source":"bench","severity":"LOW","category":"anomaly","description":"Bench ingest","confidence":0.5}'
if command -v wrk2 &>/dev/null; then
wrk2 -t2 -c${CONNECTIONS} -d${DURATION} -R${RATE} \
--latency -s /dev/stdin "${SOC}/api/soc/events" <<'LUA'
wrk.method = "POST"
wrk.headers["Content-Type"] = "application/json"
wrk.body = '{"source":"bench","severity":"LOW","category":"anomaly","description":"Bench ingest","confidence":0.5}'
LUA
elif command -v vegeta &>/dev/null; then
jq -n --arg url "${SOC}/api/soc/events" --arg body "$PAYLOAD" \
'{method: "POST", url: $url, body: $body, header: {"Content-Type": ["application/json"]}}' | \
vegeta attack -duration=${DURATION} -rate=${RATE}/1s -workers=${CONNECTIONS} -format=json | \
vegeta report
else
echo " [fallback] curl loop"
START=$(date +%s%N)
for i in $(seq 1 500); do
curl -sf -X POST "${SOC}/api/soc/events" \
-H "Content-Type: application/json" -d "$PAYLOAD" > /dev/null 2>&1
done
END=$(date +%s%N)
ELAPSED=$(( (END - START) / 1000000 ))
echo " 500 POSTs in ${ELAPSED}ms ($(( 500000 / ELAPSED )) rps)"
fi
# ── Benchmark: Dashboard (aggregation) ──
echo -e "\n[4] GET /api/soc/dashboard (aggregation)..."
if command -v wrk2 &>/dev/null; then
wrk2 -t2 -c${CONNECTIONS} -d${DURATION} -R$(( RATE / 2 )) \
--latency "${SOC}/api/soc/dashboard"
elif command -v vegeta &>/dev/null; then
echo "GET ${SOC}/api/soc/dashboard" | \
vegeta attack -duration=${DURATION} -rate=$(( RATE / 2 ))/1s -workers=${CONNECTIONS} | \
vegeta report
else
START=$(date +%s%N)
for i in $(seq 1 200); do
curl -sf "${SOC}/api/soc/dashboard" > /dev/null 2>&1
done
END=$(date +%s%N)
ELAPSED=$(( (END - START) / 1000000 ))
echo " 200 requests in ${ELAPSED}ms ($(( 200000 / ELAPSED )) rps)"
fi
# ── pprof reminder ──
echo -e "\n═══════════════════════════════════════════════════"
echo " pprof (if SOC_PPROF=true):"
echo " go tool pprof ${SOC}/debug/pprof/profile?seconds=30"
echo " go tool pprof ${SOC}/debug/pprof/heap"
echo "═══════════════════════════════════════════════════"
echo "DONE"