Skip to content

Commit

Permalink
Factor out summarize_pings();
Browse files Browse the repository at this point in the history
Display summary even after Ctl-C;
Add some test code for the awk summarize_pings() function.
  • Loading branch information
richb-hanover committed Jan 1, 2022
1 parent 4b021ac commit eac7700
Show file tree
Hide file tree
Showing 4 changed files with 178 additions and 47 deletions.
68 changes: 21 additions & 47 deletions betterspeedtest.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,49 +18,11 @@
# -i | --idle: Don't send traffic, only measure idle latency
# -n | --number: Number of simultaneous sessions (default - 5 sessions)

# Copyright (c) 2014-2019 - Rich Brown [email protected]
# Copyright (c) 2014-2022 - Rich Brown [email protected]
# GPLv2

# Summarize the contents of the ping's output file to show min, avg, median, max, etc.
# input parameter ($1) file contains the output of the ping command

summarize_pings() {

# Process the ping times, and summarize the results
# grep to keep lines that have "time=", then sed to isolate the time stamps, and sort them
# awk builds an array of those values, and prints first & last (which are min, max)
# and computes average.
# If the number of samples is >= 10, also computes median, and 10th and 90th percentile readings

# stop pinging and drawing dots
kill_pings
kill_dots

sed 's/^.*time=\([^ ]*\) ms/\1/' < "$1" | grep -v "PING" | sort -n | \
awk 'BEGIN {numdrops=0; numrows=0;} \
{ \
if ( $0 ~ /timeout/ ) { \
numdrops += 1; \
} else { \
numrows += 1; \
arr[numrows]=$1; sum+=$1; \
} \
} \
END { \
pc10="-"; pc90="-"; med="-"; \
if (numrows == 0) {numrows=1} \
if (numrows>=10) \
{ ix=int(numrows/10); pc10=arr[ix]; ix=int(numrows*9/10);pc90=arr[ix]; \
if (numrows%2==1) med=arr[(numrows+1)/2]; else med=(arr[numrows/2]); \
}; \
pktloss = numdrops/(numdrops+numrows) * 100; \
printf("\n Latency: (in msec, %d pings, %4.2f%% packet loss)\n Min: %4.3f \n 10pct: %4.3f \n Median: %4.3f \n Avg: %4.3f \n 90pct: %4.3f \n Max: %4.3f\n", numrows, pktloss, arr[1], pc10, med, sum/numrows, pc90, arr[numrows] )\
}'

# and finally remove the PINGFILE
rm "$1"

}
# include the summarize_pings() function from the lib directory
. "./lib/summarize_pings.sh"

# Print a line of dots as a progress indicator.

Expand Down Expand Up @@ -89,12 +51,22 @@ kill_pings() {
ping_pid=0
}


# Clean up all the debris from the testing
clean_up() {
kill_pings
kill_dots
rm "$PINGFILE"
}

