diff options
Diffstat (limited to 'unit/atf-src/atf-c++')
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); |