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