summaryrefslogtreecommitdiff
path: root/unit/atf-src/atf-c++
diff options
context:
space:
mode:
Diffstat (limited to 'unit/atf-src/atf-c++')
-rw-r--r--unit/atf-src/atf-c++/Kyuafile14
-rw-r--r--unit/atf-src/atf-c++/Makefile.am.inc46
-rw-r--r--unit/atf-src/atf-c++/atf-c++-api.3266
-rw-r--r--unit/atf-src/atf-c++/atf-c++.m448
-rw-r--r--unit/atf-src/atf-c++/check.cpp2
-rw-r--r--unit/atf-src/atf-c++/check.hpp6
-rw-r--r--unit/atf-src/atf-c++/check_test.cpp46
-rw-r--r--unit/atf-src/atf-c++/config.cpp2
-rw-r--r--unit/atf-src/atf-c++/config.hpp2
-rw-r--r--unit/atf-src/atf-c++/config_test.cpp2
-rw-r--r--unit/atf-src/atf-c++/detail/Atffile1
-rw-r--r--unit/atf-src/atf-c++/detail/Kyuafile14
-rw-r--r--unit/atf-src/atf-c++/detail/Makefile.am.inc30
-rw-r--r--unit/atf-src/atf-c++/detail/application.cpp11
-rw-r--r--unit/atf-src/atf-c++/detail/application.hpp2
-rw-r--r--unit/atf-src/atf-c++/detail/application_test.cpp4
-rw-r--r--unit/atf-src/atf-c++/detail/auto_array.hpp179
-rw-r--r--unit/atf-src/atf-c++/detail/auto_array_test.cpp304
-rw-r--r--unit/atf-src/atf-c++/detail/env.cpp2
-rw-r--r--unit/atf-src/atf-c++/detail/env.hpp2
-rw-r--r--unit/atf-src/atf-c++/detail/env_test.cpp2
-rw-r--r--unit/atf-src/atf-c++/detail/exceptions.cpp3
-rw-r--r--unit/atf-src/atf-c++/detail/exceptions.hpp3
-rw-r--r--unit/atf-src/atf-c++/detail/exceptions_test.cpp1
-rw-r--r--unit/atf-src/atf-c++/detail/expand.cpp2
-rw-r--r--unit/atf-src/atf-c++/detail/expand.hpp2
-rw-r--r--unit/atf-src/atf-c++/detail/expand_test.cpp2
-rw-r--r--unit/atf-src/atf-c++/detail/fs.cpp2
-rw-r--r--unit/atf-src/atf-c++/detail/fs.hpp2
-rw-r--r--unit/atf-src/atf-c++/detail/fs_test.cpp2
-rw-r--r--unit/atf-src/atf-c++/detail/parser.cpp2
-rw-r--r--unit/atf-src/atf-c++/detail/parser.hpp2
-rw-r--r--unit/atf-src/atf-c++/detail/parser_test.cpp2
-rw-r--r--unit/atf-src/atf-c++/detail/process.cpp6
-rw-r--r--unit/atf-src/atf-c++/detail/process.hpp33
-rw-r--r--unit/atf-src/atf-c++/detail/process_test.cpp2
-rw-r--r--unit/atf-src/atf-c++/detail/sanity.hpp2
-rw-r--r--unit/atf-src/atf-c++/detail/test_helpers.cpp61
-rw-r--r--unit/atf-src/atf-c++/detail/test_helpers.hpp23
-rw-r--r--unit/atf-src/atf-c++/detail/text.cpp27
-rw-r--r--unit/atf-src/atf-c++/detail/text.hpp13
-rw-r--r--unit/atf-src/atf-c++/detail/text_test.cpp27
-rw-r--r--unit/atf-src/atf-c++/detail/ui.cpp5
-rw-r--r--unit/atf-src/atf-c++/detail/ui.hpp2
-rw-r--r--unit/atf-src/atf-c++/macros.hpp41
-rw-r--r--unit/atf-src/atf-c++/macros_hpp_test.cpp7
-rw-r--r--unit/atf-src/atf-c++/macros_test.cpp236
-rw-r--r--unit/atf-src/atf-c++/noncopyable.hpp56
-rw-r--r--unit/atf-src/atf-c++/pkg_config_test.sh2
-rw-r--r--unit/atf-src/atf-c++/tests.cpp19
-rw-r--r--unit/atf-src/atf-c++/tests.hpp6
-rw-r--r--unit/atf-src/atf-c++/tests_test.cpp2
-rw-r--r--unit/atf-src/atf-c++/unused_test.cpp52
-rw-r--r--unit/atf-src/atf-c++/utils.cpp104
-rw-r--r--unit/atf-src/atf-c++/utils.hpp182
-rw-r--r--unit/atf-src/atf-c++/utils_test.cpp567
56 files changed, 1907 insertions, 578 deletions
diff --git a/unit/atf-src/atf-c++/Kyuafile b/unit/atf-src/atf-c++/Kyuafile
new file mode 100644
index 00000000..6df836f2
--- /dev/null
+++ b/unit/atf-src/atf-c++/Kyuafile
@@ -0,0 +1,14 @@
+syntax("kyuafile", 1)
+
+test_suite("atf")
+
+atf_test_program{name="atf_c++_test"}
+atf_test_program{name="build_test"}
+atf_test_program{name="check_test"}
+atf_test_program{name="config_test"}
+atf_test_program{name="macros_test"}
+atf_test_program{name="pkg_config_test"}
+atf_test_program{name="tests_test"}
+atf_test_program{name="utils_test"}
+
+include("detail/Kyuafile")
diff --git a/unit/atf-src/atf-c++/Makefile.am.inc b/unit/atf-src/atf-c++/Makefile.am.inc
index e7287d32..2d968026 100644
--- a/unit/atf-src/atf-c++/Makefile.am.inc
+++ b/unit/atf-src/atf-c++/Makefile.am.inc
@@ -1,7 +1,7 @@
#
# Automated Testing Framework (atf)
#
-# Copyright (c) 2007, 2008, 2009, 2010 The NetBSD Foundation, Inc.
+# Copyright (c) 2007 The NetBSD Foundation, Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -27,6 +27,8 @@
# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
+ATF_CXX_LIBS = libatf-c++.la libatf-c.la
+
lib_LTLIBRARIES += libatf-c++.la
libatf_c___la_LIBADD = libatf-c.la
libatf_c___la_SOURCES = atf-c++/build.cpp \
@@ -36,59 +38,63 @@ libatf_c___la_SOURCES = atf-c++/build.cpp \
atf-c++/config.cpp \
atf-c++/config.hpp \
atf-c++/macros.hpp \
+ atf-c++/noncopyable.hpp \
atf-c++/tests.cpp \
atf-c++/tests.hpp \
+ atf-c++/utils.cpp \
atf-c++/utils.hpp
+libatf_c___la_LDFLAGS = -version-info 0:0:0
include_HEADERS += atf-c++.hpp
atf_c___HEADERS = atf-c++/build.hpp \
atf-c++/check.hpp \
atf-c++/config.hpp \
atf-c++/macros.hpp \
+ atf-c++/noncopyable.hpp \
atf-c++/tests.hpp \
atf-c++/utils.hpp
atf_c__dir = $(includedir)/atf-c++
dist_man_MANS += atf-c++/atf-c++-api.3
+atf_aclocal_DATA += atf-c++/atf-c++.m4
+EXTRA_DIST += atf-c++/atf-c++.m4
+
atf_c__dirpkgconfigdir = $(atf_pkgconfigdir)
atf_c__dirpkgconfig_DATA = atf-c++/atf-c++.pc
CLEANFILES += atf-c++/atf-c++.pc
EXTRA_DIST += atf-c++/atf-c++.pc.in
-atf-c++/atf-c++.pc: $(srcdir)/atf-c++/atf-c++.pc.in
+atf-c++/atf-c++.pc: $(srcdir)/atf-c++/atf-c++.pc.in Makefile
test -d atf-c++ || mkdir -p atf-c++
- sed -e 's,__ATF_VERSION__,@PACKAGE_VERSION@,g' \
- -e 's,__CXX__,$(CXX),g' \
- -e 's,__INCLUDEDIR__,$(includedir),g' \
- -e 's,__LIBDIR__,$(libdir),g' \
+ sed -e 's#__ATF_VERSION__#$(PACKAGE_VERSION)#g' \
+ -e 's#__CXX__#$(CXX)#g' \
+ -e 's#__INCLUDEDIR__#$(includedir)#g' \
+ -e 's#__LIBDIR__#$(libdir)#g' \
<$(srcdir)/atf-c++/atf-c++.pc.in >atf-c++/atf-c++.pc.tmp
mv atf-c++/atf-c++.pc.tmp atf-c++/atf-c++.pc
tests_atf_c___DATA = atf-c++/Atffile \
- atf-c++/macros_hpp_test.cpp
+ atf-c++/Kyuafile \
+ atf-c++/macros_hpp_test.cpp \
+ atf-c++/unused_test.cpp
tests_atf_c__dir = $(pkgtestsdir)/atf-c++
EXTRA_DIST += $(tests_atf_c___DATA)
tests_atf_c___PROGRAMS = atf-c++/atf_c++_test
atf_c___atf_c___test_SOURCES = atf-c++/atf_c++_test.cpp
-atf_c___atf_c___test_LDADD = atf-c++/detail/libtest_helpers.la libatf-c++.la
-
+atf_c___atf_c___test_LDADD = atf-c++/detail/libtest_helpers.la $(ATF_CXX_LIBS)
tests_atf_c___PROGRAMS += atf-c++/build_test
atf_c___build_test_SOURCES = atf-c++/build_test.cpp atf-c/h_build.h
-atf_c___build_test_LDADD = atf-c++/detail/libtest_helpers.la libatf-c++.la
-
+atf_c___build_test_LDADD = atf-c++/detail/libtest_helpers.la $(ATF_CXX_LIBS)
tests_atf_c___PROGRAMS += atf-c++/check_test
atf_c___check_test_SOURCES = atf-c++/check_test.cpp
-atf_c___check_test_LDADD = atf-c++/detail/libtest_helpers.la libatf-c++.la
-
+atf_c___check_test_LDADD = atf-c++/detail/libtest_helpers.la $(ATF_CXX_LIBS)
tests_atf_c___PROGRAMS += atf-c++/config_test
atf_c___config_test_SOURCES = atf-c++/config_test.cpp
-atf_c___config_test_LDADD = atf-c++/detail/libtest_helpers.la libatf-c++.la
-
+atf_c___config_test_LDADD = atf-c++/detail/libtest_helpers.la $(ATF_CXX_LIBS)
tests_atf_c___PROGRAMS += atf-c++/macros_test
atf_c___macros_test_SOURCES = atf-c++/macros_test.cpp
-atf_c___macros_test_LDADD = atf-c++/detail/libtest_helpers.la libatf-c++.la
-
+atf_c___macros_test_LDADD = atf-c++/detail/libtest_helpers.la $(ATF_CXX_LIBS)
tests_atf_c___SCRIPTS = atf-c++/pkg_config_test
CLEANFILES += atf-c++/pkg_config_test
EXTRA_DIST += atf-c++/pkg_config_test.sh
@@ -99,12 +105,10 @@ atf-c++/pkg_config_test: $(srcdir)/atf-c++/pkg_config_test.sh
tests_atf_c___PROGRAMS += atf-c++/tests_test
atf_c___tests_test_SOURCES = atf-c++/tests_test.cpp
-atf_c___tests_test_LDADD = atf-c++/detail/libtest_helpers.la libatf-c++.la
-
+atf_c___tests_test_LDADD = atf-c++/detail/libtest_helpers.la $(ATF_CXX_LIBS)
tests_atf_c___PROGRAMS += atf-c++/utils_test
atf_c___utils_test_SOURCES = atf-c++/utils_test.cpp
-atf_c___utils_test_LDADD = atf-c++/detail/libtest_helpers.la libatf-c++.la
-
+atf_c___utils_test_LDADD = atf-c++/detail/libtest_helpers.la $(ATF_CXX_LIBS)
include atf-c++/detail/Makefile.am.inc
# vim: syntax=make:noexpandtab:shiftwidth=8:softtabstop=8
diff --git a/unit/atf-src/atf-c++/atf-c++-api.3 b/unit/atf-src/atf-c++/atf-c++-api.3
index 42e6ed75..d0579a9a 100644
--- a/unit/atf-src/atf-c++/atf-c++-api.3
+++ b/unit/atf-src/atf-c++/atf-c++-api.3
@@ -1,7 +1,7 @@
.\"
.\" Automated Testing Framework (atf)
.\"
-.\" Copyright (c) 2008, 2010 The NetBSD Foundation, Inc.
+.\" Copyright (c) 2008 The NetBSD Foundation, Inc.
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
@@ -26,10 +26,11 @@
.\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
.\" IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd October 21, 2010
+.Dd November 30, 2012
.Dt ATF-C++-API 3
.Os
.Sh NAME
+.Nm atf-c++-api ,
.Nm ATF_ADD_TEST_CASE ,
.Nm ATF_CHECK_ERRNO ,
.Nm ATF_FAIL ,
@@ -38,7 +39,9 @@
.Nm ATF_REQUIRE ,
.Nm ATF_REQUIRE_EQ ,
.Nm ATF_REQUIRE_ERRNO ,
+.Nm ATF_REQUIRE_IN ,
.Nm ATF_REQUIRE_MATCH ,
+.Nm ATF_REQUIRE_NOT_IN ,
.Nm ATF_REQUIRE_THROW ,
.Nm ATF_REQUIRE_THROW_RE ,
.Nm ATF_SKIP ,
@@ -46,8 +49,21 @@
.Nm ATF_TEST_CASE_BODY ,
.Nm ATF_TEST_CASE_CLEANUP ,
.Nm ATF_TEST_CASE_HEAD ,
+.Nm ATF_TEST_CASE_NAME ,
+.Nm ATF_TEST_CASE_USE ,
.Nm ATF_TEST_CASE_WITH_CLEANUP ,
.Nm ATF_TEST_CASE_WITHOUT_HEAD ,
+.Nm atf::utils::cat_file ,
+.Nm atf::utils::compare_file ,
+.Nm atf::utils::copy_file ,
+.Nm atf::utils::create_file ,
+.Nm atf::utils::file_exists ,
+.Nm atf::utils::fork ,
+.Nm atf::utils::grep_collection ,
+.Nm atf::utils::grep_file ,
+.Nm atf::utils::grep_string ,
+.Nm atf::utils::redirect ,
+.Nm atf::utils::wait
.Nd C++ API to write ATF-based test programs
.Sh SYNOPSIS
.In atf-c++.hpp
@@ -59,7 +75,9 @@
.Fn ATF_REQUIRE "expression"
.Fn ATF_REQUIRE_EQ "expression_1" "expression_2"
.Fn ATF_REQUIRE_ERRNO "exp_errno" "bool_expression"
+.Fn ATF_REQUIRE_IN "element" "collection"
.Fn ATF_REQUIRE_MATCH "regexp" "string_expression"
+.Fn ATF_REQUIRE_NOT_IN "element" "collection"
.Fn ATF_REQUIRE_THROW "expected_exception" "statement"
.Fn ATF_REQUIRE_THROW_RE "expected_exception" "regexp" "statement"
.Fn ATF_SKIP "reason"
@@ -67,8 +85,65 @@
.Fn ATF_TEST_CASE_BODY "name"
.Fn ATF_TEST_CASE_CLEANUP "name"
.Fn ATF_TEST_CASE_HEAD "name"
+.Fn ATF_TEST_CASE_NAME "name"
+.Fn ATF_TEST_CASE_USE "name"
.Fn ATF_TEST_CASE_WITH_CLEANUP "name"
.Fn ATF_TEST_CASE_WITHOUT_HEAD "name"
+.Ft void
+.Fo atf::utils::cat_file
+.Fa "const std::string& path"
+.Fa "const std::string& prefix"
+.Fc
+.Ft bool
+.Fo atf::utils::compare_file
+.Fa "const std::string& path"
+.Fa "const std::string& contents"
+.Fc
+.Ft void
+.Fo atf::utils::copy_file
+.Fa "const std::string& source"
+.Fa "const std::string& destination"
+.Fc
+.Ft void
+.Fo atf::utils::create_file
+.Fa "const std::string& path"
+.Fa "const std::string& contents"
+.Fc
+.Ft void
+.Fo atf::utils::file_exists
+.Fa "const std::string& path"
+.Fc
+.Ft pid_t
+.Fo atf::utils::fork
+.Fa "void"
+.Fc
+.Ft bool
+.Fo atf::utils::grep_collection
+.Fa "const std::string& regexp"
+.Fa "const Collection& collection"
+.Fc
+.Ft bool
+.Fo atf::utils::grep_file
+.Fa "const std::string& regexp"
+.Fa "const std::string& path"
+.Fc
+.Ft bool
+.Fo atf::utils::grep_string
+.Fa "const std::string& regexp"
+.Fa "const std::string& path"
+.Fc
+.Ft void
+.Fo atf::utils::redirect
+.Fa "const int fd"
+.Fa "const std::string& path"
+.Fc
+.Ft void
+.Fo atf::utils::wait
+.Fa "const pid_t pid"
+.Fa "const int expected_exit_status"
+.Fa "const std::string& expected_stdout"
+.Fa "const std::string& expected_stderr"
+.Fc
.Sh DESCRIPTION
ATF provides a mostly-macro-based programming interface to implement test
programs in C or C++.
@@ -166,6 +241,18 @@ and
macros, all of which take the test case's name.
Following each of these, a block of code is expected, surrounded by the
opening and closing brackets.
+.Pp
+Additionally, the
+.Fn ATF_TEST_CASE_NAME
+macro can be used to obtain the name of the class corresponding to a
+particular test case, as the name is internally manged by the library to
+prevent clashes with other user identifiers.
+Similarly, the
+.Fn ATF_TEST_CASE_USE
+macro can be executed on a particular test case to mark it as "used" and
+thus prevent compiler warnings regarding unused symbols.
+Note that
+.Em you should never have to use these macros during regular operation.
.Ss Program initialization
The library provides a way to easily define the test program's
.Fn main
@@ -185,7 +272,7 @@ The first parameter of this macro matches the name you provided in the
former call.
.Ss Header definitions
The test case's header can define the meta-data by using the
-.Fn set
+.Fn set_md_var
method, which takes two parameters: the first one specifies the
meta-data variable to be set and the second one specifies its value.
Both of them are strings.
@@ -313,14 +400,22 @@ takes an expression and raises a failure if it evaluates to false.
takes two expressions and raises a failure if the two do not evaluate to
the same exact value.
.Pp
+.Fn ATF_REQUIRE_IN
+takes an element and a collection and validates that the element is present in
+the collection.
+.Pp
.Fn ATF_REQUIRE_MATCH
takes a regular expression and a string and raises a failure if the regular
expression does not match the string.
.Pp
+.Fn ATF_REQUIRE_NOT_IN
+takes an element and a collection and validates that the element is not present
+in the collection.
+.Pp
.Fn ATF_REQUIRE_THROW
takes the name of an exception and a statement and raises a failure if
the statement does not throw the specified exception.
-.Fn ATF_REQUIRE_THROW_EQ
+.Fn ATF_REQUIRE_THROW_RE
takes the name of an exception, a regular expresion and a statement and raises a
failure if the statement does not throw the specified exception and if the
message of the exception does not match the regular expression.
@@ -334,6 +429,163 @@ variable and, second, a boolean expression that, if evaluates to true,
means that a call failed and
.Va errno
has to be checked against the first value.
+.Ss Utility functions
+The following functions are provided as part of the
+.Nm
+API to simplify the creation of a variety of tests.
+In particular, these are useful to write tests for command-line interfaces.
+.Pp
+.Ft void
+.Fo atf::utils::cat_file
+.Fa "const std::string& path"
+.Fa "const std::string& prefix"
+.Fc
+.Bd -offset indent
+Prints the contents of
+.Fa path
+to the standard output, prefixing every line with the string in
+.Fa prefix .
+.Ed
+.Pp
+.Ft bool
+.Fo atf::utils::compare_file
+.Fa "const std::string& path"
+.Fa "const std::string& contents"
+.Fc
+.Bd -offset indent
+Returns true if the given
+.Fa path
+matches exactly the expected inlined
+.Fa contents .
+.Ed
+.Pp
+.Ft void
+.Fo atf::utils::copy_file
+.Fa "const std::string& source"
+.Fa "const std::string& destination"
+.Fc
+.Bd -offset indent
+Copies the file
+.Fa source
+to
+.Fa destination .
+The permissions of the file are preserved during the code.
+.Ed
+.Pp
+.Ft void
+.Fo atf::utils::create_file
+.Fa "const std::string& path"
+.Fa "const std::string& contents"
+.Fc
+.Bd -offset indent
+Creates
+.Fa file
+with the text given in
+.Fa contents .
+.Ed
+.Pp
+.Ft void
+.Fo atf::utils::file_exists
+.Fa "const std::string& path"
+.Fc
+.Bd -offset indent
+Checks if
+.Fa path
+exists.
+.Ed
+.Pp
+.Ft pid_t
+.Fo atf::utils::fork
+.Fa "void"
+.Fc
+.Bd -offset indent
+Forks a process and redirects the standard output and standard error of the
+child to files for later validation with
+.Fn atf::utils::wait .
+Fails the test case if the fork fails, so this does not return an error.
+.Ed
+.Pp
+.Ft bool
+.Fo atf::utils::grep_collection
+.Fa "const std::string& regexp"
+.Fa "const Collection& collection"
+.Fc
+.Bd -offset indent
+Searches for the regular expression
+.Fa regexp
+in any of the strings contained in the
+.Fa collection .
+This is a template that accepts any one-dimensional container of strings.
+.Ed
+.Pp
+.Ft bool
+.Fo atf::utils::grep_file
+.Fa "const std::string& regexp"
+.Fa "const std::string& path"
+.Fc
+.Bd -offset indent
+Searches for the regular expression
+.Fa regexp
+in the file
+.Fa path .
+The variable arguments are used to construct the regular expression.
+.Ed
+.Pp
+.Ft bool
+.Fo atf::utils::grep_string
+.Fa "const std::string& regexp"
+.Fa "const std::string& str"
+.Fc
+.Bd -offset indent
+Searches for the regular expression
+.Fa regexp
+in the string
+.Fa str .
+.Ed
+.Ft void
+.Fo atf::utils::redirect
+.Fa "const int fd"
+.Fa "const std::string& path"
+.Fc
+.Bd -offset indent
+Redirects the given file descriptor
+.Fa fd
+to the file
+.Fa path .
+This function exits the process in case of an error and does not properly mark
+the test case as failed.
+As a result, it should only be used in subprocesses of the test case; specially
+those spawned by
+.Fn atf::utils::fork .
+.Ed
+.Pp
+.Ft void
+.Fo atf::utils::wait
+.Fa "const pid_t pid"
+.Fa "const int expected_exit_status"
+.Fa "const std::string& expected_stdout"
+.Fa "const std::string& expected_stderr"
+.Fc
+.Bd -offset indent
+Waits and validates the result of a subprocess spawned with
+.Fn atf::utils::wait .
+The validation involves checking that the subprocess exited cleanly and returned
+the code specified in
+.Fa expected_exit_status
+and that its standard output and standard error match the strings given in
+.Fa expected_stdout
+and
+.Fa expected_stderr .
+.Pp
+If any of the
+.Fa expected_stdout
+or
+.Fa expected_stderr
+strings are prefixed with
+.Sq save: ,
+then they specify the name of the file into which to store the stdout or stderr
+of the subprocess, and no comparison is performed.
+.Ed
.Sh EXAMPLES
The following shows a complete test program with a single test case that
validates the addition operator:
@@ -343,7 +595,7 @@ validates the addition operator:
ATF_TEST_CASE(addition);
ATF_TEST_CASE_HEAD(addition)
{
- set("descr", "Sample tests for the addition operator");
+ set_md_var("descr", "Sample tests for the addition operator");
}
ATF_TEST_CASE_BODY(addition)
{
@@ -359,7 +611,7 @@ ATF_TEST_CASE_BODY(addition)
ATF_TEST_CASE(open_failure);
ATF_TEST_CASE_HEAD(open_failure)
{
- set("descr", "Sample tests for the open function");
+ set_md_var("descr", "Sample tests for the open function");
}
ATF_TEST_CASE_BODY(open_failure)
{
@@ -369,7 +621,7 @@ ATF_TEST_CASE_BODY(open_failure)
ATF_TEST_CASE(known_bug);
ATF_TEST_CASE_HEAD(known_bug)
{
- set("descr", "Reproduces a known bug");
+ set_md_var("descr", "Reproduces a known bug");
}
ATF_TEST_CASE_BODY(known_bug)
{
diff --git a/unit/atf-src/atf-c++/atf-c++.m4 b/unit/atf-src/atf-c++/atf-c++.m4
new file mode 100644
index 00000000..0763d048
--- /dev/null
+++ b/unit/atf-src/atf-c++/atf-c++.m4
@@ -0,0 +1,48 @@
+dnl
+dnl Automated Testing Framework (atf)
+dnl
+dnl Copyright 2011 Google Inc.
+dnl All rights reserved.
+dnl
+dnl Redistribution and use in source and binary forms, with or without
+dnl modification, are permitted provided that the following conditions are
+dnl met:
+dnl
+dnl * Redistributions of source code must retain the above copyright
+dnl notice, this list of conditions and the following disclaimer.
+dnl * Redistributions in binary form must reproduce the above copyright
+dnl notice, this list of conditions and the following disclaimer in the
+dnl documentation and/or other materials provided with the distribution.
+dnl * Neither the name of Google Inc. nor the names of its contributors
+dnl may be used to endorse or promote products derived from this software
+dnl without specific prior written permission.
+dnl
+dnl THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+dnl "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+dnl LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+dnl A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+dnl OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+dnl SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+dnl LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+dnl DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+dnl THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+dnl (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+dnl OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+dnl
+
+dnl ATF_CHECK_CXX([version-spec])
+dnl
+dnl Checks if atf-c++ is present. If version-spec is provided, ensures that
+dnl the installed version of atf-sh matches the required version. This
+dnl argument must be something like '>= 0.14' and accepts any version
+dnl specification supported by pkg-config.
+dnl
+dnl Defines and substitutes ATF_CXX_CFLAGS and ATF_CXX_LIBS with the compiler
+dnl and linker flags need to build against atf-c++.
+AC_DEFUN([ATF_CHECK_CXX], [
+ spec="atf-c++[]m4_default_nblank([ $1], [])"
+ _ATF_CHECK_ARG_WITH(
+ [PKG_CHECK_MODULES([ATF_CXX], [${spec}],
+ [found=yes found_atf_cxx=yes], [found=no])],
+ [required ${spec} not found])
+])
diff --git a/unit/atf-src/atf-c++/check.cpp b/unit/atf-src/atf-c++/check.cpp
index 8f5fbcdb..b099b07a 100644
--- a/unit/atf-src/atf-c++/check.cpp
+++ b/unit/atf-src/atf-c++/check.cpp
@@ -1,7 +1,7 @@
//
// Automated Testing Framework (atf)
//
-// Copyright (c) 2007, 2008, 2009 The NetBSD Foundation, Inc.
+// Copyright (c) 2007 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
diff --git a/unit/atf-src/atf-c++/check.hpp b/unit/atf-src/atf-c++/check.hpp
index bc0189a9..0623529c 100644
--- a/unit/atf-src/atf-c++/check.hpp
+++ b/unit/atf-src/atf-c++/check.hpp
@@ -1,7 +1,7 @@
//
// Automated Testing Framework (atf)
//
-// Copyright (c) 2007, 2008, 2009 The NetBSD Foundation, Inc.
+// Copyright (c) 2007 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@@ -39,7 +39,7 @@ extern "C" {
#include <string>
#include <vector>
-#include <atf-c++/utils.hpp>
+#include <atf-c++/noncopyable.hpp>
namespace atf {
@@ -60,7 +60,7 @@ namespace check {
//! of executing arbitrary command and manages files containing
//! its output.
//!
-class check_result : utils::noncopyable {
+class check_result : noncopyable {
//!
//! \brief Internal representation of a result.
//!
diff --git a/unit/atf-src/atf-c++/check_test.cpp b/unit/atf-src/atf-c++/check_test.cpp
index d57dd290..8e5983fd 100644
--- a/unit/atf-src/atf-c++/check_test.cpp
+++ b/unit/atf-src/atf-c++/check_test.cpp
@@ -1,7 +1,7 @@
//
// Automated Testing Framework (atf)
//
-// Copyright (c) 2007, 2008, 2009, 2010 The NetBSD Foundation, Inc.
+// Copyright (c) 2007 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@@ -191,15 +191,17 @@ ATF_TEST_CASE_HEAD(build_c_o)
}
ATF_TEST_CASE_BODY(build_c_o)
{
+ ATF_TEST_CASE_USE(h_build_c_o_ok);
run_h_tc< ATF_TEST_CASE_NAME(h_build_c_o_ok) >();
- ATF_REQUIRE(grep_file("stdout", "-o test.o"));
- ATF_REQUIRE(grep_file("stdout", "-c test.c"));
+ ATF_REQUIRE(atf::utils::grep_file("-o test.o", "stdout"));
+ ATF_REQUIRE(atf::utils::grep_file("-c test.c", "stdout"));
+ ATF_TEST_CASE_USE(h_build_c_o_fail);
run_h_tc< ATF_TEST_CASE_NAME(h_build_c_o_fail) >();
- ATF_REQUIRE(grep_file("stdout", "-o test.o"));
- ATF_REQUIRE(grep_file("stdout", "-c test.c"));
- ATF_REQUIRE(grep_file("stderr", "test.c"));
- ATF_REQUIRE(grep_file("stderr", "UNDEFINED_SYMBOL"));
+ ATF_REQUIRE(atf::utils::grep_file("-o test.o", "stdout"));
+ ATF_REQUIRE(atf::utils::grep_file("-c test.c", "stdout"));
+ ATF_REQUIRE(atf::utils::grep_file("test.c", "stderr"));
+ ATF_REQUIRE(atf::utils::grep_file("UNDEFINED_SYMBOL", "stderr"));
}
ATF_TEST_CASE(build_cpp);
@@ -209,16 +211,18 @@ ATF_TEST_CASE_HEAD(build_cpp)
}
ATF_TEST_CASE_BODY(build_cpp)
{
+ ATF_TEST_CASE_USE(h_build_cpp_ok);
run_h_tc< ATF_TEST_CASE_NAME(h_build_cpp_ok) >();
- ATF_REQUIRE(grep_file("stdout", "-o.*test.p"));
- ATF_REQUIRE(grep_file("stdout", "test.c"));
- ATF_REQUIRE(grep_file("test.p", "foo bar"));
+ ATF_REQUIRE(atf::utils::grep_file("-o.*test.p", "stdout"));
+ ATF_REQUIRE(atf::utils::grep_file("test.c", "stdout"));
+ ATF_REQUIRE(atf::utils::grep_file("foo bar", "test.p"));
+ ATF_TEST_CASE_USE(h_build_cpp_fail);
run_h_tc< ATF_TEST_CASE_NAME(h_build_cpp_fail) >();
- ATF_REQUIRE(grep_file("stdout", "-o test.p"));
- ATF_REQUIRE(grep_file("stdout", "test.c"));
- ATF_REQUIRE(grep_file("stderr", "test.c"));
- ATF_REQUIRE(grep_file("stderr", "non-existent.h"));
+ ATF_REQUIRE(atf::utils::grep_file("-o test.p", "stdout"));
+ ATF_REQUIRE(atf::utils::grep_file("test.c", "stdout"));
+ ATF_REQUIRE(atf::utils::grep_file("test.c", "stderr"));
+ ATF_REQUIRE(atf::utils::grep_file("non-existent.h", "stderr"));
}
ATF_TEST_CASE(build_cxx_o);
@@ -228,15 +232,17 @@ ATF_TEST_CASE_HEAD(build_cxx_o)
}
ATF_TEST_CASE_BODY(build_cxx_o)
{
+ ATF_TEST_CASE_USE(h_build_cxx_o_ok);
run_h_tc< ATF_TEST_CASE_NAME(h_build_cxx_o_ok) >();
- ATF_REQUIRE(grep_file("stdout", "-o test.o"));
- ATF_REQUIRE(grep_file("stdout", "-c test.cpp"));
+ ATF_REQUIRE(atf::utils::grep_file("-o test.o", "stdout"));
+ ATF_REQUIRE(atf::utils::grep_file("-c test.cpp", "stdout"));
+ ATF_TEST_CASE_USE(h_build_cxx_o_fail);
run_h_tc< ATF_TEST_CASE_NAME(h_build_cxx_o_fail) >();
- ATF_REQUIRE(grep_file("stdout", "-o test.o"));
- ATF_REQUIRE(grep_file("stdout", "-c test.cpp"));
- ATF_REQUIRE(grep_file("stderr", "test.cpp"));
- ATF_REQUIRE(grep_file("stderr", "UNDEFINED_SYMBOL"));
+ ATF_REQUIRE(atf::utils::grep_file("-o test.o", "stdout"));
+ ATF_REQUIRE(atf::utils::grep_file("-c test.cpp", "stdout"));
+ ATF_REQUIRE(atf::utils::grep_file("test.cpp", "stderr"));
+ ATF_REQUIRE(atf::utils::grep_file("UNDEFINED_SYMBOL", "stderr"));
}
ATF_TEST_CASE(exec_cleanup);
diff --git a/unit/atf-src/atf-c++/config.cpp b/unit/atf-src/atf-c++/config.cpp
index d9ddf9e9..7b7d6416 100644
--- a/unit/atf-src/atf-c++/config.cpp
+++ b/unit/atf-src/atf-c++/config.cpp
@@ -1,7 +1,7 @@
//
// Automated Testing Framework (atf)
//
-// Copyright (c) 2007, 2008, 2009 The NetBSD Foundation, Inc.
+// Copyright (c) 2007 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
diff --git a/unit/atf-src/atf-c++/config.hpp b/unit/atf-src/atf-c++/config.hpp
index 1d25fe32..e11b9bb2 100644
--- a/unit/atf-src/atf-c++/config.hpp
+++ b/unit/atf-src/atf-c++/config.hpp
@@ -1,7 +1,7 @@
//
// Automated Testing Framework (atf)
//
-// Copyright (c) 2007, 2008 The NetBSD Foundation, Inc.
+// Copyright (c) 2007 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
diff --git a/unit/atf-src/atf-c++/config_test.cpp b/unit/atf-src/atf-c++/config_test.cpp
index 663d1f4f..a3cd2bb5 100644
--- a/unit/atf-src/atf-c++/config_test.cpp
+++ b/unit/atf-src/atf-c++/config_test.cpp
@@ -1,7 +1,7 @@
//
// Automated Testing Framework (atf)
//
-// Copyright (c) 2007, 2008, 2009 The NetBSD Foundation, Inc.
+// Copyright (c) 2007 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
diff --git a/unit/atf-src/atf-c++/detail/Atffile b/unit/atf-src/atf-c++/detail/Atffile
index ead6ec3d..2d53514b 100644
--- a/unit/atf-src/atf-c++/detail/Atffile
+++ b/unit/atf-src/atf-c++/detail/Atffile
@@ -3,6 +3,7 @@ Content-Type: application/X-atf-atffile; version="1"
prop: test-suite = atf
tp: application_test
+tp: auto_array_test
tp: env_test
tp: exceptions_test
tp: expand_test
diff --git a/unit/atf-src/atf-c++/detail/Kyuafile b/unit/atf-src/atf-c++/detail/Kyuafile
new file mode 100644
index 00000000..fd0d7abe
--- /dev/null
+++ b/unit/atf-src/atf-c++/detail/Kyuafile
@@ -0,0 +1,14 @@
+syntax("kyuafile", 1)
+
+test_suite("atf")
+
+atf_test_program{name="application_test"}
+atf_test_program{name="auto_array_test"}
+atf_test_program{name="env_test"}
+atf_test_program{name="exceptions_test"}
+atf_test_program{name="expand_test"}
+atf_test_program{name="fs_test"}
+atf_test_program{name="parser_test"}
+atf_test_program{name="sanity_test"}
+atf_test_program{name="text_test"}
+atf_test_program{name="ui_test"}
diff --git a/unit/atf-src/atf-c++/detail/Makefile.am.inc b/unit/atf-src/atf-c++/detail/Makefile.am.inc
index 4c064cbc..0a7bd151 100644
--- a/unit/atf-src/atf-c++/detail/Makefile.am.inc
+++ b/unit/atf-src/atf-c++/detail/Makefile.am.inc
@@ -1,7 +1,7 @@
#
# Automated Testing Framework (atf)
#
-# Copyright (c) 2007, 2008, 2009, 2010 The NetBSD Foundation, Inc.
+# Copyright (c) 2007 The NetBSD Foundation, Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -29,6 +29,7 @@
libatf_c___la_SOURCES += atf-c++/detail/application.cpp \
atf-c++/detail/application.hpp \
+ atf-c++/detail/auto_array.hpp \
atf-c++/detail/env.cpp \
atf-c++/detail/env.hpp \
atf-c++/detail/exceptions.cpp \
@@ -47,7 +48,8 @@ libatf_c___la_SOURCES += atf-c++/detail/application.cpp \
atf-c++/detail/ui.cpp \
atf-c++/detail/ui.hpp
-tests_atf_c___detail_DATA = atf-c++/detail/Atffile
+tests_atf_c___detail_DATA = atf-c++/detail/Atffile \
+ atf-c++/detail/Kyuafile
tests_atf_c___detaildir = $(pkgtestsdir)/atf-c++/detail
EXTRA_DIST += $(tests_atf_c___detail_DATA)
@@ -57,42 +59,46 @@ atf_c___detail_libtest_helpers_la_SOURCES = atf-c++/detail/test_helpers.cpp \
tests_atf_c___detail_PROGRAMS = atf-c++/detail/application_test
atf_c___detail_application_test_SOURCES = atf-c++/detail/application_test.cpp
-atf_c___detail_application_test_LDADD = atf-c++/detail/libtest_helpers.la libatf-c++.la
+atf_c___detail_application_test_LDADD = atf-c++/detail/libtest_helpers.la $(ATF_CXX_LIBS)
+
+tests_atf_c___detail_PROGRAMS += atf-c++/detail/auto_array_test
+atf_c___detail_auto_array_test_SOURCES = atf-c++/detail/auto_array_test.cpp
+atf_c___detail_auto_array_test_LDADD = atf-c++/detail/libtest_helpers.la $(ATF_CXX_LIBS)
tests_atf_c___detail_PROGRAMS += atf-c++/detail/env_test
atf_c___detail_env_test_SOURCES = atf-c++/detail/env_test.cpp
-atf_c___detail_env_test_LDADD = atf-c++/detail/libtest_helpers.la libatf-c++.la
+atf_c___detail_env_test_LDADD = atf-c++/detail/libtest_helpers.la $(ATF_CXX_LIBS)
tests_atf_c___detail_PROGRAMS += atf-c++/detail/exceptions_test
atf_c___detail_exceptions_test_SOURCES = atf-c++/detail/exceptions_test.cpp
-atf_c___detail_exceptions_test_LDADD = atf-c++/detail/libtest_helpers.la libatf-c++.la
+atf_c___detail_exceptions_test_LDADD = atf-c++/detail/libtest_helpers.la $(ATF_CXX_LIBS)
tests_atf_c___detail_PROGRAMS += atf-c++/detail/expand_test
atf_c___detail_expand_test_SOURCES = atf-c++/detail/expand_test.cpp
-atf_c___detail_expand_test_LDADD = atf-c++/detail/libtest_helpers.la libatf-c++.la
+atf_c___detail_expand_test_LDADD = atf-c++/detail/libtest_helpers.la $(ATF_CXX_LIBS)
tests_atf_c___detail_PROGRAMS += atf-c++/detail/fs_test
atf_c___detail_fs_test_SOURCES = atf-c++/detail/fs_test.cpp
-atf_c___detail_fs_test_LDADD = atf-c++/detail/libtest_helpers.la libatf-c++.la
+atf_c___detail_fs_test_LDADD = atf-c++/detail/libtest_helpers.la $(ATF_CXX_LIBS)
tests_atf_c___detail_PROGRAMS += atf-c++/detail/parser_test
atf_c___detail_parser_test_SOURCES = atf-c++/detail/parser_test.cpp
-atf_c___detail_parser_test_LDADD = atf-c++/detail/libtest_helpers.la libatf-c++.la
+atf_c___detail_parser_test_LDADD = atf-c++/detail/libtest_helpers.la $(ATF_CXX_LIBS)
tests_atf_c___detail_PROGRAMS += atf-c++/detail/process_test
atf_c___detail_process_test_SOURCES = atf-c++/detail/process_test.cpp
-atf_c___detail_process_test_LDADD = atf-c++/detail/libtest_helpers.la libatf-c++.la
+atf_c___detail_process_test_LDADD = atf-c++/detail/libtest_helpers.la $(ATF_CXX_LIBS)
tests_atf_c___detail_PROGRAMS += atf-c++/detail/sanity_test
atf_c___detail_sanity_test_SOURCES = atf-c++/detail/sanity_test.cpp
-atf_c___detail_sanity_test_LDADD = atf-c++/detail/libtest_helpers.la libatf-c++.la
+atf_c___detail_sanity_test_LDADD = atf-c++/detail/libtest_helpers.la $(ATF_CXX_LIBS)
tests_atf_c___detail_PROGRAMS += atf-c++/detail/text_test
atf_c___detail_text_test_SOURCES = atf-c++/detail/text_test.cpp
-atf_c___detail_text_test_LDADD = atf-c++/detail/libtest_helpers.la libatf-c++.la
+atf_c___detail_text_test_LDADD = atf-c++/detail/libtest_helpers.la $(ATF_CXX_LIBS)
tests_atf_c___detail_PROGRAMS += atf-c++/detail/ui_test
atf_c___detail_ui_test_SOURCES = atf-c++/detail/ui_test.cpp
-atf_c___detail_ui_test_LDADD = atf-c++/detail/libtest_helpers.la libatf-c++.la
+atf_c___detail_ui_test_LDADD = atf-c++/detail/libtest_helpers.la $(ATF_CXX_LIBS)
# vim: syntax=make:noexpandtab:shiftwidth=8:softtabstop=8
diff --git a/unit/atf-src/atf-c++/detail/application.cpp b/unit/atf-src/atf-c++/detail/application.cpp
index bc1dac03..878b010b 100644
--- a/unit/atf-src/atf-c++/detail/application.cpp
+++ b/unit/atf-src/atf-c++/detail/application.cpp
@@ -1,7 +1,7 @@
//
// Automated Testing Framework (atf)
//
-// Copyright (c) 2007, 2008, 2010 The NetBSD Foundation, Inc.
+// Copyright (c) 2007 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@@ -41,6 +41,10 @@ extern "C" {
#include <cstring>
#include <iostream>
+extern "C" {
+#include "atf-c/defs.h"
+}
+
#include "application.hpp"
#include "sanity.hpp"
#include "ui.hpp"
@@ -151,7 +155,8 @@ impl::app::specific_options(void)
}
void
-impl::app::process_option(int ch, const char* arg)
+impl::app::process_option(int ch ATF_DEFS_ATTRIBUTE_UNUSED,
+ const char* arg ATF_DEFS_ATTRIBUTE_UNUSED)
{
}
@@ -178,6 +183,7 @@ impl::app::process_options(void)
}
int ch;
+ const int old_opterr = ::opterr;
::opterr = 0;
while ((ch = ::getopt(m_argc, m_argv, optstr.c_str())) != -1) {
switch (ch) {
@@ -201,6 +207,7 @@ impl::app::process_options(void)
m_argv += ::optind;
// Clear getopt state just in case the test wants to use it.
+ opterr = old_opterr;
optind = 1;
#if defined(HAVE_OPTRESET)
optreset = 1;
diff --git a/unit/atf-src/atf-c++/detail/application.hpp b/unit/atf-src/atf-c++/detail/application.hpp
index 98644211..9d1f2420 100644
--- a/unit/atf-src/atf-c++/detail/application.hpp
+++ b/unit/atf-src/atf-c++/detail/application.hpp
@@ -1,7 +1,7 @@
//
// Automated Testing Framework (atf)
//
-// Copyright (c) 2007, 2008, 2010 The NetBSD Foundation, Inc.
+// Copyright (c) 2007 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
diff --git a/unit/atf-src/atf-c++/detail/application_test.cpp b/unit/atf-src/atf-c++/detail/application_test.cpp
index ca7dfe24..2a788bfb 100644
--- a/unit/atf-src/atf-c++/detail/application_test.cpp
+++ b/unit/atf-src/atf-c++/detail/application_test.cpp
@@ -52,13 +52,16 @@ public:
char *const argv[] = { arg1, arg2, arg3, arg4, NULL };
int ch;
+ bool zflag;
// Given that this obviously is an application, and that we used the
// same driver to start, we can test getopt(3) right here without doing
// any fancy stuff.
+ zflag = false;
while ((ch = ::getopt(argc, argv, ":Z")) != -1) {
switch (ch) {
case 'Z':
+ zflag = true;
break;
case '?':
@@ -68,6 +71,7 @@ public:
}
}
+ ATF_REQUIRE(zflag);
ATF_REQUIRE_EQ(1, argc - optind);
ATF_REQUIRE_EQ(std::string("foo"), argv[optind]);
diff --git a/unit/atf-src/atf-c++/detail/auto_array.hpp b/unit/atf-src/atf-c++/detail/auto_array.hpp
new file mode 100644
index 00000000..1459284e
--- /dev/null
+++ b/unit/atf-src/atf-c++/detail/auto_array.hpp
@@ -0,0 +1,179 @@
+//
+// Automated Testing Framework (atf)
+//
+// Copyright (c) 2007 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.
+//
+
+#if !defined(_ATF_CXX_AUTO_ARRAY_HPP_)
+#define _ATF_CXX_AUTO_ARRAY_HPP_
+
+#include <cstddef>
+
+namespace atf {
+
+// ------------------------------------------------------------------------
+// The "auto_array" class.
+// ------------------------------------------------------------------------
+
+template< class T >
+struct auto_array_ref {
+ T* m_ptr;
+
+ explicit auto_array_ref(T*);
+};
+
+template< class T >
+auto_array_ref< T >::auto_array_ref(T* ptr) :
+ m_ptr(ptr)
+{
+}
+
+template< class T >
+class auto_array {
+ T* m_ptr;
+
+public:
+ auto_array(T* = NULL) throw();
+ auto_array(auto_array< T >&) throw();
+ auto_array(auto_array_ref< T >) throw();
+ ~auto_array(void) throw();
+
+ T* get(void) throw();
+ const T* get(void) const throw();
+ T* release(void) throw();
+ void reset(T* = NULL) throw();
+
+ auto_array< T >& operator=(auto_array< T >&) throw();
+ auto_array< T >& operator=(auto_array_ref< T >) throw();
+
+ T& operator[](int) throw();
+ operator auto_array_ref< T >(void) throw();
+};
+
+template< class T >
+auto_array< T >::auto_array(T* ptr)
+ throw() :
+ m_ptr(ptr)
+{
+}
+
+template< class T >
+auto_array< T >::auto_array(auto_array< T >& ptr)
+ throw() :
+ m_ptr(ptr.release())
+{
+}
+
+template< class T >
+auto_array< T >::auto_array(auto_array_ref< T > ref)
+ throw() :
+ m_ptr(ref.m_ptr)
+{
+}
+
+template< class T >
+auto_array< T >::~auto_array(void)
+ throw()
+{
+ if (m_ptr != NULL)
+ delete [] m_ptr;
+}
+
+template< class T >
+T*
+auto_array< T >::get(void)
+ throw()
+{
+ return m_ptr;
+}
+
+template< class T >
+const T*
+auto_array< T >::get(void)
+ const throw()
+{
+ return m_ptr;
+}
+
+template< class T >
+T*
+auto_array< T >::release(void)
+ throw()
+{
+ T* ptr = m_ptr;
+ m_ptr = NULL;
+ return ptr;
+}
+
+template< class T >
+void
+auto_array< T >::reset(T* ptr)
+ throw()
+{
+ if (m_ptr != NULL)
+ delete [] m_ptr;
+ m_ptr = ptr;
+}
+
+template< class T >
+auto_array< T >&
+auto_array< T >::operator=(auto_array< T >& ptr)
+ throw()
+{
+ reset(ptr.release());
+ return *this;
+}
+
+template< class T >
+auto_array< T >&
+auto_array< T >::operator=(auto_array_ref< T > ref)
+ throw()
+{
+ if (m_ptr != ref.m_ptr) {
+ delete [] m_ptr;
+ m_ptr = ref.m_ptr;
+ }
+ return *this;
+}
+
+template< class T >
+T&
+auto_array< T >::operator[](int pos)
+ throw()
+{
+ return m_ptr[pos];
+}
+
+template< class T >
+auto_array< T >::operator auto_array_ref< T >(void)
+ throw()
+{
+ return auto_array_ref< T >(release());
+}
+
+} // namespace atf
+
+#endif // !defined(_ATF_CXX_AUTO_ARRAY_HPP_)
diff --git a/unit/atf-src/atf-c++/detail/auto_array_test.cpp b/unit/atf-src/atf-c++/detail/auto_array_test.cpp
new file mode 100644
index 00000000..dcfe4155
--- /dev/null
+++ b/unit/atf-src/atf-c++/detail/auto_array_test.cpp
@@ -0,0 +1,304 @@
+//
+// Automated Testing Framework (atf)
+//
+// Copyright (c) 2007 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.
+//
+
+extern "C" {
+#include <sys/types.h>
+}
+
+#include <iostream>
+
+#include "atf-c/defs.h"
+
+#include "../macros.hpp"
+
+#include "auto_array.hpp"
+
+// ------------------------------------------------------------------------
+// Tests for the "auto_array" class.
+// ------------------------------------------------------------------------
+
+class test_array {
+public:
+ int m_value;
+
+ static ssize_t m_nblocks;
+
+ static
+ atf::auto_array< test_array >
+ do_copy(atf::auto_array< test_array >& ta)
+ {
+ return atf::auto_array< test_array >(ta);
+ }
+
+ void* operator new(size_t size ATF_DEFS_ATTRIBUTE_UNUSED)
+ {
+ ATF_FAIL("New called but should have been new[]");
+ return new int(5);
+ }
+
+ void* operator new[](size_t size)
+ {
+ m_nblocks++;
+ void* mem = ::operator new(size);
+ std::cout << "Allocated 'test_array' object " << mem << "\n";
+ return mem;
+ }
+
+ void operator delete(void* mem ATF_DEFS_ATTRIBUTE_UNUSED)
+ {
+ ATF_FAIL("Delete called but should have been delete[]");
+ }
+
+ void operator delete[](void* mem)
+ {
+ std::cout << "Releasing 'test_array' object " << mem << "\n";
+ if (m_nblocks == 0)
+ ATF_FAIL("Unbalanced delete[]");
+ m_nblocks--;
+ ::operator delete(mem);
+ }
+};
+
+ssize_t test_array::m_nblocks = 0;
+
+ATF_TEST_CASE(auto_array_scope);
+ATF_TEST_CASE_HEAD(auto_array_scope)
+{
+ set_md_var("descr", "Tests the automatic scope handling in the "
+ "auto_array smart pointer class");
+}
+ATF_TEST_CASE_BODY(auto_array_scope)
+{
+ using atf::auto_array;
+
+ ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
+ {
+ auto_array< test_array > t(new test_array[10]);
+ ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
+ }
+ ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
+}
+
+ATF_TEST_CASE(auto_array_copy);
+ATF_TEST_CASE_HEAD(auto_array_copy)
+{
+ set_md_var("descr", "Tests the auto_array smart pointer class' copy "
+ "constructor");
+}
+ATF_TEST_CASE_BODY(auto_array_copy)
+{
+ using atf::auto_array;
+
+ ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
+ {
+ auto_array< test_array > t1(new test_array[10]);
+ ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
+
+ {
+ auto_array< test_array > t2(t1);
+ ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
+ }
+ ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
+ }
+ ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
+}
+
+ATF_TEST_CASE(auto_array_copy_ref);
+ATF_TEST_CASE_HEAD(auto_array_copy_ref)
+{
+ set_md_var("descr", "Tests the auto_array smart pointer class' copy "
+ "constructor through the auxiliary auto_array_ref object");
+}
+ATF_TEST_CASE_BODY(auto_array_copy_ref)
+{
+ using atf::auto_array;
+
+ ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
+ {
+ auto_array< test_array > t1(new test_array[10]);
+ ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
+
+ {
+ auto_array< test_array > t2 = test_array::do_copy(t1);
+ ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
+ }
+ ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
+ }
+ ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
+}
+
+ATF_TEST_CASE(auto_array_get);
+ATF_TEST_CASE_HEAD(auto_array_get)
+{
+ set_md_var("descr", "Tests the auto_array smart pointer class' get "
+ "method");
+}
+ATF_TEST_CASE_BODY(auto_array_get)
+{
+ using atf::auto_array;
+
+ test_array* ta = new test_array[10];
+ auto_array< test_array > t(ta);
+ ATF_REQUIRE_EQ(t.get(), ta);
+}
+
+ATF_TEST_CASE(auto_array_release);
+ATF_TEST_CASE_HEAD(auto_array_release)
+{
+ set_md_var("descr", "Tests the auto_array smart pointer class' release "
+ "method");
+}
+ATF_TEST_CASE_BODY(auto_array_release)
+{
+ using atf::auto_array;
+
+ test_array* ta1 = new test_array[10];
+ {
+ auto_array< test_array > t(ta1);
+ ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
+ test_array* ta2 = t.release();
+ ATF_REQUIRE_EQ(ta2, ta1);
+ ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
+ }
+ ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
+ delete [] ta1;
+}
+
+ATF_TEST_CASE(auto_array_reset);
+ATF_TEST_CASE_HEAD(auto_array_reset)
+{
+ set_md_var("descr", "Tests the auto_array smart pointer class' reset "
+ "method");
+}
+ATF_TEST_CASE_BODY(auto_array_reset)
+{
+ using atf::auto_array;
+
+ test_array* ta1 = new test_array[10];
+ test_array* ta2 = new test_array[10];
+ ATF_REQUIRE_EQ(test_array::m_nblocks, 2);
+
+ {
+ auto_array< test_array > t(ta1);
+ ATF_REQUIRE_EQ(test_array::m_nblocks, 2);
+ t.reset(ta2);
+ ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
+ t.reset();
+ ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
+ }
+ ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
+}
+
+ATF_TEST_CASE(auto_array_assign);
+ATF_TEST_CASE_HEAD(auto_array_assign)
+{
+ set_md_var("descr", "Tests the auto_array smart pointer class' "
+ "assignment operator");
+}
+ATF_TEST_CASE_BODY(auto_array_assign)
+{
+ using atf::auto_array;
+
+ ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
+ {
+ auto_array< test_array > t1(new test_array[10]);
+ ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
+
+ {
+ auto_array< test_array > t2;
+ t2 = t1;
+ ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
+ }
+ ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
+ }
+ ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
+}
+
+ATF_TEST_CASE(auto_array_assign_ref);
+ATF_TEST_CASE_HEAD(auto_array_assign_ref)
+{
+ set_md_var("descr", "Tests the auto_array smart pointer class' "
+ "assignment operator through the auxiliary auto_array_ref "
+ "object");
+}
+ATF_TEST_CASE_BODY(auto_array_assign_ref)
+{
+ using atf::auto_array;
+
+ ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
+ {
+ auto_array< test_array > t1(new test_array[10]);
+ ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
+
+ {
+ auto_array< test_array > t2;
+ t2 = test_array::do_copy(t1);
+ ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
+ }
+ ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
+ }
+ ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
+}
+
+ATF_TEST_CASE(auto_array_access);
+ATF_TEST_CASE_HEAD(auto_array_access)
+{
+ set_md_var("descr", "Tests the auto_array smart pointer class' access "
+ "operator");
+}
+ATF_TEST_CASE_BODY(auto_array_access)
+{
+ using atf::auto_array;
+
+ auto_array< test_array > t(new test_array[10]);
+
+ for (int i = 0; i < 10; i++)
+ t[i].m_value = i * 2;
+
+ for (int i = 0; i < 10; i++)
+ ATF_REQUIRE_EQ(t[i].m_value, i * 2);
+}
+
+// ------------------------------------------------------------------------
+// Main.
+// ------------------------------------------------------------------------
+
+ATF_INIT_TEST_CASES(tcs)
+{
+ // Add the test for the "auto_array" class.
+ ATF_ADD_TEST_CASE(tcs, auto_array_scope);
+ ATF_ADD_TEST_CASE(tcs, auto_array_copy);
+ ATF_ADD_TEST_CASE(tcs, auto_array_copy_ref);
+ ATF_ADD_TEST_CASE(tcs, auto_array_get);
+ ATF_ADD_TEST_CASE(tcs, auto_array_release);
+ ATF_ADD_TEST_CASE(tcs, auto_array_reset);
+ ATF_ADD_TEST_CASE(tcs, auto_array_assign);
+ ATF_ADD_TEST_CASE(tcs, auto_array_assign_ref);
+ ATF_ADD_TEST_CASE(tcs, auto_array_access);
+}
diff --git a/unit/atf-src/atf-c++/detail/env.cpp b/unit/atf-src/atf-c++/detail/env.cpp
index 2d345aab..5ca7f09c 100644
--- a/unit/atf-src/atf-c++/detail/env.cpp
+++ b/unit/atf-src/atf-c++/detail/env.cpp
@@ -1,7 +1,7 @@
//
// Automated Testing Framework (atf)
//
-// Copyright (c) 2007, 2008 The NetBSD Foundation, Inc.
+// Copyright (c) 2007 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
diff --git a/unit/atf-src/atf-c++/detail/env.hpp b/unit/atf-src/atf-c++/detail/env.hpp
index 97ce87bc..afdf69be 100644
--- a/unit/atf-src/atf-c++/detail/env.hpp
+++ b/unit/atf-src/atf-c++/detail/env.hpp
@@ -1,7 +1,7 @@
//
// Automated Testing Framework (atf)
//
-// Copyright (c) 2007, 2008 The NetBSD Foundation, Inc.
+// Copyright (c) 2007 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
diff --git a/unit/atf-src/atf-c++/detail/env_test.cpp b/unit/atf-src/atf-c++/detail/env_test.cpp
index 93678549..a7b681d1 100644
--- a/unit/atf-src/atf-c++/detail/env_test.cpp
+++ b/unit/atf-src/atf-c++/detail/env_test.cpp
@@ -1,7 +1,7 @@
//
// Automated Testing Framework (atf)
//
-// Copyright (c) 2007, 2008, 2009 The NetBSD Foundation, Inc.
+// Copyright (c) 2007 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
diff --git a/unit/atf-src/atf-c++/detail/exceptions.cpp b/unit/atf-src/atf-c++/detail/exceptions.cpp
index 8c15b30e..79c5b489 100644
--- a/unit/atf-src/atf-c++/detail/exceptions.cpp
+++ b/unit/atf-src/atf-c++/detail/exceptions.cpp
@@ -1,7 +1,7 @@
//
// Automated Testing Framework (atf)
//
-// Copyright (c) 2007, 2008, 2009 The NetBSD Foundation, Inc.
+// Copyright (c) 2007 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@@ -34,6 +34,7 @@
#include <cstdarg>
#include <cstdio>
#include <cstring>
+#include <new>
extern "C" {
#include "../../atf-c/error.h"
diff --git a/unit/atf-src/atf-c++/detail/exceptions.hpp b/unit/atf-src/atf-c++/detail/exceptions.hpp
index f10dfd5d..f655a84d 100644
--- a/unit/atf-src/atf-c++/detail/exceptions.hpp
+++ b/unit/atf-src/atf-c++/detail/exceptions.hpp
@@ -1,7 +1,7 @@
//
// Automated Testing Framework (atf)
//
-// Copyright (c) 2007, 2008 The NetBSD Foundation, Inc.
+// Copyright (c) 2007 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@@ -31,6 +31,7 @@
#define _ATF_CXX_EXCEPTIONS_HPP_
#include <stdexcept>
+#include <string>
extern "C" {
struct atf_error;
diff --git a/unit/atf-src/atf-c++/detail/exceptions_test.cpp b/unit/atf-src/atf-c++/detail/exceptions_test.cpp
index b1c9eadf..821c192d 100644
--- a/unit/atf-src/atf-c++/detail/exceptions_test.cpp
+++ b/unit/atf-src/atf-c++/detail/exceptions_test.cpp
@@ -32,6 +32,7 @@ extern "C" {
}
#include <cstdio>
+#include <new>
#include "../macros.hpp"
diff --git a/unit/atf-src/atf-c++/detail/expand.cpp b/unit/atf-src/atf-c++/detail/expand.cpp
index 03a70db6..f6f9b688 100644
--- a/unit/atf-src/atf-c++/detail/expand.cpp
+++ b/unit/atf-src/atf-c++/detail/expand.cpp
@@ -1,7 +1,7 @@
//
// Automated Testing Framework (atf)
//
-// Copyright (c) 2007, 2008, 2010 The NetBSD Foundation, Inc.
+// Copyright (c) 2007 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
diff --git a/unit/atf-src/atf-c++/detail/expand.hpp b/unit/atf-src/atf-c++/detail/expand.hpp
index 6419f512..7f4071ee 100644
--- a/unit/atf-src/atf-c++/detail/expand.hpp
+++ b/unit/atf-src/atf-c++/detail/expand.hpp
@@ -1,7 +1,7 @@
//
// Automated Testing Framework (atf)
//
-// Copyright (c) 2007, 2008, 2010 The NetBSD Foundation, Inc.
+// Copyright (c) 2007 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
diff --git a/unit/atf-src/atf-c++/detail/expand_test.cpp b/unit/atf-src/atf-c++/detail/expand_test.cpp
index 55ea718f..222ab3a9 100644
--- a/unit/atf-src/atf-c++/detail/expand_test.cpp
+++ b/unit/atf-src/atf-c++/detail/expand_test.cpp
@@ -1,7 +1,7 @@
//
// Automated Testing Framework (atf)
//
-// Copyright (c) 2007, 2008, 2009 The NetBSD Foundation, Inc.
+// Copyright (c) 2007 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
diff --git a/unit/atf-src/atf-c++/detail/fs.cpp b/unit/atf-src/atf-c++/detail/fs.cpp
index 31ef1609..3517e261 100644
--- a/unit/atf-src/atf-c++/detail/fs.cpp
+++ b/unit/atf-src/atf-c++/detail/fs.cpp
@@ -1,7 +1,7 @@
//
// Automated Testing Framework (atf)
//
-// Copyright (c) 2007, 2008, 2009 The NetBSD Foundation, Inc.
+// Copyright (c) 2007 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
diff --git a/unit/atf-src/atf-c++/detail/fs.hpp b/unit/atf-src/atf-c++/detail/fs.hpp
index 8d7a7ba5..4ffb39b2 100644
--- a/unit/atf-src/atf-c++/detail/fs.hpp
+++ b/unit/atf-src/atf-c++/detail/fs.hpp
@@ -1,7 +1,7 @@
//
// Automated Testing Framework (atf)
//
-// Copyright (c) 2007, 2008, 2009 The NetBSD Foundation, Inc.
+// Copyright (c) 2007 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
diff --git a/unit/atf-src/atf-c++/detail/fs_test.cpp b/unit/atf-src/atf-c++/detail/fs_test.cpp
index 8fe3dfd8..6cf9bf6c 100644
--- a/unit/atf-src/atf-c++/detail/fs_test.cpp
+++ b/unit/atf-src/atf-c++/detail/fs_test.cpp
@@ -1,7 +1,7 @@
//
// Automated Testing Framework (atf)
//
-// Copyright (c) 2007, 2008, 2009, 2010 The NetBSD Foundation, Inc.
+// Copyright (c) 2007 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
diff --git a/unit/atf-src/atf-c++/detail/parser.cpp b/unit/atf-src/atf-c++/detail/parser.cpp
index 54359204..7e7f680c 100644
--- a/unit/atf-src/atf-c++/detail/parser.cpp
+++ b/unit/atf-src/atf-c++/detail/parser.cpp
@@ -1,7 +1,7 @@
//
// Automated Testing Framework (atf)
//
-// Copyright (c) 2007, 2008, 2010 The NetBSD Foundation, Inc.
+// Copyright (c) 2007 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
diff --git a/unit/atf-src/atf-c++/detail/parser.hpp b/unit/atf-src/atf-c++/detail/parser.hpp
index 06012643..f1595f53 100644
--- a/unit/atf-src/atf-c++/detail/parser.hpp
+++ b/unit/atf-src/atf-c++/detail/parser.hpp
@@ -1,7 +1,7 @@
//
// Automated Testing Framework (atf)
//
-// Copyright (c) 2007, 2008, 2010 The NetBSD Foundation, Inc.
+// Copyright (c) 2007 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
diff --git a/unit/atf-src/atf-c++/detail/parser_test.cpp b/unit/atf-src/atf-c++/detail/parser_test.cpp
index 5d890147..491c0145 100644
--- a/unit/atf-src/atf-c++/detail/parser_test.cpp
+++ b/unit/atf-src/atf-c++/detail/parser_test.cpp
@@ -1,7 +1,7 @@
//
// Automated Testing Framework (atf)
//
-// Copyright (c) 2007, 2008, 2009, 2010 The NetBSD Foundation, Inc.
+// Copyright (c) 2007 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
diff --git a/unit/atf-src/atf-c++/detail/process.cpp b/unit/atf-src/atf-c++/detail/process.cpp
index e442622e..f7ae6d49 100644
--- a/unit/atf-src/atf-c++/detail/process.cpp
+++ b/unit/atf-src/atf-c++/detail/process.cpp
@@ -1,7 +1,7 @@
//
// Automated Testing Framework (atf)
//
-// Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
+// Copyright (c) 2008 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@@ -50,10 +50,10 @@ namespace impl = atf::process;
// ------------------------------------------------------------------------
template< class C >
-atf::utils::auto_array< const char* >
+atf::auto_array< const char* >
collection_to_argv(const C& c)
{
- atf::utils::auto_array< const char* > argv(new const char*[c.size() + 1]);
+ atf::auto_array< const char* > argv(new const char*[c.size() + 1]);
std::size_t pos = 0;
for (typename C::const_iterator iter = c.begin(); iter != c.end();
diff --git a/unit/atf-src/atf-c++/detail/process.hpp b/unit/atf-src/atf-c++/detail/process.hpp
index 8a020b6e..bc55a572 100644
--- a/unit/atf-src/atf-c++/detail/process.hpp
+++ b/unit/atf-src/atf-c++/detail/process.hpp
@@ -1,7 +1,7 @@
//
// Automated Testing Framework (atf)
//
-// Copyright (c) 2008, 2009, 2010 The NetBSD Foundation, Inc.
+// Copyright (c) 2008 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@@ -41,11 +41,10 @@ extern "C" {
#include <string>
#include <vector>
+#include "auto_array.hpp"
#include "exceptions.hpp"
#include "fs.hpp"
-#include "../utils.hpp"
-
namespace atf {
namespace process {
@@ -64,7 +63,7 @@ class argv_array {
// std::tr1::shared_array instead when it becomes widely available.
// The reason would be to remove all copy constructors and assignment
// operators from this class.
- utils::auto_array< const char* > m_exec_argv;
+ auto_array< const char* > m_exec_argv;
void ctor_init_exec_argv(void);
public:
@@ -118,7 +117,7 @@ class stream_capture : basic_stream {
child fork(void (*)(void*), const OutStream&, const ErrStream&, void*);
template< class OutStream, class ErrStream > friend
status exec(const atf::fs::path&, const argv_array&,
- const OutStream&, const ErrStream&);
+ const OutStream&, const ErrStream&, void (*)(void));
public:
stream_capture(void);
@@ -130,7 +129,7 @@ class stream_connect : basic_stream {
child fork(void (*)(void*), const OutStream&, const ErrStream&, void*);
template< class OutStream, class ErrStream > friend
status exec(const atf::fs::path&, const argv_array&,
- const OutStream&, const ErrStream&);
+ const OutStream&, const ErrStream&, void (*)(void));
public:
stream_connect(const int, const int);
@@ -142,7 +141,7 @@ class stream_inherit : basic_stream {
child fork(void (*)(void*), const OutStream&, const ErrStream&, void*);
template< class OutStream, class ErrStream > friend
status exec(const atf::fs::path&, const argv_array&,
- const OutStream&, const ErrStream&);
+ const OutStream&, const ErrStream&, void (*)(void));
public:
stream_inherit(void);
@@ -154,7 +153,7 @@ class stream_redirect_fd : basic_stream {
child fork(void (*)(void*), const OutStream&, const ErrStream&, void*);
template< class OutStream, class ErrStream > friend
status exec(const atf::fs::path&, const argv_array&,
- const OutStream&, const ErrStream&);
+ const OutStream&, const ErrStream&, void (*)(void));
public:
stream_redirect_fd(const int);
@@ -166,7 +165,7 @@ class stream_redirect_path : basic_stream {
child fork(void (*)(void*), const OutStream&, const ErrStream&, void*);
template< class OutStream, class ErrStream > friend
status exec(const atf::fs::path&, const argv_array&,
- const OutStream&, const ErrStream&);
+ const OutStream&, const ErrStream&, void (*)(void));
public:
stream_redirect_path(const fs::path&);
@@ -182,7 +181,7 @@ class status {
friend class child;
template< class OutStream, class ErrStream > friend
status exec(const atf::fs::path&, const argv_array&,
- const OutStream&, const ErrStream&);
+ const OutStream&, const ErrStream&, void (*)(void));
status(atf_process_status_t&);
@@ -249,7 +248,8 @@ fork(void (*start)(void*), const OutStream& outsb,
template< class OutStream, class ErrStream >
status
exec(const atf::fs::path& prog, const argv_array& argv,
- const OutStream& outsb, const ErrStream& errsb)
+ const OutStream& outsb, const ErrStream& errsb,
+ void (*prehook)(void))
{
atf_process_status_t s;
@@ -257,13 +257,22 @@ exec(const atf::fs::path& prog, const argv_array& argv,
atf_error_t err = atf_process_exec_array(&s, prog.c_path(),
argv.exec_argv(),
outsb.get_sb(),
- errsb.get_sb());
+ errsb.get_sb(),
+ prehook);
if (atf_is_error(err))
throw_atf_error(err);
return status(s);
}
+template< class OutStream, class ErrStream >
+status
+exec(const atf::fs::path& prog, const argv_array& argv,
+ const OutStream& outsb, const ErrStream& errsb)
+{
+ return exec(prog, argv, outsb, errsb, NULL);
+}
+
} // namespace process
} // namespace atf
diff --git a/unit/atf-src/atf-c++/detail/process_test.cpp b/unit/atf-src/atf-c++/detail/process_test.cpp
index ea2bc9f5..d13ab945 100644
--- a/unit/atf-src/atf-c++/detail/process_test.cpp
+++ b/unit/atf-src/atf-c++/detail/process_test.cpp
@@ -1,7 +1,7 @@
//
// Automated Testing Framework (atf)
//
-// Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
+// Copyright (c) 2008 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
diff --git a/unit/atf-src/atf-c++/detail/sanity.hpp b/unit/atf-src/atf-c++/detail/sanity.hpp
index 37ff3188..6021a6e6 100644
--- a/unit/atf-src/atf-c++/detail/sanity.hpp
+++ b/unit/atf-src/atf-c++/detail/sanity.hpp
@@ -1,7 +1,7 @@
//
// Automated Testing Framework (atf)
//
-// Copyright (c) 2007, 2008 The NetBSD Foundation, Inc.
+// Copyright (c) 2007 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
diff --git a/unit/atf-src/atf-c++/detail/test_helpers.cpp b/unit/atf-src/atf-c++/detail/test_helpers.cpp
index 8b2a7368..191649d0 100644
--- a/unit/atf-src/atf-c++/detail/test_helpers.cpp
+++ b/unit/atf-src/atf-c++/detail/test_helpers.cpp
@@ -1,7 +1,7 @@
//
// Automated Testing Framework (atf)
//
-// Copyright (c) 2009, 2010 The NetBSD Foundation, Inc.
+// Copyright (c) 2009 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@@ -27,10 +27,6 @@
// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
-extern "C" {
-#include <regex.h>
-}
-
#include <fstream>
#include <iostream>
#include <string>
@@ -45,27 +41,31 @@ extern "C" {
#include "test_helpers.hpp"
void
-build_check_cxx_o_aux(const atf::fs::path& sfile, const char* failmsg)
+build_check_cxx_o_aux(const atf::fs::path& sfile, const char* failmsg,
+ const bool expect_pass)
{
std::vector< std::string > optargs;
optargs.push_back("-I" + atf::config::get("atf_includedir"));
+ optargs.push_back("-Wall");
+ optargs.push_back("-Werror");
- if (!atf::check::build_cxx_o(sfile.str(), "test.o",
- atf::process::argv_array(optargs)))
+ const bool result = atf::check::build_cxx_o(
+ sfile.str(), "test.o", atf::process::argv_array(optargs));
+ if ((expect_pass && !result) || (!expect_pass && result))
ATF_FAIL(failmsg);
}
void
build_check_cxx_o(const atf::tests::tc& tc, const char* sfile,
- const char* failmsg)
+ const char* failmsg, const bool expect_pass)
{
const atf::fs::path sfilepath =
atf::fs::path(tc.get_config_var("srcdir")) / sfile;
- build_check_cxx_o_aux(sfilepath, failmsg);
+ build_check_cxx_o_aux(sfilepath, failmsg, expect_pass);
}
void
-header_check(const atf::tests::tc& tc, const char *hdrname)
+header_check(const char *hdrname)
{
std::ofstream srcfile("test.c");
ATF_REQUIRE(srcfile);
@@ -74,7 +74,7 @@ header_check(const atf::tests::tc& tc, const char *hdrname)
const std::string failmsg = std::string("Header check failed; ") +
hdrname + " is not self-contained";
- build_check_cxx_o_aux(atf::fs::path("test.c"), failmsg.c_str());
+ build_check_cxx_o_aux(atf::fs::path("test.c"), failmsg.c_str(), true);
}
atf::fs::path
@@ -84,43 +84,6 @@ get_process_helpers_path(const atf::tests::tc& tc)
".." / "atf-c" / "detail" / "process_helpers";
}
-bool
-grep_file(const char* name, const char* regex)
-{
- std::ifstream is(name);
- ATF_REQUIRE(is);
-
- bool found = false;
-
- std::string line;
- std::getline(is, line);
- while (!found && is.good()) {
- if (grep_string(line, regex))
- found = true;
- else
- std::getline(is, line);
- }
-
- return found;
-}
-
-bool
-grep_string(const std::string& str, const char* regex)
-{
- int res;
- regex_t preg;
-
- std::cout << "Looking for '" << regex << "' in '" << str << "'\n";
- ATF_REQUIRE(::regcomp(&preg, regex, REG_EXTENDED) == 0);
-
- res = ::regexec(&preg, str.c_str(), 0, NULL, 0);
- ATF_REQUIRE(res == 0 || res == REG_NOMATCH);
-
- ::regfree(&preg);
-
- return res == 0;
-}
-
void
test_helpers_detail::check_equal(const char* expected[],
const string_vector& actual)
diff --git a/unit/atf-src/atf-c++/detail/test_helpers.hpp b/unit/atf-src/atf-c++/detail/test_helpers.hpp
index 7da2ac48..4a39331d 100644
--- a/unit/atf-src/atf-c++/detail/test_helpers.hpp
+++ b/unit/atf-src/atf-c++/detail/test_helpers.hpp
@@ -1,7 +1,7 @@
//
// Automated Testing Framework (atf)
//
-// Copyright (c) 2009, 2010 The NetBSD Foundation, Inc.
+// Copyright (c) 2009 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@@ -53,7 +53,7 @@
} \
ATF_TEST_CASE_BODY(name) \
{ \
- header_check(*this, hdrname); \
+ header_check(hdrname); \
}
#define BUILD_TC(name, sfile, descr, failmsg) \
@@ -64,7 +64,18 @@
} \
ATF_TEST_CASE_BODY(name) \
{ \
- build_check_cxx_o(*this, sfile, failmsg); \
+ build_check_cxx_o(*this, sfile, failmsg, true); \
+ }
+
+#define BUILD_TC_FAIL(name, sfile, descr, failmsg) \
+ ATF_TEST_CASE(name); \
+ ATF_TEST_CASE_HEAD(name) \
+ { \
+ set_md_var("descr", descr); \
+ } \
+ ATF_TEST_CASE_BODY(name) \
+ { \
+ build_check_cxx_o(*this, sfile, failmsg, false); \
}
namespace atf {
@@ -73,11 +84,9 @@ class tc;
}
}
-void header_check(const atf::tests::tc&, const char*);
-void build_check_cxx_o(const atf::tests::tc&, const char*, const char*);
+void header_check(const char*);
+void build_check_cxx_o(const atf::tests::tc&, const char*, const char*, bool);
atf::fs::path get_process_helpers_path(const atf::tests::tc&);
-bool grep_file(const char*, const char*);
-bool grep_string(const std::string&, const char*);
struct run_h_tc_data {
const atf::tests::vars_map& m_config;
diff --git a/unit/atf-src/atf-c++/detail/text.cpp b/unit/atf-src/atf-c++/detail/text.cpp
index a97c230d..66eebf0a 100644
--- a/unit/atf-src/atf-c++/detail/text.cpp
+++ b/unit/atf-src/atf-c++/detail/text.cpp
@@ -1,7 +1,7 @@
//
// Automated Testing Framework (atf)
//
-// Copyright (c) 2007, 2008, 2010 The NetBSD Foundation, Inc.
+// Copyright (c) 2007 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@@ -133,3 +133,28 @@ impl::to_bool(const std::string& str)
return b;
}
+
+int64_t
+impl::to_bytes(std::string str)
+{
+ if (str.empty())
+ throw std::runtime_error("Empty value");
+
+ const char unit = str[str.length() - 1];
+ int64_t multiplier;
+ switch (unit) {
+ case 'k': case 'K': multiplier = 1 << 10; break;
+ case 'm': case 'M': multiplier = 1 << 20; break;
+ case 'g': case 'G': multiplier = 1 << 30; break;
+ case 't': case 'T': multiplier = int64_t(1) << 40; break;
+ default:
+ if (!std::isdigit(unit))
+ throw std::runtime_error(std::string("Unknown size unit '") + unit
+ + "'");
+ multiplier = 1;
+ }
+ if (multiplier != 1)
+ str.erase(str.length() - 1);
+
+ return to_type< int64_t >(str) * multiplier;
+}
diff --git a/unit/atf-src/atf-c++/detail/text.hpp b/unit/atf-src/atf-c++/detail/text.hpp
index 88896e3c..6a1b027c 100644
--- a/unit/atf-src/atf-c++/detail/text.hpp
+++ b/unit/atf-src/atf-c++/detail/text.hpp
@@ -1,7 +1,7 @@
//
// Automated Testing Framework (atf)
//
-// Copyright (c) 2007, 2008, 2010 The NetBSD Foundation, Inc.
+// Copyright (c) 2007 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@@ -30,6 +30,10 @@
#if !defined(_ATF_CXX_TEXT_HPP_)
#define _ATF_CXX_TEXT_HPP_
+extern "C" {
+#include <stdint.h>
+}
+
#include <sstream>
#include <stdexcept>
#include <string>
@@ -98,6 +102,11 @@ std::string trim(const std::string&);
bool to_bool(const std::string&);
//!
+//! \brief Converts the given string to a bytes size.
+//!
+int64_t to_bytes(std::string);
+
+//!
//! \brief Changes the case of a string to lowercase.
//!
//! Returns a new string that is a lowercased version of the original
@@ -133,7 +142,7 @@ to_type(const std::string& str)
std::istringstream ss(str);
T value;
ss >> value;
- if (!ss.eof() || (!ss.eof() && !ss.good()))
+ if (!ss.eof() || (ss.eof() && (ss.fail() || ss.bad())))
throw std::runtime_error("Cannot convert string to requested type");
return value;
}
diff --git a/unit/atf-src/atf-c++/detail/text_test.cpp b/unit/atf-src/atf-c++/detail/text_test.cpp
index 75e0386a..b7c0ba1a 100644
--- a/unit/atf-src/atf-c++/detail/text_test.cpp
+++ b/unit/atf-src/atf-c++/detail/text_test.cpp
@@ -1,7 +1,7 @@
//
// Automated Testing Framework (atf)
//
-// Copyright (c) 2007, 2008, 2009, 2010 The NetBSD Foundation, Inc.
+// Copyright (c) 2007 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@@ -310,6 +310,29 @@ ATF_TEST_CASE_BODY(to_bool)
ATF_REQUIRE_THROW(std::runtime_error, to_bool("false2"));
}
+ATF_TEST_CASE(to_bytes);
+ATF_TEST_CASE_HEAD(to_bytes)
+{
+ set_md_var("descr", "Tests the to_bytes function");
+}
+ATF_TEST_CASE_BODY(to_bytes)
+{
+ using atf::text::to_bytes;
+
+ ATF_REQUIRE_EQ(0, to_bytes("0"));
+ ATF_REQUIRE_EQ(12345, to_bytes("12345"));
+ ATF_REQUIRE_EQ(2 * 1024, to_bytes("2k"));
+ ATF_REQUIRE_EQ(4 * 1024 * 1024, to_bytes("4m"));
+ ATF_REQUIRE_EQ(int64_t(8) * 1024 * 1024 * 1024, to_bytes("8g"));
+ ATF_REQUIRE_EQ(int64_t(16) * 1024 * 1024 * 1024 * 1024, to_bytes("16t"));
+
+ ATF_REQUIRE_THROW_RE(std::runtime_error, "Empty", to_bytes(""));
+ ATF_REQUIRE_THROW_RE(std::runtime_error, "Unknown size unit 'd'",
+ to_bytes("12d"));
+ ATF_REQUIRE_THROW(std::runtime_error, to_bytes(" "));
+ ATF_REQUIRE_THROW(std::runtime_error, to_bytes(" k"));
+}
+
ATF_TEST_CASE(to_string);
ATF_TEST_CASE_HEAD(to_string)
{
@@ -335,6 +358,7 @@ ATF_TEST_CASE_BODY(to_type)
ATF_REQUIRE_EQ(to_type< int >("0"), 0);
ATF_REQUIRE_EQ(to_type< int >("1234"), 1234);
+ ATF_REQUIRE_THROW(std::runtime_error, to_type< int >(" "));
ATF_REQUIRE_THROW(std::runtime_error, to_type< int >("0 a"));
ATF_REQUIRE_THROW(std::runtime_error, to_type< int >("a"));
@@ -360,6 +384,7 @@ ATF_INIT_TEST_CASES(tcs)
ATF_ADD_TEST_CASE(tcs, split_delims);
ATF_ADD_TEST_CASE(tcs, trim);
ATF_ADD_TEST_CASE(tcs, to_bool);
+ ATF_ADD_TEST_CASE(tcs, to_bytes);
ATF_ADD_TEST_CASE(tcs, to_string);
ATF_ADD_TEST_CASE(tcs, to_type);
}
diff --git a/unit/atf-src/atf-c++/detail/ui.cpp b/unit/atf-src/atf-c++/detail/ui.cpp
index 8b6b7976..07bde4f8 100644
--- a/unit/atf-src/atf-c++/detail/ui.cpp
+++ b/unit/atf-src/atf-c++/detail/ui.cpp
@@ -1,7 +1,7 @@
//
// Automated Testing Framework (atf)
//
-// Copyright (c) 2007, 2008, 2010 The NetBSD Foundation, Inc.
+// Copyright (c) 2007 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@@ -28,11 +28,10 @@
//
extern "C" {
-#include <unistd.h>
-
#include <sys/ioctl.h>
#include <termios.h>
+#include <unistd.h>
}
#include <sstream>
diff --git a/unit/atf-src/atf-c++/detail/ui.hpp b/unit/atf-src/atf-c++/detail/ui.hpp
index c51c839f..1c81c56a 100644
--- a/unit/atf-src/atf-c++/detail/ui.hpp
+++ b/unit/atf-src/atf-c++/detail/ui.hpp
@@ -1,7 +1,7 @@
//
// Automated Testing Framework (atf)
//
-// Copyright (c) 2007, 2008 The NetBSD Foundation, Inc.
+// Copyright (c) 2007 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
diff --git a/unit/atf-src/atf-c++/macros.hpp b/unit/atf-src/atf-c++/macros.hpp
index 73eb71a1..c6ce9c2b 100644
--- a/unit/atf-src/atf-c++/macros.hpp
+++ b/unit/atf-src/atf-c++/macros.hpp
@@ -1,7 +1,7 @@
//
// Automated Testing Framework (atf)
//
-// Copyright (c) 2007, 2008, 2010 The NetBSD Foundation, Inc.
+// Copyright (c) 2007 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@@ -36,31 +36,48 @@
#include <atf-c++/tests.hpp>
+// Do not define inline methods for the test case classes. Doing so
+// significantly increases the memory requirements of GNU G++ during
+// compilation.
+
#define ATF_TEST_CASE_WITHOUT_HEAD(name) \
+ namespace { \
class atfu_tc_ ## name : public atf::tests::tc { \
void body(void) const; \
public: \
- atfu_tc_ ## name(void) : atf::tests::tc(#name, false) {} \
- };
+ atfu_tc_ ## name(void); \
+ }; \
+ static atfu_tc_ ## name* atfu_tcptr_ ## name; \
+ atfu_tc_ ## name::atfu_tc_ ## name(void) : atf::tests::tc(#name, false) {} \
+ }
#define ATF_TEST_CASE(name) \
+ namespace { \
class atfu_tc_ ## name : public atf::tests::tc { \
void head(void); \
void body(void) const; \
public: \
- atfu_tc_ ## name(void) : atf::tests::tc(#name, false) {} \
- };
+ atfu_tc_ ## name(void); \
+ }; \
+ static atfu_tc_ ## name* atfu_tcptr_ ## name; \
+ atfu_tc_ ## name::atfu_tc_ ## name(void) : atf::tests::tc(#name, false) {} \
+ }
#define ATF_TEST_CASE_WITH_CLEANUP(name) \
+ namespace { \
class atfu_tc_ ## name : public atf::tests::tc { \
void head(void); \
void body(void) const; \
void cleanup(void) const; \
public: \
- atfu_tc_ ## name(void) : atf::tests::tc(#name, true) {} \
- };
+ atfu_tc_ ## name(void); \
+ }; \
+ static atfu_tc_ ## name* atfu_tcptr_ ## name; \
+ atfu_tc_ ## name::atfu_tc_ ## name(void) : atf::tests::tc(#name, true) {} \
+ }
#define ATF_TEST_CASE_NAME(name) atfu_tc_ ## name
+#define ATF_TEST_CASE_USE(name) (atfu_tcptr_ ## name) = NULL
#define ATF_TEST_CASE_HEAD(name) \
void \
@@ -101,6 +118,12 @@
} \
} while (false)
+#define ATF_REQUIRE_IN(element, collection) \
+ ATF_REQUIRE((collection).find(element) != (collection).end())
+
+#define ATF_REQUIRE_NOT_IN(element, collection) \
+ ATF_REQUIRE((collection).find(element) == (collection).end())
+
#define ATF_REQUIRE_MATCH(regexp, string) \
do { \
if (!atf::tests::detail::match(regexp, string)) { \
@@ -192,8 +215,8 @@
#define ATF_ADD_TEST_CASE(tcs, tcname) \
do { \
- atf::tests::tc* tcptr = new atfu_tc_ ## tcname(); \
- (tcs).push_back(tcptr); \
+ atfu_tcptr_ ## tcname = new atfu_tc_ ## tcname(); \
+ (tcs).push_back(atfu_tcptr_ ## tcname); \
} while (0);
#endif // !defined(_ATF_CXX_MACROS_HPP_)
diff --git a/unit/atf-src/atf-c++/macros_hpp_test.cpp b/unit/atf-src/atf-c++/macros_hpp_test.cpp
index 77c41473..2cb75360 100644
--- a/unit/atf-src/atf-c++/macros_hpp_test.cpp
+++ b/unit/atf-src/atf-c++/macros_hpp_test.cpp
@@ -1,7 +1,7 @@
//
// Automated Testing Framework (atf)
//
-// Copyright (c) 2008, 2009, 2010 The NetBSD Foundation, Inc.
+// Copyright (c) 2008 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@@ -106,6 +106,7 @@ ATF_TEST_CASE(TEST_MACRO_1);
ATF_TEST_CASE_HEAD(TEST_MACRO_1) { }
ATF_TEST_CASE_BODY(TEST_MACRO_1) { }
void instantiate_1(void) {
+ ATF_TEST_CASE_USE(TEST_MACRO_1);
atf::tests::tc* the_test = new ATF_TEST_CASE_NAME(TEST_MACRO_1)();
delete the_test;
}
@@ -114,12 +115,16 @@ ATF_TEST_CASE_HEAD(TEST_MACRO_2) { }
ATF_TEST_CASE_BODY(TEST_MACRO_2) { }
ATF_TEST_CASE_CLEANUP(TEST_MACRO_2) { }
void instatiate_2(void) {
+ ATF_TEST_CASE_USE(TEST_MACRO_2);
atf::tests::tc* the_test = new ATF_TEST_CASE_NAME(TEST_MACRO_2)();
delete the_test;
}
ATF_TEST_CASE_WITH_CLEANUP(TEST_MACRO_3);
+ATF_TEST_CASE_HEAD(TEST_MACRO_3) { }
ATF_TEST_CASE_BODY(TEST_MACRO_3) { }
+ATF_TEST_CASE_CLEANUP(TEST_MACRO_3) { }
void instatiate_3(void) {
+ ATF_TEST_CASE_USE(TEST_MACRO_3);
atf::tests::tc* the_test = new ATF_TEST_CASE_NAME(TEST_MACRO_3)();
delete the_test;
}
diff --git a/unit/atf-src/atf-c++/macros_test.cpp b/unit/atf-src/atf-c++/macros_test.cpp
index 2fc1d5e0..67e41061 100644
--- a/unit/atf-src/atf-c++/macros_test.cpp
+++ b/unit/atf-src/atf-c++/macros_test.cpp
@@ -1,7 +1,7 @@
//
// Automated Testing Framework (atf)
//
-// Copyright (c) 2008, 2009, 2010 The NetBSD Foundation, Inc.
+// Copyright (c) 2008 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@@ -38,6 +38,7 @@ extern "C" {
#include <stdexcept>
#include "macros.hpp"
+#include "utils.hpp"
#include "detail/fs.hpp"
#include "detail/process.hpp"
@@ -51,7 +52,7 @@ extern "C" {
static
void
-create_ctl_file(const atf::tests::tc& tc, const char *name)
+create_ctl_file(const char *name)
{
ATF_REQUIRE(open(name, O_CREAT | O_WRONLY | O_TRUNC, 0644) != -1);
}
@@ -67,9 +68,9 @@ ATF_TEST_CASE_HEAD(h_pass)
}
ATF_TEST_CASE_BODY(h_pass)
{
- create_ctl_file(*this, "before");
+ create_ctl_file("before");
ATF_PASS();
- create_ctl_file(*this, "after");
+ create_ctl_file("after");
}
ATF_TEST_CASE(h_fail);
@@ -79,9 +80,9 @@ ATF_TEST_CASE_HEAD(h_fail)
}
ATF_TEST_CASE_BODY(h_fail)
{
- create_ctl_file(*this, "before");
+ create_ctl_file("before");
ATF_FAIL("Failed on purpose");
- create_ctl_file(*this, "after");
+ create_ctl_file("after");
}
ATF_TEST_CASE(h_skip);
@@ -91,9 +92,9 @@ ATF_TEST_CASE_HEAD(h_skip)
}
ATF_TEST_CASE_BODY(h_skip)
{
- create_ctl_file(*this, "before");
+ create_ctl_file("before");
ATF_SKIP("Skipped on purpose");
- create_ctl_file(*this, "after");
+ create_ctl_file("after");
}
ATF_TEST_CASE(h_require);
@@ -105,9 +106,9 @@ ATF_TEST_CASE_BODY(h_require)
{
bool condition = atf::text::to_bool(get_config_var("condition"));
- create_ctl_file(*this, "before");
+ create_ctl_file("before");
ATF_REQUIRE(condition);
- create_ctl_file(*this, "after");
+ create_ctl_file("after");
}
ATF_TEST_CASE(h_require_eq);
@@ -120,9 +121,28 @@ ATF_TEST_CASE_BODY(h_require_eq)
long v1 = atf::text::to_type< long >(get_config_var("v1"));
long v2 = atf::text::to_type< long >(get_config_var("v2"));
- create_ctl_file(*this, "before");
+ create_ctl_file("before");
ATF_REQUIRE_EQ(v1, v2);
- create_ctl_file(*this, "after");
+ create_ctl_file("after");
+}
+
+ATF_TEST_CASE(h_require_in);
+ATF_TEST_CASE_HEAD(h_require_in)
+{
+ set_md_var("descr", "Helper test case");
+}
+ATF_TEST_CASE_BODY(h_require_in)
+{
+ const std::string element = get_config_var("value");
+
+ std::set< std::string > collection;
+ collection.insert("foo");
+ collection.insert("bar");
+ collection.insert("baz");
+
+ create_ctl_file("before");
+ ATF_REQUIRE_IN(element, collection);
+ create_ctl_file("after");
}
ATF_TEST_CASE(h_require_match);
@@ -135,9 +155,28 @@ ATF_TEST_CASE_BODY(h_require_match)
const std::string regexp = get_config_var("regexp");
const std::string string = get_config_var("string");
- create_ctl_file(*this, "before");
+ create_ctl_file("before");
ATF_REQUIRE_MATCH(regexp, string);
- create_ctl_file(*this, "after");
+ create_ctl_file("after");
+}
+
+ATF_TEST_CASE(h_require_not_in);
+ATF_TEST_CASE_HEAD(h_require_not_in)
+{
+ set_md_var("descr", "Helper test case");
+}
+ATF_TEST_CASE_BODY(h_require_not_in)
+{
+ const std::string element = get_config_var("value");
+
+ std::set< std::string > collection;
+ collection.insert("foo");
+ collection.insert("bar");
+ collection.insert("baz");
+
+ create_ctl_file("before");
+ ATF_REQUIRE_NOT_IN(element, collection);
+ create_ctl_file("after");
}
ATF_TEST_CASE(h_require_throw);
@@ -147,7 +186,7 @@ ATF_TEST_CASE_HEAD(h_require_throw)
}
ATF_TEST_CASE_BODY(h_require_throw)
{
- create_ctl_file(*this, "before");
+ create_ctl_file("before");
if (get_config_var("what") == "throw_int")
ATF_REQUIRE_THROW(std::runtime_error, if (1) throw int(5));
@@ -158,7 +197,7 @@ ATF_TEST_CASE_BODY(h_require_throw)
ATF_REQUIRE_THROW(std::runtime_error,
if (0) throw std::runtime_error("e"));
- create_ctl_file(*this, "after");
+ create_ctl_file("after");
}
ATF_TEST_CASE(h_require_throw_re);
@@ -168,7 +207,7 @@ ATF_TEST_CASE_HEAD(h_require_throw_re)
}
ATF_TEST_CASE_BODY(h_require_throw_re)
{
- create_ctl_file(*this, "before");
+ create_ctl_file("before");
if (get_config_var("what") == "throw_int")
ATF_REQUIRE_THROW_RE(std::runtime_error, "5", if (1) throw int(5));
@@ -182,7 +221,7 @@ ATF_TEST_CASE_BODY(h_require_throw_re)
ATF_REQUIRE_THROW_RE(std::runtime_error, "e",
if (0) throw std::runtime_error("e"));
- create_ctl_file(*this, "after");
+ create_ctl_file("after");
}
static int
@@ -205,7 +244,7 @@ ATF_TEST_CASE_HEAD(h_check_errno)
}
ATF_TEST_CASE_BODY(h_check_errno)
{
- create_ctl_file(*this, "before");
+ create_ctl_file("before");
if (get_config_var("what") == "no_error")
ATF_CHECK_ERRNO(-1, errno_ok_stub() == -1);
@@ -216,7 +255,7 @@ ATF_TEST_CASE_BODY(h_check_errno)
else
UNREACHABLE;
- create_ctl_file(*this, "after");
+ create_ctl_file("after");
}
ATF_TEST_CASE(h_require_errno);
@@ -226,7 +265,7 @@ ATF_TEST_CASE_HEAD(h_require_errno)
}
ATF_TEST_CASE_BODY(h_require_errno)
{
- create_ctl_file(*this, "before");
+ create_ctl_file("before");
if (get_config_var("what") == "no_error")
ATF_REQUIRE_ERRNO(-1, errno_ok_stub() == -1);
@@ -237,7 +276,7 @@ ATF_TEST_CASE_BODY(h_require_errno)
else
UNREACHABLE;
- create_ctl_file(*this, "after");
+ create_ctl_file("after");
}
// ------------------------------------------------------------------------
@@ -251,8 +290,9 @@ ATF_TEST_CASE_HEAD(pass)
}
ATF_TEST_CASE_BODY(pass)
{
+ ATF_TEST_CASE_USE(h_pass);
run_h_tc< ATF_TEST_CASE_NAME(h_pass) >();
- ATF_REQUIRE(grep_file("result", "^passed"));
+ ATF_REQUIRE(atf::utils::grep_file("^passed", "result"));
ATF_REQUIRE(atf::fs::exists(atf::fs::path("before")));
ATF_REQUIRE(!atf::fs::exists(atf::fs::path("after")));
}
@@ -264,8 +304,9 @@ ATF_TEST_CASE_HEAD(fail)
}
ATF_TEST_CASE_BODY(fail)
{
+ ATF_TEST_CASE_USE(h_fail);
run_h_tc< ATF_TEST_CASE_NAME(h_fail) >();
- ATF_REQUIRE(grep_file("result", "^failed: Failed on purpose"));
+ ATF_REQUIRE(atf::utils::grep_file("^failed: Failed on purpose", "result"));
ATF_REQUIRE(atf::fs::exists(atf::fs::path("before")));
ATF_REQUIRE(!atf::fs::exists(atf::fs::path("after")));
}
@@ -277,8 +318,10 @@ ATF_TEST_CASE_HEAD(skip)
}
ATF_TEST_CASE_BODY(skip)
{
+ ATF_TEST_CASE_USE(h_skip);
run_h_tc< ATF_TEST_CASE_NAME(h_skip) >();
- ATF_REQUIRE(grep_file("result", "^skipped: Skipped on purpose"));
+ ATF_REQUIRE(atf::utils::grep_file("^skipped: Skipped on purpose",
+ "result"));
ATF_REQUIRE(atf::fs::exists(atf::fs::path("before")));
ATF_REQUIRE(!atf::fs::exists(atf::fs::path("after")));
}
@@ -308,14 +351,16 @@ ATF_TEST_CASE_BODY(require)
std::cout << "Checking with a " << t->cond << " value\n";
+ ATF_TEST_CASE_USE(h_require);
run_h_tc< ATF_TEST_CASE_NAME(h_require) >(config);
ATF_REQUIRE(atf::fs::exists(before));
if (t->ok) {
- ATF_REQUIRE(grep_file("result", "^passed"));
+ ATF_REQUIRE(atf::utils::grep_file("^passed", "result"));
ATF_REQUIRE(atf::fs::exists(after));
} else {
- ATF_REQUIRE(grep_file("result", "^failed: .*condition not met"));
+ ATF_REQUIRE(atf::utils::grep_file(
+ "^failed: .*condition not met", "result"));
ATF_REQUIRE(!atf::fs::exists(after));
}
@@ -356,14 +401,60 @@ ATF_TEST_CASE_BODY(require_eq)
<< " and expecting " << (t->ok ? "true" : "false")
<< "\n";
+ ATF_TEST_CASE_USE(h_require_eq);
run_h_tc< ATF_TEST_CASE_NAME(h_require_eq) >(config);
ATF_REQUIRE(atf::fs::exists(before));
if (t->ok) {
- ATF_REQUIRE(grep_file("result", "^passed"));
+ ATF_REQUIRE(atf::utils::grep_file("^passed", "result"));
ATF_REQUIRE(atf::fs::exists(after));
} else {
- ATF_REQUIRE(grep_file("result", "^failed: .*v1 != v2"));
+ ATF_REQUIRE(atf::utils::grep_file("^failed: .*v1 != v2", "result"));
+ ATF_REQUIRE(!atf::fs::exists(after));
+ }
+
+ atf::fs::remove(before);
+ if (t->ok)
+ atf::fs::remove(after);
+ }
+}
+
+ATF_TEST_CASE(require_in);
+ATF_TEST_CASE_HEAD(require_in)
+{
+ set_md_var("descr", "Tests the ATF_REQUIRE_IN macro");
+}
+ATF_TEST_CASE_BODY(require_in)
+{
+ struct test {
+ const char *value;
+ bool ok;
+ } *t, tests[] = {
+ { "foo", true },
+ { "bar", true },
+ { "baz", true },
+ { "xxx", false },
+ { "fooa", false },
+ { "foo ", false },
+ { NULL, false }
+ };
+
+ const atf::fs::path before("before");
+ const atf::fs::path after("after");
+
+ for (t = &tests[0]; t->value != NULL; t++) {
+ atf::tests::vars_map config;
+ config["value"] = t->value;
+
+ ATF_TEST_CASE_USE(h_require_in);
+ run_h_tc< ATF_TEST_CASE_NAME(h_require_in) >(config);
+
+ ATF_REQUIRE(atf::fs::exists(before));
+ if (t->ok) {
+ ATF_REQUIRE(atf::utils::grep_file("^passed", "result"));
+ ATF_REQUIRE(atf::fs::exists(after));
+ } else {
+ ATF_REQUIRE(atf::utils::grep_file("^failed: ", "result"));
ATF_REQUIRE(!atf::fs::exists(after));
}
@@ -402,14 +493,60 @@ ATF_TEST_CASE_BODY(require_match)
<< " and expecting " << (t->ok ? "true" : "false")
<< "\n";
+ ATF_TEST_CASE_USE(h_require_match);
run_h_tc< ATF_TEST_CASE_NAME(h_require_match) >(config);
ATF_REQUIRE(atf::fs::exists(before));
if (t->ok) {
- ATF_REQUIRE(grep_file("result", "^passed"));
+ ATF_REQUIRE(atf::utils::grep_file("^passed", "result"));
+ ATF_REQUIRE(atf::fs::exists(after));
+ } else {
+ ATF_REQUIRE(atf::utils::grep_file("^failed: ", "result"));
+ ATF_REQUIRE(!atf::fs::exists(after));
+ }
+
+ atf::fs::remove(before);
+ if (t->ok)
+ atf::fs::remove(after);
+ }
+}
+
+ATF_TEST_CASE(require_not_in);
+ATF_TEST_CASE_HEAD(require_not_in)
+{
+ set_md_var("descr", "Tests the ATF_REQUIRE_NOT_IN macro");
+}
+ATF_TEST_CASE_BODY(require_not_in)
+{
+ struct test {
+ const char *value;
+ bool ok;
+ } *t, tests[] = {
+ { "foo", false },
+ { "bar", false },
+ { "baz", false },
+ { "xxx", true },
+ { "fooa", true },
+ { "foo ", true },
+ { NULL, false }
+ };
+
+ const atf::fs::path before("before");
+ const atf::fs::path after("after");
+
+ for (t = &tests[0]; t->value != NULL; t++) {
+ atf::tests::vars_map config;
+ config["value"] = t->value;
+
+ ATF_TEST_CASE_USE(h_require_not_in);
+ run_h_tc< ATF_TEST_CASE_NAME(h_require_not_in) >(config);
+
+ ATF_REQUIRE(atf::fs::exists(before));
+ if (t->ok) {
+ ATF_REQUIRE(atf::utils::grep_file("^passed", "result"));
ATF_REQUIRE(atf::fs::exists(after));
} else {
- ATF_REQUIRE(grep_file("result", "^failed: "));
+ ATF_REQUIRE(atf::utils::grep_file("^failed: ", "result"));
ATF_REQUIRE(!atf::fs::exists(after));
}
@@ -447,17 +584,18 @@ ATF_TEST_CASE_BODY(require_throw)
std::cout << "Checking with " << t->what << " and expecting "
<< (t->ok ? "true" : "false") << "\n";
+ ATF_TEST_CASE_USE(h_require_throw);
run_h_tc< ATF_TEST_CASE_NAME(h_require_throw) >(config);
ATF_REQUIRE(atf::fs::exists(before));
if (t->ok) {
- ATF_REQUIRE(grep_file("result", "^passed"));
+ ATF_REQUIRE(atf::utils::grep_file("^passed", "result"));
ATF_REQUIRE(atf::fs::exists(after));
} else {
std::cout << "Checking that message contains '" << t->msg
<< "'\n";
std::string exp_result = std::string("^failed: .*") + t->msg;
- ATF_REQUIRE(grep_file("result", exp_result.c_str()));
+ ATF_REQUIRE(atf::utils::grep_file(exp_result.c_str(), "result"));
ATF_REQUIRE(!atf::fs::exists(after));
}
@@ -481,8 +619,9 @@ ATF_TEST_CASE_BODY(require_throw_re)
} *t, tests[] = {
{ "throw_int", false, "unexpected error" },
{ "throw_rt_match", true, NULL },
- { "throw_rt_no_match", true, "threw.*runtime_error(baz foo bar a).*"
- "does not match 'a foo bar baz'" },
+ { "throw_rt_no_match", false,
+ "threw.*runtime_error\\(baz foo bar a\\).*"
+ "does not match 'foo\\.\\*baz'" },
{ "no_throw_rt", false, "did not throw" },
{ NULL, false, NULL }
};
@@ -497,17 +636,18 @@ ATF_TEST_CASE_BODY(require_throw_re)
std::cout << "Checking with " << t->what << " and expecting "
<< (t->ok ? "true" : "false") << "\n";
- run_h_tc< ATF_TEST_CASE_NAME(h_require_throw) >(config);
+ ATF_TEST_CASE_USE(h_require_throw_re);
+ run_h_tc< ATF_TEST_CASE_NAME(h_require_throw_re) >(config);
ATF_REQUIRE(atf::fs::exists(before));
if (t->ok) {
- ATF_REQUIRE(grep_file("result", "^passed"));
+ ATF_REQUIRE(atf::utils::grep_file("^passed", "result"));
ATF_REQUIRE(atf::fs::exists(after));
} else {
std::cout << "Checking that message contains '" << t->msg
<< "'\n";
std::string exp_result = std::string("^failed: .*") + t->msg;
- ATF_REQUIRE(grep_file("result", exp_result.c_str()));
+ ATF_REQUIRE(atf::utils::grep_file(exp_result.c_str(), "result"));
ATF_REQUIRE(!atf::fs::exists(after));
}
@@ -544,19 +684,20 @@ ATF_TEST_CASE_BODY(check_errno)
atf::tests::vars_map config;
config["what"] = t->what;
+ ATF_TEST_CASE_USE(h_check_errno);
run_h_tc< ATF_TEST_CASE_NAME(h_check_errno) >(config);
ATF_REQUIRE(atf::fs::exists(before));
ATF_REQUIRE(atf::fs::exists(after));
if (t->ok) {
- ATF_REQUIRE(grep_file("result", "^passed"));
+ ATF_REQUIRE(atf::utils::grep_file("^passed", "result"));
} else {
- ATF_REQUIRE(grep_file("result", "^failed"));
+ ATF_REQUIRE(atf::utils::grep_file("^failed", "result"));
std::string exp_result = "macros_test.cpp:[0-9]+: " +
std::string(t->msg) + "$";
- ATF_REQUIRE(grep_file("stderr", exp_result.c_str()));
+ ATF_REQUIRE(atf::utils::grep_file(exp_result.c_str(), "stderr"));
}
atf::fs::remove(before);
@@ -591,16 +732,17 @@ ATF_TEST_CASE_BODY(require_errno)
atf::tests::vars_map config;
config["what"] = t->what;
+ ATF_TEST_CASE_USE(h_require_errno);
run_h_tc< ATF_TEST_CASE_NAME(h_require_errno) >(config);
ATF_REQUIRE(atf::fs::exists(before));
if (t->ok) {
- ATF_REQUIRE(grep_file("result", "^passed"));
+ ATF_REQUIRE(atf::utils::grep_file("^passed", "result"));
ATF_REQUIRE(atf::fs::exists(after));
} else {
std::string exp_result = "^failed: .*macros_test.cpp:[0-9]+: " +
std::string(t->msg) + "$";
- ATF_REQUIRE(grep_file("result", exp_result.c_str()));
+ ATF_REQUIRE(atf::utils::grep_file(exp_result.c_str(), "result"));
ATF_REQUIRE(!atf::fs::exists(after));
}
@@ -621,6 +763,11 @@ BUILD_TC(use, "macros_hpp_test.cpp",
"do not cause syntax errors when used",
"Build of macros_hpp_test.cpp failed; some macros in "
"atf-c++/macros.hpp are broken");
+BUILD_TC_FAIL(detect_unused_tests, "unused_test.cpp",
+ "Tests that defining an unused test case raises a warning (and thus "
+ "an error)",
+ "Build of unused_test.cpp passed; unused test cases are not properly "
+ "detected");
// ------------------------------------------------------------------------
// Main.
@@ -635,7 +782,9 @@ ATF_INIT_TEST_CASES(tcs)
ATF_ADD_TEST_CASE(tcs, check_errno);
ATF_ADD_TEST_CASE(tcs, require);
ATF_ADD_TEST_CASE(tcs, require_eq);
+ ATF_ADD_TEST_CASE(tcs, require_in);
ATF_ADD_TEST_CASE(tcs, require_match);
+ ATF_ADD_TEST_CASE(tcs, require_not_in);
ATF_ADD_TEST_CASE(tcs, require_throw);
ATF_ADD_TEST_CASE(tcs, require_throw_re);
ATF_ADD_TEST_CASE(tcs, require_errno);
@@ -643,4 +792,5 @@ ATF_INIT_TEST_CASES(tcs)
// Add the test cases for the header file.
ATF_ADD_TEST_CASE(tcs, include);
ATF_ADD_TEST_CASE(tcs, use);
+ ATF_ADD_TEST_CASE(tcs, detect_unused_tests);
}
diff --git a/unit/atf-src/atf-c++/noncopyable.hpp b/unit/atf-src/atf-c++/noncopyable.hpp
new file mode 100644
index 00000000..a885a668
--- /dev/null
+++ b/unit/atf-src/atf-c++/noncopyable.hpp
@@ -0,0 +1,56 @@
+//
+// Automated Testing Framework (atf)
+//
+// Copyright (c) 2007 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.
+//
+
+#if !defined(_ATF_CXX_NONCOPYABLE_HPP_)
+#define _ATF_CXX_NONCOPYABLE_HPP_
+
+namespace atf {
+
+// ------------------------------------------------------------------------
+// The "noncopyable" class.
+// ------------------------------------------------------------------------
+
+class noncopyable {
+ // The class cannot be empty; otherwise we get ABI-stability warnings
+ // during the build, which will break it due to strict checking.
+ int m_noncopyable_dummy;
+
+ noncopyable(const noncopyable& nc);
+ noncopyable& operator=(const noncopyable& nc);
+
+protected:
+ // Explicitly needed to provide some non-private functions. Otherwise
+ // we also get some warnings during the build.
+ noncopyable(void) {}
+ ~noncopyable(void) {}
+};
+
+} // namespace atf
+
+#endif // !defined(_ATF_CXX_NONCOPYABLE_HPP_)
diff --git a/unit/atf-src/atf-c++/pkg_config_test.sh b/unit/atf-src/atf-c++/pkg_config_test.sh
index 40b9559b..8409902c 100644
--- a/unit/atf-src/atf-c++/pkg_config_test.sh
+++ b/unit/atf-src/atf-c++/pkg_config_test.sh
@@ -1,7 +1,7 @@
#
# Automated Testing Framework (atf)
#
-# Copyright (c) 2008, 2010 The NetBSD Foundation, Inc.
+# Copyright (c) 2008 The NetBSD Foundation, Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
diff --git a/unit/atf-src/atf-c++/tests.cpp b/unit/atf-src/atf-c++/tests.cpp
index 054c6fbf..2c351fcb 100644
--- a/unit/atf-src/atf-c++/tests.cpp
+++ b/unit/atf-src/atf-c++/tests.cpp
@@ -1,7 +1,7 @@
//
// Automated Testing Framework (atf)
//
-// Copyright (c) 2007, 2008, 2009, 2010 The NetBSD Foundation, Inc.
+// Copyright (c) 2007 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@@ -55,9 +55,11 @@ extern "C" {
#include "atf-c/utils.h"
}
+#include "noncopyable.hpp"
#include "tests.hpp"
#include "detail/application.hpp"
+#include "detail/auto_array.hpp"
#include "detail/env.hpp"
#include "detail/exceptions.hpp"
#include "detail/fs.hpp"
@@ -127,7 +129,7 @@ detail::match(const std::string& regexp, const std::string& str)
static std::map< atf_tc_t*, impl::tc* > wraps;
static std::map< const atf_tc_t*, const impl::tc* > cwraps;
-struct impl::tc_impl : atf::utils::noncopyable {
+struct impl::tc_impl : atf::noncopyable {
std::string m_ident;
atf_tc_t m_tc;
bool m_has_cleanup;
@@ -190,8 +192,7 @@ impl::tc::init(const vars_map& config)
{
atf_error_t err;
- utils::auto_array< const char * > array(
- new const char*[(config.size() * 2) + 1]);
+ auto_array< const char * > array(new const char*[(config.size() * 2) + 1]);
const char **ptr = array.get();
for (vars_map::const_iterator iter = config.begin();
iter != config.end(); iter++) {
@@ -641,6 +642,16 @@ tp::run_tc(const std::string& tcarg)
impl::tc* tc = find_tc(init_tcs(), fields.first);
+ if (!atf::env::has("__RUNNING_INSIDE_ATF_RUN") || atf::env::get(
+ "__RUNNING_INSIDE_ATF_RUN") != "internal-yes-value")
+ {
+ std::cerr << m_prog_name << ": WARNING: Running test cases without "
+ "atf-run(1) is unsupported\n";
+ std::cerr << m_prog_name << ": WARNING: No isolation nor timeout "
+ "control is being applied; you may get unexpected failures; see "
+ "atf-test-case(4)\n";
+ }
+
try {
switch (fields.second) {
case BODY:
diff --git a/unit/atf-src/atf-c++/tests.hpp b/unit/atf-src/atf-c++/tests.hpp
index 208e33da..22a2a870 100644
--- a/unit/atf-src/atf-c++/tests.hpp
+++ b/unit/atf-src/atf-c++/tests.hpp
@@ -1,7 +1,7 @@
//
// Automated Testing Framework (atf)
//
-// Copyright (c) 2007, 2008, 2009, 2010 The NetBSD Foundation, Inc.
+// Copyright (c) 2007 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@@ -38,7 +38,7 @@ extern "C" {
#include <atf-c/defs.h>
}
-#include <atf-c++/utils.hpp>
+#include <atf-c++/noncopyable.hpp>
namespace atf {
namespace tests {
@@ -74,7 +74,7 @@ typedef std::map< std::string, std::string > vars_map;
struct tc_impl;
-class tc : utils::noncopyable {
+class tc : noncopyable {
std::auto_ptr< tc_impl > pimpl;
protected:
diff --git a/unit/atf-src/atf-c++/tests_test.cpp b/unit/atf-src/atf-c++/tests_test.cpp
index 02337a11..63ab2ef9 100644
--- a/unit/atf-src/atf-c++/tests_test.cpp
+++ b/unit/atf-src/atf-c++/tests_test.cpp
@@ -1,7 +1,7 @@
//
// Automated Testing Framework (atf)
//
-// Copyright (c) 2007, 2008, 2009, 2010 The NetBSD Foundation, Inc.
+// Copyright (c) 2007 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
diff --git a/unit/atf-src/atf-c++/unused_test.cpp b/unit/atf-src/atf-c++/unused_test.cpp
new file mode 100644
index 00000000..2a18a455
--- /dev/null
+++ b/unit/atf-src/atf-c++/unused_test.cpp
@@ -0,0 +1,52 @@
+//
+// Automated Testing Framework (atf)
+//
+// Copyright (c) 2012 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.
+//
+
+#include <atf-c++/macros.hpp>
+
+ATF_TEST_CASE(this_is_used);
+ATF_TEST_CASE_HEAD(this_is_used)
+{
+}
+ATF_TEST_CASE_BODY(this_is_used)
+{
+}
+
+ATF_TEST_CASE(this_is_unused);
+ATF_TEST_CASE_HEAD(this_is_unused)
+{
+}
+ATF_TEST_CASE_BODY(this_is_unused)
+{
+}
+
+ATF_INIT_TEST_CASES(tcs)
+{
+ ATF_ADD_TEST_CASE(tcs, this_is_used);
+ //ATF_ADD_TEST_CASE(tcs, this_is_unused);
+}
diff --git a/unit/atf-src/atf-c++/utils.cpp b/unit/atf-src/atf-c++/utils.cpp
new file mode 100644
index 00000000..cc338bb8
--- /dev/null
+++ b/unit/atf-src/atf-c++/utils.cpp
@@ -0,0 +1,104 @@
+//
+// Automated Testing Framework (atf)
+//
+// Copyright (c) 2007 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.
+//
+
+extern "C" {
+#include "atf-c/utils.h"
+}
+
+#include <cstdlib>
+#include <iostream>
+
+#include "utils.hpp"
+
+void
+atf::utils::cat_file(const std::string& path, const std::string& prefix)
+{
+ atf_utils_cat_file(path.c_str(), prefix.c_str());
+}
+
+void
+atf::utils::copy_file(const std::string& source, const std::string& destination)
+{
+ atf_utils_copy_file(source.c_str(), destination.c_str());
+}
+
+bool
+atf::utils::compare_file(const std::string& path, const std::string& contents)
+{
+ return atf_utils_compare_file(path.c_str(), contents.c_str());
+}
+
+void
+atf::utils::create_file(const std::string& path, const std::string& contents)
+{
+ atf_utils_create_file(path.c_str(), "%s", contents.c_str());
+}
+
+bool
+atf::utils::file_exists(const std::string& path)
+{
+ return atf_utils_file_exists(path.c_str());
+}
+
+pid_t
+atf::utils::fork(void)
+{
+ std::cout.flush();
+ std::cerr.flush();
+ return atf_utils_fork();
+}
+
+bool
+atf::utils::grep_file(const std::string& regex, const std::string& path)
+{
+ return atf_utils_grep_file("%s", path.c_str(), regex.c_str());
+}
+
+bool
+atf::utils::grep_string(const std::string& regex, const std::string& str)
+{
+ return atf_utils_grep_string("%s", str.c_str(), regex.c_str());
+}
+
+void
+atf::utils::redirect(const int fd, const std::string& path)
+{
+ if (fd == STDOUT_FILENO)
+ std::cout.flush();
+ else if (fd == STDERR_FILENO)
+ std::cerr.flush();
+ atf_utils_redirect(fd, path.c_str());
+}
+
+void
+atf::utils::wait(const pid_t pid, const int exitstatus,
+ const std::string& expout, const std::string& experr)
+{
+ atf_utils_wait(pid, exitstatus, expout.c_str(), experr.c_str());
+}
diff --git a/unit/atf-src/atf-c++/utils.hpp b/unit/atf-src/atf-c++/utils.hpp
index 98233c3d..b8596aec 100644
--- a/unit/atf-src/atf-c++/utils.hpp
+++ b/unit/atf-src/atf-c++/utils.hpp
@@ -1,7 +1,7 @@
//
// Automated Testing Framework (atf)
//
-// Copyright (c) 2007, 2008, 2009 The NetBSD Foundation, Inc.
+// Copyright (c) 2007 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@@ -30,170 +30,38 @@
#if !defined(_ATF_CXX_UTILS_HPP_)
#define _ATF_CXX_UTILS_HPP_
-#include <cstddef>
-
-namespace atf {
-namespace utils {
-
-// ------------------------------------------------------------------------
-// The "auto_array" class.
-// ------------------------------------------------------------------------
-
-template< class T >
-struct auto_array_ref {
- T* m_ptr;
-
- explicit auto_array_ref(T*);
-};
-
-template< class T >
-auto_array_ref< T >::auto_array_ref(T* ptr) :
- m_ptr(ptr)
-{
-}
-
-template< class T >
-class auto_array {
- T* m_ptr;
-
-public:
- auto_array(T* = NULL) throw();
- auto_array(auto_array< T >&) throw();
- auto_array(auto_array_ref< T >) throw();
- ~auto_array(void) throw();
-
- T* get(void) throw();
- const T* get(void) const throw();
- T* release(void) throw();
- void reset(T* = NULL) throw();
-
- auto_array< T >& operator=(auto_array< T >&) throw();
- auto_array< T >& operator=(auto_array_ref< T >) throw();
-
- T& operator[](int) throw();
- operator auto_array_ref< T >(void) throw();
-};
-
-template< class T >
-auto_array< T >::auto_array(T* ptr)
- throw() :
- m_ptr(ptr)
-{
-}
-
-template< class T >
-auto_array< T >::auto_array(auto_array< T >& ptr)
- throw() :
- m_ptr(ptr.release())
-{
-}
-
-template< class T >
-auto_array< T >::auto_array(auto_array_ref< T > ref)
- throw() :
- m_ptr(ref.m_ptr)
-{
-}
-
-template< class T >
-auto_array< T >::~auto_array(void)
- throw()
-{
- if (m_ptr != NULL)
- delete [] m_ptr;
+extern "C" {
+#include <unistd.h>
}
-template< class T >
-T*
-auto_array< T >::get(void)
- throw()
-{
- return m_ptr;
-}
+#include <string>
-template< class T >
-const T*
-auto_array< T >::get(void)
- const throw()
-{
- return m_ptr;
-}
-
-template< class T >
-T*
-auto_array< T >::release(void)
- throw()
-{
- T* ptr = m_ptr;
- m_ptr = NULL;
- return ptr;
-}
-
-template< class T >
-void
-auto_array< T >::reset(T* ptr)
- throw()
-{
- if (m_ptr != NULL)
- delete [] m_ptr;
- m_ptr = ptr;
-}
-
-template< class T >
-auto_array< T >&
-auto_array< T >::operator=(auto_array< T >& ptr)
- throw()
-{
- reset(ptr.release());
- return *this;
-}
+namespace atf {
+namespace utils {
-template< class T >
-auto_array< T >&
-auto_array< T >::operator=(auto_array_ref< T > ref)
- throw()
+void cat_file(const std::string&, const std::string&);
+bool compare_file(const std::string&, const std::string&);
+void copy_file(const std::string&, const std::string&);
+void create_file(const std::string&, const std::string&);
+bool file_exists(const std::string&);
+pid_t fork(void);
+bool grep_file(const std::string&, const std::string&);
+bool grep_string(const std::string&, const std::string&);
+void redirect(const int, const std::string&);
+void wait(const pid_t, const int, const std::string&, const std::string&);
+
+template< typename Collection >
+bool
+grep_collection(const std::string& regexp, const Collection& collection)
{
- if (m_ptr != ref.m_ptr) {
- delete [] m_ptr;
- m_ptr = ref.m_ptr;
+ for (typename Collection::const_iterator iter = collection.begin();
+ iter != collection.end(); ++iter) {
+ if (grep_string(regexp, *iter))
+ return true;
}
- return *this;
-}
-
-template< class T >
-T&
-auto_array< T >::operator[](int pos)
- throw()
-{
- return m_ptr[pos];
-}
-
-template< class T >
-auto_array< T >::operator auto_array_ref< T >(void)
- throw()
-{
- return auto_array_ref< T >(release());
+ return false;
}
-// ------------------------------------------------------------------------
-// The "noncopyable" class.
-// ------------------------------------------------------------------------
-
-class noncopyable {
- // The class cannot be empty; otherwise we get ABI-stability warnings
- // during the build, which will break it due to strict checking.
- int m_noncopyable_dummy;
-
- noncopyable(const noncopyable& nc);
- noncopyable& operator=(const noncopyable& nc);
-
-protected:
- // Explicitly needed to provide some non-private functions. Otherwise
- // we also get some warnings during the build.
- noncopyable(void) {}
- ~noncopyable(void) {}
-};
-
} // namespace utils
} // namespace atf
diff --git a/unit/atf-src/atf-c++/utils_test.cpp b/unit/atf-src/atf-c++/utils_test.cpp
index 5b0f5e62..37457ff2 100644
--- a/unit/atf-src/atf-c++/utils_test.cpp
+++ b/unit/atf-src/atf-c++/utils_test.cpp
@@ -1,7 +1,7 @@
//
// Automated Testing Framework (atf)
//
-// Copyright (c) 2007, 2008, 2009 The NetBSD Foundation, Inc.
+// Copyright (c) 2007 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@@ -27,257 +27,409 @@
// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
+extern "C" {
+#include <sys/stat.h>
+#include <sys/wait.h>
+
+#include <fcntl.h>
+#include <unistd.h>
+}
+
+#include <cstdlib>
#include <iostream>
+#include <set>
+#include <string>
+#include <vector>
#include "macros.hpp"
#include "utils.hpp"
#include "detail/test_helpers.hpp"
+static std::string
+read_file(const char *path)
+{
+ char buffer[1024];
+
+ const int fd = open(path, O_RDONLY);
+ if (fd == -1)
+ ATF_FAIL("Cannot open " + std::string(path));
+ const ssize_t length = read(fd, buffer, sizeof(buffer) - 1);
+ close(fd);
+ ATF_REQUIRE(length != -1);
+ if (length == sizeof(buffer) - 1)
+ ATF_FAIL("Internal buffer not long enough to read temporary file");
+ ((char *)buffer)[length] = '\0';
+
+ return buffer;
+}
+
// ------------------------------------------------------------------------
-// Tests for the "auto_array" class.
+// Tests cases for the free functions.
// ------------------------------------------------------------------------
-class test_array {
-public:
- int m_value;
+ATF_TEST_CASE_WITHOUT_HEAD(cat_file__empty);
+ATF_TEST_CASE_BODY(cat_file__empty)
+{
+ atf::utils::create_file("file.txt", "");
+ atf::utils::redirect(STDOUT_FILENO, "captured.txt");
+ atf::utils::cat_file("file.txt", "PREFIX");
+ std::cout.flush();
+ close(STDOUT_FILENO);
- static ssize_t m_nblocks;
+ ATF_REQUIRE_EQ("", read_file("captured.txt"));
+}
- static
- atf::utils::auto_array< test_array >
- do_copy(atf::utils::auto_array< test_array >& ta)
- {
- return atf::utils::auto_array< test_array >(ta);
- }
+ATF_TEST_CASE_WITHOUT_HEAD(cat_file__one_line);
+ATF_TEST_CASE_BODY(cat_file__one_line)
+{
+ atf::utils::create_file("file.txt", "This is a single line\n");
+ atf::utils::redirect(STDOUT_FILENO, "captured.txt");
+ atf::utils::cat_file("file.txt", "PREFIX");
+ std::cout.flush();
+ close(STDOUT_FILENO);
- void* operator new(size_t size)
- {
- ATF_FAIL("New called but should have been new[]");
- return new int(5);
- }
+ ATF_REQUIRE_EQ("PREFIXThis is a single line\n", read_file("captured.txt"));
+}
- void* operator new[](size_t size)
- {
- m_nblocks++;
- void* mem = ::operator new(size);
- std::cout << "Allocated 'test_array' object " << mem << "\n";
- return mem;
- }
+ATF_TEST_CASE_WITHOUT_HEAD(cat_file__several_lines);
+ATF_TEST_CASE_BODY(cat_file__several_lines)
+{
+ atf::utils::create_file("file.txt", "First\nSecond line\nAnd third\n");
+ atf::utils::redirect(STDOUT_FILENO, "captured.txt");
+ atf::utils::cat_file("file.txt", ">");
+ std::cout.flush();
+ close(STDOUT_FILENO);
+
+ ATF_REQUIRE_EQ(">First\n>Second line\n>And third\n",
+ read_file("captured.txt"));
+}
- void operator delete(void* mem)
- {
- ATF_FAIL("Delete called but should have been delete[]");
- }
+ATF_TEST_CASE_WITHOUT_HEAD(cat_file__no_newline_eof);
+ATF_TEST_CASE_BODY(cat_file__no_newline_eof)
+{
+ atf::utils::create_file("file.txt", "Foo\n bar baz");
+ atf::utils::redirect(STDOUT_FILENO, "captured.txt");
+ atf::utils::cat_file("file.txt", "PREFIX");
+ std::cout.flush();
+ close(STDOUT_FILENO);
- void operator delete[](void* mem)
- {
- std::cout << "Releasing 'test_array' object " << mem << "\n";
- if (m_nblocks == 0)
- ATF_FAIL("Unbalanced delete[]");
- m_nblocks--;
- ::operator delete(mem);
- }
-};
+ ATF_REQUIRE_EQ("PREFIXFoo\nPREFIX bar baz", read_file("captured.txt"));
+}
-ssize_t test_array::m_nblocks = 0;
+ATF_TEST_CASE_WITHOUT_HEAD(compare_file__empty__match);
+ATF_TEST_CASE_BODY(compare_file__empty__match)
+{
+ atf::utils::create_file("test.txt", "");
+ ATF_REQUIRE(atf::utils::compare_file("test.txt", ""));
+}
-ATF_TEST_CASE(auto_array_scope);
-ATF_TEST_CASE_HEAD(auto_array_scope)
+ATF_TEST_CASE_WITHOUT_HEAD(compare_file__empty__not_match);
+ATF_TEST_CASE_BODY(compare_file__empty__not_match)
{
- set_md_var("descr", "Tests the automatic scope handling in the "
- "auto_array smart pointer class");
+ atf::utils::create_file("test.txt", "");
+ ATF_REQUIRE(!atf::utils::compare_file("test.txt", "\n"));
+ ATF_REQUIRE(!atf::utils::compare_file("test.txt", "foo"));
+ ATF_REQUIRE(!atf::utils::compare_file("test.txt", " "));
}
-ATF_TEST_CASE_BODY(auto_array_scope)
+
+ATF_TEST_CASE_WITHOUT_HEAD(compare_file__short__match);
+ATF_TEST_CASE_BODY(compare_file__short__match)
{
- using atf::utils::auto_array;
+ atf::utils::create_file("test.txt", "this is a short file");
+ ATF_REQUIRE(atf::utils::compare_file("test.txt", "this is a short file"));
+}
- ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
- {
- auto_array< test_array > t(new test_array[10]);
- ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
- }
- ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
+ATF_TEST_CASE_WITHOUT_HEAD(compare_file__short__not_match);
+ATF_TEST_CASE_BODY(compare_file__short__not_match)
+{
+ atf::utils::create_file("test.txt", "this is a short file");
+ ATF_REQUIRE(!atf::utils::compare_file("test.txt", ""));
+ ATF_REQUIRE(!atf::utils::compare_file("test.txt", "\n"));
+ ATF_REQUIRE(!atf::utils::compare_file("test.txt", "this is a Short file"));
+ ATF_REQUIRE(!atf::utils::compare_file("test.txt", "this is a short fil"));
+ ATF_REQUIRE(!atf::utils::compare_file("test.txt", "this is a short file "));
}
-ATF_TEST_CASE(auto_array_copy);
-ATF_TEST_CASE_HEAD(auto_array_copy)
+ATF_TEST_CASE_WITHOUT_HEAD(compare_file__long__match);
+ATF_TEST_CASE_BODY(compare_file__long__match)
{
- set_md_var("descr", "Tests the auto_array smart pointer class' copy "
- "constructor");
+ char long_contents[3456];
+ size_t i = 0;
+ for (; i < sizeof(long_contents) - 1; i++)
+ long_contents[i] = '0' + (i % 10);
+ long_contents[i] = '\0';
+ atf::utils::create_file("test.txt", long_contents);
+
+ ATF_REQUIRE(atf::utils::compare_file("test.txt", long_contents));
}
-ATF_TEST_CASE_BODY(auto_array_copy)
+
+ATF_TEST_CASE_WITHOUT_HEAD(compare_file__long__not_match);
+ATF_TEST_CASE_BODY(compare_file__long__not_match)
{
- using atf::utils::auto_array;
-
- ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
- {
- auto_array< test_array > t1(new test_array[10]);
- ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
-
- {
- auto_array< test_array > t2(t1);
- ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
- }
- ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
- }
- ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
+ char long_contents[3456];
+ size_t i = 0;
+ for (; i < sizeof(long_contents) - 1; i++)
+ long_contents[i] = '0' + (i % 10);
+ long_contents[i] = '\0';
+ atf::utils::create_file("test.txt", long_contents);
+
+ ATF_REQUIRE(!atf::utils::compare_file("test.txt", ""));
+ ATF_REQUIRE(!atf::utils::compare_file("test.txt", "\n"));
+ ATF_REQUIRE(!atf::utils::compare_file("test.txt", "0123456789"));
+ long_contents[i - 1] = 'Z';
+ ATF_REQUIRE(!atf::utils::compare_file("test.txt", long_contents));
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(copy_file__empty);
+ATF_TEST_CASE_BODY(copy_file__empty)
+{
+ atf::utils::create_file("src.txt", "");
+ ATF_REQUIRE(chmod("src.txt", 0520) != -1);
+
+ atf::utils::copy_file("src.txt", "dest.txt");
+ ATF_REQUIRE(atf::utils::compare_file("dest.txt", ""));
+ struct stat sb;
+ ATF_REQUIRE(stat("dest.txt", &sb) != -1);
+ ATF_REQUIRE_EQ(0520, sb.st_mode & 0xfff);
}
-ATF_TEST_CASE(auto_array_copy_ref);
-ATF_TEST_CASE_HEAD(auto_array_copy_ref)
+ATF_TEST_CASE_WITHOUT_HEAD(copy_file__some_contents);
+ATF_TEST_CASE_BODY(copy_file__some_contents)
{
- set_md_var("descr", "Tests the auto_array smart pointer class' copy "
- "constructor through the auxiliary auto_array_ref object");
+ atf::utils::create_file("src.txt", "This is a\ntest file\n");
+ atf::utils::copy_file("src.txt", "dest.txt");
+ ATF_REQUIRE(atf::utils::compare_file("dest.txt", "This is a\ntest file\n"));
}
-ATF_TEST_CASE_BODY(auto_array_copy_ref)
+
+ATF_TEST_CASE_WITHOUT_HEAD(create_file);
+ATF_TEST_CASE_BODY(create_file)
{
- using atf::utils::auto_array;
-
- ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
- {
- auto_array< test_array > t1(new test_array[10]);
- ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
-
- {
- auto_array< test_array > t2 = test_array::do_copy(t1);
- ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
- }
- ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
+ atf::utils::create_file("test.txt", "This is a %d test");
+
+ ATF_REQUIRE_EQ("This is a %d test", read_file("test.txt"));
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(file_exists);
+ATF_TEST_CASE_BODY(file_exists)
+{
+ atf::utils::create_file("test.txt", "foo");
+
+ ATF_REQUIRE( atf::utils::file_exists("test.txt"));
+ ATF_REQUIRE( atf::utils::file_exists("./test.txt"));
+ ATF_REQUIRE(!atf::utils::file_exists("./test.tx"));
+ ATF_REQUIRE(!atf::utils::file_exists("test.txt2"));
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(fork);
+ATF_TEST_CASE_BODY(fork)
+{
+ std::cout << "Should not get into child\n";
+ std::cerr << "Should not get into child\n";
+ pid_t pid = atf::utils::fork();
+ if (pid == 0) {
+ std::cout << "Child stdout\n";
+ std::cerr << "Child stderr\n";
+ exit(EXIT_SUCCESS);
}
- ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
+
+ int status;
+ ATF_REQUIRE(waitpid(pid, &status, 0) != -1);
+ ATF_REQUIRE(WIFEXITED(status));
+ ATF_REQUIRE_EQ(EXIT_SUCCESS, WEXITSTATUS(status));
+
+ ATF_REQUIRE_EQ("Child stdout\n", read_file("atf_utils_fork_out.txt"));
+ ATF_REQUIRE_EQ("Child stderr\n", read_file("atf_utils_fork_err.txt"));
}
-ATF_TEST_CASE(auto_array_get);
-ATF_TEST_CASE_HEAD(auto_array_get)
+ATF_TEST_CASE_WITHOUT_HEAD(grep_collection__set);
+ATF_TEST_CASE_BODY(grep_collection__set)
{
- set_md_var("descr", "Tests the auto_array smart pointer class' get "
- "method");
+ std::set< std::string > strings;
+ strings.insert("First");
+ strings.insert("Second");
+
+ ATF_REQUIRE( atf::utils::grep_collection("irs", strings));
+ ATF_REQUIRE( atf::utils::grep_collection("cond", strings));
+ ATF_REQUIRE(!atf::utils::grep_collection("Third", strings));
}
-ATF_TEST_CASE_BODY(auto_array_get)
+
+ATF_TEST_CASE_WITHOUT_HEAD(grep_collection__vector);
+ATF_TEST_CASE_BODY(grep_collection__vector)
{
- using atf::utils::auto_array;
+ std::vector< std::string > strings;
+ strings.push_back("First");
+ strings.push_back("Second");
- test_array* ta = new test_array[10];
- auto_array< test_array > t(ta);
- ATF_REQUIRE_EQ(t.get(), ta);
+ ATF_REQUIRE( atf::utils::grep_collection("irs", strings));
+ ATF_REQUIRE( atf::utils::grep_collection("cond", strings));
+ ATF_REQUIRE(!atf::utils::grep_collection("Third", strings));
}
-ATF_TEST_CASE(auto_array_release);
-ATF_TEST_CASE_HEAD(auto_array_release)
+ATF_TEST_CASE_WITHOUT_HEAD(grep_file);
+ATF_TEST_CASE_BODY(grep_file)
{
- set_md_var("descr", "Tests the auto_array smart pointer class' release "
- "method");
+ atf::utils::create_file("test.txt", "line1\nthe second line\naaaabbbb\n");
+
+ ATF_REQUIRE(atf::utils::grep_file("line1", "test.txt"));
+ ATF_REQUIRE(atf::utils::grep_file("second line", "test.txt"));
+ ATF_REQUIRE(atf::utils::grep_file("aa.*bb", "test.txt"));
+ ATF_REQUIRE(!atf::utils::grep_file("foo", "test.txt"));
+ ATF_REQUIRE(!atf::utils::grep_file("bar", "test.txt"));
+ ATF_REQUIRE(!atf::utils::grep_file("aaaaa", "test.txt"));
}
-ATF_TEST_CASE_BODY(auto_array_release)
+
+ATF_TEST_CASE_WITHOUT_HEAD(grep_string);
+ATF_TEST_CASE_BODY(grep_string)
{
- using atf::utils::auto_array;
-
- test_array* ta1 = new test_array[10];
- {
- auto_array< test_array > t(ta1);
- ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
- test_array* ta2 = t.release();
- ATF_REQUIRE_EQ(ta2, ta1);
- ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
- }
- ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
- delete [] ta1;
+ const char *str = "a string - aaaabbbb";
+ ATF_REQUIRE(atf::utils::grep_string("a string", str));
+ ATF_REQUIRE(atf::utils::grep_string("^a string", str));
+ ATF_REQUIRE(atf::utils::grep_string("aaaabbbb$", str));
+ ATF_REQUIRE(atf::utils::grep_string("aa.*bb", str));
+ ATF_REQUIRE(!atf::utils::grep_string("foo", str));
+ ATF_REQUIRE(!atf::utils::grep_string("bar", str));
+ ATF_REQUIRE(!atf::utils::grep_string("aaaaa", str));
}
-ATF_TEST_CASE(auto_array_reset);
-ATF_TEST_CASE_HEAD(auto_array_reset)
+ATF_TEST_CASE_WITHOUT_HEAD(redirect__stdout);
+ATF_TEST_CASE_BODY(redirect__stdout)
{
- set_md_var("descr", "Tests the auto_array smart pointer class' reset "
- "method");
+ std::cout << "Buffer this";
+ atf::utils::redirect(STDOUT_FILENO, "captured.txt");
+ std::cout << "The printed message";
+ std::cout.flush();
+
+ ATF_REQUIRE_EQ("The printed message", read_file("captured.txt"));
}
-ATF_TEST_CASE_BODY(auto_array_reset)
+
+ATF_TEST_CASE_WITHOUT_HEAD(redirect__stderr);
+ATF_TEST_CASE_BODY(redirect__stderr)
{
- using atf::utils::auto_array;
-
- test_array* ta1 = new test_array[10];
- test_array* ta2 = new test_array[10];
- ATF_REQUIRE_EQ(test_array::m_nblocks, 2);
-
- {
- auto_array< test_array > t(ta1);
- ATF_REQUIRE_EQ(test_array::m_nblocks, 2);
- t.reset(ta2);
- ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
- t.reset();
- ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
- }
- ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
+ std::cerr << "Buffer this";
+ atf::utils::redirect(STDERR_FILENO, "captured.txt");
+ std::cerr << "The printed message";
+ std::cerr.flush();
+
+ ATF_REQUIRE_EQ("The printed message", read_file("captured.txt"));
}
-ATF_TEST_CASE(auto_array_assign);
-ATF_TEST_CASE_HEAD(auto_array_assign)
+ATF_TEST_CASE_WITHOUT_HEAD(redirect__other);
+ATF_TEST_CASE_BODY(redirect__other)
{
- set_md_var("descr", "Tests the auto_array smart pointer class' "
- "assignment operator");
+ const std::string message = "Foo bar\nbaz\n";
+ atf::utils::redirect(15, "captured.txt");
+ ATF_REQUIRE(write(15, message.c_str(), message.length()) != -1);
+ close(15);
+
+ ATF_REQUIRE_EQ(message, read_file("captured.txt"));
}
-ATF_TEST_CASE_BODY(auto_array_assign)
+
+static void
+fork_and_wait(const int exitstatus, const char* expout, const char* experr)
{
- using atf::utils::auto_array;
-
- ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
- {
- auto_array< test_array > t1(new test_array[10]);
- ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
-
- {
- auto_array< test_array > t2;
- t2 = t1;
- ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
- }
- ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
+ const pid_t pid = atf::utils::fork();
+ if (pid == 0) {
+ std::cout << "Some output\n";
+ std::cerr << "Some error\n";
+ exit(123);
}
- ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
+ atf::utils::wait(pid, exitstatus, expout, experr);
+ exit(EXIT_SUCCESS);
}
-ATF_TEST_CASE(auto_array_assign_ref);
-ATF_TEST_CASE_HEAD(auto_array_assign_ref)
+ATF_TEST_CASE_WITHOUT_HEAD(wait__ok);
+ATF_TEST_CASE_BODY(wait__ok)
{
- set_md_var("descr", "Tests the auto_array smart pointer class' "
- "assignment operator through the auxiliary auto_array_ref "
- "object");
+ const pid_t control = fork();
+ ATF_REQUIRE(control != -1);
+ if (control == 0)
+ fork_and_wait(123, "Some output\n", "Some error\n");
+ else {
+ int status;
+ ATF_REQUIRE(waitpid(control, &status, 0) != -1);
+ ATF_REQUIRE(WIFEXITED(status));
+ ATF_REQUIRE_EQ(EXIT_SUCCESS, WEXITSTATUS(status));
+ }
}
-ATF_TEST_CASE_BODY(auto_array_assign_ref)
+
+ATF_TEST_CASE_WITHOUT_HEAD(wait__invalid_exitstatus);
+ATF_TEST_CASE_BODY(wait__invalid_exitstatus)
{
- using atf::utils::auto_array;
-
- ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
- {
- auto_array< test_array > t1(new test_array[10]);
- ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
-
- {
- auto_array< test_array > t2;
- t2 = test_array::do_copy(t1);
- ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
- }
- ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
+ const pid_t control = fork();
+ ATF_REQUIRE(control != -1);
+ if (control == 0)
+ fork_and_wait(120, "Some output\n", "Some error\n");
+ else {
+ int status;
+ ATF_REQUIRE(waitpid(control, &status, 0) != -1);
+ ATF_REQUIRE(WIFEXITED(status));
+ ATF_REQUIRE_EQ(EXIT_FAILURE, WEXITSTATUS(status));
}
- ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
}
-ATF_TEST_CASE(auto_array_access);
-ATF_TEST_CASE_HEAD(auto_array_access)
+ATF_TEST_CASE_WITHOUT_HEAD(wait__invalid_stdout);
+ATF_TEST_CASE_BODY(wait__invalid_stdout)
{
- set_md_var("descr", "Tests the auto_array smart pointer class' access "
- "operator");
+ const pid_t control = fork();
+ ATF_REQUIRE(control != -1);
+ if (control == 0)
+ fork_and_wait(123, "Some output foo\n", "Some error\n");
+ else {
+ int status;
+ ATF_REQUIRE(waitpid(control, &status, 0) != -1);
+ ATF_REQUIRE(WIFEXITED(status));
+ ATF_REQUIRE_EQ(EXIT_FAILURE, WEXITSTATUS(status));
+ }
}
-ATF_TEST_CASE_BODY(auto_array_access)
-{
- using atf::utils::auto_array;
- auto_array< test_array > t(new test_array[10]);
+ATF_TEST_CASE_WITHOUT_HEAD(wait__invalid_stderr);
+ATF_TEST_CASE_BODY(wait__invalid_stderr)
+{
+ const pid_t control = fork();
+ ATF_REQUIRE(control != -1);
+ if (control == 0)
+ fork_and_wait(123, "Some output\n", "Some error foo\n");
+ else {
+ int status;
+ ATF_REQUIRE(waitpid(control, &status, 0) != -1);
+ ATF_REQUIRE(WIFEXITED(status));
+ ATF_REQUIRE_EQ(EXIT_FAILURE, WEXITSTATUS(status));
+ }
+}
- for (int i = 0; i < 10; i++)
- t[i].m_value = i * 2;
+ATF_TEST_CASE_WITHOUT_HEAD(wait__save_stdout);
+ATF_TEST_CASE_BODY(wait__save_stdout)
+{
+ const pid_t control = fork();
+ ATF_REQUIRE(control != -1);
+ if (control == 0)
+ fork_and_wait(123, "save:my-output.txt", "Some error\n");
+ else {
+ int status;
+ ATF_REQUIRE(waitpid(control, &status, 0) != -1);
+ ATF_REQUIRE(WIFEXITED(status));
+ ATF_REQUIRE_EQ(EXIT_SUCCESS, WEXITSTATUS(status));
+
+ ATF_REQUIRE(atf::utils::compare_file("my-output.txt", "Some output\n"));
+ }
+}
- for (int i = 0; i < 10; i++)
- ATF_REQUIRE_EQ(t[i].m_value, i * 2);
+ATF_TEST_CASE_WITHOUT_HEAD(wait__save_stderr);
+ATF_TEST_CASE_BODY(wait__save_stderr)
+{
+ const pid_t control = fork();
+ ATF_REQUIRE(control != -1);
+ if (control == 0)
+ fork_and_wait(123, "Some output\n", "save:my-output.txt");
+ else {
+ int status;
+ ATF_REQUIRE(waitpid(control, &status, 0) != -1);
+ ATF_REQUIRE(WIFEXITED(status));
+ ATF_REQUIRE_EQ(EXIT_SUCCESS, WEXITSTATUS(status));
+
+ ATF_REQUIRE(atf::utils::compare_file("my-output.txt", "Some error\n"));
+ }
}
// ------------------------------------------------------------------------
@@ -292,16 +444,43 @@ HEADER_TC(include, "atf-c++/utils.hpp");
ATF_INIT_TEST_CASES(tcs)
{
- // Add the test for the "auto_array" class.
- ATF_ADD_TEST_CASE(tcs, auto_array_scope);
- ATF_ADD_TEST_CASE(tcs, auto_array_copy);
- ATF_ADD_TEST_CASE(tcs, auto_array_copy_ref);
- ATF_ADD_TEST_CASE(tcs, auto_array_get);
- ATF_ADD_TEST_CASE(tcs, auto_array_release);
- ATF_ADD_TEST_CASE(tcs, auto_array_reset);
- ATF_ADD_TEST_CASE(tcs, auto_array_assign);
- ATF_ADD_TEST_CASE(tcs, auto_array_assign_ref);
- ATF_ADD_TEST_CASE(tcs, auto_array_access);
+ // Add the test for the free functions.
+ ATF_ADD_TEST_CASE(tcs, cat_file__empty);
+ ATF_ADD_TEST_CASE(tcs, cat_file__one_line);
+ ATF_ADD_TEST_CASE(tcs, cat_file__several_lines);
+ ATF_ADD_TEST_CASE(tcs, cat_file__no_newline_eof);
+
+ ATF_ADD_TEST_CASE(tcs, compare_file__empty__match);
+ ATF_ADD_TEST_CASE(tcs, compare_file__empty__not_match);
+ ATF_ADD_TEST_CASE(tcs, compare_file__short__match);
+ ATF_ADD_TEST_CASE(tcs, compare_file__short__not_match);
+ ATF_ADD_TEST_CASE(tcs, compare_file__long__match);
+ ATF_ADD_TEST_CASE(tcs, compare_file__long__not_match);
+
+ ATF_ADD_TEST_CASE(tcs, copy_file__empty);
+ ATF_ADD_TEST_CASE(tcs, copy_file__some_contents);
+
+ ATF_ADD_TEST_CASE(tcs, create_file);
+
+ ATF_ADD_TEST_CASE(tcs, file_exists);
+
+ ATF_ADD_TEST_CASE(tcs, fork);
+
+ ATF_ADD_TEST_CASE(tcs, grep_collection__set);
+ ATF_ADD_TEST_CASE(tcs, grep_collection__vector);
+ ATF_ADD_TEST_CASE(tcs, grep_file);
+ ATF_ADD_TEST_CASE(tcs, grep_string);
+
+ ATF_ADD_TEST_CASE(tcs, redirect__stdout);
+ ATF_ADD_TEST_CASE(tcs, redirect__stderr);
+ ATF_ADD_TEST_CASE(tcs, redirect__other);
+
+ ATF_ADD_TEST_CASE(tcs, wait__ok);
+ ATF_ADD_TEST_CASE(tcs, wait__invalid_exitstatus);
+ ATF_ADD_TEST_CASE(tcs, wait__invalid_stdout);
+ ATF_ADD_TEST_CASE(tcs, wait__invalid_stderr);
+ ATF_ADD_TEST_CASE(tcs, wait__save_stdout);
+ ATF_ADD_TEST_CASE(tcs, wait__save_stderr);
// Add the test cases for the header file.
ATF_ADD_TEST_CASE(tcs, include);