Advertisement
Guest User

Untitled

a guest
Jul 28th, 2019
504
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.85 KB | None | 0 0
  1. #!/bin/sh
  2.  
  3. # betterspeedtest.sh - Script to simulate http://speedtest.net
  4. # Start pinging, then initiate a download, let it finish, then start an upload
  5. # Output the measured transfer rates and the resulting ping latency
  6. # It's better than 'speedtest.net' because it measures latency *while* measuring the speed.
  7.  
  8. # Usage: sh betterspeedtest.sh [-4 -6] [ -H netperf-server ] [ -t duration ] [ -p host-to-ping ] [ -i ] [ -n simultaneous-streams ]
  9.  
  10. # Options: If options are present:
  11. #
  12. # -H | --host: DNS or Address of a netperf server (default - netperf.bufferbloat.net)
  13. # Alternate servers are netperf-east (east coast US), netperf-west (California),
  14. # and netperf-eu (Denmark)
  15. # -4 | -6: enable ipv4 or ipv6 testing (ipv4 is the default)
  16. # -t | --time: Duration for how long each direction's test should run - (default - 60 seconds)
  17. # -p | --ping: Host to ping to measure latency (default - gstatic.com)
  18. # -i | --idle: Don't send traffic, only measure idle latency
  19. # -n | --number: Number of simultaneous sessions (default - 5 sessions)
  20.  
  21. # Copyright (c) 2014-2019 - Rich Brown rich.brown@blueberryhillsoftware.com
  22. # GPLv2
  23.  
  24. # Summarize the contents of the ping's output file to show min, avg, median, max, etc.
  25. # input parameter ($1) file contains the output of the ping command
  26.  
  27. summarize_pings() {
  28.  
  29. # Process the ping times, and summarize the results
  30. # grep to keep lines that have "time=", then sed to isolate the time stamps, and sort them
  31. # awk builds an array of those values, and prints first & last (which are min, max)
  32. # and computes average.
  33. # If the number of samples is >= 10, also computes median, and 10th and 90th percentile readings
  34.  
  35. # stop pinging and drawing dots
  36. kill_pings
  37. kill_dots
  38.  
  39. sed 's/^.*time=\([^ ]*\) ms/\1/' < $1 | grep -v "PING" | sort -n | \
  40. awk 'BEGIN {numdrops=0; numrows=0;} \
  41. { \
  42. if ( $0 ~ /timeout/ ) { \
  43. numdrops += 1; \
  44. } else { \
  45. numrows += 1; \
  46. arr[numrows]=$1; sum+=$1; \
  47. } \
  48. } \
  49. END { \
  50. pc10="-"; pc90="-"; med="-"; \
  51. if (numrows == 0) {numrows=1} \
  52. if (numrows>=10) \
  53. { ix=int(numrows/10); pc10=arr[ix]; ix=int(numrows*9/10);pc90=arr[ix]; \
  54. if (numrows%2==1) med=arr[(numrows+1)/2]; else med=(arr[numrows/2]); \
  55. }; \
  56. pktloss = numdrops/(numdrops+numrows) * 100; \
  57. 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] )\
  58. }'
  59.  
  60. # and finally remove the PINGFILE
  61. rm $1
  62.  
  63. }
  64.  
  65. # Print a line of dots as a progress indicator.
  66.  
  67. print_dots() {
  68. while : ; do
  69. printf "."
  70. sleep 1s
  71. done
  72. }
  73.  
  74. # Stop the current print_dots() process
  75.  
  76. kill_dots() {
  77. # echo "Pings: $ping_pid Dots: $dots_pid"
  78. kill -9 $dots_pid
  79. wait $dots_pid 2>/dev/null
  80. dots_pid=0
  81. }
  82.  
  83. # Stop the current ping process
  84.  
  85. kill_pings() {
  86. # echo "Pings: $ping_pid Dots: $dots_pid"
  87. kill -9 $ping_pid
  88. wait $ping_pid 2>/dev/null
  89. ping_pid=0
  90. }
  91.  
  92. # Stop the current pings and dots, and exit
  93. # ping command catches (and handles) first Ctrl-C, so you have to hit it again...
  94. kill_pings_and_dots_and_exit() {
  95. kill_dots
  96. kill_pings
  97. echo "\nStopped"
  98. exit 1
  99. }
  100.  
  101. # ------------ start_pings() ----------------
  102. # Start printing dots, then start a ping process, saving the results to a PINGFILE
  103.  
  104. start_pings() {
  105.  
  106. # Create temp file
  107. PINGFILE=`mktemp /tmp/measurepings.XXXXXX` || exit 1
  108.  
  109. # Start dots
  110. print_dots &
  111. dots_pid=$!
  112. # echo "Dots PID: $dots_pid"
  113.  
  114. # Start Ping
  115. if [ $TESTPROTO -eq "-4" ]
  116. then
  117. ping $PINGHOST > $PINGFILE &
  118. else
  119. ping6 $PINGHOST > $PINGFILE &
  120. fi
  121. ping_pid=$!
  122. # echo "Ping PID: $ping_pid"
  123.  
  124. }
  125.  
  126. # ------------ Measure speed and ping latency for one direction ----------------
  127. #
  128. # Call measure_direction() with single parameter - "Download" or " Upload"
  129. # The function gets other info from globals determined from command-line arguments
  130.  
  131. measure_direction() {
  132.  
  133. # Create temp file
  134. SPEEDFILE=`mktemp /tmp/netperfUL.XXXXXX` || exit 1
  135. DIRECTION=$1
  136.  
  137. # start off the ping process
  138. start_pings
  139.  
  140. # Start netperf with the proper direction
  141. if [ $DIRECTION = "Download" ]; then
  142. dir="TCP_MAERTS"
  143. else
  144. dir="TCP_STREAM"
  145. fi
  146.  
  147. # Start $MAXSESSIONS datastreams between netperf client and the netperf server
  148. # netperf writes the sole output value (in Mbps) to stdout when completed
  149. for i in $( seq $MAXSESSIONS )
  150. do
  151. netperf $TESTPROTO -H $TESTHOST -t $dir -l $TESTDUR -v 0 -P 0 >> $SPEEDFILE &
  152. # echo "Starting PID $! params: $TESTPROTO -H $TESTHOST -t $dir -l $TESTDUR -v 0 -P 0 >> $SPEEDFILE"
  153. done
  154.  
  155. # Wait until each of the background netperf processes completes
  156. # echo "Process is $$"
  157. # echo `pgrep -P $$ netperf `
  158.  
  159. for i in `pgrep -P $$ netperf ` # gets a list of PIDs for child processes named 'netperf'
  160. do
  161. #echo "Waiting for $i"
  162. wait $i
  163. done
  164.  
  165. # Print TCP Download speed
  166. echo ""
  167. awk -v dir="$1" '{s+=$1} END {printf " %s: %1.2f Mbps", dir, s}' < $SPEEDFILE
  168.  
  169. # When netperf completes, summarize the ping data
  170. summarize_pings $PINGFILE
  171.  
  172. rm $SPEEDFILE
  173. }
  174.  
  175. # ------- Start of the main routine --------
  176.  
  177. # Usage: sh betterspeedtest.sh [ -4 -6 ] [ -H netperf-server ] [ -t duration ] [ -p host-to-ping ] [ -i ] [ -n simultaneous-sessions ]
  178.  
  179. # “H” and “host” DNS or IP address of the netperf server host (default: netperf.bufferbloat.net)
  180. # “t” and “time” Time to run the test in each direction (default: 60 seconds)
  181. # “p” and “ping” Host to ping for latency measurements (default: gstatic.com)
  182. # "i" and "idle" Don't send up/down traffic - just measure idle link latency
  183. # "n" and "number" Number of simultaneous upload or download sessions (default: 5 sessions;
  184. # 5 sessions chosen empirically because total didn't increase much after that number)
  185.  
  186. # set an initial values for defaults
  187. TESTHOST="netperf.bufferbloat.net"
  188. TESTDUR="60"
  189. PINGHOST="gstatic.com"
  190. MAXSESSIONS="5"
  191. TESTPROTO="-4"
  192. IDLETEST=false
  193.  
  194. # read the options
  195.  
  196. # extract options and their arguments into variables.
  197. while [ $# -gt 0 ]
  198. do
  199. case "$1" in
  200. -4|-6) TESTPROTO=$1 ; shift 1 ;;
  201. -H|--host)
  202. case "$2" in
  203. "") echo "Missing hostname" ; exit 1 ;;
  204. *) TESTHOST=$2 ; shift 2 ;;
  205. esac ;;
  206. -t|--time)
  207. case "$2" in
  208. "") echo "Missing duration" ; exit 1 ;;
  209. *) TESTDUR=$2 ; shift 2 ;;
  210. esac ;;
  211. -p|--ping)
  212. case "$2" in
  213. "") echo "Missing ping host" ; exit 1 ;;
  214. *) PINGHOST=$2 ; shift 2 ;;
  215. esac ;;
  216. -n|--number)
  217. case "$2" in
  218. "") echo "Missing number of simultaneous sessions" ; exit 1 ;;
  219. *) MAXSESSIONS=$2 ; shift 2 ;;
  220. esac ;;
  221. -i|--idle)
  222. IDLETEST=true ; shift 1 ;;
  223. --) shift ; break ;;
  224. *) echo "Usage: sh betterspeedtest.sh [-4 -6] [ -H netperf-server ] [ -t duration ] [ -p host-to-ping ] [ -n simultaneous-sessions ] [ --idle ]" ; exit 1 ;;
  225. esac
  226. done
  227.  
  228. # Start the main test
  229.  
  230. if [ $TESTPROTO -eq "-4" ]
  231. then
  232. PROTO="ipv4"
  233. else
  234. PROTO="ipv6"
  235. fi
  236. DATE=`date "+%Y-%m-%d %H:%M:%S"`
  237.  
  238. # Catch a Ctl-C and stop the pinging and the print_dots
  239. trap kill_pings_and_dots_and_exit HUP INT TERM
  240.  
  241. if $IDLETEST
  242. then
  243. echo "$DATE Testing idle line while pinging $PINGHOST ($TESTDUR seconds)"
  244. start_pings
  245. sleep $TESTDUR
  246. summarize_pings $PINGFILE
  247.  
  248. else
  249. echo "$DATE Testing against $TESTHOST ($PROTO) with $MAXSESSIONS simultaneous sessions while pinging $PINGHOST ($TESTDUR seconds in each direction)"
  250. measure_direction "Download"
  251. measure_direction " Upload"
  252. fi
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement