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