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