# Stop the current pings and dots, and exit
# ping command catches (and handles) first Ctrl-C, so you have to hit it again...
kill_pings_and_dots_and_exit() {
kill_dots
kill_pings
catch_interrupt() {
printf "\nStopped"
kill_pings
kill_dots
summarize_pings "$PINGFILE"
rm "$PINGFILE"
exit 1
}

Expand Down Expand Up @@ -169,7 +141,8 @@ measure_direction() {
# When netperf completes, summarize the ping data
summarize_pings "$PINGFILE"

rm "$SPEEDFILE"
# stop the dots & pings, rm "$PINGFILE"
clean_up
}

# ------- Start of the main routine --------
Expand Down Expand Up @@ -240,15 +213,16 @@ else
fi
DATE=$(date "+%Y-%m-%d %H:%M:%S")

# Catch a Ctl-C and stop the pinging and the print_dots
trap kill_pings_and_dots_and_exit HUP INT TERM
# Catch a Ctl-C and close up
trap catch_interrupt HUP INT TERM

if $IDLETEST
then
echo "$DATE Testing idle line while pinging $PINGHOST ($TESTDUR seconds)"
start_pings
sleep "$TESTDUR"
summarize_pings "$PINGFILE"
clean_up

else
echo "$DATE Testing against $TESTHOST ($PROTO) with $MAXSESSIONS simultaneous sessions while pinging $PINGHOST ($TESTDUR seconds in each direction)"
Expand Down
46 changes: 46 additions & 0 deletions lib/summarize_pings.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
summarize_pings() {

# Process the ping times from the passed-in file, and summarize the results
# grep to keep lines that have "time=", then sed to isolate the time stamps, and sort them
# Use awk to build an array of those values, and print first & last (which are min, max)
# and compute average.
# If the number of samples is >= 10, also compute median, and 10th and 90th percentile readings

# Display the values as:
# Latency: (in msec, 11 pings, 8.33% packet loss)
# Min: 16.556
# 10pct: 16.561
# Median: 22.370
# Avg: 21.203
# 90pct: 23.202
# Max: 23.394

grep "time" < "$1" | cat | \
sed 's/^.*time=\([^ ]*\) ms/\1/'| \
# tee >&2 | \
sort -n | \
awk 'BEGIN {numdrops=0; numrows=0} \
{ \
# print ; \
if ( $0 ~ /timeout/ ) { \
numdrops += 1; \
} else { \
numrows += 1; \
arr[numrows]=$1; sum+=$1; \
} \
} \
END { \
pc10="-"; pc90="-"; med="-"; \
if (numrows == 0) {numrows=1} \
if (numrows>=10) \
{ # get the 10th pctile - never the first one
ix=int(numrows/10); if (ix=1) {ix+=1}; pc10=arr[ix]; \
# get the 90th pctile
ix=int(numrows*9/10);pc90=arr[ix]; \
# get the median
if (numrows%2==1) med=arr[(numrows+1)/2]; else med=(arr[numrows/2]); \
}; \
pktloss = numdrops/(numdrops+numrows) * 100; \
printf("\n Latency: (in msec, %d pings, %4.2f%% packet loss)\n Min: %4.3f \n 10pct: %4.3f \n Median: %4.3f \n Avg: %4.3f \n 90pct: %4.3f \n Max: %4.3f\n", numrows, pktloss, arr[1], pc10, med, sum/numrows, pc90, arr[numrows] )\
}'
}
88 changes: 88 additions & 0 deletions tests/pingsamples.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
PING 1.1.1.1 (1.1.1.1): 56 data bytes
64 bytes from 1.1.1.1: icmp_seq=0 ttl=55 time=22.370 ms
64 bytes from 1.1.1.1: icmp_seq=1 ttl=55 time=22.639 ms
64 bytes from 1.1.1.1: icmp_seq=2 ttl=55 time=23.202 ms
64 bytes from 1.1.1.1: icmp_seq=3 ttl=55 time=16.561 ms
64 bytes from 1.1.1.1: icmp_seq=4 ttl=55 time=23.394 ms
64 bytes from 1.1.1.1: icmp_seq=5 ttl=55 time=22.348 ms
64 bytes from 1.1.1.1: icmp_seq=6 ttl=55 time=23.250 ms
64 bytes from 1.1.1.1: icmp_seq=7 ttl=55 time=16.556 ms
Request timeout for icmp_seq 8
64 bytes from 1.1.1.1: icmp_seq=9 ttl=55 time=22.247 ms
64 bytes from 1.1.1.1: icmp_seq=10 ttl=55 time=17.617 ms
64 bytes from 1.1.1.1: icmp_seq=11 ttl=55 time=23.049 ms
64 bytes from 1.1.1.1: icmp_seq=12 ttl=55 time=16.619 ms
64 bytes from 1.1.1.1: icmp_seq=13 ttl=55 time=22.737 ms
64 bytes from 1.1.1.1: icmp_seq=14 ttl=55 time=22.806 ms
64 bytes from 1.1.1.1: icmp_seq=15 ttl=55 time=22.971 ms
64 bytes from 1.1.1.1: icmp_seq=16 ttl=55 time=16.498 ms
64 bytes from 1.1.1.1: icmp_seq=17 ttl=55 time=23.385 ms
64 bytes from 1.1.1.1: icmp_seq=18 ttl=55 time=22.898 ms
64 bytes from 1.1.1.1: icmp_seq=19 ttl=55 time=22.988 ms
64 bytes from 1.1.1.1: icmp_seq=20 ttl=55 time=23.051 ms
64 bytes from 1.1.1.1: icmp_seq=21 ttl=55 time=16.487 ms
64 bytes from 1.1.1.1: icmp_seq=22 ttl=55 time=16.692 ms
64 bytes from 1.1.1.1: icmp_seq=23 ttl=55 time=15.711 ms
64 bytes from 1.1.1.1: icmp_seq=24 ttl=55 time=17.799 ms
64 bytes from 1.1.1.1: icmp_seq=25 ttl=55 time=23.230 ms
64 bytes from 1.1.1.1: icmp_seq=26 ttl=55 time=22.493 ms
64 bytes from 1.1.1.1: icmp_seq=27 ttl=55 time=23.209 ms
64 bytes from 1.1.1.1: icmp_seq=28 ttl=55 time=22.708 ms
64 bytes from 1.1.1.1: icmp_seq=29 ttl=55 time=22.146 ms
64 bytes from 1.1.1.1: icmp_seq=30 ttl=55 time=22.887 ms
64 bytes from 1.1.1.1: icmp_seq=31 ttl=55 time=23.119 ms
64 bytes from 1.1.1.1: icmp_seq=32 ttl=55 time=23.049 ms
64 bytes from 1.1.1.1: icmp_seq=33 ttl=55 time=17.061 ms
64 bytes from 1.1.1.1: icmp_seq=34 ttl=55 time=23.603 ms
64 bytes from 1.1.1.1: icmp_seq=35 ttl=55 time=16.382 ms
64 bytes from 1.1.1.1: icmp_seq=36 ttl=55 time=23.197 ms
64 bytes from 1.1.1.1: icmp_seq=37 ttl=55 time=17.043 ms
64 bytes from 1.1.1.1: icmp_seq=38 ttl=55 time=25.956 ms
64 bytes from 1.1.1.1: icmp_seq=39 ttl=55 time=23.118 ms
64 bytes from 1.1.1.1: icmp_seq=40 ttl=55 time=23.350 ms
64 bytes from 1.1.1.1: icmp_seq=41 ttl=55 time=23.614 ms
64 bytes from 1.1.1.1: icmp_seq=42 ttl=55 time=16.343 ms
64 bytes from 1.1.1.1: icmp_seq=43 ttl=55 time=28.280 ms
64 bytes from 1.1.1.1: icmp_seq=44 ttl=55 time=23.024 ms
64 bytes from 1.1.1.1: icmp_seq=45 ttl=55 time=22.868 ms
64 bytes from 1.1.1.1: icmp_seq=46 ttl=55 time=16.664 ms
64 bytes from 1.1.1.1: icmp_seq=47 ttl=55 time=22.922 ms
64 bytes from 1.1.1.1: icmp_seq=48 ttl=55 time=23.331 ms
64 bytes from 1.1.1.1: icmp_seq=49 ttl=55 time=23.770 ms
64 bytes from 1.1.1.1: icmp_seq=50 ttl=55 time=22.904 ms
64 bytes from 1.1.1.1: icmp_seq=51 ttl=55 time=23.393 ms
64 bytes from 1.1.1.1: icmp_seq=52 ttl=55 time=22.398 ms
64 bytes from 1.1.1.1: icmp_seq=53 ttl=55 time=18.838 ms
64 bytes from 1.1.1.1: icmp_seq=54 ttl=55 time=17.159 ms
64 bytes from 1.1.1.1: icmp_seq=55 ttl=55 time=23.008 ms
64 bytes from 1.1.1.1: icmp_seq=56 ttl=55 time=23.543 ms
64 bytes from 1.1.1.1: icmp_seq=57 ttl=55 time=16.356 ms
64 bytes from 1.1.1.1: icmp_seq=58 ttl=55 time=16.766 ms
64 bytes from 1.1.1.1: icmp_seq=59 ttl=55 time=22.899 ms
64 bytes from 1.1.1.1: icmp_seq=60 ttl=55 time=23.018 ms
64 bytes from 1.1.1.1: icmp_seq=61 ttl=55 time=16.107 ms
64 bytes from 1.1.1.1: icmp_seq=62 ttl=55 time=23.279 ms
64 bytes from 1.1.1.1: icmp_seq=63 ttl=55 time=17.151 ms
64 bytes from 1.1.1.1: icmp_seq=64 ttl=55 time=16.751 ms
64 bytes from 1.1.1.1: icmp_seq=65 ttl=55 time=23.201 ms
64 bytes from 1.1.1.1: icmp_seq=66 ttl=55 time=23.518 ms
64 bytes from 1.1.1.1: icmp_seq=67 ttl=55 time=23.008 ms
64 bytes from 1.1.1.1: icmp_seq=68 ttl=55 time=23.239 ms
64 bytes from 1.1.1.1: icmp_seq=69 ttl=55 time=22.914 ms
64 bytes from 1.1.1.1: icmp_seq=70 ttl=55 time=17.153 ms
64 bytes from 1.1.1.1: icmp_seq=71 ttl=55 time=22.090 ms
64 bytes from 1.1.1.1: icmp_seq=72 ttl=55 time=23.510 ms
64 bytes from 1.1.1.1: icmp_seq=73 ttl=55 time=23.084 ms
64 bytes from 1.1.1.1: icmp_seq=74 ttl=55 time=22.768 ms
64 bytes from 1.1.1.1: icmp_seq=75 ttl=55 time=22.237 ms
64 bytes from 1.1.1.1: icmp_seq=76 ttl=55 time=23.340 ms
64 bytes from 1.1.1.1: icmp_seq=77 ttl=55 time=16.883 ms
64 bytes from 1.1.1.1: icmp_seq=78 ttl=55 time=23.954 ms
64 bytes from 1.1.1.1: icmp_seq=79 ttl=55 time=23.415 ms
64 bytes from 1.1.1.1: icmp_seq=80 ttl=55 time=16.897 ms
64 bytes from 1.1.1.1: icmp_seq=81 ttl=55 time=18.440 ms
64 bytes from 1.1.1.1: icmp_seq=82 ttl=55 time=20.889 ms

--- 1.1.1.1 ping statistics ---
83 packets transmitted, 83 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 15.711/21.256/28.280/2.984 ms
23 changes: 23 additions & 0 deletions tests/test_summary.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Test scaffolding for the summarize_pings() subroutine.
# Take a known set of ping readings (in ./pingsamples.txt), strip out bogus stuff,
# then pass the first N lines (passed in as an argument) to the summarize_pings() function
#

# include the summarize_pings() function from the library
. "../lib/summarize_pings.sh"

PINGFILE=$(mktemp /tmp/measurepings.XXXXXX) || exit 1

# pre-format the pingsamples for ease of counting...
# strip out any line that doesn't contain "time" (e.g., not time= or timeout)
# Only send the specified number of lines into $PINGFILE
cat < pingsamples.txt | \
grep time | \
head -n "$1" > "$PINGFILE"
echo "=== PINGFILE ==="
cat "$PINGFILE"
echo "========"
summarize_pings "$PINGFILE"
rm "$PINGFILE"


0 comments on commit eac7700

Please sign in to comment.