This commit captures the current state before implementing the composable monorepo template system. Key changes included: Infrastructure: - Add CockroachDB provisioner adapter for database provisioning - Add Redis provisioner adapter for cache provisioning - Add build events system with PostgreSQL storage - Add WebSocket endpoint for real-time build progress Code agent improvements: - Fix Claude Code adapter to use default allowed tools instead of dangerously-skip-permissions - Add context-aware stream closing for cancellation support - Improve parser tests for edge cases Build system: - Add build event constants and metrics - Remove deprecated git_operations.go (replaced by pod_git_operations.go) - Add rollback logic for multi-step provisioning operations Documentation: - Add composable-monorepo feature documentation - Add DNS/Cloudflare service documentation - Update deployment and troubleshooting guides Cookbooks: - Add fullstack-app cookbook - Refactor landing-test with shared library Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
166 lines
4.3 KiB
Bash
Executable File
166 lines
4.3 KiB
Bash
Executable File
#!/bin/bash
|
|
# Load Test Script for Build Streaming
|
|
# Simulates concurrent builds with SSE clients to verify event delivery
|
|
#
|
|
# Usage:
|
|
# ./scripts/load-test-builds.sh [num_concurrent] [duration_seconds]
|
|
#
|
|
# Example:
|
|
# ./scripts/load-test-builds.sh 10 60 # 10 concurrent streams for 60 seconds
|
|
|
|
set -euo pipefail
|
|
|
|
# Configuration
|
|
API_URL="${RDEV_API_URL:-https://rdev.masq-ops.orchard9.ai}"
|
|
API_KEY="${RDEV_API_KEY:?RDEV_API_KEY environment variable required}"
|
|
|
|
NUM_CONCURRENT="${1:-5}"
|
|
DURATION="${2:-30}"
|
|
|
|
# Colors
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'
|
|
NC='\033[0m'
|
|
|
|
log_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
|
|
log_success() { echo -e "${GREEN}[OK]${NC} $1"; }
|
|
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
|
|
|
|
# Track metrics
|
|
EVENTS_RECEIVED=0
|
|
CONNECTIONS_OPENED=0
|
|
CONNECTIONS_FAILED=0
|
|
STREAM_PIDS=()
|
|
|
|
# Cleanup on exit
|
|
cleanup() {
|
|
log_info "Cleaning up..."
|
|
for pid in "${STREAM_PIDS[@]}"; do
|
|
kill "$pid" 2>/dev/null || true
|
|
done
|
|
}
|
|
trap cleanup EXIT
|
|
|
|
# Simulate an SSE client that counts events
|
|
run_sse_client() {
|
|
local client_id="$1"
|
|
local stream_id="load-test-stream-$client_id"
|
|
local events_file="/tmp/load-test-events-$client_id.txt"
|
|
|
|
echo "0" > "$events_file"
|
|
|
|
# Connect and count events
|
|
curl -s -N \
|
|
-H "X-API-Key: ${API_KEY}" \
|
|
-H "Accept: text/event-stream" \
|
|
"${API_URL}/projects/load-test-project/events?stream_id=${stream_id}" 2>/dev/null | \
|
|
while IFS= read -r line; do
|
|
if [[ "$line" == "data:"* ]]; then
|
|
# Increment event count
|
|
count=$(<"$events_file")
|
|
echo "$((count + 1))" > "$events_file"
|
|
fi
|
|
done &
|
|
|
|
echo $!
|
|
}
|
|
|
|
# Publish events to simulate build activity
|
|
publish_events() {
|
|
local num_events="$1"
|
|
local stream_id="$2"
|
|
|
|
for i in $(seq 1 "$num_events"); do
|
|
# Use curl to trigger some activity (this is a simulation)
|
|
# In real usage, events come from BuildExecutor
|
|
sleep 0.1
|
|
done
|
|
}
|
|
|
|
echo ""
|
|
echo "=========================================="
|
|
echo " Build Streaming Load Test"
|
|
echo "=========================================="
|
|
echo ""
|
|
echo " Concurrent clients: $NUM_CONCURRENT"
|
|
echo " Test duration: ${DURATION}s"
|
|
echo " API URL: $API_URL"
|
|
echo ""
|
|
|
|
# Check API health first
|
|
log_info "Checking API health..."
|
|
if ! curl -sf "${API_URL}/health" > /dev/null 2>&1; then
|
|
log_error "API health check failed"
|
|
exit 1
|
|
fi
|
|
log_success "API is healthy"
|
|
echo ""
|
|
|
|
# Start concurrent SSE clients
|
|
log_info "Starting $NUM_CONCURRENT SSE clients..."
|
|
for i in $(seq 1 "$NUM_CONCURRENT"); do
|
|
pid=$(run_sse_client "$i")
|
|
if [[ -n "$pid" ]]; then
|
|
STREAM_PIDS+=("$pid")
|
|
CONNECTIONS_OPENED=$((CONNECTIONS_OPENED + 1))
|
|
else
|
|
CONNECTIONS_FAILED=$((CONNECTIONS_FAILED + 1))
|
|
fi
|
|
done
|
|
|
|
log_success "Started $CONNECTIONS_OPENED clients ($CONNECTIONS_FAILED failed)"
|
|
echo ""
|
|
|
|
# Wait for test duration
|
|
log_info "Running load test for ${DURATION}s..."
|
|
sleep "$DURATION"
|
|
|
|
# Collect results
|
|
log_info "Collecting results..."
|
|
|
|
total_events=0
|
|
for i in $(seq 1 "$NUM_CONCURRENT"); do
|
|
events_file="/tmp/load-test-events-$i.txt"
|
|
if [[ -f "$events_file" ]]; then
|
|
count=$(<"$events_file")
|
|
total_events=$((total_events + count))
|
|
rm -f "$events_file"
|
|
fi
|
|
done
|
|
|
|
# Kill remaining clients
|
|
for pid in "${STREAM_PIDS[@]}"; do
|
|
kill "$pid" 2>/dev/null || true
|
|
done
|
|
STREAM_PIDS=()
|
|
|
|
echo ""
|
|
echo "=========================================="
|
|
echo " Load Test Results"
|
|
echo "=========================================="
|
|
echo ""
|
|
echo " Duration: ${DURATION}s"
|
|
echo " Clients started: $CONNECTIONS_OPENED"
|
|
echo " Clients failed: $CONNECTIONS_FAILED"
|
|
echo " Total events received: $total_events"
|
|
echo " Events per second: $(echo "scale=2; $total_events / $DURATION" | bc 2>/dev/null || echo "N/A")"
|
|
echo " Events per client: $(echo "scale=2; $total_events / $CONNECTIONS_OPENED" | bc 2>/dev/null || echo "N/A")"
|
|
echo ""
|
|
|
|
# Check for memory usage if running locally
|
|
if command -v ps > /dev/null 2>&1; then
|
|
log_info "Memory usage check:"
|
|
echo " Run 'kubectl top pods -n rdev' to check rdev-api memory"
|
|
fi
|
|
|
|
echo ""
|
|
if [[ $CONNECTIONS_FAILED -eq 0 ]] && [[ $total_events -gt 0 ]]; then
|
|
log_success "Load test completed successfully"
|
|
exit 0
|
|
else
|
|
log_error "Load test completed with issues"
|
|
exit 1
|
|
fi
|