- Add constant-arrival-rate scenarios to all 4 service scripts (api,
darkwatch, spamshield, voiceprint) to enforce 500 req/s target
- Fix defaultThresholds() to return { thresholds: {...} } so
http_req_duration and errors thresholds are actually applied
- Rewrite run-all.sh: per-service summary files, proper env var
passing (DURATION, API_TOKEN), fixed threshold aggregation
- Update CI workflow threshold check jq to match new threshold-results
structure (.services.<name>.exitCode)
Co-Authored-By: Paperclip <noreply@paperclip.ing>
126 lines
3.5 KiB
Bash
Executable File
126 lines
3.5 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Combined load test runner for all ShieldAI services
|
|
# Usage: ./run-all.sh [service]
|
|
# service: all (default), api, darkwatch, spamshield, voiceprint
|
|
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
REPORT_DIR="${SCRIPT_DIR}/reports"
|
|
TIMESTAMP="$(date +%Y%m%d-%H%M%S)"
|
|
THRESHOLD_FILE="${REPORT_DIR}/threshold-results.json"
|
|
SERVICE="${1:-all}"
|
|
|
|
mkdir -p "$REPORT_DIR"
|
|
|
|
BASE_URL="${LOAD_TEST_BASE_URL:-http://localhost:3000}"
|
|
TARGET_RPS="${TARGET_RPS:-500}"
|
|
DURATION="${DURATION:-300s}"
|
|
API_TOKEN="${API_TOKEN:-test-token}"
|
|
|
|
echo "=== ShieldAI Combined Load Test ==="
|
|
echo "Timestamp: $TIMESTAMP"
|
|
echo "Base URL: $BASE_URL"
|
|
echo "Target RPS: $TARGET_RPS"
|
|
echo "Duration: $DURATION"
|
|
echo "Service: $SERVICE"
|
|
echo ""
|
|
|
|
K6_OPTS="--summary-export ${REPORT_DIR}/summary-${TIMESTAMP}.json"
|
|
|
|
if [[ -n "${K6_CLOUD_TOKEN:-}" ]]; then
|
|
K6_OPTS="$K6_OPTS --out cloud"
|
|
echo "k6 cloud output: enabled"
|
|
fi
|
|
|
|
declare -A EXIT_CODES
|
|
ALL_PASSED=true
|
|
SERVICE_ENV="BASE_URL=$BASE_URL TARGET_RPS=$TARGET_RPS DURATION=$DURATION API_TOKEN=$API_TOKEN"
|
|
|
|
run_service_test() {
|
|
local name=$1
|
|
local script=$2
|
|
local summary_file="${REPORT_DIR}/${name}-summary-${TIMESTAMP}.json"
|
|
|
|
echo ""
|
|
echo "=== Running $name Load Test ==="
|
|
|
|
local opts="--summary-export $summary_file"
|
|
if [[ -n "${K6_CLOUD_TOKEN:-}" ]]; then
|
|
opts="$opts --out cloud"
|
|
fi
|
|
|
|
set +e
|
|
eval "$SERVICE_ENV" k6 run $opts "$script"
|
|
EXIT_CODE=$?
|
|
set -e
|
|
|
|
EXIT_CODES[$name]=$EXIT_CODE
|
|
if [[ $EXIT_CODE -ne 0 ]]; then
|
|
ALL_PASSED=false
|
|
echo "❌ $name load test FAILED (exit code: $EXIT_CODE)"
|
|
else
|
|
echo "✅ $name load test PASSED"
|
|
fi
|
|
}
|
|
|
|
if [[ "$SERVICE" == "all" || "$SERVICE" == "api" ]]; then
|
|
run_service_test "api" "${SCRIPT_DIR}/services/api.js"
|
|
fi
|
|
|
|
if [[ "$SERVICE" == "all" || "$SERVICE" == "darkwatch" ]]; then
|
|
run_service_test "darkwatch" "${SCRIPT_DIR}/services/darkwatch.js"
|
|
fi
|
|
|
|
if [[ "$SERVICE" == "all" || "$SERVICE" == "spamshield" ]]; then
|
|
run_service_test "spamshield" "${SCRIPT_DIR}/services/spamshield.js"
|
|
fi
|
|
|
|
if [[ "$SERVICE" == "all" || "$SERVICE" == "voiceprint" ]]; then
|
|
run_service_test "voiceprint" "${SCRIPT_DIR}/services/voiceprint.js"
|
|
fi
|
|
|
|
# Aggregate threshold results from all service summaries
|
|
echo ""
|
|
echo "=== Load Test Results ==="
|
|
|
|
# Build threshold-results.json from k6 summary exports
|
|
jq -n --arg timestamp "$TIMESTAMP" --arg base_url "$BASE_URL" --arg target_rps "$TARGET_RPS" \
|
|
'{timestamp: $timestamp, base_url: $base_url, target_rps: $target_rps, services: {}}' \
|
|
> "$THRESHOLD_FILE"
|
|
|
|
for name in "${!EXIT_CODES[@]}"; do
|
|
summary_file="${REPORT_DIR}/${name}-summary-${TIMESTAMP}.json"
|
|
if [[ -f "$summary_file" ]]; then
|
|
jq --arg name "$name" --argjson exit_code "${EXIT_CODES[$name]}" \
|
|
'.services[$name] = {
|
|
exitCode: $exit_code,
|
|
passed: ($exit_code == 0),
|
|
metrics: (input | .metrics // {})
|
|
}' \
|
|
"$THRESHOLD_FILE" "$summary_file" \
|
|
> "${THRESHOLD_FILE}.tmp" && mv "${THRESHOLD_FILE}.tmp" "$THRESHOLD_FILE"
|
|
else
|
|
jq --arg name "$name" --argjson exit_code "${EXIT_CODES[$name]}" \
|
|
'.services[$name] = {exitCode: $exit_code, passed: ($exit_code == 0)}' \
|
|
"$THRESHOLD_FILE" > "${THRESHOLD_FILE}.tmp" && mv "${THRESHOLD_FILE}.tmp" "$THRESHOLD_FILE"
|
|
fi
|
|
done
|
|
|
|
echo "Threshold results saved to: $THRESHOLD_FILE"
|
|
|
|
for service in "${!EXIT_CODES[@]}"; do
|
|
status="pass"
|
|
[[ ${EXIT_CODES[$service]} -ne 0 ]] && status="fail"
|
|
echo "$service: $status"
|
|
done
|
|
|
|
echo ""
|
|
if $ALL_PASSED; then
|
|
echo "✅ All load tests passed"
|
|
exit 0
|
|
else
|
|
echo "❌ Some load tests failed"
|
|
exit 1
|
|
fi
|