#! /bin/sh # Copyright (c) 2014-2022 - Rich Brown rich.brown@blueberryhillsoftware.com # GPLv2 summarize_pings() { 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] )\ }' } # set an initial values for defaults TESTHOST="netperf.bufferbloat.net" TESTDUR="60" PING4=ping command -v ping4 > /dev/null 2>&1 && PING4=ping4 PING6=ping6 PINGHOST="gstatic.com" MAXSESSIONS=4 TESTPROTO=-4 # Create temp files for netperf up/download results ULFILE=`mktemp /tmp/netperfUL.XXXXXX` || exit 1 DLFILE=`mktemp /tmp/netperfDL.XXXXXX` || exit 1 PINGFILE=`mktemp /tmp/measurepings.XXXXXX` || exit 1 # echo $ULFILE $DLFILE $PINGFILE # read the options # extract options and their arguments into variables. while [ $# -gt 0 ] do case "$1" in -4|-6) TESTPROTO=$1; shift 1 ;; -H|--host) case "$2" in "") echo "Missing hostname" ; exit 1 ;; *) TESTHOST=$2 ; shift 2 ;; esac ;; -t|--time) case "$2" in "") echo "Missing duration" ; exit 1 ;; *) TESTDUR=$2 ; shift 2 ;; esac ;; -p|--ping) case "$2" in "") echo "Missing ping host" ; exit 1 ;; *) PINGHOST=$2 ; shift 2 ;; esac ;; -n|--number) case "$2" in "") echo "Missing number of simultaneous sessions" ; exit 1 ;; *) MAXSESSIONS=$2 ; shift 2 ;; esac ;; --) shift ; break ;; *) echo "Usage: sh Netperfrunner.sh [ -H netperf-server ] [ -t duration ] [ -p host-to-ping ] [ -n simultaneous-streams ]" ; exit 1 ;; esac done # Start main test if [ $TESTPROTO -eq "-4" ] then PROTO="ipv4" else PROTO="ipv6" fi DATE=`date "+%Y-%m-%d %H:%M:%S"` # Start Ping if [ $TESTPROTO -eq "-4" ] then "${PING4}" $PINGHOST > $PINGFILE & else "${PING6}" $PINGHOST > $PINGFILE & fi ping_pid=$! # echo "Ping PID: $ping_pid" # Start $MAXSESSIONS upload datastreams from netperf client to the netperf server for i in $( seq $MAXSESSIONS ) do netperf $TESTPROTO -H $TESTHOST -t TCP_STREAM -l $TESTDUR -v 0 -P 0 >> $ULFILE & # echo "Starting upload #$i $!" done # Start $MAXSESSIONS download datastreams from netperf server to the client for i in $( seq $MAXSESSIONS ) do netperf $TESTPROTO -H $TESTHOST -t TCP_MAERTS -l $TESTDUR -v 0 -P 0 >> $DLFILE & # echo "Starting download #$i $!" done for i in `pgrep -P $$ netperf` # get a list of PIDs for child processes named 'netperf' do # echo "Waiting for $i" wait $i done # Stop the pings after the netperf's are all done kill -9 $ping_pid wait $ping_pid 2>/dev/null DL=`awk '{s+=$1} END {print s}' $DLFILE` UL=`awk '{s+=$1} END {print s}' $ULFILE` echo "${DL}" "${UL}" > /tmp/speedtest.out #summarize_pings $PINGFILE # Clean up rm $PINGFILE rm $DLFILE rm $ULFILE sleep 60 rm /tmp/speedtest.out