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