Skip to content

Instantly share code, notes, and snippets.

@rwunsch
Last active January 22, 2025 13:51
Show Gist options
  • Select an option

  • Save rwunsch/0e58524781999af7dc8f3e4cba9d6471 to your computer and use it in GitHub Desktop.

Select an option

Save rwunsch/0e58524781999af7dc8f3e4cba9d6471 to your computer and use it in GitHub Desktop.
Simple loadtest shell script
# AEM Load Test Configuration
# URL file containing multiple target URLs (one per line)
URL_FILE="urls.txt"
# Optional authentication (leave empty if not needed)
USERNAME="" # AEM username (if authentication required)
PASSWORD=""
CONCURRENT_REQUESTS=5 # Number of parallel requests
TOTAL_REQUESTS=20 # Total number of requests to send
TEST_DURATION=30 # Maximum test duration in seconds (0 = no limit)
LOG_FILE="aem_loadtest.log" # File to log request times
CSV_FILE="aem_loadtest.csv" # CSV output for data analysis
# Enable debug mode for real-time output (true/false)
DEBUG=true
#!/bin/bash
# Load configuration
CONFIG_FILE="loadtest.config"
if [[ -f "$CONFIG_FILE" ]]; then
source "$CONFIG_FILE"
else
echo "Configuration file $CONFIG_FILE not found. Exiting."
exit 1
fi
# Ensure the URL file exists
if [[ ! -f "$URL_FILE" ]]; then
echo "URL file $URL_FILE not found. Exiting."
exit 1
fi
# Read URLs into an array (trimming spaces and ensuring clean entries)
mapfile -t URLS < <(grep -v '^#' "$URL_FILE" | sed 's/\r$//') # Remove carriage returns (Windows line endings)
URL_COUNT=${#URLS[@]}
# Check if URL file is empty
if [[ "$URL_COUNT" -eq 0 ]]; then
echo "URL file is empty. Exiting."
exit 1
fi
# Initialize log files
echo "Timestamp, URL, Response Time (ms), HTTP Code" > "$CSV_FILE"
echo "Starting Load Test at $(date)" | tee -a "$LOG_FILE"
# Track start time for duration control
START_TIME=$(date +%s)
# Determine if authentication is needed
CURL_AUTH=""
if [[ -n "$USERNAME" ]]; then
CURL_AUTH="-u $USERNAME:$PASSWORD"
fi
# Function to log messages to both console and file
log_message() {
echo "$1" | tee -a "$LOG_FILE"
}
# Function to pick a random URL (fixing potential issues)
get_random_url() {
local RANDOM_INDEX=$(( RANDOM % URL_COUNT ))
local SELECTED_URL="${URLS[RANDOM_INDEX]}"
echo "$SELECTED_URL" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//' # Trim leading/trailing spaces
}
# Function to send a single request
send_request() {
local ID="$1"
local TARGET_URL=$(get_random_url) # Get a random URL
local START_TIME=$(date +%s%3N) # Start time in milliseconds
# Debug output before sending request
if [[ "$DEBUG" == "true" ]]; then
log_message "[DEBUG] Sending request #$ID to target: $TARGET_URL"
fi
# Execute curl request with -k to ignore SSL validation and measure time
RESPONSE=$(curl -s -k -o /dev/null -w "%{time_total},%{http_code}" $CURL_AUTH "$TARGET_URL")
if [[ $? -ne 0 ]]; then
log_message "[ERROR] Request #$ID to $TARGET_URL failed."
return
fi
RESPONSE_TIME=$(echo "$RESPONSE" | awk -F, '{print $1*1000}') # Convert to ms
HTTP_CODE=$(echo "$RESPONSE" | awk -F, '{print $2}')
# Timestamped log entry
TIMESTAMP=$(date +"%Y-%m-%d %H:%M:%S")
echo "$TIMESTAMP, $TARGET_URL, $RESPONSE_TIME, $HTTP_CODE" >> "$CSV_FILE"
log_message "[$TIMESTAMP] Request #$ID | URL: $TARGET_URL | Response Time: ${RESPONSE_TIME}ms | HTTP Code: $HTTP_CODE"
# Debug output after receiving response
if [[ "$DEBUG" == "true" ]]; then
log_message "[DEBUG] Request #$ID completed | URL: $TARGET_URL | Time: ${RESPONSE_TIME}ms | Code: $HTTP_CODE"
fi
}
# Function to run concurrent requests
run_load_test() {
local COUNT=0
while [[ "$COUNT" -lt "$TOTAL_REQUESTS" ]]; do
CURRENT_TIME=$(date +%s)
if [[ "$TEST_DURATION" -gt 0 ]] && [[ "$((CURRENT_TIME - START_TIME))" -ge "$TEST_DURATION" ]]; then
log_message "Test duration reached. Stopping."
break
fi
# Spawn requests in parallel
for ((i=0; i<CONCURRENT_REQUESTS; i++)); do
send_request "$((COUNT + i + 1))" &
done
wait # Ensure all parallel requests complete before proceeding
COUNT=$((COUNT + CONCURRENT_REQUESTS))
done
}
# Trap CTRL+C for graceful exit
trap 'log_message "Interrupted. Exiting..."; exit 1' SIGINT
# Run the load test
run_load_test
log_message "Load Test Completed. Results saved to $CSV_FILE and $LOG_FILE."
echo "--------------------------"
echo "Average response time:"
#To see the average response time:
awk -F, '{sum+=$2; count++} END {print "Avg Response Time:", sum/count, "ms"}' aem_loadtest.csv
echo "--------------------------"
echo "10 slowest requests:"
awk -F, '{print $2}' aem_loadtest.csv | sort -n | tail -n 10
#(Shows the slowest 10 requests)
echo "--------------------------"
#echo "find a plot/graph in response_time.png"
#To create a graph in gnuplot:
#gnuplot -e "set terminal png; set output 'response_time.png'; set title 'Response Times'; set xlabel 'Request'; set ylabel 'Time (ms)'; plot 'aem_loadtest.csv' using 1:2 with lines title 'Response Time'"
https://localhost:4502/content/we-retail/us/en.html
https://localhost:4502/content/we-retail/us/en/products.html
https://localhost:4502/content/we-retail/us/en/stories.html
https://localhost:4502/content/we-retail/us/en/contact.html
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment