1#
2# Automated Testing Framework (atf)
3#
4# Copyright (c) 2007, 2008, 2009, 2010 The NetBSD Foundation, Inc.
5# All rights reserved.
6#
7# Redistribution and use in source and binary forms, with or without
8# modification, are permitted provided that the following conditions
9# are met:
10# 1. Redistributions of source code must retain the above copyright
11#    notice, this list of conditions and the following disclaimer.
12# 2. Redistributions in binary form must reproduce the above copyright
13#    notice, this list of conditions and the following disclaimer in the
14#    documentation and/or other materials provided with the distribution.
15#
16# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
17# CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
18# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20# IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
21# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
23# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28#
29
30create_atffile()
31{
32    cat >Atffile <<EOF
33Content-Type: application/X-atf-atffile; version="1"
34
35prop: test-suite = atf
36
37EOF
38    for f in "${@}"; do
39        echo "tp: ${f}" >>Atffile
40    done
41}
42
43create_helper()
44{
45    cp $(atf_get_srcdir)/misc_helpers helper
46    create_atffile helper
47    TESTCASE=${1}; export TESTCASE
48}
49
50create_helper_stdin()
51{
52    # TODO: This really, really, really must use real test programs.
53    cat >${1} <<EOF
54#! $(atf-config -t atf_shell)
55while [ \${#} -gt 0 ]; do
56    case \${1} in
57        -l)
58            echo 'Content-Type: application/X-atf-tp; version="1"'
59            echo
60EOF
61    cnt=1
62    while [ ${cnt} -le ${2} ]; do
63        echo "echo 'ident: tc${cnt}'" >>${1}
64        [ ${cnt} -lt ${2} ] && echo "echo" >>${1}
65        cnt=$((${cnt} + 1))
66    done
67cat >>${1} <<EOF
68            exit 0
69            ;;
70        -r*)
71            resfile=\$(echo \${1} | cut -d r -f 2-)
72            ;;
73    esac
74    testcase=\$(echo \${1} | cut -d : -f 1)
75    shift
76done
77EOF
78    cat >>${1}
79}
80
81create_mount_helper()
82{
83    cat >${1} <<EOF
84#! /usr/bin/env atf-sh
85
86do_mount() {
87    platform=\$(uname)
88    case \${platform} in
89    Linux|NetBSD)
90        mount -t tmpfs tmpfs \${1} || atf_fail "Mount failed"
91        ;;
92    FreeBSD)
93        mdmfs -s 16m md \${1} || atf_fail "Mount failed"
94        ;;
95    SunOS)
96        mount -F tmpfs tmpfs \$(pwd)/\${1} || atf_fail "Mount failed"
97        ;;
98    *)
99        atf_fail "create_mount_helper called for an unsupported platform."
100        ;;
101    esac
102}
103
104atf_test_case main
105main_head() {
106    atf_set "require.user" "root"
107}
108main_body() {
109EOF
110    cat >>${1}
111    cat >>${1} <<EOF
112}
113
114atf_init_test_cases()
115{
116    atf_add_test_case main
117}
118EOF
119}
120
121atf_test_case config
122config_head()
123{
124    atf_set "descr" "Tests that the config files are read in the correct" \
125                    "order"
126}
127config_body()
128{
129    create_helper config
130
131    mkdir etc
132    mkdir .atf
133
134    echo "First: read system-wide common.conf."
135    cat >etc/common.conf <<EOF
136Content-Type: application/X-atf-config; version="1"
137
1381st = "sw common"
1392nd = "sw common"
1403rd = "sw common"
1414th = "sw common"
142EOF
143    atf_check -s eq:0 \
144        -o match:'1st: sw common' \
145        -o match:'2nd: sw common' \
146        -o match:'3rd: sw common' \
147        -o match:'4th: sw common' \
148        -e ignore -x \
149        "ATF_CONFDIR=$(pwd)/etc HOME=$(pwd) atf-run helper"
150
151    echo "Second: read system-wide <test-suite>.conf."
152    cat >etc/atf.conf <<EOF
153Content-Type: application/X-atf-config; version="1"
154
1551st = "sw atf"
156EOF
157    atf_check -s eq:0 \
158        -o match:'1st: sw atf' \
159        -o match:'2nd: sw common' \
160        -o match:'3rd: sw common' \
161        -o match:'4th: sw common' \
162        -e ignore -x \
163        "ATF_CONFDIR=$(pwd)/etc HOME=$(pwd) atf-run helper"
164
165    echo "Third: read user-specific common.conf."
166    cat >.atf/common.conf <<EOF
167Content-Type: application/X-atf-config; version="1"
168
1692nd = "us common"
170EOF
171    atf_check -s eq:0 \
172        -o match:'1st: sw atf' \
173        -o match:'2nd: us common' \
174        -o match:'3rd: sw common' \
175        -o match:'4th: sw common' \
176        -e ignore -x \
177        "ATF_CONFDIR=$(pwd)/etc HOME=$(pwd) atf-run helper"
178
179    echo "Fourth: read user-specific <test-suite>.conf."
180    cat >.atf/atf.conf <<EOF
181Content-Type: application/X-atf-config; version="1"
182
1833rd = "us atf"
184EOF
185    atf_check -s eq:0 \
186        -o match:'1st: sw atf' \
187        -o match:'2nd: us common' \
188        -o match:'3rd: us atf' \
189        -o match:'4th: sw common' \
190        -e ignore -x \
191        "ATF_CONFDIR=$(pwd)/etc HOME=$(pwd) atf-run helper"
192}
193
194atf_test_case vflag
195vflag_head()
196{
197    atf_set "descr" "Tests that the -v flag works and that it properly" \
198                    "overrides the values in configuration files"
199}
200vflag_body()
201{
202    create_helper testvar
203
204    echo "Checking that 'testvar' is not defined."
205    atf_check -s eq:1 -o ignore -e ignore -x \
206        "ATF_CONFDIR=$(pwd)/etc atf-run helper"
207
208    echo "Checking that defining 'testvar' trough '-v' works."
209    atf_check -s eq:0 -o match:'testvar: a value' -e ignore -x \
210        "ATF_CONFDIR=$(pwd)/etc atf-run -v testvar='a value' helper"
211
212    echo "Checking that defining 'testvar' trough the configuration" \
213         "file works."
214    mkdir etc
215    cat >etc/common.conf <<EOF
216Content-Type: application/X-atf-config; version="1"
217
218testvar = "value in conf file"
219EOF
220    atf_check -s eq:0 -o match:'testvar: value in conf file' -e ignore -x \
221              "ATF_CONFDIR=$(pwd)/etc atf-run helper"
222
223    echo "Checking that defining 'testvar' trough -v overrides the" \
224         "configuration file."
225    atf_check -s eq:0 -o match:'testvar: a value' -e ignore -x \
226        "ATF_CONFDIR=$(pwd)/etc atf-run -v testvar='a value' helper"
227}
228
229atf_test_case atffile
230atffile_head()
231{
232    atf_set "descr" "Tests that the variables defined by the Atffile" \
233                    "are recognized and that they take the lowest priority"
234}
235atffile_body()
236{
237    create_helper testvar
238
239    echo "Checking that 'testvar' is not defined."
240    atf_check -s eq:1 -o ignore -e ignore -x \
241              "ATF_CONFDIR=$(pwd)/etc atf-run helper"
242
243    echo "Checking that defining 'testvar' trough the Atffile works."
244    echo 'conf: testvar = "a value"' >>Atffile
245    atf_check -s eq:0 -o match:'testvar: a value' -e ignore -x \
246              "ATF_CONFDIR=$(pwd)/etc atf-run helper"
247
248    echo "Checking that defining 'testvar' trough the configuration" \
249         "file overrides the one in the Atffile."
250    mkdir etc
251    cat >etc/common.conf <<EOF
252Content-Type: application/X-atf-config; version="1"
253
254testvar = "value in conf file"
255EOF
256    atf_check -s eq:0 -o match:'testvar: value in conf file' -e ignore -x \
257              "ATF_CONFDIR=$(pwd)/etc atf-run helper"
258    rm -rf etc
259
260    echo "Checking that defining 'testvar' trough -v overrides the" \
261         "one in the Atffile."
262    atf_check -s eq:0 -o match:'testvar: new value' -e ignore -x \
263        "ATF_CONFDIR=$(pwd)/etc atf-run -v testvar='new value' helper"
264}
265
266atf_test_case atffile_recursive
267atffile_recursive_head()
268{
269    atf_set "descr" "Tests that variables defined by an Atffile are not" \
270                    "inherited by other Atffiles."
271}
272atffile_recursive_body()
273{
274    create_helper testvar
275
276    mkdir dir
277    mv Atffile helper dir
278
279    echo "Checking that 'testvar' is not inherited."
280    create_atffile dir
281    echo 'conf: testvar = "a value"' >> Atffile
282    atf_check -s eq:1 -o ignore -e ignore -x "ATF_CONFDIR=$(pwd)/etc atf-run"
283
284    echo "Checking that defining 'testvar' in the correct Atffile works."
285    echo 'conf: testvar = "a value"' >>dir/Atffile
286    atf_check -s eq:0 -o match:'testvar: a value' -e ignore -x \
287              "ATF_CONFDIR=$(pwd)/etc atf-run"
288}
289
290atf_test_case fds
291fds_head()
292{
293    atf_set "descr" "Tests that all streams are properly captured"
294}
295fds_body()
296{
297    create_helper fds
298
299    atf_check -s eq:0 \
300        -o match:'^tc-so:msg1 to stdout$' \
301        -o match:'^tc-so:msg2 to stdout$' \
302        -o match:'^tc-se:msg1 to stderr$' \
303        -o match:'^tc-se:msg2 to stderr$' \
304        -e empty atf-run
305}
306
307atf_test_case mux_streams
308mux_streams_head()
309{
310    atf_set "descr" "Tests for a race condition in stream multiplexing"
311}
312mux_streams_body()
313{
314    create_helper mux_streams
315
316    for i in 1 2 3 4 5; do
317        echo "Attempt ${i}"
318        atf_check -s eq:0 -o match:'stdout 9999' -o match:'stderr 9999' atf-run
319    done
320}
321
322atf_test_case expect
323expect_head()
324{
325    atf_set "descr" "Tests the processing of test case results and the" \
326        "expect features"
327}
328expect_body()
329{
330    ln -s "$(atf_get_srcdir)/expect_helpers" .
331    create_atffile expect_helpers
332
333    atf_check -s eq:1 \
334        -o match:'death_and_exit, expected_death' \
335        -o match:'death_and_signal, expected_death' \
336        -o match:'death_but_pass, failed' \
337        -o match:'exit_any_and_exit, expected_exit' \
338        -o match:'exit_but_pass, failed' \
339        -o match:'exit_code_and_exit, expected_exit' \
340        -o match:'fail_and_fail_check, expected_failure' \
341        -o match:'fail_and_fail_requirement, expected_failure' \
342        -o match:'fail_but_pass, failed' \
343        -o match:'pass_and_pass, passed' \
344        -o match:'pass_but_fail_check, failed' \
345        -o match:'pass_but_fail_requirement, failed' \
346        -o match:'signal_any_and_signal, expected_signal' \
347        -o match:'signal_but_pass, failed' \
348        -o match:'signal_no_and_signal, expected_signal' \
349        -o match:'timeout_and_hang, expected_timeout' \
350        -o match:'timeout_but_pass, failed' \
351        -e empty atf-run
352}
353
354atf_test_case missing_results
355missing_results_head()
356{
357    atf_set "descr" "Ensures that atf-run correctly handles test cases that " \
358                    "do not create the results file"
359}
360missing_results_body()
361{
362    create_helper_stdin helper 1 <<EOF
363test -f \${resfile} && echo "resfile found"
364exit 0
365EOF
366    chmod +x helper
367
368    create_atffile helper
369
370    atf_check -s eq:1 \
371        -o match:'^tc-end: tc1, failed,.*failed to create' \
372        -o not-match:'resfile found' \
373        -e empty atf-run
374}
375
376atf_test_case broken_results
377broken_results_head()
378{
379    atf_set "descr" "Ensures that atf-run reports test programs that" \
380                    "provide a bogus results output as broken programs"
381}
382broken_results_body()
383{
384    # We produce two errors from the header to ensure that the parse
385    # errors are printed on a single line on the output file.  Printing
386    # them on separate lines would be incorrect.
387    create_helper_stdin helper 1 <<EOF
388echo 'line 1' >\${resfile}
389echo 'line 2' >>\${resfile}
390exit 0
391EOF
392    chmod +x helper
393
394    create_atffile helper
395
396    atf_check -s eq:1 -o match:'^tc-end: tc1, .*line 1.*line 2' -e empty atf-run
397}
398
399atf_test_case broken_tp_list
400broken_tp_list_head()
401{
402    atf_set "descr" "Ensures that atf-run reports test programs that" \
403                    "provide a bogus test case list"
404}
405broken_tp_list_body()
406{
407    cat >helper <<EOF
408#! $(atf-config -t atf_shell)
409while [ \${#} -gt 0 ]; do
410    if [ \${1} = -l ]; then
411        echo 'Content-Type: application/X-atf-tp; version="1"'
412        echo
413        echo 'foo: bar'
414        exit 0
415    else
416        shift
417    fi
418done
419exit 0
420EOF
421    chmod +x helper
422
423    create_atffile helper
424
425    re='^tp-end: helper,'
426    re="${re} Invalid format for test case list:.*First property.*ident"
427    atf_check -s eq:1 -o match:"${re}" -e empty atf-run
428}
429
430atf_test_case zero_tcs
431zero_tcs_head()
432{
433    atf_set "descr" "Ensures that atf-run reports test programs without" \
434                    "test cases as errors"
435}
436zero_tcs_body()
437{
438    create_helper_stdin helper 0 <<EOF
439echo 'Content-Type: application/X-atf-tp; version="1"'
440echo
441exit 1
442EOF
443    chmod +x helper
444
445    create_atffile helper
446
447    atf_check -s eq:1 \
448        -o match:'^tp-end: helper,.*Invalid format for test case list' \
449        -e empty atf-run
450}
451
452atf_test_case exit_codes
453exit_codes_head()
454{
455    atf_set "descr" "Ensures that atf-run reports bogus exit codes for" \
456                    "programs correctly"
457}
458exit_codes_body()
459{
460    create_helper_stdin helper 1 <<EOF
461echo "failed: Yes, it failed" >\${resfile}
462exit 0
463EOF
464    chmod +x helper
465
466    create_atffile helper
467
468    atf_check -s eq:1 \
469        -o match:'^tc-end: tc1,.*exited successfully.*reported failure' \
470        -e empty atf-run
471}
472
473atf_test_case signaled
474signaled_head()
475{
476    atf_set "descr" "Ensures that atf-run reports test program's crashes" \
477                    "correctly regardless of their actual results"
478}
479signaled_body()
480{
481    create_helper_stdin helper 2 <<EOF
482echo "passed" >\${resfile}
483case \${testcase} in
484    tc1) ;;
485    tc2) echo "Killing myself!" ; kill -9 \$\$ ;;
486esac
487EOF
488    chmod +x helper
489
490    create_atffile helper
491
492    atf_check -s eq:1 -o match:'^tc-end: tc2,.*received signal 9' \
493        -e empty atf-run
494}
495
496atf_test_case hooks
497hooks_head()
498{
499    atf_set "descr" "Checks that the default hooks work and that they" \
500                    "can be overriden by the user"
501}
502hooks_body()
503{
504    cp $(atf_get_srcdir)/pass_helper helper
505    create_atffile helper
506
507    mkdir atf
508    mkdir .atf
509
510    echo "Checking default hooks"
511    atf_check -s eq:0 -o match:'^info: time.start, ' \
512        -o match:'^info: time.end, ' -e empty -x \
513        "ATF_CONFDIR=$(pwd)/atf atf-run"
514
515    echo "Checking the system-wide info_start hook"
516    cat >atf/atf-run.hooks <<EOF
517info_start_hook()
518{
519    atf_tps_writer_info "test" "sw value"
520}
521EOF
522    atf_check -s eq:0 \
523        -o match:'^info: test, sw value' \
524        -o not-match:'^info: time.start, ' \
525        -o match:'^info: time.end, ' \
526        -e empty -x \
527        "ATF_CONFDIR=$(pwd)/atf atf-run"
528
529    echo "Checking the user-specific info_start hook"
530    cat >.atf/atf-run.hooks <<EOF
531info_start_hook()
532{
533    atf_tps_writer_info "test" "user value"
534}
535EOF
536    atf_check -s eq:0 \
537        -o match:'^info: test, user value' \
538        -o not-match:'^info: time.start, ' \
539        -o match:'^info: time.end, ' \
540        -e empty -x \
541        "ATF_CONFDIR=$(pwd)/atf atf-run"
542
543    rm atf/atf-run.hooks
544    rm .atf/atf-run.hooks
545
546    echo "Checking the system-wide info_end hook"
547    cat >atf/atf-run.hooks <<EOF
548info_end_hook()
549{
550    atf_tps_writer_info "test" "sw value"
551}
552EOF
553    atf_check -s eq:0 \
554        -o match:'^info: time.start, ' \
555        -o not-match:'^info: time.end, ' \
556        -o match:'^info: test, sw value' \
557        -e empty -x \
558        "ATF_CONFDIR=$(pwd)/atf atf-run"
559
560    echo "Checking the user-specific info_end hook"
561    cat >.atf/atf-run.hooks <<EOF
562info_end_hook()
563{
564    atf_tps_writer_info "test" "user value"
565}
566EOF
567    atf_check -s eq:0 \
568        -o match:'^info: time.start, ' \
569        -o not-match:'^info: time.end, ' \
570        -o match:'^info: test, user value' \
571        -e empty -x \
572         "ATF_CONFDIR=$(pwd)/atf atf-run"
573}
574
575atf_test_case isolation_env
576isolation_env_head()
577{
578    atf_set "descr" "Tests that atf-run sets a set of environment variables" \
579                    "to known sane values"
580}
581isolation_env_body()
582{
583    undef_vars="LANG LC_ALL LC_COLLATE LC_CTYPE LC_MESSAGES LC_MONETARY \
584                LC_NUMERIC LC_TIME TZ"
585    def_vars="HOME"
586
587    mangleenv="env"
588    for v in ${undef_vars} ${def_vars}; do
589        mangleenv="${mangleenv} ${v}=bogus-value"
590    done
591
592    create_helper env_list
593    create_atffile helper
594
595    # We must ignore stderr in this call (instead of specifying -e empty)
596    # because, when atf-run invokes the shell to run the hooks, we may get
597    # error messages about an invalid locale.  This happens, at least, when
598    # the shell is bash 4.x.
599    atf_check -s eq:0 -o save:stdout -e ignore ${mangleenv} atf-run helper
600
601    for v in ${undef_vars}; do
602        atf_check -s eq:1 -o empty -e empty grep "^tc-so:${v}=" stdout
603    done
604
605    for v in ${def_vars}; do
606        atf_check -s eq:0 -o ignore -e empty grep "^tc-so:${v}=" stdout
607    done
608}
609
610atf_test_case isolation_home
611isolation_home_head()
612{
613    atf_set "descr" "Tests that atf-run sets HOME to a sane and valid value"
614}
615isolation_home_body()
616{
617    create_helper env_home
618    create_atffile helper
619    atf_check -s eq:0 -o ignore -e ignore env HOME=foo atf-run helper
620}
621
622atf_test_case isolation_umask
623isolation_umask_head()
624{
625    atf_set "descr" "Tests that atf-run sets the umask to a known value"
626}
627isolation_umask_body()
628{
629    create_helper umask
630    create_atffile helper
631
632    atf_check -s eq:0 -o match:'umask: 0022' -e ignore -x \
633        "umask 0000 && atf-run helper"
634}
635
636atf_test_case cleanup_pass
637cleanup_pass_head()
638{
639    atf_set "descr" "Tests that atf-run calls the cleanup routine of the test" \
640        "case when the test case result is passed"
641}
642cleanup_pass_body()
643{
644    create_helper cleanup_states
645    create_atffile helper
646
647    atf_check -s eq:0 -o match:'cleanup_states, passed' -e ignore atf-run \
648        -v state=pass -v statedir=$(pwd) helper
649    test -f to-stay || atf_fail "Test case body did not run correctly"
650    if [ -f to-delete ]; then
651        atf_fail "Test case cleanup did not run correctly"
652    fi
653}
654
655atf_test_case cleanup_fail
656cleanup_fail_head()
657{
658    atf_set "descr" "Tests that atf-run calls the cleanup routine of the test" \
659        "case when the test case result is failed"
660}
661cleanup_fail_body()
662{
663    create_helper cleanup_states
664    create_atffile helper
665
666    atf_check -s eq:1 -o match:'cleanup_states, failed' -e ignore atf-run \
667        -v state=fail -v statedir=$(pwd) helper
668    test -f to-stay || atf_fail "Test case body did not run correctly"
669    if [ -f to-delete ]; then
670        atf_fail "Test case cleanup did not run correctly"
671    fi
672}
673
674atf_test_case cleanup_skip
675cleanup_skip_head()
676{
677    atf_set "descr" "Tests that atf-run calls the cleanup routine of the test" \
678        "case when the test case result is skipped"
679}
680cleanup_skip_body()
681{
682    create_helper cleanup_states
683    create_atffile helper
684
685    atf_check -s eq:0 -o match:'cleanup_states, skipped' -e ignore atf-run \
686        -v state=skip -v statedir=$(pwd) helper
687    test -f to-stay || atf_fail "Test case body did not run correctly"
688    if [ -f to-delete ]; then
689        atf_fail "Test case cleanup did not run correctly"
690    fi
691}
692
693atf_test_case cleanup_curdir
694cleanup_curdir_head()
695{
696    atf_set "descr" "Tests that atf-run calls the cleanup routine in the same" \
697        "work directory as the body so that they can share data"
698}
699cleanup_curdir_body()
700{
701    create_helper cleanup_curdir
702    create_atffile helper
703
704    atf_check -s eq:0 -o match:'cleanup_curdir, passed' \
705        -o match:'Old value: 1234' -e ignore atf-run helper
706}
707
708atf_test_case cleanup_signal
709cleanup_signal_head()
710{
711    atf_set "descr" "Tests that atf-run calls the cleanup routine if it gets" \
712        "a termination signal while running the body"
713}
714cleanup_signal_body()
715{
716    : # TODO: Write this.
717}
718
719atf_test_case cleanup_mount
720cleanup_mount_head()
721{
722    atf_set "descr" "Tests that the removal algorithm does not cross" \
723                    "mount points"
724    atf_set "require.user" "root"
725}
726cleanup_mount_body()
727{
728    ROOT="$(pwd)/root"; export ROOT
729
730    create_mount_helper helper <<EOF
731echo \$(pwd) >\${ROOT}
732mkdir foo
733mkdir foo/bar
734mkdir foo/bar/mnt
735do_mount foo/bar/mnt
736mkdir foo/baz
737do_mount foo/baz
738mkdir foo/baz/foo
739mkdir foo/baz/foo/bar
740do_mount foo/baz/foo/bar
741EOF
742    create_atffile helper
743    chmod +x helper
744
745    platform=$(uname)
746    case ${platform} in
747    Linux|FreeBSD|NetBSD|SunOS)
748        ;;
749    *)
750        # XXX Possibly specify in meta-data too.
751        atf_skip "Test unimplemented in this platform (${platform})"
752        ;;
753    esac
754
755    atf_check -s eq:0 -o match:"main, passed" -e ignore atf-run helper
756    mount | grep $(cat root) && atf_fail "Some file systems remain mounted"
757    atf_check -s eq:1 -o empty -e empty test -d $(cat root)/foo
758}
759
760atf_test_case cleanup_symlink
761cleanup_symlink_head()
762{
763    atf_set "descr" "Tests that the removal algorithm does not follow" \
764                    "symlinks, which may live in another device and thus" \
765                    "be treated as mount points"
766    atf_set "require.user" "root"
767}
768cleanup_symlink_body()
769{
770    ROOT="$(pwd)/root"; export ROOT
771
772    create_mount_helper helper <<EOF
773echo \$(pwd) >\${ROOT}
774atf_check -s eq:0 -o empty -e empty mkdir foo
775atf_check -s eq:0 -o empty -e empty mkdir foo/bar
776do_mount foo/bar
777atf_check -s eq:0 -o empty -e empty touch a
778atf_check -s eq:0 -o empty -e empty ln -s "\$(pwd)/a" foo/bar
779EOF
780    create_atffile helper
781    chmod +x helper
782
783    platform=$(uname)
784    case ${platform} in
785    Linux|FreeBSD|NetBSD|SunOS)
786        ;;
787    *)
788        # XXX Possibly specify in meta-data too.
789        atf_skip "Test unimplemented in this platform (${platform})"
790        ;;
791    esac
792
793    atf_check -s eq:0 -o match:"main, passed" -e ignore atf-run helper
794    mount | grep $(cat root) && atf_fail "Some file systems remain mounted"
795    atf_check -s eq:1 -o empty -e empty test -d $(cat root)/foo
796}
797
798atf_test_case require_arch
799require_arch_head()
800{
801    atf_set "descr" "Tests that atf-run validates the require.arch property"
802}
803require_arch_body()
804{
805    create_helper require_arch
806    create_atffile helper
807
808    echo "Checking for the real architecture"
809    arch=$(atf-config -t atf_arch)
810    atf_check -s eq:0 -o match:"${TESTCASE}, passed" -e ignore atf-run \
811        -v arch="${arch}" helper
812    atf_check -s eq:0 -o match:"${TESTCASE}, passed" -e ignore atf-run \
813        -v arch="foo ${arch}" helper
814    atf_check -s eq:0 -o match:"${TESTCASE}, passed" -e ignore atf-run \
815        -v arch="${arch} foo" helper
816
817    echo "Checking for a fictitious architecture"
818    arch=fictitious
819    export ATF_ARCH=fictitious
820    atf_check -s eq:0 -o match:"${TESTCASE}, passed" -e ignore atf-run \
821        -v arch="${arch}" helper
822    atf_check -s eq:0 -o match:"${TESTCASE}, passed" -e ignore atf-run \
823        -v arch="foo ${arch}" helper
824    atf_check -s eq:0 -o match:"${TESTCASE}, passed" -e ignore atf-run \
825        -v arch="${arch} foo" helper
826
827    echo "Triggering some failures"
828    atf_check -s eq:0 -o match:"${TESTCASE}, skipped, .*foo.*architecture" \
829        -e ignore atf-run -v arch="foo" helper
830    atf_check -s eq:0 \
831        -o match:"${TESTCASE}, skipped, .*foo bar.*architectures" -e ignore \
832        atf-run -v arch="foo bar" helper
833    atf_check -s eq:0 \
834        -o match:"${TESTCASE}, skipped, .*fictitiousxxx.*architecture" \
835        -e ignore atf-run -v arch="${arch}xxx" helper
836}
837
838atf_test_case require_config
839require_config_head()
840{
841    atf_set "descr" "Tests that atf-run validates the require.config property"
842}
843require_config_body()
844{
845    create_helper require_config
846    create_atffile helper
847
848    atf_check -s eq:0 -o match:"${TESTCASE}, skipped, .*var1.*not defined" \
849        -e ignore atf-run helper
850    atf_check -s eq:0 -o match:"${TESTCASE}, skipped, .*var2.*not defined" \
851        -e ignore atf-run -v var1=foo helper
852    atf_check -s eq:0 -o match:"${TESTCASE}, passed" -e ignore atf-run \
853        -v var1=a -v var2=' ' helper
854}
855
856atf_test_case require_machine
857require_machine_head()
858{
859    atf_set "descr" "Tests that atf-run validates the require.machine property"
860}
861require_machine_body()
862{
863    create_helper require_machine
864    create_atffile helper
865
866    echo "Checking for the real machine type"
867    machine=$(atf-config -t atf_machine)
868    atf_check -s eq:0 -o match:"${TESTCASE}, passed" -e ignore atf-run \
869        -v machine="${machine}" helper
870    atf_check -s eq:0 -o match:"${TESTCASE}, passed" -e ignore atf-run \
871        -v machine="foo ${machine}" helper
872    atf_check -s eq:0 -o match:"${TESTCASE}, passed" -e ignore atf-run \
873        -v machine="${machine} foo" helper
874
875    echo "Checking for a fictitious machine type"
876    machine=fictitious
877    export ATF_MACHINE=fictitious
878    atf_check -s eq:0 -o match:"${TESTCASE}, passed" -e ignore atf-run \
879        -v machine="${machine}" helper
880    atf_check -s eq:0 -o match:"${TESTCASE}, passed" -e ignore atf-run \
881        -v machine="foo ${machine}" helper
882    atf_check -s eq:0 -o match:"${TESTCASE}, passed" -e ignore atf-run \
883        -v machine="${machine} foo" helper
884
885    echo "Triggering some failures"
886    atf_check -s eq:0 -o match:"${TESTCASE}, skipped, .*foo.*machine type" \
887        -e ignore atf-run -v machine="foo" helper
888    atf_check -s eq:0 \
889        -o match:"${TESTCASE}, skipped, .*foo bar.*machine types" -e ignore \
890        atf-run -v machine="foo bar" helper
891    atf_check -s eq:0 \
892        -o match:"${TESTCASE}, skipped, .*fictitiousxxx.*machine type" \
893        -e ignore atf-run -v machine="${machine}xxx" helper
894}
895
896atf_test_case require_progs
897require_progs_head()
898{
899    atf_set "descr" "Tests that atf-run validates the require.progs property"
900}
901require_progs_body()
902{
903    create_helper require_progs
904    create_atffile helper
905
906    echo "Checking absolute paths"
907    atf_check -s eq:0 -o match:"${TESTCASE}, passed" -e ignore atf-run \
908        -v progs='/bin/cp' helper
909    atf_check -s eq:0 \
910        -o match:"${TESTCASE}, skipped, .*/bin/__non-existent__.*PATH" \
911        -e ignore atf-run -v progs='/bin/__non-existent__' helper
912
913    echo "Checking that relative paths are not allowed"
914    atf_check -s eq:1 \
915        -o match:"${TESTCASE}, failed, Relative paths.*not allowed.*bin/cp" \
916        -e ignore atf-run -v progs='bin/cp' helper
917
918    echo "Check plain file names, searching them in the PATH."
919    atf_check -s eq:0 -o match:"${TESTCASE}, passed" -e ignore atf-run \
920        -v progs='cp' helper
921    atf_check -s eq:0 \
922        -o match:"${TESTCASE}, skipped, .*__non-existent__.*PATH" -e ignore \
923        atf-run -v progs='__non-existent__' helper
924}
925
926atf_test_case require_user_root
927require_user_root_head()
928{
929    atf_set "descr" "Tests that atf-run validates the require.user property" \
930        "when it is set to 'root'"
931}
932require_user_root_body()
933{
934    create_helper require_user
935    create_atffile helper
936
937    if [ $(id -u) -eq 0 ]; then
938        exp=passed
939    else
940        exp=skipped
941    fi
942    atf_check -s eq:0 -o match:"${TESTCASE}, ${exp}" -e ignore atf-run \
943        -v user=root helper
944}
945
946atf_test_case require_user_unprivileged
947require_user_unprivileged_head()
948{
949    atf_set "descr" "Tests that atf-run validates the require.user property" \
950        "when it is set to 'root'"
951}
952require_user_unprivileged_body()
953{
954    create_helper require_user
955    create_atffile helper
956
957    if [ $(id -u) -eq 0 ]; then
958        exp=skipped
959    else
960        exp=passed
961    fi
962    atf_check -s eq:0 -o match:"${TESTCASE}, ${exp}" -e ignore atf-run \
963        -v user=unprivileged helper
964}
965
966atf_test_case require_user_bad
967require_user_bad_head()
968{
969    atf_set "descr" "Tests that atf-run validates the require.user property" \
970        "when it is set to 'root'"
971}
972require_user_bad_body()
973{
974    create_helper require_user
975    create_atffile helper
976
977    atf_check -s eq:1 -o match:"${TESTCASE}, failed, Invalid value.*foobar" \
978        -e ignore atf-run -v user=foobar helper
979}
980
981atf_test_case timeout
982timeout_head()
983{
984    atf_set "descr" "Tests that atf-run kills a test case that times out"
985}
986timeout_body()
987{
988    create_helper timeout
989    create_atffile helper
990
991    atf_check -s eq:1 \
992        -o match:"${TESTCASE}, failed, .*timed out after 1 second" -e ignore \
993        atf-run -v statedir=$(pwd) helper
994    if [ -f finished ]; then
995        atf_fail "Test case was not killed after time out"
996    fi
997}
998
999atf_test_case timeout_forkexit
1000timeout_forkexit_head()
1001{
1002    atf_set "descr" "Tests that atf-run deals gracefully with a test program" \
1003        "that forks, exits, but the child process hangs"
1004}
1005timeout_forkexit_body()
1006{
1007    create_helper timeout_forkexit
1008    create_atffile helper
1009
1010    atf_check -s eq:0 -o match:"${TESTCASE}, passed" -e ignore atf-run \
1011        -v statedir=$(pwd) helper
1012    test -f parent-finished || atf_fail "Parent did not exit as expected"
1013    test -f child-finished && atf_fail "Subprocess exited but it should have" \
1014        "been forcibly terminated" || true
1015}
1016
1017atf_test_case ignore_deprecated_use_fs
1018ignore_deprecated_use_fs_head()
1019{
1020    atf_set "descr" "Tests that atf-run ignores the deprecated use.fs property"
1021}
1022ignore_deprecated_use_fs_body()
1023{
1024    create_helper use_fs
1025    create_atffile helper
1026
1027    atf_check -s eq:0 -o ignore -e ignore atf-run helper
1028}
1029
1030atf_init_test_cases()
1031{
1032    atf_add_test_case config
1033    atf_add_test_case vflag
1034    atf_add_test_case atffile
1035    atf_add_test_case atffile_recursive
1036    atf_add_test_case expect
1037    atf_add_test_case fds
1038    atf_add_test_case mux_streams
1039    atf_add_test_case missing_results
1040    atf_add_test_case broken_results
1041    atf_add_test_case broken_tp_list
1042    atf_add_test_case zero_tcs
1043    atf_add_test_case exit_codes
1044    atf_add_test_case signaled
1045    atf_add_test_case hooks
1046    atf_add_test_case isolation_env
1047    atf_add_test_case isolation_home
1048    atf_add_test_case isolation_umask
1049    atf_add_test_case cleanup_pass
1050    atf_add_test_case cleanup_fail
1051    atf_add_test_case cleanup_skip
1052    atf_add_test_case cleanup_curdir
1053    atf_add_test_case cleanup_signal
1054    atf_add_test_case cleanup_mount
1055    atf_add_test_case cleanup_symlink
1056    atf_add_test_case require_arch
1057    atf_add_test_case require_config
1058    atf_add_test_case require_machine
1059    atf_add_test_case require_progs
1060    atf_add_test_case require_user_root
1061    atf_add_test_case require_user_unprivileged
1062    atf_add_test_case require_user_bad
1063    atf_add_test_case timeout
1064    atf_add_test_case timeout_forkexit
1065    atf_add_test_case ignore_deprecated_use_fs
1066}
1067
1068# vim: syntax=sh:expandtab:shiftwidth=4:softtabstop=4
1069