#!/usr/bin/env bash # run-loadtests.sh — Run an artillery (ws) and/or k6 (admin) load-test scenario # and write outputs into a dated artifacts folder. # Mirrors scripts/loadtest/run-loadtests.ps1. # # Usage: # ./scripts/loadtest/run-loadtests.sh -s ws -w 'wss://...' # ./scripts/loadtest/run-loadtests.sh -s admin -a 'https://...' -c 'session=...' # ./scripts/loadtest/run-loadtests.sh -s all -w 'wss://...' -a 'https://...' -c 'session=...' set -euo pipefail script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" repo_root="$(cd "$script_dir/../.." && pwd)" SCENARIO="all" ARTIFACT_ROOT="artifacts" WS_URL="${WS_URL:-}" ADMIN_BASE_URL="${ADMIN_BASE_URL:-}" ADMIN_SESSION_COOKIE="${ADMIN_SESSION_COOKIE:-}" usage() { echo "Usage: $0 [-s ws|admin|all] [-w ws_url] [-a admin_base_url] [-c admin_session_cookie] [-r artifact_root]" >&2 exit 2 } while [[ $# -gt 0 ]]; do case "$1" in -s) SCENARIO="$2"; shift 2;; -w) WS_URL="$2"; shift 2;; -a) ADMIN_BASE_URL="$2"; shift 2;; -c) ADMIN_SESSION_COOKIE="$2"; shift 2;; -r) ARTIFACT_ROOT="$2"; shift 2;; -h|--help) usage;; *) echo "Unknown option: $1" >&2; usage;; esac done case "$SCENARIO" in ws|admin|all) ;; *) echo "Scenario must be ws|admin|all" >&2; exit 2;; esac if [[ "$SCENARIO" == ws || "$SCENARIO" == all ]] && ! command -v npx >/dev/null 2>&1; then echo "npx is required for ws scenario but was not found in PATH." >&2; exit 1 fi if [[ "$SCENARIO" == admin || "$SCENARIO" == all ]] && ! command -v k6 >/dev/null 2>&1; then echo "k6 is required for admin scenario but was not found in PATH." >&2; exit 1 fi if [[ "$ARTIFACT_ROOT" = /* ]]; then artifact_base="$ARTIFACT_ROOT"; else artifact_base="$repo_root/$ARTIFACT_ROOT"; fi artifact_dir="$artifact_base/$(date +%Y-%m-%d_%H%M%S)" mkdir -p "$artifact_dir" if [[ "$SCENARIO" == ws || "$SCENARIO" == all ]]; then [[ -n "$WS_URL" ]] || { echo "WS_URL is required for ws scenario. Pass -w or set \$WS_URL." >&2; exit 1; } ws_out="$artifact_dir/ws-chat-report.json" ws_sum="$artifact_dir/ws-chat-summary.txt" echo "== Running artillery ws scenario ==" WS_URL="$WS_URL" npx artillery run "$script_dir/ws-chat.yml" --output "$ws_out" "$script_dir/summarize-artillery.sh" "$ws_out" | tee "$ws_sum" fi if [[ "$SCENARIO" == admin || "$SCENARIO" == all ]]; then [[ -n "$ADMIN_BASE_URL" ]] || { echo "ADMIN_BASE_URL is required for admin scenario. Pass -a or set \$ADMIN_BASE_URL." >&2; exit 1; } [[ -n "$ADMIN_SESSION_COOKIE" ]] || { echo "ADMIN_SESSION_COOKIE is required for admin scenario. Pass -c or set \$ADMIN_SESSION_COOKIE." >&2; exit 1; } admin_sum="$artifact_dir/admin-api-summary.json" admin_out="$artifact_dir/admin-api-output.txt" admin_ep_sum="$artifact_dir/admin-api-endpoint-summary.txt" echo "== Running k6 admin scenario ==" ADMIN_BASE_URL="$ADMIN_BASE_URL" ADMIN_SESSION_COOKIE="$ADMIN_SESSION_COOKIE" \ k6 run --summary-export "$admin_sum" "$script_dir/admin-api.js" | tee "$admin_out" "$script_dir/summarize-k6.sh" "$admin_sum" | tee "$admin_ep_sum" fi echo "Artifacts written to $artifact_dir"