asteroid/comprehensive-performance-t...

264 lines
9.4 KiB
Bash
Executable File

#!/bin/bash
# Comprehensive Asteroid Performance Testing Script
# Tests Docker streaming + Asteroid web app together
# Usage: ./comprehensive-performance-test.sh [aac|mp3-high|mp3-low]
set -e
# Configuration
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
DOCKER_DIR="$SCRIPT_DIR/docker"
TEST_DURATION=900 # 15 minutes in seconds
STREAM_TYPE="${1:-aac}" # Default to AAC if not specified
# Log file names based on stream type
case "$STREAM_TYPE" in
"aac")
LOG_PREFIX="test-aac"
STREAM_DESC="AAC 96kbps"
;;
"mp3-high")
LOG_PREFIX="test-mp3-high"
STREAM_DESC="MP3 128kbps"
;;
"mp3-low")
LOG_PREFIX="test-mp3-low"
STREAM_DESC="MP3 64kbps"
;;
*)
echo "Usage: $0 [aac|mp3-high|mp3-low]"
exit 1
;;
esac
# Create logs directory
LOGS_DIR="$SCRIPT_DIR/performance-logs"
mkdir -p "$LOGS_DIR"
# Timestamp for this test run
TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
LOG_FILE="$LOGS_DIR/${LOG_PREFIX}_${TIMESTAMP}.log"
echo "=== Comprehensive Asteroid Performance Test ===" | tee "$LOG_FILE"
echo "Stream Type: $STREAM_DESC" | tee -a "$LOG_FILE"
echo "Test Duration: 15 minutes" | tee -a "$LOG_FILE"
echo "Started at: $(date)" | tee -a "$LOG_FILE"
echo "Log file: $LOG_FILE" | tee -a "$LOG_FILE"
echo "=========================================" | tee -a "$LOG_FILE"
# Function to cleanup on exit
cleanup() {
echo "" | tee -a "$LOG_FILE"
echo "=== CLEANUP STARTED ===" | tee -a "$LOG_FILE"
# Stop Asteroid application
if [ ! -z "$ASTEROID_PID" ] && kill -0 "$ASTEROID_PID" 2>/dev/null; then
echo "Stopping Asteroid application (PID: $ASTEROID_PID)..." | tee -a "$LOG_FILE"
kill "$ASTEROID_PID" 2>/dev/null || true
sleep 2
kill -9 "$ASTEROID_PID" 2>/dev/null || true
fi
# Stop Docker containers
echo "Stopping Docker containers..." | tee -a "$LOG_FILE"
cd "$DOCKER_DIR"
docker compose down 2>/dev/null || true
# Stop monitoring
if [ ! -z "$MONITOR_PID" ] && kill -0 "$MONITOR_PID" 2>/dev/null; then
echo "Stopping monitoring..." | tee -a "$LOG_FILE"
kill "$MONITOR_PID" 2>/dev/null || true
fi
echo "Cleanup completed at: $(date)" | tee -a "$LOG_FILE"
echo "=== TEST FINISHED ===" | tee -a "$LOG_FILE"
}
# Set trap for cleanup
trap cleanup EXIT INT TERM
# Step 1: Start Docker containers
echo "" | tee -a "$LOG_FILE"
echo "=== STARTING DOCKER CONTAINERS ===" | tee -a "$LOG_FILE"
cd "$DOCKER_DIR"
# Stop any existing containers
docker compose down 2>/dev/null || true
sleep 2
# Start containers
echo "Starting Icecast2 and Liquidsoap containers..." | tee -a "$LOG_FILE"
docker compose up -d 2>&1 | tee -a "$LOG_FILE"
# Wait for containers to be ready
echo "Waiting for containers to initialize..." | tee -a "$LOG_FILE"
sleep 10
# Verify containers are running
if ! docker compose ps | grep -q "Up"; then
echo "ERROR: Docker containers failed to start!" | tee -a "$LOG_FILE"
exit 1
fi
echo "Docker containers started successfully" | tee -a "$LOG_FILE"
# Step 2: Start Asteroid application
echo "" | tee -a "$LOG_FILE"
echo "=== STARTING ASTEROID APPLICATION ===" | tee -a "$LOG_FILE"
cd "$SCRIPT_DIR"
# Build if needed
if [ ! -f "./asteroid" ]; then
echo "Building Asteroid executable..." | tee -a "$LOG_FILE"
make 2>&1 | tee -a "$LOG_FILE"
fi
# Start Asteroid in background
echo "Starting Asteroid web application..." | tee -a "$LOG_FILE"
./asteroid > "$LOGS_DIR/${LOG_PREFIX}_asteroid_${TIMESTAMP}.log" 2>&1 &
ASTEROID_PID=$!
# Wait for Asteroid to start
echo "Waiting for Asteroid to initialize..." | tee -a "$LOG_FILE"
sleep 5
# Verify Asteroid is running
if ! kill -0 "$ASTEROID_PID" 2>/dev/null; then
echo "ERROR: Asteroid application failed to start!" | tee -a "$LOG_FILE"
exit 1
fi
echo "Asteroid application started successfully (PID: $ASTEROID_PID)" | tee -a "$LOG_FILE"
# Step 3: Wait for full system initialization
echo "" | tee -a "$LOG_FILE"
echo "=== SYSTEM INITIALIZATION ===" | tee -a "$LOG_FILE"
echo "Waiting for full system initialization..." | tee -a "$LOG_FILE"
sleep 10
# Test connectivity
echo "Testing system connectivity..." | tee -a "$LOG_FILE"
# Test Icecast
if curl -s "http://localhost:8000/" > /dev/null; then
echo "✓ Icecast2 responding on port 8000" | tee -a "$LOG_FILE"
else
echo "⚠ Icecast2 not responding" | tee -a "$LOG_FILE"
fi
# Test Asteroid web interface
if curl -s "http://localhost:8080/asteroid/" > /dev/null; then
echo "✓ Asteroid web interface responding on port 8080" | tee -a "$LOG_FILE"
else
echo "⚠ Asteroid web interface not responding" | tee -a "$LOG_FILE"
fi
# Step 4: Start monitoring
echo "" | tee -a "$LOG_FILE"
echo "=== STARTING PERFORMANCE MONITORING ===" | tee -a "$LOG_FILE"
echo "Stream: $STREAM_DESC" | tee -a "$LOG_FILE"
echo "Duration: 15 minutes" | tee -a "$LOG_FILE"
echo "Monitoring started at: $(date)" | tee -a "$LOG_FILE"
# Create monitoring function
monitor_performance() {
local monitor_log="$LOGS_DIR/${LOG_PREFIX}_monitor_${TIMESTAMP}.log"
local csv_log="$LOGS_DIR/${LOG_PREFIX}_data_${TIMESTAMP}.csv"
# CSV header
echo "timestamp,icecast_cpu,icecast_mem_mb,liquidsoap_cpu,liquidsoap_mem_mb,asteroid_cpu,asteroid_mem_mb,system_mem_used_gb,system_mem_total_gb" > "$csv_log"
local start_time=$(date +%s)
local end_time=$((start_time + TEST_DURATION))
while [ $(date +%s) -lt $end_time ]; do
local current_time=$(date '+%Y-%m-%d %H:%M:%S')
# Get Docker container stats
local icecast_stats=$(docker stats asteroid-icecast --no-stream --format "{{.CPUPerc}},{{.MemUsage}}" 2>/dev/null || echo "0.00%,0B / 0B")
local liquidsoap_stats=$(docker stats asteroid-liquidsoap --no-stream --format "{{.CPUPerc}},{{.MemUsage}}" 2>/dev/null || echo "0.00%,0B / 0B")
# Parse Docker stats
local icecast_cpu=$(echo "$icecast_stats" | cut -d',' -f1 | sed 's/%//')
local icecast_mem_raw=$(echo "$icecast_stats" | cut -d',' -f2 | cut -d'/' -f1 | sed 's/[^0-9.]//g')
local icecast_mem_mb=$(echo "$icecast_mem_raw" | awk '{print $1/1024/1024}')
local liquidsoap_cpu=$(echo "$liquidsoap_stats" | cut -d',' -f1 | sed 's/%//')
local liquidsoap_mem_raw=$(echo "$liquidsoap_stats" | cut -d',' -f2 | cut -d'/' -f1 | sed 's/[^0-9.]//g')
local liquidsoap_mem_mb=$(echo "$liquidsoap_mem_raw" | awk '{print $1/1024/1024}')
# Get Asteroid process stats
local asteroid_cpu="0.0"
local asteroid_mem_mb="0.0"
if kill -0 "$ASTEROID_PID" 2>/dev/null; then
local asteroid_stats=$(ps -p "$ASTEROID_PID" -o %cpu,rss --no-headers 2>/dev/null || echo "0.0 0")
asteroid_cpu=$(echo "$asteroid_stats" | awk '{print $1}')
local asteroid_mem_kb=$(echo "$asteroid_stats" | awk '{print $2}')
asteroid_mem_mb=$(echo "$asteroid_mem_kb" | awk '{print $1/1024}')
fi
# Get system memory
local mem_info=$(free -g | grep "^Mem:")
local system_mem_used=$(echo "$mem_info" | awk '{print $3}')
local system_mem_total=$(echo "$mem_info" | awk '{print $2}')
# Log to console and file
printf "[%s] Icecast: %s%% CPU, %.1fMB | Liquidsoap: %s%% CPU, %.1fMB | Asteroid: %s%% CPU, %.1fMB | System: %sGB/%sGB\n" \
"$current_time" "$icecast_cpu" "$icecast_mem_mb" "$liquidsoap_cpu" "$liquidsoap_mem_mb" \
"$asteroid_cpu" "$asteroid_mem_mb" "$system_mem_used" "$system_mem_total" | tee -a "$LOG_FILE"
# Log to CSV
printf "%s,%.2f,%.1f,%.2f,%.1f,%.2f,%.1f,%s,%s\n" \
"$current_time" "$icecast_cpu" "$icecast_mem_mb" "$liquidsoap_cpu" "$liquidsoap_mem_mb" \
"$asteroid_cpu" "$asteroid_mem_mb" "$system_mem_used" "$system_mem_total" >> "$csv_log"
sleep 5 # Sample every 5 seconds
done
echo "" | tee -a "$LOG_FILE"
echo "Monitoring completed at: $(date)" | tee -a "$LOG_FILE"
}
# Start monitoring in background
monitor_performance &
MONITOR_PID=$!
# Step 5: Generate some web traffic during monitoring
echo "" | tee -a "$LOG_FILE"
echo "=== GENERATING WEB TRAFFIC ===" | tee -a "$LOG_FILE"
# Function to generate light web traffic
generate_traffic() {
sleep 60 # Wait 1 minute before starting traffic
for i in {1..10}; do
# Test main pages
curl -s "http://localhost:8080/asteroid/" > /dev/null 2>&1 || true
sleep 30
# Test API endpoints
curl -s "http://localhost:8080/asteroid/api/icecast-status" > /dev/null 2>&1 || true
sleep 30
# Test player page
curl -s "http://localhost:8080/asteroid/player/" > /dev/null 2>&1 || true
sleep 30
done
} &
# Wait for monitoring to complete
wait $MONITOR_PID
echo "" | tee -a "$LOG_FILE"
echo "=== TEST SUMMARY ===" | tee -a "$LOG_FILE"
echo "Stream Type: $STREAM_DESC" | tee -a "$LOG_FILE"
echo "Test completed at: $(date)" | tee -a "$LOG_FILE"
echo "Log files created:" | tee -a "$LOG_FILE"
echo " - Main log: $LOG_FILE" | tee -a "$LOG_FILE"
echo " - CSV data: $LOGS_DIR/${LOG_PREFIX}_data_${TIMESTAMP}.csv" | tee -a "$LOG_FILE"
echo " - Asteroid log: $LOGS_DIR/${LOG_PREFIX}_asteroid_${TIMESTAMP}.log" | tee -a "$LOG_FILE"
echo "" | tee -a "$LOG_FILE"
echo "To run next test, switch stream format and run:" | tee -a "$LOG_FILE"
echo " ./comprehensive-performance-test.sh [aac|mp3-high|mp3-low]" | tee -a "$LOG_FILE"