remove plus1 variants
[anna.git] / example / diameter / launcher / resources / scripts / clone.sh
1 #!/bin/bash
2
3 #############
4 # VARIABLES #
5 #############
6 CLONE_WKDIR=$(mktemp -d)
7 #MAX_NUMBER_GROUPS=400
8 MAX_NUMBER_GROUPS=200
9 # (depends on the machine)
10
11 #############
12 # FUNCTIONS #
13 #############
14 _exit (){
15   echo
16   echo -e $1
17   echo
18
19   # Background jobs:
20   #remaining_jobs=$(jobs -p)
21   (kill -9 $(jobs -p) 2>&1) >/dev/null
22
23   # Cleanup:
24   rm -rf $CLONE_WKDIR
25
26   rc=1
27   [ -n "$2" ] && rc=$2
28   exit $rc
29 }
30
31 sig_handler() {
32   _exit "Script interrupted. Cleanup & exit ..."
33 }
34
35 usage() {
36   echo "Usage: $0 <ADML directory> <testcase variable file> <initial sequence> <final sequence> [number of groups] [population]"
37   echo
38   echo "          ADML directory:         path to the ADML directory where 'operation.sh' script is used to load the test cases."
39   echo "          testcase variable file: path to the testcase file with parseable variables, for example '<directory>/testcase.txt.msk'."
40   echo "                                  xml files within this test case, must exist with aditional .msk extension in the same directory."
41   echo
42   echo "                                  Currently, 9 variables are supported to be replaced:"
43   echo
44   echo "                                  * __TESTID__   : sequence number. For example if you provide 1 to 20 for this script, it will be 1 .. 20"
45   echo "                                  * __SEQ8__     : 8-digit number corresponding to the sequence number (00000001 for 1, and so on)"
46   echo "                                  * __IPV4HEX__  : hexadecimal IPv4 address, for example: 00000001"
47   echo "                                  * __IPV4__     : IPv4 address, for example: 0.0.0.1"
48   echo
49   #echo "                                  One variant (former ones plus 1):"
50   #echo "                                   __SEQ8P1__   : 8-digit number corresponding to the sequence number (00000002 for 1, and so on)"
51   #echo "                                   __IPV4HEXP1__: hexadecimal IPv4 address, for example: 00000002"
52   #echo "                                   __IPV4P1__   : IPv4 address, for example: 0.0.0.2"
53   #echo
54   echo "                                  Edit the variables section to add more special values if you need them."
55   echo
56   echo "          initial sequence:       initial sequence number to parse over variables."
57   echo "          final sequence:         final sequence number to parse over variables."
58   echo "          number of groups:       number of background group jobs to clone the provided sequence range."
59   echo "                                  By default (or if you provide \"\"), it will be the number of items divided by 25, with a maximum"
60   echo "                                  of $MAX_NUMBER_GROUPS."
61   echo "          population:             Optionally, a population file (basename) can be provided. It must exist on the same directory"
62   echo "                                  than other stuff (testcase, xml files). The behaviour will be the accumulation of every parsing"
63   echo "                                  operation during clone procedure regarding the templated content of the population file. The"
64   echo "                                  accumulated content will be dump over a new file created together with cloned <population> and"
65   echo "                                  named with the extension '.all' (<population>.all). This population file could be useful to"
66   echo "                                  specify database commands related to each sequence (each single testcase), in order to have"
67   echo "                                  the whole population file. This won't include common database elements for the tested scenary,"
68   echo "                                  which shall be provisioned in a separated procedure."
69   echo 
70   _exit
71 }
72
73 children () {
74   bash_pid=$$
75   children=`ps -eo ppid | grep -w $bash_pid`
76   echo $children | wc -w
77 }
78
79 # $1: sequence number; $2: file to parse(will be updated); $3: result file
80 parse_file() {
81   local vars=$(egrep -o '__((_*[A-Z]*[0-9]*)*)__' $2 | cut -d: -f2 | sort -u)
82   local file=$2
83   cp $2 $3
84   file=$3
85   for pvar in $vars
86   do
87     eval pvalue=\$$pvar
88     sed -i 's/'$pvar'/'$pvalue'/g' $file
89   done
90 }
91
92 # $1: sequence number; $2: working directory
93 clone() {
94   local sequence=$1
95   local wkdir=$2
96   mkdir -p $wkdir
97
98   ############################################# SPECIAL VARIABLES SECTION #############################################
99   ################################ EDIT THIS SECTION IF YOU NEED NEW SPECIAL VARIABLES ################################
100   testid=$sequence
101   seq8=$(printf "%08d" $testid)
102   #seq8_p1=$((seq8+1))
103   ipv4hex=$seq8
104   #ipv4hex_p1=$seq8_p1
105   #ipv4=$(for i in $(echo $seq8 | sed 's/\(..\)/0x\1 /g'); do printf "%d." $i; done | sed 's/\.$/\n/')
106   # Numbers beginning with "0" are treated as octal (i.e. base-8): we would have 'invalid octal number with 08 and 09'
107   # Solution: convert to base-10 in this way: $((10#$i))
108   ipv4=$(for i in $(echo $seq8 | sed 's/\(..\)/ \1 /g'); do printf "%d." $((10#$i)); done | sed 's/\.$/\n/')
109   #ipv4_p1=$(for i in $(echo $seq8_p1 | sed 's/\(..\)/ \1 /g'); do printf "%d." $((10#$i)); done | sed 's/\.$/\n/')
110
111   local target=$wkdir/values.${1}
112   echo "__TESTID__=$testid" > $target
113   echo "__SEQ8__=$seq8" >> $target
114   echo "__IPV4HEX__=$ipv4hex" >> $target
115   echo "__IPV4__=$ipv4" >> $target
116   ## First variant:
117   #echo "__SEQ8P1__=$seq8_p1" >> $target
118   #echo "__IPV4HEXP1__=$ipv4hex_p1" >> $target
119   #echo "__IPV4P1__=$ipv4_p1" >> $target
120   source $target
121   #rm $target
122   ######################################### END SPECIAL VARIABLES SECTION #########################################
123
124
125   # Parse template files:
126   parse_file $sequence $TESTCASE_TEMPLATE $wkdir/testcase.txt.$sequence
127   for file in $(grep sendxml $TESTCASE_TEMPLATE | cut -d\| -f4 | sed 's/\.xml$/.xml.msk/')
128   do
129     xml=`basename $file .msk`
130     parse_file $sequence $TESTCASE_TEMPLATE_DIR/$file $wkdir/${xml}.${sequence}
131     new_file=`readlink -f $wkdir/${xml}.${sequence}`
132     sed -i 's|'$xml'|'$new_file'|g' $wkdir/testcase.txt.$sequence
133   done
134   cat $wkdir/testcase.txt.$sequence >> $wkdir/testcase.txt
135   rm $wkdir/testcase.txt.$sequence
136
137   # Population:
138   if [ -n "$POPULATION" ]
139   then
140     parse_file $sequence $POPULATION_FILE $CLONE_WKDIR/${POPULATION}.$sequence
141     cat $CLONE_WKDIR/${POPULATION}.$sequence >> $POPULATION_ALL
142   fi
143 }
144
145 # $1: group number; $2: initial subrange value; $3: final subrange value
146 clone_group() {
147   for i in `seq $2 $3`
148   do
149     clone $i $CLONE_WKDIR/$1
150     sleep 0.01
151   done
152 }
153
154 #############
155 # EXECUTION #
156 #############
157 trap sig_handler SIGINT
158 trap sig_handler SIGTERM
159
160 ADML_DIR=$1
161 TESTCASE_TEMPLATE=`readlink -f $2`
162 TESTCASE_TEMPLATE_DIR=`dirname $TESTCASE_TEMPLATE`
163 CLONE_SEQ_BEGIN=$3
164 CLONE_SEQ_END=$4
165 N_GROUPS=$5
166 POPULATION=$6
167 POPULATION_FILE=$TESTCASE_TEMPLATE_DIR/$POPULATION
168 POPULATION_ALL=$TESTCASE_TEMPLATE_DIR/${POPULATION}.all
169
170 [ "$4" = "" ] && usage
171
172 # Auxiliary:
173 OPERATION=$ADML_DIR/operation.sh
174 [ ! -f $OPERATION ] && _exit "Missing '$OPERATION' file !!"
175 [ ! -f $TESTCASE_TEMPLATE ] && _exit "Missing '$TESTCASE_TEMPLATE' testcase template file !!"
176
177 if [ -n "$POPULATION" ]
178 then
179   bn_population=`basename $POPULATION`
180   [ "$bn_population" != "$POPULATION" ] && _exit "Only basename is allowed for population provided !!"
181   [ ! -f $POPULATION_FILE ] && _exit "Missing provided population file '$POPULATION_FILE' !!"
182   0> $POPULATION_ALL
183 fi
184
185 N_ITEMS=$((CLONE_SEQ_END - CLONE_SEQ_BEGIN + 1))
186 if [ -z "$N_GROUPS" ]
187 then
188   N_GROUPS=$((N_ITEMS/25))
189   [ $N_GROUPS -gt $MAX_NUMBER_GROUPS ] && N_GROUPS=$MAX_NUMBER_GROUPS
190   [ $N_GROUPS -eq 0 ] && N_GROUPS=1
191 fi
192 GROUPS_SIZE=$((N_ITEMS/N_GROUPS))
193 if [ "$GROUPS_SIZE" -eq 0 ]
194 then
195   echo "Assuming minimum allowed number of groups (one group per item): $N_ITEMS"
196   GROUPS_SIZE=1
197   N_GROUPS=$N_ITEMS
198 fi
199
200 # Start cloning:
201 timestamp_begin=$(echo "scale=3 ; $(date '+%s') + $(date '+%N') / 1000000000" | bc)
202 children_before=$(children)
203 offset=0
204 $OPERATION "test|clear"
205 echo "Please be patient, this may take a while ..."
206 #echo "Temporary directory: $CLONE_WKDIR"
207 for group in `seq 1 $((N_GROUPS+1))`
208 do
209   n_begin=$((CLONE_SEQ_BEGIN + offset))
210   n_end=$((n_begin + GROUPS_SIZE - 1))
211   [ $n_end -gt $CLONE_SEQ_END ] && n_end=$CLONE_SEQ_END
212   [ $n_end -lt $n_begin ] && break
213   clone_group $group $n_begin $n_end &
214   offset=$((group * GROUPS_SIZE))
215 done
216
217 # Wait background jobs to finish:
218 while true
219 do
220   sleep 1 
221   [ $(children) -eq $children_before ] && break
222 done
223
224 # Programming:
225 echo -n "Programming .."
226 for file in $(ls $CLONE_WKDIR/*/testcase.txt)
227 do
228   echo -n .
229   r_file=`readlink -f $file`
230   dn_r_file=`dirname $r_file`
231   $OPERATION -t 300 -f $r_file > $dn_r_file/result.txt
232   res=$?
233   if [ $res -ne 0 ]
234   then
235     bn_dn_r_file=`basename $dn_r_file`
236     exception_dir=$ADML_DIR/exception_stuff_${bn_dn_r_file}
237     rm -rf $exception_dir
238     cp -r $dn_r_file $exception_dir
239     cp $ADML_DIR/launcher.trace $exception_dir
240     _exit "Exception detected programming a testcase. Check for '$exception_dir'"
241   fi
242   rm -rf $dn_r_file &
243 done
244
245 timestamp_end=$(echo "scale=3 ; $(date '+%s') + $(date '+%N') / 1000000000" | bc)
246 echo
247 lasted=$(echo "scale=3 ; $timestamp_end - $timestamp_begin" | bc)
248 echo "Total Lasted $lasted seconds"
249 echo "Programming speed: $(echo "$N_ITEMS/$lasted" | bc) tests per second"
250
251 # Finish:
252 _exit "Done!" 0
253