uniq: don't continue field processing after end of line
[coreutils.git] / tests / init.cfg
bloba7860e7407fb04ae0c9a8bb389645a3dc3c9292c
1 # This file is sourced by init.sh, *before* its initialization.
3 # This goes hand in hand with the "exec 9>&2;" in tests/Makefile.am's
4 # TESTS_ENVIRONMENT definition.
5 stderr_fileno_=9
7 # FIXME: eventually s/error_/fail_/ and remove the definition of error_ below.
8 # FIXME: s/(framework_failure)\>/${1}_/ and remove def. of framework_failure
10 # Having an unsearchable directory in PATH causes execve to fail with EACCES
11 # when applied to an unresolvable program name, contrary to the desired ENOENT.
12 # Avoid the problem by rewriting PATH to exclude unsearchable directories.
13 sanitize_path_()
15   # FIXME: remove double quotes around $IFS when all tests use init.sh.
16   # They constitute a work-around for a bug in FreeBSD 8.1's /bin/sh.
17   local saved_IFS="$IFS"
18     IFS=:
19     set -- $PATH
20   IFS=$saved_IFS
22   local d d1
23   local colon=
24   local new_path=
25   for d in "$@"; do
26     test -z "$d" && d1=. || d1=$d
27     if ls -d "$d1/." > /dev/null 2>&1; then
28       new_path="$new_path$colon$d"
29       colon=':'
30     fi
31   done
33   PATH=$new_path
34   export PATH
37 skip_test_()
39   echo "$0: skipping test: $@" | head -1 1>&9
40   echo "$0: skipping test: $@" 1>&2
41   Exit 77
44 getlimits_()
46   eval $(getlimits)
47   test "$INT_MAX" ||
48     error_ "Error running getlimits"
51 require_acl_()
53   getfacl --version < /dev/null > /dev/null 2>&1 \
54     && setfacl --version < /dev/null > /dev/null 2>&1 \
55       || skip_test_ "This test requires getfacl and setfacl."
57   id -u bin > /dev/null 2>&1 \
58     || skip_test_ "This test requires a local user named bin."
61 is_local_dir_()
63   test $# = 1 || framework_failure
64   df --local "$1" >/dev/null 2>&1
67 require_local_dir_()
69   is_local_dir_ . ||
70     skip_test_ "This test must be run on a local file system."
73 # Skip this test if we're not in SELinux "enforcing" mode.
74 require_selinux_enforcing_()
76   test "$(getenforce)" = Enforcing \
77     || skip_test_ "This test is useful only with SELinux in Enforcing mode."
80 require_openat_support_()
82   # Skip this test if your system has neither the openat-style functions
83   # nor /proc/self/fd support with which to emulate them.
84   test -z "$CONFIG_HEADER" \
85     && skip_test_ 'internal error: CONFIG_HEADER not defined'
87   _skip=yes
88   grep '^#define HAVE_OPENAT' "$CONFIG_HEADER" > /dev/null && _skip=no
89   test -d /proc/self/fd && _skip=no
90   if test $_skip = yes; then
91     skip_test_ 'this system lacks openat support'
92   fi
95 require_ulimit_()
97   ulimit_works=yes
98   # Expect to be able to exec a program in 10MB of virtual memory,
99   # but not in 20KB.  I chose "date".  It must not be a shell built-in
100   # function, so you can't use echo, printf, true, etc.
101   # Of course, in coreutils, I could use $top_builddir/src/true,
102   # but this should be able to work for other projects, too.
103   ( ulimit -v 10000; date ) > /dev/null 2>&1 || ulimit_works=no
104   ( ulimit -v 20;    date ) > /dev/null 2>&1 && ulimit_works=no
106   test $ulimit_works = no \
107     && skip_test_ "this shell lacks ulimit support"
110 require_readable_root_()
112   test -r / || skip_test_ "/ is not readable"
115 # Skip the current test if strace is not available or doesn't work
116 # with the named syscall.  Usage: require_strace_ unlink
117 require_strace_()
119   test $# = 1 || framework_failure
121   strace -V < /dev/null > /dev/null 2>&1 ||
122     skip_test_ 'no strace program'
124   strace -qe "$1" echo > /dev/null 2>&1 ||
125     skip_test_ 'strace -qe "'"$1"'" does not work'
128 # Require a controlling input `terminal'.
129 require_controlling_input_terminal_()
131   tty -s || have_input_tty=no
132   test -t 0 || have_input_tty=no
133   if test "$have_input_tty" = no; then
134     skip_test_ 'requires controlling input terminal
135 This test must have a controlling input "terminal", so it may not be
136 run via "batch", "at", or "ssh".  On some systems, it may not even be
137 run in the background.'
138   fi
141 require_built_()
143   skip_=no
144   for i in "$@"; do
145     case " $built_programs " in
146       *" $i "*) ;;
147       *) echo "$i: not built" 1>&2; skip_=yes ;;
148     esac
149   done
151   test $skip_ = yes && skip_test_ "required program(s) not built"
154 uid_is_privileged_()
156   # Make sure id -u succeeds.
157   my_uid=$(id -u) \
158     || { echo "$0: cannot run \`id -u'" 1>&2; return 1; }
160   # Make sure it gives valid output.
161   case $my_uid in
162     0) ;;
163     *[!0-9]*)
164       echo "$0: invalid output (\`$my_uid') from \`id -u'" 1>&2
165       return 1 ;;
166     *) return 1 ;;
167   esac
170 get_process_status_()
172   sed -n '/^State:[      ]*\([[:alpha:]]\).*/s//\1/p' /proc/$1/status
175 # Convert an ls-style permission string, like drwxr----x and -rw-r-x-wx
176 # to the equivalent chmod --mode (-m) argument, (=,u=rwx,g=r,o=x and
177 # =,u=rw,g=rx,o=wx).  Ignore ACLs.
178 rwx_to_mode_()
180   case $# in
181     1) rwx=$1;;
182     *) echo "$0: wrong number of arguments" 1>&2
183       echo "Usage: $0 ls-style-mode-string" 1>&2
184       return;;
185   esac
187   case $rwx in
188     [ld-][rwx-][rwx-][rwxsS-][rwx-][rwx-][rwxsS-][rwx-][rwx-][rwxtT-]) ;;
189     [ld-][rwx-][rwx-][rwxsS-][rwx-][rwx-][rwxsS-][rwx-][rwx-][rwxtT-][+.]) ;;
190     *) echo "$0: invalid mode string: $rwx" 1>&2; return;;
191   esac
193   # Perform these conversions:
194   # S  s
195   # s  xs
196   # T  t
197   # t  xt
198   # The `T' and `t' ones are only valid for `other'.
199   s='s/S/@/;s/s/x@/;s/@/s/'
200   t='s/T/@/;s/t/x@/;s/@/t/'
202   u=`echo $rwx|sed 's/^.\(...\).*/,u=\1/;s/-//g;s/^,u=$//;'$s`
203   g=`echo $rwx|sed 's/^....\(...\).*/,g=\1/;s/-//g;s/^,g=$//;'$s`
204   o=`echo $rwx|sed 's/^.......\(...\).*/,o=\1/;s/-//g;s/^,o=$//;'$s';'$t`
205   echo "=$u$g$o"
208 skip_if_()
210   case $1 in
211     root) skip_test_ must be run as root ;;
212     non-root) skip_test_ must be run as non-root ;;
213     *) ;;  # FIXME?
214   esac
217 require_selinux_()
219   case `ls -Zd .` in
220     '? .'|'unlabeled .')
221       skip_test_ "this system (or maybe just" \
222         "the current file system) lacks SELinux support"
223     ;;
224   esac
227 very_expensive_()
229   if test "$RUN_VERY_EXPENSIVE_TESTS" != yes; then
230     skip_test_ 'very expensive: disabled by default
231 This test is very expensive, so it is disabled by default.
232 To run it anyway, rerun make check with the RUN_VERY_EXPENSIVE_TESTS
233 environment variable set to yes.  E.g.,
235   env RUN_VERY_EXPENSIVE_TESTS=yes make check
237   fi
240 expensive_()
242   if test "$RUN_EXPENSIVE_TESTS" != yes; then
243     skip_test_ 'expensive: disabled by default
244 This test is relatively expensive, so it is disabled by default.
245 To run it anyway, rerun make check with the RUN_EXPENSIVE_TESTS
246 environment variable set to yes.  E.g.,
248   env RUN_EXPENSIVE_TESTS=yes make check
250   fi
253 require_root_()
255   uid_is_privileged_ || skip_test_ "must be run as root"
256   NON_ROOT_USERNAME=${NON_ROOT_USERNAME=nobody}
257   NON_ROOT_GROUP=${NON_ROOT_GROUP=$(id -g $NON_ROOT_USERNAME)}
260 skip_if_root_() { uid_is_privileged_ && skip_test_ "must be run as non-root"; }
261 error_() { echo "$0: $@" 1>&2; Exit 1; }
262 framework_failure() { error_ 'failure in testing framework'; }
264 # Set `groups' to a space-separated list of at least two groups
265 # of which the user is a member.
266 require_membership_in_two_groups_()
268   test $# = 0 || framework_failure
270   groups=${COREUTILS_GROUPS-`(id -G || /usr/xpg4/bin/id -G) 2>/dev/null`}
271   case "$groups" in
272     *' '*) ;;
273     *) skip_test_ 'requires membership in two groups
274 this test requires that you be a member of more than one group,
275 but running `id -G'\'' either failed or found just one.  If you really
276 are a member of at least two groups, then rerun this test with
277 COREUTILS_GROUPS set in your environment to the space-separated list
278 of group names or numbers.  E.g.,
280   env COREUTILS_GROUPS='users cdrom' make check
283      ;;
284   esac
287 # Is /proc/$PID/status supported?
288 require_proc_pid_status_()
290     sleep 2 &
291     local pid=$!
292     sleep .5
293     grep '^State:[       ]*[S]' /proc/$pid/status > /dev/null 2>&1 ||
294     skip_test_ "/proc/$pid/status: missing or 'different'"
295     kill $pid
298 # Does the current (working-dir) file system support sparse files?
299 require_sparse_support_()
301   test $# = 0 || framework_failure
302   # Test whether we can create a sparse file.
303   # For example, on Darwin6.5 with a file system of type hfs, it's not possible.
304   # NTFS requires 128K before a hole appears in a sparse file.
305   t=sparse.$$
306   dd bs=1 seek=128K of=$t < /dev/null 2> /dev/null
307   set x `du -sk $t`
308   kb_size=$2
309   rm -f $t
310   if test $kb_size -ge 128; then
311     skip_test_ 'this file system does not support sparse files'
312   fi
315 mkfifo_or_skip_()
317   test $# = 1 || framework_failure
318   if ! mkfifo "$1"; then
319     # Make an exception of this case -- usually we interpret framework-creation
320     # failure as a test failure.  However, in this case, when running on a SunOS
321     # system using a disk NFS mounted from OpenBSD, the above fails like this:
322     # mkfifo: cannot make fifo `fifo-10558': Not owner
323     skip_test_ 'NOTICE: unable to create test prerequisites'
324   fi
327 # Disable the current test if the working directory seems to have
328 # the setgid bit set.
329 skip_if_setgid_()
331   setgid_tmpdir=setgid-$$
332   (umask 77; mkdir $setgid_tmpdir)
333   perms=$(stat --printf %A $setgid_tmpdir)
334   rmdir $setgid_tmpdir
335   case $perms in
336     drwx------);;
337     drwxr-xr-x);;  # Windows98 + DJGPP 2.03
338     *) skip_test_ 'this directory has the setgid bit set';;
339   esac
342 skip_if_mcstransd_is_running_()
344   test $# = 0 || framework_failure
346   # When mcstransd is running, you'll see only the 3-component
347   # version of file-system context strings.  Detect that,
348   # and if it's running, skip this test.
349   __ctx=$(stat --printf='%C\n' .) || framework_failure
350   case $__ctx in
351     *:*:*:*) ;; # four components is ok
352     *) # anything else probably means mcstransd is running
353         skip_test_ "unexpected context '$__ctx'; turn off mcstransd" ;;
354   esac
357 # Skip the current test if umask doesn't work as usual.
358 # This test should be run in the temporary directory that ends
359 # up being removed via the trap commands.
360 working_umask_or_skip_()
362   umask 022
363   touch file1 file2
364   chmod 644 file2
365   perms=`ls -l file1 file2 | sed 's/ .*//' | uniq`
366   rm -f file1 file2
368   case $perms in
369   *'
370   '*) skip_test_ 'your build directory has unusual umask semantics'
371   esac
374 # Retry a function requiring a sufficient delay to _pass_
375 # using a truncated exponential backoff method.
376 #     Example: retry_delay_ dd_reblock_1 .1 6
377 # This example will call the dd_reblock_1 function with
378 # an initial delay of .1 second and call it at most 6 times
379 # with a max delay of 3.2s (doubled each time), or a total of 6.3s
380 # Note ensure you do _not_ quote the parameter to GNU sleep in
381 # your function, as it may contain separate values that `sleep`
382 # needs to accumulate.
383 retry_delay_()
385   local test_func=$1
386   local init_delay=$2
387   local max_n_tries=$3
389   local attempt=1
390   local num_sleeps=$attempt
391   local time_fail
392   while test $attempt -le $max_n_tries; do
393     local delay=$($AWK -v n=$num_sleeps -v s="$init_delay" \
394                   'BEGIN { print s * n }')
395     "$test_func" "$delay" && { time_fail=0; break; } || time_fail=1
396     attempt=$(expr $attempt + 1)
397     num_sleeps=$(expr $num_sleeps '*' 2)
398   done
399   test "$time_fail" = 0
402 # Call this with a list of programs under test immediately after
403 # sourcing init.sh.
404 print_ver_()
406   if test "$VERBOSE" = yes; then
407     local i
408     for i in $*; do
409       env $i --version
410     done
411   fi
414 sanitize_path_