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