test: improve the cp fiemap tests
[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   # 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
21
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
32
33   PATH=$new_path
34   export PATH
35 }
36
37 skip_test_()
38 {
39   echo "$0: skipping test: $@" | head -1 1>&9
40   echo "$0: skipping test: $@" 1>&2
41   Exit 77
42 }
43
44 getlimits_()
45 {
46   eval $(getlimits)
47   test "$INT_MAX" ||
48     error_ "Error running getlimits"
49 }
50
51 require_acl_()
52 {
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."
56
57   id -u bin > /dev/null 2>&1 \
58     || skip_test_ "This test requires a local user named bin."
59 }
60
61 is_local_dir_()
62 {
63   test $# = 1 || framework_failure
64   df --local "$1" >/dev/null 2>&1
65 }
66
67 require_local_dir_()
68 {
69   is_local_dir_ . ||
70     skip_test_ "This test must be run on a local file system."
71 }
72
73 # Skip this test if we're not in SELinux "enforcing" mode.
74 require_selinux_enforcing_()
75 {
76   test "$(getenforce)" = Enforcing \
77     || skip_test_ "This test is useful only with SELinux in Enforcing mode."
78 }
79
80 require_openat_support_()
81 {
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'
86
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
93 }
94
95 require_ulimit_()
96 {
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
105
106   test $ulimit_works = no \
107     && skip_test_ "this shell lacks ulimit support"
108 }
109
110 require_readable_root_()
111 {
112   test -r / || skip_test_ "/ is not readable"
113 }
114
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_()
118 {
119   test $# = 1 || framework_failure
120
121   strace -V < /dev/null > /dev/null 2>&1 ||
122     skip_test_ 'no strace program'
123
124   strace -qe "$1" echo > /dev/null 2>&1 ||
125     skip_test_ 'strace -qe "'"$1"'" does not work'
126 }
127
128 # Require a controlling input `terminal'.
129 require_controlling_input_terminal_()
130 {
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
139 }
140
141 require_built_()
142 {
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
150
151   test $skip_ = yes && skip_test_ "required program(s) not built"
152 }
153
154 uid_is_privileged_()
155 {
156   # Make sure id -u succeeds.
157   my_uid=$(id -u) \
158     || { echo "$0: cannot run \`id -u'" 1>&2; return 1; }
159
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
168 }
169
170 get_process_status_()
171 {
172   sed -n '/^State:[      ]*\([[:alpha:]]\).*/s//\1/p' /proc/$1/status
173 }
174
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_()
179 {
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
186
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
192
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/'
201
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"
206 }
207
208 skip_if_()
209 {
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
215 }
216
217 require_selinux_()
218 {
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
225 }
226
227 very_expensive_()
228 {
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.,
234
235   env RUN_VERY_EXPENSIVE_TESTS=yes make check
236 '
237   fi
238 }
239
240 expensive_()
241 {
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.,
247
248   env RUN_EXPENSIVE_TESTS=yes make check
249 '
250   fi
251 }
252
253 require_root_()
254 {
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)}
258 }
259
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'; }
263
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_()
267 {
268   test $# = 0 || framework_failure
269
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.,
279
280   env COREUTILS_GROUPS='users cdrom' make check
281
282 '
283      ;;
284   esac
285 }
286
287 # Is /proc/$PID/status supported?
288 require_proc_pid_status_()
289 {
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
296 }
297
298 # Return nonzero if the specified path is on a file system for
299 # which FIEMAP support exists.  Note some file systems (like ext3)
300 # only support FIEMAP for files, not directories.
301 fiemap_capable_()
302 {
303   if ! python < /dev/null; then
304     echo 'fiemap_capable_: python missing: assuming not fiemap capable' 1>&2
305     return 1
306   fi
307   python $abs_srcdir/fiemap-capable "$@"
308 }
309
310 # Does the current (working-dir) file system support sparse files?
311 require_sparse_support_()
312 {
313   test $# = 0 || framework_failure
314   # Test whether we can create a sparse file.
315   # For example, on Darwin6.5 with a file system of type hfs, it's not possible.
316   # NTFS requires 128K before a hole appears in a sparse file.
317   t=sparse.$$
318   dd bs=1 seek=128K of=$t < /dev/null 2> /dev/null
319   set x `du -sk $t`
320   kb_size=$2
321   rm -f $t
322   if test $kb_size -ge 128; then
323     skip_test_ 'this file system does not support sparse files'
324   fi
325 }
326
327 mkfifo_or_skip_()
328 {
329   test $# = 1 || framework_failure
330   if ! mkfifo "$1"; then
331     # Make an exception of this case -- usually we interpret framework-creation
332     # failure as a test failure.  However, in this case, when running on a SunOS
333     # system using a disk NFS mounted from OpenBSD, the above fails like this:
334     # mkfifo: cannot make fifo `fifo-10558': Not owner
335     skip_test_ 'NOTICE: unable to create test prerequisites'
336   fi
337 }
338
339 # Disable the current test if the working directory seems to have
340 # the setgid bit set.
341 skip_if_setgid_()
342 {
343   setgid_tmpdir=setgid-$$
344   (umask 77; mkdir $setgid_tmpdir)
345   perms=$(stat --printf %A $setgid_tmpdir)
346   rmdir $setgid_tmpdir
347   case $perms in
348     drwx------);;
349     drwxr-xr-x);;  # Windows98 + DJGPP 2.03
350     *) skip_test_ 'this directory has the setgid bit set';;
351   esac
352 }
353
354 skip_if_mcstransd_is_running_()
355 {
356   test $# = 0 || framework_failure
357
358   # When mcstransd is running, you'll see only the 3-component
359   # version of file-system context strings.  Detect that,
360   # and if it's running, skip this test.
361   __ctx=$(stat --printf='%C\n' .) || framework_failure
362   case $__ctx in
363     *:*:*:*) ;; # four components is ok
364     *) # anything else probably means mcstransd is running
365         skip_test_ "unexpected context '$__ctx'; turn off mcstransd" ;;
366   esac
367 }
368
369 # Skip the current test if umask doesn't work as usual.
370 # This test should be run in the temporary directory that ends
371 # up being removed via the trap commands.
372 working_umask_or_skip_()
373 {
374   umask 022
375   touch file1 file2
376   chmod 644 file2
377   perms=`ls -l file1 file2 | sed 's/ .*//' | uniq`
378   rm -f file1 file2
379
380   case $perms in
381   *'
382   '*) skip_test_ 'your build directory has unusual umask semantics'
383   esac
384 }
385
386 # Retry a function requiring a sufficient delay to _pass_
387 # using a truncated exponential backoff method.
388 #     Example: retry_delay_ dd_reblock_1 .1 6
389 # This example will call the dd_reblock_1 function with
390 # an initial delay of .1 second and call it at most 6 times
391 # with a max delay of 3.2s (doubled each time), or a total of 6.3s
392 # Note ensure you do _not_ quote the parameter to GNU sleep in
393 # your function, as it may contain separate values that `sleep`
394 # needs to accumulate.
395 retry_delay_()
396 {
397   local test_func=$1
398   local init_delay=$2
399   local max_n_tries=$3
400
401   local attempt=1
402   local num_sleeps=$attempt
403   local time_fail
404   while test $attempt -le $max_n_tries; do
405     local delay=$($AWK -v n=$num_sleeps -v s="$init_delay" \
406                   'BEGIN { print s * n }')
407     "$test_func" "$delay" && { time_fail=0; break; } || time_fail=1
408     attempt=$(expr $attempt + 1)
409     num_sleeps=$(expr $num_sleeps '*' 2)
410   done
411   test "$time_fail" = 0
412 }
413
414 # Call this with a list of programs under test immediately after
415 # sourcing init.sh.
416 print_ver_()
417 {
418   if test "$VERBOSE" = yes; then
419     local i
420     for i in $*; do
421       env $i --version
422     done
423   fi
424 }
425
426 sanitize_path_