doc: clean up NEWS
[platform/upstream/coreutils.git] / tests / init.cfg
1 # This file is sourced by init.sh, *before* its initialization.
2
3 # Copyright (C) 2010-2011 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 3 of the License, or
8 # (at your option) 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, see <http://www.gnu.org/licenses/>.
17
18
19 # This goes hand in hand with the "exec 9>&2;" in tests/Makefile.am's
20 # TESTS_ENVIRONMENT definition.
21 stderr_fileno_=9
22
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 sanitize_path_()
27 {
28   # FIXME: remove double quotes around $IFS when all tests use init.sh.
29   # They constitute a work-around for a bug in FreeBSD 8.1's /bin/sh.
30   local saved_IFS="$IFS"
31     IFS=:
32     set -- $PATH
33   IFS=$saved_IFS
34
35   local d d1
36   local colon=
37   local new_path=
38   for d in "$@"; do
39     test -z "$d" && d1=. || d1=$d
40     if ls -d "$d1/." > /dev/null 2>&1; then
41       new_path="$new_path$colon$d"
42       colon=':'
43     fi
44   done
45
46   PATH=$new_path
47   export PATH
48 }
49
50 getlimits_()
51 {
52   eval $(getlimits)
53   test "$INT_MAX" || fatal_ "running getlimits"
54 }
55
56 require_acl_()
57 {
58   getfacl --version < /dev/null > /dev/null 2>&1 \
59     && setfacl --version < /dev/null > /dev/null 2>&1 \
60       || skip_ "This test requires getfacl and setfacl."
61
62   id -u bin > /dev/null 2>&1 \
63     || skip_ "This test requires a local user named bin."
64 }
65
66 is_local_dir_()
67 {
68   test $# = 1 || framework_failure_
69   df --local "$1" >/dev/null 2>&1
70 }
71
72 require_local_dir_()
73 {
74   is_local_dir_ . ||
75     skip_ "This test must be run on a local file system."
76 }
77
78 # Skip this test if we're not in SELinux "enforcing" mode.
79 require_selinux_enforcing_()
80 {
81   test "$(getenforce)" = Enforcing \
82     || skip_ "This test is useful only with SELinux in Enforcing mode."
83 }
84
85 require_openat_support_()
86 {
87   # Skip this test if your system has neither the openat-style functions
88   # nor /proc/self/fd support with which to emulate them.
89   test -z "$CONFIG_HEADER" \
90     && skip_ 'internal error: CONFIG_HEADER not defined'
91
92   _skip=yes
93   grep '^#define HAVE_OPENAT' "$CONFIG_HEADER" > /dev/null && _skip=no
94   test -d /proc/self/fd && _skip=no
95   if test $_skip = yes; then
96     skip_ 'this system lacks openat support'
97   fi
98 }
99
100 require_ulimit_()
101 {
102   ulimit_works=yes
103   # Expect to be able to exec a program in 10MB of virtual memory,
104   # but not in 20KB.  I chose "date".  It must not be a shell built-in
105   # function, so you can't use echo, printf, true, etc.
106   # Of course, in coreutils, I could use $top_builddir/src/true,
107   # but this should be able to work for other projects, too.
108   ( ulimit -v 10000; date ) > /dev/null 2>&1 || ulimit_works=no
109   ( ulimit -v 20;    date ) > /dev/null 2>&1 && ulimit_works=no
110
111   test $ulimit_works = no \
112     && skip_ "this shell lacks ulimit support"
113 }
114
115 require_readable_root_()
116 {
117   test -r / || skip_ "/ is not readable"
118 }
119
120 # Skip the current test if strace is not available or doesn't work
121 # with the named syscall.  Usage: require_strace_ unlink
122 require_strace_()
123 {
124   test $# = 1 || framework_failure_
125
126   strace -V < /dev/null > /dev/null 2>&1 ||
127     skip_ 'no strace program'
128
129   strace -qe "$1" echo > /dev/null 2>&1 ||
130     skip_ 'strace -qe "'"$1"'" does not work'
131 }
132
133 require_setfacl_()
134 {
135   setfacl -m user::rwx . \
136     || skip_ "setfacl does not work on the current file system"
137 }
138
139 # Require a controlling input `terminal'.
140 require_controlling_input_terminal_()
141 {
142   tty -s || have_input_tty=no
143   test -t 0 || have_input_tty=no
144   if test "$have_input_tty" = no; then
145     skip_ 'requires controlling input terminal
146 This test must have a controlling input "terminal", so it may not be
147 run via "batch", "at", or "ssh".  On some systems, it may not even be
148 run in the background.'
149   fi
150 }
151
152 require_built_()
153 {
154   skip_=no
155   for i in "$@"; do
156     case " $built_programs " in
157       *" $i "*) ;;
158       *) echo "$i: not built" 1>&2; skip_=yes ;;
159     esac
160   done
161
162   test $skip_ = yes && skip_ "required program(s) not built"
163 }
164
165 require_file_system_bytes_free_()
166 {
167   local req=$1
168   local expr=$(stat -f --printf "$req / %S <= %a" .)
169   awk "BEGIN{ exit !($expr) }" \
170     || skip_ "this test needs at least $req bytes of free space"
171 }
172
173 uid_is_privileged_()
174 {
175   # Make sure id -u succeeds.
176   my_uid=$(id -u) \
177     || { echo "$0: cannot run \`id -u'" 1>&2; return 1; }
178
179   # Make sure it gives valid output.
180   case $my_uid in
181     0) ;;
182     *[!0-9]*)
183       echo "$0: invalid output (\`$my_uid') from \`id -u'" 1>&2
184       return 1 ;;
185     *) return 1 ;;
186   esac
187 }
188
189 # Some versions of sudo do not include /sbin in PATH.
190 # Test if mkfs is in PATH, otherwise try to adapt PATH.
191 require_mkfs_PATH_()
192 {
193   type mkfs && return
194
195   case ":$PATH:" in
196     *:/sbin:*) skip_ "no usable mkfs found" ;;
197   esac
198
199   test -x /sbin/mkfs \
200     || skip_ "no usable mkfs found"
201
202   PATH="$PATH:/sbin"
203   export PATH
204 }
205
206 get_process_status_()
207 {
208   sed -n '/^State:[      ]*\([[:alpha:]]\).*/s//\1/p' /proc/$1/status
209 }
210
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_()
215 {
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
222
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
228
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/'
237
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"
242 }
243
244 skip_if_()
245 {
246   case $1 in
247     root) skip_ must be run as root ;;
248     non-root) skip_ must be run as non-root ;;
249     *) ;;  # FIXME?
250   esac
251 }
252
253 require_selinux_()
254 {
255   # When in a chroot of an SELinux-enabled system, but with a mock-simulated
256   # SELinux-*disabled* system, recognize that SELinux is disabled system wide:
257   grep 'selinuxfs$' /proc/filesystems > /dev/null \
258     || skip_ "this system lacks SELinux support"
259
260   # Independent of whether SELinux is enabled system-wide,
261   # the current file system may lack SELinux support.
262   case `ls -Zd .` in
263     '? .'|'unlabeled .')
264       skip_ "this system (or maybe just" \
265         "the current file system) lacks SELinux support"
266     ;;
267   esac
268 }
269
270 very_expensive_()
271 {
272   if test "$RUN_VERY_EXPENSIVE_TESTS" != yes; then
273     skip_ 'very expensive: disabled by default
274 This test is very expensive, so it is disabled by default.
275 To run it anyway, rerun make check with the RUN_VERY_EXPENSIVE_TESTS
276 environment variable set to yes.  E.g.,
277
278   env RUN_VERY_EXPENSIVE_TESTS=yes make check
279
280 or use the shortcut target of the toplevel Makefile,
281
282   make check-very-expensive
283 '
284   fi
285 }
286
287 expensive_()
288 {
289   if test "$RUN_EXPENSIVE_TESTS" != yes; then
290     skip_ 'expensive: disabled by default
291 This test is relatively expensive, so it is disabled by default.
292 To run it anyway, rerun make check with the RUN_EXPENSIVE_TESTS
293 environment variable set to yes.  E.g.,
294
295   env RUN_EXPENSIVE_TESTS=yes make check
296
297 or use the shortcut target of the toplevel Makefile,
298
299   make check-expensive
300 '
301   fi
302 }
303
304 require_root_()
305 {
306   uid_is_privileged_ || skip_ "must be run as root"
307   NON_ROOT_USERNAME=${NON_ROOT_USERNAME=nobody}
308   NON_ROOT_GROUP=${NON_ROOT_GROUP=$(id -g $NON_ROOT_USERNAME)}
309 }
310
311 skip_if_root_() { uid_is_privileged_ && skip_ "must be run as non-root"; }
312
313 # Set `groups' to a space-separated list of at least two groups
314 # of which the user is a member.
315 require_membership_in_two_groups_()
316 {
317   test $# = 0 || framework_failure_
318
319   groups=${COREUTILS_GROUPS-`(id -G || /usr/xpg4/bin/id -G) 2>/dev/null`}
320   case "$groups" in
321     *' '*) ;;
322     *) skip_ 'requires membership in two groups
323 this test requires that you be a member of more than one group,
324 but running `id -G'\'' either failed or found just one.  If you really
325 are a member of at least two groups, then rerun this test with
326 COREUTILS_GROUPS set in your environment to the space-separated list
327 of group names or numbers.  E.g.,
328
329   env COREUTILS_GROUPS='\''users cdrom'\'' make check
330
331 '
332      ;;
333   esac
334 }
335
336 # Is /proc/$PID/status supported?
337 require_proc_pid_status_()
338 {
339     sleep 2 &
340     local pid=$!
341     sleep .5
342     grep '^State:[       ]*[S]' /proc/$pid/status > /dev/null 2>&1 ||
343     skip_ "/proc/$pid/status: missing or 'different'"
344     kill $pid
345 }
346
347 # Return nonzero if the specified path is on a file system for
348 # which FIEMAP support exists.  Note some file systems (like ext3 and btrfs)
349 # only support FIEMAP for files, not directories.
350 fiemap_capable_()
351 {
352   if ! python < /dev/null; then
353     warn_ 'fiemap_capable_: python missing: assuming not fiemap capable'
354     return 1
355   fi
356   python $abs_srcdir/fiemap-capable "$@"
357 }
358
359 # Skip the current test if "." lacks d_type support.
360 require_dirent_d_type_()
361 {
362   python < /dev/null \
363     || skip_ python missing: assuming no d_type support
364
365   python $abs_srcdir/d_type-check \
366     || skip_ requires d_type support
367 }
368
369 # Skip the current test if we lack Perl.
370 require_perl_()
371 {
372   : ${PERL=perl}
373   $PERL -e 'use warnings' > /dev/null 2>&1 \
374     || skip_ 'configure did not find a usable version of Perl'
375 }
376
377 # Does the current (working-dir) file system support sparse files?
378 require_sparse_support_()
379 {
380   test $# = 0 || framework_failure_
381   # Test whether we can create a sparse file.
382   # For example, on Darwin6.5 with a file system of type hfs, it's not possible.
383   # NTFS requires 128K before a hole appears in a sparse file.
384   t=sparse.$$
385   dd bs=1 seek=128K of=$t < /dev/null 2> /dev/null
386   set x `du -sk $t`
387   kb_size=$2
388   rm -f $t
389   if test $kb_size -ge 128; then
390     skip_ 'this file system does not support sparse files'
391   fi
392 }
393
394 mkfifo_or_skip_()
395 {
396   test $# = 1 || framework_failure_
397   if ! mkfifo "$1"; then
398     # Make an exception of this case -- usually we interpret framework-creation
399     # failure as a test failure.  However, in this case, when running on a SunOS
400     # system using a disk NFS mounted from OpenBSD, the above fails like this:
401     # mkfifo: cannot make fifo `fifo-10558': Not owner
402     skip_ 'unable to create a fifo'
403   fi
404 }
405
406 # Disable the current test if the working directory seems to have
407 # the setgid bit set.
408 skip_if_setgid_()
409 {
410   setgid_tmpdir=setgid-$$
411   (umask 77; mkdir $setgid_tmpdir)
412   perms=$(stat --printf %A $setgid_tmpdir)
413   rmdir $setgid_tmpdir
414   case $perms in
415     drwx------);;
416     drwxr-xr-x);;  # Windows98 + DJGPP 2.03
417     *) skip_ 'this directory has the setgid bit set';;
418   esac
419 }
420
421 skip_if_mcstransd_is_running_()
422 {
423   test $# = 0 || framework_failure_
424
425   # When mcstransd is running, you'll see only the 3-component
426   # version of file-system context strings.  Detect that,
427   # and if it's running, skip this test.
428   __ctx=$(stat --printf='%C\n' .) || framework_failure_
429   case $__ctx in
430     *:*:*:*) ;; # four components is ok
431     *) # anything else probably means mcstransd is running
432         skip_ "unexpected context '$__ctx'; turn off mcstransd" ;;
433   esac
434 }
435
436 # Skip the current test if umask doesn't work as usual.
437 # This test should be run in the temporary directory that ends
438 # up being removed via the trap commands.
439 working_umask_or_skip_()
440 {
441   umask 022
442   touch file1 file2
443   chmod 644 file2
444   perms=`ls -l file1 file2 | sed 's/ .*//' | uniq`
445   rm -f file1 file2
446
447   case $perms in
448   *'
449   '*) skip_ 'your build directory has unusual umask semantics'
450   esac
451 }
452
453 # Retry a function requiring a sufficient delay to _pass_
454 # using a truncated exponential backoff method.
455 #     Example: retry_delay_ dd_reblock_1 .1 6
456 # This example will call the dd_reblock_1 function with
457 # an initial delay of .1 second and call it at most 6 times
458 # with a max delay of 3.2s (doubled each time), or a total of 6.3s
459 # Note ensure you do _not_ quote the parameter to GNU sleep in
460 # your function, as it may contain separate values that `sleep`
461 # needs to accumulate.
462 retry_delay_()
463 {
464   local test_func=$1
465   local init_delay=$2
466   local max_n_tries=$3
467
468   local attempt=1
469   local num_sleeps=$attempt
470   local time_fail
471   while test $attempt -le $max_n_tries; do
472     local delay=$($AWK -v n=$num_sleeps -v s="$init_delay" \
473                   'BEGIN { print s * n }')
474     "$test_func" "$delay" && { time_fail=0; break; } || time_fail=1
475     attempt=$(expr $attempt + 1)
476     num_sleeps=$(expr $num_sleeps '*' 2)
477   done
478   test "$time_fail" = 0
479 }
480
481 # Call this with a list of programs under test immediately after
482 # sourcing init.sh.
483 print_ver_()
484 {
485   if test "$VERBOSE" = yes; then
486     local i
487     for i in $*; do
488       env $i --version
489     done
490   fi
491 }
492
493 sanitize_path_