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