# # Automated Testing Framework (atf) # # Copyright (c) 2007, 2008, 2009, 2010 The NetBSD Foundation, Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND # CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, # INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE # GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER # IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN # IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # create_atffile() { cat >Atffile <>Atffile done } create_helper() { cp $(atf_get_srcdir)/misc_helpers helper create_atffile helper TESTCASE=${1}; export TESTCASE } create_helper_stdin() { # TODO: This really, really, really must use real test programs. cat >${1} <>${1} [ ${cnt} -lt ${2} ] && echo "echo" >>${1} cnt=$((${cnt} + 1)) done cat >>${1} <>${1} } create_mount_helper() { cat >${1} <>${1} cat >>${1} <etc/common.conf <.conf." cat >etc/atf.conf <.atf/common.conf <.conf." cat >.atf/atf.conf <etc/common.conf <>Atffile atf_check -s eq:0 -o match:'testvar: a value' -e ignore -x \ "ATF_CONFDIR=$(pwd)/etc atf-run helper" echo "Checking that defining 'testvar' trough the configuration" \ "file overrides the one in the Atffile." mkdir etc cat >etc/common.conf <> Atffile atf_check -s eq:1 -o ignore -e ignore -x "ATF_CONFDIR=$(pwd)/etc atf-run" echo "Checking that defining 'testvar' in the correct Atffile works." echo 'conf: testvar = "a value"' >>dir/Atffile atf_check -s eq:0 -o match:'testvar: a value' -e ignore -x \ "ATF_CONFDIR=$(pwd)/etc atf-run" } atf_test_case fds fds_head() { atf_set "descr" "Tests that all streams are properly captured" } fds_body() { create_helper fds atf_check -s eq:0 \ -o match:'^tc-so:msg1 to stdout$' \ -o match:'^tc-so:msg2 to stdout$' \ -o match:'^tc-se:msg1 to stderr$' \ -o match:'^tc-se:msg2 to stderr$' \ -e empty atf-run } atf_test_case mux_streams mux_streams_head() { atf_set "descr" "Tests for a race condition in stream multiplexing" } mux_streams_body() { create_helper mux_streams for i in 1 2 3 4 5; do echo "Attempt ${i}" atf_check -s eq:0 -o match:'stdout 9999' -o match:'stderr 9999' atf-run done } atf_test_case expect expect_head() { atf_set "descr" "Tests the processing of test case results and the" \ "expect features" } expect_body() { ln -s "$(atf_get_srcdir)/expect_helpers" . create_atffile expect_helpers atf_check -s eq:1 \ -o match:'death_and_exit, expected_death' \ -o match:'death_and_signal, expected_death' \ -o match:'death_but_pass, failed' \ -o match:'exit_any_and_exit, expected_exit' \ -o match:'exit_but_pass, failed' \ -o match:'exit_code_and_exit, expected_exit' \ -o match:'fail_and_fail_check, expected_failure' \ -o match:'fail_and_fail_requirement, expected_failure' \ -o match:'fail_but_pass, failed' \ -o match:'pass_and_pass, passed' \ -o match:'pass_but_fail_check, failed' \ -o match:'pass_but_fail_requirement, failed' \ -o match:'signal_any_and_signal, expected_signal' \ -o match:'signal_but_pass, failed' \ -o match:'signal_no_and_signal, expected_signal' \ -o match:'timeout_and_hang, expected_timeout' \ -o match:'timeout_but_pass, failed' \ -e empty atf-run } atf_test_case missing_results missing_results_head() { atf_set "descr" "Ensures that atf-run correctly handles test cases that " \ "do not create the results file" } missing_results_body() { create_helper_stdin helper 1 <\${resfile} echo 'line 2' >>\${resfile} exit 0 EOF chmod +x helper create_atffile helper atf_check -s eq:1 -o match:'^tc-end: tc1, .*line 1.*line 2' -e empty atf-run } atf_test_case broken_tp_list broken_tp_list_head() { atf_set "descr" "Ensures that atf-run reports test programs that" \ "provide a bogus test case list" } broken_tp_list_body() { cat >helper <\${resfile} exit 0 EOF chmod +x helper create_atffile helper atf_check -s eq:1 \ -o match:'^tc-end: tc1,.*exited successfully.*reported failure' \ -e empty atf-run } atf_test_case signaled signaled_head() { atf_set "descr" "Ensures that atf-run reports test program's crashes" \ "correctly regardless of their actual results" } signaled_body() { create_helper_stdin helper 2 <\${resfile} case \${testcase} in tc1) ;; tc2) echo "Killing myself!" ; kill -9 \$\$ ;; esac EOF chmod +x helper create_atffile helper atf_check -s eq:1 -o match:'^tc-end: tc2,.*received signal 9' \ -e empty atf-run } atf_test_case hooks hooks_head() { atf_set "descr" "Checks that the default hooks work and that they" \ "can be overriden by the user" } hooks_body() { cp $(atf_get_srcdir)/pass_helper helper create_atffile helper mkdir atf mkdir .atf echo "Checking default hooks" atf_check -s eq:0 -o match:'^info: time.start, ' \ -o match:'^info: time.end, ' -e empty -x \ "ATF_CONFDIR=$(pwd)/atf atf-run" echo "Checking the system-wide info_start hook" cat >atf/atf-run.hooks <.atf/atf-run.hooks <atf/atf-run.hooks <.atf/atf-run.hooks <\${ROOT} mkdir foo mkdir foo/bar mkdir foo/bar/mnt do_mount foo/bar/mnt mkdir foo/baz do_mount foo/baz mkdir foo/baz/foo mkdir foo/baz/foo/bar do_mount foo/baz/foo/bar EOF create_atffile helper chmod +x helper platform=$(uname) case ${platform} in Linux|FreeBSD|NetBSD|SunOS) ;; *) # XXX Possibly specify in meta-data too. atf_skip "Test unimplemented in this platform (${platform})" ;; esac atf_check -s eq:0 -o match:"main, passed" -e ignore atf-run helper mount | grep $(cat root) && atf_fail "Some file systems remain mounted" atf_check -s eq:1 -o empty -e empty test -d $(cat root)/foo } atf_test_case cleanup_symlink cleanup_symlink_head() { atf_set "descr" "Tests that the removal algorithm does not follow" \ "symlinks, which may live in another device and thus" \ "be treated as mount points" atf_set "require.user" "root" } cleanup_symlink_body() { ROOT="$(pwd)/root"; export ROOT create_mount_helper helper <\${ROOT} atf_check -s eq:0 -o empty -e empty mkdir foo atf_check -s eq:0 -o empty -e empty mkdir foo/bar do_mount foo/bar atf_check -s eq:0 -o empty -e empty touch a atf_check -s eq:0 -o empty -e empty ln -s "\$(pwd)/a" foo/bar EOF create_atffile helper chmod +x helper platform=$(uname) case ${platform} in Linux|FreeBSD|NetBSD|SunOS) ;; *) # XXX Possibly specify in meta-data too. atf_skip "Test unimplemented in this platform (${platform})" ;; esac atf_check -s eq:0 -o match:"main, passed" -e ignore atf-run helper mount | grep $(cat root) && atf_fail "Some file systems remain mounted" atf_check -s eq:1 -o empty -e empty test -d $(cat root)/foo } atf_test_case require_arch require_arch_head() { atf_set "descr" "Tests that atf-run validates the require.arch property" } require_arch_body() { create_helper require_arch create_atffile helper echo "Checking for the real architecture" arch=$(atf-config -t atf_arch) atf_check -s eq:0 -o match:"${TESTCASE}, passed" -e ignore atf-run \ -v arch="${arch}" helper atf_check -s eq:0 -o match:"${TESTCASE}, passed" -e ignore atf-run \ -v arch="foo ${arch}" helper atf_check -s eq:0 -o match:"${TESTCASE}, passed" -e ignore atf-run \ -v arch="${arch} foo" helper echo "Checking for a fictitious architecture" arch=fictitious export ATF_ARCH=fictitious atf_check -s eq:0 -o match:"${TESTCASE}, passed" -e ignore atf-run \ -v arch="${arch}" helper atf_check -s eq:0 -o match:"${TESTCASE}, passed" -e ignore atf-run \ -v arch="foo ${arch}" helper atf_check -s eq:0 -o match:"${TESTCASE}, passed" -e ignore atf-run \ -v arch="${arch} foo" helper echo "Triggering some failures" atf_check -s eq:0 -o match:"${TESTCASE}, skipped, .*foo.*architecture" \ -e ignore atf-run -v arch="foo" helper atf_check -s eq:0 \ -o match:"${TESTCASE}, skipped, .*foo bar.*architectures" -e ignore \ atf-run -v arch="foo bar" helper atf_check -s eq:0 \ -o match:"${TESTCASE}, skipped, .*fictitiousxxx.*architecture" \ -e ignore atf-run -v arch="${arch}xxx" helper } atf_test_case require_config require_config_head() { atf_set "descr" "Tests that atf-run validates the require.config property" } require_config_body() { create_helper require_config create_atffile helper atf_check -s eq:0 -o match:"${TESTCASE}, skipped, .*var1.*not defined" \ -e ignore atf-run helper atf_check -s eq:0 -o match:"${TESTCASE}, skipped, .*var2.*not defined" \ -e ignore atf-run -v var1=foo helper atf_check -s eq:0 -o match:"${TESTCASE}, passed" -e ignore atf-run \ -v var1=a -v var2=' ' helper } atf_test_case require_machine require_machine_head() { atf_set "descr" "Tests that atf-run validates the require.machine property" } require_machine_body() { create_helper require_machine create_atffile helper echo "Checking for the real machine type" machine=$(atf-config -t atf_machine) atf_check -s eq:0 -o match:"${TESTCASE}, passed" -e ignore atf-run \ -v machine="${machine}" helper atf_check -s eq:0 -o match:"${TESTCASE}, passed" -e ignore atf-run \ -v machine="foo ${machine}" helper atf_check -s eq:0 -o match:"${TESTCASE}, passed" -e ignore atf-run \ -v machine="${machine} foo" helper echo "Checking for a fictitious machine type" machine=fictitious export ATF_MACHINE=fictitious atf_check -s eq:0 -o match:"${TESTCASE}, passed" -e ignore atf-run \ -v machine="${machine}" helper atf_check -s eq:0 -o match:"${TESTCASE}, passed" -e ignore atf-run \ -v machine="foo ${machine}" helper atf_check -s eq:0 -o match:"${TESTCASE}, passed" -e ignore atf-run \ -v machine="${machine} foo" helper echo "Triggering some failures" atf_check -s eq:0 -o match:"${TESTCASE}, skipped, .*foo.*machine type" \ -e ignore atf-run -v machine="foo" helper atf_check -s eq:0 \ -o match:"${TESTCASE}, skipped, .*foo bar.*machine types" -e ignore \ atf-run -v machine="foo bar" helper atf_check -s eq:0 \ -o match:"${TESTCASE}, skipped, .*fictitiousxxx.*machine type" \ -e ignore atf-run -v machine="${machine}xxx" helper } atf_test_case require_progs require_progs_head() { atf_set "descr" "Tests that atf-run validates the require.progs property" } require_progs_body() { create_helper require_progs create_atffile helper echo "Checking absolute paths" atf_check -s eq:0 -o match:"${TESTCASE}, passed" -e ignore atf-run \ -v progs='/bin/cp' helper atf_check -s eq:0 \ -o match:"${TESTCASE}, skipped, .*/bin/__non-existent__.*PATH" \ -e ignore atf-run -v progs='/bin/__non-existent__' helper echo "Checking that relative paths are not allowed" atf_check -s eq:1 \ -o match:"${TESTCASE}, failed, Relative paths.*not allowed.*bin/cp" \ -e ignore atf-run -v progs='bin/cp' helper echo "Check plain file names, searching them in the PATH." atf_check -s eq:0 -o match:"${TESTCASE}, passed" -e ignore atf-run \ -v progs='cp' helper atf_check -s eq:0 \ -o match:"${TESTCASE}, skipped, .*__non-existent__.*PATH" -e ignore \ atf-run -v progs='__non-existent__' helper } atf_test_case require_user_root require_user_root_head() { atf_set "descr" "Tests that atf-run validates the require.user property" \ "when it is set to 'root'" } require_user_root_body() { create_helper require_user create_atffile helper if [ $(id -u) -eq 0 ]; then exp=passed else exp=skipped fi atf_check -s eq:0 -o match:"${TESTCASE}, ${exp}" -e ignore atf-run \ -v user=root helper } atf_test_case require_user_unprivileged require_user_unprivileged_head() { atf_set "descr" "Tests that atf-run validates the require.user property" \ "when it is set to 'root'" } require_user_unprivileged_body() { create_helper require_user create_atffile helper if [ $(id -u) -eq 0 ]; then exp=skipped else exp=passed fi atf_check -s eq:0 -o match:"${TESTCASE}, ${exp}" -e ignore atf-run \ -v user=unprivileged helper } atf_test_case require_user_bad require_user_bad_head() { atf_set "descr" "Tests that atf-run validates the require.user property" \ "when it is set to 'root'" } require_user_bad_body() { create_helper require_user create_atffile helper atf_check -s eq:1 -o match:"${TESTCASE}, failed, Invalid value.*foobar" \ -e ignore atf-run -v user=foobar helper } atf_test_case timeout timeout_head() { atf_set "descr" "Tests that atf-run kills a test case that times out" } timeout_body() { create_helper timeout create_atffile helper atf_check -s eq:1 \ -o match:"${TESTCASE}, failed, .*timed out after 1 second" -e ignore \ atf-run -v statedir=$(pwd) helper if [ -f finished ]; then atf_fail "Test case was not killed after time out" fi } atf_test_case timeout_forkexit timeout_forkexit_head() { atf_set "descr" "Tests that atf-run deals gracefully with a test program" \ "that forks, exits, but the child process hangs" } timeout_forkexit_body() { create_helper timeout_forkexit create_atffile helper atf_check -s eq:0 -o match:"${TESTCASE}, passed" -e ignore atf-run \ -v statedir=$(pwd) helper test -f parent-finished || atf_fail "Parent did not exit as expected" test -f child-finished && atf_fail "Subprocess exited but it should have" \ "been forcibly terminated" || true } atf_test_case ignore_deprecated_use_fs ignore_deprecated_use_fs_head() { atf_set "descr" "Tests that atf-run ignores the deprecated use.fs property" } ignore_deprecated_use_fs_body() { create_helper use_fs create_atffile helper atf_check -s eq:0 -o ignore -e ignore atf-run helper } atf_init_test_cases() { atf_add_test_case config atf_add_test_case vflag atf_add_test_case atffile atf_add_test_case atffile_recursive atf_add_test_case expect atf_add_test_case fds atf_add_test_case mux_streams atf_add_test_case missing_results atf_add_test_case broken_results atf_add_test_case broken_tp_list atf_add_test_case zero_tcs atf_add_test_case exit_codes atf_add_test_case signaled atf_add_test_case hooks atf_add_test_case isolation_env atf_add_test_case isolation_home atf_add_test_case isolation_umask atf_add_test_case cleanup_pass atf_add_test_case cleanup_fail atf_add_test_case cleanup_skip atf_add_test_case cleanup_curdir atf_add_test_case cleanup_signal atf_add_test_case cleanup_mount atf_add_test_case cleanup_symlink atf_add_test_case require_arch atf_add_test_case require_config atf_add_test_case require_machine atf_add_test_case require_progs atf_add_test_case require_user_root atf_add_test_case require_user_unprivileged atf_add_test_case require_user_bad atf_add_test_case timeout atf_add_test_case timeout_forkexit atf_add_test_case ignore_deprecated_use_fs } # vim: syntax=sh:expandtab:shiftwidth=4:softtabstop=4