## 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>
126 lines
3.6 KiB
Bash
Executable File
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
|