summaryrefslogtreecommitdiffstats
path: root/contrib/atf/atf-sh
diff options
context:
space:
mode:
authorngie <ngie@FreeBSD.org>2014-12-21 08:30:18 +0000
committerngie <ngie@FreeBSD.org>2014-12-21 08:30:18 +0000
commitdc3ad5131fa6525673d58aa537f9d67ba69edb94 (patch)
tree1473124a62111de8a694012ddb628f25f249137d /contrib/atf/atf-sh
parent1a3934911c5c7b282bc36336bafe16e321f63922 (diff)
downloadFreeBSD-src-dc3ad5131fa6525673d58aa537f9d67ba69edb94.zip
FreeBSD-src-dc3ad5131fa6525673d58aa537f9d67ba69edb94.tar.gz
MFC r273929:
r273929 (by jmmv): MFV: Import atf-0.21.
Diffstat (limited to 'contrib/atf/atf-sh')
-rw-r--r--contrib/atf/atf-sh/atf-check.135
-rw-r--r--contrib/atf/atf-sh/atf-check.cpp24
-rw-r--r--contrib/atf/atf-sh/atf-check_test.sh26
-rw-r--r--contrib/atf/atf-sh/atf-sh.164
-rw-r--r--contrib/atf/atf-sh/atf-sh.3372
-rw-r--r--contrib/atf/atf-sh/atf-sh.cpp59
-rw-r--r--contrib/atf/atf-sh/atf_check_test.sh4
-rw-r--r--contrib/atf/atf-sh/config_test.sh4
-rw-r--r--contrib/atf/atf-sh/integration_test.sh89
-rw-r--r--contrib/atf/atf-sh/libatf-sh.subr23
-rw-r--r--contrib/atf/atf-sh/misc_helpers.sh4
-rw-r--r--contrib/atf/atf-sh/normalize_test.sh4
-rw-r--r--contrib/atf/atf-sh/tc_test.sh4
-rw-r--r--contrib/atf/atf-sh/tp_test.sh4
14 files changed, 583 insertions, 133 deletions
diff --git a/contrib/atf/atf-sh/atf-check.1 b/contrib/atf/atf-sh/atf-check.1
index 66f9318..a3bd379 100644
--- a/contrib/atf/atf-sh/atf-check.1
+++ b/contrib/atf/atf-sh/atf-check.1
@@ -1,6 +1,3 @@
-.\"
-.\" Automated Testing Framework (atf)
-.\"
.\" Copyright (c) 2008 The NetBSD Foundation, Inc.
.\" All rights reserved.
.\"
@@ -25,8 +22,7 @@
.\" 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.
-.\"
-.Dd March 2, 2014
+.Dd October 5, 2014
.Dt ATF-CHECK 1
.Os
.Sh NAME
@@ -39,13 +35,16 @@
.Op Fl e Ar action:arg ...
.Op Fl x
.Ar command
-.Nm
-.Fl h
.Sh DESCRIPTION
.Nm
executes a given command and analyzes its results, including
exit code, stdout and stderr.
.Pp
+.Em Test cases must use
+.Em Xr atf-sh 3 Ns ' Ns s
+.Em Nm atf_check
+.Em builtin function instead of calling this utility directly.
+.Pp
In the first synopsis form,
.Nm
will execute the provided command and apply checks specified
@@ -67,8 +66,6 @@ will print information about all supported options and their purpose.
.Pp
The following options are available:
.Bl -tag -width XqualXvalueXX
-.It Fl h
-Shows a short summary of all available options and their purpose.
.It Fl s Ar qual:value
Analyzes termination status.
Must be one of:
@@ -133,21 +130,31 @@ Path to the system shell to be used when the
is given to run commands.
.El
.Sh EXAMPLES
+The following are sample invocations from within a test case.
+Note that we use the
+.Nm atf_check
+function provided by
+.Xr atf-sh 3
+instead of executing
+.Nm
+directly:
.Bd -literal -offset indent
# Exit code 0, nothing on stdout/stderr
-atf-check 'true'
+atf_check 'true'
# Typical usage if failure is expected
-atf-check -s not-exit:0 'false'
+atf_check -s not-exit:0 'false'
# Checking stdout/stderr
echo foobar >expout
-atf-check -o file:expout -e inline:"xx\etyy\en" \e
+atf_check -o file:expout -e inline:"xx\etyy\en" \e
'echo foobar ; printf "xx\etyy\en" >&2'
# Checking for a crash
-atf-check -s signal:sigsegv my_program
+atf_check -s signal:sigsegv my_program
# Combined checks
-atf-check -o match:foo -o not-match:bar echo foo baz
+atf_check -o match:foo -o not-match:bar echo foo baz
.Ed
+.Sh SEE ALSO
+.Xr atf-sh 1
diff --git a/contrib/atf/atf-sh/atf-check.cpp b/contrib/atf/atf-sh/atf-check.cpp
index b08c020..866b7bb 100644
--- a/contrib/atf/atf-sh/atf-check.cpp
+++ b/contrib/atf/atf-sh/atf-check.cpp
@@ -1,6 +1,3 @@
-//
-// Automated Testing Framework (atf)
-//
// Copyright (c) 2008 The NetBSD Foundation, Inc.
// All rights reserved.
//
@@ -25,7 +22,6 @@
// 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.
-//
extern "C" {
#include <sys/types.h>
@@ -48,10 +44,9 @@ extern "C" {
#include <utility>
#include "atf-c++/check.hpp"
-#include "atf-c++/config.hpp"
-
#include "atf-c++/detail/application.hpp"
#include "atf-c++/detail/auto_array.hpp"
+#include "atf-c++/detail/env.hpp"
#include "atf-c++/detail/exceptions.hpp"
#include "atf-c++/detail/fs.hpp"
#include "atf-c++/detail/process.hpp"
@@ -112,17 +107,20 @@ class temp_file : public std::ostream {
int m_fd;
public:
- temp_file(const atf::fs::path& p) :
+ temp_file(const char* pattern) :
std::ostream(NULL),
m_fd(-1)
{
- atf::auto_array< char > buf(new char[p.str().length() + 1]);
- std::strcpy(buf.get(), p.c_str());
+ const atf::fs::path file = atf::fs::path(
+ atf::env::get("TMPDIR", "/tmp")) / pattern;
+
+ atf::auto_array< char > buf(new char[file.str().length() + 1]);
+ std::strcpy(buf.get(), file.c_str());
m_fd = ::mkstemp(buf.get());
if (m_fd == -1)
throw atf::system_error("atf_check::temp_file::temp_file(" +
- p.str() + ")", "mkstemp(3) failed",
+ file.str() + ")", "mkstemp(3) failed",
errno);
m_path.reset(new atf::fs::path(buf.get()));
@@ -350,7 +348,7 @@ execute_with_shell(char* const* argv)
const std::string cmd = flatten_argv(argv);
const char* sh_argv[4];
- sh_argv[0] = atf::config::get("atf_shell").c_str();
+ sh_argv[0] = atf::env::get("ATF_SHELL", ATF_SHELL).c_str();
sh_argv[1] = "-c";
sh_argv[2] = cmd.c_str();
sh_argv[3] = NULL;
@@ -623,9 +621,7 @@ run_output_check(const output_check oc, const atf::fs::path& path,
} else if (oc.type == oc_ignore) {
result = true;
} else if (oc.type == oc_inline) {
- atf::fs::path path2 = atf::fs::path(atf::config::get("atf_workdir"))
- / "inline.XXXXXX";
- temp_file temp(path2);
+ temp_file temp("atf-check.XXXXXX");
temp.write(decode(oc.value));
temp.close();
diff --git a/contrib/atf/atf-sh/atf-check_test.sh b/contrib/atf/atf-sh/atf-check_test.sh
index 7319a2b..9542dfb 100644
--- a/contrib/atf/atf-sh/atf-check_test.sh
+++ b/contrib/atf/atf-sh/atf-check_test.sh
@@ -1,6 +1,3 @@
-#
-# Automated Testing Framework (atf)
-#
# Copyright (c) 2008 The NetBSD Foundation, Inc.
# All rights reserved.
#
@@ -25,7 +22,6 @@
# 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.
-#
# The Atf_Check and Atf-Shell variables are set by atf-sh.
@@ -211,16 +207,7 @@ oflag_inline_body()
h_pass "echo foo bar" -o inline:"foo bar\n"
h_pass "printf 'foo bar'" -o inline:"foo bar"
h_pass "printf '\t\n\t\n'" -o inline:"\t\n\t\n"
- # XXX Ugly hack to workaround the lack of \e in FreeBSD. Also, \e doesn't
- # seem to work as expected in Linux. Look for a nicer solution.
- case $(uname) in
- Darwin|FreeBSD|Linux)
- h_pass "printf '\a\b\f\n\r\t\v'" -o inline:"\a\b\f\n\r\t\v"
- ;;
- *)
- h_pass "printf '\a\b\e\f\n\r\t\v'" -o inline:"\a\b\e\f\n\r\t\v"
- ;;
- esac
+ h_pass "printf '\a\b\033\f\n\r\t\v'" -o inline:"\a\b\e\f\n\r\t\v"
h_pass "printf '\011\022\033\012'" -o inline:"\011\022\033\012"
h_fail "echo foo bar" -o inline:"foo bar"
@@ -331,16 +318,7 @@ eflag_inline_body()
h_pass "echo foo bar 1>&2" -e inline:"foo bar\n"
h_pass "printf 'foo bar' 1>&2" -e inline:"foo bar"
h_pass "printf '\t\n\t\n' 1>&2" -e inline:"\t\n\t\n"
- # XXX Ugly hack to workaround the lack of \e in FreeBSD. Also, \e doesn't
- # seem to work as expected in Linux. Look for a nicer solution.
- case $(uname) in
- Darwin|FreeBSD|Linux)
- h_pass "printf '\a\b\f\n\r\t\v' 1>&2" -e inline:"\a\b\f\n\r\t\v"
- ;;
- *)
- h_pass "printf '\a\b\e\f\n\r\t\v' 1>&2" -e inline:"\a\b\e\f\n\r\t\v"
- ;;
- esac
+ h_pass "printf '\a\b\033\f\n\r\t\v' 1>&2" -e inline:"\a\b\e\f\n\r\t\v"
h_pass "printf '\011\022\033\012' 1>&2" -e inline:"\011\022\033\012"
h_fail "echo foo bar 1>&2" -e inline:"foo bar"
diff --git a/contrib/atf/atf-sh/atf-sh.1 b/contrib/atf/atf-sh/atf-sh.1
index ad77f04..ac4a135 100644
--- a/contrib/atf/atf-sh/atf-sh.1
+++ b/contrib/atf/atf-sh/atf-sh.1
@@ -1,6 +1,3 @@
-.\"
-.\" Automated Testing Framework (atf)
-.\"
.\" Copyright (c) 2010 The NetBSD Foundation, Inc.
.\" All rights reserved.
.\"
@@ -25,24 +22,22 @@
.\" 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.
-.\"
-.Dd March 2, 2014
+.Dd September 27, 2014
.Dt ATF-SH 1
.Os
.Sh NAME
.Nm atf-sh
+.Op Fl s Ar shell
.Nd interpreter for shell-based test programs
.Sh SYNOPSIS
.Nm
.Ar script
-.Nm
-.Fl h
.Sh DESCRIPTION
.Nm
is an interpreter that runs the test program given in
.Ar script
after loading the
-.Xr atf-sh-api 3
+.Xr atf-sh 3
library.
.Pp
.Nm
@@ -51,25 +46,62 @@ the system-wide shell defined by
.Va ATF_SHELL .
.Nm
executes the interpreter, loads the
-.Xr atf-sh-api 3
+.Xr atf-sh 3
library and then runs the script.
+You must consider
+.Nm atf-sh
+to be a POSIX shell by default and thus should not use any non-standard
+extensions.
.Pp
+The following options are available:
+.Bl -tag -width XsXshellXXX
+.It Fl s Ar shell
+Specifies the shell to use instead of the value provided by
+.Va ATF_SHELL .
+.El
+.Sh ENVIRONMENT
+.Bl -tag -width ATFXLIBEXECDIRXX -compact
+.It Va ATF_LIBEXECDIR
+Overrides the builtin directory where
+.Nm
+is located.
+Should not be overridden other than for testing purposes.
+.It Va ATF_PKGDATADIR
+Overrides the builtin directory where
+.Pa libatf-sh.subr
+is located.
+Should not be overridden other than for testing purposes.
+.It Va ATF_SHELL
+Path to the system shell to be used in the generated scripts.
+Scripts must not rely on this variable being set to select a specific
+interpreter.
+.El
+.Sh EXAMPLES
Scripts using
-.Xr atf-sh-api 3
+.Xr atf-sh 3
should start with:
.Bd -literal -offset indent
#! /usr/bin/env atf-sh
.Ed
.Pp
-The following options are available:
-.Bl -tag -width XhXX
-.It Fl h
-Shows a short summary of all available options and their purpose.
-.El
+Alternatively, if you want to explicitly choose a shell interpreter, you cannot
+rely on
+.Xr env 1
+to find
+.Nm .
+Instead, you have to hardcode the path to
+.Nm
+in the script and then use the
+.Fl s
+option afterwards as a
+.Em single parameter :
+.Bd -literal -offset indent
+#! /path/to/bin/atf-sh -s/bin/bash
+.Ed
.Sh ENVIRONMENT
.Bl -tag -width ATFXSHELLXX -compact
.It Va ATF_SHELL
Path to the system shell to be used in the generated scripts.
.El
.Sh SEE ALSO
-.Xr atf-sh-api 3
+.Xr atf-sh 3
diff --git a/contrib/atf/atf-sh/atf-sh.3 b/contrib/atf/atf-sh/atf-sh.3
new file mode 100644
index 0000000..be56539
--- /dev/null
+++ b/contrib/atf/atf-sh/atf-sh.3
@@ -0,0 +1,372 @@
+.\" Copyright (c) 2008 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.
+.Dd October 13, 2014
+.Dt ATF-SH 3
+.Os
+.Sh NAME
+.Nm atf_add_test_case ,
+.Nm atf_check ,
+.Nm atf_check_equal ,
+.Nm atf_config_get ,
+.Nm atf_config_has ,
+.Nm atf_expect_death ,
+.Nm atf_expect_exit ,
+.Nm atf_expect_fail ,
+.Nm atf_expect_pass ,
+.Nm atf_expect_signal ,
+.Nm atf_expect_timeout ,
+.Nm atf_fail ,
+.Nm atf_get ,
+.Nm atf_get_srcdir ,
+.Nm atf_pass ,
+.Nm atf_require_prog ,
+.Nm atf_set ,
+.Nm atf_skip ,
+.Nm atf_test_case
+.Nd POSIX shell API to write ATF-based test programs
+.Sh SYNOPSIS
+.Nm atf_add_test_case
+.Qq name
+.Nm atf_check
+.Qq command
+.Nm atf_check_equal
+.Qq expected_expression
+.Qq actual_expression
+.Nm atf_config_get
+.Qq var_name
+.Nm atf_config_has
+.Qq var_name
+.Nm atf_expect_death
+.Qq reason
+.Qq ...
+.Nm atf_expect_exit
+.Qq exitcode
+.Qq reason
+.Qq ...
+.Nm atf_expect_fail
+.Qq reason
+.Qq ...
+.Nm atf_expect_pass
+.Qq
+.Nm atf_expect_signal
+.Qq signo
+.Qq reason
+.Qq ...
+.Nm atf_expect_timeout
+.Qq reason
+.Qq ...
+.Nm atf_fail
+.Qq reason
+.Nm atf_get
+.Qq var_name
+.Nm atf_get_srcdir
+.Nm atf_pass
+.Nm atf_require_prog
+.Qq prog_name
+.Nm atf_set
+.Qq var_name
+.Qq value
+.Nm atf_skip
+.Qq reason
+.Nm atf_test_case
+.Qq name
+.Qq cleanup
+.Sh DESCRIPTION
+ATF
+provides a simple but powerful interface to easily write test programs in
+the POSIX shell language.
+These are extremely helpful given that they are trivial to write due to the
+language simplicity and the great deal of available external tools, so they
+are often ideal to test other applications at the user level.
+.Pp
+Test programs written using this library must be run using the
+.Xr atf-sh 1
+interpreter by putting the following on their very first line:
+.Bd -literal -offset indent
+#! /usr/bin/env atf-sh
+.Ed
+.Pp
+Shell-based test programs always follow this template:
+.Bd -literal -offset indent
+atf_test_case tc1
+tc1_head() {
+ ... first test case's header ...
+}
+tc1_body() {
+ ... first test case's body ...
+}
+
+atf_test_case tc2 cleanup
+tc2_head() {
+ ... second test case's header ...
+}
+tc2_body() {
+ ... second test case's body ...
+}
+tc2_cleanup() {
+ ... second test case's cleanup ...
+}
+
+.Ns ... additional test cases ...
+
+atf_init_test_cases() {
+ atf_add_test_case tc1
+ atf_add_test_case tc2
+ ... add additional test cases ...
+}
+.Ed
+.Ss Definition of test cases
+Test cases have an identifier and are composed of three different parts:
+the header, the body and an optional cleanup routine, all of which are
+described in
+.Xr atf-test-case 4 .
+To define test cases, one can use the
+.Nm atf_test_case
+function, which takes a first parameter specifiying the test case's
+name and instructs the library to set things up to accept it as a valid
+test case.
+The second parameter is optional and, if provided, must be
+.Sq cleanup ;
+providing this parameter allows defining a cleanup routine for the test
+case.
+It is important to note that this function
+.Em does not
+set the test case up for execution when the program is run.
+In order to do so, a later registration is needed through the
+.Nm atf_add_test_case
+function detailed in
+.Sx Program initialization .
+.Pp
+Later on, one must define the three parts of the body by providing two
+or three functions (remember that the cleanup routine is optional).
+These functions are named after the test case's identifier, and are
+.Nm \*(Ltid\*(Gt_head ,
+.Nm \*(Ltid\*(Gt_body
+and
+.Nm \*(Ltid\*(Gt_cleanup .
+None of these take parameters when executed.
+.Ss Program initialization
+The test program must define an
+.Nm atf_init_test_cases
+function, which is in charge of registering the test cases that will be
+executed at run time by using the
+.Nm atf_add_test_case
+function, which takes the name of a test case as its single parameter.
+This main function should not do anything else, except maybe sourcing
+auxiliary source files that define extra variables and functions.
+.Ss Configuration variables
+The test case has read-only access to the current configuration variables
+through the
+.Nm atf_config_has
+and
+.Nm atf_config_get
+methods.
+The former takes a single parameter specifying a variable name and returns
+a boolean indicating whether the variable is defined or not.
+The latter can take one or two parameters.
+If it takes only one, it specifies the variable from which to get the
+value, and this variable must be defined.
+If it takes two, the second one specifies a default value to be returned
+if the variable is not available.
+.Ss Access to the source directory
+It is possible to get the path to the test case's source directory from
+anywhere in the test program by using the
+.Nm atf_get_srcdir
+function.
+It is interesting to note that this can be used inside
+.Nm atf_init_test_cases
+to silently include additional helper files from the source directory.
+.Ss Requiring programs
+Aside from the
+.Va require.progs
+meta-data variable available in the header only, one can also check for
+additional programs in the test case's body by using the
+.Nm atf_require_prog
+function, which takes the base name or full path of a single binary.
+Relative paths are forbidden.
+If it is not found, the test case will be automatically skipped.
+.Ss Test case finalization
+The test case finalizes either when the body reaches its end, at which
+point the test is assumed to have
+.Em passed ,
+or at any explicit call to
+.Nm atf_pass ,
+.Nm atf_fail
+or
+.Nm atf_skip .
+These three functions terminate the execution of the test case immediately.
+The cleanup routine will be processed afterwards in a completely automated
+way, regardless of the test case's termination reason.
+.Pp
+.Nm atf_pass
+does not take any parameters.
+.Nm atf_fail
+and
+.Nm atf_skip
+take a single string parameter that describes why the test case failed or
+was skipped, respectively.
+It is very important to provide a clear error message in both cases so that
+the user can quickly know why the test did not pass.
+.Ss Expectations
+Everything explained in the previous section changes when the test case
+expectations are redefined by the programmer.
+.Pp
+Each test case has an internal state called
+.Sq expect
+that describes what the test case expectations are at any point in time.
+The value of this property can change during execution by any of:
+.Bl -tag -width indent
+.It Nm atf_expect_death Qo reason Qc Qo ... Qc
+Expects the test case to exit prematurely regardless of the nature of the
+exit.
+.It Nm atf_expect_exit Qo exitcode Qc Qo reason Qc Qo ... Qc
+Expects the test case to exit cleanly.
+If
+.Va exitcode
+is not
+.Sq -1 ,
+the runtime engine will validate that the exit code of the test case
+matches the one provided in this call.
+Otherwise, the exact value will be ignored.
+.It Nm atf_expect_fail Qo reason Qc
+Any failure raised in this mode is recorded, but such failures do not report
+the test case as failed; instead, the test case finalizes cleanly and is
+reported as
+.Sq expected failure ;
+this report includes the provided
+.Fa reason
+as part of it.
+If no error is raised while running in this mode, then the test case is
+reported as
+.Sq failed .
+.Pp
+This mode is useful to reproduce actual known bugs in tests.
+Whenever the developer fixes the bug later on, the test case will start
+reporting a failure, signaling the developer that the test case must be
+adjusted to the new conditions.
+In this situation, it is useful, for example, to set
+.Fa reason
+as the bug number for tracking purposes.
+.It Nm atf_expect_pass
+This is the normal mode of execution.
+In this mode, any failure is reported as such to the user and the test case
+is marked as
+.Sq failed .
+.It Nm atf_expect_signal Qo signo Qc Qo reason Qc Qo ... Qc
+Expects the test case to terminate due to the reception of a signal.
+If
+.Va signo
+is not
+.Sq -1 ,
+the runtime engine will validate that the signal that terminated the test
+case matches the one provided in this call.
+Otherwise, the exact value will be ignored.
+.It Nm atf_expect_timeout Qo reason Qc Qo ... Qc
+Expects the test case to execute for longer than its timeout.
+.El
+.Ss Helper functions for common checks
+.Bl -tag -width indent
+.It Nm atf_check Qo [options] Qc Qo command Qc Qo [args] Qc
+Executes a command, performs checks on its exit code and its output, and
+fails the test case if any of the checks is not successful.
+This function is particularly useful in integration tests that verify the
+correct functioning of a binary.
+.Pp
+Internally, this function is just a wrapper over the
+.Xr atf-check 1
+tool (whose manual page provides all details on the calling syntax).
+You should always use the
+.Nm atf_check
+function instead of the
+.Xr atf-check 1
+tool in your scripts; the latter is not even in the path.
+.It Nm atf_check_equal Qo expected_expression Qc Qo actual_expression Qc
+This function takes two expressions, evaluates them and, if their
+results differ, aborts the test case with an appropriate failure message.
+The common style is to put the expected value in the first parameter and the
+actual value in the second parameter.
+.El
+.Sh EXAMPLES
+The following shows a complete test program with a single test case that
+validates the addition operator:
+.Bd -literal -offset indent
+atf_test_case addition
+addition_head() {
+ atf_set "descr" "Sample tests for the addition operator"
+}
+addition_body() {
+ atf_check_equal 0 $((0 + 0))
+ atf_check_equal 1 $((0 + 1))
+ atf_check_equal 1 $((1 + 0))
+
+ atf_check_equal 2 $((1 + 1))
+
+ atf_check_equal 300 $((100 + 200))
+}
+
+atf_init_test_cases() {
+ atf_add_test_case addition
+}
+.Ed
+.Pp
+This other example shows how to include a file with extra helper functions
+in the test program:
+.Bd -literal -offset indent
+.Ns ... definition of test cases ...
+
+atf_init_test_cases() {
+ . $(atf_get_srcdir)/helper_functions.sh
+
+ atf_add_test_case foo1
+ atf_add_test_case foo2
+}
+.Ed
+.Pp
+This example demonstrates the use of the very useful
+.Nm atf_check
+function:
+.Bd -literal -offset indent
+# Check for silent output
+atf_check -s exit:0 -o empty -e empty 'true'
+
+# Check for silent output and failure
+atf_check -s exit:1 -o empty -e empty 'false'
+
+# Check for known stdout and silent stderr
+echo foo >expout
+atf_check -s exit:0 -o file:expout -e empty 'echo foo'
+
+# Generate a file for later inspection
+atf_check -s exit:0 -o save:stdout -e empty 'ls'
+grep foo ls || atf_fail "foo file not found in listing"
+
+# Or just do the match along the way
+atf_check -s exit:0 -o match:"^foo$" -e empty 'ls'
+.Ed
+.Sh SEE ALSO
+.Xr atf-check 1 ,
+.Xr atf-sh 1 ,
+.Xr atf-test-program 1 ,
+.Xr atf-test-case 4
diff --git a/contrib/atf/atf-sh/atf-sh.cpp b/contrib/atf/atf-sh/atf-sh.cpp
index e985e79..9975573 100644
--- a/contrib/atf/atf-sh/atf-sh.cpp
+++ b/contrib/atf/atf-sh/atf-sh.cpp
@@ -1,6 +1,3 @@
-//
-// Automated Testing Framework (atf)
-//
// Copyright (c) 2010 The NetBSD Foundation, Inc.
// All rights reserved.
//
@@ -25,7 +22,6 @@
// 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.
-//
extern "C" {
#include <unistd.h>
@@ -36,9 +32,8 @@ extern "C" {
#include <cstring>
#include <iostream>
-#include "atf-c++/config.hpp"
-
#include "atf-c++/detail/application.hpp"
+#include "atf-c++/detail/env.hpp"
#include "atf-c++/detail/fs.hpp"
#include "atf-c++/detail/sanity.hpp"
@@ -63,9 +58,11 @@ static
std::string*
construct_script(const char* filename)
{
- const std::string libexecdir = atf::config::get("atf_libexecdir");
- const std::string pkgdatadir = atf::config::get("atf_pkgdatadir");
- const std::string shell = atf::config::get("atf_shell");
+ const std::string libexecdir = atf::env::get(
+ "ATF_LIBEXECDIR", ATF_LIBEXECDIR);
+ const std::string pkgdatadir = atf::env::get(
+ "ATF_PKGDATADIR", ATF_PKGDATADIR);
+ const std::string shell = atf::env::get("ATF_SHELL", ATF_SHELL);
std::string* command = new std::string();
command->reserve(512);
@@ -111,6 +108,11 @@ construct_argv(const std::string& shell, const int interpreter_argc,
class atf_sh : public atf::application::app {
static const char* m_description;
+ atf::fs::path m_shell;
+
+ options_set specific_options(void) const;
+ void process_option(int, const char*);
+
public:
atf_sh(void);
@@ -122,8 +124,36 @@ const char* atf_sh::m_description =
"system sh(1) with the atf-sh library.";
atf_sh::atf_sh(void) :
- app(m_description, "atf-sh(1)")
+ app(m_description, "atf-sh(1)"),
+ m_shell(atf::fs::path(atf::env::get("ATF_SHELL", ATF_SHELL)))
+{
+}
+
+atf_sh::options_set
+atf_sh::specific_options(void)
+ const
+{
+ using atf::application::option;
+ options_set opts;
+
+ INV(m_shell == atf::fs::path(atf::env::get("ATF_SHELL", ATF_SHELL)));
+ opts.insert(option('s', "shell", "Path to the shell interpreter to use; "
+ "default: " + m_shell.str()));
+
+ return opts;
+}
+
+void
+atf_sh::process_option(int ch, const char* arg)
{
+ switch (ch) {
+ case 's':
+ m_shell = atf::fs::path(arg);
+ break;
+
+ default:
+ UNREACHABLE;
+ }
}
int
@@ -137,15 +167,14 @@ atf_sh::main(void)
throw std::runtime_error("The test program '" + script.str() + "' "
"does not exist");
- const std::string shell = atf::config::get("atf_shell");
- const char** argv = construct_argv(shell, m_argc, m_argv);
+ const char** argv = construct_argv(m_shell.str(), m_argc, m_argv);
// Don't bother keeping track of the memory allocated by construct_argv:
// we are going to exec or die immediately.
- const int ret = execv(shell.c_str(), const_cast< char** >(argv));
+ const int ret = execv(m_shell.c_str(), const_cast< char** >(argv));
INV(ret == -1);
- std::cerr << "Failed to execute " << shell << ": " << std::strerror(errno)
- << "\n";
+ std::cerr << "Failed to execute " << m_shell.str() << ": "
+ << std::strerror(errno) << "\n";
return EXIT_FAILURE;
}
diff --git a/contrib/atf/atf-sh/atf_check_test.sh b/contrib/atf/atf-sh/atf_check_test.sh
index a43a952..163e905 100644
--- a/contrib/atf/atf-sh/atf_check_test.sh
+++ b/contrib/atf/atf-sh/atf_check_test.sh
@@ -1,6 +1,3 @@
-#
-# Automated Testing Framework (atf)
-#
# Copyright (c) 2007 The NetBSD Foundation, Inc.
# All rights reserved.
#
@@ -25,7 +22,6 @@
# 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.
-#
# TODO: Bring in the checks in the bootstrap testsuite for atf_check.
diff --git a/contrib/atf/atf-sh/config_test.sh b/contrib/atf/atf-sh/config_test.sh
index f7f57f0..048834c 100644
--- a/contrib/atf/atf-sh/config_test.sh
+++ b/contrib/atf/atf-sh/config_test.sh
@@ -1,6 +1,3 @@
-#
-# Automated Testing Framework (atf)
-#
# Copyright (c) 2007 The NetBSD Foundation, Inc.
# All rights reserved.
#
@@ -25,7 +22,6 @@
# 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.
-#
atf_test_case has
has_head()
diff --git a/contrib/atf/atf-sh/integration_test.sh b/contrib/atf/atf-sh/integration_test.sh
index 452c958..1150966 100644
--- a/contrib/atf/atf-sh/integration_test.sh
+++ b/contrib/atf/atf-sh/integration_test.sh
@@ -1,6 +1,3 @@
-#
-# Automated Testing Framework (atf)
-#
# Copyright (c) 2010 The NetBSD Foundation, Inc.
# All rights reserved.
#
@@ -25,12 +22,14 @@
# 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.
-#
+
+: ${ATF_SH:="__ATF_SH__"}
create_test_program() {
- echo '#! /usr/bin/env atf-sh' >"${1}"
- cat >>"${1}"
- chmod +x "${1}"
+ local output="${1}"; shift
+ echo "#! ${ATF_SH} ${*}" >"${output}"
+ cat >>"${output}"
+ chmod +x "${output}"
}
atf_test_case no_args
@@ -40,7 +39,7 @@ no_args_body()
atf-sh: ERROR: No test program provided
atf-sh: See atf-sh(1) for usage details.
EOF
- atf_check -s eq:1 -o ignore -e file:experr atf-sh
+ atf_check -s eq:1 -o ignore -e file:experr "${ATF_SH}"
}
atf_test_case missing_script
@@ -49,7 +48,7 @@ missing_script_body()
cat >experr <<EOF
atf-sh: ERROR: The test program 'non-existent' does not exist
EOF
- atf_check -s eq:1 -o ignore -e file:experr atf-sh non-existent
+ atf_check -s eq:1 -o ignore -e file:experr "${ATF_SH}" non-existent
}
atf_test_case arguments
@@ -78,7 +77,74 @@ EOF
>>> hello bye <<<
>>>foo bar<<<
EOF
- atf_check -s eq:0 -o file:expout -e empty atf-sh tp ' hello bye ' 'foo bar'
+ atf_check -s eq:0 -o file:expout -e empty "${ATF_SH}" tp \
+ ' hello bye ' 'foo bar'
+}
+
+atf_test_case custom_shell__command_line
+custom_shell__command_line_body()
+{
+ cat >expout <<EOF
+This is the custom shell
+This is the test program
+EOF
+
+ cat >custom-shell <<EOF
+#! /bin/sh
+echo "This is the custom shell"
+exec /bin/sh "\${@}"
+EOF
+ chmod +x custom-shell
+
+ echo 'main() { echo "This is the test program"; }' | create_test_program tp
+ atf_check -s eq:0 -o file:expout -e empty "${ATF_SH}" -s ./custom-shell tp
+}
+
+atf_test_case custom_shell__shebang
+custom_shell__shebang_body()
+{
+ cat >expout <<EOF
+This is the custom shell
+This is the test program
+EOF
+
+ cat >custom-shell <<EOF
+#! /bin/sh
+echo "This is the custom shell"
+exec /bin/sh "\${@}"
+EOF
+ chmod +x custom-shell
+
+ echo 'main() { echo "This is the test program"; }' | create_test_program \
+ tp "-s$(pwd)/custom-shell"
+ atf_check -s eq:0 -o file:expout -e empty ./tp
+}
+
+atf_test_case set_e
+set_e_head()
+{
+ atf_set "descr" "Simple test to validate that atf-sh works even when" \
+ "set -e is enabled"
+}
+set_e_body()
+{
+ cat >custom-shell <<EOF
+#! /bin/sh
+exec /bin/sh -e "\${@}"
+EOF
+ chmod +x custom-shell
+
+ cat >tp <<EOF
+atf_test_case helper
+helper_body() {
+ atf_skip "reached"
+}
+atf_init_test_cases() {
+ atf_add_test_case helper
+}
+EOF
+ atf_check -s eq:0 -o match:skipped.*reached \
+ "${ATF_SH}" -s ./custom-shell tp helper
}
atf_init_test_cases()
@@ -86,6 +152,9 @@ atf_init_test_cases()
atf_add_test_case no_args
atf_add_test_case missing_script
atf_add_test_case arguments
+ atf_add_test_case custom_shell__command_line
+ atf_add_test_case custom_shell__shebang
+ atf_add_test_case set_e
}
# vim: syntax=sh:expandtab:shiftwidth=4:softtabstop=4
diff --git a/contrib/atf/atf-sh/libatf-sh.subr b/contrib/atf/atf-sh/libatf-sh.subr
index 8525b22..a078975 100644
--- a/contrib/atf/atf-sh/libatf-sh.subr
+++ b/contrib/atf/atf-sh/libatf-sh.subr
@@ -1,6 +1,3 @@
-#
-# Automated Testing Framework (atf)
-#
# Copyright (c) 2007 The NetBSD Foundation, Inc.
# All rights reserved.
#
@@ -25,9 +22,6 @@
# 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.
-#
-
-set -e
# ------------------------------------------------------------------------
# GLOBAL VARIABLES
@@ -90,12 +84,13 @@ atf_check()
}
#
-# atf_check_equal expr1 expr2
+# atf_check_equal expected_expression actual_expression
#
-# Checks that expr1's value matches expr2's and, if not, raises an
-# error. Ideally expr1 and expr2 should be provided quoted (not
-# expanded) so that the error message is helpful; otherwise it will
-# only show the values, not the expressions themselves.
+# Checks that expected_expression's value matches actual_expression's
+# and, if not, raises an error. Ideally expected_expression and
+# actual_expression should be provided quoted (not expanded) so that
+# the error message is helpful; otherwise it will only show the values,
+# not the expressions themselves.
#
atf_check_equal()
{
@@ -595,7 +590,7 @@ _atf_run_tc()
_atf_has_tc "${_tcname}" || _atf_syntax_error "Unknown test case \`${1}'"
if [ "${__RUNNING_INSIDE_ATF_RUN}" != "internal-yes-value" ]; then
- _atf_warning "Running test cases without atf-run(1) is unsupported"
+ _atf_warning "Running test cases outside of kyua(1) is unsupported"
_atf_warning "No isolation nor timeout control is being applied;" \
"you may get unexpected failures; see atf-test-case(4)"
fi
@@ -741,10 +736,6 @@ main()
done
shift `expr ${OPTIND} - 1`
- # First of all, make sure that the source directory is correct. It
- # doesn't matter if the user did not change it, because the default
- # value may not work. (TODO: It possibly should, even though it is
- # not a big deal because atf-run deals with this.)
case ${Source_Dir} in
/*)
;;
diff --git a/contrib/atf/atf-sh/misc_helpers.sh b/contrib/atf/atf-sh/misc_helpers.sh
index 1f83688..62d6580 100644
--- a/contrib/atf/atf-sh/misc_helpers.sh
+++ b/contrib/atf/atf-sh/misc_helpers.sh
@@ -1,6 +1,3 @@
-#
-# Automated Testing Framework (atf)
-#
# Copyright (c) 2007 The NetBSD Foundation, Inc.
# All rights reserved.
#
@@ -25,7 +22,6 @@
# 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.
-#
# -------------------------------------------------------------------------
# Helper tests for "t_atf_check".
diff --git a/contrib/atf/atf-sh/normalize_test.sh b/contrib/atf/atf-sh/normalize_test.sh
index 0f59da0..0419db36 100644
--- a/contrib/atf/atf-sh/normalize_test.sh
+++ b/contrib/atf/atf-sh/normalize_test.sh
@@ -1,6 +1,3 @@
-#
-# Automated Testing Framework (atf)
-#
# Copyright (c) 2007 The NetBSD Foundation, Inc.
# All rights reserved.
#
@@ -25,7 +22,6 @@
# 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.
-#
atf_test_case main
main_head()
diff --git a/contrib/atf/atf-sh/tc_test.sh b/contrib/atf/atf-sh/tc_test.sh
index 5bece42..1117047 100644
--- a/contrib/atf/atf-sh/tc_test.sh
+++ b/contrib/atf/atf-sh/tc_test.sh
@@ -1,6 +1,3 @@
-#
-# Automated Testing Framework (atf)
-#
# Copyright (c) 2007 The NetBSD Foundation, Inc.
# All rights reserved.
#
@@ -25,7 +22,6 @@
# 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.
-#
atf_test_case default_status
default_status_head()
diff --git a/contrib/atf/atf-sh/tp_test.sh b/contrib/atf/atf-sh/tp_test.sh
index c159813..a9f1b96 100644
--- a/contrib/atf/atf-sh/tp_test.sh
+++ b/contrib/atf/atf-sh/tp_test.sh
@@ -1,6 +1,3 @@
-#
-# Automated Testing Framework (atf)
-#
# Copyright (c) 2007 The NetBSD Foundation, Inc.
# All rights reserved.
#
@@ -25,7 +22,6 @@
# 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.
-#
atf_test_case srcdir
srcdir_head()
OpenPOWER on IntegriCloud