"Initial commit to Gerrit"
[profile/ivi/libcroco.git] / tests / testctl
1 #! /bin/sh
2
3 #####################################
4 #This script just runs the tests of 
5 #libcroco, saves their result, diff them
6 #against a set of reference results and
7 #displays OK/KO.
8 #To use it as a tester, the best way is
9 #just to run 'testctl run' and see the result.
10 ####################################
11
12 #the directory that contains the tests sources is:
13 #$TEST_SOURCE_DIR. User can set this var in the environment
14 #before calling this script. Otherwise, we set it to a default value
15 if test x$TEST_SOURCE_DIR = x ; then
16         TEST_SOURCE_DIR=`dirname "$0"`
17 fi
18
19 #the directory that contains the test outputs is:
20 #$TEST_OUT_DIR
21 #User can set this var in the environment before
22 #calling this script. Otherwise, we set it to a default value.
23 if test x$TEST_OUT_DIR = x ; then
24         TEST_OUT_DIR=tests
25 fi
26
27
28 #the list of tests to be run
29 TEST_PROG_LIST=
30
31 #the test input dirs.
32 TEST_INPUT_DIR=test-inputs
33
34 #the reference test output dirs.
35 TEST_OUT_REF_DIR=test-output-refs
36
37 #temporary test result dir
38 TEST_OUTPUT_DIR=test-outputs
39
40 ERROR_REPORT_FILE=tests-error.log
41 COMMAND_LIST=
42 COMMAND=
43 if test x$RUN_VALGRIND = x ; then
44     RUN_VALGRIND=no
45 else
46     RUN_VALGRIND=yes
47 fi
48 if test "x$CHECKER" = "x" ; then
49     CHECKER="valgrind --tool=memcheck"
50 fi
51
52 VALGRIND_LOGS_DIR=valgrind-logs
53 VALGRIND=
54 TEST_PROG=
55 EGREP=`which egrep`
56 if test "empty$EGREP" = "empty" ; then
57     echo "You don't have the egrep program installed"
58     echo "Please, install it first"
59 fi
60
61 DIFF=`which diff`
62 if test "empty$DIFF" = "empty" ; then
63     echo "You don't have the diff program installed"
64     echo "Please, install is first"
65 fi
66
67 display_usage ()
68 {
69     echo ""
70     echo "usage: $0 [general options] <command> [command option]"
71     echo ""
72     echo "where general options are:"
73     echo "===================="
74     echo "-h|--help     displays this help"
75     echo ""
76     echo "commands are:"
77     echo "=============="
78     echo "run           run the tests and display their result"
79     echo "ref           run the tests but saves their output as a reference"
80     echo "cleanup       removes the tmp directories that may have been created"    
81     echo ""
82     echo "run command options:"
83     echo "--valgrind runs the test using valgrind"
84     echo "--testprog <test program>"
85 }
86
87 parse_command_line ()
88 {
89     if test "empty$1" = "empty" ; then
90         display_usage ;
91         exit -1
92     fi
93
94     while true ; do
95         arg=$1
96
97         if test "empty$arg" = "empty" ; then
98             break ;
99         fi
100
101         case "$arg" in
102             -h|--help)
103                 display_usage $@
104                 exit 0
105                 ;;
106
107             -*)
108                 echo "$0: unknown option: $arg"
109                 display_usage $@
110                 exit 0
111                 ;;
112
113             run|ref|cleanup)            
114                 COMMAND_LIST=$arg
115                 REMAINING_ARGS=$@
116                 echo "REMAINING_ARGS=$REMAINING_ARGS"
117                 break ;
118                 ;;
119
120             *)
121                 display_usage $@
122                 exit 0
123                 ;;
124         esac
125     done
126 }
127
128
129 #builds the list of available test functions.
130 build_tests_list ()
131 {
132     for TEST_PROG in "$TEST_SOURCE_DIR"/test*.sh "$TEST_OUT_DIR"/test?; do
133         TEST_PROG=`basename $TEST_PROG` 
134         echo "run test: $TEST_PROG"
135         TEST_PROG_LIST="$TEST_PROG_LIST $TEST_PROG"
136     done
137 }
138
139 #runs a test programs.
140 #usage run_test_prog <test-name> <reference> <display-on-stdout>
141 #where "test-name" is the name of the test program to run
142 #"reference" is a boolean value: yes/no. (the string "yes" or the string no)
143 #if yes, means that the output of the test is to be saved as a reference.
144 #if no, means that the output of the test is to be saved as a result of a test.
145 run_test_prog ()
146 {
147     TEST_PROG="$1"
148     REFERENCE="$2"
149     DISPLAY_ON_STDOUT="$3"
150     OUTPUT_DIR=
151     OUTPUT_SUFFIX=
152     TEST_INPUT_LIST=
153     VALGRIND_OPTIONS="--error-limit=no --num-callers=100 --logfile=$TEST_OUT_DIR/$VALGRIND_LOGS_DIR/$TEST_PROG-valgrind.log  --leak-check=yes --show-reachable=yes --quiet --suppressions=$TEST_SOURCE_DIR/vg.supp"
154     if test x$RUN_VALGRIND = xno ; then
155         VALGRIND=
156     else
157         if ! test -x "$TEST_SOURCE_DIR"/valgrind-version.sh ; then
158             echo "Argh! Could not find file $TEST_SOURCE_DIR/valgrind-version.sh"
159             exit -1 ;
160         fi
161         version=`"$TEST_SOURCE_DIR"/valgrind-version.sh`
162         if ! test "x$version" = "xokay" ; then
163             echo "You must install a valgrind version greater than 2.1.1"
164             echo "version=$version"
165             exit -1
166         fi
167         if test "x$CHECKER" = "x" ; then
168             VALGRIND=`which valgrind`
169             if test "x$VALGRIND" = x ; then
170                 echo "Could not find valgrind in your path"
171             else
172                 VALGRIND="$VALGRIND $VALGRIND_OPTIONS"
173                 echo "Gonna run the tests with valgrind, using the following options: $VALGRIND_OPTIONS"
174             fi
175         else
176             VALGRIND="$CHECKER $VALGRIND_OPTIONS"
177             echo "Gonna run the tests with valgrind, using the cmd line: $VALGRIND"
178         fi
179     fi
180     export VALGRIND
181     case "$TEST_PROG" in
182       *.sh) is_shell_script=yes ;;
183       *)    is_shell_script=no ;;
184     esac
185
186     if ! test -d "$TEST_OUT_DIR/$VALGRIND_LOGS_DIR" ; then
187         mkdir "$TEST_OUT_DIR/$VALGRIND_LOGS_DIR"
188     fi
189
190     for TEST_INPUT in `ls -1 "$TEST_SOURCE_DIR/$TEST_INPUT_DIR" | egrep "^${TEST_PROG}"'[.0-9]+css$'` ; do
191         TEST_INPUT_LIST="$TEST_INPUT_LIST $TEST_INPUT"
192     done
193
194     if test "$REFERENCE" = "yes" ; then
195         OUTPUT_DIR="$TEST_SOURCE_DIR/$TEST_OUT_REF_DIR"
196         OUTPUT_SUFFIX=.out
197     else
198         OUTPUT_DIR="$TEST_OUT_DIR/$TEST_OUTPUT_DIR"
199         OUTPUT_SUFFIX=.out
200         if test ! -d "$OUTPUT_DIR" ; then
201             echo "creating tmp directory $OUTPUT_DIR ..."
202             mkdir "$OUTPUT_DIR"
203             echo "done"
204         fi
205     fi
206
207     if test "empty$TEST_INPUT_LIST" != "empty" ; then
208         for TEST_INPUT in $TEST_INPUT_LIST ; do
209             TEST_INPUT_NAME=`basename $TEST_INPUT .sh`
210             if test "$DISPLAY_ON_STDOUT" = "yes" ; then
211                 echo "###############################################"
212                 echo "launching $VALGRIND $TEST_PROG $TEST_SOURCE_DIR/$TEST_INPUT_DIR/$TEST_INPUT"....
213                 echo "###############################################"          
214                 if test x$is_shell_script = xyes ; then
215                     "$TEST_SOURCE_DIR/$TEST_PROG" "$TEST_SOURCE_DIR/$TEST_INPUT_DIR/$TEST_INPUT"
216                 else
217                     $VALGRIND "$TEST_OUT_DIR/.libs/$TEST_PROG" "$TEST_SOURCE_DIR/$TEST_INPUT_DIR/$TEST_INPUT"
218                 fi              
219                 echo "###############################################"
220                 echo  "done"
221                 echo "###############################################"
222                 echo ""
223             else
224                 echo "executing $VALGRIND $TEST_PROG $TEST_SOURCE_DIR/$TEST_INPUT_DIR/$TEST_INPUT > $OUTPUT_DIR/${TEST_INPUT_NAME}${OUTPUT_SUFFIX} ..."
225                 $VALGRIND "$TEST_OUT_DIR/.libs/$TEST_PROG" "$TEST_SOURCE_DIR/$TEST_INPUT_DIR/$TEST_INPUT" > "$OUTPUT_DIR/${TEST_INPUT_NAME}${OUTPUT_SUFFIX}"
226                 echo "done"
227             fi
228         done
229     else
230         if test "$DISPLAY_ON_STDOUT" = "yes" ; then
231             echo "####################################################"
232             echo "launching $VALGRIND $TEST_PROG ..."
233             echo "####################################################"
234             if test x$is_shell_script = xyes ; then
235                 "$TEST_SOURCE_DIR/$TEST_PROG"
236             else
237                 $VALGRIND "$TEST_OUT_DIR/.libs/$TEST_PROG"
238             fi
239             echo "####################################################"
240             echo "done"
241             echo "####################################################"
242             echo ""
243         else
244             TEST_INPUT_NAME=`basename "$TEST_PROG" .sh`
245             echo "executing $VALGRIND $TEST_PROG  > $OUTPUT_DIR/${TEST_PROG}${OUTPUT_SUFFIX} ..."
246             if test x$is_shell_script = xyes ; then
247                 "$TEST_SOURCE_DIR/$TEST_PROG" > "$OUTPUT_DIR/${TEST_INPUT_NAME}${OUTPUT_SUFFIX}"
248             else
249                 $VALGRIND "$TEST_OUT_DIR/.libs/$TEST_PROG" > "$OUTPUT_DIR/${TEST_INPUT_NAME}${OUTPUT_SUFFIX}"
250             fi
251             echo "done"
252         fi
253     fi
254     unset VALGRIND
255 }
256
257 cleanup_tests ()
258 {
259     if test -d "$TEST_OUT_DIR/$TEST_OUTPUT_DIR" ; then
260         echo "removing $TEST_OUT_DIR/$TEST_OUTPUT_DIR/*"
261         rm -rf "$TEST_OUT_DIR/$TEST_OUTPUT_DIR"
262         rm -rf "$TEST_OUT_DIR/$VALGRIND_LOGS_DIR"
263     fi
264     if test -f "$TEST_OUT_DIR/$ERROR_REPORT_FILE" ; then
265         rm "$TEST_OUT_DIR/$ERROR_REPORT_FILE"
266     fi
267 }
268
269 run_test_report ()
270 {
271     diff -ur --exclude='*CVS*' --exclude='*cvs*' --exclude='Makefile*' --exclude=.arch-ids "$TEST_SOURCE_DIR/$TEST_OUT_REF_DIR" "$TEST_OUT_DIR/$TEST_OUTPUT_DIR" > "$TEST_OUT_DIR/tmpdiff.$$"
272     NB_DIFF=`wc -l < "$TEST_OUT_DIR/tmpdiff.$$"`
273
274     if test "$NB_DIFF" -eq 0 ; then
275         echo "/////////////ALL THE TESTS ARE OK :) //////////////////"
276         rm "$TEST_OUT_DIR/tmpdiff.$$"
277     else
278         echo "SOME TESTS ARE KO :("
279         mv "$TEST_OUT_DIR/tmpdiff.$$" "$TEST_OUT_DIR/$ERROR_REPORT_FILE"
280         echo "See $TEST_OUT_DIR/$ERROR_REPORT_FILE to see what's going on"
281     fi
282
283     ###################
284     #Valgrind errors  #
285     ###################
286     memleaks=no
287     for vg_log in `find "$TEST_OUT_DIR/$VALGRIND_LOGS_DIR" -name '*-valgrind.log*' -print` ; do
288         if test -s "$vg_log" ; then
289             leaks=`cat "$vg_log" | grep -i leak | grep -v no`
290             errors=`cat "$vg_log" | grep -w Invalid`
291             if test "x$leaks" = "x" -a "x$errors" = "x" ; then
292                 rm -f "$vg_log" ;
293             else
294                 echo "valgrind reported some memory leaks/corruptions in $vg_log"
295                 memleaks=yes
296             fi
297         else
298             rm "$vg_log"
299         fi
300     done
301     if test "x$RUN_VALGRIND" = "xyes" ; then
302         if test "x$memleaks" = "xno" ; then
303             echo "Oh, YESSSSSS!, VALGRIND DID NOT DETECT ANY MEMLEAK !! You can go have a beer."
304         else
305             echo "Please report these leaks by sending the valgrind logs to the authors of libcroco."
306         fi
307     fi
308 }
309
310 ############################
311 #Executes the "run" command along with
312 #its command options.
313 #For the sake of safety checking
314 ############################
315 execute_run_cmd ()
316 {
317     args=$@
318
319     if test "$1" != "run" ; then
320         echo "internal error: first argument should be \'run\'"
321         return
322     fi
323     shift
324
325     while true ; do
326         cur_arg=$1
327         echo "cur_arg=$cur_arg"
328
329         case $cur_arg in
330             --valgrind)
331                 RUN_VALGRIND=yes
332                 shift
333                 ;;
334
335             "--testprog")
336                 shift
337                 if test "empty$1" = "empty" ; then
338                     echo "--testprog should be followed by a prog name"
339                     display_usage
340                     exit
341                 fi
342                 TEST_PROG=$1
343                 echo "TEST_PROG=$TEST_PROG"
344                 shift
345                 ;;
346
347             *)
348                 break 
349                 ;;
350         esac
351     done
352
353     if test "empty$TEST_PROG" = "empty"; then
354         build_tests_list ;
355         if test "empty$TEST_PROG_LIST" = "empty" ; then
356             echo "could not find any test to run"
357             exit
358         fi
359
360         for TEST in $TEST_PROG_LIST ; do
361             run_test_prog "$TEST" no no;
362         done
363         run_test_report ;
364     else
365         #run the test and display result on stdout
366         run_test_prog "$TEST_PROG" no yes ;
367     fi
368 }
369
370 ##############################
371 #Analyzes a command string "<command> [command option]"
372 #and runs the necessary commands.
373 #
374 #Must be called with the command line
375 #starting with a command name.
376 #all the previous general argument must
377 #have been stripped away.
378 #############################
379 execute_command ()
380 {
381     arg="$1" ;
382
383     case "$arg" in
384
385         run)
386             execute_run_cmd "$@"
387             ;;
388
389         ref)
390             build_tests_list ;
391             if test "empty$TEST_PROG_LIST" = "empty" ; then
392                 echo "could not find any test to run"
393                 exit
394             fi
395
396             for TEST in $TEST_PROG_LIST ; do
397                 run_test_prog "$TEST" yes no;
398             done
399             ;;
400
401         cleanup)
402             cleanup_tests
403             ;;
404
405         *)
406             echo "unknown command"
407             exit ;
408     esac
409     
410 }
411
412 main ()
413 {
414     parse_command_line $@
415
416     if test "empty$COMMAND_LIST" = "empty" ; then
417         echo "no test command to execute"
418         exit
419     fi
420
421     execute_command $REMAINING_ARGS
422 }
423
424 main $@