#!/bin/bash # Volt Network Benchmark - Packets Per Second Tests # Tests small packet performance (best indicator of CPU overhead) set -e SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # Parse arguments SERVER_IP="${1:?Usage: $0 [backend-name] [duration]}" BACKEND="${2:-unknown}" DURATION="${3:-30}" # Setup results directory TIMESTAMP=$(date +%Y-%m-%d_%H%M%S) RESULTS_DIR="${SCRIPT_DIR}/results/${BACKEND}/${TIMESTAMP}" mkdir -p "$RESULTS_DIR" echo "=== Volt PPS Benchmark ===" echo "Server: $SERVER_IP" echo "Backend: $BACKEND" echo "Duration: ${DURATION}s per test" echo "Results: $RESULTS_DIR" echo "" echo "Note: Small packet tests show virtualization overhead best" echo "" # Function to format large numbers format_number() { local num="$1" if [ -z "$num" ] || [ "$num" = "N/A" ]; then echo "N/A" elif (( $(echo "$num >= 1000000" | bc -l 2>/dev/null || echo 0) )); then printf "%.2fM" $(echo "$num / 1000000" | bc -l) elif (( $(echo "$num >= 1000" | bc -l 2>/dev/null || echo 0) )); then printf "%.2fK" $(echo "$num / 1000" | bc -l) else printf "%.0f" "$num" fi } # UDP Small Packet Tests with iperf3 echo "--- UDP Small Packet Tests (iperf3) ---" echo "" for pkt_size in 64 128 256 512; do echo "[$(date +%H:%M:%S)] Testing ${pkt_size}-byte UDP packets..." output_file="${RESULTS_DIR}/udp-${pkt_size}byte.json" # -l sets UDP payload size, actual packet = payload + 28 (IP+UDP headers) # -b 0 = unlimited bandwidth (find max PPS) if iperf3 -c "$SERVER_IP" -u -l "$pkt_size" -b 0 -t "$DURATION" -J > "$output_file" 2>&1; then if command -v jq &> /dev/null && [ -f "$output_file" ]; then packets=$(jq -r '.end.sum.packets // 0' "$output_file" 2>/dev/null) pps=$(echo "scale=0; $packets / $DURATION" | bc 2>/dev/null || echo "N/A") bps=$(jq -r '.end.sum.bits_per_second // 0' "$output_file" 2>/dev/null) mbps=$(echo "scale=2; $bps / 1000000" | bc 2>/dev/null || echo "N/A") loss=$(jq -r '.end.sum.lost_percent // 0' "$output_file" 2>/dev/null) printf " %4d bytes: %12s pps (%s Mbps, loss: %.2f%%)\n" \ "$pkt_size" "$(format_number $pps)" "$mbps" "$loss" else echo " ${pkt_size} bytes: Complete (see JSON)" fi else echo " ${pkt_size} bytes: FAILED" fi sleep 2 done echo "" # TCP Request/Response with netperf (best for measuring transaction rate) echo "--- TCP Transaction Tests (netperf) ---" echo "" if command -v netperf &> /dev/null; then # TCP_RR - Request/Response (simulates real application traffic) echo "[$(date +%H:%M:%S)] Running TCP_RR (request/response)..." output_file="${RESULTS_DIR}/tcp-rr.txt" if netperf -H "$SERVER_IP" -l "$DURATION" -t TCP_RR > "$output_file" 2>&1; then # Extract transactions per second tps=$(tail -1 "$output_file" | awk '{print $NF}') echo " TCP_RR: $(format_number $tps) trans/sec" echo "TCP_RR_TPS=$tps" > "${RESULTS_DIR}/tcp-rr.env" else echo " TCP_RR: FAILED (is netserver running?)" fi sleep 2 # TCP_CRR - Connect/Request/Response (includes connection setup overhead) echo "[$(date +%H:%M:%S)] Running TCP_CRR (connect/request/response)..." output_file="${RESULTS_DIR}/tcp-crr.txt" if netperf -H "$SERVER_IP" -l "$DURATION" -t TCP_CRR > "$output_file" 2>&1; then tps=$(tail -1 "$output_file" | awk '{print $NF}') echo " TCP_CRR: $(format_number $tps) trans/sec" echo "TCP_CRR_TPS=$tps" > "${RESULTS_DIR}/tcp-crr.env" else echo " TCP_CRR: FAILED" fi sleep 2 # UDP_RR - UDP Request/Response echo "[$(date +%H:%M:%S)] Running UDP_RR (request/response)..." output_file="${RESULTS_DIR}/udp-rr.txt" if netperf -H "$SERVER_IP" -l "$DURATION" -t UDP_RR > "$output_file" 2>&1; then tps=$(tail -1 "$output_file" | awk '{print $NF}') echo " UDP_RR: $(format_number $tps) trans/sec" echo "UDP_RR_TPS=$tps" > "${RESULTS_DIR}/udp-rr.env" else echo " UDP_RR: FAILED" fi else echo "netperf not installed - skipping transaction tests" echo "Run ./setup.sh to install" fi echo "" # Generate summary echo "=== PPS Summary ===" SUMMARY_FILE="${RESULTS_DIR}/pps-summary.txt" { echo "Volt PPS Benchmark Results" echo "================================" echo "Backend: $BACKEND" echo "Server: $SERVER_IP" echo "Date: $(date)" echo "Duration: ${DURATION}s per test" echo "" echo "UDP Packet Rates:" echo "-----------------" for pkt_size in 64 128 256 512; do json_file="${RESULTS_DIR}/udp-${pkt_size}byte.json" if [ -f "$json_file" ] && command -v jq &> /dev/null; then packets=$(jq -r '.end.sum.packets // 0' "$json_file" 2>/dev/null) pps=$(echo "scale=0; $packets / $DURATION" | bc 2>/dev/null || echo "N/A") loss=$(jq -r '.end.sum.lost_percent // 0' "$json_file" 2>/dev/null) printf " %4d bytes: %12s pps (loss: %.2f%%)\n" "$pkt_size" "$(format_number $pps)" "$loss" fi done echo "" echo "Transaction Rates:" echo "------------------" for test in tcp-rr tcp-crr udp-rr; do env_file="${RESULTS_DIR}/${test}.env" if [ -f "$env_file" ]; then source "$env_file" case "$test" in tcp-rr) val="$TCP_RR_TPS" ;; tcp-crr) val="$TCP_CRR_TPS" ;; udp-rr) val="$UDP_RR_TPS" ;; esac printf " %-10s %12s trans/sec\n" "${test}:" "$(format_number $val)" fi done } | tee "$SUMMARY_FILE" echo "" echo "Full results saved to: $RESULTS_DIR" echo "" echo "Key Insight: 64-byte PPS shows raw packet processing overhead." echo "Higher PPS = lower virtualization overhead = better performance."