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