Last active
January 22, 2025 13:51
-
-
Save rwunsch/0e58524781999af7dc8f3e4cba9d6471 to your computer and use it in GitHub Desktop.
Simple loadtest shell script
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # 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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/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'" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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