maint: new function: usable_st_size
[coreutils.git] / tests / init.cfg
blob2e43c162d47f5a93a71dc351dfc74a2533602a1e
1 # This file is sourced by init.sh, *before* its initialization.
3 # Copyright (C) 2010-2012 Free Software Foundation, Inc.
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 3 of the License, or
8 # (at your option) any later version.
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.
15 # You should have received a copy of the GNU General Public License
16 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 # This goes hand in hand with the "exec 9>&2;" in tests/Makefile.am's
20 # TESTS_ENVIRONMENT definition.
21 stderr_fileno_=9
23 # Having an unsearchable directory in PATH causes execve to fail with EACCES
24 # when applied to an unresolvable program name, contrary to the desired ENOENT.
25 # Avoid the problem by rewriting PATH to exclude unsearchable directories.
26 # Also, if PATH lacks /sbin and/or /usr/sbin, append it/them.
27 sanitize_path_()
29   # FIXME: remove double quotes around $IFS when all tests use init.sh.
30   # They constitute a work-around for a bug in FreeBSD 8.1's /bin/sh.
31   local saved_IFS="$IFS"
32     IFS=:
33     set -- $PATH
34   IFS=$saved_IFS
36   local d d1
37   local colon=
38   local new_path=
39   for d in "$@"; do
40     test -z "$d" && d1=. || d1=$d
41     if ls -d "$d1/." > /dev/null 2>&1; then
42       new_path="$new_path$colon$d"
43       colon=':'
44     fi
45   done
47   for d in /sbin /usr/sbin ; do
48     case ":$new_path:" in
49       *:$d:*) ;;
50       *) new_path="$new_path:$d" ;;
51     esac
52   done
54   PATH=$new_path
55   export PATH
58 getlimits_()
60   eval $(getlimits)
61   test "$INT_MAX" || fatal_ "running getlimits"
64 require_acl_()
66   getfacl --version < /dev/null > /dev/null 2>&1 \
67     && setfacl --version < /dev/null > /dev/null 2>&1 \
68       || skip_ "This test requires getfacl and setfacl."
70   id -u bin > /dev/null 2>&1 \
71     || skip_ "This test requires a local user named bin."
74 is_local_dir_()
76   test $# = 1 || framework_failure_
77   df --local "$1" >/dev/null 2>&1
80 require_local_dir_()
82   is_local_dir_ . ||
83     skip_ "This test must be run on a local file system."
86 # Skip this test if we're not in SELinux "enforcing" mode.
87 require_selinux_enforcing_()
89   test "$(getenforce)" = Enforcing \
90     || skip_ "This test is useful only with SELinux in Enforcing mode."
93 require_openat_support_()
95   # Skip this test if your system has neither the openat-style functions
96   # nor /proc/self/fd support with which to emulate them.
97   test -z "$CONFIG_HEADER" \
98     && skip_ 'internal error: CONFIG_HEADER not defined'
100   _skip=yes
101   grep '^#define HAVE_OPENAT' "$CONFIG_HEADER" > /dev/null && _skip=no
102   test -d /proc/self/fd && _skip=no
103   if test $_skip = yes; then
104     skip_ 'this system lacks openat support'
105   fi
108 require_ulimit_()
110   ulimit_works=yes
111   # Expect to be able to exec a program in 10MB of virtual memory,
112   # but not in 20KB.  I chose "date".  It must not be a shell built-in
113   # function, so you can't use echo, printf, true, etc.
114   # Of course, in coreutils, I could use $top_builddir/src/true,
115   # but this should be able to work for other projects, too.
116   ( ulimit -v 10000; date ) > /dev/null 2>&1 || ulimit_works=no
117   ( ulimit -v 20;    date ) > /dev/null 2>&1 && ulimit_works=no
119   test $ulimit_works = no \
120     && skip_ "this shell lacks ulimit support"
123 require_readable_root_()
125   test -r / || skip_ "/ is not readable"
128 # Skip the current test if strace is not available or doesn't work
129 # with the named syscall.  Usage: require_strace_ unlink
130 require_strace_()
132   test $# = 1 || framework_failure_
134   strace -V < /dev/null > /dev/null 2>&1 ||
135     skip_ 'no strace program'
137   strace -qe "$1" echo > /dev/null 2>&1 ||
138     skip_ 'strace -qe "'"$1"'" does not work'
140   # On some linux/sparc64 systems, strace works fine on 32-bit executables,
141   # but prints only one line of output for every 64-bit executable.
142   strace -o log-help ls --help >/dev/null || framework_failure_
143   n_lines_help=$(wc -l < log-help)
144   rm -f log-help
145   if test $n_lines_help = 0 || test $n_lines_help = 1; then
146     skip_ 'strace produces no more than one line of output'
147   fi
150 require_setfacl_()
152   setfacl -m user::rwx . \
153     || skip_ "setfacl does not work on the current file system"
156 # Require a controlling input 'terminal'.
157 require_controlling_input_terminal_()
159   tty -s || have_input_tty=no
160   test -t 0 || have_input_tty=no
161   if test "$have_input_tty" = no; then
162     skip_ 'requires controlling input terminal
163 This test must have a controlling input "terminal", so it may not be
164 run via "batch", "at", or "ssh".  On some systems, it may not even be
165 run in the background.'
166   fi
169 require_built_()
171   skip_=no
172   for i in "$@"; do
173     case " $built_programs " in
174       *" $i "*) ;;
175       *) echo "$i: not built" 1>&2; skip_=yes ;;
176     esac
177   done
179   test $skip_ = yes && skip_ "required program(s) not built"
182 require_file_system_bytes_free_()
184   local req=$1
185   local expr=$(stat -f --printf "$req / %S <= %a" .)
186   awk "BEGIN{ exit !($expr) }" \
187     || skip_ "this test needs at least $req bytes of free space"
190 uid_is_privileged_()
192   # Make sure id -u succeeds.
193   my_uid=$(id -u) \
194     || { echo "$0: cannot run 'id -u'" 1>&2; return 1; }
196   # Make sure it gives valid output.
197   case $my_uid in
198     0) ;;
199     *[!0-9]*)
200       echo "$0: invalid output ('$my_uid') from 'id -u'" 1>&2
201       return 1 ;;
202     *) return 1 ;;
203   esac
206 get_process_status_()
208   sed -n '/^State:[      ]*\([[:alpha:]]\).*/s//\1/p' /proc/$1/status
211 # Convert an ls-style permission string, like drwxr----x and -rw-r-x-wx
212 # to the equivalent chmod --mode (-m) argument, (=,u=rwx,g=r,o=x and
213 # =,u=rw,g=rx,o=wx).  Ignore ACLs.
214 rwx_to_mode_()
216   case $# in
217     1) rwx=$1;;
218     *) echo "$0: wrong number of arguments" 1>&2
219       echo "Usage: $0 ls-style-mode-string" 1>&2
220       return;;
221   esac
223   case $rwx in
224     [ld-][rwx-][rwx-][rwxsS-][rwx-][rwx-][rwxsS-][rwx-][rwx-][rwxtT-]) ;;
225     [ld-][rwx-][rwx-][rwxsS-][rwx-][rwx-][rwxsS-][rwx-][rwx-][rwxtT-][+.]) ;;
226     *) echo "$0: invalid mode string: $rwx" 1>&2; return;;
227   esac
229   # Perform these conversions:
230   # S  s
231   # s  xs
232   # T  t
233   # t  xt
234   # The 'T' and 't' ones are only valid for 'other'.
235   s='s/S/@/;s/s/x@/;s/@/s/'
236   t='s/T/@/;s/t/x@/;s/@/t/'
238   u=$(echo $rwx|sed 's/^.\(...\).*/,u=\1/;s/-//g;s/^,u=$//;'$s)
239   g=$(echo $rwx|sed 's/^....\(...\).*/,g=\1/;s/-//g;s/^,g=$//;'$s)
240   o=$(echo $rwx|sed 's/^.......\(...\).*/,o=\1/;s/-//g;s/^,o=$//;'$s';'$t)
241   echo "=$u$g$o"
244 # Set the global variable stty_reversible_ to a space-separated list of the
245 # reversible settings from stty.c.  stty_reversible_ also starts and ends
246 # with a space.
247 stty_reversible_init_()
249   # Pad start with one space for the first option to match in query function.
250   stty_reversible_=' '$(perl -lne '/^ *{"(.*?)",.*\bREV\b/ and print $1' \
251     $abs_top_srcdir/src/stty.c | tr '\n' ' ')
252   # Ensure that there are at least 62, i.e., so we're alerted if
253   # reformatting the source empties the list.
254   test 62 -le $(echo "$stty_reversible_"|wc -w)  \
255     || framework_failure_ "too few reversible settings"
258 # Test whether $1 is one of stty's reversible options.
259 stty_reversible_query_()
261   case $stty_reversible_ in
262     '')
263       framework_failure_ "stty_reversible_init_() not called?";;
264     *" $1 "*)
265       return 0;;
266     *)
267       return 1;;
268   esac
271 skip_if_()
273   case $1 in
274     root) skip_ must be run as root ;;
275     non-root) skip_ must be run as non-root ;;
276     *) ;;  # FIXME?
277   esac
280 require_selinux_()
282   # When in a chroot of an SELinux-enabled system, but with a mock-simulated
283   # SELinux-*disabled* system, recognize that SELinux is disabled system wide:
284   grep 'selinuxfs$' /proc/filesystems > /dev/null \
285     || skip_ "this system lacks SELinux support"
287   # Independent of whether SELinux is enabled system-wide,
288   # the current file system may lack SELinux support.
289   case $(ls -Zd .) in
290     '? .'|'unlabeled .')
291       skip_ "this system (or maybe just" \
292         "the current file system) lacks SELinux support"
293     ;;
294   esac
297 very_expensive_()
299   if test "$RUN_VERY_EXPENSIVE_TESTS" != yes; then
300     skip_ 'very expensive: disabled by default
301 This test is very expensive, so it is disabled by default.
302 To run it anyway, rerun make check with the RUN_VERY_EXPENSIVE_TESTS
303 environment variable set to yes.  E.g.,
305   env RUN_VERY_EXPENSIVE_TESTS=yes make check
307 or use the shortcut target of the toplevel Makefile,
309   make check-very-expensive
311   fi
314 expensive_()
316   if test "$RUN_EXPENSIVE_TESTS" != yes; then
317     skip_ 'expensive: disabled by default
318 This test is relatively expensive, so it is disabled by default.
319 To run it anyway, rerun make check with the RUN_EXPENSIVE_TESTS
320 environment variable set to yes.  E.g.,
322   env RUN_EXPENSIVE_TESTS=yes make check
324 or use the shortcut target of the toplevel Makefile,
326   make check-expensive
328   fi
331 require_root_()
333   uid_is_privileged_ || skip_ "must be run as root"
334   NON_ROOT_USERNAME=${NON_ROOT_USERNAME=nobody}
335   NON_ROOT_GROUP=${NON_ROOT_GROUP=$(id -g $NON_ROOT_USERNAME)}
338 skip_if_root_() { uid_is_privileged_ && skip_ "must be run as non-root"; }
340 # Set 'groups' to a space-separated list of at least two groups
341 # of which the user is a member.
342 require_membership_in_two_groups_()
344   test $# = 0 || framework_failure_
346   groups=${COREUTILS_GROUPS-$( (id -G || /usr/xpg4/bin/id -G) 2>/dev/null)}
347   case "$groups" in
348     *' '*) ;;
349     *) skip_ 'requires membership in two groups
350 this test requires that you be a member of more than one group,
351 but running 'id -G'\'' either failed or found just one.  If you really
352 are a member of at least two groups, then rerun this test with
353 COREUTILS_GROUPS set in your environment to the space-separated list
354 of group names or numbers.  E.g.,
356   env COREUTILS_GROUPS='\''users cdrom'\'' make check
359      ;;
360   esac
363 # Is /proc/$PID/status supported?
364 require_proc_pid_status_()
366     sleep 2 &
367     local pid=$!
368     sleep .5
369     grep '^State:[       ]*[S]' /proc/$pid/status > /dev/null 2>&1 ||
370     skip_ "/proc/$pid/status: missing or 'different'"
371     kill $pid
374 # Return nonzero if the specified path is on a file system for
375 # which FIEMAP support exists.  Note some file systems (like ext3 and btrfs)
376 # only support FIEMAP for files, not directories.
377 fiemap_capable_()
379   if ! python < /dev/null; then
380     warn_ 'fiemap_capable_: python missing: assuming not fiemap capable'
381     return 1
382   fi
383   python $abs_srcdir/fiemap-capable "$@"
386 # Skip the current test if "." lacks d_type support.
387 require_dirent_d_type_()
389   python < /dev/null \
390     || skip_ python missing: assuming no d_type support
392   # Manually exclude xfs, since the test would mistakenly report
393   # that it has d_type support: d_type == DT_DIR for "." and "..",
394   # but DT_UNKNOWN for all other types.
395   df -x xfs . > /dev/null 2>&1 \
396     || skip_ requires d_type support
398   python $abs_srcdir/d_type-check \
399     || skip_ requires d_type support
402 # Skip the current test if we lack Perl.
403 require_perl_()
405   : ${PERL=perl}
406   $PERL -e 'use warnings' > /dev/null 2>&1 \
407     || skip_ 'configure did not find a usable version of Perl'
410 # Does the current (working-dir) file system support sparse files?
411 require_sparse_support_()
413   test $# = 0 || framework_failure_
414   # Test whether we can create a sparse file.
415   # For example, on Darwin6.5 with a file system of type hfs, it's not possible.
416   # NTFS requires 128K before a hole appears in a sparse file.
417   t=sparse.$$
418   dd bs=1 seek=128K of=$t < /dev/null 2> /dev/null
419   set x $(du -sk $t)
420   kb_size=$2
421   rm -f $t
422   if test $kb_size -ge 128; then
423     skip_ 'this file system does not support sparse files'
424   fi
427 mkfifo_or_skip_()
429   test $# = 1 || framework_failure_
430   if ! mkfifo "$1"; then
431     # Make an exception of this case -- usually we interpret framework-creation
432     # failure as a test failure.  However, in this case, when running on a SunOS
433     # system using a disk NFS mounted from OpenBSD, the above fails like this:
434     # mkfifo: cannot make fifo 'fifo-10558': Not owner
435     skip_ 'unable to create a fifo'
436   fi
439 # Disable the current test if the working directory seems to have
440 # the setgid bit set.
441 skip_if_setgid_()
443   setgid_tmpdir=setgid-$$
444   (umask 77; mkdir $setgid_tmpdir)
445   perms=$(stat --printf %A $setgid_tmpdir)
446   rmdir $setgid_tmpdir
447   case $perms in
448     drwx------);;
449     drwxr-xr-x);;  # Windows98 + DJGPP 2.03
450     *) skip_ 'this directory has the setgid bit set';;
451   esac
454 skip_if_mcstransd_is_running_()
456   test $# = 0 || framework_failure_
458   # When mcstransd is running, you'll see only the 3-component
459   # version of file-system context strings.  Detect that,
460   # and if it's running, skip this test.
461   __ctx=$(stat --printf='%C\n' .) || framework_failure_
462   case $__ctx in
463     *:*:*:*) ;; # four components is ok
464     *) # anything else probably means mcstransd is running
465         skip_ "unexpected context '$__ctx'; turn off mcstransd" ;;
466   esac
469 # Skip the current test if umask doesn't work as usual.
470 # This test should be run in the temporary directory that ends
471 # up being removed via the trap commands.
472 working_umask_or_skip_()
474   umask 022
475   touch file1 file2
476   chmod 644 file2
477   perms=$(ls -l file1 file2 | sed 's/ .*//' | uniq)
478   rm -f file1 file2
480   case $perms in
481   *'
482   '*) skip_ 'your build directory has unusual umask semantics'
483   esac
486 # Retry a function requiring a sufficient delay to _pass_
487 # using a truncated exponential backoff method.
488 #     Example: retry_delay_ dd_reblock_1 .1 6
489 # This example will call the dd_reblock_1 function with
490 # an initial delay of .1 second and call it at most 6 times
491 # with a max delay of 3.2s (doubled each time), or a total of 6.3s
492 # Note ensure you do _not_ quote the parameter to GNU sleep in
493 # your function, as it may contain separate values that sleep
494 # needs to accumulate.
495 retry_delay_()
497   local test_func=$1
498   local init_delay=$2
499   local max_n_tries=$3
501   local attempt=1
502   local num_sleeps=$attempt
503   local time_fail
504   while test $attempt -le $max_n_tries; do
505     local delay=$($AWK -v n=$num_sleeps -v s="$init_delay" \
506                   'BEGIN { print s * n }')
507     "$test_func" "$delay" && { time_fail=0; break; } || time_fail=1
508     attempt=$(expr $attempt + 1)
509     num_sleeps=$(expr $num_sleeps '*' 2)
510   done
511   test "$time_fail" = 0
514 # Call this with a list of programs under test immediately after
515 # sourcing init.sh.
516 print_ver_()
518   if test "$VERBOSE" = yes; then
519     local i
520     for i in $*; do
521       env $i --version
522     done
523   fi
526 # Are we running on GNU/Hurd?
527 require_gnu_()
529   test "$(uname)" = GNU \
530     || skip_ 'not running on GNU/Hurd'
533 sanitize_path_