improvs
[anna.git] / example / diameter / launcher / deployments / st-client / program.sh
1 #!/bin/bash
2
3 #############
4 # VARIABLES #
5 #############
6 ADML_INSTANCES=`cat .st_conf_adml_instances 2>/dev/null`
7 RATE_PER_INSTANCE=`cat .st_conf_rate_per_instance 2>/dev/null`
8 DESIRED_RATE=`cat .st_conf_desired_rate 2>/dev/null`
9 REPEATS=`cat .st_conf_cycle_repeats 2>/dev/null`
10 PROGRAM_LAYOUT_FILE=.st_conf_n_testcases_program_layout
11
12 #############
13 # FUNCTIONS #
14 #############
15 _exit() {
16   echo
17   echo $1
18   echo
19   exit 1
20 }
21
22 usage() {
23   cat << EOF
24 Usage: $0 <test stuff directory|dynamic> [-s]
25
26        Performs test case programming from scratch (current test cases will be dropped
27         from ADML involved instances). There are two types of programming depending on
28         the first argument provided:
29
30        test stuff directory:
31
32           The folder provided must contain msk files, specially a testcase file with
33           xml files referenced inside. Those xml files (without the .msk extension)
34           shall exists in the directory. For example:
35
36              $0 st_examples/DynamicQualification
37
38           Optionally, a file 'specific' could exists containing testcase-specific
39           information, which normally will be used to specify database sentences.
40           This file will be accumulated as a cloning seed over the file 'specific.all'
41           created on test stuff directory.
42
43           Template type programming could be used for medium-duration testings, because
44           the scripting used for programming, have lots of groups divisions which even
45           background-executed are much more slower on programming than a c++ builtin
46           procedure: dynamic type is the one for large sets of test cases:
47
48
49        dynamic:
50
51           The current dynamic procedure selected by mean 'dynlibs/select.sh' script,
52           will be programmed using its dirname resources: inside, you may found not
53           only the .so library but the needed xml files for the implemented scenary
54           and a file called 'dynamic.suffix' used to complete the dynamic operation
55           in this way:
56
57              dynamic|<initial sequence>|<final sequence>|<dynamic.suffix content>
58
59           For example, you could have this content for 'dynamic.suffix':
60
61              7|CCR-I.xml|CCR-T.xml
62
63           in order to generate the operation:
64
65              dynamic|<initial sequence>|<final sequence>|7|CCR-I.xml|CCR-T.xml
66
67           which would be parsed for the specific ADML instance programmed:
68
69              dynamic|2000001|2001000|7|CCR-I.xml|CCR-T.xml
70
71           The file 'dynamic.suffix' could have several lines for several scenaries.
72           In this case, this script will prompt for the desired one.
73
74           This script will build every operation for the configured ADML instances
75           to complete all the sequence ranges along the whole test system.
76
77
78
79        -s: start testing just after programming, using desired rate: $DESIRED_RATE test cases per second.
80 EOF
81   [ $ADML_INSTANCES -gt 1 ] && echo "           In your case, with $ADML_INSTANCES, a rate of $RATE_PER_INSTANCE ttps will be send per instance."
82   echo
83   _exit
84 }
85
86 #############
87 # EXECUTION #
88 #############
89 miss_conf=
90 [ ! -f .st_conf_adml_instances ] && miss_conf=yes
91 [ ! -f .st_conf_n_testcases_program_layout ] && miss_conf=yes
92 [ ! -f .st_conf_cycle_repeats ] && miss_conf=yes
93 [ ! -f .st_conf_rate_per_instance ] && miss_conf=yes
94 [ ! -f .st_conf_desired_rate ] && miss_conf=yes
95 [ -n "$miss_conf" ] && _exit "You must run './configure.sh' script firtly !!"
96
97 echo
98 [ -z "$1" ] && usage
99 echo "Starting testcases programming ..."
100 echo
101
102 ./operation.sh --ping >/dev/null
103 [ $? -ne 0 ] && _exit "Programming aborted (some ADML client process is not running) !"
104
105 # Arguments:
106 PROG_TYPE=$1
107 AUTOSTART=$2
108
109 # test case stuff programming #########################################################
110 if [ "$PROG_TYPE" != "dynamic" ]
111 then
112   TESTCASE_DIR=$PROG_TYPE
113
114   [ ! -d $TESTCASE_DIR ] && _exit "Cannot found the test directory '$TESTCASE_DIR' !!"
115   TESTCASE=( `ls $TESTCASE_DIR/testcase*msk 2>/dev/null` )
116   TESTCASE_FILES=${#TESTCASE[@]}
117   [ $TESTCASE_FILES -ne 1 ] && _exit "One and only one 'testcase*msk' file must be present !!"
118
119   MAX_NUMBER_GROUPS=$(grep ^MAX_NUMBER_GROUPS= clone.sh | cut -d= -f2)
120   CLONE_GROUPS=$((MAX_NUMBER_GROUPS/ADML_INSTANCES))
121   #CLONE_GROUPS=1
122   specific=
123   [ -f $TESTCASE_DIR/specific ] && specific=specific
124   
125   [ -z "$ADML_CONCURRENT_PROVISION_JOBS" ] && ADML_CONCURRENT_PROVISION_JOBS=5
126   
127   count=0
128   while read -r line
129   do
130     instance=$(echo $line | awk '{ print $1 }')
131     ini_seq=$(echo $line | awk '{ print $2 }')
132     fin_seq=$(echo $line | awk '{ print $3 }')
133     ADML_DIR=`readlink -f ADMLS/ADML-$instance`
134     echo -e "\rCloning interval [$ini_seq,$fin_seq] for $(basename $ADML_DIR) ..."
135     ./clone.sh $ADML_DIR $TESTCASE $ini_seq $fin_seq $CLONE_GROUPS $specific &
136     sleep 0.1
137     count=$((count+1))
138     if [ $count -eq $ADML_CONCURRENT_PROVISION_JOBS ]
139     then
140       idle_cpu=$(top -b -d 0.1 -n 2 | grep 'Cpu(s):'| tail -1 |awk '{print $8}')
141       echo
142       echo "Idle cpu = $idle_cpu%"
143       echo "if cpu is not overcommited, consider increase ADML_CONCURRENT_PROVISION_JOBS environment variable (now $ADML_CONCURRENT_PROVISION_JOBS)"
144       echo
145       wait $(jobs -p)
146       count=0
147     fi
148   
149   done < $PROGRAM_LAYOUT_FILE
150   
151   # Wait background jobs to finish:
152   sleep 5
153   echo "Waiting for clone completion ..."
154   echo "(please be patient, this may take a while)"
155   echo
156   echo "Background Jobs: $(jobs -p | wc -l)"
157   wait $(jobs -p)
158   
159   echo
160   echo "Programming has finished !"
161   echo
162   
163   echo "Configuring repeat cycles ..."
164   ./operation.sh "test|repeats|$REPEATS"
165   
166   if [ -n "$specific" ]
167   then
168     echo "A new file '$TESTCASE_DIR/specific.all' has been created."
169     echo "Probably you need to apply it before starting traffic."
170     echo
171     echo "Press ENTER to continue, CTRL-C to abort ..."
172     read dummy
173   fi
174
175 # dynamic programming #################################################################
176 else
177   TESTCASE_DIR=$(readlink -f dynlibs/libanna_dynamicLauncherProcedure.so | xargs dirname)
178   DYNAMIC_SUFFIX_FILE=$TESTCASE_DIR/dynamic.suffix
179
180   [ ! -f $DYNAMIC_SUFFIX_FILE ] && _exit "Missing '$DYNAMIC_SUFFIX_FILE' file. Use 'dynlibs/select.sh' to change the dynamic procedure and restart the ADML instances."
181   dynamic_suffix=( $(grep -v ^# $DYNAMIC_SUFFIX_FILE) )
182
183   # Multiple scenarios:
184   suffixes=${#dynamic_suffix[@]}
185   if [ $suffixes -gt 1 ]
186   then
187     echo "Detected $suffixes scenarios. Please, select the desired option:"
188     echo
189     tmpfile=$(mktemp)
190     opt=1
191     for line in $(grep -v ^# $DYNAMIC_SUFFIX_FILE)
192     do
193       echo "${opt}) $line"
194       opt=$((opt+1))
195     done > $tmpfile
196     cat $tmpfile
197     echo
198     read option
199     while [ -z "$option" ]; do read option ; done
200     dynamic_suffix=$(grep "^${option}) " $tmpfile | cut -d" " -f2-)
201     [ -z "$dynamic_suffix" ] && _exit "Invalid option !"
202   fi
203
204   # Modify xml files path:
205   xmls=( $(echo $dynamic_suffix | sed 's/'\|'/ /g') )
206   dynamic_suffix=$(for xml in ${xmls[@]}
207   do
208     echo $xml | grep -q "\.xml$"
209     [ $? -eq 0 ] && echo -n "$TESTCASE_DIR/"
210     echo -n "${xml}|"
211   done | sed 's/'\|'$//')
212
213   # If still idle CPU, you could increase chunks number of background jobs
214   CHUNKS=10
215   echo "Dynamic programming ..."
216   echo
217   while read -r line
218   do
219     instance=$(echo $line | awk '{ print $1 }')
220     ini_seq=$(echo $line | awk '{ print $2 }')
221     fin_seq=$(echo $line | awk '{ print $3 }')
222     ADML_DIR=`readlink -f ADMLS/ADML-$instance`
223   
224     cd $ADML_DIR                                                      
225     ./operation.sh -t 60 "dynamic|$ini_seq|$fin_seq|$dynamic_suffix" &
226     count=$((count+1))                                                
227     [ $count -eq $CHUNKS ] && { wait $(jobs -p) ; count=1 ; }               
228     cd - >/dev/null                                                   
229   
230   done < $PROGRAM_LAYOUT_FILE
231
232 fi
233
234 echo
235 echo
236 start_testing=
237 if [ "$AUTOSTART" = "-s" ]
238 then
239   start_testing=yes
240 else
241   echo "Input desired rate (test cases per second) to start testing [0: nothing done]:"
242   read desired_rate
243   if [ "$desired_rate" != "" ]
244   then
245     rate_per_instance=$((desired_rate/$ADML_INSTANCES))
246     [ $rate_per_instance -lt 1 ] && rate_per_instance=1
247     ./operation.sh "test|ttps|$rate_per_instance"
248   else
249     cat << EOF
250
251 To start testing, you must use the './operation.sh' script. Use '-h'
252  to get detailed help. The most common commands used for testing are:
253
254  * Enable reports dump for failed tests:
255     ./operation.sh "test|report|failed"
256
257  * Launch traffic:
258     ./operation.sh "test|ttps|<test cases per second and instance(*)>"
259
260     (*) note: ttps value is related to a single instance: you should"
261               divide the desired CPS by the number of instances. For"
262               exampl, if you need $DESIRED_RATE test cases per second:
263
264                 ./operation.sh "test|ttps|$RATE_PER_INSTANCE"
265
266  * Stop traffic:
267     ./operation.sh "test|ttps|0"
268
269  * Reset already classified (Success/Failed) test cases:
270     ./operation.sh "test|reset[|soft]"
271
272  * Reset also 'in-progress' state test cases:
273     ./operation.sh "test|reset|hard"
274
275 Remember that './operation.sh' broadcasts the operation scripts along
276  the ADML instances, then some operations should better be used within
277  a specific 'ADMLS/ADML-<instance>' directory to avoid console spam,
278  for example: 
279
280  * Check a testcase in runtime:
281    ADMLS/ADML-001/operation.sh "test|look|<test id>"
282
283  * Execute the next programmed test case:
284    ADMLS/ADML-001/operation.sh "test|next"
285
286  * Interactive-step execution:
287    ADMLS/ADML-001/operation.sh "test|interact|<steps to execute>|<test id>"
288
289  * Summary:
290    ADMLS/ADML-001/operation.sh "test|summary"
291
292 EOF
293
294   fi
295 fi
296
297 if [ -n "$start_testing" ]
298 then
299   echo
300   echo "Start testing to achieve desired rate of $DESIRED_RATE test cases per second ..."
301   echo
302   ./operation.sh "test|ttps|$RATE_PER_INSTANCE"
303 fi
304
305 echo
306 echo "Done !"
307 echo
308