X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=tests%2Finit.sh;h=bd2048e22d66d7bf6d19e0082ec7898f519803f8;hb=fa1db0dd22768f09a507674a30beb5b8a87bb35f;hp=14f3b198d43d2b3677f17fb489f7324f9de2183b;hpb=6383a3bbe16d3615791568c030fed5bfe86a4381;p=gnulib.git diff --git a/tests/init.sh b/tests/init.sh index 14f3b198d..bd2048e22 100644 --- a/tests/init.sh +++ b/tests/init.sh @@ -1,6 +1,6 @@ # source this file; set up for tests -# Copyright (C) 2009, 2010 Free Software Foundation, Inc. +# Copyright (C) 2009-2013 Free Software Foundation, Inc. # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -61,23 +61,37 @@ ME_=`expr "./$0" : '.*/\(.*\)$'` # We use a trap below for cleanup. This requires us to go through # hoops to get the right exit status transported through the handler. -# So use `Exit STATUS' instead of `exit STATUS' inside of the tests. +# So use 'Exit STATUS' instead of 'exit STATUS' inside of the tests. # Turn off errexit here so that we don't trip the bug with OSF1/Tru64 # sh inside this function. Exit () { set +e; (exit $1); exit $1; } # Print warnings (e.g., about skipped and failed tests) to this file number. # Override by defining to say, 9, in init.cfg, and putting say, -# "export ...ENVVAR_SETTINGS...; exec 9>&2; $(SHELL)" in the definition -# of TESTS_ENVIRONMENT in your tests/Makefile.am file. +# export ...ENVVAR_SETTINGS...; $(SHELL) 9>&2 +# in the definition of TESTS_ENVIRONMENT in your tests/Makefile.am file. # This is useful when using automake's parallel tests mode, to print # the reason for skip/failure to console, rather than to the .log files. : ${stderr_fileno_=2} -warn_() { echo "$@" 1>&$stderr_fileno_; } -fail_() { warn_ "$ME_: failed test: $@"; Exit 1; } -skip_() { warn_ "$ME_: skipped test: $@"; Exit 77; } -framework_failure_() { warn_ "$ME_: set-up failure: $@"; Exit 99; } +# Note that correct expansion of "$*" depends on IFS starting with ' '. +# Always write the full diagnostic to stderr. +# When stderr_fileno_ is not 2, also emit the first line of the +# diagnostic to that file descriptor. +warn_ () +{ + # If IFS does not start with ' ', set it and emit the warning in a subshell. + case $IFS in + ' '*) printf '%s\n' "$*" >&2 + test $stderr_fileno_ = 2 \ + || { printf '%s\n' "$*" | sed 1q >&$stderr_fileno_ ; } ;; + *) (IFS=' '; warn_ "$@");; + esac +} +fail_ () { warn_ "$ME_: failed test: $@"; Exit 1; } +skip_ () { warn_ "$ME_: skipped test: $@"; Exit 77; } +fatal_ () { warn_ "$ME_: hard error: $@"; Exit 99; } +framework_failure_ () { warn_ "$ME_: set-up failure: $@"; Exit 99; } # Sanitize this shell to POSIX mode, if possible. DUALCASE=1; export DUALCASE @@ -111,7 +125,7 @@ fi # Eval this code in a subshell to determine a shell's suitability. # 10 - passes all tests; ok to use -# 9 - ok, but enabling "set -x" corrupts application stderr; prefer higher score +# 9 - ok, but enabling "set -x" corrupts app stderr; prefer higher score # ? - not ok gl_shell_test_script_=' test $(echo y) = y || exit 1 @@ -158,7 +172,7 @@ else if test "$re_shell_" = __current__; then # 'eval'ing this code makes Solaris 10's /bin/sh exit with # $? set to 2. It does not evaluate any of the code after the - # "unexpected" first `('. Thus, we must run it in a subshell. + # "unexpected" first '('. Thus, we must run it in a subshell. ( eval "$gl_shell_test_script_" ) > /dev/null 2>&1 else "$re_shell_" -c "$gl_shell_test_script_" 2>/dev/null @@ -167,7 +181,10 @@ else st_=$? # $re_shell_ works just fine. Use it. - test $st_ = 10 && break + if test $st_ = 10; then + gl_set_x_corrupts_stderr_=false + break + fi # If this is our first marginally acceptable shell, remember it. if test "$st_:$marginal_" = 9: ; then @@ -190,10 +207,18 @@ else fi fi +# If this is bash, turn off all aliases. +test -n "$BASH_VERSION" && unalias -a + +# Note that when supporting $EXEEXT (transparently mapping from PROG_NAME to +# PROG_NAME.exe), we want to support hyphen-containing names like test-acos. +# That is part of the shell-selection test above. Why use aliases rather +# than functions? Because support for hyphen-containing aliases is more +# widespread than that for hyphen-containing function names. test -n "$EXEEXT" && shopt -s expand_aliases # Enable glibc's malloc-perturbing option. -# This is cheap and useful for exposing code that depends on the fact that +# This is useful for exposing code that depends on the fact that # malloc-related functions often return memory that is mostly zeroed. # If you have the time and cycles, use valgrind to do an even better job. : ${MALLOC_PERTURB_=87} @@ -202,22 +227,113 @@ export MALLOC_PERTURB_ # This is a stub function that is run upon trap (upon regular exit and # interrupt). Override it with a per-test function, e.g., to unmount # a partition, or to undo any other global state changes. -cleanup_() { :; } +cleanup_ () { :; } + +# Emit a header similar to that from diff -u; Print the simulated "diff" +# command so that the order of arguments is clear. Don't bother with @@ lines. +emit_diff_u_header_ () +{ + printf '%s\n' "diff -u $*" \ + "--- $1 1970-01-01" \ + "+++ $2 1970-01-01" +} + +# Arrange not to let diff or cmp operate on /dev/null, +# since on some systems (at least OSF/1 5.1), that doesn't work. +# When there are not two arguments, or no argument is /dev/null, return 2. +# When one argument is /dev/null and the other is not empty, +# cat the nonempty file to stderr and return 1. +# Otherwise, return 0. +compare_dev_null_ () +{ + test $# = 2 || return 2 + + if test "x$1" = x/dev/null; then + test -s "$2" || return 0 + emit_diff_u_header_ "$@"; sed 's/^/+/' "$2" + return 1 + fi + + if test "x$2" = x/dev/null; then + test -s "$1" || return 0 + emit_diff_u_header_ "$@"; sed 's/^/-/' "$1" + return 1 + fi + + return 2 +} -if ( diff --version < /dev/null 2>&1 | grep GNU ) > /dev/null 2>&1; then - compare() { diff -u "$@"; } +if diff_out_=`exec 2>/dev/null; diff -u "$0" "$0" < /dev/null` \ + && diff -u Makefile "$0" 2>/dev/null | grep '^[+]#!' >/dev/null; then + # diff accepts the -u option and does not (like AIX 7 'diff') produce an + # extra space on column 1 of every content line. + if test -z "$diff_out_"; then + compare_ () { diff -u "$@"; } + else + compare_ () + { + if diff -u "$@" > diff.out; then + # No differences were found, but Solaris 'diff' produces output + # "No differences encountered". Hide this output. + rm -f diff.out + true + else + cat diff.out + rm -f diff.out + false + fi + } + fi +elif diff_out_=`exec 2>/dev/null; diff -c "$0" "$0" < /dev/null`; then + if test -z "$diff_out_"; then + compare_ () { diff -c "$@"; } + else + compare_ () + { + if diff -c "$@" > diff.out; then + # No differences were found, but AIX and HP-UX 'diff' produce output + # "No differences encountered" or "There are no differences between the + # files.". Hide this output. + rm -f diff.out + true + else + cat diff.out + rm -f diff.out + false + fi + } + fi elif ( cmp --version < /dev/null 2>&1 | grep GNU ) > /dev/null 2>&1; then - compare() { cmp -s "$@"; } + compare_ () { cmp -s "$@"; } else - compare() { cmp "$@"; } + compare_ () { cmp "$@"; } fi +# Usage: compare EXPECTED ACTUAL +# +# Given compare_dev_null_'s preprocessing, defer to compare_ if 2 or more. +# Otherwise, propagate $? to caller: any diffs have already been printed. +compare () +{ + # This looks like it can be factored to use a simple "case $?" + # after unchecked compare_dev_null_ invocation, but that would + # fail in a "set -e" environment. + if compare_dev_null_ "$@"; then + return 0 + else + case $? in + 1) return 1;; + *) compare_ "$@";; + esac + fi +} + # An arbitrary prefix to help distinguish test directories. -testdir_prefix_() { printf gt; } +testdir_prefix_ () { printf gt; } # Run the user-overridable cleanup_ function, remove the temporary # directory and exit with the incoming value of $?. -remove_tmp_() +remove_tmp_ () { __st=$? cleanup_ @@ -233,7 +349,7 @@ remove_tmp_() # contains only the specified bytes (see the case stmt below), then print # a space-separated list of those names and return 0. Otherwise, don't # print anything and return 1. Naming constraints apply also to DIR. -find_exe_basenames_() +find_exe_basenames_ () { feb_dir_=$1 feb_fail_=0 @@ -245,6 +361,9 @@ find_exe_basenames_() # below, just skip it. test "x$feb_file_" = "x$feb_dir_/*.exe" && test ! -f "$feb_file_" \ && continue + # Exempt [.exe, since we can't create a function by that name, yet + # we can't invoke [ by PATH search anyways due to shell builtins. + test "x$feb_file_" = "x$feb_dir_/[.exe" && continue case $feb_file_ in *[!-a-zA-Z/0-9_.+]*) feb_fail_=1; break;; *) # Remove leading file name components as well as the .exe suffix. @@ -263,7 +382,7 @@ find_exe_basenames_() # PROG that simply invokes PROG.exe, then return 0. If any selected # file name or the directory name, $1, contains an unexpected character, # define no alias and return 1. -create_exe_shims_() +create_exe_shims_ () { case $EXEEXT in '') return 0 ;; @@ -272,7 +391,7 @@ create_exe_shims_() esac base_names_=`find_exe_basenames_ $1` \ - || { echo "$0 (exe_shim): skipping directory: $1" 1>&2; return 1; } + || { echo "$0 (exe_shim): skipping directory: $1" 1>&2; return 0; } if test -n "$base_names_"; then for base_ in $base_names_; do @@ -285,15 +404,14 @@ create_exe_shims_() # Use this function to prepend to PATH an absolute name for each # specified, possibly-$initial_cwd_-relative, directory. -path_prepend_() +path_prepend_ () { while test $# != 0; do path_dir_=$1 case $path_dir_ in '') fail_ "invalid path dir: '$1'";; /*) abs_path_dir_=$path_dir_;; - *) abs_path_dir_=`cd "$initial_cwd_/$path_dir_" && echo "$PWD"` \ - || fail_ "invalid path dir: $path_dir_";; + *) abs_path_dir_=$initial_cwd_/$path_dir_;; esac case $abs_path_dir_ in *:*) fail_ "invalid path dir: '$abs_path_dir_'";; @@ -308,7 +426,7 @@ path_prepend_() export PATH } -setup_() +setup_ () { if test "$VERBOSE" = yes; then # Test whether set -x may cause the selected shell to corrupt an @@ -324,11 +442,12 @@ setup_() fi initial_cwd_=$PWD + fail=0 pfx_=`testdir_prefix_` test_dir_=`mktempd_ "$initial_cwd_" "$pfx_-$ME_.XXXX"` \ || fail_ "failed to create temporary directory in $initial_cwd_" - cd "$test_dir_" + cd "$test_dir_" || fail_ "failed to cd to temporary directory" # As autoconf-generated configure scripts do, ensure that IFS # is defined initially, so that saving and restoring $IFS works. @@ -360,7 +479,7 @@ setup_() # - make only $MAX_TRIES_ attempts # Helper function. Print $N pseudo-random bytes from a-zA-Z0-9. -rand_bytes_() +rand_bytes_ () { n_=$1 @@ -392,11 +511,11 @@ rand_bytes_() | LC_ALL=C tr -c $chars_ 01234567$chars_$chars_$chars_ } -mktempd_() +mktempd_ () { case $# in 2);; - *) fail_ "Usage: $ME DIR TEMPLATE";; + *) fail_ "Usage: mktempd_ DIR TEMPLATE";; esac destdir_=$1 @@ -413,13 +532,12 @@ mktempd_() case $template_ in *XXXX) ;; - *) fail_ "invalid template: $template_ (must have a suffix of at least 4 X's)";; + *) fail_ \ + "invalid template: $template_ (must have a suffix of at least 4 X's)";; esac - fail=0 - # First, try to use mktemp. - d=`unset TMPDIR; mktemp -d -t -p "$destdir_" "$template_" 2>/dev/null` \ + d=`unset TMPDIR; { mktemp -d -t -p "$destdir_" "$template_"; } 2>/dev/null` \ || fail=1 # The resulting name must be in the specified directory.