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