b000f8d8081fc4784f6440781eb832f119e1ca7d
[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 -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|<timeout ms>|<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|0|<initial sequence>|<final sequence>|7|CCR-I.xml|CCR-T.xml
65
66           which would be parsed for the specific ADML instance programmed:
67
68              dynamic|0|2000001|2001000|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 }
93
94 #############
95 # EXECUTION #
96 #############
97 miss_conf=
98 [ ! -f .st_conf_adml_instances ] && miss_conf=yes
99 [ ! -f .st_conf_n_testcases_program_layout ] && miss_conf=yes
100 [ ! -f .st_conf_cycle_repeats ] && miss_conf=yes
101 [ ! -f .st_conf_rate_per_instance ] && miss_conf=yes
102 [ ! -f .st_conf_desired_rate ] && miss_conf=yes
103 [ -n "$miss_conf" ] && _exit "You must run './configure.sh' script firtly !!"
104
105 echo
106 [ -z "$1" ] && usage
107 echo "Starting testcases programming ..."
108 echo
109
110 ./operation.sh --ping >/dev/null
111 [ $? -ne 0 ] && _exit "Programming aborted (some ADML client process is not running) !"
112
113 # Arguments:
114 PROG_TYPE=$1
115 AUTOSTART=$2
116
117 # test case stuff programming #########################################################
118 if [ "$PROG_TYPE" != "dynamic" ]
119 then
120   TESTCASE_DIR=$PROG_TYPE
121
122   [ ! -d $TESTCASE_DIR ] && _exit "Cannot found the test directory '$TESTCASE_DIR' !!"
123   TESTCASE=( `ls $TESTCASE_DIR/testcase*msk 2>/dev/null` )
124   TESTCASE_FILES=${#TESTCASE[@]}
125   [ $TESTCASE_FILES -ne 1 ] && _exit "One and only one 'testcase*msk' file must be present !!"
126
127   MAX_NUMBER_GROUPS=$(grep ^MAX_NUMBER_GROUPS= clone.sh | cut -d= -f2)
128   CLONE_GROUPS=$((MAX_NUMBER_GROUPS/ADML_INSTANCES))
129   #CLONE_GROUPS=1
130   specific=
131   [ -f $TESTCASE_DIR/specific ] && specific=specific
132   
133   count=0
134   while read -r line
135   do
136     instance=$(echo $line | awk '{ print $1 }')
137     ini_seq=$(echo $line | awk '{ print $2 }')
138     fin_seq=$(echo $line | awk '{ print $3 }')
139     ADML_DIR=`readlink -f ADMLS/ADML-$instance`
140     echo -e "\rCloning interval [$ini_seq,$fin_seq] for $(basename $ADML_DIR) ..."
141     ./clone.sh $ADML_DIR $TESTCASE $ini_seq $fin_seq $CLONE_GROUPS $specific &
142     sleep 0.1
143     count=$((count+1))
144     if [ $count -eq $ADML_CONCURRENT_PROVISION_JOBS ]
145     then
146       wait $(jobs -p)
147       count=0
148     fi
149   
150   done < $PROGRAM_LAYOUT_FILE
151
152   # Advice for idle cpu:
153   advice_to_squeeze_idle_cpu
154   
155   # Wait background jobs to finish:
156   sleep 5
157   echo "Waiting for clone completion ..."
158   echo "(please be patient, this may take a while)"
159   echo
160   echo "Background Jobs: $(jobs -p | wc -l)"
161   wait $(jobs -p)
162   
163   echo
164   echo "Programming has finished !"
165   echo
166   
167   echo "Configuring repeat cycles ..."
168   ./operation.sh "test|repeats|$REPEATS"
169   
170   if [ -n "$specific" ]
171   then
172     echo "A new file '$TESTCASE_DIR/specific.all' has been created."
173     echo "Probably you need to apply it before starting traffic."
174     echo
175     echo "Press ENTER to continue, CTRL-C to abort ..."
176     read dummy
177   fi
178
179 # dynamic programming #################################################################
180 else
181   TESTCASE_DIR=$(readlink -f dynlibs/libanna_dynamicLauncherProcedure.so | xargs dirname)
182   DYNAMIC_SUFFIX_FILE=$TESTCASE_DIR/dynamic.suffix
183
184   [ ! -f $DYNAMIC_SUFFIX_FILE ] && _exit "Missing '$DYNAMIC_SUFFIX_FILE' file.\nUse 'dynlibs/select.sh' to change the dynamic procedure and restart the ADML instances."
185   dynamic_suffix=( $(grep -v ^# $DYNAMIC_SUFFIX_FILE) )
186
187   # Multiple scenarios:
188   suffixes=${#dynamic_suffix[@]}
189   if [ $suffixes -gt 1 ]
190   then
191     echo
192     echo "----------------------------------------------------------------"
193     cat $DYNAMIC_SUFFIX_FILE
194     echo "----------------------------------------------------------------"
195     echo
196     echo "Detected $suffixes scenarios:"
197     echo
198     tmpfile=$(mktemp)
199     opt=1
200     for line in $(grep -v ^# $DYNAMIC_SUFFIX_FILE)
201     do
202       echo "${opt}) $line"
203       opt=$((opt+1))
204     done > $tmpfile
205     cat $tmpfile
206     echo
207     echo "Select the desired option (0 to input a user defined one):"
208     read option
209     while [ -z "$option" ]; do read option ; done
210     if [ "$option" != "0" ]
211     then
212       dynamic_suffix=$(grep "^${option}) " $tmpfile | cut -d" " -f2-)
213       [ -z "$dynamic_suffix" ] && _exit "Invalid option !"
214     else
215       echo "Input specific program arguments:"
216       echo " (be sure that are supported by the dynamic procedure)"
217       echo
218       read dynamic_suffix
219       while [ -z "$dynamic_suffix" ]; do read dynamic_suffix ; done
220     fi
221   fi
222
223   # Modify xml files path:
224   xmls=( $(echo $dynamic_suffix | sed 's/'\|'/ /g') )
225   dynamic_suffix=$(for xml in ${xmls[@]}
226   do
227     echo $xml | grep -q "\.xml$"
228     [ $? -eq 0 ] && echo -n "$TESTCASE_DIR/"
229     echo -n "${xml}|"
230   done | sed 's/'\|'$//')
231
232   # If still idle CPU, you could increase chunks number of background jobs
233   echo "Dynamic programming ..."
234   echo
235   while read -r line
236   do
237     instance=$(echo $line | awk '{ print $1 }')
238     ini_seq=$(echo $line | awk '{ print $2 }')
239     fin_seq=$(echo $line | awk '{ print $3 }')
240     ADML_DIR=`readlink -f ADMLS/ADML-$instance`
241   
242     cd $ADML_DIR                                                      
243     ./operation.sh -t 60 "dynamic|$ini_seq|$fin_seq|$dynamic_suffix" &
244     sleep 0.1
245     count=$((count+1))                                                
246     if [ $count -eq $ADML_CONCURRENT_PROVISION_JOBS ]
247     then
248       wait $(jobs -p)
249       count=1
250     fi
251     cd - >/dev/null                                                   
252   
253   done < $PROGRAM_LAYOUT_FILE
254
255   # Advice for idle cpu:
256   advice_to_squeeze_idle_cpu
257
258 fi
259
260 echo
261 echo
262 start_testing=
263 if [ "$AUTOSTART" = "-s" ]
264 then
265   start_testing=yes
266 else
267   echo "Input desired rate (test cases per second) to start testing [0: nothing done]:"
268   read desired_rate
269   if [ "$desired_rate" != "" ]
270   then
271     rate_per_instance=$((desired_rate/$ADML_INSTANCES))
272     [ $rate_per_instance -lt 1 ] && rate_per_instance=1
273     ./operation.sh "test|ttps|$rate_per_instance"
274   else
275     cat << EOF
276
277 To start testing, you must use the './operation.sh' script. The most
278  common commands used for testing are:
279
280  - Enable reports dump for failed tests: ./operation.sh "test|report|failed"
281  - Launch traffic: ./operation.sh "test|ttps|<test ticks per second (*)>"
282
283    (*) this is related to a single instance, because operation script launched
284        here invokes every 'ADMLS/ADML-<instance>/operation.sh' counterpart
285        script. Then, you should divide the desired CPS by the number of
286        instances. For example, if you need $DESIRED_RATE test cases per second,
287        as you have $ADML_INSTANCES instances, then you should execute:
288
289         ./operation.sh "test|ttps|$RATE_PER_INSTANCE"
290
291  - Stop traffic: ./operation.sh "test|ttps|0"
292  - Reset already classified (Success/Failed) test cases: ./operation.sh "test|reset[|soft]"
293  - Reset also 'in-progress' state test cases: ./operation.sh "test|reset|hard"
294  - Clear programmed test cases: ./operation.sh "test|clear"
295
296 Remember that './operation.sh' broadcasts the operation scripts inside
297  the ADML instances, then some operations should better be used within
298  a specific 'ADMLS/ADML-<instance>' directory to avoid console spam:
299
300  - Check a testcase in runtime: ADMLS/ADML-001/operation.sh "test|look|<test id>"
301  - Execute the next programmed test case: ADMLS/ADML-001/operation.sh "test|next"
302  - Interactive-step execution: ADMLS/ADML-001/operation.sh "test|interact|<steps to execute>|<test id>"
303  - Summary: ADMLS/ADML-001/operation.sh "test|summary"
304
305 For a complete and detailed information, execute: ./operation.sh --help | less
306
307 EOF
308
309   fi
310 fi
311
312 if [ -n "$start_testing" ]
313 then
314   echo
315   echo "Start testing to achieve desired rate of $DESIRED_RATE test cases per second ..."
316   echo
317   ./operation.sh "test|ttps|$RATE_PER_INSTANCE"
318 fi
319
320 echo
321 echo "Done !"
322 echo
323