stemedb/scripts/run-load-test.sh
jordan 157dbbb9eb feat: Complete Aphoria Phase 8-9 + UAT suite (90/90 tests passing)
## Phase 8: Enterprise Extractor Improvements 
- 14 security extractors (TLS, JWT, SQL injection, XSS, etc.)
- 10 framework-specific extractors (Spring, Django, Rails, etc.)
- Config file security detection (YAML, TOML)

## Phase 9: Autonomous Extractor Generation 
- Shadow mode executor with TP/FP tracking
- Graduation pipeline with confidence thresholds
- Auto-rollback on regression detection
- Cross-project pattern syncing

## UAT Suite Complete (14 scripts, 90 tests)
- test-core-detection.sh (6 tests)
- test-declarative-extractors.sh (5 tests)
- test-domain-frameworks.sh (5 tests)
- test-domain-unreal.sh (3 tests)
- test-llm-extraction.sh (6 tests)
- test-eval-harness.sh (5 tests)
- test-cross-language.sh (3 tests)
- test-precommit-performance.sh (4 tests)
- test-output-formats.sh (8 tests)
- test-drift-detection.sh (6 tests)
- test-exit-codes.sh (12 tests)
+ 3 more scripts

## Other Changes
- Updated roadmap to mark Phase 8-9 complete
- Added .gitignore entries for build artifacts
- Updated pre-commit: 800 line limit, exclude tests/data/cmd

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-06 22:50:55 -07:00

126 lines
3.6 KiB
Bash
Executable File

#!/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