How A Simple Test Script Evolve
The requirement is pretty simple. "Can I have a script to submit program-a to run 5 times for 10 minutes, 3 times for 5 minutes and 2 times for half an hour?". There you go with a one-time throw-away script. BTW, this is supposed to run on a Linux system
#! /bin/sh ./program-a --duration 600 ./program-a --duration 600 ./program-a --duration 600 ./program-a --duration 600 ./program-a --duration 600 ./program-a --duration 300 ./program-a --duration 300 ./program-a --duration 300 ./program-a --duration 1800 ./program-a --duration 1800
Our job is done. What if the requirement for duration needs to be changed and we will have to modify quite a few places in the above script. So the script evolved to do some looping.
#! /bin/sh for i in 1 2 3 4 5 do ./program-a --duration 600 done for i in 1 2 3 do ./program-a --duration 300 done for i in 1 2 do ./program-a --duration 1800 done
Not too bad! But there are still a few places where we hard code things like how many times we loop and the duration. OK, may be we can do some form of input instead of fix values
#! /bin/sh while read duration howmany do seq $howmany | while read count do ./program-a --duration $duration done done <<EOF 600 5 300 3 1800 2 EOF
Now all I have to do is to change the input data (within the EOF) in the script to control the duration in seconds and how many times to loop through. Hey, but I still need to modify the program every time there is a change in requirement. Can't we have that information to be controlled by input arguments. Also, I want to tell the script in terms of day/hour/minute/second instead of just seconds because I am lazy to calculate. Not a problem at all. Let say the input argument takes the form of "1d23h45m6sx7" to represent looping through the prgroam 7 times with a duration of 1 day 23 hours 45 minutes 6 seconds (that is 171906 seconds, if you work it out). This calculation can be easily done by using sed to substitute day (d) with '*86400+', hour (h) with '*3600+', minute (m) with '*60+' and second (s) with ''. You also need to remove any ending '+' to avoid illegal arthematic epxpression.
#! /bin/sh if [ $# -eq 0 ]; then echo "Usage: $0 [?d?h?m?sx?]" echo " Eg. $0 1d23h45m6sx17 4h30sx8 1hx7" exit 1 fi # check arg syntax for arg in $@ do echo $arg | egrep '^([1-9][0-9]*d)?([1-9][0-9]*h)?([1-9][0-9]*m)?([1-9][0-9]*s)?x[1-9][0-9]*$' > /dev/null if [ $? -ne 0 ]; then echo "Error. $arg syntax not correct" exit 2 fi done for arg in $@ do duration=`echo ${arg%x*} | sed -e 's/d/*86400+/;s/h/*3600+/;s/m/*60+/;s/s//;s/+$//' | bc` for count in `seq ${arg#*x}` do ./program-a --duration $duration done done
If you need to run program-a 1.5 day once, 3 hour and 5 seconds twice and 30 minutes thrice, all you need to do is
./loop.sh 1d12hx1 3h5sx2 30mx3
I hope this blog shows you how a simple script can evolve into something so generic that your future test scripts can be based on.
Labels: shell script