#!/usr/bin/env bash # Run StemeDB load tests with a fresh server instance. # # Usage: # ./scripts/run-load-test.sh # Quick test (5 min sustained) # LOAD_TEST_DURATION=1h ./scripts/run-load-test.sh # Full 1-hour test # ./scripts/run-load-test.sh --scenario baseline # Run specific scenario # # Environment variables: # STEMEDB_PORT - API port (default: 18180) # STEMEDB_DATA_DIR - Data directory (default: /tmp/stemedb-loadtest) # LOAD_TEST_DURATION - Sustained test duration (default: 5m) # LOAD_TEST_TARGET_RPS - Target writes/sec (default: 1000) # LOAD_TEST_READERS - Concurrent readers (default: 100) # set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" # Configuration API_PORT="${STEMEDB_PORT:-18180}" API_URL="http://127.0.0.1:${API_PORT}" DATA_DIR="${STEMEDB_DATA_DIR:-/tmp/stemedb-loadtest}" DURATION="${LOAD_TEST_DURATION:-5m}" TARGET_RPS="${LOAD_TEST_TARGET_RPS:-1000}" READERS="${LOAD_TEST_READERS:-100}" # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' # No Color log_info() { echo -e "${GREEN}[INFO]${NC} $*"; } log_warn() { echo -e "${YELLOW}[WARN]${NC} $*"; } log_error() { echo -e "${RED}[ERROR]${NC} $*"; } cleanup() { if [[ -n "${API_PID:-}" ]]; then log_info "Stopping StemeDB API (PID: $API_PID)..." kill "$API_PID" 2>/dev/null || true wait "$API_PID" 2>/dev/null || true fi } trap cleanup EXIT # Parse arguments to pass through to load-test LOAD_TEST_ARGS=("$@") cd "$REPO_ROOT" # Clean state for reproducible results log_info "Cleaning data directory: $DATA_DIR" rm -rf "$DATA_DIR" && mkdir -p "$DATA_DIR" # Build the load tester log_info "Building load tester..." cd cmd/load-test go build -o "$REPO_ROOT/target/load-test" . cd "$REPO_ROOT" # Build and start the server with meter disabled log_info "Building and starting StemeDB API (release mode)..." log_info " Data dir: $DATA_DIR" log_info " API URL: $API_URL" STEMEDB_METER_ENABLED=false \ STEMEDB_WAL_DIR="$DATA_DIR/wal" \ STEMEDB_DB_DIR="$DATA_DIR/db" \ STEMEDB_BIND_ADDR="127.0.0.1:$API_PORT" \ cargo run --release --bin stemedb-api 2>&1 | sed 's/^/ [server] /' & API_PID=$! # Wait for server to be ready log_info "Waiting for API to be ready..." for i in {1..60}; do if curl -sf "$API_URL/v1/health" >/dev/null 2>&1; then log_info "API is ready (attempt $i)" break fi if ! kill -0 "$API_PID" 2>/dev/null; then log_error "Server process died unexpectedly" exit 1 fi sleep 1 done # Verify server is actually running if ! curl -sf "$API_URL/v1/health" >/dev/null 2>&1; then log_error "API failed to start within 60 seconds" exit 1 fi # Show server health HEALTH=$(curl -sf "$API_URL/v1/health") log_info "Server health: $HEALTH" # Run load tests log_info "Starting load tests..." log_info " Duration: $DURATION" log_info " Target RPS: $TARGET_RPS" log_info " Readers: $READERS" echo "$REPO_ROOT/target/load-test" \ --api-url "$API_URL" \ --keys-file "$REPO_ROOT/demo/keys/agents.json" \ --output "$REPO_ROOT/uat/production-readiness/results" \ --duration "$DURATION" \ --target-rps "$TARGET_RPS" \ --readers "$READERS" \ "${LOAD_TEST_ARGS[@]}" EXIT_CODE=$? echo log_info "Load test complete." log_info "Results saved to: uat/production-readiness/results/" # Show final assertion count FINAL_HEALTH=$(curl -sf "$API_URL/v1/health" 2>/dev/null || echo '{"assertions_count": "unknown"}') log_info "Final server state: $FINAL_HEALTH" exit $EXIT_CODE