7751c7ee28d3475e80ec858ac807943ca63bdfdf
[platform/upstream/coreutils.git] / tests / general / atgeneral.m4
1 include(m4sh.m4)                                            -*- Autoconf -*-
2 # M4 macros used in building test suites.
3 # Copyright 2000 Free Software Foundation, Inc.
4
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 2, or (at your option)
8 # any later version.
9 #
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 # 02110-1301, USA.
19
20 # This script is part of Autotest.  Unlimited permission to copy,
21 # distribute and modify the testing scripts that are the output of
22 # that Autotest script is given.  You need not follow the terms of the
23 # GNU General Public License when using or distributing such scripts,
24 # even though portions of the text of Autotest appear in them.  The
25 # GNU General Public License (GPL) does govern all other use of the
26 # material that constitutes the Autotest.
27 #
28 # Certain portions of the Autotest source text are designed to be
29 # copied (in certain cases, depending on the input) into the output of
30 # Autotest.  We call these the "data" portions.  The rest of the
31 # Autotest source text consists of comments plus executable code that
32 # decides which of the data portions to output in any given case.  We
33 # call these comments and executable code the "non-data" portions.
34 # Autotest never copies any of the non-data portions into its output.
35 #
36 # This special exception to the GPL applies to versions of Autotest
37 # released by the Free Software Foundation.  When you make and
38 # distribute a modified version of Autotest, you may extend this
39 # special exception to the GPL to apply to your modified version as
40 # well, *unless* your modified version has the potential to copy into
41 # its output some of the text that was the non-data portion of the
42 # version that you started with.  (In other words, unless your change
43 # moves or copies text from the non-data portions to the data
44 # portions.)  If your modification has such potential, you must delete
45 # any notice of this special exception to the GPL from your modified
46 # version.
47
48
49 m4_define([AT_DEFINE], m4_defn([m4_define]))
50 m4_define([AT_INCLUDE], m4_defn([m4_include]))
51 m4_define([AT_SHIFT], m4_defn([m4_shift]))
52 m4_define([AT_UNDEFINE], m4_defn([m4_undefine]))
53
54
55
56 # Use of diversions:
57 #
58 #  - DEFAULT
59 #    Overall initialization, value of $at_tests_all.
60 #  - OPTIONS
61 #    Option processing
62 #  - HELP
63 #    Help message.  Of course it is useless, you could just push into
64 #    OPTIONS, but that's much clearer this way.
65 #  - SETUP
66 #    Be ready to run the tests.
67 #  - TESTS
68 #    The core of the test suite, the ``normal'' diversion.
69 #  - TAIL
70 #    tail of the core for;case, overall wrap up, generation of debugging
71 #    scripts and statistics.
72 #
73 #  - TEST
74 #    for each test group: proper code, to reinsert between cleanups;
75 #    undiverted into TESTS once at_data_files diverted.
76
77 m4_define([_m4_divert(DEFAULT)],       0)
78 m4_define([_m4_divert(OPTIONS)],      10)
79 m4_define([_m4_divert(HELP)],         20)
80 m4_define([_m4_divert(SETUP)],        30)
81 m4_define([_m4_divert(TESTS)],        50)
82 m4_define([_m4_divert(TAIL)],         60)
83
84 m4_define([_m4_divert(TEST)],        100)
85
86 m4_divert_push([TESTS])
87 m4_divert_push([KILL])
88
89
90 # AT_LINE
91 # -------
92 # Return the current file sans directory, a colon, and the current line.
93 AT_DEFINE([AT_LINE],
94 [m4_patsubst(__file__, ^.*/\(.*\), \1):__line__])
95
96
97 # AT_INIT(PROGRAM)
98 # ----------------
99 # Begin testing suite, using PROGRAM to check version.  The search path
100 # should be already preset so the proper executable will be selected.
101 AT_DEFINE([AT_INIT],
102 [AT_DEFINE([AT_ordinal], 0)
103 m4_divert_push([DEFAULT])dnl
104 #! /bin/sh
105
106 AS_SHELL_SANITIZE
107
108 . ./atconfig
109 # Use absolute file notations, as the test might change directories.
110 at_srcdir=`cd "$srcdir" && pwd`
111 at_top_srcdir=`cd "$top_srcdir" && pwd`
112
113 if test -n "$AUTOTEST_PATH"; then
114   export PATH; PATH=`pwd`:`cd "$AUTOTEST_PATH" && pwd`:$PATH
115 else
116   export PATH; PATH=`pwd`:$PATH
117 fi
118
119 test -f atlocal && . ./atlocal
120
121 # -e sets to true
122 at_stop_on_error=false;
123 # Shall we save and check stdout and stderr?
124 # -n sets to false
125 at_check_stds=:;
126 # Shall we be verbose?
127 at_verbose=:
128 # Shall we keep the debug scripts?  Must be `:' when testsuite is
129 # run by a debug script, so that the script doesn't remove itself.
130 at_debug=false
131 # Display help message?
132 at_help=false
133 # Tests to run
134 at_tests=
135 m4_divert([OPTIONS])dnl Other vars inserted here.
136
137 while test $[#] -gt 0; do
138   case $[1] in
139     --help | -h) at_help=:; break ;;
140     --version) echo "$[0] ($at_package) $at_version"; exit 0 ;;
141
142     -d) at_debug=:;;
143     -e) at_stop_on_error=:;;
144     -n) at_check_stds=false;;
145     -v) at_verbose=echo;;
146     -x) at_traceon='set -vx'; at_traceoff='set +vx'; at_check_stds=false;;
147
148     [[0-9] | [0-9][0-9] | [0-9][0-9][0-9] | [0-9][0-9][0-9][0-9]])
149         at_tests="$at_tests$[1] ";;
150
151      *) echo 1>&2 "Try \`$[0] --help' for more information."; exit 1 ;;
152   esac
153   shift
154 done
155
156 test -z "$at_tests" && at_tests=$at_tests_all
157
158 # Help message.
159 # Display only the title of selected tests.
160 if $at_help; then
161   cat <<EOF
162 Usage: $[0] [[OPTION]]... [[TESTS]]
163
164 Run all the tests, or the selected TESTS.
165
166 Options:
167   -h  Display this help message and the list of tests
168   -e  Abort the full suite and inhibit normal clean up if a test fails
169   -n  Do not redirect stdout and stderr and do not test their contents
170   -v  Force more detailed output, default for debugging scripts
171   -x  Have the shell to trace command execution; also implies option -n
172
173 Tests:
174 EOF
175   # "1 42 45 " => " (1|42|45|dummy): "
176   at_tests_pattern=`echo "$at_tests" | tr ' ' '|'`
177   egrep -e " (${at_tests_pattern}dummy): " <<EOF
178 m4_divert([HELP])dnl Help message inserted here.
179 m4_divert([SETUP])dnl
180 EOF
181   exit 0
182 fi
183
184 # To check whether a test succeeded or not, we compare an expected
185 # output with a reference.  In the testing suite, we just need `cmp'
186 # but in debugging scripts, we want more information, so we prefer
187 # `diff -u'.  Nonetheless we will use `diff' only, because in DOS
188 # environments, `diff' considers that two files are equal included
189 # when there are only differences on the coding of new lines. `cmp'
190 # does not.
191 #
192 # Finally, not all the `diff' support `-u', and some, like Tru64, even
193 # refuse to `diff' /dev/null.
194 : >empty
195
196 if diff -u empty empty >/dev/null 2>&1; then
197   at_diff='diff -u'
198 else
199   at_diff='diff'
200 fi
201
202
203
204 # Each generated debugging script, containing a single test group, cleans
205 # up files at the beginning only, not at the end.  This is so we can repeat
206 # the script many times and browse left over files.  To cope with such left
207 # over files, the full test suite cleans up both before and after test groups.
208
209 if $1 --version | grep "$at_package.*$at_version" >/dev/null; then
210   at_banner="Test suite for $at_package, version $at_version"
211   at_dashes=`echo $at_banner | sed s/./=/g`
212   echo "$at_dashes"
213   echo "$at_banner"
214   echo "$at_dashes"
215 else
216   echo '======================================================='
217   echo 'ERROR: Not using the proper version, no tests performed'
218   echo '======================================================='
219   exit 1
220 fi
221
222 at_failed_list=
223 at_ignore_count=0
224 at_test_count=0
225 m4_divert([TESTS])dnl
226
227 for at_test in $at_tests
228 do
229   at_status=0;
230   case $at_test in
231 m4_divert([TAIL])[]dnl
232   esac
233   at_test_count=`expr 1 + $at_test_count`
234   $at_verbose $at_n "     $at_test. $srcdir/`cat at-setup-line`: $at_c"
235   case $at_status in
236     0) echo ok
237        ;;
238     77) echo "ignored near \``cat at-check-line`'"
239         at_ignore_count=`expr $at_ignore_count + 1`
240         ;;
241     *) echo "FAILED near \``cat at-check-line`'"
242        at_failed_list="$at_failed_list $at_test"
243        $at_stop_on_error && break
244        ;;
245   esac
246   $at_debug || rm -rf $at_data_files
247 done
248
249 # Wrap up the testing suite with summary statistics.
250
251 rm -f at-check-line at-setup-line
252 at_fail_count=0
253 if test -z "$at_failed_list"; then
254   if test "$at_ignore_count" = 0; then
255     at_banner="All $at_test_count tests were successful"
256   else
257     at_banner="All $at_test_count tests were successful ($at_ignore_count ignored)"
258   fi
259 elif test $at_debug = false; then
260   # Remove any debugging script resulting from a previous run.
261   rm -f debug-*.sh
262   echo
263   echo $at_n "Writing \`debug-NN.sh' scripts, NN =$at_c"
264   for at_group in $at_failed_list; do
265     echo $at_n " $at_group$at_c"
266     ( echo "#! /bin/sh"
267       echo 'exec '"$[0]"' -v -d '"$at_group"' ${1+"$[@]"}'
268       echo 'exit 1'
269     ) >debug-$at_group.sh
270     chmod +x debug-$at_group.sh
271     at_fail_count=`expr $at_fail_count + 1`
272   done
273   echo ', done'
274   if $at_stop_on_error; then
275     at_banner='ERROR: One of the tests failed, inhibiting subsequent tests'
276   else
277     at_banner="ERROR: Suite unsuccessful, $at_fail_count of $at_test_count tests failed"
278   fi
279 fi
280 at_dashes=`echo $at_banner | sed s/./=/g`
281 echo
282 echo "$at_dashes"
283 echo "$at_banner"
284 echo "$at_dashes"
285
286 if test $at_debug = false && test -n "$at_failed_list"; then
287   echo
288   echo 'When reporting failed tests to maintainers, do not merely list test'
289   echo 'numbers, as the numbering changes between releases and pretests.'
290   echo 'Be careful to give at least all the information you got about them.'
291   echo 'You may investigate any problem if you feel able to do so, in which'
292   echo 'case the testsuite provide a good starting point.'
293   echo 'information.  Now, failed tests will be executed again, verbosely.'
294   for at_group in $at_failed_list; do
295     ./debug-$at_group.sh
296   done
297   exit 1
298 fi
299
300 exit 0
301 m4_divert_pop()dnl
302 m4_wrap([m4_divert_text([DEFAULT],
303                         [# List of the tests.
304 at_tests_all="m4_for([i], 1, AT_ordinal, 1, [i ])"])])dnl
305 ])# AT_INIT
306
307
308
309 # AT_SETUP(DESCRIPTION)
310 # ---------------------
311 # Start a group of related tests, all to be executed in the same subshell.
312 # The group is testing what DESCRIPTION says.
313 AT_DEFINE([AT_SETUP],
314 [m4_define([AT_ordinal], m4_eval(AT_ordinal + 1))
315 m4_divert_text([HELP],
316                [m4_format([ %3d: %-15s %s], AT_ordinal, AT_LINE, [$1])])
317 m4_pushdef([AT_data_files], [stdout stderr ])
318 m4_divert_push([TESTS])dnl
319   AT_ordinal )
320 dnl Here will be inserted the definition of at_data_files.
321 m4_divert([TEST])[]dnl
322     rm -rf $at_data_files
323     echo AT_LINE >at-setup-line
324     $at_verbose 'testing $1'
325     $at_verbose $at_n "     $at_c"
326     if test $at_verbose = echo; then
327       echo "AT_ordinal. $srcdir/AT_LINE..."
328     else
329       echo $at_n "m4_substr(AT_ordinal. $srcdir/AT_LINE                            , 0, 30)[]$at_c"
330     fi
331     (
332       $at_traceon
333 ])
334
335
336 # AT_CLEANUP_FILE_IFELSE(FILE, IF-REGISTERED, IF-NOT-REGISTERED)
337 # --------------------------------------------------------------
338 AT_DEFINE([AT_CLEANUP_FILE_IFELSE],
339 [ifelse(m4_regexp(AT_data_files, m4_patsubst([ $1 ], [\([\[\]*.]\)], [\\\1])),
340         -1,
341         [$3], [$2])])
342
343
344 # AT_CLEANUP_FILE(FILE)
345 # ---------------------
346 # Register FILE for AT_CLEANUP.
347 AT_DEFINE([AT_CLEANUP_FILE],
348 [AT_CLEANUP_FILE_IFELSE([$1], [],
349                         [m4_append([AT_data_files], [$1 ])])])
350
351
352 # AT_CLEANUP_FILES(FILES)
353 # -----------------------
354 # Declare a list of FILES to clean.
355 AT_DEFINE([AT_CLEANUP_FILES],
356 [m4_foreach([AT_File], m4_quote(m4_patsubst([$1], [  *], [,])),
357             [AT_CLEANUP_FILE(AT_File)])])
358
359
360 # AT_CLEANUP(FILES)
361 # -----------------
362 # Complete a group of related tests, recursively remove those FILES
363 # created within the test.  There is no need to list stdout, stderr,
364 # nor files created with AT_DATA.
365 AT_DEFINE([AT_CLEANUP],
366 [AT_CLEANUP_FILES([$1])dnl
367       $at_traceoff
368     )
369     at_status=$?
370     ;;
371 m4_divert([TESTS])[]dnl
372     at_data_files="AT_data_files"
373 m4_undivert([TEST])[]dnl
374 m4_popdef([AT_data_files])dnl
375 m4_divert_pop()dnl
376 ])# AT_CLEANUP
377
378
379 # AT_DATA(FILE, CONTENTS)
380 # -----------------------
381 # Initialize an input data FILE with given CONTENTS, which should end with
382 # an end of line.
383 # This macro is not robust to active symbols in CONTENTS *on purpose*.
384 # If you don't want CONTENT to be evaluated, quote it twice.
385 AT_DEFINE([AT_DATA],
386 [AT_CLEANUP_FILES([$1])dnl
387 cat >$1 <<'_ATEOF'
388 $2[]_ATEOF
389 ])
390
391
392 # AT_CHECK(COMMANDS, [STATUS], STDOUT, STDERR)
393 # --------------------------------------------
394 # Execute a test by performing given shell COMMANDS.  These commands
395 # should normally exit with STATUS, while producing expected STDOUT and
396 # STDERR contents.  The special word `expout' for STDOUT means that file
397 # `expout' contents has been set to the expected stdout.  The special word
398 # `experr' for STDERR means that file `experr' contents has been set to
399 # the expected stderr.
400 # STATUS is not checked if it is empty.
401 # STDOUT and STDERR can be the special value `ignore', in which case
402 # their content is not checked.
403 AT_DEFINE([AT_CHECK],
404 [$at_traceoff
405 $at_verbose "$srcdir/AT_LINE: m4_patsubst([$1], [\([\"`$]\)], \\\1)"
406 echo AT_LINE >at-check-line
407 $at_check_stds && exec 5>&1 6>&2 1>stdout 2>stderr
408 $at_traceon
409 $1
410 ifelse([$2], [], [],
411 [at_status=$?
412 if test $at_status != $2; then
413   $at_verbose "Exit code was $at_status, expected $2" >&6
414 dnl Maybe there was an important message to read before it died.
415   $at_verbose = echo && $at_check_stds && cat stderr >&6
416 dnl Preserve exit code 77.
417   test $at_status = 77 && exit 77
418   exit 1
419 fi
420 ])dnl
421 $at_traceoff
422 if $at_check_stds; then
423 dnl Restore stdout to fd1 and stderr to fd2.
424   exec 1>&5 2>&6
425 dnl If not verbose, neutralize the output of diff.
426   test $at_verbose = : && exec 1>/dev/null 2>/dev/null
427   at_failed=false;
428   m4_case([$4],
429           ignore, [$at_verbose = echo && cat stderr;:],
430           experr, [AT_CLEANUP_FILE([experr])dnl
431 $at_diff experr stderr || at_failed=:],
432           [], [$at_diff empty stderr || at_failed=:],
433           [echo $at_n "m4_patsubst([$4], [\([\"`$]\)], \\\1)$at_c" | $at_diff - stderr || at_failed=:])
434   m4_case([$3],
435           ignore, [test $at_verbose = echo && cat stdout;:],
436           expout, [AT_CLEANUP_FILES([expout])dnl
437 $at_diff expout stdout || at_failed=:],
438           [], [$at_diff empty stdout || at_failed=:],
439           [echo $at_n "m4_patsubst([$3], [\([\"`$]\)], \\\1)$at_c" | $at_diff - stdout || at_failed=:])
440   if $at_failed; then
441     exit 1
442   else
443     :
444   fi
445 fi
446 $at_traceon
447 ])# AT_CHECK