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