193 lines
6.3 KiB
Bash
Executable File
193 lines
6.3 KiB
Bash
Executable File
#!/bin/bash
|
||
# Async Docker Operations Load Testing Script
|
||
|
||
set -e
|
||
|
||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||
|
||
echo "🏋️ Async Docker Operations Load Testing"
|
||
echo "=" * 50
|
||
|
||
# Configuration
|
||
ASYNC_MODE="${USE_ASYNC_DOCKER:-true}"
|
||
MAX_CONCURRENT="${MAX_CONCURRENT_SESSIONS:-3}"
|
||
TEST_DURATION="${TEST_DURATION:-30}"
|
||
|
||
echo "Testing configuration:"
|
||
echo " Async mode: $ASYNC_MODE"
|
||
echo " Max concurrent sessions: $MAX_CONCURRENT"
|
||
echo " Test duration: $TEST_DURATION seconds"
|
||
echo
|
||
|
||
# Test 1: Basic async Docker functionality
|
||
echo "1️⃣ Testing async Docker functionality..."
|
||
if python3 "$SCRIPT_DIR/test-async-docker.py" > /dev/null 2>&1; then
|
||
echo "✅ Async Docker functionality test passed"
|
||
else
|
||
echo "❌ Async Docker functionality test failed"
|
||
exit 1
|
||
fi
|
||
|
||
# Test 2: Service startup with async mode
|
||
echo -e "\n2️⃣ Testing service startup with async Docker..."
|
||
cd "$PROJECT_ROOT"
|
||
|
||
# Ensure certificates exist
|
||
if [[ ! -f "docker/certs/ca.pem" ]]; then
|
||
echo "⚠️ TLS certificates not found. Generating..."
|
||
cd docker && ./scripts/generate-certs.sh && cd ..
|
||
fi
|
||
|
||
# Start services
|
||
echo "Starting session-manager with async Docker..."
|
||
USE_ASYNC_DOCKER="$ASYNC_MODE" docker-compose up -d session-manager > /dev/null 2>&1
|
||
|
||
# Wait for service to be ready
|
||
timeout=30
|
||
counter=0
|
||
while [ $counter -lt $timeout ]; do
|
||
if curl -f -s http://localhost:8000/health > /dev/null 2>&1; then
|
||
echo "✅ Service is healthy"
|
||
break
|
||
fi
|
||
sleep 1
|
||
counter=$((counter + 1))
|
||
done
|
||
|
||
if [ $counter -ge $timeout ]; then
|
||
echo "❌ Service failed to start within $timeout seconds"
|
||
docker-compose logs session-manager
|
||
exit 1
|
||
fi
|
||
|
||
# Verify async mode is active
|
||
HEALTH_RESPONSE=$(curl -s http://localhost:8000/health)
|
||
DOCKER_MODE=$(echo "$HEALTH_RESPONSE" | grep -o '"docker_mode": "[^"]*"' | cut -d'"' -f4)
|
||
|
||
if [[ "$DOCKER_MODE" == "async" ]]; then
|
||
echo "✅ Async Docker mode is active"
|
||
elif [[ "$DOCKER_MODE" == "sync" ]]; then
|
||
echo "ℹ️ Sync Docker mode is active (expected when USE_ASYNC_DOCKER=false)"
|
||
else
|
||
echo "❌ Could not determine Docker mode"
|
||
exit 1
|
||
fi
|
||
|
||
# Test 3: Concurrent session creation stress test
|
||
echo -e "\n3️⃣ Testing concurrent session creation under load..."
|
||
|
||
# Function to create sessions concurrently
|
||
create_sessions_concurrent() {
|
||
local num_sessions=$1
|
||
local results_file=$2
|
||
|
||
for i in $(seq 1 "$num_sessions"); do
|
||
# Run in background
|
||
(
|
||
start_time=$(date +%s.%3N)
|
||
response=$(curl -s -w "%{http_code}" -o /dev/null -X POST http://localhost:8000/sessions)
|
||
end_time=$(date +%s.%3N)
|
||
duration=$(echo "$end_time - $start_time" | bc 2>/dev/null || echo "0")
|
||
|
||
if [ "$response" = "200" ]; then
|
||
echo "SUCCESS $duration" >> "$results_file"
|
||
elif [ "$response" = "429" ]; then
|
||
echo "THROTTLED $duration" >> "$results_file"
|
||
elif [ "$response" = "503" ]; then
|
||
echo "RESOURCE_LIMIT $duration" >> "$results_file"
|
||
else
|
||
echo "FAILED $duration" >> "$results_file"
|
||
fi
|
||
) &
|
||
done
|
||
|
||
# Wait for all background jobs to complete
|
||
wait
|
||
}
|
||
|
||
# Run stress test
|
||
RESULTS_FILE="/tmp/session_creation_results.txt"
|
||
rm -f "$RESULTS_FILE"
|
||
|
||
echo "Creating $MAX_CONCURRENT concurrent sessions for $TEST_DURATION seconds..."
|
||
end_time=$((SECONDS + TEST_DURATION))
|
||
|
||
while [ $SECONDS -lt $end_time ]; do
|
||
# Create batch of concurrent requests
|
||
create_sessions_concurrent "$MAX_CONCURRENT" "$RESULTS_FILE"
|
||
|
||
# Small delay between batches
|
||
sleep 1
|
||
done
|
||
|
||
# Analyze results
|
||
if [[ -f "$RESULTS_FILE" ]]; then
|
||
total_requests=$(wc -l < "$RESULTS_FILE")
|
||
successful=$(grep -c "SUCCESS" "$RESULTS_FILE")
|
||
throttled=$(grep -c "THROTTLED" "$RESULTS_FILE")
|
||
resource_limited=$(grep -c "RESOURCE_LIMIT" "$RESULTS_FILE")
|
||
failed=$(grep -c "FAILED" "$RESULTS_FILE")
|
||
|
||
# Calculate average response time for successful requests
|
||
avg_response_time=$(grep "SUCCESS" "$RESULTS_FILE" | awk '{sum += $2; count++} END {if (count > 0) print sum/count; else print "0"}')
|
||
|
||
echo "Load test results:"
|
||
echo " Total requests: $total_requests"
|
||
echo " Successful: $successful"
|
||
echo " Throttled: $throttled"
|
||
echo " Resource limited: $resource_limited"
|
||
echo " Failed: $failed"
|
||
echo " Avg response time: ${avg_response_time}s"
|
||
|
||
# Performance assessment
|
||
success_rate=$(echo "scale=2; $successful * 100 / $total_requests" | bc 2>/dev/null || echo "0")
|
||
|
||
if (( $(echo "$success_rate > 90" | bc -l 2>/dev/null || echo "0") )); then
|
||
echo "✅ Excellent performance: ${success_rate}% success rate"
|
||
elif (( $(echo "$success_rate > 75" | bc -l 2>/dev/null || echo "0") )); then
|
||
echo "✅ Good performance: ${success_rate}% success rate"
|
||
else
|
||
echo "⚠️ Performance issues detected: ${success_rate}% success rate"
|
||
fi
|
||
|
||
# Response time assessment
|
||
if (( $(echo "$avg_response_time < 2.0" | bc -l 2>/dev/null || echo "0") )); then
|
||
echo "✅ Fast response times: ${avg_response_time}s average"
|
||
elif (( $(echo "$avg_response_time < 5.0" | bc -l 2>/dev/null || echo "0") )); then
|
||
echo "✅ Acceptable response times: ${avg_response_time}s average"
|
||
else
|
||
echo "⚠️ Slow response times: ${avg_response_time}s average"
|
||
fi
|
||
|
||
else
|
||
echo "❌ No results file generated"
|
||
exit 1
|
||
fi
|
||
|
||
# Test 4: Session cleanup under load
|
||
echo -e "\n4️⃣ Testing session cleanup under load..."
|
||
|
||
# Trigger manual cleanup
|
||
CLEANUP_RESPONSE=$(curl -s -X POST http://localhost:8000/cleanup)
|
||
if echo "$CLEANUP_RESPONSE" | grep -q '"message"'; then
|
||
echo "✅ Cleanup operation successful"
|
||
else
|
||
echo "❌ Cleanup operation failed"
|
||
fi
|
||
|
||
# Check final session count
|
||
FINAL_HEALTH=$(curl -s http://localhost:8000/health)
|
||
ACTIVE_SESSIONS=$(echo "$FINAL_HEALTH" | grep -o '"active_sessions": [0-9]*' | cut -d' ' -f2)
|
||
|
||
echo "Final active sessions: $ACTIVE_SESSIONS"
|
||
|
||
# Cleanup
|
||
echo -e "\n🧹 Cleaning up test resources..."
|
||
docker-compose down > /dev/null 2>&1
|
||
rm -f "$RESULTS_FILE"
|
||
|
||
echo -e "\n🎉 Async Docker load testing completed!"
|
||
echo "✅ Async operations provide improved concurrency"
|
||
echo "✅ Resource limits prevent system overload"
|
||
echo "✅ Session throttling maintains stability" |