summaryrefslogtreecommitdiff
path: root/external
diff options
context:
space:
mode:
authorjmmv <jmmv@NetBSD.org>2010-07-03 08:04:47 +0000
committerjmmv <jmmv@NetBSD.org>2010-07-03 08:04:47 +0000
commitedebbb8e6f8abcd6fefa7fb39b74d08d581cbece (patch)
tree06057ac7f9bce3eb8f2d78e347cc5d2c97a65f8d /external
parent6c3fa23d545e3de776d657c73f1f19ab26c533b6 (diff)
Import atf 0.10:
Miscellaneous features * Added expected failures support to test cases and atf-run. These include, for example, expected clean exits, expected reception of fatal signals, expected timeouts and expected errors in condition checks. These statuses can be used to denote test cases that are known to fail due to a bug in the code they are testing. atf-report reports these tests separately but they do not count towards the failed test cases amount. * Added the ATF_CHECK_ERRNO and ATF_REQUIRE_ERRNO to the C library to allow easy checking of call failures that update errno. * Added the has.cleanup meta-data property to test caes that specifies whether the test case has a cleanup routine or not; its value is automatically set. This property is read by atf-run to know if it has to run the cleanup routine; skipping this run for every test case significantly speeds up the run time of test suites. * Reversed the order of the ATF_CHECK_THROW macro in the C++ binding to take the expected exception as the first argument and the statement to execute as the second argument. Changes in atf-check * Changed atf-check to support negating the status and output checks by prefixing them with not- and added support to specify multiple checkers for stdout and stderr, not only one. * Added the match output checker to atf-check to look for regular expressions in the stdout and stderr of commands. * Modified the exit checks in atf-check to support checking for the reception of signals. Code simplifications and cleanups * Removed usage messages from test programs to simplify the implementation of every binding by a significant amount. They just now refer the user to the appropriate manual page and do not attempt to wrap lines on terminal boundaries. Test programs are not supposed to be run by users directly so this minor interface regression is not important. * Removed the atf-format internal utility, which is unused after the change documented above. * Removed the atf-cleanup internal utility. It has been unused since the test case isolation was moved to atf-run in 0.8 * Splitted the Makefile.am into smaller files for easier maintenance and dropped the use of M4. Only affects users building from the repository sources. * Intermixed tests with the source files in the source tree to provide them more visibility and easier access. The tests directory is gone from the source tree and tests are now suffixed by _test, not prefixed by t_. * Simplifications to the atf-c library: removed the io, tcr and ui modules as they had become unnecessary after all simplifications introduced since the 0.8 release. * Removed the application/X-atf-tcr format introduced in 0.8 release. Tests now print a much simplified format that is easy to parse and nicer to read by end users. As a side effect, the default for test cases is now to print their results to stdout unless otherwise stated by providing the -r flag. * Removed XML distribution documents and replaced them with plain-text documents. They provided little value and introduced a lot of complexity to the build system. * Simplified the output of atf-version by not attempting to print a revision number when building form a distfile. Makes the build system easier to maintain.
Diffstat (limited to 'external')
-rw-r--r--external/bsd/atf/dist/AUTHORS34
-rw-r--r--external/bsd/atf/dist/Atffile12
-rw-r--r--external/bsd/atf/dist/COPYING100
-rw-r--r--external/bsd/atf/dist/NEWS476
-rw-r--r--external/bsd/atf/dist/README60
-rw-r--r--external/bsd/atf/dist/atf-c++/Atffile23
-rw-r--r--external/bsd/atf/dist/atf-c++/application.cpp56
-rw-r--r--external/bsd/atf/dist/atf-c++/application.hpp4
-rw-r--r--external/bsd/atf/dist/atf-c++/application_test.cpp48
-rw-r--r--external/bsd/atf/dist/atf-c++/atf-c++-api.3112
-rw-r--r--external/bsd/atf/dist/atf-c++/atf_c++_test.cpp48
-rw-r--r--external/bsd/atf/dist/atf-c++/build_test.cpp247
-rw-r--r--external/bsd/atf/dist/atf-c++/check.cpp15
-rw-r--r--external/bsd/atf/dist/atf-c++/check.hpp10
-rw-r--r--external/bsd/atf/dist/atf-c++/check_test.cpp419
-rw-r--r--external/bsd/atf/dist/atf-c++/config.cpp1
-rw-r--r--external/bsd/atf/dist/atf-c++/config_test.cpp232
-rw-r--r--external/bsd/atf/dist/atf-c++/env_test.cpp101
-rw-r--r--external/bsd/atf/dist/atf-c++/exceptions_test.cpp157
-rw-r--r--external/bsd/atf/dist/atf-c++/expand_test.cpp282
-rw-r--r--external/bsd/atf/dist/atf-c++/fs.cpp90
-rw-r--r--external/bsd/atf/dist/atf-c++/fs.hpp86
-rw-r--r--external/bsd/atf/dist/atf-c++/fs_test.cpp706
-rw-r--r--external/bsd/atf/dist/atf-c++/io.cpp43
-rw-r--r--external/bsd/atf/dist/atf-c++/io_test.cpp585
-rw-r--r--external/bsd/atf/dist/atf-c++/macros.hpp16
-rw-r--r--external/bsd/atf/dist/atf-c++/macros_hpp_test.cpp125
-rw-r--r--external/bsd/atf/dist/atf-c++/macros_test.cpp517
-rw-r--r--external/bsd/atf/dist/atf-c++/parser.cpp233
-rw-r--r--external/bsd/atf/dist/atf-c++/parser.hpp81
-rw-r--r--external/bsd/atf/dist/atf-c++/parser_test.cpp1050
-rw-r--r--external/bsd/atf/dist/atf-c++/pkg_config_test.sh150
-rw-r--r--external/bsd/atf/dist/atf-c++/process_test.cpp367
-rw-r--r--external/bsd/atf/dist/atf-c++/sanity_test.cpp48
-rw-r--r--external/bsd/atf/dist/atf-c++/signals_test.cpp283
-rw-r--r--external/bsd/atf/dist/atf-c++/test_helpers.cpp122
-rw-r--r--external/bsd/atf/dist/atf-c++/test_helpers.hpp187
-rw-r--r--external/bsd/atf/dist/atf-c++/tests_test.cpp207
-rw-r--r--external/bsd/atf/dist/atf-c++/text_test.cpp375
-rw-r--r--external/bsd/atf/dist/atf-c++/ui.cpp129
-rw-r--r--external/bsd/atf/dist/atf-c++/ui_test.cpp471
-rw-r--r--external/bsd/atf/dist/atf-c++/user_test.cpp152
-rw-r--r--external/bsd/atf/dist/atf-c++/utils_test.cpp308
-rw-r--r--external/bsd/atf/dist/atf-c/Atffile5
-rw-r--r--external/bsd/atf/dist/atf-c/atf-c-api.3126
-rw-r--r--external/bsd/atf/dist/atf-c/atf_c_test.c50
-rw-r--r--external/bsd/atf/dist/atf-c/build_test.c286
-rw-r--r--external/bsd/atf/dist/atf-c/check.c12
-rw-r--r--external/bsd/atf/dist/atf-c/check.h2
-rw-r--r--external/bsd/atf/dist/atf-c/check_test.c578
-rw-r--r--external/bsd/atf/dist/atf-c/config.c1
-rw-r--r--external/bsd/atf/dist/atf-c/config_test.c156
-rw-r--r--external/bsd/atf/dist/atf-c/dynstr_test.c647
-rw-r--r--external/bsd/atf/dist/atf-c/env_test.c126
-rw-r--r--external/bsd/atf/dist/atf-c/error_test.c311
-rw-r--r--external/bsd/atf/dist/atf-c/fs.h2
-rw-r--r--external/bsd/atf/dist/atf-c/fs_test.c1106
-rw-r--r--external/bsd/atf/dist/atf-c/h_build.h414
-rw-r--r--external/bsd/atf/dist/atf-c/list_test.c336
-rw-r--r--external/bsd/atf/dist/atf-c/macros.h16
-rw-r--r--external/bsd/atf/dist/atf-c/macros_h_test.c103
-rw-r--r--external/bsd/atf/dist/atf-c/macros_test.c788
-rw-r--r--external/bsd/atf/dist/atf-c/map_test.c331
-rw-r--r--external/bsd/atf/dist/atf-c/pkg_config_test.sh151
-rw-r--r--external/bsd/atf/dist/atf-c/process_helpers.c117
-rw-r--r--external/bsd/atf/dist/atf-c/process_test.c1159
-rw-r--r--external/bsd/atf/dist/atf-c/sanity_test.c263
-rw-r--r--external/bsd/atf/dist/atf-c/tc.h14
-rw-r--r--external/bsd/atf/dist/atf-c/tc_test.c199
-rw-r--r--external/bsd/atf/dist/atf-c/test_helpers.c214
-rw-r--r--external/bsd/atf/dist/atf-c/test_helpers.h77
-rw-r--r--external/bsd/atf/dist/atf-c/test_helpers_test.c188
-rw-r--r--external/bsd/atf/dist/atf-c/text_test.c434
-rw-r--r--external/bsd/atf/dist/atf-c/tp.c2
-rw-r--r--external/bsd/atf/dist/atf-c/tp_main.c110
-rw-r--r--external/bsd/atf/dist/atf-c/tp_test.c50
-rw-r--r--external/bsd/atf/dist/atf-c/user_test.c151
-rw-r--r--external/bsd/atf/dist/atf-check/Atffile5
-rw-r--r--external/bsd/atf/dist/atf-check/atf-check.cpp670
-rw-r--r--external/bsd/atf/dist/atf-check/integration_test.sh462
-rw-r--r--external/bsd/atf/dist/atf-config/Atffile5
-rw-r--r--external/bsd/atf/dist/atf-config/atf-config.110
-rw-r--r--external/bsd/atf/dist/atf-config/integration_test.sh219
-rw-r--r--external/bsd/atf/dist/atf-report/Atffile5
-rw-r--r--external/bsd/atf/dist/atf-report/fail_helper.cpp45
-rw-r--r--external/bsd/atf/dist/atf-report/integration_test.sh427
-rw-r--r--external/bsd/atf/dist/atf-report/misc_helpers.cpp68
-rw-r--r--external/bsd/atf/dist/atf-report/pass_helper.cpp44
-rw-r--r--external/bsd/atf/dist/atf-report/reader.cpp383
-rw-r--r--external/bsd/atf/dist/atf-report/reader.hpp86
-rw-r--r--external/bsd/atf/dist/atf-report/reader_test.cpp943
-rw-r--r--external/bsd/atf/dist/atf-run/Atffile5
-rw-r--r--external/bsd/atf/dist/atf-run/atf-run.12
-rw-r--r--external/bsd/atf/dist/atf-run/atffile.cpp337
-rw-r--r--external/bsd/atf/dist/atf-run/atffile.hpp94
-rw-r--r--external/bsd/atf/dist/atf-run/atffile_test.cpp648
-rw-r--r--external/bsd/atf/dist/atf-run/bad_metadata_helper.c38
-rw-r--r--external/bsd/atf/dist/atf-run/config.cpp101
-rw-r--r--external/bsd/atf/dist/atf-run/config.hpp18
-rw-r--r--external/bsd/atf/dist/atf-run/config_test.cpp380
-rw-r--r--external/bsd/atf/dist/atf-run/expect_helpers.c193
-rw-r--r--external/bsd/atf/dist/atf-run/fs.cpp255
-rw-r--r--external/bsd/atf/dist/atf-run/fs.hpp58
-rw-r--r--external/bsd/atf/dist/atf-run/fs_test.cpp292
-rw-r--r--external/bsd/atf/dist/atf-run/integration_test.sh1067
-rw-r--r--external/bsd/atf/dist/atf-run/misc_helpers.cpp307
-rw-r--r--external/bsd/atf/dist/atf-run/pass_helper.cpp44
-rw-r--r--external/bsd/atf/dist/atf-run/requirements_test.cpp304
-rw-r--r--external/bsd/atf/dist/atf-run/several_tcs_helper.c71
-rw-r--r--external/bsd/atf/dist/atf-run/test_program_test.cpp1018
-rw-r--r--external/bsd/atf/dist/atf-run/zero_tcs_helper.c35
-rw-r--r--external/bsd/atf/dist/atf-sh/Atffile10
-rw-r--r--external/bsd/atf/dist/atf-sh/atf-sh-api.393
-rw-r--r--external/bsd/atf/dist/atf-sh/atf_check_test.sh187
-rw-r--r--external/bsd/atf/dist/atf-sh/config_test.sh85
-rw-r--r--external/bsd/atf/dist/atf-sh/integration_test.sh100
-rw-r--r--external/bsd/atf/dist/atf-sh/libatf-sh.subr296
-rw-r--r--external/bsd/atf/dist/atf-sh/misc_helpers.sh278
-rw-r--r--external/bsd/atf/dist/atf-sh/normalize_test.sh49
-rw-r--r--external/bsd/atf/dist/atf-sh/tc_test.sh50
-rw-r--r--external/bsd/atf/dist/atf-sh/tp_test.sh57
-rwxr-xr-xexternal/bsd/atf/dist/atf-version/generate-revision.sh182
-rw-r--r--external/bsd/atf/dist/atf-version/revision.h4
-rw-r--r--external/bsd/atf/dist/doc/atf-formats.532
-rw-r--r--external/bsd/atf/dist/doc/atf-test-case.455
-rw-r--r--external/bsd/atf/dist/doc/atf-test-program.163
-rw-r--r--external/bsd/atf/dist/doc/atf.7.in25
-rw-r--r--external/bsd/atf/dist/test-programs/Atffile10
-rw-r--r--external/bsd/atf/dist/test-programs/c_helpers.c577
-rw-r--r--external/bsd/atf/dist/test-programs/common.sh43
-rw-r--r--external/bsd/atf/dist/test-programs/config_test.sh63
-rw-r--r--external/bsd/atf/dist/test-programs/cpp_helpers.cpp382
-rw-r--r--external/bsd/atf/dist/test-programs/expect_test.sh167
-rw-r--r--external/bsd/atf/dist/test-programs/fork_test.sh65
-rw-r--r--external/bsd/atf/dist/test-programs/meta_data_test.sh66
-rw-r--r--external/bsd/atf/dist/test-programs/result_test.sh124
-rw-r--r--external/bsd/atf/dist/test-programs/sh_helpers.sh431
-rw-r--r--external/bsd/atf/dist/test-programs/srcdir_test.sh153
138 files changed, 28532 insertions, 1047 deletions
diff --git a/external/bsd/atf/dist/AUTHORS b/external/bsd/atf/dist/AUTHORS
index 9c07378ceb4..28e7b7e9239 100644
--- a/external/bsd/atf/dist/AUTHORS
+++ b/external/bsd/atf/dist/AUTHORS
@@ -1,27 +1,25 @@
- List of contributors to ATF
+Authors and contributors Automated Testing Framework
+===========================================================================
- By Julio Merino, The NetBSD Foundation
- Contents
+* Julio Merino <jmmv@NetBSD.org>
- 1. Authors
+ Main developer. He started the work on this project when he took part in
+ the Google Summer of Code 2007 program as a student.
- Authors
+* Martin Husemann <martin@NetBSD.org>
- * Julio Merino <jmmv@NetBSD.org>
+ Mentored this project during its development as part of the Google Summer
+ of Code 2007 program.
- Main developer. He started the work on this project when he took part
- in the Google Summer of Code 2007 program as a student.
+* Lukasz Strzygowski <qx89l4@gmail.com>
- * Martin Husemann <martin@NetBSD.org>
+ Participant of the Google Summer of Code 2008 program. Mentored by The
+ NetBSD Foundation, he worked on the atfify NetBSD-SoC project and, as a
+ side-effect, he contributed to the ATF source code. He developed the
+ initial version of the atf-check utility and started the addition of the
+ ATF_REQUIRE family of macros in the C interface.
- Mentored this project during its development as part of the Google
- Summer of Code 2007 program.
- * Lukasz Strzygowski <qx89l4@gmail.com>
-
- Participant of the Google Summer of Code 2008 program. Mentored by The
- NetBSD Foundation, he worked on the atfify NetBSD-SoC project and, as
- a side-effect, he contributed to the ATF source code. He developed the
- initial version of the atf-check utility and started the addition of
- the ATF_REQUIRE family of macros in the C interface.
+===========================================================================
+vim: filetype=text:textwidth=75:expandtab:shiftwidth=2:softtabstop=2
diff --git a/external/bsd/atf/dist/Atffile b/external/bsd/atf/dist/Atffile
new file mode 100644
index 00000000000..454342d495e
--- /dev/null
+++ b/external/bsd/atf/dist/Atffile
@@ -0,0 +1,12 @@
+Content-Type: application/X-atf-atffile; version="1"
+
+prop: test-suite = atf
+
+tp: atf-c
+tp: atf-c++
+tp: atf-sh
+tp: test-programs
+tp: atf-check
+tp: atf-config
+tp: atf-report
+tp: atf-run
diff --git a/external/bsd/atf/dist/COPYING b/external/bsd/atf/dist/COPYING
index 923edf908df..bf6db08a21f 100644
--- a/external/bsd/atf/dist/COPYING
+++ b/external/bsd/atf/dist/COPYING
@@ -1,70 +1,70 @@
- Redistribution terms
+Redistribution terms Automated Testing Framework
+===========================================================================
- By Julio Merino, The NetBSD Foundation
- Contents
+License
+*******
- 1. License
+Copyright (c) 2007, 2008, 2009, 2010 The NetBSD Foundation, Inc.
+All rights reserved.
- 2. Relicensed code
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
- License
+1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
- Copyright (c) 2007, 2008, 2009, 2010 The NetBSD Foundation, Inc. All
- rights reserved.
+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.
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are
- met:
+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.
- 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.
+Relicensed code
+***************
- 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.
+The following code snippets have been taken from other projects. Even
+though they were not originally licensed under the terms above, the
+original authors have agreed to relicense their work so that this project
+can be distributed under a single license. This section is put here just to
+clarify this fact.
- Relicensed code
+* configure.ac, Makefile.am: The original versions were derived from the
+ ones in the XML Catalog Manager project, version 2.2.
- The following code snippets have been taken from other projects. Even
- though they were not originally licensed under the terms above, the
- original authors have agreed to relicense their work so that this project
- can be distributed under a single license. This section is put here just
- to clarify this fact.
+ Author: Julio Merino <jmmv@users.sourceforge.net>
- * configure.ac, Makefile.am: The original versions were derived from the
- ones in the XML Catalog Manager project, version 2.2.
+* atf-c/ui.c: The format_paragraph and format_text functions were
+ derived form the ones in the Monotone project, revision
+ 3a0982da308228d796df35f98d787c5cff2bb5b6.
- Author: Julio M. Merino Vidal <jmmv@users.sourceforge.net>
+ Author: Julio Merino <jmmv@NetBSD.org>
- * atf-c/ui.c: The format_paragraph and format_text functions were
- derived form the ones in the Monotone project, revision
- 3a0982da308228d796df35f98d787c5cff2bb5b6.
+* atf-c++/io.hpp, atf-c++/io.cpp, tests/atf-c++/t_io.cpp: These files
+ were derived from the file_handle, systembuf, pipe, pistream and postream
+ classes and tests found in the Boost.Process library.
- Author: Julio M. Merino Vidal <jmmv@NetBSD.org>
+ Author: Julio Merino <jmmv84@gmail.com>
- * atf-c++/io.hpp, atf-c++/io.cpp, tests/atf-c++/t_io.cpp: These files
- were derived from the file_handle, systembuf, pipe, pistream and
- postream classes and tests found in the Boost.Process library.
+* admin/check-style.sh, admin/check-style-common.awk,
+ admin/check-style-cpp.awk, admin/check-style-shell.awk: These files,
+ except the first one, were first implemented in the Buildtool project.
+ They were later adapted to be part of Boost.Process and, during that
+ process, the shell script was created.
- Author: Julio M. Merino Vidal <jmmv84@gmail.com>
+ Author: Julio Merino <jmmv84@gmail.com>
- * admin/check-style.sh, admin/check-style-common.awk,
- admin/check-style-cpp.awk, admin/check-style-shell.awk: These files,
- except the first one, were first implemented in the Buildtool project.
- They were later adapted to be part of Boost.Process and, during that
- process, the shell script was created.
- Author: Julio M. Merino Vidal <jmmv84@gmail.com>
+===========================================================================
+vim: filetype=text:textwidth=75:expandtab:shiftwidth=2:softtabstop=2
diff --git a/external/bsd/atf/dist/NEWS b/external/bsd/atf/dist/NEWS
index 0b1463d81ea..29f0c071e6a 100644
--- a/external/bsd/atf/dist/NEWS
+++ b/external/bsd/atf/dist/NEWS
@@ -1,284 +1,364 @@
- Major changes in ATF releases
+Major changes between releases Automated Testing Framework
+===========================================================================
- By Julio Merino, The NetBSD Foundation
- Contents
+Changes in version 0.10
+***********************
- 1. Changes in version 0.9
+Experimental version released on July 2nd, 2010.
- 2. Changes in version 0.8
+Miscellaneous features
- 3. Changes in version 0.7
+* Added expected failures support to test cases and atf-run. These
+ include, for example, expected clean exits, expected reception of fatal
+ signals, expected timeouts and expected errors in condition checks.
+ These statuses can be used to denote test cases that are known to fail
+ due to a bug in the code they are testing. atf-report reports these
+ tests separately but they do not count towards the failed test cases
+ amount.
- 4. Changes in version 0.6
+* Added the ATF_CHECK_ERRNO and ATF_REQUIRE_ERRNO to the C library to
+ allow easy checking of call failures that update errno.
- 5. Changes in version 0.5
+* Added the has.cleanup meta-data property to test caes that specifies
+ whether the test case has a cleanup routine or not; its value is
+ automatically set. This property is read by atf-run to know if it has to
+ run the cleanup routine; skipping this run for every test case
+ significantly speeds up the run time of test suites.
- 6. Changes in version 0.4
+* Reversed the order of the ATF_CHECK_THROW macro in the C++ binding to
+ take the expected exception as the first argument and the statement to
+ execute as the second argument.
- 7. Changes in version 0.3
+Changes in atf-check
- 8. Changes in version 0.2
+* Changed atf-check to support negating the status and output checks by
+ prefixing them with not- and added support to specify multiple checkers
+ for stdout and stderr, not only one.
- 9. Changes in version 0.1
+* Added the match output checker to atf-check to look for regular
+ expressions in the stdout and stderr of commands.
- Changes in version 0.9
+* Modified the exit checks in atf-check to support checking for the
+ reception of signals.
- Experimental version released on June 3rd, 2010.
+Code simplifications and cleanups
- * Added atf-sh, an interpreter to process test programs written using
- the shell API. This is not really a shell interpreter by itself
- though: it is just a wrapper around the system shell that eases the
- loading of the necessary ATF libraries.
+* Removed usage messages from test programs to simplify the
+ implementation of every binding by a significant amount. They just now
+ refer the user to the appropriate manual page and do not attempt to wrap
+ lines on terminal boundaries. Test programs are not supposed to be run
+ by users directly so this minor interface regression is not important.
- * Removed atf-compile in favour of atf-sh.
+* Removed the atf-format internal utility, which is unused after the
+ change documented above.
- * Added the use.fs metadata property to test case, which is used to
- specify which test cases require file system access. This is to
- highlight dependencies on external resources more clearly and to speed
- up the execution of test suites by skipping the creation of many
- unnecessary work directories.
+* Removed the atf-cleanup internal utility. It has been unused since the
+ test case isolation was moved to atf-run in 0.8
- * Fixed test programs to get a sane default value for their source
- directory. This means that it should not be necessary any more to pass
- -s when running test programs that do not live in the current
- directory.
+* Splitted the Makefile.am into smaller files for easier maintenance and
+ dropped the use of M4. Only affects users building from the repository
+ sources.
- * Defining test case headers became optional. This is trivial to achieve
- in shell-based tests but a bit ugly in C and C++. In C, use the new
- ATF_TC_WITHOUT_HEAD macro to define the test case, and in C++ use
- ATF_TEST_CASE_WITHOUT_HEAD.
+* Intermixed tests with the source files in the source tree to provide
+ them more visibility and easier access. The tests directory is gone from
+ the source tree and tests are now suffixed by _test, not prefixed by t_.
- Changes in version 0.8
+* Simplifications to the atf-c library: removed the io, tcr and ui
+ modules as they had become unnecessary after all simplifications
+ introduced since the 0.8 release.
- Experimental version released on May 7th, 2010.
+* Removed the application/X-atf-tcr format introduced in 0.8 release.
+ Tests now print a much simplified format that is easy to parse and nicer
+ to read by end users. As a side effect, the default for test cases is
+ now to print their results to stdout unless otherwise stated by providing
+ the -r flag.
- * Test programs no longer run several test cases in a row. The execution
- of a test program now requires a test case name, and that single test
- case is executed. To execute several test cases, use the atf-run
- utility as usual.
+* Removed XML distribution documents and replaced them with plain-text
+ documents. They provided little value and introduced a lot of complexity
+ to the build system.
- * Test programs no longer fork a subprocess to isolate the execution of
- test cases. They run the test case code in-process, and a crash of the
- test case will result in a crash of the test program. This is to ease
- debugging of faulty test cases.
+* Simplified the output of atf-version by not attempting to print a
+ revision number when building form a distfile. Makes the build system
+ easier to maintain.
- * Test programs no longer isolate their test cases. This means that they
- will not create temporary directories nor sanitize the environment any
- more. Yes: running a test case that depends on system state by hand
- will most likely yield different results depending on where (machine,
- directory, user environment, etc.) it is run. Isolation has been moved
- to atf-run.
- * Test programs no longer print a cryptic format (application/X-atf-tcs)
- on a special file channel. They can now print whatever they want on
- the screen. Because test programs can now only run one test case every
- time, providing controlled output is not necessary any more.
+Changes in version 0.9
+**********************
- * Test programs no longer write their status into a special file
- descriptor. Instead, they create a file with the results, which is
- later parsed by atf-run. This changes the semantics of the -r flag.
+Experimental version released on June 3rd, 2010.
- * atf-run has been adjusted to perform the test case isolation. As a
- result, there is now a single canonical place that implements the
- isolation of test caes. In previous releases, the three language
- bindings (C, C++ and shell) had to be kept in sync with each other
- (read: not a nice thing to do at all). As a side effect of this
- change, writing bindings for other languages will be much, much easier
- from now on.
+* Added atf-sh, an interpreter to process test programs written using
+ the shell API. This is not really a shell interpreter by itself though:
+ it is just a wrapper around the system shell that eases the loading of
+ the necessary ATF libraries.
- * atf-run forks test programs on a test case basis, instead of on a test
- program basis as it did before. This is to provide the test case
- isolation that was before implemented by the test programs themselves.
+* Removed atf-compile in favour of atf-sh.
- * Removed the atf-exec tool. This was used to implement test case
- isolation in atf-sh, but it is now unnecessary.
+* Added the use.fs metadata property to test case, which is used to
+ specify which test cases require file system access. This is to
+ highlight dependencies on external resources more clearly and to speed up
+ the execution of test suites by skipping the creation of many unnecessary
+ work directories.
- * It is now optional to define the descr meta-data property. It has been
- proven to be mostly useless, because test cases often carry a
- descriptive name of their own.
+* Fixed test programs to get a sane default value for their source
+ directory. This means that it should not be necessary any more to pass
+ -s when running test programs that do not live in the current directory.
- Changes in version 0.7
+* Defining test case headers became optional. This is trivial to achieve
+ in shell-based tests but a bit ugly in C and C++. In C, use the new
+ ATF_TC_WITHOUT_HEAD macro to define the test case, and in C++ use
+ ATF_TEST_CASE_WITHOUT_HEAD.
- Experimental version released on December 22nd, 2009.
- * Added build-time checks to atf-c and atf-c++. A binding for atf-sh
- will come later.
+Changes in version 0.8
+**********************
- * Migrated all build-time checks for header files to proper ATF tests.
- This demonstrates the use of the new feature described above.
+Experimental version released on May 7th, 2010.
- * Added an internal API for child process management.
+* Test programs no longer run several test cases in a row. The execution
+ of a test program now requires a test case name, and that single test
+ case is executed. To execute several test cases, use the atf-run utility
+ as usual.
- * Converted all plain-text distribution documents to a Docbook canonical
- version, and include pre-generated plain text and HTML copies in the
- distribution file.
+* Test programs no longer fork a subprocess to isolate the execution of
+ test cases. They run the test case code in-process, and a crash of the
+ test case will result in a crash of the test program. This is to ease
+ debugging of faulty test cases.
- * Simplified the contents of the Makefile.am by regenerating it from a
- canonical Makefile.am.m4 source. As a side-effect, some dependency
- specifications were fixed.
+* Test programs no longer isolate their test cases. This means that they
+ will not create temporary directories nor sanitize the environment any
+ more. Yes: running a test case that depends on system state by hand will
+ most likely yield different results depending on where (machine,
+ directory, user environment, etc.) it is run. Isolation has been moved
+ to atf-run.
- * Migrated all checks from the check target to installcheck, as these
- require ATF to be installed.
+* Test programs no longer print a cryptic format (application/X-atf-tcs)
+ on a special file channel. They can now print whatever they want on the
+ screen. Because test programs can now only run one test case every time,
+ providing controlled output is not necessary any more.
- * Fixed sign comparison mismatches triggered by the now-enabled
- -Wsign-compare.
+* Test programs no longer write their status into a special file
+ descriptor. Instead, they create a file with the results, which is later
+ parsed by atf-run. This changes the semantics of the -r flag.
- * Fixed many memory and object leaks.
+* atf-run has been adjusted to perform the test case isolation. As a
+ result, there is now a single canonical place that implements the
+ isolation of test caes. In previous releases, the three language
+ bindings (C, C++ and shell) had to be kept in sync with each other (read:
+ not a nice thing to do at all). As a side effect of this change, writing
+ bindings for other languages will be much, much easier from now on.
- Changes in version 0.6
+* atf-run forks test programs on a test case basis, instead of on a test
+ program basis as it did before. This is to provide the test case
+ isolation that was before implemented by the test programs themselves.
- Experimental version released on January 18th, 2009.
+* Removed the atf-exec tool. This was used to implement test case
+ isolation in atf-sh, but it is now unnecessary.
- * Make atf-exec be able to kill its child process after a certain period
- of time; this is controlled through the new -t option.
+* It is now optional to define the descr meta-data property. It has been
+ proven to be mostly useless, because test cases often carry a descriptive
+ name of their own.
- * Change atf-sh to use atf-exec's -t option to control the test case's
- timeouts, instead of doing it internally. Same behavior as before, but
- noticeably faster.
- * atf-exec's -g option and atf-killpg are gone due to the previous
- change.
+Changes in version 0.7
+**********************
- * Added the atf-check(1) tool, a program that executes a given command
- and checks its exit code against a known value and allows the
- management of stdout and stderr in multiple ways. This replaces the
- previous atf_check function in the atf-sh library and exposes this
- functionality to both atf-c and atf-c++.
+Experimental version released on December 22nd, 2009.
- * Added the ATF_REQUIRE family of macros to the C interface. These help
- in checking for fatal test conditions. The old ATF_CHECK macros now
- perform non-fatal checks only. I.e. by using ATF_CHECK, the test case
- can now continue its execution and the failures will not be reported
- until the end of the whole run.
+* Added build-time checks to atf-c and atf-c++. A binding for atf-sh
+ will come later.
- * Extended the amount of ATF_CHECK_* C macros with new ones to provide
- more features to the developer. These also have their corresponding
- counterparts in the ATF_REQUIRE_* family. The new macros (listing the
- suffixes only) are: _EQ (replaces _EQUAL), _EQ_MSG, _STREQ and
- _STREQ_MSG.
+* Migrated all build-time checks for header files to proper ATF tests.
+ This demonstrates the use of the new feature described above.
- Changes in version 0.5
+* Added an internal API for child process management.
- Experimental version released on May 1st, 2008.
+* Converted all plain-text distribution documents to a Docbook canonical
+ version, and include pre-generated plain text and HTML copies in the
+ distribution file.
- * Clauses 3 and 4 of the BSD license used by the project were dropped.
- All the code is now under a 2-clause BSD license compatible with the
- GNU General Public License (GPL).
+* Simplified the contents of the Makefile.am by regenerating it from a
+ canonical Makefile.am.m4 source. As a side-effect, some dependency
+ specifications were fixed.
- * Added a C-only binding so that binary test programs do not need to be
- tied to C++ at all. This binding is now known as the atf-c library.
+* Migrated all checks from the check target to installcheck, as these
+ require ATF to be installed.
- * Renamed the C++ binding to atf-c++ for consistency with the new atf-c.
+* Fixed sign comparison mismatches triggered by the now-enabled
+ -Wsign-compare.
- * Renamed the POSIX shell binding to atf-sh for consistency with the new
- atf-c and atf-c++.
+* Fixed many memory and object leaks.
- * Added a -w flag to test programs through which it is possible to
- specify the work directory to be used. This was possible in prior
- releases by defining the workdir configuration variable (-v
- workdir=...), but was a conceptually incorrect mechanism.
- * Test programs now preserve the execution order of test cases when they
- are given in the command line. Even those mentioned more than once are
- executed multiple times to comply with the user's requests.
+Changes in version 0.6
+**********************
- Changes in version 0.4
+Experimental version released on January 18th, 2009.
- Experimental version released on February 4th, 2008.
+* Make atf-exec be able to kill its child process after a certain period
+ of time; this is controlled through the new -t option.
- * Added two new manual pages, atf-c++-api and atf-sh-api, describing the
- C++ and POSIX shell interfaces used to write test programs.
+* Change atf-sh to use atf-exec's -t option to control the test case's
+ timeouts, instead of doing it internally. Same behavior as before, but
+ noticeably faster.
- * Added a pkg-config file, useful to get the flags to build against the
- C++ library or to easily detect the presence of ATF.
+* atf-exec's -g option and atf-killpg are gone due to the previous
+ change.
- * Added a way for test cases to require a specific architecture and/or
- machine type through the new 'require.arch' and 'require.machine'
- meta-data properties, respectively.
+* Added the atf-check(1) tool, a program that executes a given command
+ and checks its exit code against a known value and allows the management
+ of stdout and stderr in multiple ways. This replaces the previous
+ atf_check function in the atf-sh library and exposes this functionality
+ to both atf-c and atf-c++.
- * Added the 'timeout' property to test cases, useful to set an
- upper-bound limit for the test's run time and thus prevent global test
- program stalls due to the test case's misbehavior.
+* Added the ATF_REQUIRE family of macros to the C interface. These help
+ in checking for fatal test conditions. The old ATF_CHECK macros now
+ perform non-fatal checks only. I.e. by using ATF_CHECK, the test case
+ can now continue its execution and the failures will not be reported
+ until the end of the whole run.
- * Added the atf-exec(1) internal utility, used to execute a command
- after changing the process group it belongs to.
+* Extended the amount of ATF_CHECK_* C macros with new ones to provide
+ more features to the developer. These also have their corresponding
+ counterparts in the ATF_REQUIRE_* family. The new macros (listing the
+ suffixes only) are: _EQ (replaces _EQUAL), _EQ_MSG, _STREQ and
+ _STREQ_MSG.
- * Added the atf-killpg(1) internal utility, used to kill process groups.
- * Multiple portability fixes. Of special interest, full support for
- SunOS (Solaris Express Developer Edition 2007/09) using the Sun Studio
- 12 C++ compiler.
+Changes in version 0.5
+**********************
- * Fixed a serious bug that prevented atf-run(1) from working at all
- under Fedora 8 x86_64. Due to the nature of the bug, other platforms
- were likely affected too.
+Experimental version released on May 1st, 2008.
- Changes in version 0.3
+* Clauses 3 and 4 of the BSD license used by the project were dropped.
+ All the code is now under a 2-clause BSD license compatible with the GNU
+ General Public License (GPL).
- Experimental version released on November 11th, 2007.
+* Added a C-only binding so that binary test programs do not need to be
+ tied to C++ at all. This binding is now known as the atf-c library.
- * Added XML output support to atf-report. This is accompanied by a DTD
- for the format's structure and sample XSLT/CSS files to post-process
- this output and convert it to a plain HTML report.
+* Renamed the C++ binding to atf-c++ for consistency with the new atf-c.
- * Changed atf-run to add system information to the report it generates.
- This is currently used by atf-report's XML output only, and is later
- printed in the HTML reports in a nice and useful summary table. The
- user and system administrator are allowed to tune this feature by
- means of hooks.
+* Renamed the POSIX shell binding to atf-sh for consistency with the new
+ atf-c and atf-c++.
- * Removed the test cases' 'isolated' property. This was intended to
- avoid touching the file system at all when running the related test
- case, but this has not been true for a long while: some control files
- are unconditionally required for several purposes, and we cannot
- easily get rid of them. This way we remove several critical and
- delicate pieces of code.
+* Added a -w flag to test programs through which it is possible to
+ specify the work directory to be used. This was possible in prior
+ releases by defining the workdir configuration variable (-v workdir=...),
+ but was a conceptually incorrect mechanism.
- * Improved atf-report's CSV output format to include information about
- test programs too.
+* Test programs now preserve the execution order of test cases when they
+ are given in the command line. Even those mentioned more than once are
+ executed multiple times to comply with the user's requests.
- * Fixed the tests that used atf-compile to not require this tool as a
- helper. Avoids systems without build-time utilities to skip many tests
- that could otherwise be run. (E.g. NetBSD without the comp.tgz set
- installed.)
- * Many general cleanups: Fixed many pieces of code marked as ugly and/or
- incomplete.
+Changes in version 0.4
+**********************
- Changes in version 0.2
+Experimental version released on February 4th, 2008.
- Experimental version released on September 20th, 2007.
+* Added two new manual pages, atf-c++-api and atf-sh-api, describing the
+ C++ and POSIX shell interfaces used to write test programs.
- * Test cases now get a known umask on entry.
+* Added a pkg-config file, useful to get the flags to build against the
+ C++ library or to easily detect the presence of ATF.
- * atf-run now detects many unexpected failures caused by test programs
- and reports them as bogus tests. atf-report is able to handle these
- new errors and nicely reports them to the user.
+* Added a way for test cases to require a specific architecture and/or
+ machine type through the new 'require.arch' and 'require.machine'
+ meta-data properties, respectively.
- * All the data formats read and written by the tools have been
- documented and cleaned up. These include those grammars that define
- how the different components communicate with each other as well as
- the format of files written by the developers and users: the Atffiles
- and the configuration files.
+* Added the 'timeout' property to test cases, useful to set an
+ upper-bound limit for the test's run time and thus prevent global test
+ program stalls due to the test case's misbehavior.
- * Added the atf-version tool, a utility that displays information about
- the currently installed version of ATF.
+* Added the atf-exec(1) internal utility, used to execute a command
+ after changing the process group it belongs to.
- * Test cases can now define an optional cleanup routine to undo their
- actions regardless of their exit status.
+* Added the atf-killpg(1) internal utility, used to kill process groups.
- * atf-report now summarizes the list of failed (bogus) test programs
- when using the ticker output format.
+* Multiple portability fixes. Of special interest, full support for
+ SunOS (Solaris Express Developer Edition 2007/09) using the Sun Studio 12
+ C++ compiler.
- * Test programs now capture some termination signals and clean up any
- temporary files before exiting the program.
+* Fixed a serious bug that prevented atf-run(1) from working at all
+ under Fedora 8 x86_64. Due to the nature of the bug, other platforms
+ were likely affected too.
- * Multiple bug fixes and improvements all around.
- Changes in version 0.1
+Changes in version 0.3
+**********************
- Experimental version released on August 20th, 2007.
+Experimental version released on November 11th, 2007.
- * First public version. This was released coinciding with the end of the
- Google Summer of Code 2007 program.
+* Added XML output support to atf-report. This is accompanied by a DTD
+ for the format's structure and sample XSLT/CSS files to post-process this
+ output and convert it to a plain HTML report.
+
+* Changed atf-run to add system information to the report it generates.
+ This is currently used by atf-report's XML output only, and is later
+ printed in the HTML reports in a nice and useful summary table. The user
+ and system administrator are allowed to tune this feature by means of
+ hooks.
+
+* Removed the test cases' 'isolated' property. This was intended to
+ avoid touching the file system at all when running the related test case,
+ but this has not been true for a long while: some control files are
+ unconditionally required for several purposes, and we cannot easily get
+ rid of them. This way we remove several critical and delicate pieces of
+ code.
+
+* Improved atf-report's CSV output format to include information about
+ test programs too.
+
+* Fixed the tests that used atf-compile to not require this tool as a
+ helper. Avoids systems without build-time utilities to skip many tests
+ that could otherwise be run. (E.g. NetBSD without the comp.tgz set
+ installed.)
+
+* Many general cleanups: Fixed many pieces of code marked as ugly and/or
+ incomplete.
+
+
+Changes in version 0.2
+**********************
+
+Experimental version released on September 20th, 2007.
+
+* Test cases now get a known umask on entry.
+
+* atf-run now detects many unexpected failures caused by test programs and
+ reports them as bogus tests. atf-report is able to handle these new
+ errors and nicely reports them to the user.
+
+* All the data formats read and written by the tools have been
+ documented and cleaned up. These include those grammars that define how
+ the different components communicate with each other as well as the
+ format of files written by the developers and users: the Atffiles and the
+ configuration files.
+
+* Added the atf-version tool, a utility that displays information about
+ the currently installed version of ATF.
+
+* Test cases can now define an optional cleanup routine to undo their
+ actions regardless of their exit status.
+
+* atf-report now summarizes the list of failed (bogus) test programs
+ when using the ticker output format.
+
+* Test programs now capture some termination signals and clean up any
+ temporary files before exiting the program.
+
+* Multiple bug fixes and improvements all around.
+
+
+Changes in version 0.1
+**********************
+
+Experimental version released on August 20th, 2007.
+
+* First public version. This was released coinciding with the end of the
+ Google Summer of Code 2007 program.
+
+
+===========================================================================
+vim: filetype=text:textwidth=75:expandtab:shiftwidth=2:softtabstop=2
diff --git a/external/bsd/atf/dist/README b/external/bsd/atf/dist/README
index 0741bb3ed6f..00caa122a39 100644
--- a/external/bsd/atf/dist/README
+++ b/external/bsd/atf/dist/README
@@ -1,46 +1,40 @@
- Basic information
+Introductory information Automated Testing Framework
+===========================================================================
- By Julio Merino, The NetBSD Foundation
- Contents
+Introduction
+************
- 1. Introduction
+The Automated Testing Framework (ATF) is a collection of libraries and
+utilities designed to ease unattended application testing in the hands of
+developers and end users of a specific piece of software.
- 2. Other documents
+As regards developers, ATF provides the necessary means to easily create
+test suites composed of multiple test programs, which in turn are a
+collection of test cases. It also attempts to simplify the debugging of
+problems when these test cases detect an error by providing as much
+information as possible about the failure.
- 3. Contributing
+As regards users, it simplifies the process of running the test suites and,
+in special, encourages end users to run them often: they do not need to
+have source trees around nor any other development tools installed to be
+able to certify that a given piece of software works on their machine as
+advertised.
- Introduction
- The Automated Testing Framework (ATF) is a collection of libraries and
- utilities designed to ease unattended application testing in the hands of
- developers and end users of a specific piece of software.
+Other documents
+***************
- As regards developers, ATF provides the necessary means to easily create
- test suites composed of multiple test programs, which in turn are a
- collection of test cases. It also attempts to simplify the debugging of
- problems when these test cases detect an error by providing as much
- information as possible about the failure.
+* AUTHORS: List of authors and contributors for this project.
- As regards users, it simplifies the process of running the test suites
- and, in special, encourages end users to run them often: they do not need
- to have source trees around nor any other development tools installed to
- be able to certify that a given piece of software works on their machine
- as advertised.
+* COPYING: License information.
- Other documents
+* INSTALL: Compilation and installation instructions. These is not the
+ standard document shipped with many packages, so be sure to read it for
+ things that are specific to ATF's build.
- * AUTHORS: List of authors and contributors for this project.
+* NEWS: List of major changes between formal, published releases.
- * COPYING: License information.
- * INSTALL: Compilation and installation instructions. These is not the
- standard document shipped with many packages, so be sure to read it
- for things that are specific to ATF's build.
-
- * NEWS: List of major changes between formal, published releases.
-
- Contributing
-
- If you are planning to contribute code to the project, be absolutely sure
- to read doc/hacking.txt first.
+===========================================================================
+vim: filetype=text:textwidth=75:expandtab:shiftwidth=2:softtabstop=2
diff --git a/external/bsd/atf/dist/atf-c++/Atffile b/external/bsd/atf/dist/atf-c++/Atffile
new file mode 100644
index 00000000000..00e649398a2
--- /dev/null
+++ b/external/bsd/atf/dist/atf-c++/Atffile
@@ -0,0 +1,23 @@
+Content-Type: application/X-atf-atffile; version="1"
+
+prop: test-suite = atf
+
+tp: env_test
+tp: config_test
+tp: text_test
+tp: fs_test
+tp: macros_test
+tp: io_test
+tp: expand_test
+tp: user_test
+tp: parser_test
+tp: signals_test
+tp: tests_test
+tp: utils_test
+tp: process_test
+tp: build_test
+tp: application_test
+tp: exceptions_test
+tp: sanity_test
+tp: ui_test
+tp: pkg_config_test
diff --git a/external/bsd/atf/dist/atf-c++/application.cpp b/external/bsd/atf/dist/atf-c++/application.cpp
index d52e1983f7f..58781b24a27 100644
--- a/external/bsd/atf/dist/atf-c++/application.cpp
+++ b/external/bsd/atf/dist/atf-c++/application.cpp
@@ -103,14 +103,16 @@ impl::option::operator<(const impl::option& o)
impl::app::app(const std::string& description,
const std::string& manpage,
- const std::string& global_manpage) :
+ const std::string& global_manpage,
+ const bool use_ui) :
m_hflag(false),
m_argc(-1),
m_argv(NULL),
m_prog_name(NULL),
m_description(description),
m_manpage(manpage),
- m_global_manpage(global_manpage)
+ m_global_manpage(global_manpage),
+ m_use_ui(use_ui)
{
}
@@ -128,7 +130,9 @@ impl::app::options_set
impl::app::options(void)
{
options_set opts = specific_options();
- opts.insert(option('h', "", "Shows this help message"));
+ if (m_use_ui) {
+ opts.insert(option('h', "", "Shows this help message"));
+ }
return opts;
}
@@ -178,6 +182,7 @@ impl::app::process_options(void)
while ((ch = ::getopt(m_argc, m_argv, optstr.c_str())) != -1) {
switch (ch) {
case 'h':
+ INV(m_use_ui);
m_hflag = true;
break;
@@ -280,6 +285,7 @@ impl::app::run(int argc, char* const* argv)
process_options();
if (m_hflag) {
+ INV(m_use_ui);
if (oldargc != 2)
throw usage_error("-h must be given alone.");
@@ -288,27 +294,41 @@ impl::app::run(int argc, char* const* argv)
} else
errcode = main();
} catch (const usage_error& e) {
- std::cerr << ui::format_error(m_prog_name, e.what())
- << std::endl
- << ui::format_info(m_prog_name, std::string("Type `") +
- m_prog_name + " -h' for more details.")
- << std::endl;
+ if (m_use_ui) {
+ std::cerr << ui::format_error(m_prog_name, e.what()) << std::endl
+ << ui::format_info(m_prog_name, std::string("Type `") +
+ m_prog_name + " -h' for more details.")
+ << std::endl;
+ } else {
+ std::cerr << m_prog_name << ": ERROR: " << e.what() << "\n";
+ std::cerr << m_prog_name << ": See " << m_manpage << " for usage "
+ "details.\n";
+ }
errcode = EXIT_FAILURE;
} catch (const std::runtime_error& e) {
- std::cerr << ui::format_error(m_prog_name, std::string(e.what()))
- << std::endl;
+ if (m_use_ui) {
+ std::cerr << ui::format_error(m_prog_name, std::string(e.what()))
+ << std::endl;
+ } else {
+ std::cerr << m_prog_name << ": ERROR: " << e.what() << "\n";
+ }
errcode = EXIT_FAILURE;
} catch (const std::exception& e) {
- std::cerr << ui::format_error(m_prog_name,
- std::string("Caught unexpected error: ")
- + e.what() + "\n" + bug)
- << std::endl;
+ if (m_use_ui) {
+ std::cerr << ui::format_error(m_prog_name, std::string("Caught "
+ "unexpected error: ") + e.what() + "\n" + bug) << std::endl;
+ } else {
+ std::cerr << m_prog_name << ": ERROR: Caught unexpected error: "
+ << e.what() << "\n";
+ }
errcode = EXIT_FAILURE;
} catch (...) {
- std::cerr << ui::format_error(m_prog_name,
- std::string("Caught unknown error\n") +
- bug)
- << std::endl;
+ if (m_use_ui) {
+ std::cerr << ui::format_error(m_prog_name, std::string("Caught "
+ "unknown error\n") + bug) << std::endl;
+ } else {
+ std::cerr << m_prog_name << ": ERROR: Caught unknown error\n";
+ }
errcode = EXIT_FAILURE;
}
return errcode;
diff --git a/external/bsd/atf/dist/atf-c++/application.hpp b/external/bsd/atf/dist/atf-c++/application.hpp
index 94227522b74..98644211a7b 100644
--- a/external/bsd/atf/dist/atf-c++/application.hpp
+++ b/external/bsd/atf/dist/atf-c++/application.hpp
@@ -91,6 +91,7 @@ protected:
const char* m_prog_name;
std::string m_description;
std::string m_manpage, m_global_manpage;
+ const bool m_use_ui;
options_set options(void);
@@ -101,7 +102,8 @@ protected:
virtual int main(void) = 0;
public:
- app(const std::string&, const std::string&, const std::string&);
+ app(const std::string&, const std::string&, const std::string&,
+ bool = true);
virtual ~app(void);
int run(int, char* const*);
diff --git a/external/bsd/atf/dist/atf-c++/application_test.cpp b/external/bsd/atf/dist/atf-c++/application_test.cpp
new file mode 100644
index 00000000000..15aefed5b1d
--- /dev/null
+++ b/external/bsd/atf/dist/atf-c++/application_test.cpp
@@ -0,0 +1,48 @@
+//
+// Automated Testing Framework (atf)
+//
+// Copyright (c) 2009 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"
+
+#include "test_helpers.hpp"
+
+// ------------------------------------------------------------------------
+// Tests cases for the header file.
+// ------------------------------------------------------------------------
+
+HEADER_TC(include, "atf-c++/application.hpp");
+
+// ------------------------------------------------------------------------
+// Main.
+// ------------------------------------------------------------------------
+
+ATF_INIT_TEST_CASES(tcs)
+{
+ // Add the test cases for the header file.
+ ATF_ADD_TEST_CASE(tcs, include);
+}
diff --git a/external/bsd/atf/dist/atf-c++/atf-c++-api.3 b/external/bsd/atf/dist/atf-c++/atf-c++-api.3
index 3748465a53a..0ab87998b7d 100644
--- a/external/bsd/atf/dist/atf-c++/atf-c++-api.3
+++ b/external/bsd/atf/dist/atf-c++/atf-c++-api.3
@@ -26,17 +26,19 @@
.\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
.\" IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd June 1, 2010
+.Dd June 28, 2010
.Dt ATF-C++-API 3
.Os
.Sh NAME
.Nm ATF_ADD_TEST_CASE ,
.Nm ATF_CHECK ,
.Nm ATF_CHECK_EQUAL ,
+.Nm ATF_CHECK_ERRNO ,
.Nm ATF_CHECK_THROW ,
.Nm ATF_FAIL ,
.Nm ATF_INIT_TEST_CASES ,
.Nm ATF_PASS ,
+.Nm ATF_REQUIRE_ERRNO ,
.Nm ATF_SKIP ,
.Nm ATF_TEST_CASE ,
.Nm ATF_TEST_CASE_BODY ,
@@ -50,10 +52,12 @@
.Fn ATF_ADD_TEST_CASE "tcs" "name"
.Fn ATF_CHECK "expression"
.Fn ATF_CHECK_EQUAL "expression_1" "expression_2"
-.Fn ATF_CHECK_THROW "statement_1" "expected_exception"
+.Fn ATF_CHECK_ERRNO "exp_errno" "bool_expression"
+.Fn ATF_CHECK_THROW "expected_exception" "statement"
.Fn ATF_FAIL "reason"
.Fn ATF_INIT_TEST_CASES "tcs"
.Fn ATF_PASS
+.Fn ATF_REQUIRE_ERRNO "exp_errno" "bool_expression"
.Fn ATF_SKIP "reason"
.Fn ATF_TEST_CASE "name"
.Fn ATF_TEST_CASE_BODY "name"
@@ -126,7 +130,7 @@ ATF_INIT_TEST_CASES(tcs)
Test cases have an identifier and are composed of three different parts:
the header, the body and an optional cleanup routine, all of which are
described in
-.Xr atf-test-case 8 .
+.Xr atf-test-case 4 .
To define test cases, one can use the
.Fn ATF_TEST_CASE ,
.Fn ATF_TEST_CASE_WITH_CLEANUP
@@ -226,6 +230,65 @@ take a single string that describes why the test case failed or
was skipped, respectively.
It is very important to provide a clear error message in both cases so that
the user can quickly know why the test did not pass.
+.Ss Expectations
+Everything explained in the previous section changes when the test case
+expectations are redefined by the programmer.
+.Pp
+Each test case has an internal state called
+.Sq expect
+that describes what the test case expectations are at any point in time.
+The value of this property can change during execution by any of:
+.Bl -tag -width indent
+.It Fn expect_death "reason"
+Expects the test case to exit prematurely regardless of the nature of the
+exit.
+.It Fn expect_exit "exitcode" "reason"
+Expects the test case to exit cleanly.
+If
+.Va exitcode
+is not
+.Sq -1 ,
+.Xr atf-run 1
+will validate that the exit code of the test case matches the one provided
+in this call.
+Otherwise, the exact value will be ignored.
+.It Fn expect_fail "reason"
+Any failure (be it fatal or non-fatal) raised in this mode is recorded.
+However, such failures do not report the test case as failed; instead, the
+test case finalizes cleanly and is reported as
+.Sq expected failure ;
+this report includes the provided
+.Fa reason
+as part of it.
+If no error is raised while running in this mode, then the test case is
+reported as
+.Sq failed .
+.Pp
+This mode is useful to reproduce actual known bugs in tests.
+Whenever the developer fixes the bug later on, the test case will start
+reporting a failure, signaling the developer that the test case must be
+adjusted to the new conditions.
+In this situation, it is useful, for example, to set
+.Fa reason
+as the bug number for tracking purposes.
+.It Fn expect_pass
+This is the normal mode of execution.
+In this mode, any failure is reported as such to the user and the test case
+is marked as
+.Sq failed .
+.It Fn expect_signal "signo" "reason"
+Expects the test case to terminate due to the reception of a signal.
+If
+.Va signo
+is not
+.Sq -1 ,
+.Xr atf-run 1
+will validate that the signal that terminated the test case matches the one
+provided in this call.
+Otherwise, the exact value will be ignored.
+.It Fn expect_timeout "reason"
+Expects the test case to execute for longer than its timeout.
+.El
.Ss Helper macros for common checks
The library provides several macros that are very handy in multiple
situations.
@@ -243,8 +306,18 @@ takes two expressions and raises a failure if the two do not evaluate to
the same exact value.
.Pp
.Fn ATF_CHECK_THROW
-takes a statement and the name of an exception and raises a failure if
-the statement did not throw the specified exception.
+takes the name of an exception and a statement and raises a failure if
+the statement does not throw the specified exception.
+.Pp
+.Fn ATF_CHECK_ERRNO
+and
+.Fn ATF_REQUIRE_ERRNO
+take, first, the error code that the check is expecting to find in the
+.Va errno
+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.
.Sh EXAMPLES
The following shows a complete test program with a single test case that
validates the addition operator:
@@ -267,12 +340,37 @@ ATF_TEST_CASE_BODY(addition)
ATF_CHECK_EQUAL(100 + 200, 300);
}
+ATF_TEST_CASE(open_failure);
+ATF_TEST_CASE_HEAD(open_failure)
+{
+ set("descr", "Sample tests for the open function");
+}
+ATF_TEST_CASE_BODY(open_failure)
+{
+ ATF_CHECK_ERRNO(ENOENT, open("non-existent", O_RDONLY) == -1);
+}
+
+ATF_TEST_CASE(known_bug);
+ATF_TEST_CASE_HEAD(known_bug)
+{
+ set("descr", "Reproduces a known bug");
+}
+ATF_TEST_CASE_BODY(known_bug)
+{
+ expect_fail("See bug number foo/bar");
+ ATF_CHECK_EQUAL(3, 1 + 1);
+ expect_pass();
+ ATF_CHECK_EQUAL(3, 1 + 2);
+}
+
ATF_INIT_TEST_CASES(tcs)
{
ATF_ADD_TEST_CASE(tcs, addition);
+ ATF_ADD_TEST_CASE(tcs, open_failure);
+ ATF_ADD_TEST_CASE(tcs, known_bug);
}
.Ed
.Sh SEE ALSO
.Xr atf-test-program 1 ,
-.Xr atf 7 ,
-.Xr atf-test-case 8
+.Xr atf-test-case 4 ,
+.Xr atf 7
diff --git a/external/bsd/atf/dist/atf-c++/atf_c++_test.cpp b/external/bsd/atf/dist/atf-c++/atf_c++_test.cpp
new file mode 100644
index 00000000000..03b759e4930
--- /dev/null
+++ b/external/bsd/atf/dist/atf-c++/atf_c++_test.cpp
@@ -0,0 +1,48 @@
+//
+// Automated Testing Framework (atf)
+//
+// Copyright (c) 2009 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"
+
+#include "test_helpers.hpp"
+
+// ------------------------------------------------------------------------
+// Tests cases for the header file.
+// ------------------------------------------------------------------------
+
+HEADER_TC(include, "atf-c++.hpp");
+
+// ------------------------------------------------------------------------
+// Main.
+// ------------------------------------------------------------------------
+
+ATF_INIT_TEST_CASES(tcs)
+{
+ // Add the test cases for the header file.
+ ATF_ADD_TEST_CASE(tcs, include);
+}
diff --git a/external/bsd/atf/dist/atf-c++/build_test.cpp b/external/bsd/atf/dist/atf-c++/build_test.cpp
new file mode 100644
index 00000000000..f093cb92ea4
--- /dev/null
+++ b/external/bsd/atf/dist/atf-c++/build_test.cpp
@@ -0,0 +1,247 @@
+//
+// Automated Testing Framework (atf)
+//
+// Copyright (c) 2009 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 <cstring>
+#include <iostream>
+
+#include "atf-c++/build.hpp"
+#include "atf-c++/config.hpp"
+#include "atf-c++/env.hpp"
+#include "atf-c++/macros.hpp"
+#include "atf-c++/process.hpp"
+
+#include "../atf-c/h_build.h"
+
+#include "test_helpers.hpp"
+
+// ------------------------------------------------------------------------
+// Auxiliary functions.
+// ------------------------------------------------------------------------
+
+namespace atf {
+ namespace config {
+ void __reinit(void);
+ }
+}
+
+template< class C >
+void
+print_col(const char* prefix, const C& c)
+{
+ std::cout << prefix << ":";
+ for (typename C::const_iterator iter = c.begin(); iter != c.end();
+ iter++)
+ std::cout << " '" << *iter << "'";
+ std::cout << "\n";
+}
+
+static
+void
+print_array(const char* prefix, const char* const* a)
+{
+ std::cout << prefix << ":";
+ for (; *a != NULL; a++)
+ std::cout << " '" << *a << "'";
+ std::cout << "\n";
+}
+
+static
+void
+verbose_set_env(const char *var, const char *val)
+{
+ std::cout << "Setting " << var << " to '" << val << "'\n";
+ atf::env::set(var, val);
+}
+
+static
+bool
+equal_argvs(const atf::process::argv_array& aa, const char* const* array)
+{
+ bool equal = true;
+
+ atf::process::argv_array::size_type i = 0;
+ while (equal && (i < aa.size() && array[i] != NULL)) {
+ if (std::strcmp(aa[i], array[i]) != 0)
+ equal = false;
+ else
+ i++;
+ }
+
+ if (equal && (i < aa.size() || array[i] != NULL))
+ equal = false;
+
+ return equal;
+}
+
+static
+void
+check_equal_argvs(const atf::process::argv_array& aa, const char* const* array)
+{
+ print_array("Expected arguments", array);
+ print_col("Arguments returned", aa);
+
+ if (!equal_argvs(aa, array))
+ ATF_FAIL("The constructed argv differs from the expected values");
+}
+
+// ------------------------------------------------------------------------
+// Internal test cases.
+// ------------------------------------------------------------------------
+
+ATF_TEST_CASE(equal_argvs);
+ATF_TEST_CASE_HEAD(equal_argvs)
+{
+ set_md_var("descr", "Tests the test case internal equal_argvs function");
+}
+ATF_TEST_CASE_BODY(equal_argvs)
+{
+ {
+ const char* const array[] = { NULL };
+ const char* const argv[] = { NULL };
+
+ ATF_CHECK(equal_argvs(atf::process::argv_array(argv), array));
+ }
+
+ {
+ const char* const array[] = { NULL };
+ const char* const argv[] = { "foo", NULL };
+
+ ATF_CHECK(!equal_argvs(atf::process::argv_array(argv), array));
+ }
+
+ {
+ const char* const array[] = { "foo", NULL };
+ const char* const argv[] = { NULL };
+
+ ATF_CHECK(!equal_argvs(atf::process::argv_array(argv), array));
+ }
+
+ {
+ const char* const array[] = { "foo", NULL };
+ const char* const argv[] = { "foo", NULL };
+
+ ATF_CHECK(equal_argvs(atf::process::argv_array(argv), array));
+ }
+}
+
+// ------------------------------------------------------------------------
+// Test cases for the free functions.
+// ------------------------------------------------------------------------
+
+ATF_TEST_CASE(c_o);
+ATF_TEST_CASE_HEAD(c_o)
+{
+ set_md_var("descr", "Tests the c_o function");
+}
+ATF_TEST_CASE_BODY(c_o)
+{
+ for (struct c_o_test* test = c_o_tests; test->expargv[0] != NULL;
+ test++) {
+ std::cout << "> Test: " << test->msg << "\n";
+
+ verbose_set_env("ATF_BUILD_CC", test->cc);
+ verbose_set_env("ATF_BUILD_CFLAGS", test->cflags);
+ verbose_set_env("ATF_BUILD_CPPFLAGS", test->cppflags);
+ atf::config::__reinit();
+
+ atf::process::argv_array argv =
+ atf::build::c_o(test->sfile, test->ofile,
+ atf::process::argv_array(test->optargs));
+ check_equal_argvs(argv, test->expargv);
+ }
+}
+
+ATF_TEST_CASE(cpp);
+ATF_TEST_CASE_HEAD(cpp)
+{
+ set_md_var("descr", "Tests the cpp function");
+}
+ATF_TEST_CASE_BODY(cpp)
+{
+ for (struct cpp_test* test = cpp_tests; test->expargv[0] != NULL;
+ test++) {
+ std::cout << "> Test: " << test->msg << "\n";
+
+ verbose_set_env("ATF_BUILD_CPP", test->cpp);
+ verbose_set_env("ATF_BUILD_CPPFLAGS", test->cppflags);
+ atf::config::__reinit();
+
+ atf::process::argv_array argv =
+ atf::build::cpp(test->sfile, test->ofile,
+ atf::process::argv_array(test->optargs));
+ check_equal_argvs(argv, test->expargv);
+ }
+}
+
+ATF_TEST_CASE(cxx_o);
+ATF_TEST_CASE_HEAD(cxx_o)
+{
+ set_md_var("descr", "Tests the cxx_o function");
+}
+ATF_TEST_CASE_BODY(cxx_o)
+{
+ for (struct cxx_o_test* test = cxx_o_tests; test->expargv[0] != NULL;
+ test++) {
+ std::cout << "> Test: " << test->msg << "\n";
+
+ verbose_set_env("ATF_BUILD_CXX", test->cxx);
+ verbose_set_env("ATF_BUILD_CXXFLAGS", test->cxxflags);
+ verbose_set_env("ATF_BUILD_CPPFLAGS", test->cppflags);
+ atf::config::__reinit();
+
+ atf::process::argv_array argv =
+ atf::build::cxx_o(test->sfile, test->ofile,
+ atf::process::argv_array(test->optargs));
+ check_equal_argvs(argv, test->expargv);
+ }
+}
+
+// ------------------------------------------------------------------------
+// Tests cases for the header file.
+// ------------------------------------------------------------------------
+
+HEADER_TC(include, "atf-c++/build.hpp");
+
+// ------------------------------------------------------------------------
+// Main.
+// ------------------------------------------------------------------------
+
+ATF_INIT_TEST_CASES(tcs)
+{
+ // Add the internal test cases.
+ ATF_ADD_TEST_CASE(tcs, equal_argvs);
+
+ // Add the test cases for the free functions.
+ ATF_ADD_TEST_CASE(tcs, c_o);
+ ATF_ADD_TEST_CASE(tcs, cpp);
+ ATF_ADD_TEST_CASE(tcs, cxx_o);
+
+ // Add the test cases for the header file.
+ ATF_ADD_TEST_CASE(tcs, include);
+}
diff --git a/external/bsd/atf/dist/atf-c++/check.cpp b/external/bsd/atf/dist/atf-c++/check.cpp
index c1004efccba..16202215ee6 100644
--- a/external/bsd/atf/dist/atf-c++/check.cpp
+++ b/external/bsd/atf/dist/atf-c++/check.cpp
@@ -82,6 +82,21 @@ impl::check_result::exitcode(void)
return atf_check_result_exitcode(&m_result);
}
+bool
+impl::check_result::signaled(void)
+ const
+{
+ return atf_check_result_signaled(&m_result);
+}
+
+int
+impl::check_result::termsig(void)
+ const
+{
+ PRE(signaled());
+ return atf_check_result_termsig(&m_result);
+}
+
const atf::fs::path
impl::check_result::stdout_path(void)
const
diff --git a/external/bsd/atf/dist/atf-c++/check.hpp b/external/bsd/atf/dist/atf-c++/check.hpp
index c1804c5e4a7..276057d3410 100644
--- a/external/bsd/atf/dist/atf-c++/check.hpp
+++ b/external/bsd/atf/dist/atf-c++/check.hpp
@@ -105,6 +105,16 @@ public:
int exitcode(void) const;
//!
+ //! \brief Returns whether the command received a signal or not.
+ //!
+ bool signaled(void) const;
+
+ //!
+ //! \brief Returns the signal that terminated the command.
+ //!
+ int termsig(void) const;
+
+ //!
//! \brief Returns the path to file contaning command's stdout.
//!
const atf::fs::path stdout_path(void) const;
diff --git a/external/bsd/atf/dist/atf-c++/check_test.cpp b/external/bsd/atf/dist/atf-c++/check_test.cpp
new file mode 100644
index 00000000000..9a7e2ddfb71
--- /dev/null
+++ b/external/bsd/atf/dist/atf-c++/check_test.cpp
@@ -0,0 +1,419 @@
+//
+// Automated Testing Framework (atf)
+//
+// Copyright (c) 2007, 2008, 2009, 2010 The NetBSD Foundation, Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
+// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+extern "C" {
+#include <fcntl.h>
+#include <signal.h>
+#include <unistd.h>
+}
+
+#include <cstdlib>
+#include <cstring>
+#include <fstream>
+#include <iostream>
+#include <list>
+#include <memory>
+#include <vector>
+
+#include <atf-c++.hpp>
+
+#include "atf-c++/check.hpp"
+#include "atf-c++/config.hpp"
+#include "atf-c++/fs.hpp"
+#include "atf-c++/process.hpp"
+#include "atf-c++/text.hpp"
+#include "atf-c++/utils.hpp"
+
+#include "test_helpers.hpp"
+
+// ------------------------------------------------------------------------
+// Auxiliary functions.
+// ------------------------------------------------------------------------
+
+static
+atf::check::check_result
+do_exec(const atf::tests::tc* tc, const char* helper_name)
+{
+ std::vector< std::string > argv;
+ argv.push_back(tc->get_config_var("srcdir") + "/../atf-c/h_check");
+ argv.push_back(helper_name);
+ std::cout << "Executing " << argv[0] << " " << argv[1] << "\n";
+
+ atf::process::argv_array argva(argv);
+ return atf::check::exec(argva);
+}
+
+static
+atf::check::check_result
+do_exec(const atf::tests::tc* tc, const char* helper_name, const char *carg2)
+{
+ std::vector< std::string > argv;
+ argv.push_back(tc->get_config_var("srcdir") + "/../atf-c/h_check");
+ argv.push_back(helper_name);
+ argv.push_back(carg2);
+ std::cout << "Executing " << argv[0] << " " << argv[1] << " "
+ << argv[2] << "\n";
+
+ atf::process::argv_array argva(argv);
+ return atf::check::exec(argva);
+}
+
+// ------------------------------------------------------------------------
+// Helper test cases for the free functions.
+// ------------------------------------------------------------------------
+
+ATF_TEST_CASE(h_build_c_o_ok);
+ATF_TEST_CASE_HEAD(h_build_c_o_ok)
+{
+ set_md_var("descr", "Helper test case for build_c_o");
+}
+ATF_TEST_CASE_BODY(h_build_c_o_ok)
+{
+ std::ofstream sfile("test.c");
+ sfile << "#include <stdio.h>\n";
+ sfile.close();
+
+ ATF_CHECK(atf::check::build_c_o(atf::fs::path("test.c"),
+ atf::fs::path("test.o"),
+ atf::process::argv_array()));
+}
+
+ATF_TEST_CASE(h_build_c_o_fail);
+ATF_TEST_CASE_HEAD(h_build_c_o_fail)
+{
+ set_md_var("descr", "Helper test case for build_c_o");
+}
+ATF_TEST_CASE_BODY(h_build_c_o_fail)
+{
+ std::ofstream sfile("test.c");
+ sfile << "void foo(void) { int a = UNDEFINED_SYMBOL; }\n";
+ sfile.close();
+
+ ATF_CHECK(!atf::check::build_c_o(atf::fs::path("test.c"),
+ atf::fs::path("test.o"),
+ atf::process::argv_array()));
+}
+
+ATF_TEST_CASE(h_build_cpp_ok);
+ATF_TEST_CASE_HEAD(h_build_cpp_ok)
+{
+ set_md_var("descr", "Helper test case for build_cpp");
+}
+ATF_TEST_CASE_BODY(h_build_cpp_ok)
+{
+ std::ofstream sfile("test.c");
+ sfile << "#define A foo\n";
+ sfile << "#define B bar\n";
+ sfile << "A B\n";
+ sfile.close();
+
+ ATF_CHECK(atf::check::build_cpp(atf::fs::path("test.c"),
+ atf::fs::path("test.p"),
+ atf::process::argv_array()));
+}
+
+ATF_TEST_CASE(h_build_cpp_fail);
+ATF_TEST_CASE_HEAD(h_build_cpp_fail)
+{
+ set_md_var("descr", "Helper test case for build_cpp");
+}
+ATF_TEST_CASE_BODY(h_build_cpp_fail)
+{
+ std::ofstream sfile("test.c");
+ sfile << "#include \"./non-existent.h\"\n";
+ sfile.close();
+
+ ATF_CHECK(!atf::check::build_cpp(atf::fs::path("test.c"),
+ atf::fs::path("test.p"),
+ atf::process::argv_array()));
+}
+
+ATF_TEST_CASE(h_build_cxx_o_ok);
+ATF_TEST_CASE_HEAD(h_build_cxx_o_ok)
+{
+ set_md_var("descr", "Helper test case for build_cxx_o");
+}
+ATF_TEST_CASE_BODY(h_build_cxx_o_ok)
+{
+ std::ofstream sfile("test.cpp");
+ sfile << "#include <iostream>\n";
+ sfile.close();
+
+ ATF_CHECK(atf::check::build_cxx_o(atf::fs::path("test.cpp"),
+ atf::fs::path("test.o"),
+ atf::process::argv_array()));
+}
+
+ATF_TEST_CASE(h_build_cxx_o_fail);
+ATF_TEST_CASE_HEAD(h_build_cxx_o_fail)
+{
+ set_md_var("descr", "Helper test case for build_cxx_o");
+}
+ATF_TEST_CASE_BODY(h_build_cxx_o_fail)
+{
+ std::ofstream sfile("test.cpp");
+ sfile << "void foo(void) { int a = UNDEFINED_SYMBOL; }\n";
+ sfile.close();
+
+ ATF_CHECK(!atf::check::build_cxx_o(atf::fs::path("test.cpp"),
+ atf::fs::path("test.o"),
+ atf::process::argv_array()));
+}
+
+// ------------------------------------------------------------------------
+// Test cases for the free functions.
+// ------------------------------------------------------------------------
+
+ATF_TEST_CASE(build_c_o);
+ATF_TEST_CASE_HEAD(build_c_o)
+{
+ set_md_var("descr", "Tests the build_c_o function");
+}
+ATF_TEST_CASE_BODY(build_c_o)
+{
+ run_h_tc< ATF_TEST_CASE_NAME(h_build_c_o_ok) >();
+ ATF_CHECK(grep_file("stdout", "-o test.o"));
+ ATF_CHECK(grep_file("stdout", "-c test.c"));
+
+ run_h_tc< ATF_TEST_CASE_NAME(h_build_c_o_fail) >();
+ ATF_CHECK(grep_file("stdout", "-o test.o"));
+ ATF_CHECK(grep_file("stdout", "-c test.c"));
+ ATF_CHECK(grep_file("stderr", "test.c"));
+ ATF_CHECK(grep_file("stderr", "UNDEFINED_SYMBOL"));
+}
+
+ATF_TEST_CASE(build_cpp);
+ATF_TEST_CASE_HEAD(build_cpp)
+{
+ set_md_var("descr", "Tests the build_cpp function");
+}
+ATF_TEST_CASE_BODY(build_cpp)
+{
+ run_h_tc< ATF_TEST_CASE_NAME(h_build_cpp_ok) >();
+ ATF_CHECK(grep_file("stdout", "-o.*test.p"));
+ ATF_CHECK(grep_file("stdout", "test.c"));
+ ATF_CHECK(grep_file("test.p", "foo bar"));
+
+ run_h_tc< ATF_TEST_CASE_NAME(h_build_cpp_fail) >();
+ ATF_CHECK(grep_file("stdout", "-o test.p"));
+ ATF_CHECK(grep_file("stdout", "test.c"));
+ ATF_CHECK(grep_file("stderr", "test.c"));
+ ATF_CHECK(grep_file("stderr", "non-existent.h"));
+}
+
+ATF_TEST_CASE(build_cxx_o);
+ATF_TEST_CASE_HEAD(build_cxx_o)
+{
+ set_md_var("descr", "Tests the build_cxx_o function");
+}
+ATF_TEST_CASE_BODY(build_cxx_o)
+{
+ run_h_tc< ATF_TEST_CASE_NAME(h_build_cxx_o_ok) >();
+ ATF_CHECK(grep_file("stdout", "-o test.o"));
+ ATF_CHECK(grep_file("stdout", "-c test.cpp"));
+
+ run_h_tc< ATF_TEST_CASE_NAME(h_build_cxx_o_fail) >();
+ ATF_CHECK(grep_file("stdout", "-o test.o"));
+ ATF_CHECK(grep_file("stdout", "-c test.cpp"));
+ ATF_CHECK(grep_file("stderr", "test.cpp"));
+ ATF_CHECK(grep_file("stderr", "UNDEFINED_SYMBOL"));
+}
+
+ATF_TEST_CASE(exec_argv);
+ATF_TEST_CASE_HEAD(exec_argv)
+{
+ set_md_var("descr", "Tests that exec preserves the provided argv");
+}
+ATF_TEST_CASE_BODY(exec_argv)
+{
+ const atf::check::check_result r = do_exec(this, "exit-success");
+ ATF_CHECK_EQUAL(r.argv().size(), 2);
+ ATF_CHECK_EQUAL(r.argv()[0],
+ get_config_var("srcdir") + "/../atf-c/h_check");
+ ATF_CHECK_EQUAL(r.argv()[1], "exit-success");
+}
+
+ATF_TEST_CASE(exec_cleanup);
+ATF_TEST_CASE_HEAD(exec_cleanup)
+{
+ set_md_var("descr", "Tests that exec properly cleans up the temporary "
+ "files it creates");
+}
+ATF_TEST_CASE_BODY(exec_cleanup)
+{
+ std::auto_ptr< atf::fs::path > out;
+ std::auto_ptr< atf::fs::path > err;
+
+ {
+ const atf::check::check_result r = do_exec(this, "exit-success");
+ out.reset(new atf::fs::path(r.stdout_path()));
+ err.reset(new atf::fs::path(r.stderr_path()));
+ ATF_CHECK(atf::fs::exists(*out.get()));
+ ATF_CHECK(atf::fs::exists(*err.get()));
+ }
+ ATF_CHECK(!atf::fs::exists(*out.get()));
+ ATF_CHECK(!atf::fs::exists(*err.get()));
+}
+
+ATF_TEST_CASE(exec_exitstatus);
+ATF_TEST_CASE_HEAD(exec_exitstatus)
+{
+ set_md_var("descr", "Tests that exec properly captures the exit "
+ "status of the executed command");
+}
+ATF_TEST_CASE_BODY(exec_exitstatus)
+{
+ {
+ atf::check::check_result r = do_exec(this, "exit-success");
+ ATF_CHECK(r.exited());
+ ATF_CHECK(!r.signaled());
+ ATF_CHECK_EQUAL(r.exitcode(), EXIT_SUCCESS);
+ }
+
+ {
+ atf::check::check_result r = do_exec(this, "exit-failure");
+ ATF_CHECK(r.exited());
+ ATF_CHECK(!r.signaled());
+ ATF_CHECK_EQUAL(r.exitcode(), EXIT_FAILURE);
+ }
+
+ {
+ atf::check::check_result r = do_exec(this, "exit-signal");
+ ATF_CHECK(!r.exited());
+ ATF_CHECK(r.signaled());
+ ATF_CHECK_EQUAL(r.termsig(), SIGKILL);
+ }
+}
+
+static
+void
+check_lines(const atf::fs::path& path, const char* outname,
+ const char* resname)
+{
+ std::ifstream f(path.c_str());
+ ATF_CHECK(f);
+
+ std::string line;
+ std::getline(f, line);
+ ATF_CHECK_EQUAL(line, std::string("Line 1 to ") + outname + " for " +
+ resname);
+ std::getline(f, line);
+ ATF_CHECK_EQUAL(line, std::string("Line 2 to ") + outname + " for " +
+ resname);
+}
+
+ATF_TEST_CASE(exec_stdout_stderr);
+ATF_TEST_CASE_HEAD(exec_stdout_stderr)
+{
+ set_md_var("descr", "Tests that exec properly captures the stdout "
+ "and stderr streams of the child process");
+}
+ATF_TEST_CASE_BODY(exec_stdout_stderr)
+{
+ const atf::check::check_result r1 = do_exec(this, "stdout-stderr",
+ "result1");
+ ATF_CHECK(r1.exited());
+ ATF_CHECK_EQUAL(r1.exitcode(), EXIT_SUCCESS);
+
+ const atf::check::check_result r2 = do_exec(this, "stdout-stderr",
+ "result2");
+ ATF_CHECK(r2.exited());
+ ATF_CHECK_EQUAL(r2.exitcode(), EXIT_SUCCESS);
+
+ const atf::fs::path& out1 = r1.stdout_path();
+ const atf::fs::path& out2 = r2.stdout_path();
+ const atf::fs::path& err1 = r1.stderr_path();
+ const atf::fs::path& err2 = r2.stderr_path();
+
+ ATF_CHECK(out1.str().find("check.XXXXXX") == std::string::npos);
+ ATF_CHECK(out2.str().find("check.XXXXXX") == std::string::npos);
+ ATF_CHECK(err1.str().find("check.XXXXXX") == std::string::npos);
+ ATF_CHECK(err2.str().find("check.XXXXXX") == std::string::npos);
+
+ ATF_CHECK(out1.str().find("/check") != std::string::npos);
+ ATF_CHECK(out2.str().find("/check") != std::string::npos);
+ ATF_CHECK(err1.str().find("/check") != std::string::npos);
+ ATF_CHECK(err2.str().find("/check") != std::string::npos);
+
+ ATF_CHECK(out1.str().find("/stdout") != std::string::npos);
+ ATF_CHECK(out2.str().find("/stdout") != std::string::npos);
+ ATF_CHECK(err1.str().find("/stderr") != std::string::npos);
+ ATF_CHECK(err2.str().find("/stderr") != std::string::npos);
+
+ ATF_CHECK(out1 != out2);
+ ATF_CHECK(err1 != err2);
+
+ check_lines(out1, "stdout", "result1");
+ check_lines(out2, "stdout", "result2");
+ check_lines(err1, "stderr", "result1");
+ check_lines(err2, "stderr", "result2");
+}
+
+ATF_TEST_CASE(exec_unknown);
+ATF_TEST_CASE_HEAD(exec_unknown)
+{
+ set_md_var("descr", "Tests that running a non-existing binary "
+ "is handled correctly");
+}
+ATF_TEST_CASE_BODY(exec_unknown)
+{
+ std::vector< std::string > argv;
+ argv.push_back(atf::config::get("atf_workdir") + "/non-existent");
+
+ atf::process::argv_array argva(argv);
+ const atf::check::check_result r = atf::check::exec(argva);
+ ATF_CHECK(r.exited());
+ ATF_CHECK_EQUAL(r.exitcode(), 127);
+}
+
+// ------------------------------------------------------------------------
+// Tests cases for the header file.
+// ------------------------------------------------------------------------
+
+HEADER_TC(include, "atf-c++/check.hpp");
+
+// ------------------------------------------------------------------------
+// Main.
+// ------------------------------------------------------------------------
+
+ATF_INIT_TEST_CASES(tcs)
+{
+ // Add the test cases for the free functions.
+ ATF_ADD_TEST_CASE(tcs, build_c_o);
+ ATF_ADD_TEST_CASE(tcs, build_cpp);
+ ATF_ADD_TEST_CASE(tcs, build_cxx_o);
+ ATF_ADD_TEST_CASE(tcs, exec_argv);
+ ATF_ADD_TEST_CASE(tcs, exec_cleanup);
+ ATF_ADD_TEST_CASE(tcs, exec_exitstatus);
+ ATF_ADD_TEST_CASE(tcs, exec_stdout_stderr);
+ ATF_ADD_TEST_CASE(tcs, exec_unknown);
+
+ // Add the test cases for the header file.
+ ATF_ADD_TEST_CASE(tcs, include);
+}
diff --git a/external/bsd/atf/dist/atf-c++/config.cpp b/external/bsd/atf/dist/atf-c++/config.cpp
index 6385ef85a53..7a69232217f 100644
--- a/external/bsd/atf/dist/atf-c++/config.cpp
+++ b/external/bsd/atf/dist/atf-c++/config.cpp
@@ -61,7 +61,6 @@ init_variables(void)
m_variables["atf_confdir"] = atf_config_get("atf_confdir");
m_variables["atf_includedir"] = atf_config_get("atf_includedir");
m_variables["atf_libdir"] = atf_config_get("atf_libdir");
- m_variables["atf_libexecdir"] = atf_config_get("atf_libexecdir");
m_variables["atf_machine"] = atf_config_get("atf_machine");
m_variables["atf_m4"] = atf_config_get("atf_m4");
m_variables["atf_pkgdatadir"] = atf_config_get("atf_pkgdatadir");
diff --git a/external/bsd/atf/dist/atf-c++/config_test.cpp b/external/bsd/atf/dist/atf-c++/config_test.cpp
new file mode 100644
index 00000000000..18c0714d136
--- /dev/null
+++ b/external/bsd/atf/dist/atf-c++/config_test.cpp
@@ -0,0 +1,232 @@
+//
+// Automated Testing Framework (atf)
+//
+// Copyright (c) 2007, 2008, 2009 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 <cstring>
+#include <iostream>
+
+#include "atf-c++/config.hpp"
+#include "atf-c++/env.hpp"
+#include "atf-c++/exceptions.hpp"
+#include "atf-c++/macros.hpp"
+
+#include "test_helpers.hpp"
+
+static const char *test_value = "env-value";
+
+static struct varnames {
+ const char *lc;
+ const char *uc;
+ bool can_be_empty;
+} all_vars[] = {
+ { "atf_arch", "ATF_ARCH", false },
+ { "atf_build_cc", "ATF_BUILD_CC", false },
+ { "atf_build_cflags", "ATF_BUILD_CFLAGS", true },
+ { "atf_build_cpp", "ATF_BUILD_CPP", false },
+ { "atf_build_cppflags", "ATF_BUILD_CPPFLAGS", true },
+ { "atf_build_cxx", "ATF_BUILD_CXX", false },
+ { "atf_build_cxxflags", "ATF_BUILD_CXXFLAGS", true },
+ { "atf_confdir", "ATF_CONFDIR", false },
+ { "atf_includedir", "ATF_INCLUDEDIR", false },
+ { "atf_libdir", "ATF_LIBDIR", false },
+ { "atf_machine", "ATF_MACHINE", false },
+ { "atf_m4", "ATF_M4", false },
+ { "atf_pkgdatadir", "ATF_PKGDATADIR", false },
+ { "atf_shell", "ATF_SHELL", false },
+ { "atf_workdir", "ATF_WORKDIR", false },
+ { NULL, NULL, false }
+};
+
+// ------------------------------------------------------------------------
+// Auxiliary functions.
+// ------------------------------------------------------------------------
+
+namespace atf {
+ namespace config {
+ void __reinit(void);
+ }
+}
+
+static
+void
+set_env_var(const char* name, const char* val)
+{
+ try {
+ atf::env::set(name, val);
+ } catch (const atf::system_error& e) {
+ ATF_FAIL(std::string("set_env_var(") + name + ", " + val +
+ ") failed");
+ }
+}
+
+static
+void
+unset_env_var(const char* name)
+{
+ try {
+ atf::env::unset(name);
+ } catch (const atf::system_error& e) {
+ ATF_FAIL(std::string("unset_env_var(") + name + ") failed");
+ }
+}
+
+static
+size_t
+all_vars_count(void)
+{
+ size_t count = 0;
+ for (const struct varnames* v = all_vars; v->lc != NULL; v++)
+ count++;
+ return count;
+}
+
+static
+void
+unset_all(void)
+{
+ for (const struct varnames* v = all_vars; v->lc != NULL; v++)
+ unset_env_var(v->uc);
+}
+
+static
+void
+compare_one(const char* var, const char* expvalue)
+{
+ std::cout << "Checking that " << var << " is set to " << expvalue
+ << std::endl;
+
+ for (const struct varnames* v = all_vars; v->lc != NULL; v++) {
+ if (std::strcmp(v->lc, var) == 0)
+ ATF_CHECK_EQUAL(atf::config::get(v->lc), test_value);
+ else
+ ATF_CHECK(atf::config::get(v->lc) != test_value);
+ }
+}
+
+// ------------------------------------------------------------------------
+// Test cases for the free functions.
+// ------------------------------------------------------------------------
+
+ATF_TEST_CASE(get);
+ATF_TEST_CASE_HEAD(get)
+{
+ set_md_var("descr", "Tests the config::get function");
+}
+ATF_TEST_CASE_BODY(get)
+{
+ // Unset all known environment variables and make sure the built-in
+ // values do not match the bogus value we will use for testing.
+ unset_all();
+ atf::config::__reinit();
+ for (const struct varnames* v = all_vars; v->lc != NULL; v++)
+ ATF_CHECK(atf::config::get(v->lc) != test_value);
+
+ // Test the behavior of empty values.
+ for (const struct varnames* v = all_vars; v->lc != NULL; v++) {
+ unset_all();
+ if (!atf::config::get(v->lc).empty()) {
+ set_env_var(v->uc, "");
+ atf::config::__reinit();
+ if (v->can_be_empty)
+ ATF_CHECK(atf::config::get(v->lc).empty());
+ else
+ ATF_CHECK(!atf::config::get(v->lc).empty());
+ }
+ }
+
+ // Check if the ATF_ARCH variable is recognized.
+ for (const struct varnames* v = all_vars; v->lc != NULL; v++) {
+ unset_all();
+ set_env_var(v->uc, test_value);
+ atf::config::__reinit();
+ compare_one(v->lc, test_value);
+ }
+}
+
+ATF_TEST_CASE(get_all);
+ATF_TEST_CASE_HEAD(get_all)
+{
+ set_md_var("descr", "Tests the config::get_all function");
+}
+ATF_TEST_CASE_BODY(get_all)
+{
+ atf::config::__reinit();
+
+ // Check that the valid variables, and only those, are returned.
+ std::map< std::string, std::string > vars = atf::config::get_all();
+ ATF_CHECK_EQUAL(vars.size(), all_vars_count());
+ for (const struct varnames* v = all_vars; v->lc != NULL; v++)
+ ATF_CHECK(vars.find(v->lc) != vars.end());
+}
+
+ATF_TEST_CASE(has);
+ATF_TEST_CASE_HEAD(has)
+{
+ set_md_var("descr", "Tests the config::has function");
+}
+ATF_TEST_CASE_BODY(has)
+{
+ atf::config::__reinit();
+
+ // Check for all the variables that must exist.
+ for (const struct varnames* v = all_vars; v->lc != NULL; v++)
+ ATF_CHECK(atf::config::has(v->lc));
+
+ // Same as above, but using uppercase (which is incorrect).
+ for (const struct varnames* v = all_vars; v->lc != NULL; v++)
+ ATF_CHECK(!atf::config::has(v->uc));
+
+ // Check for some other variables that cannot exist.
+ ATF_CHECK(!atf::config::has("foo"));
+ ATF_CHECK(!atf::config::has("BAR"));
+ ATF_CHECK(!atf::config::has("atf_foo"));
+ ATF_CHECK(!atf::config::has("ATF_BAR"));
+ ATF_CHECK(!atf::config::has("atf_shel"));
+ ATF_CHECK(!atf::config::has("atf_shells"));
+}
+
+// ------------------------------------------------------------------------
+// Tests cases for the header file.
+// ------------------------------------------------------------------------
+
+HEADER_TC(include, "atf-c++/config.hpp");
+
+// ------------------------------------------------------------------------
+// Main.
+// ------------------------------------------------------------------------
+
+ATF_INIT_TEST_CASES(tcs)
+{
+ // Add the test cases for the free functions.
+ ATF_ADD_TEST_CASE(tcs, has);
+ ATF_ADD_TEST_CASE(tcs, get);
+ ATF_ADD_TEST_CASE(tcs, get_all);
+
+ // Add the test cases for the header file.
+ ATF_ADD_TEST_CASE(tcs, include);
+}
diff --git a/external/bsd/atf/dist/atf-c++/env_test.cpp b/external/bsd/atf/dist/atf-c++/env_test.cpp
new file mode 100644
index 00000000000..9764b11f0b9
--- /dev/null
+++ b/external/bsd/atf/dist/atf-c++/env_test.cpp
@@ -0,0 +1,101 @@
+//
+// Automated Testing Framework (atf)
+//
+// Copyright (c) 2007, 2008, 2009 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++/env.hpp"
+#include "atf-c++/macros.hpp"
+
+#include "test_helpers.hpp"
+
+// ------------------------------------------------------------------------
+// Test cases for the free functions.
+// ------------------------------------------------------------------------
+
+ATF_TEST_CASE(has_get);
+ATF_TEST_CASE_HEAD(has_get)
+{
+ set_md_var("descr", "Tests the has and get functions");
+}
+ATF_TEST_CASE_BODY(has_get)
+{
+ ATF_CHECK(atf::env::has("PATH"));
+ ATF_CHECK(!atf::env::get("PATH").empty());
+
+ ATF_CHECK(!atf::env::has("_UNDEFINED_VARIABLE_"));
+}
+
+ATF_TEST_CASE(set);
+ATF_TEST_CASE_HEAD(set)
+{
+ set_md_var("descr", "Tests the set function");
+}
+ATF_TEST_CASE_BODY(set)
+{
+ ATF_CHECK(atf::env::has("PATH"));
+ const std::string& oldval = atf::env::get("PATH");
+ atf::env::set("PATH", "foo-bar");
+ ATF_CHECK(atf::env::get("PATH") != oldval);
+ ATF_CHECK_EQUAL(atf::env::get("PATH"), "foo-bar");
+
+ ATF_CHECK(!atf::env::has("_UNDEFINED_VARIABLE_"));
+ atf::env::set("_UNDEFINED_VARIABLE_", "foo2-bar2");
+ ATF_CHECK_EQUAL(atf::env::get("_UNDEFINED_VARIABLE_"), "foo2-bar2");
+}
+
+ATF_TEST_CASE(unset);
+ATF_TEST_CASE_HEAD(unset)
+{
+ set_md_var("descr", "Tests the unset function");
+}
+ATF_TEST_CASE_BODY(unset)
+{
+ ATF_CHECK(atf::env::has("PATH"));
+ atf::env::unset("PATH");
+ ATF_CHECK(!atf::env::has("PATH"));
+}
+
+// ------------------------------------------------------------------------
+// Tests cases for the header file.
+// ------------------------------------------------------------------------
+
+HEADER_TC(include, "atf-c++/env.hpp");
+
+// ------------------------------------------------------------------------
+// Main.
+// ------------------------------------------------------------------------
+
+ATF_INIT_TEST_CASES(tcs)
+{
+ // Add the test cases for the free functions.
+ ATF_ADD_TEST_CASE(tcs, has_get);
+ ATF_ADD_TEST_CASE(tcs, set);
+ ATF_ADD_TEST_CASE(tcs, unset);
+
+ // Add the test cases for the header file.
+ ATF_ADD_TEST_CASE(tcs, include);
+}
diff --git a/external/bsd/atf/dist/atf-c++/exceptions_test.cpp b/external/bsd/atf/dist/atf-c++/exceptions_test.cpp
new file mode 100644
index 00000000000..931b5dfe1a4
--- /dev/null
+++ b/external/bsd/atf/dist/atf-c++/exceptions_test.cpp
@@ -0,0 +1,157 @@
+//
+// Automated Testing Framework (atf)
+//
+// Copyright (c) 2009 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/error.h"
+}
+
+#include <cstdio>
+
+#include "atf-c++/exceptions.hpp"
+#include "atf-c++/macros.hpp"
+#include "atf-c++/sanity.hpp"
+
+#include "test_helpers.hpp"
+
+// ------------------------------------------------------------------------
+// The "test" error.
+// ------------------------------------------------------------------------
+
+extern "C" {
+
+struct test_error_data {
+ const char* m_msg;
+};
+typedef struct test_error_data test_error_data_t;
+
+static
+void
+test_format(const atf_error_t err, char *buf, size_t buflen)
+{
+ const test_error_data_t* data;
+
+ PRE(atf_error_is(err, "test"));
+
+ data = static_cast< const test_error_data_t * >(atf_error_data(err));
+ snprintf(buf, buflen, "Message: %s", data->m_msg);
+}
+
+static
+atf_error_t
+test_error(const char* msg)
+{
+ atf_error_t err;
+ test_error_data_t data;
+
+ data.m_msg = msg;
+
+ err = atf_error_new("test", &data, sizeof(data), test_format);
+
+ return err;
+}
+
+} // extern
+
+// ------------------------------------------------------------------------
+// Tests cases for the free functions.
+// ------------------------------------------------------------------------
+
+ATF_TEST_CASE(throw_atf_error_libc);
+ATF_TEST_CASE_HEAD(throw_atf_error_libc)
+{
+ set_md_var("descr", "Tests the throw_atf_error function when raising "
+ "a libc error");
+}
+ATF_TEST_CASE_BODY(throw_atf_error_libc)
+{
+ try {
+ atf::throw_atf_error(atf_libc_error(1, "System error 1"));
+ } catch (const atf::system_error& e) {
+ ATF_CHECK(e.code() == 1);
+ ATF_CHECK(std::string(e.what()).find("System error 1") !=
+ std::string::npos);
+ } catch (const std::exception& e) {
+ ATF_FAIL(std::string("Got unexpected exception: ") + e.what());
+ }
+}
+
+ATF_TEST_CASE(throw_atf_error_no_memory);
+ATF_TEST_CASE_HEAD(throw_atf_error_no_memory)
+{
+ set_md_var("descr", "Tests the throw_atf_error function when raising "
+ "a no_memory error");
+}
+ATF_TEST_CASE_BODY(throw_atf_error_no_memory)
+{
+ try {
+ atf::throw_atf_error(atf_no_memory_error());
+ } catch (const std::bad_alloc& e) {
+ } catch (const std::exception& e) {
+ ATF_FAIL(std::string("Got unexpected exception: ") + e.what());
+ }
+}
+
+ATF_TEST_CASE(throw_atf_error_unknown);
+ATF_TEST_CASE_HEAD(throw_atf_error_unknown)
+{
+ set_md_var("descr", "Tests the throw_atf_error function when raising "
+ "an unknown error");
+}
+ATF_TEST_CASE_BODY(throw_atf_error_unknown)
+{
+ try {
+ atf::throw_atf_error(test_error("The message"));
+ } catch (const std::runtime_error& e) {
+ const std::string msg = e.what();
+ ATF_CHECK(msg.find("The message") != std::string::npos);
+ } catch (const std::exception& e) {
+ ATF_FAIL(std::string("Got unexpected exception: ") + e.what());
+ }
+}
+
+// ------------------------------------------------------------------------
+// Tests cases for the header file.
+// ------------------------------------------------------------------------
+
+HEADER_TC(include, "atf-c++/exceptions.hpp");
+
+// ------------------------------------------------------------------------
+// Main.
+// ------------------------------------------------------------------------
+
+ATF_INIT_TEST_CASES(tcs)
+{
+ // Add the test cases for the free functions.
+ ATF_ADD_TEST_CASE(tcs, throw_atf_error_libc);
+ ATF_ADD_TEST_CASE(tcs, throw_atf_error_no_memory);
+ ATF_ADD_TEST_CASE(tcs, throw_atf_error_unknown);
+
+ // Add the test cases for the header file.
+ ATF_ADD_TEST_CASE(tcs, include);
+}
diff --git a/external/bsd/atf/dist/atf-c++/expand_test.cpp b/external/bsd/atf/dist/atf-c++/expand_test.cpp
new file mode 100644
index 00000000000..60412585e51
--- /dev/null
+++ b/external/bsd/atf/dist/atf-c++/expand_test.cpp
@@ -0,0 +1,282 @@
+//
+// Automated Testing Framework (atf)
+//
+// Copyright (c) 2007, 2008, 2009 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 <cstring>
+
+#include "atf-c++/expand.hpp"
+#include "atf-c++/macros.hpp"
+
+#include "test_helpers.hpp"
+
+// XXX Many of the tests here are duplicated in atf-c/t_expand. Should
+// find a way to easily share them, or maybe remove the ones here.
+
+// ------------------------------------------------------------------------
+// Test cases for the free functions.
+// ------------------------------------------------------------------------
+
+ATF_TEST_CASE(is_glob);
+ATF_TEST_CASE_HEAD(is_glob)
+{
+ set_md_var("descr", "Tests the is_glob function.");
+}
+ATF_TEST_CASE_BODY(is_glob)
+{
+ using atf::expand::is_glob;
+
+ ATF_CHECK(!is_glob(""));
+ ATF_CHECK(!is_glob("a"));
+ ATF_CHECK(!is_glob("foo"));
+
+ ATF_CHECK( is_glob("*"));
+ ATF_CHECK( is_glob("a*"));
+ ATF_CHECK( is_glob("*a"));
+ ATF_CHECK( is_glob("a*b"));
+
+ ATF_CHECK( is_glob("?"));
+ ATF_CHECK( is_glob("a?"));
+ ATF_CHECK( is_glob("?a"));
+ ATF_CHECK( is_glob("a?b"));
+}
+
+ATF_TEST_CASE(matches_glob_plain);
+ATF_TEST_CASE_HEAD(matches_glob_plain)
+{
+ set_md_var("descr", "Tests the matches_glob function by using plain "
+ "text strings as patterns only.");
+}
+ATF_TEST_CASE_BODY(matches_glob_plain)
+{
+ using atf::expand::matches_glob;
+
+ ATF_CHECK( matches_glob("", ""));
+ ATF_CHECK(!matches_glob("a", ""));
+ ATF_CHECK(!matches_glob("", "a"));
+
+ ATF_CHECK( matches_glob("ab", "ab"));
+ ATF_CHECK(!matches_glob("abc", "ab"));
+ ATF_CHECK(!matches_glob("ab", "abc"));
+}
+
+ATF_TEST_CASE(matches_glob_star);
+ATF_TEST_CASE_HEAD(matches_glob_star)
+{
+ set_md_var("descr", "Tests the matches_glob function by using the '*' "
+ "meta-character as part of the pattern.");
+}
+ATF_TEST_CASE_BODY(matches_glob_star)
+{
+ using atf::expand::matches_glob;
+
+ ATF_CHECK( matches_glob("*", ""));
+ ATF_CHECK( matches_glob("*", "a"));
+ ATF_CHECK( matches_glob("*", "ab"));
+
+ ATF_CHECK(!matches_glob("a*", ""));
+ ATF_CHECK( matches_glob("a*", "a"));
+ ATF_CHECK( matches_glob("a*", "aa"));
+ ATF_CHECK( matches_glob("a*", "ab"));
+ ATF_CHECK( matches_glob("a*", "abc"));
+ ATF_CHECK(!matches_glob("a*", "ba"));
+
+ ATF_CHECK( matches_glob("*a", "a"));
+ ATF_CHECK( matches_glob("*a", "ba"));
+ ATF_CHECK(!matches_glob("*a", "bc"));
+ ATF_CHECK(!matches_glob("*a", "bac"));
+
+ ATF_CHECK( matches_glob("*ab", "ab"));
+ ATF_CHECK( matches_glob("*ab", "aab"));
+ ATF_CHECK( matches_glob("*ab", "aaab"));
+ ATF_CHECK( matches_glob("*ab", "bab"));
+ ATF_CHECK(!matches_glob("*ab", "bcb"));
+ ATF_CHECK(!matches_glob("*ab", "bacb"));
+
+ ATF_CHECK( matches_glob("a*b", "ab"));
+ ATF_CHECK( matches_glob("a*b", "acb"));
+ ATF_CHECK( matches_glob("a*b", "acdeb"));
+ ATF_CHECK(!matches_glob("a*b", "acdebz"));
+ ATF_CHECK(!matches_glob("a*b", "zacdeb"));
+}
+
+ATF_TEST_CASE(matches_glob_question);
+ATF_TEST_CASE_HEAD(matches_glob_question)
+{
+ set_md_var("descr", "Tests the matches_glob function by using the '?' "
+ "meta-character as part of the pattern.");
+}
+ATF_TEST_CASE_BODY(matches_glob_question)
+{
+ using atf::expand::matches_glob;
+
+ ATF_CHECK(!matches_glob("?", ""));
+ ATF_CHECK( matches_glob("?", "a"));
+ ATF_CHECK(!matches_glob("?", "ab"));
+
+ ATF_CHECK( matches_glob("?", "b"));
+ ATF_CHECK( matches_glob("?", "c"));
+
+ ATF_CHECK( matches_glob("a?", "ab"));
+ ATF_CHECK( matches_glob("a?", "ac"));
+ ATF_CHECK(!matches_glob("a?", "ca"));
+
+ ATF_CHECK( matches_glob("???", "abc"));
+ ATF_CHECK( matches_glob("???", "def"));
+ ATF_CHECK(!matches_glob("???", "a"));
+ ATF_CHECK(!matches_glob("???", "ab"));
+ ATF_CHECK(!matches_glob("???", "abcd"));
+}
+
+ATF_TEST_CASE(expand_glob_base);
+ATF_TEST_CASE_HEAD(expand_glob_base)
+{
+ set_md_var("descr", "Tests the expand_glob function with random "
+ "patterns.");
+}
+ATF_TEST_CASE_BODY(expand_glob_base)
+{
+ using atf::expand::expand_glob;
+
+ std::vector< std::string > candidates;
+ candidates.push_back("foo");
+ candidates.push_back("bar");
+ candidates.push_back("baz");
+ candidates.push_back("foobar");
+ candidates.push_back("foobarbaz");
+ candidates.push_back("foobarbazfoo");
+
+ std::vector< std::string > exps;
+
+ exps = expand_glob("foo", candidates);
+ ATF_CHECK_EQUAL(exps.size(), 1);
+ ATF_CHECK(exps[0] == "foo");
+
+ exps = expand_glob("bar", candidates);
+ ATF_CHECK_EQUAL(exps.size(), 1);
+ ATF_CHECK(exps[0] == "bar");
+
+ exps = expand_glob("foo*", candidates);
+ ATF_CHECK_EQUAL(exps.size(), 4);
+ ATF_CHECK(exps[0] == "foo");
+ ATF_CHECK(exps[1] == "foobar");
+ ATF_CHECK(exps[2] == "foobarbaz");
+ ATF_CHECK(exps[3] == "foobarbazfoo");
+
+ exps = expand_glob("*foo", candidates);
+ ATF_CHECK_EQUAL(exps.size(), 2);
+ ATF_CHECK(exps[0] == "foo");
+ ATF_CHECK(exps[1] == "foobarbazfoo");
+
+ exps = expand_glob("*foo*", candidates);
+ ATF_CHECK_EQUAL(exps.size(), 4);
+ ATF_CHECK(exps[0] == "foo");
+ ATF_CHECK(exps[1] == "foobar");
+ ATF_CHECK(exps[2] == "foobarbaz");
+ ATF_CHECK(exps[3] == "foobarbazfoo");
+
+ exps = expand_glob("ba", candidates);
+ ATF_CHECK_EQUAL(exps.size(), 0);
+
+ exps = expand_glob("ba*", candidates);
+ ATF_CHECK_EQUAL(exps.size(), 2);
+ ATF_CHECK(exps[0] == "bar");
+ ATF_CHECK(exps[1] == "baz");
+
+ exps = expand_glob("*ba", candidates);
+ ATF_CHECK_EQUAL(exps.size(), 0);
+
+ exps = expand_glob("*ba*", candidates);
+ ATF_CHECK_EQUAL(exps.size(), 5);
+ ATF_CHECK(exps[0] == "bar");
+ ATF_CHECK(exps[1] == "baz");
+ ATF_CHECK(exps[2] == "foobar");
+ ATF_CHECK(exps[3] == "foobarbaz");
+ ATF_CHECK(exps[4] == "foobarbazfoo");
+}
+
+ATF_TEST_CASE(expand_glob_tps);
+ATF_TEST_CASE_HEAD(expand_glob_tps)
+{
+ set_md_var("descr", "Tests the expand_glob function with patterns that "
+ "match typical test program names. This is just a subcase "
+ "of expand_base, but it is nice to make sure that it really "
+ "works.");
+}
+ATF_TEST_CASE_BODY(expand_glob_tps)
+{
+ using atf::expand::expand_glob;
+
+ std::vector< std::string > candidates;
+ candidates.push_back("Atffile");
+ candidates.push_back("h_foo");
+ candidates.push_back("t_foo");
+ candidates.push_back("t_bar");
+ candidates.push_back("t_baz");
+ candidates.push_back("foo_helper");
+ candidates.push_back("foo_test");
+ candidates.push_back("bar_test");
+ candidates.push_back("baz_test");
+
+ std::vector< std::string > exps;
+
+ exps = expand_glob("t_*", candidates);
+ ATF_CHECK_EQUAL(exps.size(), 3);
+ ATF_CHECK(exps[0] == "t_foo");
+ ATF_CHECK(exps[1] == "t_bar");
+ ATF_CHECK(exps[2] == "t_baz");
+
+ exps = expand_glob("*_test", candidates);
+ ATF_CHECK_EQUAL(exps.size(), 3);
+ ATF_CHECK(exps[0] == "foo_test");
+ ATF_CHECK(exps[1] == "bar_test");
+ ATF_CHECK(exps[2] == "baz_test");
+}
+
+// ------------------------------------------------------------------------
+// Tests cases for the header file.
+// ------------------------------------------------------------------------
+
+HEADER_TC(include, "atf-c++/expand.hpp");
+
+// ------------------------------------------------------------------------
+// Main.
+// ------------------------------------------------------------------------
+
+ATF_INIT_TEST_CASES(tcs)
+{
+ // Add the tests for the free functions.
+ ATF_ADD_TEST_CASE(tcs, is_glob);
+ ATF_ADD_TEST_CASE(tcs, matches_glob_plain);
+ ATF_ADD_TEST_CASE(tcs, matches_glob_star);
+ ATF_ADD_TEST_CASE(tcs, matches_glob_question);
+ ATF_ADD_TEST_CASE(tcs, expand_glob_base);
+ ATF_ADD_TEST_CASE(tcs, expand_glob_tps);
+
+ // Add the test cases for the header file.
+ ATF_ADD_TEST_CASE(tcs, include);
+}
diff --git a/external/bsd/atf/dist/atf-c++/fs.cpp b/external/bsd/atf/dist/atf-c++/fs.cpp
index c07fd690ea8..9b09dc180bb 100644
--- a/external/bsd/atf/dist/atf-c++/fs.cpp
+++ b/external/bsd/atf/dist/atf-c++/fs.cpp
@@ -54,6 +54,7 @@ extern "C" {
#include "atf-c++/env.hpp"
#include "atf-c++/fs.hpp"
#include "atf-c++/io.hpp"
+#include "atf-c++/process.hpp"
#include "atf-c++/sanity.hpp"
#include "atf-c++/text.hpp"
#include "atf-c++/user.hpp"
@@ -66,6 +67,8 @@ namespace impl = atf::fs;
// Auxiliary functions.
// ------------------------------------------------------------------------
+static bool safe_access(const impl::path&, int, int);
+
//!
//! \brief A controlled version of access(2).
//!
@@ -446,34 +449,6 @@ impl::directory::names(void)
}
// ------------------------------------------------------------------------
-// The "temp_dir" class.
-// ------------------------------------------------------------------------
-
-impl::temp_dir::temp_dir(const path& p)
-{
- atf::utils::auto_array< char > buf(new char[p.str().length() + 1]);
- std::strcpy(buf.get(), p.c_str());
- if (::mkdtemp(buf.get()) == NULL)
- throw system_error(IMPL_NAME "::temp_dir::temp_dir(" +
- p.str() + ")", "mkdtemp(3) failed",
- errno);
-
- m_path.reset(new path(buf.get()));
-}
-
-impl::temp_dir::~temp_dir(void)
-{
- cleanup(*m_path);
-}
-
-const impl::path&
-impl::temp_dir::get_path(void)
- const
-{
- return *m_path;
-}
-
-// ------------------------------------------------------------------------
// The "temp_file" class.
// ------------------------------------------------------------------------
@@ -533,20 +508,6 @@ impl::temp_file::fd(void)
// Free functions.
// ------------------------------------------------------------------------
-impl::path
-impl::change_directory(const path& dir)
-{
- path olddir = get_current_dir();
-
- if (olddir != dir) {
- if (::chdir(dir.c_str()) == -1)
- throw system_error(IMPL_NAME "::chdir(" + dir.str() + ")",
- "chdir(2) failed", errno);
- }
-
- return olddir;
-}
-
bool
impl::exists(const path& p)
{
@@ -583,20 +544,6 @@ impl::have_prog_in_path(const std::string& prog)
return found;
}
-impl::path
-impl::get_current_dir(void)
-{
- atf_fs_path_t cwd;
-
- atf_error_t err = atf_fs_getcwd(&cwd);
- if (atf_is_error(err))
- throw_atf_error(err);
-
- path p(atf_fs_path_cstring(&cwd));
- atf_fs_path_fini(&cwd);
- return p;
-}
-
bool
impl::is_executable(const path& p)
{
@@ -619,40 +566,9 @@ impl::remove(const path& p)
}
void
-impl::cleanup(const path& p)
-{
- atf_error_t err;
-
- err = atf_fs_cleanup(p.c_path());
- if (atf_is_error(err))
- throw_atf_error(err);
-}
-
-void
impl::rmdir(const path& p)
{
atf_error_t err = atf_fs_rmdir(p.c_path());
if (atf_is_error(err))
throw_atf_error(err);
}
-
-// XXX: This is racy if we have other threads. We should grab the current
-// umask durent program initialization and never query it again, provided
-// that we don't modify it, of course.
-mode_t
-impl::current_umask(void)
-{
- const mode_t current = umask(0);
- (void)umask(current);
- return current;
-}
-
-bool
-impl::set_immutable(const atf::fs::path& p, bool value)
-{
- bool done;
- atf_error_t err = atf_fs_set_immutable(p.c_path(), value, &done);
- if (atf_is_error(err))
- throw_atf_error(err);
- return done;
-}
diff --git a/external/bsd/atf/dist/atf-c++/fs.hpp b/external/bsd/atf/dist/atf-c++/fs.hpp
index 6761a8bfef9..72696f11a34 100644
--- a/external/bsd/atf/dist/atf-c++/fs.hpp
+++ b/external/bsd/atf/dist/atf-c++/fs.hpp
@@ -354,49 +354,6 @@ public:
};
// ------------------------------------------------------------------------
-// The "temp_dir" class.
-// ------------------------------------------------------------------------
-
-//!
-//! \brief A RAII model for temporary directories.
-//!
-//! The temp_dir class provides a RAII model for temporary directories.
-//! During construction, a safe temporary directory is created and during
-//! destruction it is carefully removed by making use of the cleanup
-//! function.
-//!
-class temp_dir {
- //!
- //! \brief The path to this temporary directory.
- //!
- std::auto_ptr< path > m_path;
-
-public:
- //!
- //! \brief Creates a new temporary directory.
- //!
- //! Creates a new temporary directory based on the provided name
- //! template. The template must end with six X characters preceded
- //! by a dot. These characters are replaced with a unique name on
- //! the file system as described in mkdtemp(3).
- //!
- temp_dir(const path&);
-
- //!
- //! \brief Destroys the temporary directory.
- //!
- //! Destroys this temporary directory object as well as its file
- //! system representation.
- //!
- ~temp_dir(void);
-
- //!
- //! \brief Returns the path to this temporary directory.
- //!
- const path& get_path(void) const;
-};
-
-// ------------------------------------------------------------------------
// The "temp_file" class.
// ------------------------------------------------------------------------
@@ -467,16 +424,6 @@ public:
// ------------------------------------------------------------------------
//!
-//! \brief Changes the current working directory.
-//!
-//! Changes the current working directory to the given path. Returns the
-//! path to the directory just left.
-//!
-//! \throw system_error If ::chdir failed.
-//!
-path change_directory(const path&);
-
-//!
//! \brief Checks if the given path exists.
//!
bool exists(const path&);
@@ -490,16 +437,6 @@ bool exists(const path&);
bool have_prog_in_path(const std::string&);
//!
-//! \brief Returns the path to the current working directory.
-//!
-//! Calculates and returns the path to the current working directory, which
-//! is guessed using the ::getcwd function.
-//!
-//! \throw system_error If ::getcwd failed.
-//!
-path get_current_dir(void);
-
-//!
//! \brief Checks if the given path exists, is accessible and is executable.
//!
bool is_executable(const path&);
@@ -510,33 +447,10 @@ bool is_executable(const path&);
void remove(const path&);
//!
-//! \brief Recursively cleans up a directory.
-//!
-//! This function cleans up a directory hierarchy. First of all, it looks
-//! for any file system that may be mounted under the given path and, if
-//! any is found, an attempt is made to unmount it. Later on, the
-//! directory is removed alongside all of its contents.
-//!
-void cleanup(const path&);
-
-//!
//! \brief Removes an empty directory.
//!
void rmdir(const path&);
-//!
-//! \brief Gets the current umask.
-//!
-mode_t current_umask(void);
-
-//!
-//! \brief Changes the immutability of a file.
-//!
-//! Returns true if the operation was performed, or false if the operation
-//! is not supported.
-//!
-bool set_immutable(const atf::fs::path&, bool);
-
} // namespace fs
} // namespace atf
diff --git a/external/bsd/atf/dist/atf-c++/fs_test.cpp b/external/bsd/atf/dist/atf-c++/fs_test.cpp
new file mode 100644
index 00000000000..461d2775c99
--- /dev/null
+++ b/external/bsd/atf/dist/atf-c++/fs_test.cpp
@@ -0,0 +1,706 @@
+//
+// Automated Testing Framework (atf)
+//
+// Copyright (c) 2007, 2008, 2009, 2010 The NetBSD Foundation, Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
+// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+extern "C" {
+#include <sys/types.h>
+#include <sys/stat.h>
+}
+
+#include <fstream>
+#include <cerrno>
+#include <cstdio>
+
+#include "atf-c++/exceptions.hpp"
+#include "atf-c++/fs.hpp"
+#include "atf-c++/macros.hpp"
+#include "atf-c++/user.hpp"
+
+#include "test_helpers.hpp"
+
+// ------------------------------------------------------------------------
+// Auxiliary functions.
+// ------------------------------------------------------------------------
+
+static
+void
+create_files(void)
+{
+ ::mkdir("files", 0755);
+ ::mkdir("files/dir", 0755);
+
+ std::ofstream os("files/reg");
+ os.close();
+
+ // TODO: Should create all other file types (blk, chr, fifo, lnk, sock)
+ // and test for them... but the underlying file system may not support
+ // most of these. Specially as we are working on /tmp, which can be
+ // mounted with flags such as "nodev". See how to deal with this
+ // situation.
+}
+
+// ------------------------------------------------------------------------
+// Test cases for the "path" class.
+// ------------------------------------------------------------------------
+
+ATF_TEST_CASE(path_normalize);
+ATF_TEST_CASE_HEAD(path_normalize)
+{
+ set_md_var("descr", "Tests the path's normalization");
+}
+ATF_TEST_CASE_BODY(path_normalize)
+{
+ using atf::fs::path;
+
+ ATF_CHECK_EQUAL(path(".").str(), ".");
+ ATF_CHECK_EQUAL(path("..").str(), "..");
+
+ ATF_CHECK_EQUAL(path("foo").str(), "foo");
+ ATF_CHECK_EQUAL(path("foo/bar").str(), "foo/bar");
+ ATF_CHECK_EQUAL(path("foo/bar/").str(), "foo/bar");
+
+ ATF_CHECK_EQUAL(path("/foo").str(), "/foo");
+ ATF_CHECK_EQUAL(path("/foo/bar").str(), "/foo/bar");
+ ATF_CHECK_EQUAL(path("/foo/bar/").str(), "/foo/bar");
+
+ ATF_CHECK_EQUAL(path("///foo").str(), "/foo");
+ ATF_CHECK_EQUAL(path("///foo///bar").str(), "/foo/bar");
+ ATF_CHECK_EQUAL(path("///foo///bar///").str(), "/foo/bar");
+}
+
+ATF_TEST_CASE(path_is_absolute);
+ATF_TEST_CASE_HEAD(path_is_absolute)
+{
+ set_md_var("descr", "Tests the path::is_absolute function");
+}
+ATF_TEST_CASE_BODY(path_is_absolute)
+{
+ using atf::fs::path;
+
+ ATF_CHECK( path("/").is_absolute());
+ ATF_CHECK( path("////").is_absolute());
+ ATF_CHECK( path("////a").is_absolute());
+ ATF_CHECK( path("//a//").is_absolute());
+ ATF_CHECK(!path("a////").is_absolute());
+ ATF_CHECK(!path("../foo").is_absolute());
+}
+
+ATF_TEST_CASE(path_is_root);
+ATF_TEST_CASE_HEAD(path_is_root)
+{
+ set_md_var("descr", "Tests the path::is_root function");
+}
+ATF_TEST_CASE_BODY(path_is_root)
+{
+ using atf::fs::path;
+
+ ATF_CHECK( path("/").is_root());
+ ATF_CHECK( path("////").is_root());
+ ATF_CHECK(!path("////a").is_root());
+ ATF_CHECK(!path("//a//").is_root());
+ ATF_CHECK(!path("a////").is_root());
+ ATF_CHECK(!path("../foo").is_root());
+}
+
+ATF_TEST_CASE(path_branch_path);
+ATF_TEST_CASE_HEAD(path_branch_path)
+{
+ set_md_var("descr", "Tests the path::branch_path function");
+}
+ATF_TEST_CASE_BODY(path_branch_path)
+{
+ using atf::fs::path;
+
+ ATF_CHECK_EQUAL(path(".").branch_path().str(), ".");
+ ATF_CHECK_EQUAL(path("foo").branch_path().str(), ".");
+ ATF_CHECK_EQUAL(path("foo/bar").branch_path().str(), "foo");
+ ATF_CHECK_EQUAL(path("/foo").branch_path().str(), "/");
+ ATF_CHECK_EQUAL(path("/foo/bar").branch_path().str(), "/foo");
+}
+
+ATF_TEST_CASE(path_leaf_name);
+ATF_TEST_CASE_HEAD(path_leaf_name)
+{
+ set_md_var("descr", "Tests the path::leaf_name function");
+}
+ATF_TEST_CASE_BODY(path_leaf_name)
+{
+ using atf::fs::path;
+
+ ATF_CHECK_EQUAL(path(".").leaf_name(), ".");
+ ATF_CHECK_EQUAL(path("foo").leaf_name(), "foo");
+ ATF_CHECK_EQUAL(path("foo/bar").leaf_name(), "bar");
+ ATF_CHECK_EQUAL(path("/foo").leaf_name(), "foo");
+ ATF_CHECK_EQUAL(path("/foo/bar").leaf_name(), "bar");
+}
+
+ATF_TEST_CASE(path_compare_equal);
+ATF_TEST_CASE_HEAD(path_compare_equal)
+{
+ set_md_var("descr", "Tests the comparison for equality between paths");
+}
+ATF_TEST_CASE_BODY(path_compare_equal)
+{
+ using atf::fs::path;
+
+ ATF_CHECK(path("/") == path("///"));
+ ATF_CHECK(path("/a") == path("///a"));
+ ATF_CHECK(path("/a") == path("///a///"));
+
+ ATF_CHECK(path("a/b/c") == path("a//b//c"));
+ ATF_CHECK(path("a/b/c") == path("a//b//c///"));
+}
+
+ATF_TEST_CASE(path_compare_different);
+ATF_TEST_CASE_HEAD(path_compare_different)
+{
+ set_md_var("descr", "Tests the comparison for difference between paths");
+}
+ATF_TEST_CASE_BODY(path_compare_different)
+{
+ using atf::fs::path;
+
+ ATF_CHECK(path("/") != path("//a/"));
+ ATF_CHECK(path("/a") != path("a///"));
+
+ ATF_CHECK(path("a/b/c") != path("a/b"));
+ ATF_CHECK(path("a/b/c") != path("a//b"));
+ ATF_CHECK(path("a/b/c") != path("/a/b/c"));
+ ATF_CHECK(path("a/b/c") != path("/a//b//c"));
+}
+
+ATF_TEST_CASE(path_concat);
+ATF_TEST_CASE_HEAD(path_concat)
+{
+ set_md_var("descr", "Tests the concatenation of multiple paths");
+}
+ATF_TEST_CASE_BODY(path_concat)
+{
+ using atf::fs::path;
+
+ ATF_CHECK_EQUAL((path("foo") / "bar").str(), "foo/bar");
+ ATF_CHECK_EQUAL((path("foo/") / "/bar").str(), "foo/bar");
+ ATF_CHECK_EQUAL((path("foo/") / "/bar/baz").str(), "foo/bar/baz");
+ ATF_CHECK_EQUAL((path("foo/") / "///bar///baz").str(), "foo/bar/baz");
+}
+
+ATF_TEST_CASE(path_to_absolute);
+ATF_TEST_CASE_HEAD(path_to_absolute)
+{
+ set_md_var("descr", "Tests the conversion of a relative path to an "
+ "absolute one");
+ set_md_var("use.fs", "true");
+}
+ATF_TEST_CASE_BODY(path_to_absolute)
+{
+ using atf::fs::file_info;
+ using atf::fs::path;
+
+ create_files();
+
+ {
+ const path p(".");
+ path pa = p.to_absolute();
+ ATF_CHECK(pa.is_absolute());
+
+ file_info fi(p);
+ file_info fia(pa);
+ ATF_CHECK_EQUAL(fi.get_device(), fia.get_device());
+ ATF_CHECK_EQUAL(fi.get_inode(), fia.get_inode());
+ }
+
+ {
+ const path p("files/reg");
+ path pa = p.to_absolute();
+ ATF_CHECK(pa.is_absolute());
+
+ file_info fi(p);
+ file_info fia(pa);
+ ATF_CHECK_EQUAL(fi.get_device(), fia.get_device());
+ ATF_CHECK_EQUAL(fi.get_inode(), fia.get_inode());
+ }
+}
+
+ATF_TEST_CASE(path_op_less);
+ATF_TEST_CASE_HEAD(path_op_less)
+{
+ set_md_var("descr", "Tests that the path's less-than operator works");
+}
+ATF_TEST_CASE_BODY(path_op_less)
+{
+ using atf::fs::path;
+
+ create_files();
+
+ ATF_CHECK(!(path("aaa") < path("aaa")));
+
+ ATF_CHECK( path("aab") < path("abc"));
+ ATF_CHECK(!(path("abc") < path("aab")));
+}
+
+// ------------------------------------------------------------------------
+// Test cases for the "directory" class.
+// ------------------------------------------------------------------------
+
+ATF_TEST_CASE(directory_read);
+ATF_TEST_CASE_HEAD(directory_read)
+{
+ set_md_var("descr", "Tests the directory class creation, which reads "
+ "the contents of a directory");
+ set_md_var("use.fs", "true");
+}
+ATF_TEST_CASE_BODY(directory_read)
+{
+ using atf::fs::directory;
+ using atf::fs::path;
+
+ create_files();
+
+ directory d(path("files"));
+ ATF_CHECK_EQUAL(d.size(), 4);
+ ATF_CHECK(d.find(".") != d.end());
+ ATF_CHECK(d.find("..") != d.end());
+ ATF_CHECK(d.find("dir") != d.end());
+ ATF_CHECK(d.find("reg") != d.end());
+}
+
+ATF_TEST_CASE(directory_file_info);
+ATF_TEST_CASE_HEAD(directory_file_info)
+{
+ set_md_var("descr", "Tests that the file_info objects attached to the "
+ "directory are valid");
+ set_md_var("use.fs", "true");
+}
+ATF_TEST_CASE_BODY(directory_file_info)
+{
+ using atf::fs::directory;
+ using atf::fs::file_info;
+ using atf::fs::path;
+
+ create_files();
+
+ directory d(path("files"));
+
+ {
+ directory::const_iterator iter = d.find("dir");
+ ATF_CHECK(iter != d.end());
+ const file_info& fi = (*iter).second;
+ ATF_CHECK(fi.get_type() == file_info::dir_type);
+ }
+
+ {
+ directory::const_iterator iter = d.find("reg");
+ ATF_CHECK(iter != d.end());
+ const file_info& fi = (*iter).second;
+ ATF_CHECK(fi.get_type() == file_info::reg_type);
+ }
+}
+
+ATF_TEST_CASE(directory_names);
+ATF_TEST_CASE_HEAD(directory_names)
+{
+ set_md_var("descr", "Tests the directory's names method");
+ set_md_var("use.fs", "true");
+}
+ATF_TEST_CASE_BODY(directory_names)
+{
+ using atf::fs::directory;
+ using atf::fs::path;
+
+ create_files();
+
+ directory d(path("files"));
+ std::set< std::string > ns = d.names();
+ ATF_CHECK_EQUAL(ns.size(), 4);
+ ATF_CHECK(ns.find(".") != ns.end());
+ ATF_CHECK(ns.find("..") != ns.end());
+ ATF_CHECK(ns.find("dir") != ns.end());
+ ATF_CHECK(ns.find("reg") != ns.end());
+}
+
+// ------------------------------------------------------------------------
+// Test cases for the "file_info" class.
+// ------------------------------------------------------------------------
+
+ATF_TEST_CASE(file_info_stat);
+ATF_TEST_CASE_HEAD(file_info_stat)
+{
+ set_md_var("descr", "Tests the file_info creation and its basic contents");
+ set_md_var("use.fs", "true");
+}
+ATF_TEST_CASE_BODY(file_info_stat)
+{
+ using atf::fs::file_info;
+ using atf::fs::path;
+
+ create_files();
+
+ {
+ path p("files/dir");
+ file_info fi(p);
+ ATF_CHECK(fi.get_type() == file_info::dir_type);
+ }
+
+ {
+ path p("files/reg");
+ file_info fi(p);
+ ATF_CHECK(fi.get_type() == file_info::reg_type);
+ }
+}
+
+ATF_TEST_CASE(file_info_perms);
+ATF_TEST_CASE_HEAD(file_info_perms)
+{
+ set_md_var("descr", "Tests the file_info methods to get the file's "
+ "permissions");
+ set_md_var("use.fs", "true");
+}
+ATF_TEST_CASE_BODY(file_info_perms)
+{
+ using atf::fs::file_info;
+ using atf::fs::path;
+
+ path p("file");
+
+ std::ofstream os(p.c_str());
+ os.close();
+
+#define perms(ur, uw, ux, gr, gw, gx, othr, othw, othx) \
+ { \
+ file_info fi(p); \
+ ATF_CHECK(fi.is_owner_readable() == ur); \
+ ATF_CHECK(fi.is_owner_writable() == uw); \
+ ATF_CHECK(fi.is_owner_executable() == ux); \
+ ATF_CHECK(fi.is_group_readable() == gr); \
+ ATF_CHECK(fi.is_group_writable() == gw); \
+ ATF_CHECK(fi.is_group_executable() == gx); \
+ ATF_CHECK(fi.is_other_readable() == othr); \
+ ATF_CHECK(fi.is_other_writable() == othw); \
+ ATF_CHECK(fi.is_other_executable() == othx); \
+ }
+
+ ::chmod(p.c_str(), 0000);
+ perms(false, false, false, false, false, false, false, false, false);
+
+ ::chmod(p.c_str(), 0001);
+ perms(false, false, false, false, false, false, false, false, true);
+
+ ::chmod(p.c_str(), 0010);
+ perms(false, false, false, false, false, true, false, false, false);
+
+ ::chmod(p.c_str(), 0100);
+ perms(false, false, true, false, false, false, false, false, false);
+
+ ::chmod(p.c_str(), 0002);
+ perms(false, false, false, false, false, false, false, true, false);
+
+ ::chmod(p.c_str(), 0020);
+ perms(false, false, false, false, true, false, false, false, false);
+
+ ::chmod(p.c_str(), 0200);
+ perms(false, true, false, false, false, false, false, false, false);
+
+ ::chmod(p.c_str(), 0004);
+ perms(false, false, false, false, false, false, true, false, false);
+
+ ::chmod(p.c_str(), 0040);
+ perms(false, false, false, true, false, false, false, false, false);
+
+ ::chmod(p.c_str(), 0400);
+ perms(true, false, false, false, false, false, false, false, false);
+
+ ::chmod(p.c_str(), 0644);
+ perms(true, true, false, true, false, false, true, false, false);
+
+ ::chmod(p.c_str(), 0755);
+ perms(true, true, true, true, false, true, true, false, true);
+
+ ::chmod(p.c_str(), 0777);
+ perms(true, true, true, true, true, true, true, true, true);
+
+#undef perms
+}
+
+// ------------------------------------------------------------------------
+// Test cases for the "temp_file" class.
+// ------------------------------------------------------------------------
+
+ATF_TEST_CASE(temp_file_raii);
+ATF_TEST_CASE_HEAD(temp_file_raii)
+{
+ set_md_var("descr", "Tests the RAII behavior of the temp_file class");
+ set_md_var("use.fs", "true");
+}
+ATF_TEST_CASE_BODY(temp_file_raii)
+{
+ using atf::fs::exists;
+ using atf::fs::file_info;
+ using atf::fs::path;
+ using atf::fs::temp_file;
+
+ path t1("non-existent");
+ path t2("non-existent");
+
+ {
+ path tmpl("testfile.XXXXXX");
+ temp_file tf1(tmpl);
+ temp_file tf2(tmpl);
+ t1 = tf1.get_path();
+ t2 = tf2.get_path();
+ ATF_CHECK(t1.str().find("XXXXXX") == std::string::npos);
+ ATF_CHECK(t2.str().find("XXXXXX") == std::string::npos);
+ ATF_CHECK(t1 != t2);
+ ATF_CHECK(!exists(tmpl));
+ ATF_CHECK( exists(t1));
+ ATF_CHECK( exists(t2));
+
+ file_info fi1(t1);
+ ATF_CHECK( fi1.is_owner_readable());
+ ATF_CHECK( fi1.is_owner_writable());
+ ATF_CHECK(!fi1.is_owner_executable());
+ ATF_CHECK(!fi1.is_group_readable());
+ ATF_CHECK(!fi1.is_group_writable());
+ ATF_CHECK(!fi1.is_group_executable());
+ ATF_CHECK(!fi1.is_other_readable());
+ ATF_CHECK(!fi1.is_other_writable());
+ ATF_CHECK(!fi1.is_other_executable());
+
+ file_info fi2(t2);
+ ATF_CHECK( fi2.is_owner_readable());
+ ATF_CHECK( fi2.is_owner_writable());
+ ATF_CHECK(!fi2.is_owner_executable());
+ ATF_CHECK(!fi2.is_group_readable());
+ ATF_CHECK(!fi2.is_group_writable());
+ ATF_CHECK(!fi2.is_group_executable());
+ ATF_CHECK(!fi2.is_other_readable());
+ ATF_CHECK(!fi2.is_other_writable());
+ ATF_CHECK(!fi2.is_other_executable());
+ }
+
+ ATF_CHECK(t1.str() != "non-existent");
+ ATF_CHECK(!exists(t1));
+ ATF_CHECK(t2.str() != "non-existent");
+ ATF_CHECK(!exists(t2));
+}
+
+ATF_TEST_CASE(temp_file_stream);
+ATF_TEST_CASE_HEAD(temp_file_stream)
+{
+ set_md_var("descr", "Tests the stream in the temp_file class");
+ set_md_var("use.fs", "true");
+}
+ATF_TEST_CASE_BODY(temp_file_stream)
+{
+ std::string line;
+ {
+ using atf::fs::path;
+ using atf::fs::temp_file;
+
+ path tmpl("tempfile.XXXXXX");
+ temp_file tf(tmpl);
+ tf << "A string\n";
+ tf.close();
+
+ std::ifstream is(tf.get_path().c_str());
+ ATF_CHECK(is);
+
+ std::getline(is, line);
+ }
+ ATF_CHECK_EQUAL(line, "A string");
+}
+
+ATF_TEST_CASE(temp_file_fd);
+ATF_TEST_CASE_HEAD(temp_file_fd)
+{
+ set_md_var("descr", "Tests access to the fd in the temp_file class");
+ set_md_var("use.fs", "true");
+}
+ATF_TEST_CASE_BODY(temp_file_fd)
+{
+ const std::string msg = "A string\n";
+ std::string line;
+ {
+ using atf::fs::path;
+ using atf::fs::temp_file;
+
+ path tmpl("tempfile.XXXXXX");
+ temp_file tf(tmpl);
+ ATF_CHECK_EQUAL(static_cast< int >(msg.length()),
+ ::write(tf.fd(), msg.c_str(), msg.length()));
+ tf.close();
+
+ std::ifstream is(tf.get_path().c_str());
+ ATF_CHECK(is);
+
+ std::getline(is, line);
+ }
+ ATF_CHECK_EQUAL(line, "A string");
+}
+
+ATF_TEST_CASE(temp_file_delete);
+ATF_TEST_CASE_HEAD(temp_file_delete)
+{
+ set_md_var("descr", "Tests that the destructor does not complain if the "
+ "file is deleted before it gets called");
+ set_md_var("use.fs", "true");
+}
+ATF_TEST_CASE_BODY(temp_file_delete)
+{
+ atf::fs::path tmpl("tempfile.XXXXXX");
+ {
+ atf::fs::temp_file tf(tmpl);
+ tf.close();
+ atf::fs::remove(tf.get_path());
+ }
+ // We let tf go out of scope and attempt to delete the file. If we
+ // get here, we are safe.
+}
+
+// ------------------------------------------------------------------------
+// Test cases for the free functions.
+// ------------------------------------------------------------------------
+
+ATF_TEST_CASE(exists);
+ATF_TEST_CASE_HEAD(exists)
+{
+ set_md_var("descr", "Tests the exists function");
+ set_md_var("use.fs", "true");
+}
+ATF_TEST_CASE_BODY(exists)
+{
+ using atf::fs::exists;
+ using atf::fs::path;
+
+ create_files();
+
+ ATF_CHECK( exists(path("files")));
+ ATF_CHECK(!exists(path("file")));
+ ATF_CHECK(!exists(path("files2")));
+
+ ATF_CHECK( exists(path("files/.")));
+ ATF_CHECK( exists(path("files/..")));
+ ATF_CHECK( exists(path("files/dir")));
+ ATF_CHECK( exists(path("files/reg")));
+ ATF_CHECK(!exists(path("files/foo")));
+}
+
+ATF_TEST_CASE(is_executable);
+ATF_TEST_CASE_HEAD(is_executable)
+{
+ set_md_var("descr", "Tests the is_executable function");
+ set_md_var("use.fs", "true");
+}
+ATF_TEST_CASE_BODY(is_executable)
+{
+ using atf::fs::is_executable;
+ using atf::fs::path;
+
+ create_files();
+
+ ATF_CHECK( is_executable(path("files")));
+ ATF_CHECK( is_executable(path("files/.")));
+ ATF_CHECK( is_executable(path("files/..")));
+ ATF_CHECK( is_executable(path("files/dir")));
+
+ ATF_CHECK(!is_executable(path("non-existent")));
+
+ ATF_CHECK(!is_executable(path("files/reg")));
+ ATF_CHECK(::chmod("files/reg", 0755) != -1);
+ ATF_CHECK( is_executable(path("files/reg")));
+}
+
+ATF_TEST_CASE(remove);
+ATF_TEST_CASE_HEAD(remove)
+{
+ set_md_var("descr", "Tests the remove function");
+ set_md_var("use.fs", "true");
+}
+ATF_TEST_CASE_BODY(remove)
+{
+ using atf::fs::exists;
+ using atf::fs::path;
+ using atf::fs::remove;
+
+ create_files();
+
+ ATF_CHECK( exists(path("files/reg")));
+ remove(path("files/reg"));
+ ATF_CHECK(!exists(path("files/reg")));
+
+ ATF_CHECK( exists(path("files/dir")));
+ ATF_CHECK_THROW(atf::system_error, remove(path("files/dir")));
+ ATF_CHECK( exists(path("files/dir")));
+}
+
+// ------------------------------------------------------------------------
+// Tests cases for the header file.
+// ------------------------------------------------------------------------
+
+HEADER_TC(include, "atf-c++/fs.hpp");
+
+// ------------------------------------------------------------------------
+// Main.
+// ------------------------------------------------------------------------
+
+ATF_INIT_TEST_CASES(tcs)
+{
+ // Add the tests for the "path" class.
+ ATF_ADD_TEST_CASE(tcs, path_normalize);
+ ATF_ADD_TEST_CASE(tcs, path_is_absolute);
+ ATF_ADD_TEST_CASE(tcs, path_is_root);
+ ATF_ADD_TEST_CASE(tcs, path_branch_path);
+ ATF_ADD_TEST_CASE(tcs, path_leaf_name);
+ ATF_ADD_TEST_CASE(tcs, path_compare_equal);
+ ATF_ADD_TEST_CASE(tcs, path_compare_different);
+ ATF_ADD_TEST_CASE(tcs, path_concat);
+ ATF_ADD_TEST_CASE(tcs, path_to_absolute);
+ ATF_ADD_TEST_CASE(tcs, path_op_less);
+
+ // Add the tests for the "file_info" class.
+ ATF_ADD_TEST_CASE(tcs, file_info_stat);
+ ATF_ADD_TEST_CASE(tcs, file_info_perms);
+
+ // Add the tests for the "directory" class.
+ ATF_ADD_TEST_CASE(tcs, directory_read);
+ ATF_ADD_TEST_CASE(tcs, directory_names);
+ ATF_ADD_TEST_CASE(tcs, directory_file_info);
+
+ // Add the tests for the "temp_file" class.
+ ATF_ADD_TEST_CASE(tcs, temp_file_raii);
+ ATF_ADD_TEST_CASE(tcs, temp_file_stream);
+ ATF_ADD_TEST_CASE(tcs, temp_file_fd);
+ ATF_ADD_TEST_CASE(tcs, temp_file_delete);
+
+ // Add the tests for the free functions.
+ ATF_ADD_TEST_CASE(tcs, exists);
+ ATF_ADD_TEST_CASE(tcs, is_executable);
+ ATF_ADD_TEST_CASE(tcs, remove);
+
+ // Add the test cases for the header file.
+ ATF_ADD_TEST_CASE(tcs, include);
+}
diff --git a/external/bsd/atf/dist/atf-c++/io.cpp b/external/bsd/atf/dist/atf-c++/io.cpp
index e6f3e612352..2c340bd12ee 100644
--- a/external/bsd/atf/dist/atf-c++/io.cpp
+++ b/external/bsd/atf/dist/atf-c++/io.cpp
@@ -28,15 +28,16 @@
//
extern "C" {
+#include <fcntl.h>
#include <poll.h>
#include <unistd.h>
}
#include <cerrno>
+#include <cstring>
extern "C" {
#include "atf-c/error.h"
-#include "atf-c/io.h"
}
#include "atf-c++/exceptions.hpp"
@@ -422,11 +423,41 @@ impl::getline(unbuffered_istream& uis, std::string& str)
int
impl::cmp(const fs::path& p1, const fs::path& p2)
{
- int r;
+ bool equal = false;
- atf_error_t err = atf_io_cmp(&r, p1.c_path(), p2.c_path());
- if (atf_is_error(err))
- throw_atf_error(err);
+ int fd1 = ::open(p1.c_str(), O_RDONLY);
+ if (fd1 == -1)
+ throw system_error(IMPL_NAME "::cmp", "open(2) failed", errno);
+ file_handle f1(fd1);
- return r;
+ int fd2 = ::open(p2.c_str(), O_RDONLY);
+ if (fd2 == -1)
+ throw system_error(IMPL_NAME "::cmp", "open(2) failed", errno);
+ file_handle f2(fd2);
+
+ for (;;) {
+ ssize_t r1, r2;
+ char buf1[512], buf2[512];
+
+ r1 = ::read(fd1, buf1, sizeof(buf1));
+ if (r1 < 0)
+ throw system_error(IMPL_NAME "::cmp", "read(2) failed for " +
+ p1.str(), errno);
+
+ r2 = read(fd2, buf2, sizeof(buf2));
+ if (r2 < 0)
+ throw system_error(IMPL_NAME "::cmp", "read(2) failed for " +
+ p2.str(), errno);
+
+ if ((r1 == 0) && (r2 == 0)) {
+ equal = true;
+ break;
+ }
+
+ if ((r1 != r2) || (std::memcmp(buf1, buf2, r1) != 0)) {
+ break;
+ }
+ }
+
+ return equal;
}
diff --git a/external/bsd/atf/dist/atf-c++/io_test.cpp b/external/bsd/atf/dist/atf-c++/io_test.cpp
new file mode 100644
index 00000000000..9a694ca76c1
--- /dev/null
+++ b/external/bsd/atf/dist/atf-c++/io_test.cpp
@@ -0,0 +1,585 @@
+//
+// Automated Testing Framework (atf)
+//
+// Copyright (c) 2007, 2008, 2009, 2010 The NetBSD Foundation, Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
+// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+extern "C" {
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+}
+
+#include <cstddef>
+#include <cstdlib>
+#include <cstring>
+#include <fstream>
+#include <iostream>
+#include <istream>
+#include <ostream>
+
+#include "atf-c++/io.hpp"
+#include "atf-c++/macros.hpp"
+
+#include "test_helpers.hpp"
+
+// ------------------------------------------------------------------------
+// Auxiliary functions.
+// ------------------------------------------------------------------------
+
+static
+void
+systembuf_check_data(std::istream& is, std::size_t length)
+{
+ char ch = 'A', chr;
+ std::size_t cnt = 0;
+ while (is >> chr) {
+ ATF_CHECK_EQUAL(ch, chr);
+ if (ch == 'Z')
+ ch = 'A';
+ else
+ ch++;
+ cnt++;
+ }
+ ATF_CHECK_EQUAL(cnt, length);
+}
+
+static
+void
+systembuf_write_data(std::ostream& os, std::size_t length)
+{
+ char ch = 'A';
+ for (std::size_t i = 0; i < length; i++) {
+ os << ch;
+ if (ch == 'Z')
+ ch = 'A';
+ else
+ ch++;
+ }
+ os.flush();
+}
+
+static
+void
+systembuf_test_read(std::size_t length, std::size_t bufsize)
+{
+ using atf::io::systembuf;
+
+ std::ofstream f("test_read.txt");
+ systembuf_write_data(f, length);
+ f.close();
+
+ int fd = ::open("test_read.txt", O_RDONLY);
+ ATF_CHECK(fd != -1);
+ systembuf sb(fd, bufsize);
+ std::istream is(&sb);
+ systembuf_check_data(is, length);
+ ::close(fd);
+ ::unlink("test_read.txt");
+}
+
+static
+void
+systembuf_test_write(std::size_t length, std::size_t bufsize)
+{
+ using atf::io::systembuf;
+
+ int fd = ::open("test_write.txt", O_WRONLY | O_CREAT | O_TRUNC,
+ S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+ ATF_CHECK(fd != -1);
+ systembuf sb(fd, bufsize);
+ std::ostream os(&sb);
+ systembuf_write_data(os, length);
+ ::close(fd);
+
+ std::ifstream is("test_write.txt");
+ systembuf_check_data(is, length);
+ is.close();
+ ::unlink("test_write.txt");
+}
+
+// ------------------------------------------------------------------------
+// Test cases for the "file_handle" class.
+// ------------------------------------------------------------------------
+
+ATF_TEST_CASE(file_handle_ctor);
+ATF_TEST_CASE_HEAD(file_handle_ctor)
+{
+ set_md_var("descr", "Tests file_handle's constructors");
+}
+ATF_TEST_CASE_BODY(file_handle_ctor)
+{
+ using atf::io::file_handle;
+
+ file_handle fh1;
+ ATF_CHECK(!fh1.is_valid());
+
+ file_handle fh2(STDOUT_FILENO);
+ ATF_CHECK(fh2.is_valid());
+ fh2.disown();
+}
+
+ATF_TEST_CASE(file_handle_copy);
+ATF_TEST_CASE_HEAD(file_handle_copy)
+{
+ set_md_var("descr", "Tests file_handle's copy constructor");
+}
+ATF_TEST_CASE_BODY(file_handle_copy)
+{
+ using atf::io::file_handle;
+
+ file_handle fh1;
+ file_handle fh2(STDOUT_FILENO);
+
+ file_handle fh3(fh2);
+ ATF_CHECK(!fh2.is_valid());
+ ATF_CHECK(fh3.is_valid());
+
+ fh1 = fh3;
+ ATF_CHECK(!fh3.is_valid());
+ ATF_CHECK(fh1.is_valid());
+
+ fh1.disown();
+}
+
+ATF_TEST_CASE(file_handle_get);
+ATF_TEST_CASE_HEAD(file_handle_get)
+{
+ set_md_var("descr", "Tests the file_handle::get method");
+}
+ATF_TEST_CASE_BODY(file_handle_get)
+{
+ using atf::io::file_handle;
+
+ file_handle fh1(STDOUT_FILENO);
+ ATF_CHECK_EQUAL(fh1.get(), STDOUT_FILENO);
+}
+
+ATF_TEST_CASE(file_handle_posix_remap);
+ATF_TEST_CASE_HEAD(file_handle_posix_remap)
+{
+ set_md_var("descr", "Tests the file_handle::posix_remap method");
+}
+ATF_TEST_CASE_BODY(file_handle_posix_remap)
+{
+ using atf::io::file_handle;
+
+ int pfd[2];
+
+ ATF_CHECK(::pipe(pfd) != -1);
+ file_handle rend(pfd[0]);
+ file_handle wend(pfd[1]);
+
+ ATF_CHECK(rend.get() != 10);
+ ATF_CHECK(wend.get() != 10);
+ wend.posix_remap(10);
+ ATF_CHECK_EQUAL(wend.get(), 10);
+ ATF_CHECK(::write(wend.get(), "test-posix-remap", 16) != -1);
+ {
+ char buf[17];
+ ATF_CHECK_EQUAL(::read(rend.get(), buf, sizeof(buf)), 16);
+ buf[16] = '\0';
+ ATF_CHECK(std::strcmp(buf, "test-posix-remap") == 0);
+ }
+
+ // Redo previous to ensure that remapping over the same descriptor
+ // has no side-effects.
+ ATF_CHECK_EQUAL(wend.get(), 10);
+ wend.posix_remap(10);
+ ATF_CHECK_EQUAL(wend.get(), 10);
+ ATF_CHECK(::write(wend.get(), "test-posix-remap", 16) != -1);
+ {
+ char buf[17];
+ ATF_CHECK_EQUAL(::read(rend.get(), buf, sizeof(buf)), 16);
+ buf[16] = '\0';
+ ATF_CHECK(std::strcmp(buf, "test-posix-remap") == 0);
+ }
+}
+
+// ------------------------------------------------------------------------
+// Test cases for the "systembuf" class.
+// ------------------------------------------------------------------------
+
+ATF_TEST_CASE(systembuf_short_read);
+ATF_TEST_CASE_HEAD(systembuf_short_read)
+{
+ set_md_var("descr", "Tests that a short read (one that fits in the "
+ "internal buffer) works when using systembuf");
+ set_md_var("use.fs", "true");
+}
+ATF_TEST_CASE_BODY(systembuf_short_read)
+{
+ systembuf_test_read(64, 1024);
+}
+
+ATF_TEST_CASE(systembuf_long_read);
+ATF_TEST_CASE_HEAD(systembuf_long_read)
+{
+ set_md_var("descr", "Tests that a long read (one that does not fit in "
+ "the internal buffer) works when using systembuf");
+ set_md_var("use.fs", "true");
+}
+ATF_TEST_CASE_BODY(systembuf_long_read)
+{
+ systembuf_test_read(64 * 1024, 1024);
+}
+
+ATF_TEST_CASE(systembuf_short_write);
+ATF_TEST_CASE_HEAD(systembuf_short_write)
+{
+ set_md_var("descr", "Tests that a short write (one that fits in the "
+ "internal buffer) works when using systembuf");
+ set_md_var("use.fs", "true");
+}
+ATF_TEST_CASE_BODY(systembuf_short_write)
+{
+ systembuf_test_write(64, 1024);
+}
+
+ATF_TEST_CASE(systembuf_long_write);
+ATF_TEST_CASE_HEAD(systembuf_long_write)
+{
+ set_md_var("descr", "Tests that a long write (one that does not fit "
+ "in the internal buffer) works when using systembuf");
+ set_md_var("use.fs", "true");
+}
+ATF_TEST_CASE_BODY(systembuf_long_write)
+{
+ systembuf_test_write(64 * 1024, 1024);
+}
+
+// ------------------------------------------------------------------------
+// Test cases for the "pipe" class.
+// ------------------------------------------------------------------------
+
+ATF_TEST_CASE(pipe_read_and_write);
+ATF_TEST_CASE_HEAD(pipe_read_and_write)
+{
+ set_md_var("descr", "Tests reading from and writing to a pipe");
+}
+ATF_TEST_CASE_BODY(pipe_read_and_write)
+{
+ using atf::io::pipe;
+ using atf::io::systembuf;
+
+ pipe p;
+ systembuf rbuf(p.rend().get());
+ systembuf wbuf(p.wend().get());
+ std::istream rend(&rbuf);
+ std::ostream wend(&wbuf);
+
+ // XXX This assumes that the pipe's buffer is big enough to accept
+ // the data written without blocking!
+ wend << "1Test 1message" << std::endl;
+ std::string tmp;
+ rend >> tmp;
+ ATF_CHECK_EQUAL(tmp, "1Test");
+ rend >> tmp;
+ ATF_CHECK_EQUAL(tmp, "1message");
+}
+
+ATF_TEST_CASE(pipe_remap_read);
+ATF_TEST_CASE_HEAD(pipe_remap_read)
+{
+ set_md_var("descr", "Tests the pipe::remap_read method");
+}
+ATF_TEST_CASE_BODY(pipe_remap_read)
+{
+ using atf::io::pipe;
+ using atf::io::systembuf;
+
+ pipe p;
+ systembuf wbuf(p.wend().get());
+ std::ostream wend(&wbuf);
+ p.rend().posix_remap(STDIN_FILENO);
+
+ // XXX This assumes that the pipe's buffer is big enough to accept
+ // the data written without blocking!
+ wend << "2Test 2message" << std::endl;
+ std::string tmp;
+ std::cin >> tmp;
+ ATF_CHECK_EQUAL(tmp, "2Test");
+ std::cin >> tmp;
+ ATF_CHECK_EQUAL(tmp, "2message");
+}
+
+ATF_TEST_CASE(pipe_remap_write);
+ATF_TEST_CASE_HEAD(pipe_remap_write)
+{
+ set_md_var("descr", "Tests the pipe::remap_write method");
+}
+ATF_TEST_CASE_BODY(pipe_remap_write)
+{
+ using atf::io::pipe;
+ using atf::io::systembuf;
+
+ pipe p;
+ if (p.rend().get() == STDOUT_FILENO) {
+ if (p.rend().get() > p.wend().get())
+ p.rend().posix_remap(p.rend().get() + 1);
+ else
+ p.rend().posix_remap(p.wend().get() + 1);
+ }
+ systembuf rbuf(p.rend().get());
+ std::istream rend(&rbuf);
+ p.wend().posix_remap(STDOUT_FILENO);
+
+ // XXX This assumes that the pipe's buffer is big enough to accept
+ // the data written without blocking!
+ std::cout << "3Test 3message" << std::endl;
+ std::string tmp;
+ rend >> tmp;
+ ATF_CHECK_EQUAL(tmp, "3Test");
+ rend >> tmp;
+ ATF_CHECK_EQUAL(tmp, "3message");
+}
+
+// ------------------------------------------------------------------------
+// Test cases for the "pistream" class.
+// ------------------------------------------------------------------------
+
+ATF_TEST_CASE(pistream);
+ATF_TEST_CASE_HEAD(pistream)
+{
+ set_md_var("descr", "Tests the pistream class");
+}
+ATF_TEST_CASE_BODY(pistream)
+{
+ using atf::io::pipe;
+ using atf::io::pistream;
+ using atf::io::systembuf;
+
+ pipe p;
+ int fh = p.rend().get();
+ pistream rend(p.rend());
+ ATF_CHECK_EQUAL(fh, rend.handle().get());
+ systembuf wbuf(p.wend().get());
+ std::ostream wend(&wbuf);
+
+ // XXX This assumes that the pipe's buffer is big enough to accept
+ // the data written without blocking!
+ wend << "1Test 1message" << std::endl;
+ std::string tmp;
+ rend >> tmp;
+ ATF_CHECK_EQUAL(tmp, "1Test");
+ rend >> tmp;
+ ATF_CHECK_EQUAL(tmp, "1message");
+}
+
+// ------------------------------------------------------------------------
+// Test cases for the "postream" class.
+// ------------------------------------------------------------------------
+
+ATF_TEST_CASE(postream);
+ATF_TEST_CASE_HEAD(postream)
+{
+ set_md_var("descr", "Tests the postream class");
+}
+ATF_TEST_CASE_BODY(postream)
+{
+ using atf::io::pipe;
+ using atf::io::postream;
+ using atf::io::systembuf;
+
+ pipe p;
+ int fh = p.wend().get();
+ postream wend(p.wend());
+ ATF_CHECK_EQUAL(fh, wend.handle().get());
+
+ // The following block is to ensure that the read end is closed
+ // before the write one. Otherwise we get a SIGPIPE, at least
+ // under FreeBSD 6.2.
+ {
+ systembuf rbuf(p.rend().get());
+ std::istream rend(&rbuf);
+
+ // XXX This assumes that the pipe's buffer is big enough to accept
+ // the data written without blocking!
+ wend << "1Test 1message" << std::endl;
+ std::string tmp;
+ rend >> tmp;
+ ATF_CHECK_EQUAL(tmp, "1Test");
+ rend >> tmp;
+ ATF_CHECK_EQUAL(tmp, "1message");
+ }
+}
+
+// ------------------------------------------------------------------------
+// Test cases for the "std_muxer" class.
+// ------------------------------------------------------------------------
+
+class test_std_muxer : public atf::io::std_muxer {
+public:
+ std::vector< std::string > m_stdout_lines, m_stderr_lines;
+ bool m_eof;
+
+ test_std_muxer(void) :
+ m_eof(false)
+ {
+ }
+
+private:
+ void
+ got_stdout_line(const std::string& line)
+ {
+ ATF_CHECK(!m_eof);
+ m_stdout_lines.push_back(line);
+ }
+
+ void
+ got_stderr_line(const std::string& line)
+ {
+ ATF_CHECK(!m_eof);
+ m_stderr_lines.push_back(line);
+ }
+
+ void
+ got_eof(void)
+ {
+ ATF_CHECK(!m_eof);
+ m_eof = true;
+ }
+};
+
+static
+int
+create_file(const char* name, const std::vector< std::string >& lines)
+{
+ const int wrfd = ::open(name, O_CREAT | O_WRONLY | O_TRUNC,
+ S_IRUSR | S_IWUSR);
+ ATF_CHECK(wrfd != -1);
+
+ for (std::vector< std::string >::const_iterator iter = lines.begin();
+ iter != lines.end(); iter++) {
+ const std::string line = *iter + "\n";
+ ATF_CHECK(::write(wrfd, line.c_str(), line.size()) != -1);
+ }
+
+ ::close(wrfd);
+
+ const int rdfd = ::open(name, O_RDONLY);
+ ATF_CHECK(rdfd != -1);
+ return rdfd;
+}
+
+ATF_TEST_CASE(std_muxer_empty);
+ATF_TEST_CASE_HEAD(std_muxer_empty)
+{
+ set_md_var("descr", "Tests the std_muxer class");
+ set_md_var("use.fs", "true");
+}
+ATF_TEST_CASE_BODY(std_muxer_empty)
+{
+ std::vector< std::string > outlines;
+ atf::io::file_handle outfh(create_file("out.txt", outlines));
+ atf::io::unbuffered_istream outs(outfh);
+
+ std::vector< std::string > errlines;
+ atf::io::file_handle errfh(create_file("err.txt", errlines));
+ atf::io::unbuffered_istream errs(errfh);
+
+ test_std_muxer m;
+ m.read(outs, errs);
+ ATF_CHECK(m.m_eof);
+ ATF_CHECK(m.m_stdout_lines.empty());
+ ATF_CHECK(m.m_stderr_lines.empty());
+}
+
+ATF_TEST_CASE(std_muxer_lines);
+ATF_TEST_CASE_HEAD(std_muxer_lines)
+{
+ set_md_var("descr", "Tests the std_muxer class");
+ set_md_var("use.fs", "true");
+}
+ATF_TEST_CASE_BODY(std_muxer_lines)
+{
+ std::vector< std::string > outlines;
+ outlines.push_back("stdout line 1");
+ outlines.push_back("stdout line 2");
+ outlines.push_back("stdout line 3");
+ atf::io::file_handle outfh(create_file("out.txt", outlines));
+ atf::io::unbuffered_istream outs(outfh);
+
+ std::vector< std::string > errlines;
+ errlines.push_back("stderr line a");
+ errlines.push_back("stderr line b");
+ atf::io::file_handle errfh(create_file("err.txt", errlines));
+ atf::io::unbuffered_istream errs(errfh);
+
+ test_std_muxer m;
+ m.read(outs, errs);
+ ATF_CHECK(m.m_eof);
+ ATF_CHECK_EQUAL(3, m.m_stdout_lines.size());
+ ATF_CHECK_EQUAL("stdout line 1", m.m_stdout_lines[0]);
+ ATF_CHECK_EQUAL("stdout line 2", m.m_stdout_lines[1]);
+ ATF_CHECK_EQUAL("stdout line 3", m.m_stdout_lines[2]);
+ ATF_CHECK_EQUAL(2, m.m_stderr_lines.size());
+ ATF_CHECK_EQUAL("stderr line a", m.m_stderr_lines[0]);
+ ATF_CHECK_EQUAL("stderr line b", m.m_stderr_lines[1]);
+}
+
+// ------------------------------------------------------------------------
+// Tests cases for the header file.
+// ------------------------------------------------------------------------
+
+HEADER_TC(include, "atf-c++/io.hpp");
+
+// ------------------------------------------------------------------------
+// Main.
+// ------------------------------------------------------------------------
+
+ATF_INIT_TEST_CASES(tcs)
+{
+ // Add the tests for the "file_handle" class.
+ ATF_ADD_TEST_CASE(tcs, file_handle_ctor);
+ ATF_ADD_TEST_CASE(tcs, file_handle_copy);
+ ATF_ADD_TEST_CASE(tcs, file_handle_get);
+ ATF_ADD_TEST_CASE(tcs, file_handle_posix_remap);
+
+ // Add the tests for the "systembuf" class.
+ ATF_ADD_TEST_CASE(tcs, systembuf_short_read);
+ ATF_ADD_TEST_CASE(tcs, systembuf_long_read);
+ ATF_ADD_TEST_CASE(tcs, systembuf_short_write);
+ ATF_ADD_TEST_CASE(tcs, systembuf_long_write);
+
+ // Add the tests for the "pipe" class.
+ ATF_ADD_TEST_CASE(tcs, pipe_read_and_write);
+ ATF_ADD_TEST_CASE(tcs, pipe_remap_read);
+ ATF_ADD_TEST_CASE(tcs, pipe_remap_write);
+
+ // Add the tests for the "pistream" class.
+ ATF_ADD_TEST_CASE(tcs, pistream);
+
+ // Add the tests for the "postream" class.
+ ATF_ADD_TEST_CASE(tcs, postream);
+
+ // Add the tests for the "std_muxer" class.
+ ATF_ADD_TEST_CASE(tcs, std_muxer_empty);
+ ATF_ADD_TEST_CASE(tcs, std_muxer_lines);
+
+ // Add the test cases for the header file.
+ ATF_ADD_TEST_CASE(tcs, include);
+}
diff --git a/external/bsd/atf/dist/atf-c++/macros.hpp b/external/bsd/atf/dist/atf-c++/macros.hpp
index 47b3c1ab440..89ea33a8490 100644
--- a/external/bsd/atf/dist/atf-c++/macros.hpp
+++ b/external/bsd/atf/dist/atf-c++/macros.hpp
@@ -40,7 +40,7 @@
class atfu_tc_ ## name : public atf::tests::tc { \
void body(void) const; \
public: \
- atfu_tc_ ## name(void) : atf::tests::tc(#name) {} \
+ atfu_tc_ ## name(void) : atf::tests::tc(#name, false) {} \
};
#define ATF_TEST_CASE(name) \
@@ -48,7 +48,7 @@
void head(void); \
void body(void) const; \
public: \
- atfu_tc_ ## name(void) : atf::tests::tc(#name) {} \
+ atfu_tc_ ## name(void) : atf::tests::tc(#name, false) {} \
};
#define ATF_TEST_CASE_WITH_CLEANUP(name) \
@@ -57,7 +57,7 @@
void body(void) const; \
void cleanup(void) const; \
public: \
- atfu_tc_ ## name(void) : atf::tests::tc(#name) {} \
+ atfu_tc_ ## name(void) : atf::tests::tc(#name, true) {} \
};
#define ATF_TEST_CASE_NAME(name) atfu_tc_ ## name
@@ -101,7 +101,7 @@
} \
} while (false)
-#define ATF_CHECK_THROW(x, e) \
+#define ATF_CHECK_THROW(e, x) \
do { \
try { \
x; \
@@ -123,6 +123,14 @@
} \
} while (false)
+#define ATF_CHECK_ERRNO(exp_errno, bool_expr) \
+ atf::tests::tc::check_errno(__FILE__, __LINE__, exp_errno, #bool_expr, \
+ bool_expr)
+
+#define ATF_REQUIRE_ERRNO(exp_errno, bool_expr) \
+ atf::tests::tc::require_errno(__FILE__, __LINE__, exp_errno, #bool_expr, \
+ bool_expr)
+
#define ATF_INIT_TEST_CASES(tcs) \
namespace atf { \
namespace tests { \
diff --git a/external/bsd/atf/dist/atf-c++/macros_hpp_test.cpp b/external/bsd/atf/dist/atf-c++/macros_hpp_test.cpp
new file mode 100644
index 00000000000..9f7137bb914
--- /dev/null
+++ b/external/bsd/atf/dist/atf-c++/macros_hpp_test.cpp
@@ -0,0 +1,125 @@
+//
+// Automated Testing Framework (atf)
+//
+// Copyright (c) 2008, 2009, 2010 The NetBSD Foundation, Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
+// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#include <stdexcept>
+
+#include <atf-c++/macros.hpp>
+
+void
+atf_check_inside_if(void)
+{
+ // Make sure that ATF_CHECK can be used inside an if statement that
+ // does not have braces. Earlier versions of it generated an error
+ // if there was an else clause because they confused the compiler
+ // by defining an unprotected nested if.
+ if (true)
+ ATF_CHECK(true);
+ else
+ ATF_CHECK(true);
+}
+
+void
+atf_check_equal_inside_if(void)
+{
+ // Make sure that ATF_CHECK_EQUAL can be used inside an if statement
+ // that does not have braces. Earlier versions of it generated an
+ // error if there was an else clause because they confused the
+ // compiler by defining an unprotected nested if.
+ if (true)
+ ATF_CHECK_EQUAL(true, true);
+ else
+ ATF_CHECK_EQUAL(true, true);
+}
+
+void
+atf_check_throw_runtime_error(void)
+{
+ // Check that we can pass std::runtime_error to ATF_CHECK_THROW.
+ // Earlier versions generated a warning because the macro's code also
+ // attempted to capture this exception, and thus we had a duplicate
+ // catch clause.
+ ATF_CHECK_THROW(std::runtime_error, (void)0);
+}
+
+void
+atf_check_throw_inside_if(void)
+{
+ // Make sure that ATF_CHECK_THROW can be used inside an if statement
+ // that does not have braces. Earlier versions of it generated an
+ // error because a trailing ; after a catch block was not allowed.
+ if (true)
+ ATF_CHECK_THROW(std::runtime_error, (void)0);
+ else
+ ATF_CHECK_THROW(std::runtime_error, (void)1);
+}
+
+void
+atf_check_errno_semicolons(void)
+{
+ // Check that ATF_CHECK_ERRNO does not contain a semicolon that would
+ // cause an empty-statement that confuses some compilers.
+ ATF_CHECK_ERRNO(1, 1 == 1);
+ ATF_CHECK_ERRNO(2, 2 == 2);
+}
+
+void
+atf_require_errno_semicolons(void)
+{
+ // Check that ATF_REQUIRE_ERRNO does not contain a semicolon that would
+ // cause an empty-statement that confuses some compilers.
+ ATF_REQUIRE_ERRNO(1, 1 == 1);
+ ATF_REQUIRE_ERRNO(2, 2 == 2);
+}
+
+// Test case names should not be expanded during instatiation so that they
+// can have the exact same name as macros.
+#define TEST_MACRO_1 invalid + name
+#define TEST_MACRO_2 invalid + name
+#define TEST_MACRO_3 invalid + name
+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::tests::tc* the_test = new ATF_TEST_CASE_NAME(TEST_MACRO_1)();
+ delete the_test;
+}
+ATF_TEST_CASE_WITH_CLEANUP(TEST_MACRO_2);
+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::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_BODY(TEST_MACRO_3) { }
+void instatiate_3(void) {
+ atf::tests::tc* the_test = new ATF_TEST_CASE_NAME(TEST_MACRO_3)();
+ delete the_test;
+}
diff --git a/external/bsd/atf/dist/atf-c++/macros_test.cpp b/external/bsd/atf/dist/atf-c++/macros_test.cpp
new file mode 100644
index 00000000000..5c0a4f3b1d7
--- /dev/null
+++ b/external/bsd/atf/dist/atf-c++/macros_test.cpp
@@ -0,0 +1,517 @@
+//
+// Automated Testing Framework (atf)
+//
+// Copyright (c) 2008, 2009, 2010 The NetBSD Foundation, Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
+// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+extern "C" {
+#include <fcntl.h>
+#include <unistd.h>
+}
+
+#include <cerrno>
+#include <cstdlib>
+#include <iostream>
+#include <stdexcept>
+
+#include "atf-c++/fs.hpp"
+#include "atf-c++/macros.hpp"
+#include "atf-c++/process.hpp"
+#include "atf-c++/sanity.hpp"
+#include "atf-c++/text.hpp"
+
+#include "test_helpers.hpp"
+
+// ------------------------------------------------------------------------
+// Auxiliary functions.
+// ------------------------------------------------------------------------
+
+static
+void
+create_ctl_file(const atf::tests::tc& tc, const char *name)
+{
+ ATF_CHECK(open(name, O_CREAT | O_WRONLY | O_TRUNC, 0644) != -1);
+}
+
+// ------------------------------------------------------------------------
+// Auxiliary test cases.
+// ------------------------------------------------------------------------
+
+ATF_TEST_CASE(h_pass);
+ATF_TEST_CASE_HEAD(h_pass)
+{
+ set_md_var("descr", "Helper test case");
+}
+ATF_TEST_CASE_BODY(h_pass)
+{
+ create_ctl_file(*this, "before");
+ ATF_PASS();
+ create_ctl_file(*this, "after");
+}
+
+ATF_TEST_CASE(h_fail);
+ATF_TEST_CASE_HEAD(h_fail)
+{
+ set_md_var("descr", "Helper test case");
+}
+ATF_TEST_CASE_BODY(h_fail)
+{
+ create_ctl_file(*this, "before");
+ ATF_FAIL("Failed on purpose");
+ create_ctl_file(*this, "after");
+}
+
+ATF_TEST_CASE(h_skip);
+ATF_TEST_CASE_HEAD(h_skip)
+{
+ set_md_var("descr", "Helper test case");
+}
+ATF_TEST_CASE_BODY(h_skip)
+{
+ create_ctl_file(*this, "before");
+ ATF_SKIP("Skipped on purpose");
+ create_ctl_file(*this, "after");
+}
+
+ATF_TEST_CASE(h_check);
+ATF_TEST_CASE_HEAD(h_check)
+{
+ set_md_var("descr", "Helper test case");
+}
+ATF_TEST_CASE_BODY(h_check)
+{
+ bool condition = atf::text::to_bool(get_config_var("condition"));
+
+ create_ctl_file(*this, "before");
+ ATF_CHECK(condition);
+ create_ctl_file(*this, "after");
+}
+
+ATF_TEST_CASE(h_check_equal);
+ATF_TEST_CASE_HEAD(h_check_equal)
+{
+ set_md_var("descr", "Helper test case");
+}
+ATF_TEST_CASE_BODY(h_check_equal)
+{
+ 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");
+ ATF_CHECK_EQUAL(v1, v2);
+ create_ctl_file(*this, "after");
+}
+
+ATF_TEST_CASE(h_check_throw);
+ATF_TEST_CASE_HEAD(h_check_throw)
+{
+ set_md_var("descr", "Helper test case");
+}
+ATF_TEST_CASE_BODY(h_check_throw)
+{
+ create_ctl_file(*this, "before");
+
+ if (get_config_var("what") == "throw_int")
+ ATF_CHECK_THROW(std::runtime_error, if (1) throw int(5));
+ else if (get_config_var("what") == "throw_rt")
+ ATF_CHECK_THROW(std::runtime_error,
+ if (1) throw std::runtime_error("e"));
+ else if (get_config_var("what") == "no_throw_rt")
+ ATF_CHECK_THROW(std::runtime_error,
+ if (0) throw std::runtime_error("e"));
+
+ create_ctl_file(*this, "after");
+}
+
+static int
+errno_fail_stub(const int raised_errno)
+{
+ errno = raised_errno;
+ return -1;
+}
+
+static int
+errno_ok_stub(void)
+{
+ return 0;
+}
+
+ATF_TEST_CASE(h_check_errno);
+ATF_TEST_CASE_HEAD(h_check_errno)
+{
+ set_md_var("descr", "Helper test case");
+}
+ATF_TEST_CASE_BODY(h_check_errno)
+{
+ create_ctl_file(*this, "before");
+
+ if (get_config_var("what") == "no_error")
+ ATF_CHECK_ERRNO(-1, errno_ok_stub() == -1);
+ else if (get_config_var("what") == "errno_ok")
+ ATF_CHECK_ERRNO(2, errno_fail_stub(2) == -1);
+ else if (get_config_var("what") == "errno_fail")
+ ATF_CHECK_ERRNO(3, errno_fail_stub(4) == -1);
+ else
+ UNREACHABLE;
+
+ create_ctl_file(*this, "after");
+}
+
+ATF_TEST_CASE(h_require_errno);
+ATF_TEST_CASE_HEAD(h_require_errno)
+{
+ set_md_var("descr", "Helper test case");
+}
+ATF_TEST_CASE_BODY(h_require_errno)
+{
+ create_ctl_file(*this, "before");
+
+ if (get_config_var("what") == "no_error")
+ ATF_REQUIRE_ERRNO(-1, errno_ok_stub() == -1);
+ else if (get_config_var("what") == "errno_ok")
+ ATF_REQUIRE_ERRNO(2, errno_fail_stub(2) == -1);
+ else if (get_config_var("what") == "errno_fail")
+ ATF_REQUIRE_ERRNO(3, errno_fail_stub(4) == -1);
+ else
+ UNREACHABLE;
+
+ create_ctl_file(*this, "after");
+}
+
+// ------------------------------------------------------------------------
+// Test cases for the macros.
+// ------------------------------------------------------------------------
+
+ATF_TEST_CASE(pass);
+ATF_TEST_CASE_HEAD(pass)
+{
+ set_md_var("descr", "Tests the ATF_PASS macro");
+ set_md_var("use.fs", "true");
+}
+ATF_TEST_CASE_BODY(pass)
+{
+ run_h_tc< ATF_TEST_CASE_NAME(h_pass) >();
+ ATF_CHECK(grep_file("result", "^passed"));
+ ATF_CHECK(atf::fs::exists(atf::fs::path("before")));
+ ATF_CHECK(!atf::fs::exists(atf::fs::path("after")));
+}
+
+ATF_TEST_CASE(fail);
+ATF_TEST_CASE_HEAD(fail)
+{
+ set_md_var("descr", "Tests the ATF_FAIL macro");
+ set_md_var("use.fs", "true");
+}
+ATF_TEST_CASE_BODY(fail)
+{
+ run_h_tc< ATF_TEST_CASE_NAME(h_fail) >();
+ ATF_CHECK(grep_file("result", "^failed: Failed on purpose"));
+ ATF_CHECK(atf::fs::exists(atf::fs::path("before")));
+ ATF_CHECK(!atf::fs::exists(atf::fs::path("after")));
+}
+
+ATF_TEST_CASE(skip);
+ATF_TEST_CASE_HEAD(skip)
+{
+ set_md_var("descr", "Tests the ATF_SKIP macro");
+ set_md_var("use.fs", "true");
+}
+ATF_TEST_CASE_BODY(skip)
+{
+ run_h_tc< ATF_TEST_CASE_NAME(h_skip) >();
+ ATF_CHECK(grep_file("result", "^skipped: Skipped on purpose"));
+ ATF_CHECK(atf::fs::exists(atf::fs::path("before")));
+ ATF_CHECK(!atf::fs::exists(atf::fs::path("after")));
+}
+
+ATF_TEST_CASE(check);
+ATF_TEST_CASE_HEAD(check)
+{
+ set_md_var("descr", "Tests the ATF_CHECK macro");
+ set_md_var("use.fs", "true");
+}
+ATF_TEST_CASE_BODY(check)
+{
+ struct test {
+ const char *cond;
+ bool ok;
+ } *t, tests[] = {
+ { "false", false },
+ { "true", true },
+ { NULL, false }
+ };
+
+ const atf::fs::path before("before");
+ const atf::fs::path after("after");
+
+ for (t = &tests[0]; t->cond != NULL; t++) {
+ atf::tests::vars_map config;
+ config["condition"] = t->cond;
+
+ std::cout << "Checking with a " << t->cond << " value" << std::endl;
+
+ run_h_tc< ATF_TEST_CASE_NAME(h_check) >(config);
+
+ ATF_CHECK(atf::fs::exists(before));
+ if (t->ok) {
+ ATF_CHECK(grep_file("result", "^passed"));
+ ATF_CHECK(atf::fs::exists(after));
+ } else {
+ ATF_CHECK(grep_file("result", "^failed: .*condition not met"));
+ ATF_CHECK(!atf::fs::exists(after));
+ }
+
+ atf::fs::remove(before);
+ if (t->ok)
+ atf::fs::remove(after);
+ }
+}
+
+ATF_TEST_CASE(check_equal);
+ATF_TEST_CASE_HEAD(check_equal)
+{
+ set_md_var("descr", "Tests the ATF_CHECK_EQUAL macro");
+ set_md_var("use.fs", "true");
+}
+ATF_TEST_CASE_BODY(check_equal)
+{
+ struct test {
+ const char *v1;
+ const char *v2;
+ bool ok;
+ } *t, tests[] = {
+ { "1", "1", true },
+ { "1", "2", false },
+ { "2", "1", false },
+ { "2", "2", true },
+ { NULL, NULL, false }
+ };
+
+ const atf::fs::path before("before");
+ const atf::fs::path after("after");
+
+ for (t = &tests[0]; t->v1 != NULL; t++) {
+ atf::tests::vars_map config;
+ config["v1"] = t->v1;
+ config["v2"] = t->v2;
+
+ std::cout << "Checking with " << t->v1 << ", " << t->v2
+ << " and expecting " << (t->ok ? "true" : "false")
+ << std::endl;
+
+ run_h_tc< ATF_TEST_CASE_NAME(h_check_equal) >(config);
+
+ ATF_CHECK(atf::fs::exists(before));
+ if (t->ok) {
+ ATF_CHECK(grep_file("result", "^passed"));
+ ATF_CHECK(atf::fs::exists(after));
+ } else {
+ ATF_CHECK(grep_file("result", "^failed: .*v1 != v2"));
+ ATF_CHECK(!atf::fs::exists(after));
+ }
+
+ atf::fs::remove(before);
+ if (t->ok)
+ atf::fs::remove(after);
+ }
+}
+
+ATF_TEST_CASE(check_throw);
+ATF_TEST_CASE_HEAD(check_throw)
+{
+ set_md_var("descr", "Tests the ATF_CHECK_THROW macro");
+ set_md_var("use.fs", "true");
+}
+ATF_TEST_CASE_BODY(check_throw)
+{
+ struct test {
+ const char *what;
+ bool ok;
+ const char *msg;
+ } *t, tests[] = {
+ { "throw_int", false, "unexpected error" },
+ { "throw_rt", true, NULL },
+ { "no_throw_rt", false, "did not throw" },
+ { NULL, false, NULL }
+ };
+
+ const atf::fs::path before("before");
+ const atf::fs::path after("after");
+
+ for (t = &tests[0]; t->what != NULL; t++) {
+ atf::tests::vars_map config;
+ config["what"] = t->what;
+
+ std::cout << "Checking with " << t->what << " and expecting "
+ << (t->ok ? "true" : "false") << std::endl;
+
+ run_h_tc< ATF_TEST_CASE_NAME(h_check_throw) >(config);
+
+ ATF_CHECK(atf::fs::exists(before));
+ if (t->ok) {
+ ATF_CHECK(grep_file("result", "^passed"));
+ ATF_CHECK(atf::fs::exists(after));
+ } else {
+ std::cout << "Checking that message contains '" << t->msg
+ << "'" << std::endl;
+ std::string exp_result = std::string("^failed: .*") + t->msg;
+ ATF_CHECK(grep_file("result", exp_result.c_str()));
+ ATF_CHECK(!atf::fs::exists(after));
+ }
+
+ atf::fs::remove(before);
+ if (t->ok)
+ atf::fs::remove(after);
+ }
+}
+
+ATF_TEST_CASE(check_errno);
+ATF_TEST_CASE_HEAD(check_errno)
+{
+ set_md_var("descr", "Tests the ATF_CHECK_ERRNO macro");
+ set_md_var("use.fs", "true");
+}
+ATF_TEST_CASE_BODY(check_errno)
+{
+ struct test {
+ const char *what;
+ bool ok;
+ const char *msg;
+ } *t, tests[] = {
+ { "no_error", false,
+ "Expected true value in errno_ok_stub\\(\\) == -1" },
+ { "errno_ok", true, NULL },
+ { "errno_fail", false,
+ "Expected errno 3, got 4, in errno_fail_stub\\(4\\) == -1" },
+ { NULL, false, NULL }
+ };
+
+ const atf::fs::path before("before");
+ const atf::fs::path after("after");
+
+ for (t = &tests[0]; t->what != NULL; t++) {
+ atf::tests::vars_map config;
+ config["what"] = t->what;
+
+ run_h_tc< ATF_TEST_CASE_NAME(h_check_errno) >(config);
+
+ ATF_CHECK(atf::fs::exists(before));
+ ATF_CHECK(atf::fs::exists(after));
+
+ if (t->ok) {
+ ATF_CHECK(grep_file("result", "^passed"));
+ } else {
+ ATF_CHECK(grep_file("result", "^failed"));
+
+ std::string exp_result = "macros_test.cpp:[0-9]+: " +
+ std::string(t->msg) + "$";
+ ATF_CHECK(grep_file("stderr", exp_result.c_str()));
+ }
+
+ atf::fs::remove(before);
+ atf::fs::remove(after);
+ }
+}
+
+ATF_TEST_CASE(require_errno);
+ATF_TEST_CASE_HEAD(require_errno)
+{
+ set_md_var("descr", "Tests the ATF_REQUIRE_ERRNO macro");
+ set_md_var("use.fs", "true");
+}
+ATF_TEST_CASE_BODY(require_errno)
+{
+ struct test {
+ const char *what;
+ bool ok;
+ const char *msg;
+ } *t, tests[] = {
+ { "no_error", false,
+ "Expected true value in errno_ok_stub\\(\\) == -1" },
+ { "errno_ok", true, NULL },
+ { "errno_fail", false,
+ "Expected errno 3, got 4, in errno_fail_stub\\(4\\) == -1" },
+ { NULL, false, NULL }
+ };
+
+ const atf::fs::path before("before");
+ const atf::fs::path after("after");
+
+ for (t = &tests[0]; t->what != NULL; t++) {
+ atf::tests::vars_map config;
+ config["what"] = t->what;
+
+ run_h_tc< ATF_TEST_CASE_NAME(h_require_errno) >(config);
+
+ ATF_CHECK(atf::fs::exists(before));
+ if (t->ok) {
+ ATF_CHECK(grep_file("result", "^passed"));
+ ATF_CHECK(atf::fs::exists(after));
+ } else {
+ std::string exp_result = "^failed: .*macros_test.cpp:[0-9]+: " +
+ std::string(t->msg) + "$";
+ ATF_CHECK(grep_file("result", exp_result.c_str()));
+
+ ATF_CHECK(!atf::fs::exists(after));
+ }
+
+ atf::fs::remove(before);
+ if (t->ok)
+ atf::fs::remove(after);
+ }
+}
+
+// ------------------------------------------------------------------------
+// Tests cases for the header file.
+// ------------------------------------------------------------------------
+
+HEADER_TC(include, "atf-c++/macros.hpp");
+BUILD_TC(use, "macros_hpp_test.cpp",
+ "Tests that the macros provided by the atf-c++/macros.hpp file "
+ "do not cause syntax errors when used",
+ "Build of macros_hpp_test.cpp failed; some macros in "
+ "atf-c++/macros.hpp are broken");
+
+// ------------------------------------------------------------------------
+// Main.
+// ------------------------------------------------------------------------
+
+ATF_INIT_TEST_CASES(tcs)
+{
+ // Add the test cases for the macros.
+ ATF_ADD_TEST_CASE(tcs, pass);
+ ATF_ADD_TEST_CASE(tcs, fail);
+ ATF_ADD_TEST_CASE(tcs, skip);
+ ATF_ADD_TEST_CASE(tcs, check);
+ ATF_ADD_TEST_CASE(tcs, check_equal);
+ ATF_ADD_TEST_CASE(tcs, check_throw);
+ ATF_ADD_TEST_CASE(tcs, check_errno);
+ ATF_ADD_TEST_CASE(tcs, require_errno);
+
+ // Add the test cases for the header file.
+ ATF_ADD_TEST_CASE(tcs, include);
+ ATF_ADD_TEST_CASE(tcs, use);
+}
diff --git a/external/bsd/atf/dist/atf-c++/parser.cpp b/external/bsd/atf/dist/atf-c++/parser.cpp
index 85c2fe5caf3..327996b9758 100644
--- a/external/bsd/atf/dist/atf-c++/parser.cpp
+++ b/external/bsd/atf/dist/atf-c++/parser.cpp
@@ -30,6 +30,7 @@
#include <sstream>
#include "atf-c++/parser.hpp"
+#include "atf-c++/sanity.hpp"
#include "atf-c++/text.hpp"
namespace impl = atf::parser;
@@ -98,6 +99,15 @@ impl::parse_errors::what(void)
}
// ------------------------------------------------------------------------
+// The "format_error" class.
+// ------------------------------------------------------------------------
+
+impl::format_error::format_error(const std::string& w) :
+ std::runtime_error(w.c_str())
+{
+}
+
+// ------------------------------------------------------------------------
// The "token" class.
// ------------------------------------------------------------------------
@@ -149,3 +159,226 @@ impl::token::operator!(void)
{
return !m_inited;
}
+
+// ------------------------------------------------------------------------
+// The "header_entry" class.
+// ------------------------------------------------------------------------
+
+impl::header_entry::header_entry(void)
+{
+}
+
+impl::header_entry::header_entry(const std::string& n, const std::string& v,
+ attrs_map as) :
+ m_name(n),
+ m_value(v),
+ m_attrs(as)
+{
+}
+
+const std::string&
+impl::header_entry::name(void) const
+{
+ return m_name;
+}
+
+const std::string&
+impl::header_entry::value(void) const
+{
+ return m_value;
+}
+
+const impl::attrs_map&
+impl::header_entry::attrs(void) const
+{
+ return m_attrs;
+}
+
+bool
+impl::header_entry::has_attr(const std::string& n) const
+{
+ return m_attrs.find(n) != m_attrs.end();
+}
+
+const std::string&
+impl::header_entry::get_attr(const std::string& n) const
+{
+ attrs_map::const_iterator iter = m_attrs.find(n);
+ PRE(iter != m_attrs.end());
+ return (*iter).second;
+}
+
+// ------------------------------------------------------------------------
+// The header tokenizer.
+// ------------------------------------------------------------------------
+
+namespace header {
+
+static const impl::token_type& eof_type = 0;
+static const impl::token_type& nl_type = 1;
+static const impl::token_type& text_type = 2;
+static const impl::token_type& colon_type = 3;
+static const impl::token_type& semicolon_type = 4;
+static const impl::token_type& dblquote_type = 5;
+static const impl::token_type& equal_type = 6;
+
+class tokenizer : public impl::tokenizer< std::istream > {
+public:
+ tokenizer(std::istream& is, size_t curline) :
+ impl::tokenizer< std::istream >
+ (is, true, eof_type, nl_type, text_type, curline)
+ {
+ add_delim(';', semicolon_type);
+ add_delim(':', colon_type);
+ add_delim('=', equal_type);
+ add_quote('"', dblquote_type);
+ }
+};
+
+static
+impl::parser< header::tokenizer >&
+read(impl::parser< header::tokenizer >& p, impl::header_entry& he)
+{
+ using namespace header;
+
+ impl::token t = p.expect(text_type, nl_type, "a header name");
+ if (t.type() == nl_type) {
+ he = impl::header_entry();
+ return p;
+ }
+ std::string hdr_name = t.text();
+
+ t = p.expect(colon_type, "`:'");
+
+ t = p.expect(text_type, "a textual value");
+ std::string hdr_value = t.text();
+
+ impl::attrs_map attrs;
+
+ for (;;) {
+ t = p.expect(eof_type, semicolon_type, nl_type,
+ "eof, `;' or new line");
+ if (t.type() == eof_type || t.type() == nl_type)
+ break;
+
+ t = p.expect(text_type, "an attribute name");
+ std::string attr_name = t.text();
+
+ t = p.expect(equal_type, "`='");
+
+ t = p.expect(text_type, "word or quoted string");
+ std::string attr_value = t.text();
+ attrs[attr_name] = attr_value;
+ }
+
+ he = impl::header_entry(hdr_name, hdr_value, attrs);
+
+ return p;
+}
+
+static
+std::ostream&
+write(std::ostream& os, const impl::header_entry& he)
+{
+ std::string line = he.name() + ": " + he.value();
+ impl::attrs_map as = he.attrs();
+ for (impl::attrs_map::const_iterator iter = as.begin(); iter != as.end();
+ iter++) {
+ PRE((*iter).second.find('\"') == std::string::npos);
+ line += "; " + (*iter).first + "=\"" + (*iter).second + "\"";
+ }
+
+ os << line << std::endl;
+
+ return os;
+}
+
+} // namespace header
+
+// ------------------------------------------------------------------------
+// Free functions.
+// ------------------------------------------------------------------------
+
+std::pair< size_t, impl::headers_map >
+impl::read_headers(std::istream& is, size_t curline)
+{
+ using impl::format_error;
+
+ headers_map hm;
+
+ //
+ // Grammar
+ //
+ // header = entry+ nl
+ // entry = line nl
+ // line = text colon text
+ // (semicolon (text equal (text | dblquote string dblquote)))*
+ // string = quoted_string
+ //
+
+ header::tokenizer tkz(is, curline);
+ impl::parser< header::tokenizer > p(tkz);
+
+ bool first = true;
+ for (;;) {
+ try {
+ header_entry he;
+ if (!header::read(p, he).good() || he.name().empty())
+ break;
+
+ if (first && he.name() != "Content-Type")
+ throw format_error("Could not determine content type");
+ else
+ first = false;
+
+ hm[he.name()] = he;
+ } catch (const impl::parse_error& pe) {
+ p.add_error(pe);
+ p.reset(header::nl_type);
+ }
+ }
+
+ if (!is.good())
+ throw format_error("Unexpected end of stream");
+
+ return std::pair< size_t, headers_map >(tkz.lineno(), hm);
+}
+
+void
+impl::write_headers(const impl::headers_map& hm, std::ostream& os)
+{
+ PRE(!hm.empty());
+ headers_map::const_iterator ct = hm.find("Content-Type");
+ PRE(ct != hm.end());
+ header::write(os, (*ct).second);
+ for (headers_map::const_iterator iter = hm.begin(); iter != hm.end();
+ iter++) {
+ if ((*iter).first != "Content-Type")
+ header::write(os, (*iter).second);
+ }
+ os << std::endl;
+}
+
+void
+impl::validate_content_type(const impl::headers_map& hm, const std::string& fmt,
+ int version)
+{
+ using impl::format_error;
+
+ headers_map::const_iterator iter = hm.find("Content-Type");
+ if (iter == hm.end())
+ throw format_error("Could not determine content type");
+
+ const header_entry& he = (*iter).second;
+ if (he.value() != fmt)
+ throw format_error("Mismatched content type: expected `" + fmt +
+ "' but got `" + he.value() + "'");
+
+ if (!he.has_attr("version"))
+ throw format_error("Could not determine version");
+ const std::string& vstr = atf::text::to_string(version);
+ if (he.get_attr("version") != vstr)
+ throw format_error("Mismatched version: expected `" +
+ vstr + "' but got `" +
+ he.get_attr("version") + "'");
+}
diff --git a/external/bsd/atf/dist/atf-c++/parser.hpp b/external/bsd/atf/dist/atf-c++/parser.hpp
index 7210cfd356e..060126432de 100644
--- a/external/bsd/atf/dist/atf-c++/parser.hpp
+++ b/external/bsd/atf/dist/atf-c++/parser.hpp
@@ -30,7 +30,9 @@
#if !defined(_ATF_CXX_PARSER_HPP_)
#define _ATF_CXX_PARSER_HPP_
+#include <istream>
#include <map>
+#include <ostream>
#include <stdexcept>
#include <string>
#include <utility>
@@ -73,6 +75,15 @@ public:
};
// ------------------------------------------------------------------------
+// The "format_error" class.
+// ------------------------------------------------------------------------
+
+class format_error : public std::runtime_error {
+public:
+ format_error(const std::string&);
+};
+
+// ------------------------------------------------------------------------
// The "token" class.
// ------------------------------------------------------------------------
@@ -354,6 +365,17 @@ public:
const token_type&,
const token_type&,
const std::string&);
+
+ token
+ expect(const token_type&,
+ const token_type&,
+ const token_type&,
+ const token_type&,
+ const token_type&,
+ const token_type&,
+ const token_type&,
+ const token_type&,
+ const std::string&);
};
template< class TKZ >
@@ -520,6 +542,65 @@ parser< TKZ >::expect(const token_type& t1,
return t;
}
+template< class TKZ >
+token
+parser< TKZ >::expect(const token_type& t1,
+ const token_type& t2,
+ const token_type& t3,
+ const token_type& t4,
+ const token_type& t5,
+ const token_type& t6,
+ const token_type& t7,
+ const token_type& t8,
+ const std::string& textual)
+{
+ token t = next();
+
+ if (t.type() != t1 && t.type() != t2 && t.type() != t3 &&
+ t.type() != t4 && t.type() != t5 && t.type() != t6 &&
+ t.type() != t7 && t.type() != t8)
+ throw parse_error(t.lineno(),
+ "Unexpected token `" + t.text() +
+ "'; expected " + textual);
+
+ return t;
+}
+
+#define ATF_PARSER_CALLBACK(parser, func) \
+ do { \
+ if (!(parser).has_errors()) \
+ func; \
+ } while (false)
+
+// ------------------------------------------------------------------------
+// Header parsing.
+// ------------------------------------------------------------------------
+
+typedef std::map< std::string, std::string > attrs_map;
+
+class header_entry {
+ std::string m_name;
+ std::string m_value;
+ attrs_map m_attrs;
+
+public:
+ header_entry(void);
+ header_entry(const std::string&, const std::string&,
+ attrs_map = attrs_map());
+
+ const std::string& name(void) const;
+ const std::string& value(void) const;
+ const attrs_map& attrs(void) const;
+ bool has_attr(const std::string&) const;
+ const std::string& get_attr(const std::string&) const;
+};
+
+typedef std::map< std::string, header_entry > headers_map;
+
+std::pair< size_t, headers_map > read_headers(std::istream&, size_t);
+void write_headers(const headers_map&, std::ostream&);
+void validate_content_type(const headers_map&, const std::string&, int);
+
} // namespace parser
} // namespace atf
diff --git a/external/bsd/atf/dist/atf-c++/parser_test.cpp b/external/bsd/atf/dist/atf-c++/parser_test.cpp
new file mode 100644
index 00000000000..c497ac4bd47
--- /dev/null
+++ b/external/bsd/atf/dist/atf-c++/parser_test.cpp
@@ -0,0 +1,1050 @@
+//
+// Automated Testing Framework (atf)
+//
+// Copyright (c) 2007, 2008, 2009, 2010 The NetBSD Foundation, Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
+// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#include <sstream>
+
+#include "atf-c++/macros.hpp"
+#include "atf-c++/parser.hpp"
+
+#include "test_helpers.hpp"
+
+// ------------------------------------------------------------------------
+// Tests for the "parse_error" class.
+// ------------------------------------------------------------------------
+
+ATF_TEST_CASE(parse_error_to_string);
+ATF_TEST_CASE_HEAD(parse_error_to_string)
+{
+ set_md_var("descr", "Tests the parse_error conversion to strings");
+}
+ATF_TEST_CASE_BODY(parse_error_to_string)
+{
+ using atf::parser::parse_error;
+
+ const parse_error e(123, "This is the message");
+ ATF_CHECK_EQUAL("123: This is the message", std::string(e));
+}
+
+// ------------------------------------------------------------------------
+// Tests for the "parse_errors" class.
+// ------------------------------------------------------------------------
+
+ATF_TEST_CASE(parse_errors_what);
+ATF_TEST_CASE_HEAD(parse_errors_what)
+{
+ set_md_var("descr", "Tests the parse_errors description");
+}
+ATF_TEST_CASE_BODY(parse_errors_what)
+{
+ using atf::parser::parse_error;
+ using atf::parser::parse_errors;
+
+ parse_errors es;
+ es.push_back(parse_error(2, "Second error"));
+ es.push_back(parse_error(1, "First error"));
+
+ ATF_CHECK_EQUAL("2: Second error\n1: First error", std::string(es.what()));
+}
+
+// ------------------------------------------------------------------------
+// Tests for the "token" class.
+// ------------------------------------------------------------------------
+
+ATF_TEST_CASE(token_getters);
+ATF_TEST_CASE_HEAD(token_getters)
+{
+ set_md_var("descr", "Tests the token getters");
+}
+ATF_TEST_CASE_BODY(token_getters)
+{
+ using atf::parser::token;
+
+ {
+ token t(10, 0);
+ ATF_CHECK_EQUAL(t.lineno(), 10);
+ ATF_CHECK_EQUAL(t.type(), 0);
+ ATF_CHECK(t.text().empty());
+ }
+
+ {
+ token t(10, 0, "foo");
+ ATF_CHECK_EQUAL(t.lineno(), 10);
+ ATF_CHECK_EQUAL(t.type(), 0);
+ ATF_CHECK_EQUAL(t.text(), "foo");
+ }
+
+ {
+ token t(20, 1);
+ ATF_CHECK_EQUAL(t.lineno(), 20);
+ ATF_CHECK_EQUAL(t.type(), 1);
+ ATF_CHECK(t.text().empty());
+ }
+
+ {
+ token t(20, 1, "bar");
+ ATF_CHECK_EQUAL(t.lineno(), 20);
+ ATF_CHECK_EQUAL(t.type(), 1);
+ ATF_CHECK_EQUAL(t.text(), "bar");
+ }
+}
+
+// ------------------------------------------------------------------------
+// Tests for the "tokenizer" class.
+// ------------------------------------------------------------------------
+
+#define EXPECT(tkz, ttype, ttext) \
+ do { \
+ atf::parser::token t = tkz.next(); \
+ ATF_CHECK(t.type() == ttype); \
+ ATF_CHECK_EQUAL(t.text(), ttext); \
+ } while (false);
+
+namespace minimal {
+
+ static const atf::parser::token_type& eof_type = 0;
+ static const atf::parser::token_type& nl_type = 1;
+ static const atf::parser::token_type& word_type = 2;
+
+ class tokenizer : public atf::parser::tokenizer< std::istream > {
+ public:
+ tokenizer(std::istream& is, bool skipws) :
+ atf::parser::tokenizer< std::istream >
+ (is, skipws, eof_type, nl_type, word_type)
+ {
+ }
+ };
+
+}
+
+namespace delims {
+
+ static const atf::parser::token_type& eof_type = 0;
+ static const atf::parser::token_type& nl_type = 1;
+ static const atf::parser::token_type& word_type = 2;
+ static const atf::parser::token_type& plus_type = 3;
+ static const atf::parser::token_type& minus_type = 4;
+ static const atf::parser::token_type& equal_type = 5;
+
+ class tokenizer : public atf::parser::tokenizer< std::istream > {
+ public:
+ tokenizer(std::istream& is, bool skipws) :
+ atf::parser::tokenizer< std::istream >
+ (is, skipws, eof_type, nl_type, word_type)
+ {
+ add_delim('+', plus_type);
+ add_delim('-', minus_type);
+ add_delim('=', equal_type);
+ }
+ };
+
+}
+
+namespace keywords {
+
+ static const atf::parser::token_type& eof_type = 0;
+ static const atf::parser::token_type& nl_type = 1;
+ static const atf::parser::token_type& word_type = 2;
+ static const atf::parser::token_type& var_type = 3;
+ static const atf::parser::token_type& loop_type = 4;
+ static const atf::parser::token_type& endloop_type = 5;
+
+ class tokenizer : public atf::parser::tokenizer< std::istream > {
+ public:
+ tokenizer(std::istream& is, bool skipws) :
+ atf::parser::tokenizer< std::istream >
+ (is, skipws, eof_type, nl_type, word_type)
+ {
+ add_keyword("var", var_type);
+ add_keyword("loop", loop_type);
+ add_keyword("endloop", endloop_type);
+ }
+ };
+
+}
+
+namespace quotes {
+
+ static const atf::parser::token_type& eof_type = 0;
+ static const atf::parser::token_type& nl_type = 1;
+ static const atf::parser::token_type& word_type = 2;
+ static const atf::parser::token_type& dblquote_type = 3;
+
+ class tokenizer : public atf::parser::tokenizer< std::istream > {
+ public:
+ tokenizer(std::istream& is, bool skipws) :
+ atf::parser::tokenizer< std::istream >
+ (is, skipws, eof_type, nl_type, word_type)
+ {
+ add_quote('"', dblquote_type);
+ }
+ };
+
+}
+
+ATF_TEST_CASE(tokenizer_minimal_nows);
+ATF_TEST_CASE_HEAD(tokenizer_minimal_nows)
+{
+ set_md_var("descr", "Tests the tokenizer class using a minimal parser "
+ "and not skipping whitespace");
+}
+ATF_TEST_CASE_BODY(tokenizer_minimal_nows)
+{
+ using namespace minimal;
+
+ {
+ std::istringstream iss("");
+ tokenizer mt(iss, false);
+
+ EXPECT(mt, eof_type, "<<EOF>>");
+ EXPECT(mt, eof_type, "<<EOF>>");
+ }
+
+ {
+ std::istringstream iss("\n");
+ tokenizer mt(iss, false);
+
+ EXPECT(mt, nl_type, "<<NEWLINE>>");
+ EXPECT(mt, eof_type, "<<EOF>>");
+ EXPECT(mt, eof_type, "<<EOF>>");
+ }
+
+ {
+ std::istringstream iss("\n\n\n");
+ tokenizer mt(iss, false);
+
+ EXPECT(mt, nl_type, "<<NEWLINE>>");
+ EXPECT(mt, nl_type, "<<NEWLINE>>");
+ EXPECT(mt, nl_type, "<<NEWLINE>>");
+ EXPECT(mt, eof_type, "<<EOF>>");
+ EXPECT(mt, eof_type, "<<EOF>>");
+ }
+
+ {
+ std::istringstream iss("line 1");
+ tokenizer mt(iss, false);
+
+ EXPECT(mt, word_type, "line 1");
+ EXPECT(mt, eof_type, "<<EOF>>");
+ EXPECT(mt, eof_type, "<<EOF>>");
+ }
+
+ {
+ std::istringstream iss("line 1\n");
+ tokenizer mt(iss, false);
+
+ EXPECT(mt, word_type, "line 1");
+ EXPECT(mt, nl_type, "<<NEWLINE>>");
+ EXPECT(mt, eof_type, "<<EOF>>");
+ EXPECT(mt, eof_type, "<<EOF>>");
+ }
+
+ {
+ std::istringstream iss("line 1\nline 2");
+ tokenizer mt(iss, false);
+
+ EXPECT(mt, word_type, "line 1");
+ EXPECT(mt, nl_type, "<<NEWLINE>>");
+ EXPECT(mt, word_type, "line 2");
+ EXPECT(mt, eof_type, "<<EOF>>");
+ EXPECT(mt, eof_type, "<<EOF>>");
+ }
+
+ {
+ std::istringstream iss("line 1\nline 2\nline 3\n");
+ tokenizer mt(iss, false);
+
+ EXPECT(mt, word_type, "line 1");
+ EXPECT(mt, nl_type, "<<NEWLINE>>");
+ EXPECT(mt, word_type, "line 2");
+ EXPECT(mt, nl_type, "<<NEWLINE>>");
+ EXPECT(mt, word_type, "line 3");
+ EXPECT(mt, nl_type, "<<NEWLINE>>");
+ EXPECT(mt, eof_type, "<<EOF>>");
+ EXPECT(mt, eof_type, "<<EOF>>");
+ }
+}
+
+ATF_TEST_CASE(tokenizer_minimal_ws);
+ATF_TEST_CASE_HEAD(tokenizer_minimal_ws)
+{
+ set_md_var("descr", "Tests the tokenizer class using a minimal parser "
+ "and skipping whitespace");
+}
+ATF_TEST_CASE_BODY(tokenizer_minimal_ws)
+{
+ using namespace minimal;
+
+ {
+ std::istringstream iss("");
+ minimal::tokenizer mt(iss, true);
+
+ EXPECT(mt, eof_type, "<<EOF>>");
+ EXPECT(mt, eof_type, "<<EOF>>");
+ }
+
+ {
+ std::istringstream iss(" \t ");
+ tokenizer mt(iss, true);
+
+ EXPECT(mt, eof_type, "<<EOF>>");
+ EXPECT(mt, eof_type, "<<EOF>>");
+ }
+
+ {
+ std::istringstream iss("\n");
+ tokenizer mt(iss, true);
+
+ EXPECT(mt, nl_type, "<<NEWLINE>>");
+ EXPECT(mt, eof_type, "<<EOF>>");
+ EXPECT(mt, eof_type, "<<EOF>>");
+ }
+
+ {
+ std::istringstream iss(" \t \n \t ");
+ tokenizer mt(iss, true);
+
+ EXPECT(mt, nl_type, "<<NEWLINE>>");
+ EXPECT(mt, eof_type, "<<EOF>>");
+ EXPECT(mt, eof_type, "<<EOF>>");
+ }
+
+ {
+ std::istringstream iss("\n\n\n");
+ tokenizer mt(iss, true);
+
+ EXPECT(mt, nl_type, "<<NEWLINE>>");
+ EXPECT(mt, nl_type, "<<NEWLINE>>");
+ EXPECT(mt, nl_type, "<<NEWLINE>>");
+ EXPECT(mt, eof_type, "<<EOF>>");
+ EXPECT(mt, eof_type, "<<EOF>>");
+ }
+
+ {
+ std::istringstream iss("line 1");
+ tokenizer mt(iss, true);
+
+ EXPECT(mt, word_type, "line");
+ EXPECT(mt, word_type, "1");
+ EXPECT(mt, eof_type, "<<EOF>>");
+ EXPECT(mt, eof_type, "<<EOF>>");
+ }
+
+ {
+ std::istringstream iss(" \tline\t 1\t");
+ tokenizer mt(iss, true);
+
+ EXPECT(mt, word_type, "line");
+ EXPECT(mt, word_type, "1");
+ EXPECT(mt, eof_type, "<<EOF>>");
+ EXPECT(mt, eof_type, "<<EOF>>");
+ }
+
+ {
+ std::istringstream iss("line 1\n");
+ tokenizer mt(iss, true);
+
+ EXPECT(mt, word_type, "line");
+ EXPECT(mt, word_type, "1");
+ EXPECT(mt, nl_type, "<<NEWLINE>>");
+ EXPECT(mt, eof_type, "<<EOF>>");
+ EXPECT(mt, eof_type, "<<EOF>>");
+ }
+
+ {
+ std::istringstream iss("line 1\nline 2");
+ tokenizer mt(iss, true);
+
+ EXPECT(mt, word_type, "line");
+ EXPECT(mt, word_type, "1");
+ EXPECT(mt, nl_type, "<<NEWLINE>>");
+ EXPECT(mt, word_type, "line");
+ EXPECT(mt, word_type, "2");
+ EXPECT(mt, eof_type, "<<EOF>>");
+ EXPECT(mt, eof_type, "<<EOF>>");
+ }
+
+ {
+ std::istringstream iss("line 1\nline 2\nline 3\n");
+ tokenizer mt(iss, true);
+
+ EXPECT(mt, word_type, "line");
+ EXPECT(mt, word_type, "1");
+ EXPECT(mt, nl_type, "<<NEWLINE>>");
+ EXPECT(mt, word_type, "line");
+ EXPECT(mt, word_type, "2");
+ EXPECT(mt, nl_type, "<<NEWLINE>>");
+ EXPECT(mt, word_type, "line");
+ EXPECT(mt, word_type, "3");
+ EXPECT(mt, nl_type, "<<NEWLINE>>");
+ EXPECT(mt, eof_type, "<<EOF>>");
+ EXPECT(mt, eof_type, "<<EOF>>");
+ }
+
+ {
+ std::istringstream iss(" \t line \t 1\n\tline\t2\n line 3 \n");
+ tokenizer mt(iss, true);
+
+ EXPECT(mt, word_type, "line");
+ EXPECT(mt, word_type, "1");
+ EXPECT(mt, nl_type, "<<NEWLINE>>");
+ EXPECT(mt, word_type, "line");
+ EXPECT(mt, word_type, "2");
+ EXPECT(mt, nl_type, "<<NEWLINE>>");
+ EXPECT(mt, word_type, "line");
+ EXPECT(mt, word_type, "3");
+ EXPECT(mt, nl_type, "<<NEWLINE>>");
+ EXPECT(mt, eof_type, "<<EOF>>");
+ EXPECT(mt, eof_type, "<<EOF>>");
+ }
+}
+
+ATF_TEST_CASE(tokenizer_delims_nows);
+ATF_TEST_CASE_HEAD(tokenizer_delims_nows)
+{
+ set_md_var("descr", "Tests the tokenizer class using a parser with some "
+ "additional delimiters and not skipping whitespace");
+}
+ATF_TEST_CASE_BODY(tokenizer_delims_nows)
+{
+ using namespace delims;
+
+ {
+ std::istringstream iss("+-=");
+ tokenizer mt(iss, false);
+
+ EXPECT(mt, plus_type, "+");
+ EXPECT(mt, minus_type, "-");
+ EXPECT(mt, equal_type, "=");
+ EXPECT(mt, eof_type, "<<EOF>>");
+ EXPECT(mt, eof_type, "<<EOF>>");
+ }
+
+ {
+ std::istringstream iss("+++");
+ tokenizer mt(iss, false);
+
+ EXPECT(mt, plus_type, "+");
+ EXPECT(mt, plus_type, "+");
+ EXPECT(mt, plus_type, "+");
+ EXPECT(mt, eof_type, "<<EOF>>");
+ EXPECT(mt, eof_type, "<<EOF>>");
+ }
+
+ {
+ std::istringstream iss("\n+\n++\n");
+ tokenizer mt(iss, false);
+
+ EXPECT(mt, nl_type, "<<NEWLINE>>");
+ EXPECT(mt, plus_type, "+");
+ EXPECT(mt, nl_type, "<<NEWLINE>>");
+ EXPECT(mt, plus_type, "+");
+ EXPECT(mt, plus_type, "+");
+ EXPECT(mt, nl_type, "<<NEWLINE>>");
+ EXPECT(mt, eof_type, "<<EOF>>");
+ EXPECT(mt, eof_type, "<<EOF>>");
+ }
+
+ {
+ std::istringstream iss("foo+bar=baz");
+ tokenizer mt(iss, false);
+
+ EXPECT(mt, word_type, "foo");
+ EXPECT(mt, plus_type, "+");
+ EXPECT(mt, word_type, "bar");
+ EXPECT(mt, equal_type, "=");
+ EXPECT(mt, word_type, "baz");
+ EXPECT(mt, eof_type, "<<EOF>>");
+ EXPECT(mt, eof_type, "<<EOF>>");
+ }
+
+ {
+ std::istringstream iss(" foo\t+\tbar = baz ");
+ tokenizer mt(iss, false);
+
+ EXPECT(mt, word_type, " foo\t");
+ EXPECT(mt, plus_type, "+");
+ EXPECT(mt, word_type, "\tbar ");
+ EXPECT(mt, equal_type, "=");
+ EXPECT(mt, word_type, " baz ");
+ EXPECT(mt, eof_type, "<<EOF>>");
+ EXPECT(mt, eof_type, "<<EOF>>");
+ }
+}
+
+ATF_TEST_CASE(tokenizer_delims_ws);
+ATF_TEST_CASE_HEAD(tokenizer_delims_ws)
+{
+ set_md_var("descr", "Tests the tokenizer class using a parser with some "
+ "additional delimiters and skipping whitespace");
+}
+ATF_TEST_CASE_BODY(tokenizer_delims_ws)
+{
+ using namespace delims;
+
+ {
+ std::istringstream iss(" foo\t+\tbar = baz ");
+ tokenizer mt(iss, true);
+
+ EXPECT(mt, word_type, "foo");
+ EXPECT(mt, plus_type, "+");
+ EXPECT(mt, word_type, "bar");
+ EXPECT(mt, equal_type, "=");
+ EXPECT(mt, word_type, "baz");
+ EXPECT(mt, eof_type, "<<EOF>>");
+ EXPECT(mt, eof_type, "<<EOF>>");
+ }
+}
+
+ATF_TEST_CASE(tokenizer_keywords_nows);
+ATF_TEST_CASE_HEAD(tokenizer_keywords_nows)
+{
+ set_md_var("descr", "Tests the tokenizer class using a parser with some "
+ "additional keywords and not skipping whitespace");
+}
+ATF_TEST_CASE_BODY(tokenizer_keywords_nows)
+{
+ using namespace keywords;
+
+ {
+ std::istringstream iss("var");
+ tokenizer mt(iss, false);
+
+ EXPECT(mt, var_type, "var");
+ EXPECT(mt, eof_type, "<<EOF>>");
+ EXPECT(mt, eof_type, "<<EOF>>");
+ }
+
+ {
+ std::istringstream iss("va");
+ tokenizer mt(iss, false);
+
+ EXPECT(mt, word_type, "va");
+ EXPECT(mt, eof_type, "<<EOF>>");
+ EXPECT(mt, eof_type, "<<EOF>>");
+ }
+
+ {
+ std::istringstream iss("vara");
+ tokenizer mt(iss, false);
+
+ EXPECT(mt, word_type, "vara");
+ EXPECT(mt, eof_type, "<<EOF>>");
+ EXPECT(mt, eof_type, "<<EOF>>");
+ }
+
+ {
+ std::istringstream iss("var ");
+ tokenizer mt(iss, false);
+
+ EXPECT(mt, word_type, "var ");
+ EXPECT(mt, eof_type, "<<EOF>>");
+ EXPECT(mt, eof_type, "<<EOF>>");
+ }
+
+ {
+ std::istringstream iss("var\nloop\nendloop");
+ tokenizer mt(iss, false);
+
+ EXPECT(mt, var_type, "var");
+ EXPECT(mt, nl_type, "<<NEWLINE>>");
+ EXPECT(mt, loop_type, "loop");
+ EXPECT(mt, nl_type, "<<NEWLINE>>");
+ EXPECT(mt, endloop_type, "endloop");
+ EXPECT(mt, eof_type, "<<EOF>>");
+ EXPECT(mt, eof_type, "<<EOF>>");
+ }
+}
+
+ATF_TEST_CASE(tokenizer_keywords_ws);
+ATF_TEST_CASE_HEAD(tokenizer_keywords_ws)
+{
+ set_md_var("descr", "Tests the tokenizer class using a parser with some "
+ "additional keywords and not skipping whitespace");
+}
+ATF_TEST_CASE_BODY(tokenizer_keywords_ws)
+{
+ using namespace keywords;
+
+ {
+ std::istringstream iss("var ");
+ tokenizer mt(iss, true);
+
+ EXPECT(mt, var_type, "var");
+ EXPECT(mt, eof_type, "<<EOF>>");
+ EXPECT(mt, eof_type, "<<EOF>>");
+ }
+
+ {
+ std::istringstream iss(" var \n\tloop\t\n \tendloop \t");
+ tokenizer mt(iss, true);
+
+ EXPECT(mt, var_type, "var");
+ EXPECT(mt, nl_type, "<<NEWLINE>>");
+ EXPECT(mt, loop_type, "loop");
+ EXPECT(mt, nl_type, "<<NEWLINE>>");
+ EXPECT(mt, endloop_type, "endloop");
+ EXPECT(mt, eof_type, "<<EOF>>");
+ EXPECT(mt, eof_type, "<<EOF>>");
+ }
+
+ {
+ std::istringstream iss("var loop endloop");
+ tokenizer mt(iss, true);
+
+ EXPECT(mt, var_type, "var");
+ EXPECT(mt, loop_type, "loop");
+ EXPECT(mt, endloop_type, "endloop");
+ EXPECT(mt, eof_type, "<<EOF>>");
+ EXPECT(mt, eof_type, "<<EOF>>");
+ }
+}
+
+ATF_TEST_CASE(tokenizer_quotes_nows);
+ATF_TEST_CASE_HEAD(tokenizer_quotes_nows)
+{
+ set_md_var("descr", "Tests the tokenizer class using a parser with "
+ "quoted strings and not skipping whitespace");
+}
+ATF_TEST_CASE_BODY(tokenizer_quotes_nows)
+{
+ using namespace quotes;
+
+ {
+ std::istringstream iss("var");
+ tokenizer mt(iss, false);
+
+ EXPECT(mt, word_type, "var");
+ EXPECT(mt, eof_type, "<<EOF>>");
+ EXPECT(mt, eof_type, "<<EOF>>");
+ }
+
+ {
+ std::istringstream iss("\"var\"");
+ tokenizer mt(iss, false);
+
+ EXPECT(mt, word_type, "var");
+ EXPECT(mt, eof_type, "<<EOF>>");
+ EXPECT(mt, eof_type, "<<EOF>>");
+ }
+
+ {
+ std::istringstream iss("var1\"var2\"");
+ tokenizer mt(iss, false);
+
+ EXPECT(mt, word_type, "var1");
+ EXPECT(mt, word_type, "var2");
+ EXPECT(mt, eof_type, "<<EOF>>");
+ EXPECT(mt, eof_type, "<<EOF>>");
+ }
+
+ {
+ std::istringstream iss("var1\" var2 \"");
+ tokenizer mt(iss, false);
+
+ EXPECT(mt, word_type, "var1");
+ EXPECT(mt, word_type, " var2 ");
+ EXPECT(mt, eof_type, "<<EOF>>");
+ EXPECT(mt, eof_type, "<<EOF>>");
+ }
+}
+
+ATF_TEST_CASE(tokenizer_quotes_ws);
+ATF_TEST_CASE_HEAD(tokenizer_quotes_ws)
+{
+ set_md_var("descr", "Tests the tokenizer class using a parser with "
+ "quoted strings and skipping whitespace");
+}
+ATF_TEST_CASE_BODY(tokenizer_quotes_ws)
+{
+ using namespace quotes;
+
+ {
+ std::istringstream iss(" var ");
+ tokenizer mt(iss, true);
+
+ EXPECT(mt, word_type, "var");
+ EXPECT(mt, eof_type, "<<EOF>>");
+ EXPECT(mt, eof_type, "<<EOF>>");
+ }
+
+ {
+ std::istringstream iss(" \"var\" ");
+ tokenizer mt(iss, true);
+
+ EXPECT(mt, word_type, "var");
+ EXPECT(mt, eof_type, "<<EOF>>");
+ EXPECT(mt, eof_type, "<<EOF>>");
+ }
+
+ {
+ std::istringstream iss(" var1 \"var2\" ");
+ tokenizer mt(iss, true);
+
+ EXPECT(mt, word_type, "var1");
+ EXPECT(mt, word_type, "var2");
+ EXPECT(mt, eof_type, "<<EOF>>");
+ EXPECT(mt, eof_type, "<<EOF>>");
+ }
+
+ {
+ std::istringstream iss(" var1 \" var2 \" ");
+ tokenizer mt(iss, true);
+
+ EXPECT(mt, word_type, "var1");
+ EXPECT(mt, word_type, " var2 ");
+ EXPECT(mt, eof_type, "<<EOF>>");
+ EXPECT(mt, eof_type, "<<EOF>>");
+ }
+}
+
+// ------------------------------------------------------------------------
+// Tests for the headers parser.
+// ------------------------------------------------------------------------
+
+class header_reader {
+ std::istream& m_is;
+
+public:
+ header_reader(std::istream& is) :
+ m_is(is)
+ {
+ }
+
+ void
+ read(void)
+ {
+ std::pair< size_t, atf::parser::headers_map > hml =
+ atf::parser::read_headers(m_is, 1);
+ atf::parser::validate_content_type(hml.second,
+ "application/X-atf-headers-test", 1234);
+ }
+
+ std::vector< std::string > m_calls;
+};
+
+ATF_TEST_CASE_WITHOUT_HEAD(headers_1);
+ATF_TEST_CASE_BODY(headers_1)
+{
+ const char* input =
+ ""
+ ;
+
+ const char* exp_calls[] = {
+ NULL
+ };
+
+ const char* exp_errors[] = {
+ "1: Unexpected token `<<EOF>>'; expected a header name",
+ NULL
+ };
+
+ do_parser_test< header_reader >(input, exp_calls, exp_errors);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(headers_2);
+ATF_TEST_CASE_BODY(headers_2)
+{
+ const char* input =
+ "Content-Type\n"
+ ;
+
+ const char* exp_calls[] = {
+ NULL
+ };
+
+ const char* exp_errors[] = {
+ "1: Unexpected token `<<NEWLINE>>'; expected `:'",
+ NULL
+ };
+
+ do_parser_test< header_reader >(input, exp_calls, exp_errors);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(headers_3);
+ATF_TEST_CASE_BODY(headers_3)
+{
+ const char* input =
+ "Content-Type:\n"
+ ;
+
+ const char* exp_calls[] = {
+ NULL
+ };
+
+ const char* exp_errors[] = {
+ "1: Unexpected token `<<NEWLINE>>'; expected a textual value",
+ NULL
+ };
+
+ do_parser_test< header_reader >(input, exp_calls, exp_errors);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(headers_4);
+ATF_TEST_CASE_BODY(headers_4)
+{
+ const char* input =
+ "Content-Type: application/X-atf-headers-test\n"
+ ;
+
+ const char* exp_calls[] = {
+ NULL
+ };
+
+ const char* exp_errors[] = {
+ "2: Unexpected token `<<EOF>>'; expected a header name",
+ NULL
+ };
+
+ do_parser_test< header_reader >(input, exp_calls, exp_errors);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(headers_5);
+ATF_TEST_CASE_BODY(headers_5)
+{
+ const char* input =
+ "Content-Type: application/X-atf-headers-test;\n"
+ ;
+
+ const char* exp_calls[] = {
+ NULL
+ };
+
+ const char* exp_errors[] = {
+ "1: Unexpected token `<<NEWLINE>>'; expected an attribute name",
+ NULL
+ };
+
+ do_parser_test< header_reader >(input, exp_calls, exp_errors);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(headers_6);
+ATF_TEST_CASE_BODY(headers_6)
+{
+ const char* input =
+ "Content-Type: application/X-atf-headers-test; version\n"
+ ;
+
+ const char* exp_calls[] = {
+ NULL
+ };
+
+ const char* exp_errors[] = {
+ "1: Unexpected token `<<NEWLINE>>'; expected `='",
+ NULL
+ };
+
+ do_parser_test< header_reader >(input, exp_calls, exp_errors);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(headers_7);
+ATF_TEST_CASE_BODY(headers_7)
+{
+ const char* input =
+ "Content-Type: application/X-atf-headers-test; version=\n"
+ ;
+
+ const char* exp_calls[] = {
+ NULL
+ };
+
+ const char* exp_errors[] = {
+ "1: Unexpected token `<<NEWLINE>>'; expected word or quoted string",
+ NULL
+ };
+
+ do_parser_test< header_reader >(input, exp_calls, exp_errors);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(headers_8);
+ATF_TEST_CASE_BODY(headers_8)
+{
+ const char* input =
+ "Content-Type: application/X-atf-headers-test; version=\"1234\n"
+ ;
+
+ const char* exp_calls[] = {
+ NULL
+ };
+
+ const char* exp_errors[] = {
+ "1: Missing double quotes before end of line",
+ NULL
+ };
+
+ do_parser_test< header_reader >(input, exp_calls, exp_errors);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(headers_9);
+ATF_TEST_CASE_BODY(headers_9)
+{
+ const char* input =
+ "Content-Type: application/X-atf-headers-test; version=1234\"\n"
+ ;
+
+ const char* exp_calls[] = {
+ NULL
+ };
+
+ const char* exp_errors[] = {
+ "1: Missing double quotes before end of line",
+ NULL
+ };
+
+ do_parser_test< header_reader >(input, exp_calls, exp_errors);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(headers_10);
+ATF_TEST_CASE_BODY(headers_10)
+{
+ const char* input =
+ "Content-Type: application/X-atf-headers-test; version=1234\n"
+ ;
+
+ const char* exp_calls[] = {
+ NULL
+ };
+
+ const char* exp_errors[] = {
+ "2: Unexpected token `<<EOF>>'; expected a header name",
+ NULL
+ };
+
+ do_parser_test< header_reader >(input, exp_calls, exp_errors);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(headers_11);
+ATF_TEST_CASE_BODY(headers_11)
+{
+ const char* input =
+ "Content-Type: application/X-atf-headers-test; version=\"1234\"\n"
+ ;
+
+ const char* exp_calls[] = {
+ NULL
+ };
+
+ const char* exp_errors[] = {
+ "2: Unexpected token `<<EOF>>'; expected a header name",
+ NULL
+ };
+
+ do_parser_test< header_reader >(input, exp_calls, exp_errors);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(headers_12);
+ATF_TEST_CASE_BODY(headers_12)
+{
+ const char* input =
+ "Content-Type: application/X-atf-headers-test; version=\"1234\"\n"
+ "a b\n"
+ "a-b:\n"
+ "a-b: foo;\n"
+ "a-b: foo; var\n"
+ "a-b: foo; var=\n"
+ "a-b: foo; var=\"a\n"
+ "a-b: foo; var=a\"\n"
+ "a-b: foo; var=\"a\";\n"
+ "a-b: foo; var=\"a\"; second\n"
+ "a-b: foo; var=\"a\"; second=\n"
+ "a-b: foo; var=\"a\"; second=\"b\n"
+ "a-b: foo; var=\"a\"; second=b\"\n"
+ "a-b: foo; var=\"a\"; second=\"b\"\n"
+ ;
+
+ const char* exp_calls[] = {
+ NULL
+ };
+
+ const char* exp_errors[] = {
+ "2: Unexpected token `b'; expected `:'",
+ "3: Unexpected token `<<NEWLINE>>'; expected a textual value",
+ "4: Unexpected token `<<NEWLINE>>'; expected an attribute name",
+ "5: Unexpected token `<<NEWLINE>>'; expected `='",
+ "6: Unexpected token `<<NEWLINE>>'; expected word or quoted string",
+ "7: Missing double quotes before end of line",
+ "8: Missing double quotes before end of line",
+ "9: Unexpected token `<<NEWLINE>>'; expected an attribute name",
+ "10: Unexpected token `<<NEWLINE>>'; expected `='",
+ "11: Unexpected token `<<NEWLINE>>'; expected word or quoted string",
+ "12: Missing double quotes before end of line",
+ "13: Missing double quotes before end of line",
+ NULL
+ };
+
+ do_parser_test< header_reader >(input, exp_calls, exp_errors);
+}
+
+// ------------------------------------------------------------------------
+// Tests cases for the header file.
+// ------------------------------------------------------------------------
+
+HEADER_TC(include, "atf-c++/parser.hpp");
+
+// ------------------------------------------------------------------------
+// Main.
+// ------------------------------------------------------------------------
+
+ATF_INIT_TEST_CASES(tcs)
+{
+ // Add test cases for the "parse_error" class.
+ ATF_ADD_TEST_CASE(tcs, parse_error_to_string);
+
+ // Add test cases for the "parse_errors" class.
+ ATF_ADD_TEST_CASE(tcs, parse_errors_what);
+
+ // Add test cases for the "token" class.
+ ATF_ADD_TEST_CASE(tcs, token_getters);
+
+ // Add test cases for the "tokenizer" class.
+ ATF_ADD_TEST_CASE(tcs, tokenizer_minimal_nows);
+ ATF_ADD_TEST_CASE(tcs, tokenizer_minimal_ws);
+ ATF_ADD_TEST_CASE(tcs, tokenizer_delims_nows);
+ ATF_ADD_TEST_CASE(tcs, tokenizer_delims_ws);
+ ATF_ADD_TEST_CASE(tcs, tokenizer_keywords_nows);
+ ATF_ADD_TEST_CASE(tcs, tokenizer_keywords_ws);
+ ATF_ADD_TEST_CASE(tcs, tokenizer_quotes_nows);
+ ATF_ADD_TEST_CASE(tcs, tokenizer_quotes_ws);
+
+ // Add the tests for the headers parser.
+
+ // Add the test cases for the header file.
+ ATF_ADD_TEST_CASE(tcs, headers_1);
+ ATF_ADD_TEST_CASE(tcs, headers_2);
+ ATF_ADD_TEST_CASE(tcs, headers_3);
+ ATF_ADD_TEST_CASE(tcs, headers_4);
+ ATF_ADD_TEST_CASE(tcs, headers_5);
+ ATF_ADD_TEST_CASE(tcs, headers_6);
+ ATF_ADD_TEST_CASE(tcs, headers_7);
+ ATF_ADD_TEST_CASE(tcs, headers_8);
+ ATF_ADD_TEST_CASE(tcs, headers_9);
+ ATF_ADD_TEST_CASE(tcs, headers_10);
+ ATF_ADD_TEST_CASE(tcs, headers_11);
+ ATF_ADD_TEST_CASE(tcs, headers_12);
+ ATF_ADD_TEST_CASE(tcs, include);
+}
diff --git a/external/bsd/atf/dist/atf-c++/pkg_config_test.sh b/external/bsd/atf/dist/atf-c++/pkg_config_test.sh
new file mode 100644
index 00000000000..a932e7c4a01
--- /dev/null
+++ b/external/bsd/atf/dist/atf-c++/pkg_config_test.sh
@@ -0,0 +1,150 @@
+#
+# Automated Testing Framework (atf)
+#
+# Copyright (c) 2008, 2010 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
+# CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+# The following tests assume that the atfc++.pc file is installed in a
+# directory that is known by pkg-config. Otherwise they will fail,
+# and you will be required to adjust PKG_CONFIG_PATH accordingly.
+#
+# It would be possible to bypass this requirement by setting the path
+# explicitly during the tests, but then this would not do a real check
+# to ensure that the installation is working.
+
+require_pc()
+{
+ pkg-config ${1} || atf_fail "pkg-config could not locate ${1}.pc;" \
+ "maybe need to set PKG_CONFIG_PATH?"
+}
+
+check_version()
+{
+ atf_check -s eq:0 -o save:stdout -e empty -x \
+ "atf-version | head -n 1 | cut -d ' ' -f 4"
+ ver1=$(cat stdout)
+ echo "Version reported by atf-version: ${ver1}"
+
+ atf_check -s eq:0 -o save:stdout -e empty pkg-config --modversion "${1}"
+ ver2=$(cat stdout)
+ echo "Version reported by pkg-config: ${ver2}"
+
+ atf_check_equal ${ver1} ${ver2}
+}
+
+atf_test_case version
+version_head()
+{
+ atf_set "descr" "Checks that the version in atf-c++ is correct"
+ atf_set "require.progs" "pkg-config"
+}
+version_body()
+{
+ require_pc "atf-c++"
+
+ check_version "atf-c++"
+}
+
+atf_test_case build
+build_head()
+{
+ atf_set "descr" "Checks that a test program can be built against" \
+ "the C++ library based on the pkg-config information"
+ atf_set "require.progs" "pkg-config"
+ atf_set "use.fs" "true"
+}
+build_body()
+{
+ require_pc "atf-c++"
+
+ atf_check -s eq:0 -o save:stdout -e empty \
+ pkg-config --variable=cxx atf-c++
+ cxx=$(cat stdout)
+ echo "Compiler is: ${cxx}"
+ atf_require_prog ${cxx}
+
+ cat >tp.cpp <<EOF
+#include <iostream>
+
+#include <atf-c++.hpp>
+
+ATF_TEST_CASE(tc);
+ATF_TEST_CASE_HEAD(tc) {
+ set_md_var("descr", "A test case");
+}
+ATF_TEST_CASE_BODY(tc) {
+ std::cout << "Running" << std::endl;
+}
+
+ATF_INIT_TEST_CASES(tcs) {
+ ATF_ADD_TEST_CASE(tcs, tc);
+}
+EOF
+
+ atf_check -s eq:0 -o save:stdout -e empty pkg-config --cflags atf-c++
+ cxxflags=$(cat stdout)
+ echo "CXXFLAGS are: ${cxxflags}"
+
+ atf_check -s eq:0 -o save:stdout -e empty \
+ pkg-config --libs-only-L --libs-only-other atf-c++
+ ldflags=$(cat stdout)
+ atf_check -s eq:0 -o save:stdout -e empty \
+ pkg-config --libs-only-l atf-c++
+ libs=$(cat stdout)
+ echo "LDFLAGS are: ${ldflags}"
+ echo "LIBS are: ${libs}"
+
+ atf_check -s eq:0 -o empty -e empty ${cxx} ${cxxflags} -o tp.o -c tp.cpp
+ atf_check -s eq:0 -o empty -e empty ${cxx} ${ldflags} -o tp tp.o ${libs}
+
+ libpath=
+ for f in ${ldflags}; do
+ case ${f} in
+ -L*)
+ dir=$(echo ${f} | sed -e 's,^-L,,')
+ if [ -z "${libpath}" ]; then
+ libpath="${dir}"
+ else
+ libpath="${libpath}:${dir}"
+ fi
+ ;;
+ *)
+ ;;
+ esac
+ done
+
+ atf_check -s eq:0 -o empty -e empty test -x tp
+ atf_check -s eq:0 -o match:'Running' -e empty -x \
+ "LD_LIBRARY_PATH=${libpath} ./tp tc"
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case version
+ atf_add_test_case build
+}
+
+# vim: syntax=sh:expandtab:shiftwidth=4:softtabstop=4
diff --git a/external/bsd/atf/dist/atf-c++/process_test.cpp b/external/bsd/atf/dist/atf-c++/process_test.cpp
new file mode 100644
index 00000000000..cc009029c06
--- /dev/null
+++ b/external/bsd/atf/dist/atf-c++/process_test.cpp
@@ -0,0 +1,367 @@
+//
+// Automated Testing Framework (atf)
+//
+// Copyright (c) 2008, 2009 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 <cstdlib>
+#include <cstring>
+
+#include <atf-c++.hpp>
+
+#include "atf-c++/process.hpp"
+
+#include "test_helpers.hpp"
+
+// TODO: Testing the fork function is a huge task and I'm afraid of
+// copy/pasting tons of stuff from the C version. I'd rather not do that
+// until some code can be shared, which cannot happen until the C++ binding
+// is cleaned by a fair amount. Instead... just rely (at the moment) on
+// the system tests for the tools using this module.
+
+// ------------------------------------------------------------------------
+// Auxiliary functions.
+// ------------------------------------------------------------------------
+
+static
+std::size_t
+array_size(const char* const* array)
+{
+ std::size_t size = 0;
+
+ for (const char* const* ptr = array; *ptr != NULL; ptr++)
+ size++;
+
+ return size;
+}
+
+static
+atf::process::status
+exec_process_helpers(const atf::tests::tc& tc, const char* helper_name)
+{
+ using atf::process::exec;
+
+ std::vector< std::string > argv;
+ argv.push_back(get_process_helpers_path(tc).leaf_name());
+ argv.push_back(helper_name);
+
+ return exec(get_process_helpers_path(tc),
+ atf::process::argv_array(argv),
+ atf::process::stream_inherit(),
+ atf::process::stream_inherit());
+}
+
+// ------------------------------------------------------------------------
+// Tests for the "argv_array" type.
+// ------------------------------------------------------------------------
+
+ATF_TEST_CASE(argv_array_init_carray);
+ATF_TEST_CASE_HEAD(argv_array_init_carray)
+{
+ set_md_var("descr", "Tests that argv_array is correctly constructed "
+ "from a C-style array of strings");
+}
+ATF_TEST_CASE_BODY(argv_array_init_carray)
+{
+ {
+ const char* const carray[] = { NULL };
+ atf::process::argv_array argv(carray);
+
+ ATF_CHECK_EQUAL(argv.size(), 0);
+ }
+
+ {
+ const char* const carray[] = { "arg0", NULL };
+ atf::process::argv_array argv(carray);
+
+ ATF_CHECK_EQUAL(argv.size(), 1);
+ ATF_CHECK(std::strcmp(argv[0], carray[0]) == 0);
+ }
+
+ {
+ const char* const carray[] = { "arg0", "arg1", "arg2", NULL };
+ atf::process::argv_array argv(carray);
+
+ ATF_CHECK_EQUAL(argv.size(), 3);
+ ATF_CHECK(std::strcmp(argv[0], carray[0]) == 0);
+ ATF_CHECK(std::strcmp(argv[1], carray[1]) == 0);
+ ATF_CHECK(std::strcmp(argv[2], carray[2]) == 0);
+ }
+}
+
+ATF_TEST_CASE(argv_array_init_col);
+ATF_TEST_CASE_HEAD(argv_array_init_col)
+{
+ set_md_var("descr", "Tests that argv_array is correctly constructed "
+ "from a string collection");
+}
+ATF_TEST_CASE_BODY(argv_array_init_col)
+{
+ {
+ std::vector< std::string > col;
+ atf::process::argv_array argv(col);
+
+ ATF_CHECK_EQUAL(argv.size(), 0);
+ }
+
+ {
+ std::vector< std::string > col;
+ col.push_back("arg0");
+ atf::process::argv_array argv(col);
+
+ ATF_CHECK_EQUAL(argv.size(), 1);
+ ATF_CHECK_EQUAL(argv[0], col[0]);
+ }
+
+ {
+ std::vector< std::string > col;
+ col.push_back("arg0");
+ col.push_back("arg1");
+ col.push_back("arg2");
+ atf::process::argv_array argv(col);
+
+ ATF_CHECK_EQUAL(argv.size(), 3);
+ ATF_CHECK_EQUAL(argv[0], col[0]);
+ ATF_CHECK_EQUAL(argv[1], col[1]);
+ ATF_CHECK_EQUAL(argv[2], col[2]);
+ }
+}
+
+ATF_TEST_CASE(argv_array_init_empty);
+ATF_TEST_CASE_HEAD(argv_array_init_empty)
+{
+ set_md_var("descr", "Tests that argv_array is correctly constructed "
+ "by the default constructor");
+}
+ATF_TEST_CASE_BODY(argv_array_init_empty)
+{
+ atf::process::argv_array argv;
+
+ ATF_CHECK_EQUAL(argv.size(), 0);
+}
+
+ATF_TEST_CASE(argv_array_init_varargs);
+ATF_TEST_CASE_HEAD(argv_array_init_varargs)
+{
+ set_md_var("descr", "Tests that argv_array is correctly constructed "
+ "from a variable list of arguments");
+}
+ATF_TEST_CASE_BODY(argv_array_init_varargs)
+{
+ {
+ atf::process::argv_array argv("arg0", NULL);
+
+ ATF_CHECK_EQUAL(argv.size(), 1);
+ ATF_CHECK_EQUAL(argv[0], std::string("arg0"));
+ }
+
+ {
+ atf::process::argv_array argv("arg0", "arg1", "arg2", NULL);
+
+ ATF_CHECK_EQUAL(argv.size(), 3);
+ ATF_CHECK_EQUAL(argv[0], std::string("arg0"));
+ ATF_CHECK_EQUAL(argv[1], std::string("arg1"));
+ ATF_CHECK_EQUAL(argv[2], std::string("arg2"));
+ }
+}
+
+ATF_TEST_CASE(argv_array_assign);
+ATF_TEST_CASE_HEAD(argv_array_assign)
+{
+ set_md_var("descr", "Tests that assigning an argv_array works");
+}
+ATF_TEST_CASE_BODY(argv_array_assign)
+{
+ using atf::process::argv_array;
+
+ const char* const carray1[] = { "arg1", NULL };
+ const char* const carray2[] = { "arg1", "arg2", NULL };
+
+ std::auto_ptr< argv_array > argv1(new argv_array(carray1));
+ std::auto_ptr< argv_array > argv2(new argv_array(carray2));
+
+ *argv2 = *argv1;
+ ATF_CHECK_EQUAL(argv2->size(), argv1->size());
+ ATF_CHECK(std::strcmp((*argv2)[0], (*argv1)[0]) == 0);
+
+ ATF_CHECK(argv2->exec_argv() != argv1->exec_argv());
+ argv1.release();
+ {
+ const char* const* eargv2 = argv2->exec_argv();
+ ATF_CHECK(std::strcmp(eargv2[0], carray1[0]) == 0);
+ ATF_CHECK_EQUAL(eargv2[1], static_cast< const char* >(NULL));
+ }
+
+ argv2.release();
+}
+
+ATF_TEST_CASE(argv_array_copy);
+ATF_TEST_CASE_HEAD(argv_array_copy)
+{
+ set_md_var("descr", "Tests that copying an argv_array constructed from "
+ "a C-style array of strings works");
+}
+ATF_TEST_CASE_BODY(argv_array_copy)
+{
+ using atf::process::argv_array;
+
+ const char* const carray[] = { "arg0", NULL };
+
+ std::auto_ptr< argv_array > argv1(new argv_array(carray));
+ std::auto_ptr< argv_array > argv2(new argv_array(*argv1));
+
+ ATF_CHECK_EQUAL(argv2->size(), argv1->size());
+ ATF_CHECK(std::strcmp((*argv2)[0], (*argv1)[0]) == 0);
+
+ ATF_CHECK(argv2->exec_argv() != argv1->exec_argv());
+ argv1.release();
+ {
+ const char* const* eargv2 = argv2->exec_argv();
+ ATF_CHECK(std::strcmp(eargv2[0], carray[0]) == 0);
+ ATF_CHECK_EQUAL(eargv2[1], static_cast< const char* >(NULL));
+ }
+
+ argv2.release();
+}
+
+ATF_TEST_CASE(argv_array_exec_argv);
+ATF_TEST_CASE_HEAD(argv_array_exec_argv)
+{
+ set_md_var("descr", "Tests that the exec argv provided by an argv_array "
+ "is correct");
+}
+ATF_TEST_CASE_BODY(argv_array_exec_argv)
+{
+ using atf::process::argv_array;
+
+ {
+ argv_array argv;
+ const char* const* eargv = argv.exec_argv();
+ ATF_CHECK_EQUAL(array_size(eargv), 0);
+ ATF_CHECK_EQUAL(eargv[0], static_cast< const char* >(NULL));
+ }
+
+ {
+ const char* const carray[] = { "arg0", NULL };
+ argv_array argv(carray);
+ const char* const* eargv = argv.exec_argv();
+ ATF_CHECK_EQUAL(array_size(eargv), 1);
+ ATF_CHECK(std::strcmp(eargv[0], "arg0") == 0);
+ ATF_CHECK_EQUAL(eargv[1], static_cast< const char* >(NULL));
+ }
+
+ {
+ std::vector< std::string > col;
+ col.push_back("arg0");
+ argv_array argv(col);
+ const char* const* eargv = argv.exec_argv();
+ ATF_CHECK_EQUAL(array_size(eargv), 1);
+ ATF_CHECK(std::strcmp(eargv[0], "arg0") == 0);
+ ATF_CHECK_EQUAL(eargv[1], static_cast< const char* >(NULL));
+ }
+}
+
+ATF_TEST_CASE(argv_array_iter);
+ATF_TEST_CASE_HEAD(argv_array_iter)
+{
+ set_md_var("descr", "Tests that an argv_array can be iterated");
+}
+ATF_TEST_CASE_BODY(argv_array_iter)
+{
+ using atf::process::argv_array;
+
+ std::vector< std::string > vector;
+ vector.push_back("arg0");
+ vector.push_back("arg1");
+ vector.push_back("arg2");
+
+ argv_array argv(vector);
+ ATF_CHECK_EQUAL(argv.size(), 3);
+ std::vector< std::string >::size_type pos = 0;
+ for (argv_array::const_iterator iter = argv.begin(); iter != argv.end();
+ iter++) {
+ ATF_CHECK_EQUAL(*iter, vector[pos]);
+ pos++;
+ }
+}
+
+// ------------------------------------------------------------------------
+// Tests cases for the free functions.
+// ------------------------------------------------------------------------
+
+ATF_TEST_CASE(exec_failure);
+ATF_TEST_CASE_HEAD(exec_failure)
+{
+ set_md_var("descr", "Tests execing a command that reports failure");
+}
+ATF_TEST_CASE_BODY(exec_failure)
+{
+ const atf::process::status s = exec_process_helpers(*this, "exit-failure");
+ ATF_CHECK(s.exited());
+ ATF_CHECK_EQUAL(s.exitstatus(), EXIT_FAILURE);
+}
+
+ATF_TEST_CASE(exec_success);
+ATF_TEST_CASE_HEAD(exec_success)
+{
+ set_md_var("descr", "Tests execing a command that reports success");
+}
+ATF_TEST_CASE_BODY(exec_success)
+{
+ const atf::process::status s = exec_process_helpers(*this, "exit-success");
+ ATF_CHECK(s.exited());
+ ATF_CHECK_EQUAL(s.exitstatus(), EXIT_SUCCESS);
+}
+
+// ------------------------------------------------------------------------
+// Tests cases for the header file.
+// ------------------------------------------------------------------------
+
+HEADER_TC(include, "atf-c++/process.hpp");
+
+// ------------------------------------------------------------------------
+// Main.
+// ------------------------------------------------------------------------
+
+ATF_INIT_TEST_CASES(tcs)
+{
+ // Add the test cases for the "argv_array" type.
+ ATF_ADD_TEST_CASE(tcs, argv_array_assign);
+ ATF_ADD_TEST_CASE(tcs, argv_array_copy);
+ ATF_ADD_TEST_CASE(tcs, argv_array_exec_argv);
+ ATF_ADD_TEST_CASE(tcs, argv_array_init_carray);
+ ATF_ADD_TEST_CASE(tcs, argv_array_init_col);
+ ATF_ADD_TEST_CASE(tcs, argv_array_init_empty);
+ ATF_ADD_TEST_CASE(tcs, argv_array_init_varargs);
+ ATF_ADD_TEST_CASE(tcs, argv_array_iter);
+
+ // Add the test cases for the free functions.
+ ATF_ADD_TEST_CASE(tcs, exec_failure);
+ ATF_ADD_TEST_CASE(tcs, exec_success);
+
+ // Add the test cases for the header file.
+ ATF_ADD_TEST_CASE(tcs, include);
+}
diff --git a/external/bsd/atf/dist/atf-c++/sanity_test.cpp b/external/bsd/atf/dist/atf-c++/sanity_test.cpp
new file mode 100644
index 00000000000..282aaa7fe50
--- /dev/null
+++ b/external/bsd/atf/dist/atf-c++/sanity_test.cpp
@@ -0,0 +1,48 @@
+//
+// Automated Testing Framework (atf)
+//
+// Copyright (c) 2009 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"
+
+#include "test_helpers.hpp"
+
+// ------------------------------------------------------------------------
+// Tests cases for the header file.
+// ------------------------------------------------------------------------
+
+HEADER_TC(include, "atf-c++/sanity.hpp");
+
+// ------------------------------------------------------------------------
+// Main.
+// ------------------------------------------------------------------------
+
+ATF_INIT_TEST_CASES(tcs)
+{
+ // Add the test cases for the header file.
+ ATF_ADD_TEST_CASE(tcs, include);
+}
diff --git a/external/bsd/atf/dist/atf-c++/signals_test.cpp b/external/bsd/atf/dist/atf-c++/signals_test.cpp
new file mode 100644
index 00000000000..7c8d86334d7
--- /dev/null
+++ b/external/bsd/atf/dist/atf-c++/signals_test.cpp
@@ -0,0 +1,283 @@
+//
+// Automated Testing Framework (atf)
+//
+// Copyright (c) 2008, 2009, 2010 The NetBSD Foundation, Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
+// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+extern "C" {
+#include <sys/types.h>
+#include <signal.h>
+#include <unistd.h>
+}
+
+#include <cerrno>
+#include <iostream>
+
+#include "atf-c++/exceptions.hpp"
+#include "atf-c++/macros.hpp"
+#include "atf-c++/process.hpp"
+#include "atf-c++/signals.hpp"
+
+#include "test_helpers.hpp"
+
+// ------------------------------------------------------------------------
+// Auxiliary functions.
+// ------------------------------------------------------------------------
+
+namespace sigusr1 {
+ static bool happened = false;
+
+ static
+ void
+ handler(int signo)
+ {
+ happened = true;
+ }
+
+ static
+ void
+ program(void)
+ {
+ struct sigaction sa;
+ sa.sa_handler = handler;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = 0;
+ if (::sigaction(SIGUSR1, &sa, NULL) == -1)
+ throw atf::system_error("sigusr1::program",
+ "sigaction(2) failed", errno);
+ }
+} // namespace sigusr1
+
+namespace sigusr1_2 {
+ static bool happened = false;
+
+ static
+ void
+ handler(int signo)
+ {
+ happened = true;
+ }
+} // namespace sigusr1_2
+
+// ------------------------------------------------------------------------
+// Tests for the "signal_holder" class.
+// ------------------------------------------------------------------------
+
+ATF_TEST_CASE(signal_holder_preserve);
+ATF_TEST_CASE_HEAD(signal_holder_preserve)
+{
+ set_md_var("descr", "Tests that signal_holder preserves the original "
+ "signal handler and restores it upon destruction");
+}
+ATF_TEST_CASE_BODY(signal_holder_preserve)
+{
+ using atf::signals::signal_holder;
+
+ sigusr1::program();
+
+ sigusr1::happened = false;
+ ::kill(::getpid(), SIGUSR1);
+ ATF_CHECK(sigusr1::happened);
+
+ {
+ signal_holder hld(SIGUSR1);
+ ::kill(::getpid(), SIGUSR1);
+ }
+
+ sigusr1::happened = false;
+ ::kill(::getpid(), SIGUSR1);
+ ATF_CHECK(sigusr1::happened);
+}
+
+ATF_TEST_CASE(signal_holder_destructor);
+ATF_TEST_CASE_HEAD(signal_holder_destructor)
+{
+ set_md_var("descr", "Tests that signal_holder processes a pending "
+ "signal upon destruction");
+}
+ATF_TEST_CASE_BODY(signal_holder_destructor)
+{
+ using atf::signals::signal_holder;
+
+ sigusr1::program();
+
+ sigusr1::happened = false;
+ ::kill(::getpid(), SIGUSR1);
+ ATF_CHECK(sigusr1::happened);
+
+ {
+ signal_holder hld(SIGUSR1);
+
+ sigusr1::happened = false;
+ ::kill(::getpid(), SIGUSR1);
+ ATF_CHECK(!sigusr1::happened);
+ }
+ ATF_CHECK(sigusr1::happened);
+}
+
+ATF_TEST_CASE(signal_holder_process);
+ATF_TEST_CASE_HEAD(signal_holder_process)
+{
+ set_md_var("descr", "Tests that signal_holder's process method works "
+ "to process a delayed signal explicitly");
+}
+ATF_TEST_CASE_BODY(signal_holder_process)
+{
+ using atf::signals::signal_holder;
+
+ sigusr1::program();
+
+ sigusr1::happened = false;
+ ::kill(::getpid(), SIGUSR1);
+ ATF_CHECK(sigusr1::happened);
+
+ {
+ signal_holder hld(SIGUSR1);
+
+ sigusr1::happened = false;
+ ::kill(::getpid(), SIGUSR1);
+ ATF_CHECK(!sigusr1::happened);
+
+ hld.process();
+ ATF_CHECK(sigusr1::happened);
+
+ sigusr1::happened = false;
+ }
+ ATF_CHECK(!sigusr1::happened);
+}
+
+// ------------------------------------------------------------------------
+// Tests for the "signal_programmer" class.
+// ------------------------------------------------------------------------
+
+ATF_TEST_CASE(signal_programmer_program);
+ATF_TEST_CASE_HEAD(signal_programmer_program)
+{
+ set_md_var("descr", "Tests that signal_programmer correctly installs a "
+ "handler");
+}
+ATF_TEST_CASE_BODY(signal_programmer_program)
+{
+ using atf::signals::signal_programmer;
+
+ signal_programmer sp(SIGUSR1, sigusr1_2::handler);
+
+ sigusr1_2::happened = false;
+ ::kill(::getpid(), SIGUSR1);
+ ATF_CHECK(sigusr1_2::happened);
+}
+
+ATF_TEST_CASE(signal_programmer_preserve);
+ATF_TEST_CASE_HEAD(signal_programmer_preserve)
+{
+ set_md_var("descr", "Tests that signal_programmer uninstalls the "
+ "handler during destruction");
+}
+ATF_TEST_CASE_BODY(signal_programmer_preserve)
+{
+ using atf::signals::signal_programmer;
+
+ sigusr1::program();
+ sigusr1::happened = false;
+
+ {
+ signal_programmer sp(SIGUSR1, sigusr1_2::handler);
+
+ sigusr1_2::happened = false;
+ ::kill(::getpid(), SIGUSR1);
+ ATF_CHECK(sigusr1_2::happened);
+ }
+
+ ATF_CHECK(!sigusr1::happened);
+ ::kill(::getpid(), SIGUSR1);
+ ATF_CHECK(sigusr1::happened);
+}
+
+// ------------------------------------------------------------------------
+// Tests cases for the free functions.
+// ------------------------------------------------------------------------
+
+static
+void
+reset_child(void *v)
+{
+ sigusr1::program();
+
+ sigusr1::happened = false;
+ atf::signals::reset(SIGUSR1);
+ kill(::getpid(), SIGUSR1);
+
+ if (sigusr1::happened) {
+ std::cerr << "Signal was not resetted correctly" << std::endl;
+ abort();
+ } else {
+ exit(EXIT_SUCCESS);
+ }
+}
+
+ATF_TEST_CASE(reset);
+ATF_TEST_CASE_HEAD(reset)
+{
+ set_md_var("descr", "Tests the reset function");
+}
+ATF_TEST_CASE_BODY(reset)
+{
+ atf::process::child c =
+ atf::process::fork(reset_child, atf::process::stream_inherit(),
+ atf::process::stream_inherit(), NULL);
+
+ const atf::process::status s = c.wait();
+ ATF_CHECK(s.exited() || s.signaled());
+ ATF_CHECK(!s.signaled() || s.termsig() == SIGUSR1);
+}
+
+// ------------------------------------------------------------------------
+// Tests cases for the header file.
+// ------------------------------------------------------------------------
+
+HEADER_TC(include, "atf-c++/signals.hpp");
+
+// ------------------------------------------------------------------------
+// Main.
+// ------------------------------------------------------------------------
+
+ATF_INIT_TEST_CASES(tcs)
+{
+ // Add the tests for the "signal_holder" class.
+ ATF_ADD_TEST_CASE(tcs, signal_holder_preserve);
+ ATF_ADD_TEST_CASE(tcs, signal_holder_destructor);
+ ATF_ADD_TEST_CASE(tcs, signal_holder_process);
+
+ // Add the tests for the "signal_programmer" class.
+ ATF_ADD_TEST_CASE(tcs, signal_programmer_program);
+ ATF_ADD_TEST_CASE(tcs, signal_programmer_preserve);
+
+ // Add the test cases for the free functions.
+ ATF_ADD_TEST_CASE(tcs, reset);
+
+ // Add the test cases for the header file.
+ ATF_ADD_TEST_CASE(tcs, include);
+}
diff --git a/external/bsd/atf/dist/atf-c++/test_helpers.cpp b/external/bsd/atf/dist/atf-c++/test_helpers.cpp
new file mode 100644
index 00000000000..47e3f1d90fb
--- /dev/null
+++ b/external/bsd/atf/dist/atf-c++/test_helpers.cpp
@@ -0,0 +1,122 @@
+//
+// Automated Testing Framework (atf)
+//
+// Copyright (c) 2009, 2010 The NetBSD Foundation, Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
+// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+extern "C" {
+#include <regex.h>
+}
+
+#include <fstream>
+#include <iostream>
+#include <string>
+#include <vector>
+
+#include "atf-c++/check.hpp"
+#include "atf-c++/config.hpp"
+#include "atf-c++/fs.hpp"
+#include "atf-c++/macros.hpp"
+#include "atf-c++/process.hpp"
+
+#include "test_helpers.hpp"
+
+void
+build_check_cxx_o_aux(const atf::fs::path& sfile, const char* failmsg)
+{
+ std::vector< std::string > optargs;
+ optargs.push_back("-I" + atf::config::get("atf_includedir"));
+
+ if (!atf::check::build_cxx_o(sfile, atf::fs::path("test.o"),
+ atf::process::argv_array(optargs)))
+ ATF_FAIL(failmsg);
+}
+
+void
+build_check_cxx_o(const atf::tests::tc& tc, const char* sfile,
+ const char* failmsg)
+{
+ const atf::fs::path sfilepath =
+ atf::fs::path(tc.get_config_var("srcdir")) / sfile;
+ build_check_cxx_o_aux(sfilepath, failmsg);
+}
+
+void
+header_check(const atf::tests::tc& tc, const char *hdrname)
+{
+ std::ofstream srcfile("test.c");
+ ATF_CHECK(srcfile);
+ srcfile << "#include <" << hdrname << ">\n";
+ srcfile.close();
+
+ 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());
+}
+
+atf::fs::path
+get_process_helpers_path(const atf::tests::tc& tc)
+{
+ return atf::fs::path(tc.get_config_var("srcdir")) /
+ ".." / "atf-c" / "process_helpers";
+}
+
+bool
+grep_file(const char* name, const char* regex)
+{
+ std::ifstream is(name);
+ ATF_CHECK(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_CHECK(::regcomp(&preg, regex, REG_EXTENDED) == 0);
+
+ res = ::regexec(&preg, str.c_str(), 0, NULL, 0);
+ ATF_CHECK(res == 0 || res == REG_NOMATCH);
+
+ ::regfree(&preg);
+
+ return res == 0;
+}
diff --git a/external/bsd/atf/dist/atf-c++/test_helpers.hpp b/external/bsd/atf/dist/atf-c++/test_helpers.hpp
new file mode 100644
index 00000000000..3c16c6f55f5
--- /dev/null
+++ b/external/bsd/atf/dist/atf-c++/test_helpers.hpp
@@ -0,0 +1,187 @@
+//
+// Automated Testing Framework (atf)
+//
+// Copyright (c) 2009, 2010 The NetBSD Foundation, Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
+// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#if defined(TESTS_ATF_ATF_CXX_TEST_HELPERS_H)
+# error "Cannot include test_helpers.hpp more than once."
+#else
+# define TESTS_ATF_ATF_CXX_TEST_HELPERS_H
+#endif
+
+#include <cstdlib>
+#include <iostream>
+#include <sstream>
+#include <utility>
+
+#include "atf-c++/parser.hpp"
+#include "atf-c++/process.hpp"
+#include "atf-c++/text.hpp"
+
+#define HEADER_TC(name, hdrname) \
+ ATF_TEST_CASE(name); \
+ ATF_TEST_CASE_HEAD(name) \
+ { \
+ set_md_var("descr", "Tests that the " hdrname " file can be " \
+ "included on its own, without any prerequisites"); \
+ set_md_var("use.fs", "true"); \
+ } \
+ ATF_TEST_CASE_BODY(name) \
+ { \
+ header_check(*this, hdrname); \
+ }
+
+#define BUILD_TC(name, sfile, descr, failmsg) \
+ ATF_TEST_CASE(name); \
+ ATF_TEST_CASE_HEAD(name) \
+ { \
+ set_md_var("descr", descr); \
+ set_md_var("use.fs", "true"); \
+ } \
+ ATF_TEST_CASE_BODY(name) \
+ { \
+ build_check_cxx_o(*this, sfile, failmsg); \
+ }
+
+namespace atf {
+namespace tests {
+class tc;
+}
+}
+
+void header_check(const atf::tests::tc&, const char*);
+void build_check_cxx_o(const atf::tests::tc&, const char*, const char*);
+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;
+
+ run_h_tc_data(const atf::tests::vars_map& config) :
+ m_config(config) {}
+};
+
+template< class TestCase >
+void
+run_h_tc_child(void* v)
+{
+ run_h_tc_data* data = static_cast< run_h_tc_data* >(v);
+
+ TestCase tc;
+ tc.init(data->m_config);
+ tc.run(atf::fs::path("result"));
+ std::exit(EXIT_SUCCESS);
+}
+
+template< class TestCase >
+void
+run_h_tc(atf::tests::vars_map config = atf::tests::vars_map())
+{
+ run_h_tc_data data(config);
+ atf::process::child c = atf::process::fork(
+ run_h_tc_child< TestCase >,
+ atf::process::stream_redirect_path(atf::fs::path("stdout")),
+ atf::process::stream_redirect_path(atf::fs::path("stderr")),
+ &data);
+ const atf::process::status s = c.wait();
+ ATF_CHECK(s.exited());
+}
+
+namespace test_helpers_detail {
+
+typedef std::vector< std::string > string_vector;
+
+template< class Reader >
+std::pair< string_vector, string_vector >
+do_read(const char* input)
+{
+ string_vector errors;
+
+ std::istringstream is(input);
+ Reader reader(is);
+ try {
+ reader.read();
+ } catch (const atf::parser::parse_errors& pes) {
+ for (std::vector< atf::parser::parse_error >::const_iterator iter =
+ pes.begin(); iter != pes.end(); iter++)
+ errors.push_back(*iter);
+ } catch (const atf::parser::parse_error& pe) {
+ ATF_FAIL("Raised a lonely parse error: " +
+ atf::text::to_string(pe.first) + ": " + pe.second);
+ }
+
+ return std::make_pair(reader.m_calls, errors);
+}
+
+static
+void
+check_equal(const char* expected[], const string_vector& actual)
+{
+ const char** expected_iter = expected;
+ string_vector::const_iterator actual_iter = actual.begin();
+
+ bool equals = true;
+ while (equals && *expected_iter != NULL && actual_iter != actual.end()) {
+ if (*expected_iter != *actual_iter) {
+ equals = false;
+ } else {
+ expected_iter++;
+ actual_iter++;
+ }
+ }
+ if (equals && ((*expected_iter == NULL && actual_iter != actual.end()) ||
+ (*expected_iter != NULL && actual_iter == actual.end())))
+ equals = false;
+
+ if (!equals) {
+ std::cerr << "EXPECTED:\n";
+ for (expected_iter = expected; *expected_iter != NULL; expected_iter++)
+ std::cerr << *expected_iter << "\n";
+
+ std::cerr << "ACTUAL:\n";
+ for (actual_iter = actual.begin(); actual_iter != actual.end();
+ actual_iter++)
+ std::cerr << *actual_iter << "\n";
+
+ ATF_FAIL("Expected results differ to actual values");
+ }
+}
+
+} // namespace test_helpers_detail
+
+template< class Reader >
+void
+do_parser_test(const char* input, const char* exp_calls[],
+ const char* exp_errors[])
+{
+ const std::pair< test_helpers_detail::string_vector,
+ test_helpers_detail::string_vector >
+ actual = test_helpers_detail::do_read< Reader >(input);
+ test_helpers_detail::check_equal(exp_calls, actual.first);
+ test_helpers_detail::check_equal(exp_errors, actual.second);
+}
diff --git a/external/bsd/atf/dist/atf-c++/tests_test.cpp b/external/bsd/atf/dist/atf-c++/tests_test.cpp
new file mode 100644
index 00000000000..29258a10c11
--- /dev/null
+++ b/external/bsd/atf/dist/atf-c++/tests_test.cpp
@@ -0,0 +1,207 @@
+//
+// Automated Testing Framework (atf)
+//
+// Copyright (c) 2007, 2008, 2009, 2010 The NetBSD Foundation, Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
+// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+extern "C" {
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <fcntl.h>
+#include <unistd.h>
+}
+
+#include <fstream>
+#include <sstream>
+
+#include <atf-c++.hpp>
+
+#include "atf-c++/parser.hpp"
+#include "atf-c++/user.hpp"
+
+#include "test_helpers.hpp"
+
+// ------------------------------------------------------------------------
+// Tests for the "atf_tp_writer" class.
+// ------------------------------------------------------------------------
+
+static
+void
+print_indented(const std::string& str)
+{
+ std::vector< std::string > ws = atf::text::split(str, "\n");
+ for (std::vector< std::string >::const_iterator iter = ws.begin();
+ iter != ws.end(); iter++)
+ std::cout << ">>" << *iter << "<<" << std::endl;
+}
+
+// XXX Should this string handling and verbosity level be part of the
+// ATF_CHECK_EQUAL macro? It may be hard to predict sometimes that a
+// string can have newlines in it, and so the error message generated
+// at the moment will be bogus if there are some.
+static
+void
+check_equal(const std::string& str, const std::string& exp)
+{
+ if (str != exp) {
+ std::cout << "String equality check failed." << std::endl
+ << "Adding >> and << to delimit the string boundaries "
+ "below." << std::endl;
+ std::cout << "GOT:" << std::endl;
+ print_indented(str);
+ std::cout << "EXPECTED:" << std::endl;
+ print_indented(exp);
+ atf_tc_fail("Constructed string differs from the expected one");
+ }
+}
+
+ATF_TEST_CASE(atf_tp_writer);
+ATF_TEST_CASE_HEAD(atf_tp_writer)
+{
+ set_md_var("descr", "Verifies the application/X-atf-tp writer");
+}
+ATF_TEST_CASE_BODY(atf_tp_writer)
+{
+ std::ostringstream expss;
+ std::ostringstream ss;
+
+#define RESET \
+ expss.str(""); \
+ ss.str("")
+
+#define CHECK \
+ check_equal(ss.str(), expss.str())
+
+ {
+ RESET;
+
+ atf::tests::detail::atf_tp_writer w(ss);
+ expss << "Content-Type: application/X-atf-tp; version=\"1\""
+ << std::endl << std::endl;
+ CHECK;
+ }
+
+ {
+ RESET;
+
+ atf::tests::detail::atf_tp_writer w(ss);
+ expss << "Content-Type: application/X-atf-tp; version=\"1\""
+ << std::endl << std::endl;
+ CHECK;
+
+ w.start_tc("test1");
+ expss << "ident: test1" << std::endl;
+ CHECK;
+
+ w.end_tc();
+ CHECK;
+ }
+
+ {
+ RESET;
+
+ atf::tests::detail::atf_tp_writer w(ss);
+ expss << "Content-Type: application/X-atf-tp; version=\"1\""
+ << std::endl << std::endl;
+ CHECK;
+
+ w.start_tc("test1");
+ expss << "ident: test1" << std::endl;
+ CHECK;
+
+ w.end_tc();
+ CHECK;
+
+ w.start_tc("test2");
+ expss << std::endl << "ident: test2" << std::endl;
+ CHECK;
+
+ w.end_tc();
+ CHECK;
+ }
+
+ {
+ RESET;
+
+ atf::tests::detail::atf_tp_writer w(ss);
+ expss << "Content-Type: application/X-atf-tp; version=\"1\""
+ << std::endl << std::endl;
+ CHECK;
+
+ w.start_tc("test1");
+ expss << "ident: test1" << std::endl;
+ CHECK;
+
+ w.tc_meta_data("descr", "the description");
+ expss << "descr: the description" << std::endl;
+ CHECK;
+
+ w.end_tc();
+ CHECK;
+
+ w.start_tc("test2");
+ expss << std::endl << "ident: test2" << std::endl;
+ CHECK;
+
+ w.tc_meta_data("descr", "second test case");
+ expss << "descr: second test case" << std::endl;
+ CHECK;
+
+ w.tc_meta_data("require.progs", "/bin/cp");
+ expss << "require.progs: /bin/cp" << std::endl;
+ CHECK;
+
+ w.tc_meta_data("X-custom", "foo bar baz");
+ expss << "X-custom: foo bar baz" << std::endl;
+ CHECK;
+
+ w.end_tc();
+ CHECK;
+ }
+
+#undef CHECK
+#undef RESET
+}
+
+// ------------------------------------------------------------------------
+// Tests cases for the header file.
+// ------------------------------------------------------------------------
+
+HEADER_TC(include, "atf-c++/tests.hpp");
+
+// ------------------------------------------------------------------------
+// Main.
+// ------------------------------------------------------------------------
+
+ATF_INIT_TEST_CASES(tcs)
+{
+ // Add tests for the "atf_tp_writer" class.
+ ATF_ADD_TEST_CASE(tcs, atf_tp_writer);
+
+ // Add the test cases for the header file.
+ ATF_ADD_TEST_CASE(tcs, include);
+}
diff --git a/external/bsd/atf/dist/atf-c++/text_test.cpp b/external/bsd/atf/dist/atf-c++/text_test.cpp
new file mode 100644
index 00000000000..31ca6d0568e
--- /dev/null
+++ b/external/bsd/atf/dist/atf-c++/text_test.cpp
@@ -0,0 +1,375 @@
+//
+// Automated Testing Framework (atf)
+//
+// Copyright (c) 2007, 2008, 2009, 2010 The NetBSD Foundation, Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
+// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#include <cstring>
+#include <set>
+#include <vector>
+
+#include "atf-c++/macros.hpp"
+#include "atf-c++/text.hpp"
+
+#include "test_helpers.hpp"
+
+// ------------------------------------------------------------------------
+// Test cases for the free functions.
+// ------------------------------------------------------------------------
+
+ATF_TEST_CASE(duplicate);
+ATF_TEST_CASE_HEAD(duplicate)
+{
+ set_md_var("descr", "Tests the duplicate function");
+}
+ATF_TEST_CASE_BODY(duplicate)
+{
+ using atf::text::duplicate;
+
+ const char* orig = "foo";
+
+ char* copy = duplicate(orig);
+ ATF_CHECK_EQUAL(std::strlen(copy), 3);
+ ATF_CHECK(std::strcmp(copy, "foo") == 0);
+
+ std::strcpy(copy, "bar");
+ ATF_CHECK(std::strcmp(copy, "bar") == 0);
+ ATF_CHECK(std::strcmp(orig, "foo") == 0);
+}
+
+ATF_TEST_CASE(join);
+ATF_TEST_CASE_HEAD(join)
+{
+ set_md_var("descr", "Tests the join function");
+}
+ATF_TEST_CASE_BODY(join)
+{
+ using atf::text::join;
+
+ // First set of tests using a non-sorted collection, std::vector.
+ {
+ std::vector< std::string > words;
+ std::string str;
+
+ words.clear();
+ str = join(words, ",");
+ ATF_CHECK_EQUAL(str, "");
+
+ words.clear();
+ words.push_back("");
+ str = join(words, ",");
+ ATF_CHECK_EQUAL(str, "");
+
+ words.clear();
+ words.push_back("");
+ words.push_back("");
+ str = join(words, ",");
+ ATF_CHECK_EQUAL(str, ",");
+
+ words.clear();
+ words.push_back("foo");
+ words.push_back("");
+ words.push_back("baz");
+ str = join(words, ",");
+ ATF_CHECK_EQUAL(str, "foo,,baz");
+
+ words.clear();
+ words.push_back("foo");
+ words.push_back("bar");
+ words.push_back("baz");
+ str = join(words, ",");
+ ATF_CHECK_EQUAL(str, "foo,bar,baz");
+ }
+
+ // Second set of tests using a sorted collection, std::set.
+ {
+ std::set< std::string > words;
+ std::string str;
+
+ words.clear();
+ str = join(words, ",");
+ ATF_CHECK_EQUAL(str, "");
+
+ words.clear();
+ words.insert("");
+ str = join(words, ",");
+ ATF_CHECK_EQUAL(str, "");
+
+ words.clear();
+ words.insert("foo");
+ words.insert("");
+ words.insert("baz");
+ str = join(words, ",");
+ ATF_CHECK_EQUAL(str, ",baz,foo");
+
+ words.clear();
+ words.insert("foo");
+ words.insert("bar");
+ words.insert("baz");
+ str = join(words, ",");
+ ATF_CHECK_EQUAL(str, "bar,baz,foo");
+ }
+}
+
+ATF_TEST_CASE(match);
+ATF_TEST_CASE_HEAD(match)
+{
+ set_md_var("descr", "Tests the match function");
+}
+ATF_TEST_CASE_BODY(match)
+{
+ using atf::text::match;
+
+ ATF_CHECK_THROW(std::runtime_error, match("", "["));
+
+ ATF_CHECK(match("", ""));
+ ATF_CHECK(!match("foo", ""));
+
+ ATF_CHECK(match("", ".*"));
+ ATF_CHECK(match("", "[a-z]*"));
+
+ ATF_CHECK(match("hello", "hello"));
+ ATF_CHECK(match("hello", "[a-z]+"));
+ ATF_CHECK(match("hello", "^[a-z]+$"));
+
+ ATF_CHECK(!match("hello", "helooo"));
+ ATF_CHECK(!match("hello", "[a-z]+5"));
+ ATF_CHECK(!match("hello", "^ [a-z]+$"));
+}
+
+ATF_TEST_CASE(split);
+ATF_TEST_CASE_HEAD(split)
+{
+ set_md_var("descr", "Tests the split function");
+}
+ATF_TEST_CASE_BODY(split)
+{
+ using atf::text::split;
+
+ std::vector< std::string > words;
+
+ words = split("", " ");
+ ATF_CHECK_EQUAL(words.size(), 0);
+
+ words = split(" ", " ");
+ ATF_CHECK_EQUAL(words.size(), 0);
+
+ words = split(" ", " ");
+ ATF_CHECK_EQUAL(words.size(), 0);
+
+ words = split("a b", " ");
+ ATF_CHECK_EQUAL(words.size(), 2);
+ ATF_CHECK_EQUAL(words[0], "a");
+ ATF_CHECK_EQUAL(words[1], "b");
+
+ words = split("a b c d", " ");
+ ATF_CHECK_EQUAL(words.size(), 4);
+ ATF_CHECK_EQUAL(words[0], "a");
+ ATF_CHECK_EQUAL(words[1], "b");
+ ATF_CHECK_EQUAL(words[2], "c");
+ ATF_CHECK_EQUAL(words[3], "d");
+
+ words = split("foo bar", " ");
+ ATF_CHECK_EQUAL(words.size(), 2);
+ ATF_CHECK_EQUAL(words[0], "foo");
+ ATF_CHECK_EQUAL(words[1], "bar");
+
+ words = split("foo bar baz foobar", " ");
+ ATF_CHECK_EQUAL(words.size(), 4);
+ ATF_CHECK_EQUAL(words[0], "foo");
+ ATF_CHECK_EQUAL(words[1], "bar");
+ ATF_CHECK_EQUAL(words[2], "baz");
+ ATF_CHECK_EQUAL(words[3], "foobar");
+
+ words = split(" foo bar", " ");
+ ATF_CHECK_EQUAL(words.size(), 2);
+ ATF_CHECK_EQUAL(words[0], "foo");
+ ATF_CHECK_EQUAL(words[1], "bar");
+
+ words = split("foo bar", " ");
+ ATF_CHECK_EQUAL(words.size(), 2);
+ ATF_CHECK_EQUAL(words[0], "foo");
+ ATF_CHECK_EQUAL(words[1], "bar");
+
+ words = split("foo bar ", " ");
+ ATF_CHECK_EQUAL(words.size(), 2);
+ ATF_CHECK_EQUAL(words[0], "foo");
+ ATF_CHECK_EQUAL(words[1], "bar");
+
+ words = split(" foo bar ", " ");
+ ATF_CHECK_EQUAL(words.size(), 2);
+ ATF_CHECK_EQUAL(words[0], "foo");
+ ATF_CHECK_EQUAL(words[1], "bar");
+}
+
+ATF_TEST_CASE(split_delims);
+ATF_TEST_CASE_HEAD(split_delims)
+{
+ set_md_var("descr", "Tests the split function using different delimiters");
+}
+ATF_TEST_CASE_BODY(split_delims)
+{
+ using atf::text::split;
+
+ std::vector< std::string > words;
+
+ words = split("", "/");
+ ATF_CHECK_EQUAL(words.size(), 0);
+
+ words = split(" ", "/");
+ ATF_CHECK_EQUAL(words.size(), 1);
+ ATF_CHECK_EQUAL(words[0], " ");
+
+ words = split(" ", "/");
+ ATF_CHECK_EQUAL(words.size(), 1);
+ ATF_CHECK_EQUAL(words[0], " ");
+
+ words = split("a/b", "/");
+ ATF_CHECK_EQUAL(words.size(), 2);
+ ATF_CHECK_EQUAL(words[0], "a");
+ ATF_CHECK_EQUAL(words[1], "b");
+
+ words = split("aLONGDELIMbcdLONGDELIMef", "LONGDELIM");
+ ATF_CHECK_EQUAL(words.size(), 3);
+ ATF_CHECK_EQUAL(words[0], "a");
+ ATF_CHECK_EQUAL(words[1], "bcd");
+ ATF_CHECK_EQUAL(words[2], "ef");
+}
+
+ATF_TEST_CASE(trim);
+ATF_TEST_CASE_HEAD(trim)
+{
+ set_md_var("descr", "Tests the trim function");
+}
+ATF_TEST_CASE_BODY(trim)
+{
+ using atf::text::trim;
+
+ ATF_CHECK_EQUAL(trim(""), "");
+ ATF_CHECK_EQUAL(trim(" "), "");
+ ATF_CHECK_EQUAL(trim("\t"), "");
+
+ ATF_CHECK_EQUAL(trim(" foo"), "foo");
+ ATF_CHECK_EQUAL(trim("\t foo"), "foo");
+ ATF_CHECK_EQUAL(trim(" \tfoo"), "foo");
+ ATF_CHECK_EQUAL(trim("foo\t "), "foo");
+ ATF_CHECK_EQUAL(trim("foo \t"), "foo");
+
+ ATF_CHECK_EQUAL(trim("foo bar"), "foo bar");
+ ATF_CHECK_EQUAL(trim("\t foo bar"), "foo bar");
+ ATF_CHECK_EQUAL(trim(" \tfoo bar"), "foo bar");
+ ATF_CHECK_EQUAL(trim("foo bar\t "), "foo bar");
+ ATF_CHECK_EQUAL(trim("foo bar \t"), "foo bar");
+}
+
+ATF_TEST_CASE(to_bool);
+ATF_TEST_CASE_HEAD(to_bool)
+{
+ set_md_var("descr", "Tests the to_string function");
+}
+ATF_TEST_CASE_BODY(to_bool)
+{
+ using atf::text::to_bool;
+
+ ATF_CHECK(to_bool("true"));
+ ATF_CHECK(to_bool("TRUE"));
+ ATF_CHECK(to_bool("yes"));
+ ATF_CHECK(to_bool("YES"));
+
+ ATF_CHECK(!to_bool("false"));
+ ATF_CHECK(!to_bool("FALSE"));
+ ATF_CHECK(!to_bool("no"));
+ ATF_CHECK(!to_bool("NO"));
+
+ ATF_CHECK_THROW(std::runtime_error, to_bool(""));
+ ATF_CHECK_THROW(std::runtime_error, to_bool("tru"));
+ ATF_CHECK_THROW(std::runtime_error, to_bool("true2"));
+ ATF_CHECK_THROW(std::runtime_error, to_bool("fals"));
+ ATF_CHECK_THROW(std::runtime_error, to_bool("false2"));
+}
+
+ATF_TEST_CASE(to_string);
+ATF_TEST_CASE_HEAD(to_string)
+{
+ set_md_var("descr", "Tests the to_string function");
+}
+ATF_TEST_CASE_BODY(to_string)
+{
+ using atf::text::to_string;
+
+ ATF_CHECK_EQUAL(to_string('a'), "a");
+ ATF_CHECK_EQUAL(to_string("a"), "a");
+ ATF_CHECK_EQUAL(to_string(5), "5");
+}
+
+ATF_TEST_CASE(to_type);
+ATF_TEST_CASE_HEAD(to_type)
+{
+ set_md_var("descr", "Tests the to_type function");
+}
+ATF_TEST_CASE_BODY(to_type)
+{
+ using atf::text::to_type;
+
+ ATF_CHECK_EQUAL(to_type< int >("0"), 0);
+ ATF_CHECK_EQUAL(to_type< int >("1234"), 1234);
+ ATF_CHECK_THROW(std::runtime_error, to_type< int >("0 a"));
+ ATF_CHECK_THROW(std::runtime_error, to_type< int >("a"));
+
+ ATF_CHECK_EQUAL(to_type< float >("0.5"), 0.5);
+ ATF_CHECK_EQUAL(to_type< float >("1234.5"), 1234.5);
+ ATF_CHECK_THROW(std::runtime_error, to_type< float >("0.5 a"));
+ ATF_CHECK_THROW(std::runtime_error, to_type< float >("a"));
+
+ ATF_CHECK_EQUAL(to_type< std::string >("a"), "a");
+}
+
+// ------------------------------------------------------------------------
+// Tests cases for the header file.
+// ------------------------------------------------------------------------
+
+HEADER_TC(include, "atf-c++/text.hpp");
+
+// ------------------------------------------------------------------------
+// Main.
+// ------------------------------------------------------------------------
+
+ATF_INIT_TEST_CASES(tcs)
+{
+ // Add the test cases for the free functions.
+ ATF_ADD_TEST_CASE(tcs, duplicate);
+ ATF_ADD_TEST_CASE(tcs, join);
+ ATF_ADD_TEST_CASE(tcs, match);
+ ATF_ADD_TEST_CASE(tcs, split);
+ 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_string);
+ ATF_ADD_TEST_CASE(tcs, to_type);
+
+ // Add the test cases for the header file.
+ ATF_ADD_TEST_CASE(tcs, include);
+}
diff --git a/external/bsd/atf/dist/atf-c++/ui.cpp b/external/bsd/atf/dist/atf-c++/ui.cpp
index d7d3c86353a..7797092f088 100644
--- a/external/bsd/atf/dist/atf-c++/ui.cpp
+++ b/external/bsd/atf/dist/atf-c++/ui.cpp
@@ -1,7 +1,7 @@
//
// Automated Testing Framework (atf)
//
-// Copyright (c) 2007, 2008 The NetBSD Foundation, Inc.
+// Copyright (c) 2007, 2008, 2010 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@@ -27,23 +27,98 @@
// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
-#include <sstream>
-
extern "C" {
-#include "atf-c/dynstr.h"
-#include "atf-c/error.h"
-#include "atf-c/ui.h"
+#include <sys/ioctl.h>
+
+#include <termios.h>
}
+#include <sstream>
+
#include "atf-c++/env.hpp"
-#include "atf-c++/exceptions.hpp"
#include "atf-c++/text.hpp"
#include "atf-c++/sanity.hpp"
+#include "atf-c++/text.hpp"
#include "atf-c++/ui.hpp"
namespace impl = atf::ui;
#define IMPL_NAME "atf::ui"
+static
+size_t
+terminal_width(void)
+{
+ static bool done = false;
+ static size_t width = 0;
+
+ if (!done) {
+ if (atf::env::has("COLUMNS")) {
+ const std::string cols = atf::env::get("COLUMNS");
+ if (cols.length() > 0) {
+ width = atf::text::to_type< size_t >(cols);
+ }
+ } else {
+ struct winsize ws;
+ if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) != -1)
+ width = ws.ws_col;
+ }
+
+ if (width >= 80)
+ width -= 5;
+
+ done = true;
+ }
+
+ return width;
+}
+
+static
+std::string
+format_paragraph(const std::string& text,
+ const std::string& tag,
+ const bool first,
+ const bool repeat,
+ const size_t col)
+{
+ PRE(text.find('\n') == std::string::npos);
+
+ const std::string pad(col - tag.length(), ' ');
+ const std::string fullpad(col, ' ');
+
+ std::string formatted;
+ if (first || repeat)
+ formatted = tag + pad;
+ else
+ formatted = fullpad;
+ INV(formatted.length() == col);
+ size_t curcol = col;
+
+ const size_t maxcol = terminal_width();
+
+ std::vector< std::string > words = atf::text::split(text, " ");
+ for (std::vector< std::string >::const_iterator iter = words.begin();
+ iter != words.end(); iter++) {
+ const std::string& word = *iter;
+
+ if (iter != words.begin() && maxcol > 0 &&
+ curcol + word.length() + 1 > maxcol) {
+ if (repeat)
+ formatted += '\n' + tag + pad;
+ else
+ formatted += '\n' + fullpad;
+ curcol = col;
+ } else if (iter != words.begin()) {
+ formatted += ' ';
+ curcol++;
+ }
+
+ formatted += word;
+ curcol += word.length();
+ }
+
+ return formatted;
+}
+
std::string
impl::format_error(const std::string& prog_name, const std::string& error)
{
@@ -66,26 +141,28 @@ std::string
impl::format_text_with_tag(const std::string& text, const std::string& tag,
bool repeat, size_t col)
{
- atf_dynstr_t dest;
- atf_error_t err;
-
- err = atf_dynstr_init(&dest);
- if (atf_is_error(err))
- throw_atf_error(err);
-
- try {
- err = atf_ui_format_fmt(&dest, tag.c_str(), repeat, col, "%s",
- text.c_str());
- if (atf_is_error(err))
- throw_atf_error(err);
-
- std::string formatted(atf_dynstr_cstring(&dest));
- atf_dynstr_fini(&dest);
- return formatted;
- } catch (...) {
- atf_dynstr_fini(&dest);
- throw;
+ PRE(col == 0 || col >= tag.length());
+ if (col == 0)
+ col = tag.length();
+
+ std::string formatted;
+
+ std::vector< std::string > lines = atf::text::split(text, "\n");
+ for (std::vector< std::string >::const_iterator iter = lines.begin();
+ iter != lines.end(); iter++) {
+ const std::string& line = *iter;
+
+ formatted += format_paragraph(line, tag, iter == lines.begin(),
+ repeat, col);
+ if (iter + 1 != lines.end()) {
+ if (repeat)
+ formatted += "\n" + tag + "\n";
+ else
+ formatted += "\n\n";
+ }
}
+
+ return formatted;
}
std::string
diff --git a/external/bsd/atf/dist/atf-c++/ui_test.cpp b/external/bsd/atf/dist/atf-c++/ui_test.cpp
new file mode 100644
index 00000000000..53a102303e7
--- /dev/null
+++ b/external/bsd/atf/dist/atf-c++/ui_test.cpp
@@ -0,0 +1,471 @@
+//
+// Automated Testing Framework (atf)
+//
+// Copyright (c) 2009 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 <cstring>
+
+#include "atf-c++/env.hpp"
+#include "atf-c++/macros.hpp"
+#include "atf-c++/ui.hpp"
+
+#include "test_helpers.hpp"
+
+// ------------------------------------------------------------------------
+// Test cases for the free functions.
+// ------------------------------------------------------------------------
+
+struct test {
+ const char *tc;
+ const char *tag;
+ bool repeat;
+ size_t col;
+ const char *fmt;
+ const char *result;
+} tests[] = {
+ //
+ // wo_tag
+ //
+
+ {
+ "wo_tag",
+ "",
+ false,
+ 0,
+ "12345",
+ "12345",
+ },
+
+ {
+ "wo_tag",
+ "",
+ false,
+ 0,
+ "12345 ",
+ "12345",
+ },
+
+ {
+ "wo_tag",
+ "",
+ false,
+ 0,
+ "12345 7890",
+ "12345 7890",
+ },
+
+ {
+ "wo_tag",
+ "",
+ false,
+ 0,
+ "12345 789012 45",
+ "12345 789012 45",
+ },
+
+ {
+ "wo_tag",
+ "",
+ false,
+ 0,
+ "12345 789012 456",
+ "12345 789012\n456",
+ },
+
+ {
+ "wo_tag",
+ "",
+ false,
+ 0,
+ "1234567890123456",
+ "1234567890123456",
+ },
+
+ // TODO(jmmv): Fix the code to pass this test...
+// {
+// "wo_tag",
+// "",
+// false,
+// 0,
+// " 2345678901234567",
+// "\n2345678901234567",
+// },
+
+ {
+ "wo_tag",
+ "",
+ false,
+ 0,
+ "12345 789012345 78",
+ "12345 789012345\n78",
+ },
+
+ //
+ // wo_tag_col
+ //
+
+ {
+ "wo_tag_col",
+ "",
+ false,
+ 10,
+ "12345",
+ " 12345",
+ },
+
+ {
+ "wo_tag_col",
+ "",
+ false,
+ 10,
+ "12345 7890",
+ " 12345\n"
+ " 7890",
+ },
+
+ {
+ "wo_tag_col",
+ "",
+ false,
+ 10,
+ "1 3 5 7 9",
+ " 1 3 5\n"
+ " 7 9",
+ },
+
+ //
+ // w_tag_no_repeat
+ //
+
+ {
+ "w_tag_no_repeat",
+ "1234: ",
+ false,
+ 0,
+ "789012345",
+ "1234: 789012345",
+ },
+
+ {
+ "w_tag_no_repeat",
+ "1234: ",
+ false,
+ 0,
+ "789 1234 56789",
+ "1234: 789 1234\n"
+ " 56789",
+ },
+
+ {
+ "w_tag_no_repeat",
+ "1234: ",
+ false,
+ 0,
+ "789012345",
+ "1234: 789012345",
+ },
+
+ {
+ "w_tag_no_repeat",
+ "1234: ",
+ false,
+ 0,
+ "789012345 7890",
+ "1234: 789012345\n"
+ " 7890",
+ },
+
+ //
+ // w_tag_repeat
+ //
+
+ {
+ "w_tag_repeat",
+ "1234: ",
+ true,
+ 0,
+ "789012345",
+ "1234: 789012345",
+ },
+
+ {
+ "w_tag_repeat",
+ "1234: ",
+ true,
+ 0,
+ "789 1234 56789",
+ "1234: 789 1234\n"
+ "1234: 56789",
+ },
+
+ {
+ "w_tag_repeat",
+ "1234: ",
+ true,
+ 0,
+ "789012345",
+ "1234: 789012345",
+ },
+
+ {
+ "w_tag_no_repeat",
+ "1234: ",
+ true,
+ 0,
+ "789012345 7890",
+ "1234: 789012345\n"
+ "1234: 7890",
+ },
+
+ //
+ // w_tag_col
+ //
+
+ {
+ "w_tag_col",
+ "1234:",
+ false,
+ 10,
+ "1 3 5",
+ "1234: 1 3 5",
+ },
+
+ {
+ "w_tag_col",
+ "1234:",
+ false,
+ 10,
+ "1 3 5 7 9",
+ "1234: 1 3 5\n"
+ " 7 9",
+ },
+
+ {
+ "w_tag_col",
+ "1234:",
+ true,
+ 10,
+ "1 3 5 7 9",
+ "1234: 1 3 5\n"
+ "1234: 7 9",
+ },
+
+ //
+ // paragraphs
+ //
+
+ {
+ "paragraphs",
+ "",
+ false,
+ 0,
+ "1 3 5\n\n",
+ "1 3 5"
+ },
+
+ {
+ "paragraphs",
+ "",
+ false,
+ 0,
+ "1 3 5\n2 4 6",
+ "1 3 5\n\n2 4 6"
+ },
+
+ {
+ "paragraphs",
+ "",
+ false,
+ 0,
+ "1234 6789 123456\n2 4 6",
+ "1234 6789\n123456\n\n2 4 6"
+ },
+
+ {
+ "paragraphs",
+ "12: ",
+ false,
+ 0,
+ "56789 123456\n2 4 6",
+ "12: 56789\n 123456\n\n 2 4 6"
+ },
+
+ {
+ "paragraphs",
+ "12: ",
+ true,
+ 0,
+ "56789 123456\n2 4 6",
+ "12: 56789\n12: 123456\n12: \n12: 2 4 6"
+ },
+
+ {
+ "paragraphs",
+ "12:",
+ false,
+ 4,
+ "56789 123456\n2 4 6",
+ "12: 56789\n 123456\n\n 2 4 6"
+ },
+
+ {
+ "paragraphs",
+ "12:",
+ true,
+ 4,
+ "56789 123456\n2 4 6",
+ "12: 56789\n12: 123456\n12:\n12: 2 4 6"
+ },
+
+ //
+ // end
+ //
+
+ {
+ NULL,
+ NULL,
+ false,
+ 0,
+ NULL,
+ NULL,
+ },
+};
+
+static
+void
+run_tests(const char *tc)
+{
+ struct test *t;
+
+ std::cout << "Running tests for " << tc << "\n";
+
+ atf::env::set("COLUMNS", "15");
+
+ for (t = &tests[0]; t->tc != NULL; t++) {
+ if (std::strcmp(t->tc, tc) == 0) {
+ std::cout << "\n";
+ std::cout << "Testing with tag '" << t->tag << "', '"
+ << (t->repeat ? "repeat" : "no repeat") << "', col "
+ << t->col << "\n";
+ std::cout << "Input: >>>" << t->fmt << "<<<\n";
+ std::cout << "Expected output: >>>" << t->result << "<<<\n";
+
+ std::string result = atf::ui::format_text_with_tag(t->fmt, t->tag,
+ t->repeat, t->col);
+ std::cout << "Output : >>>" << result << "<<<\n";
+ ATF_CHECK_EQUAL(t->result, result);
+ }
+ }
+}
+
+ATF_TEST_CASE(wo_tag);
+ATF_TEST_CASE_HEAD(wo_tag)
+{
+ set_md_var("descr", "Checks formatting without tags");
+}
+ATF_TEST_CASE_BODY(wo_tag)
+{
+ run_tests("wo_tag");
+}
+
+ATF_TEST_CASE(wo_tag_col);
+ATF_TEST_CASE_HEAD(wo_tag_col)
+{
+ set_md_var("descr", "Checks formatting without tags and with a non-zero "
+ "starting column");
+}
+ATF_TEST_CASE_BODY(wo_tag_col)
+{
+ run_tests("wo_tag_col");
+}
+
+ATF_TEST_CASE(w_tag_no_repeat);
+ATF_TEST_CASE_HEAD(w_tag_no_repeat)
+{
+ set_md_var("descr", "Checks formatting with a tag");
+}
+ATF_TEST_CASE_BODY(w_tag_no_repeat)
+{
+ run_tests("w_tag_no_repeat");
+}
+
+ATF_TEST_CASE(w_tag_repeat);
+ATF_TEST_CASE_HEAD(w_tag_repeat)
+{
+ set_md_var("descr", "Checks formatting with a tag and repeating it on "
+ "each line");
+}
+ATF_TEST_CASE_BODY(w_tag_repeat)
+{
+ run_tests("w_tag_repeat");
+}
+
+ATF_TEST_CASE(w_tag_col);
+ATF_TEST_CASE_HEAD(w_tag_col)
+{
+ set_md_var("descr", "Checks formatting with a tag and starting at a "
+ "column greater than its length");
+}
+ATF_TEST_CASE_BODY(w_tag_col)
+{
+ run_tests("w_tag_col");
+}
+
+ATF_TEST_CASE(paragraphs);
+ATF_TEST_CASE_HEAD(paragraphs)
+{
+ set_md_var("descr", "Checks formatting a string that contains multiple "
+ "paragraphs");
+}
+ATF_TEST_CASE_BODY(paragraphs)
+{
+ run_tests("paragraphs");
+}
+
+// ------------------------------------------------------------------------
+// Tests cases for the header file.
+// ------------------------------------------------------------------------
+
+HEADER_TC(include, "atf-c++/ui.hpp");
+
+// ------------------------------------------------------------------------
+// Main.
+// ------------------------------------------------------------------------
+
+ATF_INIT_TEST_CASES(tcs)
+{
+ // Add the test cases for the free functions.
+ ATF_ADD_TEST_CASE(tcs, wo_tag);
+ ATF_ADD_TEST_CASE(tcs, wo_tag_col);
+ ATF_ADD_TEST_CASE(tcs, w_tag_no_repeat);
+ ATF_ADD_TEST_CASE(tcs, w_tag_repeat);
+ ATF_ADD_TEST_CASE(tcs, w_tag_col);
+ ATF_ADD_TEST_CASE(tcs, paragraphs);
+
+ // Add the test cases for the header file.
+ ATF_ADD_TEST_CASE(tcs, include);
+}
diff --git a/external/bsd/atf/dist/atf-c++/user_test.cpp b/external/bsd/atf/dist/atf-c++/user_test.cpp
new file mode 100644
index 00000000000..078a8e6613d
--- /dev/null
+++ b/external/bsd/atf/dist/atf-c++/user_test.cpp
@@ -0,0 +1,152 @@
+//
+// Automated Testing Framework (atf)
+//
+// Copyright (c) 2007, 2008, 2009 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/param.h>
+#include <sys/types.h>
+#include <limits.h>
+#include <unistd.h>
+}
+
+#include <iostream>
+#include <set>
+
+#include "atf-c++/exceptions.hpp"
+#include "atf-c++/macros.hpp"
+#include "atf-c++/user.hpp"
+
+#include "test_helpers.hpp"
+
+// ------------------------------------------------------------------------
+// Test cases for the free functions.
+// ------------------------------------------------------------------------
+
+ATF_TEST_CASE(euid);
+ATF_TEST_CASE_HEAD(euid)
+{
+ set_md_var("descr", "Tests the euid function");
+}
+ATF_TEST_CASE_BODY(euid)
+{
+ using atf::user::euid;
+
+ ATF_CHECK_EQUAL(euid(), ::geteuid());
+}
+
+ATF_TEST_CASE(is_member_of_group);
+ATF_TEST_CASE_HEAD(is_member_of_group)
+{
+ set_md_var("descr", "Tests the is_member_of_group function");
+}
+ATF_TEST_CASE_BODY(is_member_of_group)
+{
+ using atf::user::is_member_of_group;
+
+ std::set< gid_t > groups;
+ gid_t maxgid = 0;
+ {
+ gid_t gids[NGROUPS_MAX];
+ int ngids = ::getgroups(NGROUPS_MAX, gids);
+ if (ngids == -1)
+ ATF_FAIL("Call to ::getgroups failed");
+ for (int i = 0; i < ngids; i++) {
+ groups.insert(gids[i]);
+ if (gids[i] > maxgid)
+ maxgid = gids[i];
+ }
+ std::cout << "User belongs to " << ngids << " groups" << std::endl;
+ std::cout << "Last GID is " << maxgid << std::endl;
+ }
+
+ for (gid_t g = 0; g <= maxgid; g++) {
+ if (groups.find(g) == groups.end()) {
+ std::cout << "Checking if user does not belong to group "
+ << g << std::endl;
+ ATF_CHECK(!is_member_of_group(g));
+ } else {
+ std::cout << "Checking if user belongs to group "
+ << g << std::endl;
+ ATF_CHECK(is_member_of_group(g));
+ }
+ }
+}
+
+ATF_TEST_CASE(is_root);
+ATF_TEST_CASE_HEAD(is_root)
+{
+ set_md_var("descr", "Tests the is_root function");
+}
+ATF_TEST_CASE_BODY(is_root)
+{
+ using atf::user::is_root;
+
+ if (::geteuid() == 0) {
+ ATF_CHECK(is_root());
+ } else {
+ ATF_CHECK(!is_root());
+ }
+}
+
+ATF_TEST_CASE(is_unprivileged);
+ATF_TEST_CASE_HEAD(is_unprivileged)
+{
+ set_md_var("descr", "Tests the is_unprivileged function");
+}
+ATF_TEST_CASE_BODY(is_unprivileged)
+{
+ using atf::user::is_unprivileged;
+
+ if (::geteuid() != 0) {
+ ATF_CHECK(is_unprivileged());
+ } else {
+ ATF_CHECK(!is_unprivileged());
+ }
+}
+
+// ------------------------------------------------------------------------
+// Tests cases for the header file.
+// ------------------------------------------------------------------------
+
+HEADER_TC(include, "atf-c++/user.hpp");
+
+// ------------------------------------------------------------------------
+// Main.
+// ------------------------------------------------------------------------
+
+ATF_INIT_TEST_CASES(tcs)
+{
+ // Add the tests for the free functions.
+ ATF_ADD_TEST_CASE(tcs, euid);
+ ATF_ADD_TEST_CASE(tcs, is_member_of_group);
+ ATF_ADD_TEST_CASE(tcs, is_root);
+ ATF_ADD_TEST_CASE(tcs, is_unprivileged);
+
+ // Add the test cases for the header file.
+ ATF_ADD_TEST_CASE(tcs, include);
+}
diff --git a/external/bsd/atf/dist/atf-c++/utils_test.cpp b/external/bsd/atf/dist/atf-c++/utils_test.cpp
new file mode 100644
index 00000000000..ec8f5ef47ab
--- /dev/null
+++ b/external/bsd/atf/dist/atf-c++/utils_test.cpp
@@ -0,0 +1,308 @@
+//
+// Automated Testing Framework (atf)
+//
+// Copyright (c) 2007, 2008, 2009 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 <iostream>
+
+#include "atf-c++/macros.hpp"
+#include "atf-c++/utils.hpp"
+
+#include "test_helpers.hpp"
+
+// ------------------------------------------------------------------------
+// Tests for the "auto_array" class.
+// ------------------------------------------------------------------------
+
+class test_array {
+public:
+ int m_value;
+
+ static ssize_t m_nblocks;
+
+ static
+ atf::utils::auto_array< test_array >
+ do_copy(atf::utils::auto_array< test_array >& ta)
+ {
+ return atf::utils::auto_array< test_array >(ta);
+ }
+
+ void* operator new(size_t size)
+ {
+ 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 << std::endl;
+ return mem;
+ }
+
+ void operator delete(void* mem)
+ {
+ ATF_FAIL("Delete called but should have been delete[]");
+ }
+
+ void operator delete[](void* mem)
+ {
+ std::cout << "Releasing 'test_array' object " << mem << std::endl;
+ 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::utils::auto_array;
+
+ ATF_CHECK_EQUAL(test_array::m_nblocks, 0);
+ {
+ auto_array< test_array > t(new test_array[10]);
+ ATF_CHECK_EQUAL(test_array::m_nblocks, 1);
+ }
+ ATF_CHECK_EQUAL(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::utils::auto_array;
+
+ ATF_CHECK_EQUAL(test_array::m_nblocks, 0);
+ {
+ auto_array< test_array > t1(new test_array[10]);
+ ATF_CHECK_EQUAL(test_array::m_nblocks, 1);
+
+ {
+ auto_array< test_array > t2(t1);
+ ATF_CHECK_EQUAL(test_array::m_nblocks, 1);
+ }
+ ATF_CHECK_EQUAL(test_array::m_nblocks, 0);
+ }
+ ATF_CHECK_EQUAL(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::utils::auto_array;
+
+ ATF_CHECK_EQUAL(test_array::m_nblocks, 0);
+ {
+ auto_array< test_array > t1(new test_array[10]);
+ ATF_CHECK_EQUAL(test_array::m_nblocks, 1);
+
+ {
+ auto_array< test_array > t2 = test_array::do_copy(t1);
+ ATF_CHECK_EQUAL(test_array::m_nblocks, 1);
+ }
+ ATF_CHECK_EQUAL(test_array::m_nblocks, 0);
+ }
+ ATF_CHECK_EQUAL(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::utils::auto_array;
+
+ test_array* ta = new test_array[10];
+ auto_array< test_array > t(ta);
+ ATF_CHECK_EQUAL(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::utils::auto_array;
+
+ test_array* ta1 = new test_array[10];
+ {
+ auto_array< test_array > t(ta1);
+ ATF_CHECK_EQUAL(test_array::m_nblocks, 1);
+ test_array* ta2 = t.release();
+ ATF_CHECK_EQUAL(ta2, ta1);
+ ATF_CHECK_EQUAL(test_array::m_nblocks, 1);
+ }
+ ATF_CHECK_EQUAL(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::utils::auto_array;
+
+ test_array* ta1 = new test_array[10];
+ test_array* ta2 = new test_array[10];
+ ATF_CHECK_EQUAL(test_array::m_nblocks, 2);
+
+ {
+ auto_array< test_array > t(ta1);
+ ATF_CHECK_EQUAL(test_array::m_nblocks, 2);
+ t.reset(ta2);
+ ATF_CHECK_EQUAL(test_array::m_nblocks, 1);
+ t.reset();
+ ATF_CHECK_EQUAL(test_array::m_nblocks, 0);
+ }
+ ATF_CHECK_EQUAL(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::utils::auto_array;
+
+ ATF_CHECK_EQUAL(test_array::m_nblocks, 0);
+ {
+ auto_array< test_array > t1(new test_array[10]);
+ ATF_CHECK_EQUAL(test_array::m_nblocks, 1);
+
+ {
+ auto_array< test_array > t2;
+ t2 = t1;
+ ATF_CHECK_EQUAL(test_array::m_nblocks, 1);
+ }
+ ATF_CHECK_EQUAL(test_array::m_nblocks, 0);
+ }
+ ATF_CHECK_EQUAL(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::utils::auto_array;
+
+ ATF_CHECK_EQUAL(test_array::m_nblocks, 0);
+ {
+ auto_array< test_array > t1(new test_array[10]);
+ ATF_CHECK_EQUAL(test_array::m_nblocks, 1);
+
+ {
+ auto_array< test_array > t2;
+ t2 = test_array::do_copy(t1);
+ ATF_CHECK_EQUAL(test_array::m_nblocks, 1);
+ }
+ ATF_CHECK_EQUAL(test_array::m_nblocks, 0);
+ }
+ ATF_CHECK_EQUAL(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::utils::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_CHECK_EQUAL(t[i].m_value, i * 2);
+}
+
+// ------------------------------------------------------------------------
+// Tests cases for the header file.
+// ------------------------------------------------------------------------
+
+HEADER_TC(include, "atf-c++/utils.hpp");
+
+// ------------------------------------------------------------------------
+// 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);
+
+ // Add the test cases for the header file.
+ ATF_ADD_TEST_CASE(tcs, include);
+}
diff --git a/external/bsd/atf/dist/atf-c/Atffile b/external/bsd/atf/dist/atf-c/Atffile
new file mode 100644
index 00000000000..146211e000d
--- /dev/null
+++ b/external/bsd/atf/dist/atf-c/Atffile
@@ -0,0 +1,5 @@
+Content-Type: application/X-atf-atffile; version="1"
+
+prop: test-suite = atf
+
+tp-glob: *_test
diff --git a/external/bsd/atf/dist/atf-c/atf-c-api.3 b/external/bsd/atf/dist/atf-c/atf-c-api.3
index 908f574b07b..5ae229738fe 100644
--- a/external/bsd/atf/dist/atf-c/atf-c-api.3
+++ b/external/bsd/atf/dist/atf-c/atf-c-api.3
@@ -26,7 +26,7 @@
.\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
.\" IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd June 1, 2010
+.Dd June 28, 2010
.Dt ATF-C-API 3
.Os
.Sh NAME
@@ -36,12 +36,14 @@
.Nm ATF_CHECK_EQ_MSG ,
.Nm ATF_CHECK_STREQ ,
.Nm ATF_CHECK_STREQ_MSG ,
+.Nm ATF_CHECK_ERRNO ,
.Nm ATF_REQUIRE ,
.Nm ATF_REQUIRE_MSG ,
.Nm ATF_REQUIRE_EQ ,
.Nm ATF_REQUIRE_EQ_MSG ,
.Nm ATF_REQUIRE_STREQ ,
.Nm ATF_REQUIRE_STREQ_MSG ,
+.Nm ATF_REQUIRE_ERRNO ,
.Nm ATF_TC ,
.Nm ATF_TC_BODY ,
.Nm ATF_TC_BODY_NAME ,
@@ -55,6 +57,12 @@
.Nm ATF_TP_ADD_TC ,
.Nm ATF_TP_ADD_TCS ,
.Nm atf_no_error ,
+.Nm atf_tc_expect_death ,
+.Nm atf_tc_expect_exit ,
+.Nm atf_tc_expect_fail ,
+.Nm atf_tc_expect_pass ,
+.Nm atf_tc_expect_signal ,
+.Nm atf_tc_expect_timeout ,
.Nm atf_tc_fail ,
.Nm atf_tc_fail_nonfatal ,
.Nm atf_tc_pass ,
@@ -68,12 +76,14 @@
.Fn ATF_CHECK_EQ_MSG "expression_1" "expression_2" "fail_msg_fmt" ...
.Fn ATF_CHECK_STREQ "string_1" "string_2"
.Fn ATF_CHECK_STREQ_MSG "string_1" "string_2" "fail_msg_fmt" ...
+.Fn ATF_CHECK_ERRNO "exp_errno" "bool_expression"
.Fn ATF_REQUIRE "expression"
.Fn ATF_REQUIRE_MSG "expression" "fail_msg_fmt" ...
.Fn ATF_REQUIRE_EQ "expression_1" "expression_2"
.Fn ATF_REQUIRE_EQ_MSG "expression_1" "expression_2" "fail_msg_fmt" ...
.Fn ATF_REQUIRE_STREQ "string_1" "string_2"
.Fn ATF_REQUIRE_STREQ_MSG "string_1" "string_2" "fail_msg_fmt" ...
+.Fn ATF_REQUIRE_ERRNO "exp_errno" "bool_expression"
.Fn ATF_TC "name"
.Fn ATF_TC_BODY "name" "tc"
.Fn ATF_TC_BODY_NAME "name"
@@ -84,9 +94,15 @@
.Fn ATF_TC_NAME "name"
.Fn ATF_TC_WITH_CLEANUP "name"
.Fn ATF_TC_WITHOUT_HEAD "name"
-.Fn ATF_TP_ADD_TC "tp_name"
-.Fn ATF_TP_ADD_TCS "tp_name" "tc_name"
+.Fn ATF_TP_ADD_TC "tp_name" "tc_name"
+.Fn ATF_TP_ADD_TCS "tp_name"
.Fn atf_no_error
+.Fn atf_tc_expect_death "reason" "..."
+.Fn atf_tc_expect_exit "exitcode" "reason" "..."
+.Fn atf_tc_expect_fail "reason" "..."
+.Fn atf_tc_expect_pass
+.Fn atf_tc_expect_signal "signo" "reason" "..."
+.Fn atf_tc_expect_timeout "reason" "..."
.Fn atf_tc_fail "reason"
.Fn atf_tc_fail_nonfatal "reason"
.Fn atf_tc_pass
@@ -132,7 +148,7 @@ ATF_TC_BODY(tc3, tc)
.Ns ... additional test cases ...
-ATF_TP_ADD_TCS(tp, tcs)
+ATF_TP_ADD_TCS(tp)
{
ATF_TP_ADD_TC(tcs, tc1);
ATF_TP_ADD_TC(tcs, tc2);
@@ -146,7 +162,7 @@ ATF_TP_ADD_TCS(tp, tcs)
Test cases have an identifier and are composed of three different parts:
the header, the body and an optional cleanup routine, all of which are
described in
-.Xr atf-test-case 8 .
+.Xr atf-test-case 4 .
To define test cases, one can use the
.Fn ATF_TC ,
.Fn ATF_TC_WITH_CLEANUP
@@ -262,6 +278,65 @@ a user-friendly manner, why the test case failed or was skipped,
respectively.
It is very important to provide a clear error message in both cases so that
the user can quickly know why the test did not pass.
+.Ss Expectations
+Everything explained in the previous section changes when the test case
+expectations are redefined by the programmer.
+.Pp
+Each test case has an internal state called
+.Sq expect
+that describes what the test case expectations are at any point in time.
+The value of this property can change during execution by any of:
+.Bl -tag -width indent
+.It Fn atf_tc_expect_death "reason" "..."
+Expects the test case to exit prematurely regardless of the nature of the
+exit.
+.It Fn atf_tc_expect_exit "exitcode" "reason" "..."
+Expects the test case to exit cleanly.
+If
+.Va exitcode
+is not
+.Sq -1 ,
+.Xr atf-run 1
+will validate that the exit code of the test case matches the one provided
+in this call.
+Otherwise, the exact value will be ignored.
+.It Fn atf_tc_expect_fail "reason" "..."
+Any failure (be it fatal or non-fatal) raised in this mode is recorded.
+However, such failures do not report the test case as failed; instead, the
+test case finalizes cleanly and is reported as
+.Sq expected failure ;
+this report includes the provided
+.Fa reason
+as part of it.
+If no error is raised while running in this mode, then the test case is
+reported as
+.Sq failed .
+.Pp
+This mode is useful to reproduce actual known bugs in tests.
+Whenever the developer fixes the bug later on, the test case will start
+reporting a failure, signaling the developer that the test case must be
+adjusted to the new conditions.
+In this situation, it is useful, for example, to set
+.Fa reason
+as the bug number for tracking purposes.
+.It Fn atf_tc_expect_pass
+This is the normal mode of execution.
+In this mode, any failure is reported as such to the user and the test case
+is marked as
+.Sq failed .
+.It Fn atf_tc_expect_signal "signo" "reason" "..."
+Expects the test case to terminate due to the reception of a signal.
+If
+.Va signo
+is not
+.Sq -1 ,
+.Xr atf-run 1
+will validate that the signal that terminated the test case matches the one
+provided in this call.
+Otherwise, the exact value will be ignored.
+.It Fn atf_tc_expect_timeout "reason" "..."
+Expects the test case to execute for longer than its timeout.
+.El
.Ss Helper macros for common checks
The library provides several macros that are very handy in multiple
situations.
@@ -316,6 +391,16 @@ take two expressions and fail if the two evaluated values are not equal.
and
.Fn ATF_REQUIRE_STREQ_MSG
take two strings and fail if the two are not equal character by character.
+.Pp
+.Fn ATF_CHECK_ERRNO
+and
+.Fn ATF_REQUIRE_ERRNO
+take, first, the error code that the check is expecting to find in the
+.Va errno
+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.
.Sh EXAMPLES
The following shows a complete test program with a single test case that
validates the addition operator:
@@ -352,15 +437,42 @@ ATF_TC_BODY(string_formatting, tc)
ATF_CHECK_STREQ_MSG("a string", buf, "%s is not working");
}
+ATF_TC(open_failure);
+ATF_TC_HEAD(open_failure, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Sample tests for the open function");
+}
+ATF_TC_BODY(open_failure, tc)
+{
+ ATF_CHECK_ERRNO(ENOENT, open("non-existent", O_RDONLY) == -1);
+}
+
+ATF_TC(known_bug);
+ATF_TC_HEAD(known_bug, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Reproduces a known bug");
+}
+ATF_TC_BODY(known_bug, tc)
+{
+ atf_tc_expect_fail("See bug number foo/bar");
+ ATF_CHECK_EQ(3, 1 + 1);
+ atf_tc_expect_pass();
+ ATF_CHECK_EQ(3, 1 + 2);
+}
+
ATF_TP_ADD_TCS(tp)
{
ATF_TP_ADD_TC(tp, addition);
ATF_TP_ADD_TC(tp, string_formatting);
+ ATF_TP_ADD_TC(tp, open_failure);
+ ATF_TP_ADD_TC(tp, known_bug);
return atf_no_error();
}
.Ed
.Sh SEE ALSO
.Xr atf-test-program 1 ,
-.Xr atf 7 ,
-.Xr atf-test-case 8
+.Xr atf-test-case 4 ,
+.Xr atf 7
diff --git a/external/bsd/atf/dist/atf-c/atf_c_test.c b/external/bsd/atf/dist/atf-c/atf_c_test.c
new file mode 100644
index 00000000000..b381c560b80
--- /dev/null
+++ b/external/bsd/atf/dist/atf-c/atf_c_test.c
@@ -0,0 +1,50 @@
+/*
+ * Automated Testing Framework (atf)
+ *
+ * Copyright (c) 2008, 2009 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.h>
+
+#include "test_helpers.h"
+
+/* ---------------------------------------------------------------------
+ * Tests cases for the header file.
+ * --------------------------------------------------------------------- */
+
+HEADER_TC(include, "atf-c.h");
+
+/* ---------------------------------------------------------------------
+ * Main.
+ * --------------------------------------------------------------------- */
+
+ATF_TP_ADD_TCS(tp)
+{
+ /* Add the test cases for the header file. */
+ ATF_TP_ADD_TC(tp, include);
+
+ return atf_no_error();
+}
diff --git a/external/bsd/atf/dist/atf-c/build_test.c b/external/bsd/atf/dist/atf-c/build_test.c
new file mode 100644
index 00000000000..d6a2a9de816
--- /dev/null
+++ b/external/bsd/atf/dist/atf-c/build_test.c
@@ -0,0 +1,286 @@
+/*
+ * Automated Testing Framework (atf)
+ *
+ * Copyright (c) 2009 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <atf-c.h>
+
+#include "atf-c/build.h"
+#include "atf-c/config.h"
+#include "atf-c/env.h"
+
+#include "h_build.h"
+#include "test_helpers.h"
+
+/* ---------------------------------------------------------------------
+ * Auxiliary functions.
+ * --------------------------------------------------------------------- */
+
+void __atf_config_reinit(void);
+
+static
+bool
+equal_list_array(const atf_list_t *l, const char *const *a)
+{
+ bool equal;
+
+ if (atf_list_size(l) == 0 && *a == NULL)
+ equal = true;
+ else if (atf_list_size(l) == 0 || *a == NULL)
+ equal = false;
+ else {
+ atf_list_citer_t liter;
+
+ equal = true;
+ atf_list_for_each_c(liter, l) {
+ if (*a == NULL ||
+ strcmp((const char *)atf_list_citer_data(liter), *a) != 0) {
+ equal = false;
+ break;
+ }
+ a++;
+ }
+ }
+
+ return equal;
+}
+
+static
+void
+print_list(const char *prefix, const atf_list_t *l)
+{
+ atf_list_citer_t iter;
+
+ printf("%s:", prefix);
+ atf_list_for_each_c(iter, l)
+ printf(" '%s'", (const char *)atf_list_citer_data(iter));
+ printf("\n");
+}
+
+static
+void
+print_array(const char *prefix, const char *const *a)
+{
+ printf("%s:", prefix);
+ for (; *a != NULL; a++)
+ printf(" '%s'", *a);
+ printf("\n");
+}
+
+static
+void
+check_equal_list_array(const atf_list_t *l, const char *const *a)
+{
+ print_array("Expected arguments", a);
+ print_list("Arguments returned", l);
+
+ if (!equal_list_array(l, a))
+ atf_tc_fail_nonfatal("The constructed argv differs from the "
+ "expected values");
+}
+
+static
+void
+verbose_set_env(const char *var, const char *val)
+{
+ printf("Setting %s to '%s'\n", var, val);
+ RE(atf_env_set(var, val));
+}
+
+/* ---------------------------------------------------------------------
+ * Internal test cases.
+ * --------------------------------------------------------------------- */
+
+ATF_TC(equal_list_array);
+ATF_TC_HEAD(equal_list_array, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests the test case internal "
+ "equal_list_array function");
+}
+ATF_TC_BODY(equal_list_array, tc)
+{
+ {
+ atf_list_t list;
+ const char *const array[] = { NULL };
+
+ RE(atf_list_init(&list));
+ ATF_CHECK(equal_list_array(&list, array));
+ atf_list_fini(&list);
+ }
+
+ {
+ atf_list_t list;
+ const char *const array[] = { NULL };
+
+ RE(atf_list_init(&list));
+ atf_list_append(&list, strdup("foo"), true);
+ ATF_CHECK(!equal_list_array(&list, array));
+ atf_list_fini(&list);
+ }
+
+ {
+ atf_list_t list;
+ const char *const array[] = { "foo", NULL };
+
+ RE(atf_list_init(&list));
+ ATF_CHECK(!equal_list_array(&list, array));
+ atf_list_fini(&list);
+ }
+
+ {
+ atf_list_t list;
+ const char *const array[] = { "foo", NULL };
+
+ RE(atf_list_init(&list));
+ atf_list_append(&list, strdup("foo"), true);
+ ATF_CHECK(equal_list_array(&list, array));
+ atf_list_fini(&list);
+ }
+}
+
+/* ---------------------------------------------------------------------
+ * Test cases for the free functions.
+ * --------------------------------------------------------------------- */
+
+ATF_TC(c_o);
+ATF_TC_HEAD(c_o, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests the atf_build_c_o function");
+}
+ATF_TC_BODY(c_o, tc)
+{
+ struct c_o_test *test;
+
+ for (test = c_o_tests; test->expargv[0] != NULL; test++) {
+ printf("> Test: %s\n", test->msg);
+
+ verbose_set_env("ATF_BUILD_CC", test->cc);
+ verbose_set_env("ATF_BUILD_CFLAGS", test->cflags);
+ verbose_set_env("ATF_BUILD_CPPFLAGS", test->cppflags);
+ __atf_config_reinit();
+
+ {
+ atf_list_t argv;
+ if (test->hasoptargs)
+ RE(atf_build_c_o(test->sfile, test->ofile, test->optargs,
+ &argv));
+ else
+ RE(atf_build_c_o(test->sfile, test->ofile, NULL, &argv));
+ check_equal_list_array(&argv, test->expargv);
+ atf_list_fini(&argv);
+ }
+ }
+}
+
+ATF_TC(cpp);
+ATF_TC_HEAD(cpp, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests the atf_build_cpp function");
+}
+ATF_TC_BODY(cpp, tc)
+{
+ struct cpp_test *test;
+
+ for (test = cpp_tests; test->expargv[0] != NULL; test++) {
+ printf("> Test: %s\n", test->msg);
+
+ verbose_set_env("ATF_BUILD_CPP", test->cpp);
+ verbose_set_env("ATF_BUILD_CPPFLAGS", test->cppflags);
+ __atf_config_reinit();
+
+ {
+ atf_list_t argv;
+ if (test->hasoptargs)
+ RE(atf_build_cpp(test->sfile, test->ofile, test->optargs,
+ &argv));
+ else
+ RE(atf_build_cpp(test->sfile, test->ofile, NULL, &argv));
+ check_equal_list_array(&argv, test->expargv);
+ atf_list_fini(&argv);
+ }
+ }
+}
+
+ATF_TC(cxx_o);
+ATF_TC_HEAD(cxx_o, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests the atf_build_cxx_o function");
+}
+ATF_TC_BODY(cxx_o, tc)
+{
+ struct cxx_o_test *test;
+
+ for (test = cxx_o_tests; test->expargv[0] != NULL; test++) {
+ printf("> Test: %s\n", test->msg);
+
+ verbose_set_env("ATF_BUILD_CXX", test->cxx);
+ verbose_set_env("ATF_BUILD_CXXFLAGS", test->cxxflags);
+ verbose_set_env("ATF_BUILD_CPPFLAGS", test->cppflags);
+ __atf_config_reinit();
+
+ {
+ atf_list_t argv;
+ if (test->hasoptargs)
+ RE(atf_build_cxx_o(test->sfile, test->ofile, test->optargs,
+ &argv));
+ else
+ RE(atf_build_cxx_o(test->sfile, test->ofile, NULL, &argv));
+ check_equal_list_array(&argv, test->expargv);
+ atf_list_fini(&argv);
+ }
+ }
+}
+
+/* ---------------------------------------------------------------------
+ * Tests cases for the header file.
+ * --------------------------------------------------------------------- */
+
+HEADER_TC(include, "atf-c/build.h");
+
+/* ---------------------------------------------------------------------
+ * Main.
+ * --------------------------------------------------------------------- */
+
+ATF_TP_ADD_TCS(tp)
+{
+ /* Add the internal test cases. */
+ ATF_TP_ADD_TC(tp, equal_list_array);
+
+ /* Add the test cases for the free functions. */
+ ATF_TP_ADD_TC(tp, c_o);
+ ATF_TP_ADD_TC(tp, cpp);
+ ATF_TP_ADD_TC(tp, cxx_o);
+
+ /* Add the test cases for the header file. */
+ ATF_TP_ADD_TC(tp, include);
+
+ return atf_no_error();
+}
diff --git a/external/bsd/atf/dist/atf-c/check.c b/external/bsd/atf/dist/atf-c/check.c
index d415f738af0..e7c8e9c7e28 100644
--- a/external/bsd/atf/dist/atf-c/check.c
+++ b/external/bsd/atf/dist/atf-c/check.c
@@ -418,6 +418,18 @@ atf_check_result_exitcode(const atf_check_result_t *r)
return atf_process_status_exitstatus(&r->m_status);
}
+bool
+atf_check_result_signaled(const atf_check_result_t *r)
+{
+ return atf_process_status_signaled(&r->m_status);
+}
+
+int
+atf_check_result_termsig(const atf_check_result_t *r)
+{
+ return atf_process_status_termsig(&r->m_status);
+}
+
/* ---------------------------------------------------------------------
* Free functions.
* --------------------------------------------------------------------- */
diff --git a/external/bsd/atf/dist/atf-c/check.h b/external/bsd/atf/dist/atf-c/check.h
index 89333d31e82..e850ebe6c74 100644
--- a/external/bsd/atf/dist/atf-c/check.h
+++ b/external/bsd/atf/dist/atf-c/check.h
@@ -57,6 +57,8 @@ const atf_fs_path_t *atf_check_result_stdout(const atf_check_result_t *);
const atf_fs_path_t *atf_check_result_stderr(const atf_check_result_t *);
bool atf_check_result_exited(const atf_check_result_t *);
int atf_check_result_exitcode(const atf_check_result_t *);
+bool atf_check_result_signaled(const atf_check_result_t *);
+int atf_check_result_termsig(const atf_check_result_t *);
/* ---------------------------------------------------------------------
* Free functions.
diff --git a/external/bsd/atf/dist/atf-c/check_test.c b/external/bsd/atf/dist/atf-c/check_test.c
new file mode 100644
index 00000000000..629a2e42f85
--- /dev/null
+++ b/external/bsd/atf/dist/atf-c/check_test.c
@@ -0,0 +1,578 @@
+/*
+ * Automated Testing Framework (atf)
+ *
+ * Copyright (c) 2008, 2009, 2010 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <fcntl.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <atf-c.h>
+
+#include "atf-c/check.h"
+#include "atf-c/config.h"
+#include "atf-c/fs.h"
+#include "atf-c/process.h"
+
+#include "test_helpers.h"
+
+/* ---------------------------------------------------------------------
+ * Auxiliary functions.
+ * --------------------------------------------------------------------- */
+
+static
+void
+do_exec(const atf_tc_t *tc, const char *helper_name, atf_check_result_t *r)
+{
+ atf_fs_path_t process_helpers;
+ const char *argv[3];
+
+ get_process_helpers_path(tc, &process_helpers);
+
+ argv[0] = atf_fs_path_cstring(&process_helpers);
+ argv[1] = helper_name;
+ argv[2] = NULL;
+ printf("Executing %s %s\n", argv[0], argv[1]);
+ RE(atf_check_exec_array(argv, r));
+
+ atf_fs_path_fini(&process_helpers);
+}
+
+static
+void
+do_exec_with_arg(const atf_tc_t *tc, const char *helper_name, const char *arg,
+ atf_check_result_t *r)
+{
+ atf_fs_path_t process_helpers;
+ const char *argv[4];
+
+ get_process_helpers_path(tc, &process_helpers);
+
+ argv[0] = atf_fs_path_cstring(&process_helpers);
+ argv[1] = helper_name;
+ argv[2] = arg;
+ argv[3] = NULL;
+ printf("Executing %s %s %s\n", argv[0], argv[1], argv[2]);
+ RE(atf_check_exec_array(argv, r));
+
+ atf_fs_path_fini(&process_helpers);
+}
+
+static
+void
+check_line(int fd, const char *exp)
+{
+ atf_dynstr_t line;
+
+ atf_dynstr_init(&line);
+ ATF_CHECK(!read_line(fd, &line));
+ ATF_CHECK_MSG(atf_equal_dynstr_cstring(&line, exp),
+ "read: '%s', expected: '%s'",
+ atf_dynstr_cstring(&line), exp);
+ atf_dynstr_fini(&line);
+}
+
+/* ---------------------------------------------------------------------
+ * Helper test cases for the free functions.
+ * --------------------------------------------------------------------- */
+
+ATF_TC(h_build_c_o_ok);
+ATF_TC_HEAD(h_build_c_o_ok, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Helper test case for build_c_o");
+}
+ATF_TC_BODY(h_build_c_o_ok, tc)
+{
+ FILE *sfile;
+ bool success;
+
+ ATF_REQUIRE((sfile = fopen("test.c", "w")) != NULL);
+ fprintf(sfile, "#include <stdio.h>\n");
+ fclose(sfile);
+
+ RE(atf_check_build_c_o("test.c", "test.o", NULL, &success));
+ ATF_REQUIRE(success);
+}
+
+ATF_TC(h_build_c_o_fail);
+ATF_TC_HEAD(h_build_c_o_fail, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Helper test case for build_c_o");
+}
+ATF_TC_BODY(h_build_c_o_fail, tc)
+{
+ FILE *sfile;
+ bool success;
+
+ ATF_REQUIRE((sfile = fopen("test.c", "w")) != NULL);
+ fprintf(sfile, "void foo(void) { int a = UNDEFINED_SYMBOL; }\n");
+ fclose(sfile);
+
+ RE(atf_check_build_c_o("test.c", "test.o", NULL, &success));
+ ATF_REQUIRE(!success);
+}
+
+ATF_TC(h_build_cpp_ok);
+ATF_TC_HEAD(h_build_cpp_ok, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Helper test case for build_cpp");
+}
+ATF_TC_BODY(h_build_cpp_ok, tc)
+{
+ FILE *sfile;
+ bool success;
+ atf_fs_path_t test_p;
+
+ RE(atf_fs_path_init_fmt(&test_p, "test.p"));
+
+ ATF_REQUIRE((sfile = fopen("test.c", "w")) != NULL);
+ fprintf(sfile, "#define A foo\n");
+ fprintf(sfile, "#define B bar\n");
+ fprintf(sfile, "A B\n");
+ fclose(sfile);
+
+ RE(atf_check_build_cpp("test.c", atf_fs_path_cstring(&test_p), NULL,
+ &success));
+ ATF_REQUIRE(success);
+
+ atf_fs_path_fini(&test_p);
+}
+
+ATF_TC(h_build_cpp_fail);
+ATF_TC_HEAD(h_build_cpp_fail, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Helper test case for build_cpp");
+}
+ATF_TC_BODY(h_build_cpp_fail, tc)
+{
+ FILE *sfile;
+ bool success;
+
+ ATF_REQUIRE((sfile = fopen("test.c", "w")) != NULL);
+ fprintf(sfile, "#include \"./non-existent.h\"\n");
+ fclose(sfile);
+
+ RE(atf_check_build_cpp("test.c", "test.p", NULL, &success));
+ ATF_REQUIRE(!success);
+}
+
+ATF_TC(h_build_cxx_o_ok);
+ATF_TC_HEAD(h_build_cxx_o_ok, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Helper test case for build_cxx_o");
+}
+ATF_TC_BODY(h_build_cxx_o_ok, tc)
+{
+ FILE *sfile;
+ bool success;
+
+ ATF_REQUIRE((sfile = fopen("test.cpp", "w")) != NULL);
+ fprintf(sfile, "#include <iostream>\n");
+ fclose(sfile);
+
+ RE(atf_check_build_cxx_o("test.cpp", "test.o", NULL, &success));
+ ATF_REQUIRE(success);
+}
+
+ATF_TC(h_build_cxx_o_fail);
+ATF_TC_HEAD(h_build_cxx_o_fail, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Helper test case for build_cxx_o");
+}
+ATF_TC_BODY(h_build_cxx_o_fail, tc)
+{
+ FILE *sfile;
+ bool success;
+
+ ATF_REQUIRE((sfile = fopen("test.cpp", "w")) != NULL);
+ fprintf(sfile, "void foo(void) { int a = UNDEFINED_SYMBOL; }\n");
+ fclose(sfile);
+
+ RE(atf_check_build_cxx_o("test.cpp", "test.o", NULL, &success));
+ ATF_REQUIRE(!success);
+}
+
+/* ---------------------------------------------------------------------
+ * Test cases for the free functions.
+ * --------------------------------------------------------------------- */
+
+static
+void
+init_and_run_h_tc(atf_tc_t *tc, const atf_tc_pack_t *tcpack,
+ const char *outname, const char *errname)
+{
+ atf_map_t config;
+
+ RE(atf_map_init(&config));
+
+ RE(atf_tc_init_pack(tc, tcpack, &config));
+ run_h_tc(tc, outname, errname, "result");
+ atf_tc_fini(tc);
+
+ atf_map_fini(&config);
+}
+
+ATF_TC(build_c_o);
+ATF_TC_HEAD(build_c_o, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks the atf_check_build_c_o "
+ "function");
+ atf_tc_set_md_var(tc, "use.fs", "true");
+}
+ATF_TC_BODY(build_c_o, tc)
+{
+ init_and_run_h_tc(&ATF_TC_NAME(h_build_c_o_ok),
+ &ATF_TC_PACK_NAME(h_build_c_o_ok), "stdout", "stderr");
+ ATF_CHECK(grep_file("stdout", "-o test.o"));
+ ATF_CHECK(grep_file("stdout", "-c test.c"));
+
+ init_and_run_h_tc(&ATF_TC_NAME(h_build_c_o_fail),
+ &ATF_TC_PACK_NAME(h_build_c_o_fail), "stdout", "stderr");
+ ATF_CHECK(grep_file("stdout", "-o test.o"));
+ ATF_CHECK(grep_file("stdout", "-c test.c"));
+ ATF_CHECK(grep_file("stderr", "test.c"));
+ ATF_CHECK(grep_file("stderr", "UNDEFINED_SYMBOL"));
+}
+
+ATF_TC(build_cpp);
+ATF_TC_HEAD(build_cpp, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks the atf_check_build_cpp "
+ "function");
+ atf_tc_set_md_var(tc, "use.fs", "true");
+}
+ATF_TC_BODY(build_cpp, tc)
+{
+ init_and_run_h_tc(&ATF_TC_NAME(h_build_cpp_ok),
+ &ATF_TC_PACK_NAME(h_build_cpp_ok), "stdout", "stderr");
+ ATF_CHECK(grep_file("stdout", "-o.*test.p"));
+ ATF_CHECK(grep_file("stdout", "test.c"));
+ ATF_CHECK(grep_file("test.p", "foo bar"));
+
+ init_and_run_h_tc(&ATF_TC_NAME(h_build_cpp_fail),
+ &ATF_TC_PACK_NAME(h_build_cpp_fail), "stdout", "stderr");
+ ATF_CHECK(grep_file("stdout", "-o test.p"));
+ ATF_CHECK(grep_file("stdout", "test.c"));
+ ATF_CHECK(grep_file("stderr", "test.c"));
+ ATF_CHECK(grep_file("stderr", "non-existent.h"));
+}
+
+ATF_TC(build_cxx_o);
+ATF_TC_HEAD(build_cxx_o, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks the atf_check_build_cxx_o "
+ "function");
+ atf_tc_set_md_var(tc, "use.fs", "true");
+}
+ATF_TC_BODY(build_cxx_o, tc)
+{
+ init_and_run_h_tc(&ATF_TC_NAME(h_build_cxx_o_ok),
+ &ATF_TC_PACK_NAME(h_build_cxx_o_ok), "stdout", "stderr");
+ ATF_CHECK(grep_file("stdout", "-o test.o"));
+ ATF_CHECK(grep_file("stdout", "-c test.cpp"));
+
+ init_and_run_h_tc(&ATF_TC_NAME(h_build_cxx_o_fail),
+ &ATF_TC_PACK_NAME(h_build_cxx_o_fail), "stdout", "stderr");
+ ATF_CHECK(grep_file("stdout", "-o test.o"));
+ ATF_CHECK(grep_file("stdout", "-c test.cpp"));
+ ATF_CHECK(grep_file("stderr", "test.cpp"));
+ ATF_CHECK(grep_file("stderr", "UNDEFINED_SYMBOL"));
+}
+
+ATF_TC(exec_argv);
+ATF_TC_HEAD(exec_argv, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks that atf_check_exec_array "
+ "preserves the provided argv");
+}
+ATF_TC_BODY(exec_argv, tc)
+{
+ atf_fs_path_t process_helpers;
+ atf_check_result_t result;
+
+ get_process_helpers_path(tc, &process_helpers);
+ do_exec(tc, "exit-success", &result);
+
+ const atf_list_t *argv = atf_check_result_argv(&result);
+ ATF_REQUIRE_EQ(atf_list_size(argv), 2);
+ ATF_CHECK_STREQ((const char *)atf_list_index_c(argv, 0),
+ atf_fs_path_cstring(&process_helpers));
+ ATF_CHECK_STREQ((const char *)atf_list_index_c(argv, 1), "exit-success");
+
+ atf_check_result_fini(&result);
+ atf_fs_path_fini(&process_helpers);
+}
+
+ATF_TC(exec_cleanup);
+ATF_TC_HEAD(exec_cleanup, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks that atf_check_exec_array "
+ "properly cleans up the temporary files it creates");
+}
+ATF_TC_BODY(exec_cleanup, tc)
+{
+ atf_fs_path_t out, err;
+ atf_check_result_t result;
+ bool exists;
+
+ do_exec(tc, "exit-success", &result);
+ RE(atf_fs_path_copy(&out, atf_check_result_stdout(&result)));
+ RE(atf_fs_path_copy(&err, atf_check_result_stderr(&result)));
+
+ RE(atf_fs_exists(&out, &exists)); ATF_CHECK(exists);
+ RE(atf_fs_exists(&err, &exists)); ATF_CHECK(exists);
+ atf_check_result_fini(&result);
+ RE(atf_fs_exists(&out, &exists)); ATF_CHECK(!exists);
+ RE(atf_fs_exists(&err, &exists)); ATF_CHECK(!exists);
+
+ atf_fs_path_fini(&err);
+ atf_fs_path_fini(&out);
+}
+
+ATF_TC(exec_exitstatus);
+ATF_TC_HEAD(exec_exitstatus, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks that atf_check_exec_array "
+ "properly captures the exit status of the executed "
+ "command");
+}
+ATF_TC_BODY(exec_exitstatus, tc)
+{
+ {
+ atf_check_result_t result;
+ do_exec(tc, "exit-success", &result);
+ ATF_CHECK(atf_check_result_exited(&result));
+ ATF_CHECK(!atf_check_result_signaled(&result));
+ ATF_CHECK(atf_check_result_exitcode(&result) == EXIT_SUCCESS);
+ atf_check_result_fini(&result);
+ }
+
+ {
+ atf_check_result_t result;
+ do_exec(tc, "exit-failure", &result);
+ ATF_CHECK(atf_check_result_exited(&result));
+ ATF_CHECK(!atf_check_result_signaled(&result));
+ ATF_CHECK(atf_check_result_exitcode(&result) == EXIT_FAILURE);
+ atf_check_result_fini(&result);
+ }
+
+ {
+ atf_check_result_t result;
+ do_exec(tc, "exit-signal", &result);
+ ATF_CHECK(!atf_check_result_exited(&result));
+ ATF_CHECK(atf_check_result_signaled(&result));
+ ATF_CHECK(atf_check_result_termsig(&result) == SIGKILL);
+ atf_check_result_fini(&result);
+ }
+}
+
+ATF_TC(exec_list);
+ATF_TC_HEAD(exec_list, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks that atf_check_exec_list "
+ "works properly; assumes that this method is "
+ "backed by atf_check_exec_array, so the tests "
+ "are not exhaustive");
+}
+ATF_TC_BODY(exec_list, tc)
+{
+ atf_fs_path_t process_helpers;
+ atf_list_t argv;
+ atf_check_result_t result;
+
+ RE(atf_list_init(&argv));
+
+ get_process_helpers_path(tc, &process_helpers);
+ atf_list_append(&argv, strdup(atf_fs_path_cstring(&process_helpers)), true);
+ atf_list_append(&argv, strdup("echo"), true);
+ atf_list_append(&argv, strdup("test-message"), true);
+ RE(atf_check_exec_list(&argv, &result));
+ atf_list_fini(&argv);
+
+ ATF_CHECK(atf_check_result_exited(&result));
+ ATF_CHECK(atf_check_result_exitcode(&result) == EXIT_SUCCESS);
+
+ {
+ const atf_fs_path_t *path = atf_check_result_stdout(&result);
+ int fd = open(atf_fs_path_cstring(path), O_RDONLY);
+ ATF_CHECK(fd != -1);
+ check_line(fd, "test-message");
+ close(fd);
+ }
+
+ atf_check_result_fini(&result);
+ atf_fs_path_fini(&process_helpers);
+}
+
+ATF_TC(exec_stdout_stderr);
+ATF_TC_HEAD(exec_stdout_stderr, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks that atf_check_exec_array "
+ "properly captures the stdout and stderr streams "
+ "of the child process");
+}
+ATF_TC_BODY(exec_stdout_stderr, tc)
+{
+ atf_check_result_t result1, result2;
+ const atf_fs_path_t *out1, *out2;
+ const atf_fs_path_t *err1, *err2;
+
+ do_exec_with_arg(tc, "stdout-stderr", "result1", &result1);
+ ATF_CHECK(atf_check_result_exited(&result1));
+ ATF_CHECK(atf_check_result_exitcode(&result1) == EXIT_SUCCESS);
+
+ do_exec_with_arg(tc, "stdout-stderr", "result2", &result2);
+ ATF_CHECK(atf_check_result_exited(&result2));
+ ATF_CHECK(atf_check_result_exitcode(&result2) == EXIT_SUCCESS);
+
+ out1 = atf_check_result_stdout(&result1);
+ out2 = atf_check_result_stdout(&result2);
+ err1 = atf_check_result_stderr(&result1);
+ err2 = atf_check_result_stderr(&result2);
+
+ ATF_CHECK(strstr(atf_fs_path_cstring(out1), "check.XXXXXX") == NULL);
+ ATF_CHECK(strstr(atf_fs_path_cstring(out2), "check.XXXXXX") == NULL);
+ ATF_CHECK(strstr(atf_fs_path_cstring(err1), "check.XXXXXX") == NULL);
+ ATF_CHECK(strstr(atf_fs_path_cstring(err2), "check.XXXXXX") == NULL);
+
+ ATF_CHECK(strstr(atf_fs_path_cstring(out1), "/check") != NULL);
+ ATF_CHECK(strstr(atf_fs_path_cstring(out2), "/check") != NULL);
+ ATF_CHECK(strstr(atf_fs_path_cstring(err1), "/check") != NULL);
+ ATF_CHECK(strstr(atf_fs_path_cstring(err2), "/check") != NULL);
+
+ ATF_CHECK(strstr(atf_fs_path_cstring(out1), "/stdout") != NULL);
+ ATF_CHECK(strstr(atf_fs_path_cstring(out2), "/stdout") != NULL);
+ ATF_CHECK(strstr(atf_fs_path_cstring(err1), "/stderr") != NULL);
+ ATF_CHECK(strstr(atf_fs_path_cstring(err2), "/stderr") != NULL);
+
+ ATF_CHECK(strcmp(atf_fs_path_cstring(out1),
+ atf_fs_path_cstring(out2)) != 0);
+ ATF_CHECK(strcmp(atf_fs_path_cstring(err1),
+ atf_fs_path_cstring(err2)) != 0);
+
+#define CHECK_LINES(path, outname, resname) \
+ do { \
+ int fd = open(atf_fs_path_cstring(path), O_RDONLY); \
+ ATF_CHECK(fd != -1); \
+ check_line(fd, "Line 1 to " outname " for " resname); \
+ check_line(fd, "Line 2 to " outname " for " resname); \
+ close(fd); \
+ } while (false)
+
+ CHECK_LINES(out1, "stdout", "result1");
+ CHECK_LINES(out2, "stdout", "result2");
+ CHECK_LINES(err1, "stderr", "result1");
+ CHECK_LINES(err2, "stderr", "result2");
+
+#undef CHECK_LINES
+
+ atf_check_result_fini(&result2);
+ atf_check_result_fini(&result1);
+}
+
+ATF_TC(exec_umask);
+ATF_TC_HEAD(exec_umask, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks that atf_check_exec_array "
+ "correctly reports an error if the umask is too "
+ "restrictive to create temporary files");
+}
+ATF_TC_BODY(exec_umask, tc)
+{
+ atf_check_result_t result;
+ atf_fs_path_t process_helpers;
+ const char *argv[3];
+
+ get_process_helpers_path(tc, &process_helpers);
+ argv[0] = atf_fs_path_cstring(&process_helpers);
+ argv[1] = "exit-success";
+ argv[2] = NULL;
+
+ umask(0222);
+ atf_error_t err = atf_check_exec_array(argv, &result);
+ ATF_CHECK(atf_is_error(err));
+ ATF_CHECK(atf_error_is(err, "invalid_umask"));
+ atf_error_free(err);
+
+ atf_fs_path_fini(&process_helpers);
+}
+
+ATF_TC(exec_unknown);
+ATF_TC_HEAD(exec_unknown, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks that running a non-existing "
+ "binary is handled correctly");
+}
+ATF_TC_BODY(exec_unknown, tc)
+{
+ char buf[1024];
+ snprintf(buf, sizeof(buf), "%s/non-existent",
+ atf_config_get("atf_workdir"));
+
+ const char *argv[2];
+ argv[0] = buf;
+ argv[1] = NULL;
+
+ atf_check_result_t result;
+ RE(atf_check_exec_array(argv, &result));
+ ATF_CHECK(atf_check_result_exited(&result));
+ ATF_CHECK(atf_check_result_exitcode(&result) == 127);
+ atf_check_result_fini(&result);
+}
+
+/* ---------------------------------------------------------------------
+ * Tests cases for the header file.
+ * --------------------------------------------------------------------- */
+
+HEADER_TC(include, "atf-c/check.h");
+
+/* ---------------------------------------------------------------------
+ * Main.
+ * --------------------------------------------------------------------- */
+
+ATF_TP_ADD_TCS(tp)
+{
+ /* Add the test cases for the free functions. */
+ ATF_TP_ADD_TC(tp, build_c_o);
+ ATF_TP_ADD_TC(tp, build_cpp);
+ ATF_TP_ADD_TC(tp, build_cxx_o);
+ ATF_TP_ADD_TC(tp, exec_argv);
+ ATF_TP_ADD_TC(tp, exec_cleanup);
+ ATF_TP_ADD_TC(tp, exec_exitstatus);
+ ATF_TP_ADD_TC(tp, exec_list);
+ ATF_TP_ADD_TC(tp, exec_stdout_stderr);
+ ATF_TP_ADD_TC(tp, exec_umask);
+ ATF_TP_ADD_TC(tp, exec_unknown);
+
+ /* Add the test cases for the header file. */
+ ATF_TP_ADD_TC(tp, include);
+
+ return atf_no_error();
+}
diff --git a/external/bsd/atf/dist/atf-c/config.c b/external/bsd/atf/dist/atf-c/config.c
index 2b5cddbf801..8c3b26a499b 100644
--- a/external/bsd/atf/dist/atf-c/config.c
+++ b/external/bsd/atf/dist/atf-c/config.c
@@ -54,7 +54,6 @@ static struct var {
{ "atf_confdir", ATF_CONFDIR, NULL, false, },
{ "atf_includedir", ATF_INCLUDEDIR, NULL, false, },
{ "atf_libdir", ATF_LIBDIR, NULL, false, },
- { "atf_libexecdir", ATF_LIBEXECDIR, NULL, false, },
{ "atf_machine", ATF_MACHINE, NULL, false, },
{ "atf_m4", ATF_M4, NULL, false, },
{ "atf_pkgdatadir", ATF_PKGDATADIR, NULL, false, },
diff --git a/external/bsd/atf/dist/atf-c/config_test.c b/external/bsd/atf/dist/atf-c/config_test.c
new file mode 100644
index 00000000000..72052c9f315
--- /dev/null
+++ b/external/bsd/atf/dist/atf-c/config_test.c
@@ -0,0 +1,156 @@
+/*
+ * Automated Testing Framework (atf)
+ *
+ * Copyright (c) 2007, 2008, 2009 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 <stdio.h>
+#include <string.h>
+
+#include <atf-c.h>
+
+#include "atf-c/config.h"
+#include "atf-c/env.h"
+
+#include "test_helpers.h"
+
+static const char *test_value = "env-value";
+
+static struct varnames {
+ const char *lc;
+ const char *uc;
+ bool can_be_empty;
+} all_vars[] = {
+ { "atf_arch", "ATF_ARCH", false },
+ { "atf_build_cc", "ATF_BUILD_CC", false },
+ { "atf_build_cflags", "ATF_BUILD_CFLAGS", true },
+ { "atf_build_cpp", "ATF_BUILD_CPP", false },
+ { "atf_build_cppflags", "ATF_BUILD_CPPFLAGS", true },
+ { "atf_build_cxx", "ATF_BUILD_CXX", false },
+ { "atf_build_cxxflags", "ATF_BUILD_CXXFLAGS", true },
+ { "atf_confdir", "ATF_CONFDIR", false },
+ { "atf_includedir", "ATF_INCLUDEDIR", false },
+ { "atf_libdir", "ATF_LIBDIR", false },
+ { "atf_machine", "ATF_MACHINE", false },
+ { "atf_m4", "ATF_M4", false },
+ { "atf_pkgdatadir", "ATF_PKGDATADIR", false },
+ { "atf_shell", "ATF_SHELL", false },
+ { "atf_workdir", "ATF_WORKDIR", false },
+ { NULL, NULL, false }
+};
+
+/* ---------------------------------------------------------------------
+ * Auxiliary functions.
+ * --------------------------------------------------------------------- */
+
+void __atf_config_reinit(void);
+
+static
+void
+unset_all(void)
+{
+ const struct varnames *v;
+ for (v = all_vars; v->lc != NULL; v++)
+ RE(atf_env_unset(v->uc));
+}
+
+static
+void
+compare_one(const char *var, const char *expvalue)
+{
+ const struct varnames *v;
+
+ printf("Checking that %s is set to %s\n", var, expvalue);
+
+ for (v = all_vars; v->lc != NULL; v++) {
+ if (strcmp(v->lc, var) == 0)
+ ATF_CHECK_STREQ(atf_config_get(v->lc), test_value);
+ else
+ ATF_CHECK(strcmp(atf_config_get(v->lc), test_value) != 0);
+ }
+}
+
+/* ---------------------------------------------------------------------
+ * Test cases for the free functions.
+ * --------------------------------------------------------------------- */
+
+ATF_TC(get);
+ATF_TC_HEAD(get, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests the atf_config_get function");
+}
+ATF_TC_BODY(get, tc)
+{
+ const struct varnames *v;
+
+ /* Unset all known environment variables and make sure the built-in
+ * values do not match the bogus value we will use for testing. */
+ unset_all();
+ __atf_config_reinit();
+ for (v = all_vars; v->lc != NULL; v++)
+ ATF_CHECK(strcmp(atf_config_get(v->lc), test_value) != 0);
+
+ /* Test the behavior of empty values. */
+ for (v = all_vars; v->lc != NULL; v++) {
+ unset_all();
+ if (strcmp(atf_config_get(v->lc), "") != 0) {
+ RE(atf_env_set(v->uc, ""));
+ __atf_config_reinit();
+ if (v->can_be_empty)
+ ATF_CHECK(strlen(atf_config_get(v->lc)) == 0);
+ else
+ ATF_CHECK(strlen(atf_config_get(v->lc)) > 0);
+ }
+ }
+
+ /* Check if every variable is recognized individually. */
+ for (v = all_vars; v->lc != NULL; v++) {
+ unset_all();
+ RE(atf_env_set(v->uc, test_value));
+ __atf_config_reinit();
+ compare_one(v->lc, test_value);
+ }
+}
+
+/* ---------------------------------------------------------------------
+ * Tests cases for the header file.
+ * --------------------------------------------------------------------- */
+
+HEADER_TC(include, "atf-c/config.h");
+
+/* ---------------------------------------------------------------------
+ * Main.
+ * --------------------------------------------------------------------- */
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, get);
+
+ /* Add the test cases for the header file. */
+ ATF_TP_ADD_TC(tp, include);
+
+ return atf_no_error();
+}
diff --git a/external/bsd/atf/dist/atf-c/dynstr_test.c b/external/bsd/atf/dist/atf-c/dynstr_test.c
new file mode 100644
index 00000000000..62df205e1db
--- /dev/null
+++ b/external/bsd/atf/dist/atf-c/dynstr_test.c
@@ -0,0 +1,647 @@
+/*
+ * Automated Testing Framework (atf)
+ *
+ * Copyright (c) 2008, 2009, 2010 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdarg.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <atf-c.h>
+
+#include "atf-c/dynstr.h"
+
+#include "test_helpers.h"
+
+/* ---------------------------------------------------------------------
+ * Tests for the "atf_dynstr" type.
+ * --------------------------------------------------------------------- */
+
+/*
+ * Constructors and destructors.
+ */
+
+ATF_TC(init);
+ATF_TC_HEAD(init, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks the empty constructor");
+}
+ATF_TC_BODY(init, tc)
+{
+ atf_dynstr_t str;
+
+ RE(atf_dynstr_init(&str));
+ ATF_REQUIRE_EQ(atf_dynstr_length(&str), 0);
+ ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "") == 0);
+ atf_dynstr_fini(&str);
+}
+
+static
+void
+init_fmt(atf_dynstr_t *str, const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ RE(atf_dynstr_init_ap(str, fmt, ap));
+ va_end(ap);
+}
+
+ATF_TC(init_ap);
+ATF_TC_HEAD(init_ap, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks the formatted constructor using "
+ "a va_list argument");
+}
+ATF_TC_BODY(init_ap, tc)
+{
+ atf_dynstr_t str;
+
+ init_fmt(&str, "String 1");
+ ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "String 1") == 0);
+ atf_dynstr_fini(&str);
+
+ init_fmt(&str, "String %d", 2);
+ ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "String 2") == 0);
+ atf_dynstr_fini(&str);
+
+ init_fmt(&str, "%s %d", "String", 3);
+ ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "String 3") == 0);
+ atf_dynstr_fini(&str);
+
+ init_fmt(&str, "%s%s%s%s%s%s%s", "This ", "should ", "be ", "a ",
+ "large ", "string ", "aaaabbbbccccdddd");
+ ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str),
+ "This should be a large string "
+ "aaaabbbbccccdddd") == 0);
+ atf_dynstr_fini(&str);
+}
+
+ATF_TC(init_fmt);
+ATF_TC_HEAD(init_fmt, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks the formatted constructor using "
+ "a variable list of parameters");
+}
+ATF_TC_BODY(init_fmt, tc)
+{
+ atf_dynstr_t str;
+
+ RE(atf_dynstr_init_fmt(&str, "String 1"));
+ ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "String 1") == 0);
+ atf_dynstr_fini(&str);
+
+ RE(atf_dynstr_init_fmt(&str, "String %d", 2));
+ ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "String 2") == 0);
+ atf_dynstr_fini(&str);
+
+ RE(atf_dynstr_init_fmt(&str, "%s %d", "String", 3));
+ ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "String 3") == 0);
+ atf_dynstr_fini(&str);
+
+ RE(atf_dynstr_init_fmt(&str, "%s%s%s%s%s%s%s", "This ", "should ",
+ "be ", "a ", "large ", "string ",
+ "aaaabbbbccccdddd"));
+ ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str),
+ "This should be a large string "
+ "aaaabbbbccccdddd") == 0);
+ atf_dynstr_fini(&str);
+}
+
+ATF_TC(init_raw);
+ATF_TC_HEAD(init_raw, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks the construction of a string "
+ "using a raw memory pointer");
+}
+ATF_TC_BODY(init_raw, tc)
+{
+ const char *src = "String 1, String 2";
+ atf_dynstr_t str;
+
+ RE(atf_dynstr_init_raw(&str, src, 0));
+ ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "") == 0);
+ atf_dynstr_fini(&str);
+
+ RE(atf_dynstr_init_raw(&str, src, 8));
+ ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "String 1") == 0);
+ atf_dynstr_fini(&str);
+
+ RE(atf_dynstr_init_raw(&str, src + 10, 8));
+ ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "String 2") == 0);
+ atf_dynstr_fini(&str);
+
+ RE(atf_dynstr_init_raw(&str, "String\0Lost", 11));
+ ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "String") == 0);
+ atf_dynstr_fini(&str);
+
+ {
+ atf_error_t err = atf_dynstr_init_raw(&str, "NULL", SIZE_MAX - 1);
+ ATF_REQUIRE(atf_is_error(err));
+ ATF_REQUIRE(atf_error_is(err, "no_memory"));
+ atf_error_free(err);
+ }
+}
+
+ATF_TC(init_rep);
+ATF_TC_HEAD(init_rep, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks the construction of a string by "
+ "repeating characters");
+}
+ATF_TC_BODY(init_rep, tc)
+{
+ const size_t maxlen = 8192;
+ char buf[maxlen + 1];
+ size_t i;
+
+ buf[0] = '\0';
+
+ for (i = 0; i < maxlen; i++) {
+ atf_dynstr_t str;
+
+ RE(atf_dynstr_init_rep(&str, i, 'a'));
+
+ if (strcmp(atf_dynstr_cstring(&str), buf) != 0) {
+ fprintf(stderr, "Failed at iteration %zd\n", i);
+ atf_tc_fail("Failed to construct dynstr by repeating %zd "
+ "times the '%c' character", i, 'a');
+ }
+
+ atf_dynstr_fini(&str);
+
+ strcat(buf, "a");
+ }
+
+ {
+ atf_dynstr_t str;
+ atf_error_t err;
+
+ err = atf_dynstr_init_rep(&str, SIZE_MAX, 'a');
+ ATF_REQUIRE(atf_is_error(err));
+ ATF_REQUIRE(atf_error_is(err, "no_memory"));
+ atf_error_free(err);
+
+ err = atf_dynstr_init_rep(&str, SIZE_MAX - 1, 'a');
+ ATF_REQUIRE(atf_is_error(err));
+ ATF_REQUIRE(atf_error_is(err, "no_memory"));
+ atf_error_free(err);
+ }
+}
+
+ATF_TC(init_substr);
+ATF_TC_HEAD(init_substr, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks the construction of a string "
+ "using a substring of another one");
+}
+ATF_TC_BODY(init_substr, tc)
+{
+ atf_dynstr_t src;
+ atf_dynstr_t str;
+
+ RE(atf_dynstr_init_fmt(&src, "Str 1, Str 2"));
+
+ RE(atf_dynstr_init_substr(&str, &src, 0, 0));
+ ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "") == 0);
+ atf_dynstr_fini(&str);
+
+ RE(atf_dynstr_init_substr(&str, &src, 0, atf_dynstr_npos));
+ ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "Str 1, Str 2") == 0);
+ atf_dynstr_fini(&str);
+
+ RE(atf_dynstr_init_substr(&str, &src, 0, 100));
+ ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "Str 1, Str 2") == 0);
+ atf_dynstr_fini(&str);
+
+ RE(atf_dynstr_init_substr(&str, &src, 0, 5));
+ ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "Str 1") == 0);
+ atf_dynstr_fini(&str);
+
+ RE(atf_dynstr_init_substr(&str, &src, 100, atf_dynstr_npos));
+ ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "") == 0);
+ atf_dynstr_fini(&str);
+
+ RE(atf_dynstr_init_substr(&str, &src, 7, atf_dynstr_npos));
+ ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "Str 2") == 0);
+ atf_dynstr_fini(&str);
+
+ atf_dynstr_fini(&src);
+}
+
+ATF_TC(copy);
+ATF_TC_HEAD(copy, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks the atf_dynstr_copy constructor");
+}
+ATF_TC_BODY(copy, tc)
+{
+ atf_dynstr_t str, str2;
+
+ RE(atf_dynstr_init_fmt(&str, "Test string"));
+ RE(atf_dynstr_copy(&str2, &str));
+
+ ATF_REQUIRE(atf_equal_dynstr_dynstr(&str, &str2));
+
+ RE(atf_dynstr_append_fmt(&str2, " non-shared text"));
+
+ ATF_REQUIRE(!atf_equal_dynstr_dynstr(&str, &str2));
+
+ atf_dynstr_fini(&str2);
+ atf_dynstr_fini(&str);
+}
+
+ATF_TC(fini_disown);
+ATF_TC_HEAD(fini_disown, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks grabbing ownership of the "
+ "internal plain C string");
+}
+ATF_TC_BODY(fini_disown, tc)
+{
+ const char *cstr;
+ char *cstr2;
+ atf_dynstr_t str;
+
+ RE(atf_dynstr_init_fmt(&str, "Test string 1"));
+ cstr = atf_dynstr_cstring(&str);
+ cstr2 = atf_dynstr_fini_disown(&str);
+
+ ATF_REQUIRE_EQ(cstr, cstr2);
+ free(cstr2);
+}
+
+/*
+ * Getters.
+ */
+
+ATF_TC(cstring);
+ATF_TC_HEAD(cstring, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks the method to obtain a plain C "
+ "string");
+}
+ATF_TC_BODY(cstring, tc)
+{
+ const char *cstr;
+ atf_dynstr_t str;
+
+ RE(atf_dynstr_init_fmt(&str, "Test string 1"));
+ cstr = atf_dynstr_cstring(&str);
+ ATF_REQUIRE(cstr != NULL);
+ ATF_REQUIRE(strcmp(cstr, "Test string 1") == 0);
+ atf_dynstr_fini(&str);
+
+ RE(atf_dynstr_init_fmt(&str, "Test string 2"));
+ cstr = atf_dynstr_cstring(&str);
+ ATF_REQUIRE(cstr != NULL);
+ ATF_REQUIRE(strcmp(cstr, "Test string 2") == 0);
+ atf_dynstr_fini(&str);
+}
+
+ATF_TC(length);
+ATF_TC_HEAD(length, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks the method to obtain the length");
+}
+ATF_TC_BODY(length, tc)
+{
+ size_t i;
+
+ for (i = 0; i < 8192; i++) {
+ atf_dynstr_t str;
+ RE(atf_dynstr_init_rep(&str, i, 'a'));
+ ATF_REQUIRE_EQ(atf_dynstr_length(&str), i);
+ atf_dynstr_fini(&str);
+ }
+}
+
+ATF_TC(rfind_ch);
+ATF_TC_HEAD(rfind_ch, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks the method to locate the first "
+ "occurrence of a character starting from the end");
+}
+ATF_TC_BODY(rfind_ch, tc)
+{
+ atf_dynstr_t str;
+
+ RE(atf_dynstr_init_fmt(&str, "Foo1/Bar2/,.Baz"));
+
+ ATF_REQUIRE_EQ(atf_dynstr_rfind_ch(&str, '\0'), atf_dynstr_npos);
+
+ ATF_REQUIRE_EQ(atf_dynstr_rfind_ch(&str, '0'), atf_dynstr_npos);
+ ATF_REQUIRE_EQ(atf_dynstr_rfind_ch(&str, 'b'), atf_dynstr_npos);
+
+ ATF_REQUIRE_EQ(atf_dynstr_rfind_ch(&str, 'F'), 0);
+ ATF_REQUIRE_EQ(atf_dynstr_rfind_ch(&str, '/'), 9);
+ ATF_REQUIRE_EQ(atf_dynstr_rfind_ch(&str, 'a'), 13);
+ ATF_REQUIRE_EQ(atf_dynstr_rfind_ch(&str, 'z'), 14);
+
+ atf_dynstr_fini(&str);
+}
+
+/*
+ * Modifiers.
+ */
+
+static
+void
+check_append(atf_error_t (*append)(atf_dynstr_t *, const char *, ...))
+{
+ const size_t maxlen = 8192;
+ char buf[maxlen + 1];
+ size_t i;
+ atf_dynstr_t str;
+
+ printf("Appending with plain string\n");
+ buf[0] = '\0';
+ RE(atf_dynstr_init(&str));
+ for (i = 0; i < maxlen; i++) {
+ if (strcmp(atf_dynstr_cstring(&str), buf) != 0) {
+ fprintf(stderr, "Failed at iteration %zd\n", i);
+ atf_tc_fail("Failed to append character at iteration %zd", i);
+ }
+
+ RE(append(&str, "a"));
+ strcat(buf, "a");
+ }
+ atf_dynstr_fini(&str);
+
+ printf("Appending with formatted string\n");
+ buf[0] = '\0';
+ RE(atf_dynstr_init(&str));
+ for (i = 0; i < maxlen; i++) {
+ if (strcmp(atf_dynstr_cstring(&str), buf) != 0) {
+ fprintf(stderr, "Failed at iteration %zd\n", i);
+ atf_tc_fail("Failed to append character at iteration %zd", i);
+ }
+
+ RE(append(&str, "%s", "a"));
+ strcat(buf, "a");
+ }
+ atf_dynstr_fini(&str);
+}
+
+static
+atf_error_t
+append_ap_aux(atf_dynstr_t *str, const char *fmt, ...)
+{
+ va_list ap;
+ atf_error_t err;
+
+ va_start(ap, fmt);
+ err = atf_dynstr_append_ap(str, fmt, ap);
+ va_end(ap);
+
+ return err;
+}
+
+ATF_TC(append_ap);
+ATF_TC_HEAD(append_ap, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks that appending a string to "
+ "another one works");
+}
+ATF_TC_BODY(append_ap, tc)
+{
+ check_append(append_ap_aux);
+}
+
+ATF_TC(append_fmt);
+ATF_TC_HEAD(append_fmt, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks that appending a string to "
+ "another one works");
+}
+ATF_TC_BODY(append_fmt, tc)
+{
+ check_append(atf_dynstr_append_fmt);
+}
+
+ATF_TC(clear);
+ATF_TC_HEAD(clear, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks clearing a string");
+}
+ATF_TC_BODY(clear, tc)
+{
+ atf_dynstr_t str;
+
+ printf("Clear an empty string\n");
+ RE(atf_dynstr_init(&str));
+ atf_dynstr_clear(&str);
+ ATF_REQUIRE_EQ(atf_dynstr_length(&str), 0);
+ ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "") == 0);
+ atf_dynstr_fini(&str);
+
+ printf("Clear a non-empty string\n");
+ RE(atf_dynstr_init_fmt(&str, "Not empty"));
+ ATF_REQUIRE_EQ(atf_dynstr_length(&str), strlen("Not empty"));
+ ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "Not empty") == 0);
+ atf_dynstr_clear(&str);
+ ATF_REQUIRE_EQ(atf_dynstr_length(&str), 0);
+ ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "") == 0);
+ atf_dynstr_fini(&str);
+}
+
+static
+void
+check_prepend(atf_error_t (*prepend)(atf_dynstr_t *, const char *, ...))
+{
+ const size_t maxlen = 8192;
+ char buf[maxlen + 1];
+ size_t i;
+ atf_dynstr_t str;
+
+ printf("Prepending with plain string\n");
+ buf[0] = '\0';
+ RE(atf_dynstr_init(&str));
+ for (i = 0; i < maxlen; i++) {
+ if (strcmp(atf_dynstr_cstring(&str), buf) != 0) {
+ fprintf(stderr, "Failed at iteration %zd\n", i);
+ atf_tc_fail("Failed to prepend character at iteration %zd", i);
+ }
+
+ memmove(buf + 1, buf, i + 1);
+ if (i % 2 == 0) {
+ RE(prepend(&str, "%s", "a"));
+ buf[0] = 'a';
+ } else {
+ RE(prepend(&str, "%s", "b"));
+ buf[0] = 'b';
+ }
+ }
+ atf_dynstr_fini(&str);
+
+ printf("Prepending with formatted string\n");
+ buf[0] = '\0';
+ RE(atf_dynstr_init(&str));
+ for (i = 0; i < maxlen; i++) {
+ if (strcmp(atf_dynstr_cstring(&str), buf) != 0) {
+ fprintf(stderr, "Failed at iteration %zd\n", i);
+ atf_tc_fail("Failed to prepend character at iteration %zd", i);
+ }
+
+ memmove(buf + 1, buf, i + 1);
+ if (i % 2 == 0) {
+ RE(prepend(&str, "%s", "a"));
+ buf[0] = 'a';
+ } else {
+ RE(prepend(&str, "%s", "b"));
+ buf[0] = 'b';
+ }
+ }
+ atf_dynstr_fini(&str);
+}
+
+static
+atf_error_t
+prepend_ap_aux(atf_dynstr_t *str, const char *fmt, ...)
+{
+ va_list ap;
+ atf_error_t err;
+
+ va_start(ap, fmt);
+ err = atf_dynstr_prepend_ap(str, fmt, ap);
+ va_end(ap);
+
+ return err;
+}
+
+ATF_TC(prepend_ap);
+ATF_TC_HEAD(prepend_ap, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks that prepending a string to "
+ "another one works");
+}
+ATF_TC_BODY(prepend_ap, tc)
+{
+ check_prepend(prepend_ap_aux);
+}
+
+ATF_TC(prepend_fmt);
+ATF_TC_HEAD(prepend_fmt, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks that prepending a string to "
+ "another one works");
+}
+ATF_TC_BODY(prepend_fmt, tc)
+{
+ check_prepend(atf_dynstr_prepend_fmt);
+}
+
+/*
+ * Operators.
+ */
+
+ATF_TC(equal_cstring);
+ATF_TC_HEAD(equal_cstring, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks the atf_equal_dynstr_cstring "
+ "function");
+}
+ATF_TC_BODY(equal_cstring, tc)
+{
+ atf_dynstr_t str;
+
+ RE(atf_dynstr_init(&str));
+ ATF_REQUIRE( atf_equal_dynstr_cstring(&str, ""));
+ ATF_REQUIRE(!atf_equal_dynstr_cstring(&str, "Test"));
+ atf_dynstr_fini(&str);
+
+ RE(atf_dynstr_init_fmt(&str, "Test"));
+ ATF_REQUIRE( atf_equal_dynstr_cstring(&str, "Test"));
+ ATF_REQUIRE(!atf_equal_dynstr_cstring(&str, ""));
+ ATF_REQUIRE(!atf_equal_dynstr_cstring(&str, "Tes"));
+ ATF_REQUIRE(!atf_equal_dynstr_cstring(&str, "Test "));
+ atf_dynstr_fini(&str);
+}
+
+ATF_TC(equal_dynstr);
+ATF_TC_HEAD(equal_dynstr, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks the atf_equal_dynstr_dynstr "
+ "function");
+}
+ATF_TC_BODY(equal_dynstr, tc)
+{
+ atf_dynstr_t str, str2;
+
+ RE(atf_dynstr_init(&str));
+ RE(atf_dynstr_init_fmt(&str2, "Test"));
+ ATF_REQUIRE( atf_equal_dynstr_dynstr(&str, &str));
+ ATF_REQUIRE(!atf_equal_dynstr_dynstr(&str, &str2));
+ atf_dynstr_fini(&str2);
+ atf_dynstr_fini(&str);
+}
+
+/* ---------------------------------------------------------------------
+ * Tests cases for the header file.
+ * --------------------------------------------------------------------- */
+
+HEADER_TC(include, "atf-c/dynstr.h");
+
+/* ---------------------------------------------------------------------
+ * Main.
+ * --------------------------------------------------------------------- */
+
+ATF_TP_ADD_TCS(tp)
+{
+ /* Constructors and destructors. */
+ ATF_TP_ADD_TC(tp, init);
+ ATF_TP_ADD_TC(tp, init_ap);
+ ATF_TP_ADD_TC(tp, init_fmt);
+ ATF_TP_ADD_TC(tp, init_raw);
+ ATF_TP_ADD_TC(tp, init_rep);
+ ATF_TP_ADD_TC(tp, init_substr);
+ ATF_TP_ADD_TC(tp, copy);
+ ATF_TP_ADD_TC(tp, fini_disown);
+
+ /* Getters. */
+ ATF_TP_ADD_TC(tp, cstring);
+ ATF_TP_ADD_TC(tp, length);
+ ATF_TP_ADD_TC(tp, rfind_ch);
+
+ /* Modifiers. */
+ ATF_TP_ADD_TC(tp, append_ap);
+ ATF_TP_ADD_TC(tp, append_fmt);
+ ATF_TP_ADD_TC(tp, clear);
+ ATF_TP_ADD_TC(tp, prepend_ap);
+ ATF_TP_ADD_TC(tp, prepend_fmt);
+
+ /* Operators. */
+ ATF_TP_ADD_TC(tp, equal_cstring);
+ ATF_TP_ADD_TC(tp, equal_dynstr);
+
+ /* Add the test cases for the header file. */
+ ATF_TP_ADD_TC(tp, include);
+
+ return atf_no_error();
+}
diff --git a/external/bsd/atf/dist/atf-c/env_test.c b/external/bsd/atf/dist/atf-c/env_test.c
new file mode 100644
index 00000000000..c5ac6c3979a
--- /dev/null
+++ b/external/bsd/atf/dist/atf-c/env_test.c
@@ -0,0 +1,126 @@
+/*
+ * Automated Testing Framework (atf)
+ *
+ * Copyright (c) 2007, 2008, 2009 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 <stdlib.h>
+#include <string.h>
+
+#include <atf-c.h>
+
+#include "atf-c/env.h"
+#include "atf-c/text.h"
+
+#include "test_helpers.h"
+
+/* ---------------------------------------------------------------------
+ * Test cases for the free functions.
+ * --------------------------------------------------------------------- */
+
+ATF_TC(has);
+ATF_TC_HEAD(has, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests the atf_env_has function");
+}
+ATF_TC_BODY(has, tc)
+{
+ ATF_REQUIRE(atf_env_has("PATH"));
+ ATF_REQUIRE(!atf_env_has("_UNDEFINED_VARIABLE_"));
+}
+
+ATF_TC(get);
+ATF_TC_HEAD(get, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests the atf_env_get function");
+}
+ATF_TC_BODY(get, tc)
+{
+ const char *val;
+
+ ATF_REQUIRE(atf_env_has("PATH"));
+
+ val = atf_env_get("PATH");
+ ATF_REQUIRE(strlen(val) > 0);
+ ATF_REQUIRE(strchr(val, ':') != NULL);
+}
+
+ATF_TC(set);
+ATF_TC_HEAD(set, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests the atf_env_set function");
+}
+ATF_TC_BODY(set, tc)
+{
+ char *oldval;
+
+ ATF_REQUIRE(atf_env_has("PATH"));
+ RE(atf_text_format(&oldval, "%s", atf_env_get("PATH")));
+ RE(atf_env_set("PATH", "foo-bar"));
+ ATF_REQUIRE(strcmp(atf_env_get("PATH"), oldval) != 0);
+ ATF_REQUIRE(strcmp(atf_env_get("PATH"), "foo-bar") == 0);
+ free(oldval);
+
+ ATF_REQUIRE(!atf_env_has("_UNDEFINED_VARIABLE_"));
+ RE(atf_env_set("_UNDEFINED_VARIABLE_", "foo2-bar2"));
+ ATF_REQUIRE(strcmp(atf_env_get("_UNDEFINED_VARIABLE_"),
+ "foo2-bar2") == 0);
+}
+
+ATF_TC(unset);
+ATF_TC_HEAD(unset, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests the atf_env_unset function");
+}
+ATF_TC_BODY(unset, tc)
+{
+ ATF_REQUIRE(atf_env_has("PATH"));
+ RE(atf_env_unset("PATH"));
+ ATF_REQUIRE(!atf_env_has("PATH"));
+}
+
+/* ---------------------------------------------------------------------
+ * Tests cases for the header file.
+ * --------------------------------------------------------------------- */
+
+HEADER_TC(include, "atf-c/env.h");
+
+/* ---------------------------------------------------------------------
+ * Main.
+ * --------------------------------------------------------------------- */
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, has);
+ ATF_TP_ADD_TC(tp, get);
+ ATF_TP_ADD_TC(tp, set);
+ ATF_TP_ADD_TC(tp, unset);
+
+ /* Add the test cases for the header file. */
+ ATF_TP_ADD_TC(tp, include);
+
+ return atf_no_error();
+}
diff --git a/external/bsd/atf/dist/atf-c/error_test.c b/external/bsd/atf/dist/atf-c/error_test.c
new file mode 100644
index 00000000000..bebcd727292
--- /dev/null
+++ b/external/bsd/atf/dist/atf-c/error_test.c
@@ -0,0 +1,311 @@
+/*
+ * Automated Testing Framework (atf)
+ *
+ * Copyright (c) 2008, 2009, 2010 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <errno.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <atf-c.h>
+
+#include "atf-c/error.h"
+
+#include "test_helpers.h"
+
+/* ---------------------------------------------------------------------
+ * Auxiliary functions.
+ * --------------------------------------------------------------------- */
+
+static
+void
+test_format(const atf_error_t err, char *buf, size_t buflen)
+{
+ snprintf(buf, buflen, "Test formatting function");
+}
+
+/* ---------------------------------------------------------------------
+ * Tests for the "atf_error" type.
+ * --------------------------------------------------------------------- */
+
+ATF_TC(error_new);
+ATF_TC_HEAD(error_new, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks the construction of an error "
+ "object");
+}
+ATF_TC_BODY(error_new, tc)
+{
+ atf_error_t err;
+ int data;
+
+ err = atf_error_new("test_error", NULL, 0, NULL);
+ ATF_REQUIRE(atf_error_is(err, "test_error"));
+ ATF_REQUIRE(!atf_error_is(err, "unknown_error"));
+ ATF_REQUIRE(atf_error_data(err) == NULL);
+ atf_error_free(err);
+
+ data = 5;
+ err = atf_error_new("test_data_error", &data, sizeof(data), NULL);
+ ATF_REQUIRE(atf_error_is(err, "test_data_error"));
+ ATF_REQUIRE(!atf_error_is(err, "unknown_error"));
+ ATF_REQUIRE(atf_error_data(err) != NULL);
+ ATF_REQUIRE_EQ(*((const int *)atf_error_data(err)), 5);
+ atf_error_free(err);
+}
+
+ATF_TC(error_new_wo_memory);
+ATF_TC_HEAD(error_new_wo_memory, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks that an unavailable memory error "
+ "raised when constructing an error object "
+ "is properly converted to the no_memory "
+ "static error type");
+}
+ATF_TC_BODY(error_new_wo_memory, tc)
+{
+ atf_error_t err;
+ void *invalid;
+
+ invalid = (void *)1;
+
+ err = atf_error_new("test_error", invalid, SIZE_MAX, NULL);
+ ATF_REQUIRE(atf_error_is(err, "no_memory"));
+ ATF_REQUIRE(atf_error_data(err) == NULL);
+ atf_error_free(err);
+}
+
+ATF_TC(no_error);
+ATF_TC_HEAD(no_error, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks that constructing a non-error "
+ "object works");
+}
+ATF_TC_BODY(no_error, tc)
+{
+ atf_error_t err;
+
+ err = atf_no_error();
+ ATF_REQUIRE(!atf_is_error(err));
+}
+
+ATF_TC(is_error);
+ATF_TC_HEAD(is_error, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks the is_error method to determine "
+ "if an error object holds success or an error");
+}
+ATF_TC_BODY(is_error, tc)
+{
+ atf_error_t err;
+
+ err = atf_no_error();
+ ATF_REQUIRE(!atf_is_error(err));
+
+ err = atf_error_new("test_error", NULL, 0, NULL);
+ ATF_REQUIRE(atf_is_error(err));
+ atf_error_free(err);
+}
+
+ATF_TC(format);
+ATF_TC_HEAD(format, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks the default formatting function "
+ "and the ability to change it");
+}
+ATF_TC_BODY(format, tc)
+{
+ atf_error_t err;
+ char buf[1024];
+
+ printf("Testing default formatting function\n");
+ err = atf_error_new("test_error", NULL, 0, NULL);
+ atf_error_format(err, buf, sizeof(buf));
+ printf("Error string is: %s\n", buf);
+ ATF_REQUIRE(strcmp(buf, "Error 'test_error'") == 0);
+ atf_error_free(err);
+
+ printf("Testing custom formatting function\n");
+ err = atf_error_new("test_error", NULL, 0, test_format);
+ atf_error_format(err, buf, sizeof(buf));
+ printf("Error string is: %s\n", buf);
+ ATF_REQUIRE(strcmp(buf, "Test formatting function") == 0);
+ atf_error_free(err);
+}
+
+/* ---------------------------------------------------------------------
+ * Tests for the "libc" error.
+ * --------------------------------------------------------------------- */
+
+ATF_TC(libc_new);
+ATF_TC_HEAD(libc_new, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks the construction of libc errors");
+}
+ATF_TC_BODY(libc_new, tc)
+{
+ atf_error_t err;
+
+ err = atf_libc_error(ENOMEM, "Test message 1");
+ ATF_REQUIRE(atf_error_is(err, "libc"));
+ ATF_REQUIRE_EQ(atf_libc_error_code(err), ENOMEM);
+ ATF_REQUIRE(strcmp(atf_libc_error_msg(err), "Test message 1") == 0);
+ atf_error_free(err);
+
+ err = atf_libc_error(EPERM, "%s message %d", "Test", 2);
+ ATF_REQUIRE(atf_error_is(err, "libc"));
+ ATF_REQUIRE_EQ(atf_libc_error_code(err), EPERM);
+ ATF_REQUIRE(strcmp(atf_libc_error_msg(err), "Test message 2") == 0);
+ atf_error_free(err);
+}
+
+ATF_TC(libc_format);
+ATF_TC_HEAD(libc_format, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks the formatting of libc errors");
+}
+ATF_TC_BODY(libc_format, tc)
+{
+ atf_error_t err;
+ char buf[1024];
+
+ err = atf_libc_error(ENOMEM, "Test message 1");
+ atf_error_format(err, buf, sizeof(buf));
+ ATF_REQUIRE(strstr(buf, strerror(ENOMEM)) != NULL);
+ ATF_REQUIRE(strstr(buf, "Test message 1") != NULL);
+ atf_error_free(err);
+
+ err = atf_libc_error(EPERM, "Test message 2");
+ atf_error_format(err, buf, sizeof(buf));
+ ATF_REQUIRE(strstr(buf, strerror(EPERM)) != NULL);
+ ATF_REQUIRE(strstr(buf, "Test message 2") != NULL);
+ atf_error_free(err);
+
+ err = atf_libc_error(EPERM, "%s message %d", "Test", 3);
+ atf_error_format(err, buf, sizeof(buf));
+ ATF_REQUIRE(strstr(buf, strerror(EPERM)) != NULL);
+ ATF_REQUIRE(strstr(buf, "Test message 3") != NULL);
+ atf_error_free(err);
+}
+
+/* ---------------------------------------------------------------------
+ * Tests for the "no_memory" error.
+ * --------------------------------------------------------------------- */
+
+ATF_TC(no_memory_new);
+ATF_TC_HEAD(no_memory_new, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks the construction of no_memory "
+ "errors");
+}
+ATF_TC_BODY(no_memory_new, tc)
+{
+ atf_error_t err;
+
+ err = atf_no_memory_error();
+ ATF_REQUIRE(atf_error_is(err, "no_memory"));
+ ATF_REQUIRE(atf_error_data(err) == NULL);
+ atf_error_free(err);
+}
+
+ATF_TC(no_memory_format);
+ATF_TC_HEAD(no_memory_format, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks the formatting of no_memory "
+ "errors");
+}
+ATF_TC_BODY(no_memory_format, tc)
+{
+ atf_error_t err;
+ char buf[1024];
+
+ err = atf_no_memory_error();
+ atf_error_format(err, buf, sizeof(buf));
+ ATF_REQUIRE(strcmp(buf, "Not enough memory") == 0);
+ atf_error_free(err);
+}
+
+ATF_TC(no_memory_twice);
+ATF_TC_HEAD(no_memory_twice, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks the construction of no_memory "
+ "errors multiple times, as this error is initialized "
+ "statically");
+}
+ATF_TC_BODY(no_memory_twice, tc)
+{
+ {
+ atf_error_t err = atf_no_memory_error();
+ ATF_REQUIRE(atf_error_is(err, "no_memory"));
+ ATF_REQUIRE(atf_error_data(err) == NULL);
+ atf_error_free(err);
+ }
+
+ {
+ atf_error_t err = atf_no_memory_error();
+ ATF_REQUIRE(atf_error_is(err, "no_memory"));
+ ATF_REQUIRE(atf_error_data(err) == NULL);
+ atf_error_free(err);
+ }
+}
+
+/* ---------------------------------------------------------------------
+ * Tests cases for the header file.
+ * --------------------------------------------------------------------- */
+
+HEADER_TC(include, "atf-c/error.h");
+HEADER_TC(include_fwd, "atf-c/error_fwd.h");
+
+/* ---------------------------------------------------------------------
+ * Main.
+ * --------------------------------------------------------------------- */
+
+ATF_TP_ADD_TCS(tp)
+{
+ /* Add the tests for the "atf_error" type. */
+ ATF_TP_ADD_TC(tp, error_new);
+ ATF_TP_ADD_TC(tp, error_new_wo_memory);
+ ATF_TP_ADD_TC(tp, no_error);
+ ATF_TP_ADD_TC(tp, is_error);
+ ATF_TP_ADD_TC(tp, format);
+
+ /* Add the tests for the "libc" error. */
+ ATF_TP_ADD_TC(tp, libc_new);
+ ATF_TP_ADD_TC(tp, libc_format);
+
+ /* Add the tests for the "no_memory" error. */
+ ATF_TP_ADD_TC(tp, no_memory_new);
+ ATF_TP_ADD_TC(tp, no_memory_format);
+ ATF_TP_ADD_TC(tp, no_memory_twice);
+
+ /* Add the test cases for the header file. */
+ ATF_TP_ADD_TC(tp, include);
+ ATF_TP_ADD_TC(tp, include_fwd);
+
+ return atf_no_error();
+}
diff --git a/external/bsd/atf/dist/atf-c/fs.h b/external/bsd/atf/dist/atf-c/fs.h
index 468562d4206..cbec8d1328e 100644
--- a/external/bsd/atf/dist/atf-c/fs.h
+++ b/external/bsd/atf/dist/atf-c/fs.h
@@ -121,14 +121,12 @@ extern const int atf_fs_access_r;
extern const int atf_fs_access_w;
extern const int atf_fs_access_x;
-atf_error_t atf_fs_cleanup(const atf_fs_path_t *);
atf_error_t atf_fs_eaccess(const atf_fs_path_t *, int);
atf_error_t atf_fs_exists(const atf_fs_path_t *, bool *);
atf_error_t atf_fs_getcwd(atf_fs_path_t *);
atf_error_t atf_fs_mkdtemp(atf_fs_path_t *);
atf_error_t atf_fs_mkstemp(atf_fs_path_t *, int *);
atf_error_t atf_fs_rmdir(const atf_fs_path_t *);
-atf_error_t atf_fs_set_immutable(const atf_fs_path_t *, bool, bool *);
atf_error_t atf_fs_unlink(const atf_fs_path_t *);
#endif /* !defined(ATF_C_FS_H) */
diff --git a/external/bsd/atf/dist/atf-c/fs_test.c b/external/bsd/atf/dist/atf-c/fs_test.c
new file mode 100644
index 00000000000..5007ee65618
--- /dev/null
+++ b/external/bsd/atf/dist/atf-c/fs_test.c
@@ -0,0 +1,1106 @@
+/*
+ * Automated Testing Framework (atf)
+ *
+ * Copyright (c) 2007, 2008, 2009, 2010 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <atf-c.h>
+
+#include "atf-c/fs.h"
+#include "atf-c/user.h"
+
+#include "test_helpers.h"
+
+/* ---------------------------------------------------------------------
+ * Auxiliary functions.
+ * --------------------------------------------------------------------- */
+
+static
+void
+create_dir(const char *p, int mode)
+{
+ int ret;
+
+ ret = mkdir(p, mode);
+ if (ret == -1)
+ atf_tc_fail("Could not create helper directory %s", p);
+}
+
+static
+void
+create_file(const char *p, int mode)
+{
+ int fd;
+
+ fd = open(p, O_CREAT | O_WRONLY | O_TRUNC, mode);
+ if (fd == -1)
+ atf_tc_fail("Could not create helper file %s", p);
+ close(fd);
+}
+
+static
+bool
+exists(const atf_fs_path_t *p)
+{
+ return access(atf_fs_path_cstring(p), F_OK) == 0;
+}
+
+static
+atf_error_t
+mkstemp_discard_fd(atf_fs_path_t *p)
+{
+ int fd;
+ atf_error_t err = atf_fs_mkstemp(p, &fd);
+ if (!atf_is_error(err))
+ close(fd);
+ return err;
+}
+
+/* ---------------------------------------------------------------------
+ * Test cases for the "atf_fs_path" type.
+ * --------------------------------------------------------------------- */
+
+ATF_TC(path_normalize);
+ATF_TC_HEAD(path_normalize, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests the path's normalization");
+}
+ATF_TC_BODY(path_normalize, tc)
+{
+ struct test {
+ const char *in;
+ const char *out;
+ } tests[] = {
+ { ".", ".", },
+ { "..", "..", },
+
+ { "/", "/", },
+ { "//", "/", }, /* NO_CHECK_STYLE */
+ { "///", "/", }, /* NO_CHECK_STYLE */
+
+ { "foo", "foo", },
+ { "foo/", "foo", },
+ { "foo/bar", "foo/bar", },
+ { "foo/bar/", "foo/bar", },
+
+ { "/foo", "/foo", },
+ { "/foo/bar", "/foo/bar", },
+ { "/foo/bar/", "/foo/bar", },
+
+ { "///foo", "/foo", }, /* NO_CHECK_STYLE */
+ { "///foo///bar", "/foo/bar", }, /* NO_CHECK_STYLE */
+ { "///foo///bar///", "/foo/bar", }, /* NO_CHECK_STYLE */
+
+ { NULL, NULL }
+ };
+ struct test *t;
+
+ for (t = &tests[0]; t->in != NULL; t++) {
+ atf_fs_path_t p;
+
+ printf("Input : >%s<\n", t->in);
+ printf("Expected output: >%s<\n", t->out);
+
+ RE(atf_fs_path_init_fmt(&p, "%s", t->in));
+ printf("Output : >%s<\n", atf_fs_path_cstring(&p));
+ ATF_REQUIRE(strcmp(atf_fs_path_cstring(&p), t->out) == 0);
+ atf_fs_path_fini(&p);
+
+ printf("\n");
+ }
+}
+
+ATF_TC(path_copy);
+ATF_TC_HEAD(path_copy, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_path_copy constructor");
+}
+ATF_TC_BODY(path_copy, tc)
+{
+ atf_fs_path_t str, str2;
+
+ RE(atf_fs_path_init_fmt(&str, "foo"));
+ RE(atf_fs_path_copy(&str2, &str));
+
+ ATF_REQUIRE(atf_equal_fs_path_fs_path(&str, &str2));
+
+ RE(atf_fs_path_append_fmt(&str2, "bar"));
+
+ ATF_REQUIRE(!atf_equal_fs_path_fs_path(&str, &str2));
+
+ atf_fs_path_fini(&str2);
+ atf_fs_path_fini(&str);
+}
+
+ATF_TC(path_is_absolute);
+ATF_TC_HEAD(path_is_absolute, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests the path::is_absolute function");
+}
+ATF_TC_BODY(path_is_absolute, tc)
+{
+ struct test {
+ const char *in;
+ bool abs;
+ } tests[] = {
+ { "/", true },
+ { "////", true }, /* NO_CHECK_STYLE */
+ { "////a", true }, /* NO_CHECK_STYLE */
+ { "//a//", true }, /* NO_CHECK_STYLE */
+ { "a////", false }, /* NO_CHECK_STYLE */
+ { "../foo", false },
+ { NULL, false },
+ };
+ struct test *t;
+
+ for (t = &tests[0]; t->in != NULL; t++) {
+ atf_fs_path_t p;
+
+ printf("Input : %s\n", t->in);
+ printf("Expected result: %s\n", t->abs ? "true" : "false");
+
+ RE(atf_fs_path_init_fmt(&p, "%s", t->in));
+ printf("Result : %s\n",
+ atf_fs_path_is_absolute(&p) ? "true" : "false");
+ if (t->abs)
+ ATF_REQUIRE(atf_fs_path_is_absolute(&p));
+ else
+ ATF_REQUIRE(!atf_fs_path_is_absolute(&p));
+ atf_fs_path_fini(&p);
+
+ printf("\n");
+ }
+}
+
+ATF_TC(path_is_root);
+ATF_TC_HEAD(path_is_root, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests the path::is_root function");
+}
+ATF_TC_BODY(path_is_root, tc)
+{
+ struct test {
+ const char *in;
+ bool root;
+ } tests[] = {
+ { "/", true },
+ { "////", true }, /* NO_CHECK_STYLE */
+ { "////a", false }, /* NO_CHECK_STYLE */
+ { "//a//", false }, /* NO_CHECK_STYLE */
+ { "a////", false }, /* NO_CHECK_STYLE */
+ { "../foo", false },
+ { NULL, false },
+ };
+ struct test *t;
+
+ for (t = &tests[0]; t->in != NULL; t++) {
+ atf_fs_path_t p;
+
+ printf("Input : %s\n", t->in);
+ printf("Expected result: %s\n", t->root ? "true" : "false");
+
+ RE(atf_fs_path_init_fmt(&p, "%s", t->in));
+ printf("Result : %s\n",
+ atf_fs_path_is_root(&p) ? "true" : "false");
+ if (t->root)
+ ATF_REQUIRE(atf_fs_path_is_root(&p));
+ else
+ ATF_REQUIRE(!atf_fs_path_is_root(&p));
+ atf_fs_path_fini(&p);
+
+ printf("\n");
+ }
+}
+
+ATF_TC(path_branch_path);
+ATF_TC_HEAD(path_branch_path, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_path_branch_path "
+ "function");
+}
+ATF_TC_BODY(path_branch_path, tc)
+{
+ struct test {
+ const char *in;
+ const char *branch;
+ } tests[] = {
+ { ".", "." },
+ { "foo", "." },
+ { "foo/bar", "foo" },
+ { "/foo", "/" },
+ { "/foo/bar", "/foo" },
+ { NULL, NULL },
+ };
+ struct test *t;
+
+ for (t = &tests[0]; t->in != NULL; t++) {
+ atf_fs_path_t p, bp;
+
+ printf("Input : %s\n", t->in);
+ printf("Expected output: %s\n", t->branch);
+
+ RE(atf_fs_path_init_fmt(&p, "%s", t->in));
+ RE(atf_fs_path_branch_path(&p, &bp));
+ printf("Output : %s\n", atf_fs_path_cstring(&bp));
+ ATF_REQUIRE(strcmp(atf_fs_path_cstring(&bp), t->branch) == 0);
+ atf_fs_path_fini(&bp);
+ atf_fs_path_fini(&p);
+
+ printf("\n");
+ }
+}
+
+ATF_TC(path_leaf_name);
+ATF_TC_HEAD(path_leaf_name, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_path_leaf_name "
+ "function");
+}
+ATF_TC_BODY(path_leaf_name, tc)
+{
+ struct test {
+ const char *in;
+ const char *leaf;
+ } tests[] = {
+ { ".", "." },
+ { "foo", "foo" },
+ { "foo/bar", "bar" },
+ { "/foo", "foo" },
+ { "/foo/bar", "bar" },
+ { NULL, NULL },
+ };
+ struct test *t;
+
+ for (t = &tests[0]; t->in != NULL; t++) {
+ atf_fs_path_t p;
+ atf_dynstr_t ln;
+
+ printf("Input : %s\n", t->in);
+ printf("Expected output: %s\n", t->leaf);
+
+ RE(atf_fs_path_init_fmt(&p, "%s", t->in));
+ RE(atf_fs_path_leaf_name(&p, &ln));
+ printf("Output : %s\n", atf_dynstr_cstring(&ln));
+ ATF_REQUIRE(atf_equal_dynstr_cstring(&ln, t->leaf));
+ atf_dynstr_fini(&ln);
+ atf_fs_path_fini(&p);
+
+ printf("\n");
+ }
+}
+
+ATF_TC(path_append);
+ATF_TC_HEAD(path_append, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests the concatenation of multiple "
+ "paths");
+}
+ATF_TC_BODY(path_append, tc)
+{
+ struct test {
+ const char *in;
+ const char *ap;
+ const char *out;
+ } tests[] = {
+ { "foo", "bar", "foo/bar" },
+ { "foo/", "/bar", "foo/bar" },
+ { "foo/", "/bar/baz", "foo/bar/baz" },
+ { "foo/", "///bar///baz", "foo/bar/baz" }, /* NO_CHECK_STYLE */
+
+ { NULL, NULL, NULL }
+ };
+ struct test *t;
+
+ for (t = &tests[0]; t->in != NULL; t++) {
+ atf_fs_path_t p;
+
+ printf("Input : >%s<\n", t->in);
+ printf("Append : >%s<\n", t->ap);
+ printf("Expected output: >%s<\n", t->out);
+
+ RE(atf_fs_path_init_fmt(&p, "%s", t->in));
+
+ RE(atf_fs_path_append_fmt(&p, "%s", t->ap));
+
+ printf("Output : >%s<\n", atf_fs_path_cstring(&p));
+ ATF_REQUIRE(strcmp(atf_fs_path_cstring(&p), t->out) == 0);
+
+ atf_fs_path_fini(&p);
+
+ printf("\n");
+ }
+}
+
+ATF_TC(path_to_absolute);
+ATF_TC_HEAD(path_to_absolute, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_path_to_absolute "
+ "function");
+ atf_tc_set_md_var(tc, "use.fs", "true");
+}
+ATF_TC_BODY(path_to_absolute, tc)
+{
+ const char *names[] = { ".", "dir", NULL };
+ const char **n;
+
+ ATF_REQUIRE(mkdir("dir", 0755) != -1);
+
+ for (n = names; *n != NULL; n++) {
+ atf_fs_path_t p, p2;
+ atf_fs_stat_t st1, st2;
+
+ RE(atf_fs_path_init_fmt(&p, "%s", *n));
+ RE(atf_fs_stat_init(&st1, &p));
+ printf("Relative path: %s\n", atf_fs_path_cstring(&p));
+
+ RE(atf_fs_path_to_absolute(&p, &p2));
+ printf("Absolute path: %s\n", atf_fs_path_cstring(&p2));
+
+ ATF_REQUIRE(atf_fs_path_is_absolute(&p2));
+ RE(atf_fs_stat_init(&st2, &p2));
+
+ ATF_REQUIRE_EQ(atf_fs_stat_get_device(&st1),
+ atf_fs_stat_get_device(&st2));
+ ATF_REQUIRE_EQ(atf_fs_stat_get_inode(&st1),
+ atf_fs_stat_get_inode(&st2));
+
+ atf_fs_stat_fini(&st2);
+ atf_fs_stat_fini(&st1);
+ atf_fs_path_fini(&p2);
+ atf_fs_path_fini(&p);
+
+ printf("\n");
+ }
+}
+
+ATF_TC(path_equal);
+ATF_TC_HEAD(path_equal, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests the equality operators for paths");
+}
+ATF_TC_BODY(path_equal, tc)
+{
+ atf_fs_path_t p1, p2;
+
+ RE(atf_fs_path_init_fmt(&p1, "foo"));
+
+ RE(atf_fs_path_init_fmt(&p2, "foo"));
+ ATF_REQUIRE(atf_equal_fs_path_fs_path(&p1, &p2));
+ atf_fs_path_fini(&p2);
+
+ RE(atf_fs_path_init_fmt(&p2, "bar"));
+ ATF_REQUIRE(!atf_equal_fs_path_fs_path(&p1, &p2));
+ atf_fs_path_fini(&p2);
+
+ atf_fs_path_fini(&p1);
+}
+
+/* ---------------------------------------------------------------------
+ * Test cases for the "atf_fs_stat" type.
+ * --------------------------------------------------------------------- */
+
+ATF_TC(stat_mode);
+ATF_TC_HEAD(stat_mode, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_stat_get_mode function "
+ "and, indirectly, the constructor");
+ atf_tc_set_md_var(tc, "use.fs", "true");
+}
+ATF_TC_BODY(stat_mode, tc)
+{
+ atf_fs_path_t p;
+ atf_fs_stat_t st;
+
+ create_file("f1", 0400);
+ create_file("f2", 0644);
+
+ RE(atf_fs_path_init_fmt(&p, "f1"));
+ RE(atf_fs_stat_init(&st, &p));
+ ATF_CHECK_EQ(0400, atf_fs_stat_get_mode(&st));
+ atf_fs_stat_fini(&st);
+ atf_fs_path_fini(&p);
+
+ RE(atf_fs_path_init_fmt(&p, "f2"));
+ RE(atf_fs_stat_init(&st, &p));
+ ATF_CHECK_EQ(0644, atf_fs_stat_get_mode(&st));
+ atf_fs_stat_fini(&st);
+ atf_fs_path_fini(&p);
+}
+
+ATF_TC(stat_type);
+ATF_TC_HEAD(stat_type, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_stat_get_type function "
+ "and, indirectly, the constructor");
+ atf_tc_set_md_var(tc, "use.fs", "true");
+}
+ATF_TC_BODY(stat_type, tc)
+{
+ atf_fs_path_t p;
+ atf_fs_stat_t st;
+
+ create_dir("dir", 0755);
+ create_file("reg", 0644);
+
+ RE(atf_fs_path_init_fmt(&p, "dir"));
+ RE(atf_fs_stat_init(&st, &p));
+ ATF_REQUIRE_EQ(atf_fs_stat_get_type(&st), atf_fs_stat_dir_type);
+ atf_fs_stat_fini(&st);
+ atf_fs_path_fini(&p);
+
+ RE(atf_fs_path_init_fmt(&p, "reg"));
+ RE(atf_fs_stat_init(&st, &p));
+ ATF_REQUIRE_EQ(atf_fs_stat_get_type(&st), atf_fs_stat_reg_type);
+ atf_fs_stat_fini(&st);
+ atf_fs_path_fini(&p);
+}
+
+ATF_TC(stat_perms);
+ATF_TC_HEAD(stat_perms, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_stat_is_* functions");
+ atf_tc_set_md_var(tc, "use.fs", "true");
+}
+ATF_TC_BODY(stat_perms, tc)
+{
+ atf_fs_path_t p;
+ atf_fs_stat_t st;
+
+ create_file("reg", 0);
+
+ RE(atf_fs_path_init_fmt(&p, "reg"));
+
+#define perms(ur, uw, ux, gr, gw, gx, othr, othw, othx) \
+ { \
+ RE(atf_fs_stat_init(&st, &p)); \
+ ATF_REQUIRE(atf_fs_stat_is_owner_readable(&st) == ur); \
+ ATF_REQUIRE(atf_fs_stat_is_owner_writable(&st) == uw); \
+ ATF_REQUIRE(atf_fs_stat_is_owner_executable(&st) == ux); \
+ ATF_REQUIRE(atf_fs_stat_is_group_readable(&st) == gr); \
+ ATF_REQUIRE(atf_fs_stat_is_group_writable(&st) == gw); \
+ ATF_REQUIRE(atf_fs_stat_is_group_executable(&st) == gx); \
+ ATF_REQUIRE(atf_fs_stat_is_other_readable(&st) == othr); \
+ ATF_REQUIRE(atf_fs_stat_is_other_writable(&st) == othw); \
+ ATF_REQUIRE(atf_fs_stat_is_other_executable(&st) == othx); \
+ atf_fs_stat_fini(&st); \
+ }
+
+ chmod("reg", 0000);
+ perms(false, false, false, false, false, false, false, false, false);
+
+ chmod("reg", 0001);
+ perms(false, false, false, false, false, false, false, false, true);
+
+ chmod("reg", 0010);
+ perms(false, false, false, false, false, true, false, false, false);
+
+ chmod("reg", 0100);
+ perms(false, false, true, false, false, false, false, false, false);
+
+ chmod("reg", 0002);
+ perms(false, false, false, false, false, false, false, true, false);
+
+ chmod("reg", 0020);
+ perms(false, false, false, false, true, false, false, false, false);
+
+ chmod("reg", 0200);
+ perms(false, true, false, false, false, false, false, false, false);
+
+ chmod("reg", 0004);
+ perms(false, false, false, false, false, false, true, false, false);
+
+ chmod("reg", 0040);
+ perms(false, false, false, true, false, false, false, false, false);
+
+ chmod("reg", 0400);
+ perms(true, false, false, false, false, false, false, false, false);
+
+ chmod("reg", 0644);
+ perms(true, true, false, true, false, false, true, false, false);
+
+ chmod("reg", 0755);
+ perms(true, true, true, true, false, true, true, false, true);
+
+ chmod("reg", 0777);
+ perms(true, true, true, true, true, true, true, true, true);
+
+#undef perms
+
+ atf_fs_path_fini(&p);
+}
+
+/* ---------------------------------------------------------------------
+ * Test cases for the free functions.
+ * --------------------------------------------------------------------- */
+
+ATF_TC(exists);
+ATF_TC_HEAD(exists, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_exists function");
+ atf_tc_set_md_var(tc, "use.fs", "true");
+}
+ATF_TC_BODY(exists, tc)
+{
+ atf_error_t err;
+ atf_fs_path_t pdir, pfile;
+ bool b;
+
+ RE(atf_fs_path_init_fmt(&pdir, "dir"));
+ RE(atf_fs_path_init_fmt(&pfile, "dir/file"));
+
+ create_dir(atf_fs_path_cstring(&pdir), 0755);
+ create_file(atf_fs_path_cstring(&pfile), 0644);
+
+ printf("Checking existence of a directory\n");
+ RE(atf_fs_exists(&pdir, &b));
+ ATF_REQUIRE(b);
+
+ printf("Checking existence of a file\n");
+ RE(atf_fs_exists(&pfile, &b));
+ ATF_REQUIRE(b);
+
+ /* XXX: This should probably be a separate test case to let the user
+ * be aware that some tests were skipped because privileges were not
+ * correct. */
+ if (!atf_user_is_root()) {
+ printf("Checking existence of a file inside a directory without "
+ "permissions\n");
+ ATF_REQUIRE(chmod(atf_fs_path_cstring(&pdir), 0000) != -1);
+ err = atf_fs_exists(&pfile, &b);
+ ATF_REQUIRE(atf_is_error(err));
+ ATF_REQUIRE(atf_error_is(err, "libc"));
+ ATF_REQUIRE(chmod(atf_fs_path_cstring(&pdir), 0755) != -1);
+ atf_error_free(err);
+ }
+
+ printf("Checking existence of a non-existent file\n");
+ ATF_REQUIRE(unlink(atf_fs_path_cstring(&pfile)) != -1);
+ RE(atf_fs_exists(&pfile, &b));
+ ATF_REQUIRE(!b);
+
+ atf_fs_path_fini(&pfile);
+ atf_fs_path_fini(&pdir);
+}
+
+ATF_TC(eaccess);
+ATF_TC_HEAD(eaccess, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_eaccess function");
+ atf_tc_set_md_var(tc, "use.fs", "true");
+}
+ATF_TC_BODY(eaccess, tc)
+{
+ const int modes[] = { atf_fs_access_f, atf_fs_access_r, atf_fs_access_w,
+ atf_fs_access_x, 0 };
+ const int *m;
+ struct tests {
+ mode_t fmode;
+ int amode;
+ int uerror;
+ int rerror;
+ } tests[] = {
+ { 0000, atf_fs_access_r, EACCES, 0 },
+ { 0000, atf_fs_access_w, EACCES, 0 },
+ { 0000, atf_fs_access_x, EACCES, EACCES },
+
+ { 0001, atf_fs_access_r, EACCES, 0 },
+ { 0001, atf_fs_access_w, EACCES, 0 },
+ { 0001, atf_fs_access_x, EACCES, 0 },
+ { 0002, atf_fs_access_r, EACCES, 0 },
+ { 0002, atf_fs_access_w, EACCES, 0 },
+ { 0002, atf_fs_access_x, EACCES, EACCES },
+ { 0004, atf_fs_access_r, EACCES, 0 },
+ { 0004, atf_fs_access_w, EACCES, 0 },
+ { 0004, atf_fs_access_x, EACCES, EACCES },
+
+ { 0010, atf_fs_access_r, EACCES, 0 },
+ { 0010, atf_fs_access_w, EACCES, 0 },
+ { 0010, atf_fs_access_x, 0, 0 },
+ { 0020, atf_fs_access_r, EACCES, 0 },
+ { 0020, atf_fs_access_w, 0, 0 },
+ { 0020, atf_fs_access_x, EACCES, EACCES },
+ { 0040, atf_fs_access_r, 0, 0 },
+ { 0040, atf_fs_access_w, EACCES, 0 },
+ { 0040, atf_fs_access_x, EACCES, EACCES },
+
+ { 0100, atf_fs_access_r, EACCES, 0 },
+ { 0100, atf_fs_access_w, EACCES, 0 },
+ { 0100, atf_fs_access_x, 0, 0 },
+ { 0200, atf_fs_access_r, EACCES, 0 },
+ { 0200, atf_fs_access_w, 0, 0 },
+ { 0200, atf_fs_access_x, EACCES, EACCES },
+ { 0400, atf_fs_access_r, 0, 0 },
+ { 0400, atf_fs_access_w, EACCES, 0 },
+ { 0400, atf_fs_access_x, EACCES, EACCES },
+
+ { 0, 0, 0, 0 }
+ };
+ struct tests *t;
+ atf_fs_path_t p;
+ atf_error_t err;
+
+ RE(atf_fs_path_init_fmt(&p, "the-file"));
+
+ printf("Non-existent file checks\n");
+ for (m = &modes[0]; *m != 0; m++) {
+ err = atf_fs_eaccess(&p, *m);
+ ATF_REQUIRE(atf_is_error(err));
+ ATF_REQUIRE(atf_error_is(err, "libc"));
+ ATF_REQUIRE_EQ(atf_libc_error_code(err), ENOENT);
+ atf_error_free(err);
+ }
+
+ create_file(atf_fs_path_cstring(&p), 0000);
+ ATF_REQUIRE(chown(atf_fs_path_cstring(&p), geteuid(), getegid()) != -1);
+
+ for (t = &tests[0]; t->amode != 0; t++) {
+ const int experr = atf_user_is_root() ? t->rerror : t->uerror;
+
+ printf("\n");
+ printf("File mode : %04o\n", (unsigned int)t->fmode);
+ printf("Access mode : 0x%02x\n", t->amode);
+
+ ATF_REQUIRE(chmod(atf_fs_path_cstring(&p), t->fmode) != -1);
+
+ /* First, existence check. */
+ err = atf_fs_eaccess(&p, atf_fs_access_f);
+ ATF_REQUIRE(!atf_is_error(err));
+
+ /* Now do the specific test case. */
+ printf("Expected error: %d\n", experr);
+ err = atf_fs_eaccess(&p, t->amode);
+ if (atf_is_error(err)) {
+ if (atf_error_is(err, "libc"))
+ printf("Error : %d\n", atf_libc_error_code(err));
+ else
+ printf("Error : Non-libc error\n");
+ } else
+ printf("Error : None\n");
+ if (experr == 0) {
+ ATF_REQUIRE(!atf_is_error(err));
+ } else {
+ ATF_REQUIRE(atf_is_error(err));
+ ATF_REQUIRE(atf_error_is(err, "libc"));
+ ATF_REQUIRE_EQ(atf_libc_error_code(err), experr);
+ atf_error_free(err);
+ }
+ }
+
+ atf_fs_path_fini(&p);
+}
+
+ATF_TC(getcwd);
+ATF_TC_HEAD(getcwd, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_getcwd function");
+ atf_tc_set_md_var(tc, "use.fs", "true");
+}
+ATF_TC_BODY(getcwd, tc)
+{
+ atf_fs_path_t cwd1, cwd2;
+
+ create_dir ("root", 0755);
+
+ RE(atf_fs_getcwd(&cwd1));
+ ATF_REQUIRE(chdir("root") != -1);
+ RE(atf_fs_getcwd(&cwd2));
+
+ RE(atf_fs_path_append_fmt(&cwd1, "root"));
+
+ ATF_REQUIRE(atf_equal_fs_path_fs_path(&cwd1, &cwd2));
+
+ atf_fs_path_fini(&cwd2);
+ atf_fs_path_fini(&cwd1);
+}
+
+ATF_TC(rmdir_empty);
+ATF_TC_HEAD(rmdir_empty, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_rmdir function");
+ atf_tc_set_md_var(tc, "use.fs", "true");
+}
+ATF_TC_BODY(rmdir_empty, tc)
+{
+ atf_fs_path_t p;
+
+ RE(atf_fs_path_init_fmt(&p, "test-dir"));
+
+ ATF_REQUIRE(mkdir("test-dir", 0755) != -1);
+ ATF_REQUIRE(exists(&p));
+ RE(atf_fs_rmdir(&p));
+ ATF_REQUIRE(!exists(&p));
+
+ atf_fs_path_fini(&p);
+}
+
+ATF_TC(rmdir_enotempty);
+ATF_TC_HEAD(rmdir_enotempty, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_rmdir function");
+ atf_tc_set_md_var(tc, "use.fs", "true");
+}
+ATF_TC_BODY(rmdir_enotempty, tc)
+{
+ atf_fs_path_t p;
+ atf_error_t err;
+
+ RE(atf_fs_path_init_fmt(&p, "test-dir"));
+
+ ATF_REQUIRE(mkdir("test-dir", 0755) != -1);
+ ATF_REQUIRE(exists(&p));
+ create_file("test-dir/foo", 0644);
+
+ err = atf_fs_rmdir(&p);
+ ATF_REQUIRE(atf_is_error(err));
+ ATF_REQUIRE(atf_error_is(err, "libc"));
+ ATF_REQUIRE_EQ(atf_libc_error_code(err), ENOTEMPTY);
+ atf_error_free(err);
+
+ atf_fs_path_fini(&p);
+}
+
+ATF_TC(rmdir_eperm);
+ATF_TC_HEAD(rmdir_eperm, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_rmdir function");
+ atf_tc_set_md_var(tc, "use.fs", "true");
+}
+ATF_TC_BODY(rmdir_eperm, tc)
+{
+ atf_fs_path_t p;
+ atf_error_t err;
+
+ RE(atf_fs_path_init_fmt(&p, "test-dir/foo"));
+
+ ATF_REQUIRE(mkdir("test-dir", 0755) != -1);
+ ATF_REQUIRE(mkdir("test-dir/foo", 0755) != -1);
+ ATF_REQUIRE(chmod("test-dir", 0555) != -1);
+ ATF_REQUIRE(exists(&p));
+
+ err = atf_fs_rmdir(&p);
+ if (atf_user_is_root()) {
+ ATF_REQUIRE(!atf_is_error(err));
+ } else {
+ ATF_REQUIRE(atf_is_error(err));
+ ATF_REQUIRE(atf_error_is(err, "libc"));
+ ATF_REQUIRE_EQ(atf_libc_error_code(err), EACCES);
+ atf_error_free(err);
+ }
+
+ atf_fs_path_fini(&p);
+}
+
+ATF_TC(mkdtemp_ok);
+ATF_TC_HEAD(mkdtemp_ok, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_mkdtemp function, "
+ "successful execution");
+ atf_tc_set_md_var(tc, "use.fs", "true");
+}
+ATF_TC_BODY(mkdtemp_ok, tc)
+{
+ atf_fs_path_t p1, p2;
+ atf_fs_stat_t s1, s2;
+
+ RE(atf_fs_path_init_fmt(&p1, "testdir.XXXXXX"));
+ RE(atf_fs_path_init_fmt(&p2, "testdir.XXXXXX"));
+ RE(atf_fs_mkdtemp(&p1));
+ RE(atf_fs_mkdtemp(&p2));
+ ATF_REQUIRE(!atf_equal_fs_path_fs_path(&p1, &p2));
+ ATF_REQUIRE(exists(&p1));
+ ATF_REQUIRE(exists(&p2));
+
+ RE(atf_fs_stat_init(&s1, &p1));
+ ATF_REQUIRE_EQ(atf_fs_stat_get_type(&s1), atf_fs_stat_dir_type);
+ ATF_REQUIRE( atf_fs_stat_is_owner_readable(&s1));
+ ATF_REQUIRE( atf_fs_stat_is_owner_writable(&s1));
+ ATF_REQUIRE( atf_fs_stat_is_owner_executable(&s1));
+ ATF_REQUIRE(!atf_fs_stat_is_group_readable(&s1));
+ ATF_REQUIRE(!atf_fs_stat_is_group_writable(&s1));
+ ATF_REQUIRE(!atf_fs_stat_is_group_executable(&s1));
+ ATF_REQUIRE(!atf_fs_stat_is_other_readable(&s1));
+ ATF_REQUIRE(!atf_fs_stat_is_other_writable(&s1));
+ ATF_REQUIRE(!atf_fs_stat_is_other_executable(&s1));
+
+ RE(atf_fs_stat_init(&s2, &p2));
+ ATF_REQUIRE_EQ(atf_fs_stat_get_type(&s2), atf_fs_stat_dir_type);
+ ATF_REQUIRE( atf_fs_stat_is_owner_readable(&s2));
+ ATF_REQUIRE( atf_fs_stat_is_owner_writable(&s2));
+ ATF_REQUIRE( atf_fs_stat_is_owner_executable(&s2));
+ ATF_REQUIRE(!atf_fs_stat_is_group_readable(&s2));
+ ATF_REQUIRE(!atf_fs_stat_is_group_writable(&s2));
+ ATF_REQUIRE(!atf_fs_stat_is_group_executable(&s2));
+ ATF_REQUIRE(!atf_fs_stat_is_other_readable(&s2));
+ ATF_REQUIRE(!atf_fs_stat_is_other_writable(&s2));
+ ATF_REQUIRE(!atf_fs_stat_is_other_executable(&s2));
+
+ atf_fs_stat_fini(&s2);
+ atf_fs_stat_fini(&s1);
+ atf_fs_path_fini(&p2);
+ atf_fs_path_fini(&p1);
+}
+
+ATF_TC(mkdtemp_err);
+ATF_TC_HEAD(mkdtemp_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_mkdtemp function, "
+ "error conditions");
+ atf_tc_set_md_var(tc, "require.user", "unprivileged");
+ atf_tc_set_md_var(tc, "use.fs", "true");
+}
+ATF_TC_BODY(mkdtemp_err, tc)
+{
+ atf_error_t err;
+ atf_fs_path_t p;
+
+ ATF_REQUIRE(mkdir("dir", 0555) != -1);
+
+ RE(atf_fs_path_init_fmt(&p, "dir/testdir.XXXXXX"));
+
+ err = atf_fs_mkdtemp(&p);
+ ATF_REQUIRE(atf_is_error(err));
+ ATF_REQUIRE(atf_error_is(err, "libc"));
+ ATF_CHECK_EQ(atf_libc_error_code(err), EACCES);
+ atf_error_free(err);
+
+ ATF_CHECK(!exists(&p));
+ ATF_CHECK(strcmp(atf_fs_path_cstring(&p), "dir/testdir.XXXXXX") == 0);
+
+ atf_fs_path_fini(&p);
+}
+
+static
+void
+do_umask_check(atf_error_t (*const mk_func)(atf_fs_path_t *),
+ atf_fs_path_t *path, const mode_t test_mask,
+ const char *str_mask, const char *exp_name)
+{
+ char buf[1024];
+ int old_umask;
+ atf_error_t err;
+
+ printf("Creating temporary %s with umask %s\n", exp_name, str_mask);
+
+ old_umask = umask(test_mask);
+ err = mk_func(path);
+ (void)umask(old_umask);
+
+ ATF_REQUIRE(atf_is_error(err));
+ ATF_REQUIRE(atf_error_is(err, "invalid_umask"));
+ atf_error_format(err, buf, sizeof(buf));
+ ATF_CHECK(strstr(buf, exp_name) != NULL);
+ ATF_CHECK(strstr(buf, str_mask) != NULL);
+ atf_error_free(err);
+}
+
+ATF_TC(mkdtemp_umask);
+ATF_TC_HEAD(mkdtemp_umask, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_mkdtemp function "
+ "causing an error due to a too strict umask");
+}
+ATF_TC_BODY(mkdtemp_umask, tc)
+{
+ atf_fs_path_t p;
+
+ RE(atf_fs_path_init_fmt(&p, "testdir.XXXXXX"));
+
+ do_umask_check(atf_fs_mkdtemp, &p, 00100, "00100", "directory");
+ do_umask_check(atf_fs_mkdtemp, &p, 00200, "00200", "directory");
+ do_umask_check(atf_fs_mkdtemp, &p, 00400, "00400", "directory");
+ do_umask_check(atf_fs_mkdtemp, &p, 00500, "00500", "directory");
+ do_umask_check(atf_fs_mkdtemp, &p, 00600, "00600", "directory");
+
+ atf_fs_path_fini(&p);
+}
+
+ATF_TC(mkstemp_ok);
+ATF_TC_HEAD(mkstemp_ok, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_mkstemp function, "
+ "successful execution");
+ atf_tc_set_md_var(tc, "use.fs", "true");
+}
+ATF_TC_BODY(mkstemp_ok, tc)
+{
+ int fd1, fd2;
+ atf_fs_path_t p1, p2;
+ atf_fs_stat_t s1, s2;
+
+ RE(atf_fs_path_init_fmt(&p1, "testfile.XXXXXX"));
+ RE(atf_fs_path_init_fmt(&p2, "testfile.XXXXXX"));
+ fd1 = fd2 = -1;
+ RE(atf_fs_mkstemp(&p1, &fd1));
+ RE(atf_fs_mkstemp(&p2, &fd2));
+ ATF_REQUIRE(!atf_equal_fs_path_fs_path(&p1, &p2));
+ ATF_REQUIRE(exists(&p1));
+ ATF_REQUIRE(exists(&p2));
+
+ ATF_CHECK(fd1 != -1);
+ ATF_CHECK(fd2 != -1);
+ ATF_CHECK(write(fd1, "foo", 3) == 3);
+ ATF_CHECK(write(fd2, "bar", 3) == 3);
+ close(fd1);
+ close(fd2);
+
+ RE(atf_fs_stat_init(&s1, &p1));
+ ATF_CHECK_EQ(atf_fs_stat_get_type(&s1), atf_fs_stat_reg_type);
+ ATF_CHECK( atf_fs_stat_is_owner_readable(&s1));
+ ATF_CHECK( atf_fs_stat_is_owner_writable(&s1));
+ ATF_CHECK(!atf_fs_stat_is_owner_executable(&s1));
+ ATF_CHECK(!atf_fs_stat_is_group_readable(&s1));
+ ATF_CHECK(!atf_fs_stat_is_group_writable(&s1));
+ ATF_CHECK(!atf_fs_stat_is_group_executable(&s1));
+ ATF_CHECK(!atf_fs_stat_is_other_readable(&s1));
+ ATF_CHECK(!atf_fs_stat_is_other_writable(&s1));
+ ATF_CHECK(!atf_fs_stat_is_other_executable(&s1));
+
+ RE(atf_fs_stat_init(&s2, &p2));
+ ATF_CHECK_EQ(atf_fs_stat_get_type(&s2), atf_fs_stat_reg_type);
+ ATF_CHECK( atf_fs_stat_is_owner_readable(&s2));
+ ATF_CHECK( atf_fs_stat_is_owner_writable(&s2));
+ ATF_CHECK(!atf_fs_stat_is_owner_executable(&s2));
+ ATF_CHECK(!atf_fs_stat_is_group_readable(&s2));
+ ATF_CHECK(!atf_fs_stat_is_group_writable(&s2));
+ ATF_CHECK(!atf_fs_stat_is_group_executable(&s2));
+ ATF_CHECK(!atf_fs_stat_is_other_readable(&s2));
+ ATF_CHECK(!atf_fs_stat_is_other_writable(&s2));
+ ATF_CHECK(!atf_fs_stat_is_other_executable(&s2));
+
+ atf_fs_stat_fini(&s2);
+ atf_fs_stat_fini(&s1);
+ atf_fs_path_fini(&p2);
+ atf_fs_path_fini(&p1);
+}
+
+ATF_TC(mkstemp_err);
+ATF_TC_HEAD(mkstemp_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_mkstemp function, "
+ "error conditions");
+ atf_tc_set_md_var(tc, "require.user", "unprivileged");
+ atf_tc_set_md_var(tc, "use.fs", "true");
+}
+ATF_TC_BODY(mkstemp_err, tc)
+{
+ int fd;
+ atf_error_t err;
+ atf_fs_path_t p;
+
+ ATF_REQUIRE(mkdir("dir", 0555) != -1);
+
+ RE(atf_fs_path_init_fmt(&p, "dir/testfile.XXXXXX"));
+ fd = 1234;
+
+ err = atf_fs_mkstemp(&p, &fd);
+ ATF_REQUIRE(atf_is_error(err));
+ ATF_REQUIRE(atf_error_is(err, "libc"));
+ ATF_CHECK_EQ(atf_libc_error_code(err), EACCES);
+ atf_error_free(err);
+
+ ATF_CHECK(!exists(&p));
+ ATF_CHECK(strcmp(atf_fs_path_cstring(&p), "dir/testfile.XXXXXX") == 0);
+ ATF_CHECK_EQ(fd, 1234);
+
+ atf_fs_path_fini(&p);
+}
+
+ATF_TC(mkstemp_umask);
+ATF_TC_HEAD(mkstemp_umask, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_mkstemp function "
+ "causing an error due to a too strict umask");
+}
+ATF_TC_BODY(mkstemp_umask, tc)
+{
+ atf_fs_path_t p;
+
+ RE(atf_fs_path_init_fmt(&p, "testfile.XXXXXX"));
+
+ do_umask_check(mkstemp_discard_fd, &p, 00100, "00100", "regular file");
+ do_umask_check(mkstemp_discard_fd, &p, 00200, "00200", "regular file");
+ do_umask_check(mkstemp_discard_fd, &p, 00400, "00400", "regular file");
+
+ atf_fs_path_fini(&p);
+}
+
+/* ---------------------------------------------------------------------
+ * Tests cases for the header file.
+ * --------------------------------------------------------------------- */
+
+HEADER_TC(include, "atf-c/fs.h");
+
+/* ---------------------------------------------------------------------
+ * Main.
+ * --------------------------------------------------------------------- */
+
+ATF_TP_ADD_TCS(tp)
+{
+ /* Add the tests for the "atf_fs_path" type. */
+ ATF_TP_ADD_TC(tp, path_normalize);
+ ATF_TP_ADD_TC(tp, path_copy);
+ ATF_TP_ADD_TC(tp, path_is_absolute);
+ ATF_TP_ADD_TC(tp, path_is_root);
+ ATF_TP_ADD_TC(tp, path_branch_path);
+ ATF_TP_ADD_TC(tp, path_leaf_name);
+ ATF_TP_ADD_TC(tp, path_append);
+ ATF_TP_ADD_TC(tp, path_to_absolute);
+ ATF_TP_ADD_TC(tp, path_equal);
+
+ /* Add the tests for the "atf_fs_stat" type. */
+ ATF_TP_ADD_TC(tp, stat_mode);
+ ATF_TP_ADD_TC(tp, stat_type);
+ ATF_TP_ADD_TC(tp, stat_perms);
+
+ /* Add the tests for the free functions. */
+ ATF_TP_ADD_TC(tp, eaccess);
+ ATF_TP_ADD_TC(tp, exists);
+ ATF_TP_ADD_TC(tp, getcwd);
+ ATF_TP_ADD_TC(tp, rmdir_empty);
+ ATF_TP_ADD_TC(tp, rmdir_enotempty);
+ ATF_TP_ADD_TC(tp, rmdir_eperm);
+ ATF_TP_ADD_TC(tp, mkdtemp_ok);
+ ATF_TP_ADD_TC(tp, mkdtemp_err);
+ ATF_TP_ADD_TC(tp, mkdtemp_umask);
+ ATF_TP_ADD_TC(tp, mkstemp_ok);
+ ATF_TP_ADD_TC(tp, mkstemp_err);
+ ATF_TP_ADD_TC(tp, mkstemp_umask);
+
+ /* Add the test cases for the header file. */
+ ATF_TP_ADD_TC(tp, include);
+
+ return atf_no_error();
+}
diff --git a/external/bsd/atf/dist/atf-c/h_build.h b/external/bsd/atf/dist/atf-c/h_build.h
new file mode 100644
index 00000000000..9454fdfde80
--- /dev/null
+++ b/external/bsd/atf/dist/atf-c/h_build.h
@@ -0,0 +1,414 @@
+/*
+ * Automated Testing Framework (atf)
+ *
+ * Copyright (c) 2009 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(TESTS_ATF_ATF_C_H_BUILD_H)
+# error "Cannot include h_build.h more than once."
+#else
+# define TESTS_ATF_ATF_C_H_BUILD_H
+#endif
+
+/* ---------------------------------------------------------------------
+ * Test case data.
+ * --------------------------------------------------------------------- */
+
+static struct c_o_test {
+ const char *msg;
+ const char *cc;
+ const char *cflags;
+ const char *cppflags;
+ const char *sfile;
+ const char *ofile;
+ bool hasoptargs;
+ const char *const optargs[16];
+ const char *const expargv[16];
+} c_o_tests[] = {
+ {
+ "No flags",
+ "cc",
+ "",
+ "",
+ "test.c",
+ "test.o",
+ false,
+ {
+ NULL
+ },
+ {
+ "cc", "-o", "test.o", "-c", "test.c", NULL
+ },
+ },
+
+ {
+ "Multi-word program name",
+ "cc -foo",
+ "",
+ "",
+ "test.c",
+ "test.o",
+ false,
+ {
+ NULL
+ },
+ {
+ "cc", "-foo", "-o", "test.o", "-c", "test.c", NULL
+ },
+ },
+
+ {
+ "Some cflags",
+ "cc",
+ "-f1 -f2 -f3 -f4-f5",
+ "",
+ "test.c",
+ "test.o",
+ false,
+ {
+ NULL
+ },
+ {
+ "cc", "-f1", "-f2", "-f3", "-f4-f5", "-o", "test.o",
+ "-c", "test.c", NULL
+ },
+ },
+
+ {
+ "Some cppflags",
+ "cc",
+ "",
+ "-f1 -f2 -f3 -f4-f5",
+ "test.c",
+ "test.o",
+ false,
+ {
+ NULL
+ },
+ {
+ "cc", "-f1", "-f2", "-f3", "-f4-f5", "-o", "test.o",
+ "-c", "test.c", NULL
+ },
+ },
+
+ {
+ "Some cflags and cppflags",
+ "cc",
+ "-f2",
+ "-f1",
+ "test.c",
+ "test.o",
+ false,
+ {
+ NULL
+ },
+ {
+ "cc", "-f1", "-f2", "-o", "test.o", "-c", "test.c", NULL
+ },
+ },
+
+ {
+ "Some optional arguments",
+ "cc",
+ "",
+ "",
+ "test.c",
+ "test.o",
+ true,
+ {
+ "-o1", "-o2", NULL
+ },
+ {
+ "cc", "-o1", "-o2", "-o", "test.o", "-c", "test.c", NULL
+ },
+ },
+
+ {
+ "Some cflags, cppflags and optional arguments",
+ "cc",
+ "-f2",
+ "-f1",
+ "test.c",
+ "test.o",
+ true,
+ {
+ "-o1", "-o2", NULL
+ },
+ {
+ "cc", "-f1", "-f2", "-o1", "-o2", "-o", "test.o",
+ "-c", "test.c", NULL
+ },
+ },
+
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ false,
+ { NULL },
+ { NULL },
+ },
+};
+
+static struct cpp_test {
+ const char *msg;
+ const char *cpp;
+ const char *cppflags;
+ const char *sfile;
+ const char *ofile;
+ bool hasoptargs;
+ const char *const optargs[16];
+ const char *const expargv[16];
+} cpp_tests[] = {
+ {
+ "No flags",
+ "cpp",
+ "",
+ "test.c",
+ "test.out",
+ false,
+ {
+ NULL
+ },
+ {
+ "cpp", "-o", "test.out", "test.c", NULL
+ },
+ },
+
+ {
+ "Multi-word program name",
+ "cpp -foo",
+ "",
+ "test.c",
+ "test.out",
+ false,
+ {
+ NULL
+ },
+ {
+ "cpp", "-foo", "-o", "test.out", "test.c", NULL
+ },
+ },
+
+ {
+ "Some cppflags",
+ "cpp",
+ "-f1 -f2 -f3 -f4-f5",
+ "test.c",
+ "test.out",
+ false,
+ {
+ NULL
+ },
+ {
+ "cpp", "-f1", "-f2", "-f3", "-f4-f5", "-o", "test.out",
+ "test.c", NULL
+ },
+ },
+
+ {
+ "Some optional arguments",
+ "cpp",
+ "",
+ "test.c",
+ "test.out",
+ true,
+ {
+ "-o1", "-o2", NULL
+ },
+ {
+ "cpp", "-o1", "-o2", "-o", "test.out", "test.c", NULL
+ },
+ },
+
+ {
+ "Some cppflags and optional arguments",
+ "cpp",
+ "-f1",
+ "test.c",
+ "test.out",
+ true,
+ {
+ "-o1", "-o2", NULL
+ },
+ {
+ "cpp", "-f1", "-o1", "-o2", "-o", "test.out", "test.c", NULL
+ },
+ },
+
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ false,
+ { NULL },
+ { NULL },
+ },
+};
+
+static struct cxx_o_test {
+ const char *msg;
+ const char *cxx;
+ const char *cxxflags;
+ const char *cppflags;
+ const char *sfile;
+ const char *ofile;
+ bool hasoptargs;
+ const char *const optargs[16];
+ const char *const expargv[16];
+} cxx_o_tests[] = {
+ {
+ "No flags",
+ "c++",
+ "",
+ "",
+ "test.c",
+ "test.o",
+ false,
+ {
+ NULL
+ },
+ {
+ "c++", "-o", "test.o", "-c", "test.c", NULL
+ },
+ },
+
+ {
+ "Multi-word program name",
+ "c++ -foo",
+ "",
+ "",
+ "test.c",
+ "test.o",
+ false,
+ {
+ NULL
+ },
+ {
+ "c++", "-foo", "-o", "test.o", "-c", "test.c", NULL
+ },
+ },
+
+ {
+ "Some cxxflags",
+ "c++",
+ "-f1 -f2 -f3 -f4-f5",
+ "",
+ "test.c",
+ "test.o",
+ false,
+ {
+ NULL
+ },
+ {
+ "c++", "-f1", "-f2", "-f3", "-f4-f5", "-o", "test.o",
+ "-c", "test.c", NULL
+ },
+ },
+
+ {
+ "Some cppflags",
+ "c++",
+ "",
+ "-f1 -f2 -f3 -f4-f5",
+ "test.c",
+ "test.o",
+ false,
+ {
+ NULL
+ },
+ {
+ "c++", "-f1", "-f2", "-f3", "-f4-f5", "-o", "test.o",
+ "-c", "test.c", NULL
+ },
+ },
+
+ {
+ "Some cxxflags and cppflags",
+ "c++",
+ "-f2",
+ "-f1",
+ "test.c",
+ "test.o",
+ false,
+ {
+ NULL
+ },
+ {
+ "c++", "-f1", "-f2", "-o", "test.o", "-c", "test.c", NULL
+ },
+ },
+
+ {
+ "Some optional arguments",
+ "c++",
+ "",
+ "",
+ "test.c",
+ "test.o",
+ true,
+ {
+ "-o1", "-o2", NULL
+ },
+ {
+ "c++", "-o1", "-o2", "-o", "test.o", "-c", "test.c", NULL
+ },
+ },
+
+ {
+ "Some cxxflags, cppflags and optional arguments",
+ "c++",
+ "-f2",
+ "-f1",
+ "test.c",
+ "test.o",
+ true,
+ {
+ "-o1", "-o2", NULL
+ },
+ {
+ "c++", "-f1", "-f2", "-o1", "-o2", "-o", "test.o",
+ "-c", "test.c", NULL
+ },
+ },
+
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ false,
+ { NULL },
+ { NULL },
+ },
+};
diff --git a/external/bsd/atf/dist/atf-c/list_test.c b/external/bsd/atf/dist/atf-c/list_test.c
new file mode 100644
index 00000000000..900a3dd3145
--- /dev/null
+++ b/external/bsd/atf/dist/atf-c/list_test.c
@@ -0,0 +1,336 @@
+/*
+ * Automated Testing Framework (atf)
+ *
+ * Copyright (c) 2008, 2009 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 <stdio.h>
+
+#include <atf-c.h>
+
+#include "atf-c/list.h"
+
+#include "test_helpers.h"
+
+/* ---------------------------------------------------------------------
+ * Tests for the "atf_list" type.
+ * --------------------------------------------------------------------- */
+
+/*
+ * Constructors and destructors.
+ */
+
+ATF_TC(list_init);
+ATF_TC_HEAD(list_init, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks the atf_list_init function");
+}
+ATF_TC_BODY(list_init, tc)
+{
+ atf_list_t list;
+
+ RE(atf_list_init(&list));
+ ATF_REQUIRE_EQ(atf_list_size(&list), 0);
+ atf_list_fini(&list);
+}
+
+/*
+ * Getters.
+ */
+
+ATF_TC(list_index);
+ATF_TC_HEAD(list_index, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks the atf_list_index function");
+}
+ATF_TC_BODY(list_index, tc)
+{
+ atf_list_t list;
+ int i1 = 1;
+ int i2 = 5;
+ int i3 = 9;
+
+ RE(atf_list_init(&list));
+ RE(atf_list_append(&list, &i1, false));
+ RE(atf_list_append(&list, &i2, false));
+ RE(atf_list_append(&list, &i3, false));
+
+ ATF_CHECK_EQ(*(int *)atf_list_index(&list, 0), 1);
+ ATF_CHECK_EQ(*(int *)atf_list_index(&list, 1), 5);
+ ATF_CHECK_EQ(*(int *)atf_list_index(&list, 2), 9);
+
+ atf_list_fini(&list);
+}
+
+ATF_TC(list_index_c);
+ATF_TC_HEAD(list_index_c, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks the atf_list_index_c function");
+}
+ATF_TC_BODY(list_index_c, tc)
+{
+ atf_list_t list;
+ int i1 = 1;
+ int i2 = 5;
+ int i3 = 9;
+
+ RE(atf_list_init(&list));
+ RE(atf_list_append(&list, &i1, false));
+ RE(atf_list_append(&list, &i2, false));
+ RE(atf_list_append(&list, &i3, false));
+
+ ATF_CHECK_EQ(*(const int *)atf_list_index_c(&list, 0), 1);
+ ATF_CHECK_EQ(*(const int *)atf_list_index_c(&list, 1), 5);
+ ATF_CHECK_EQ(*(const int *)atf_list_index_c(&list, 2), 9);
+
+ atf_list_fini(&list);
+}
+
+/*
+ * Modifiers.
+ */
+
+ATF_TC(list_append);
+ATF_TC_HEAD(list_append, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks the atf_list_append function");
+}
+ATF_TC_BODY(list_append, tc)
+{
+ atf_list_t list;
+ size_t i;
+ char buf[] = "Test string";
+
+ RE(atf_list_init(&list));
+ for (i = 0; i < 1024; i++) {
+ ATF_REQUIRE_EQ(atf_list_size(&list), i);
+ RE(atf_list_append(&list, buf, false));
+ }
+ atf_list_fini(&list);
+}
+
+ATF_TC(list_append_list);
+ATF_TC_HEAD(list_append_list, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks the atf_list_append_list "
+ "function");
+}
+ATF_TC_BODY(list_append_list, tc)
+{
+ {
+ atf_list_t l1, l2;
+
+ RE(atf_list_init(&l1));
+ RE(atf_list_init(&l2));
+
+ atf_list_append_list(&l1, &l2);
+ ATF_CHECK_EQ(atf_list_size(&l1), 0);
+
+ atf_list_fini(&l1);
+ }
+
+ {
+ atf_list_t l1, l2;
+ int item = 5;
+
+ RE(atf_list_init(&l1));
+ RE(atf_list_append(&l1, &item, false));
+ RE(atf_list_init(&l2));
+
+ atf_list_append_list(&l1, &l2);
+ ATF_CHECK_EQ(atf_list_size(&l1), 1);
+ ATF_CHECK_EQ(*(int *)atf_list_index(&l1, 0), item);
+
+ atf_list_fini(&l1);
+ }
+
+ {
+ atf_list_t l1, l2;
+ int item = 5;
+
+ RE(atf_list_init(&l1));
+ RE(atf_list_init(&l2));
+ RE(atf_list_append(&l2, &item, false));
+
+ atf_list_append_list(&l1, &l2);
+ ATF_CHECK_EQ(atf_list_size(&l1), 1);
+ ATF_CHECK_EQ(*(int *)atf_list_index(&l1, 0), item);
+
+ atf_list_fini(&l1);
+ }
+
+ {
+ atf_list_t l1, l2;
+ int item1 = 5;
+ int item2 = 9;
+
+ RE(atf_list_init(&l1));
+ RE(atf_list_append(&l1, &item1, false));
+ RE(atf_list_init(&l2));
+ RE(atf_list_append(&l2, &item2, false));
+
+ atf_list_append_list(&l1, &l2);
+ ATF_CHECK_EQ(atf_list_size(&l1), 2);
+ ATF_CHECK_EQ(*(int *)atf_list_index(&l1, 0), item1);
+ ATF_CHECK_EQ(*(int *)atf_list_index(&l1, 1), item2);
+
+ atf_list_fini(&l1);
+ }
+
+ {
+ atf_list_t l1, l2;
+ atf_list_citer_t end1, end2;
+
+ RE(atf_list_init(&l1));
+ RE(atf_list_init(&l2));
+
+ end1 = atf_list_end_c(&l1);
+ end2 = atf_list_end_c(&l2);
+ /* XXX Shouldn't query m_entry here. */
+ ATF_CHECK(end1.m_entry != end2.m_entry);
+
+ atf_list_append_list(&l1, &l2);
+ ATF_CHECK(atf_list_end_c(&l1).m_entry == end2.m_entry);
+
+ atf_list_fini(&l1);
+ }
+}
+
+/*
+ * Macros.
+ */
+
+ATF_TC(list_for_each);
+ATF_TC_HEAD(list_for_each, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks the atf_list_for_each macro");
+}
+ATF_TC_BODY(list_for_each, tc)
+{
+ atf_list_t list;
+ atf_list_iter_t iter;
+ size_t count, i, size;
+ int nums[10];
+
+ printf("Iterating over empty list\n");
+ RE(atf_list_init(&list));
+ count = 0;
+ atf_list_for_each(iter, &list) {
+ count++;
+ printf("Item count is now %zd\n", count);
+ }
+ ATF_REQUIRE_EQ(count, 0);
+ atf_list_fini(&list);
+
+ for (size = 0; size <= 10; size++) {
+ printf("Iterating over list of %zd elements\n", size);
+ RE(atf_list_init(&list));
+ for (i = 0; i < size; i++) {
+ nums[i] = i + 1;
+ RE(atf_list_append(&list, &nums[i], false));
+ }
+ count = 0;
+ atf_list_for_each(iter, &list) {
+ printf("Retrieved item: %d\n", *(int *)atf_list_iter_data(iter));
+ count++;
+ }
+ ATF_REQUIRE_EQ(count, size);
+ atf_list_fini(&list);
+ }
+}
+
+ATF_TC(list_for_each_c);
+ATF_TC_HEAD(list_for_each_c, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks the atf_list_for_each_c macro");
+}
+ATF_TC_BODY(list_for_each_c, tc)
+{
+ atf_list_t list;
+ atf_list_citer_t iter;
+ size_t count, i, size;
+ int nums[10];
+
+ printf("Iterating over empty list\n");
+ RE(atf_list_init(&list));
+ count = 0;
+ atf_list_for_each_c(iter, &list) {
+ count++;
+ printf("Item count is now %zd\n", count);
+ }
+ ATF_REQUIRE_EQ(count, 0);
+ atf_list_fini(&list);
+
+ for (size = 0; size <= 10; size++) {
+ printf("Iterating over list of %zd elements\n", size);
+ RE(atf_list_init(&list));
+ for (i = 0; i < size; i++) {
+ nums[i] = i + 1;
+ RE(atf_list_append(&list, &nums[i], false));
+ }
+ count = 0;
+ atf_list_for_each_c(iter, &list) {
+ printf("Retrieved item: %d\n",
+ *(const int *)atf_list_citer_data(iter));
+ count++;
+ }
+ ATF_REQUIRE_EQ(count, size);
+ atf_list_fini(&list);
+ }
+}
+
+/* ---------------------------------------------------------------------
+ * Tests cases for the header file.
+ * --------------------------------------------------------------------- */
+
+HEADER_TC(include, "atf-c/list.h");
+
+/* ---------------------------------------------------------------------
+ * Main.
+ * --------------------------------------------------------------------- */
+
+ATF_TP_ADD_TCS(tp)
+{
+ /* Constructors and destructors. */
+ ATF_TP_ADD_TC(tp, list_init);
+
+ /* Getters. */
+ ATF_TP_ADD_TC(tp, list_index);
+ ATF_TP_ADD_TC(tp, list_index_c);
+
+ /* Modifiers. */
+ ATF_TP_ADD_TC(tp, list_append);
+ ATF_TP_ADD_TC(tp, list_append_list);
+
+ /* Macros. */
+ ATF_TP_ADD_TC(tp, list_for_each);
+ ATF_TP_ADD_TC(tp, list_for_each_c);
+
+ /* Add the test cases for the header file. */
+ ATF_TP_ADD_TC(tp, include);
+
+ return atf_no_error();
+}
diff --git a/external/bsd/atf/dist/atf-c/macros.h b/external/bsd/atf/dist/atf-c/macros.h
index ff082555cb9..405c8e7d6a5 100644
--- a/external/bsd/atf/dist/atf-c/macros.h
+++ b/external/bsd/atf/dist/atf-c/macros.h
@@ -135,10 +135,16 @@
} while(0)
#define ATF_REQUIRE(x) \
- ATF_REQUIRE_MSG(x, #x " not met")
+ do { \
+ if (!(x)) \
+ atf_tc_fail_requirement(__FILE__, __LINE__, "%s", #x " not met"); \
+ } while(0)
#define ATF_CHECK(x) \
- ATF_CHECK_MSG(x, #x " not met")
+ do { \
+ if (!(x)) \
+ atf_tc_fail_check(__FILE__, __LINE__, "%s", #x " not met"); \
+ } while(0)
#define ATF_REQUIRE_EQ(x, y) \
ATF_REQUIRE_MSG((x) == (y), "%s != %s", #x, #y)
@@ -166,4 +172,10 @@
ATF_CHECK_MSG(strcmp(x, y) == 0, "%s != %s (%s != %s): " fmt, \
#x, #y, x, y, ##__VA_ARGS__)
+#define ATF_CHECK_ERRNO(exp_errno, bool_expr) \
+ atf_tc_check_errno(__FILE__, __LINE__, exp_errno, #bool_expr, bool_expr)
+
+#define ATF_REQUIRE_ERRNO(exp_errno, bool_expr) \
+ atf_tc_require_errno(__FILE__, __LINE__, exp_errno, #bool_expr, bool_expr)
+
#endif /* !defined(ATF_C_MACROS_H) */
diff --git a/external/bsd/atf/dist/atf-c/macros_h_test.c b/external/bsd/atf/dist/atf-c/macros_h_test.c
new file mode 100644
index 00000000000..cd2f4013719
--- /dev/null
+++ b/external/bsd/atf/dist/atf-c/macros_h_test.c
@@ -0,0 +1,103 @@
+/*
+ * Automated Testing Framework (atf)
+ *
+ * Copyright (c) 2008, 2009, 2010 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <atf-c/macros.h>
+
+void atf_require_inside_if(void);
+void atf_require_equal_inside_if(void);
+void atf_check_errno_semicolons(void);
+void atf_require_errno_semicolons(void);
+
+void
+atf_require_inside_if(void)
+{
+ /* Make sure that ATF_REQUIRE can be used inside an if statement that
+ * does not have braces. Earlier versions of it generated an error
+ * if there was an else clause because they confused the compiler
+ * by defining an unprotected nested if. */
+ if (true)
+ ATF_REQUIRE(true);
+ else
+ ATF_REQUIRE(true);
+}
+
+void
+atf_require_equal_inside_if(void)
+{
+ /* Make sure that ATF_REQUIRE_EQUAL can be used inside an if statement
+ * that does not have braces. Earlier versions of it generated an
+ * error if there was an else clause because they confused the
+ * compiler by defining an unprotected nested if. */
+ if (true)
+ ATF_REQUIRE_EQ(true, true);
+ else
+ ATF_REQUIRE_EQ(true, true);
+}
+
+void
+atf_check_errno_semicolons(void)
+{
+ /* Check that ATF_CHECK_ERRNO does not contain a semicolon that would
+ * cause an empty-statement that confuses some compilers. */
+ ATF_CHECK_ERRNO(1, 1 == 1);
+ ATF_CHECK_ERRNO(2, 2 == 2);
+}
+
+void
+atf_require_errno_semicolons(void)
+{
+ /* Check that ATF_REQUIRE_ERRNO does not contain a semicolon that would
+ * cause an empty-statement that confuses some compilers. */
+ ATF_REQUIRE_ERRNO(1, 1 == 1);
+ ATF_REQUIRE_ERRNO(2, 2 == 2);
+}
+
+/* Test case names should not be expanded during instatiation so that they
+ * can have the exact same name as macros. */
+#define TEST_MACRO_1 invalid + name
+#define TEST_MACRO_2 invalid + name
+#define TEST_MACRO_3 invalid + name
+ATF_TC(TEST_MACRO_1);
+ATF_TC_HEAD(TEST_MACRO_1, tc) { }
+ATF_TC_BODY(TEST_MACRO_1, tc) { }
+atf_tc_t *test_name_1 = &ATF_TC_NAME(TEST_MACRO_1);
+void (*head_1)(atf_tc_t *) = ATF_TC_HEAD_NAME(TEST_MACRO_1);
+void (*body_1)(const atf_tc_t *) = ATF_TC_BODY_NAME(TEST_MACRO_1);
+ATF_TC_WITH_CLEANUP(TEST_MACRO_2);
+ATF_TC_HEAD(TEST_MACRO_2, tc) { }
+ATF_TC_BODY(TEST_MACRO_2, tc) { }
+ATF_TC_CLEANUP(TEST_MACRO_2, tc) { }
+atf_tc_t *test_name_2 = &ATF_TC_NAME(TEST_MACRO_2);
+void (*head_2)(atf_tc_t *) = ATF_TC_HEAD_NAME(TEST_MACRO_2);
+void (*body_2)(const atf_tc_t *) = ATF_TC_BODY_NAME(TEST_MACRO_2);
+void (*cleanup_2)(const atf_tc_t *) = ATF_TC_CLEANUP_NAME(TEST_MACRO_2);
+ATF_TC_WITHOUT_HEAD(TEST_MACRO_3);
+ATF_TC_BODY(TEST_MACRO_3, tc) { }
+atf_tc_t *test_name_3 = &ATF_TC_NAME(TEST_MACRO_3);
+void (*body_3)(const atf_tc_t *) = ATF_TC_BODY_NAME(TEST_MACRO_3);
diff --git a/external/bsd/atf/dist/atf-c/macros_test.c b/external/bsd/atf/dist/atf-c/macros_test.c
new file mode 100644
index 00000000000..a9b02bb9328
--- /dev/null
+++ b/external/bsd/atf/dist/atf-c/macros_test.c
@@ -0,0 +1,788 @@
+/*
+ * Automated Testing Framework (atf)
+ *
+ * Copyright (c) 2008, 2009, 2010 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <atf-c.h>
+
+#include "atf-c/fs.h"
+#include "atf-c/process.h"
+#include "atf-c/text.h"
+
+#include "test_helpers.h"
+
+/* ---------------------------------------------------------------------
+ * Auxiliary functions.
+ * --------------------------------------------------------------------- */
+
+static
+void
+create_ctl_file(const atf_tc_t *tc, const char *name)
+{
+ atf_fs_path_t p;
+
+ RE(atf_fs_path_init_fmt(&p, "%s", name));
+ ATF_REQUIRE(open(atf_fs_path_cstring(&p),
+ O_CREAT | O_WRONLY | O_TRUNC, 0644) != -1);
+ atf_fs_path_fini(&p);
+}
+
+static
+bool
+exists(const char *p)
+{
+ bool b;
+ atf_fs_path_t pp;
+
+ RE(atf_fs_path_init_fmt(&pp, "%s", p));
+ RE(atf_fs_exists(&pp, &b));
+ atf_fs_path_fini(&pp);
+
+ return b;
+}
+
+static
+void
+init_and_run_h_tc(const char *name, void (*head)(atf_tc_t *),
+ void (*body)(const atf_tc_t *))
+{
+ atf_tc_t tc;
+ atf_map_t config;
+
+ RE(atf_map_init(&config));
+ RE(atf_tc_init(&tc, name, head, body, NULL, &config));
+ run_h_tc(&tc, "output", "error", "result");
+ atf_tc_fini(&tc);
+ atf_map_fini(&config);
+}
+
+/* ---------------------------------------------------------------------
+ * Helper test cases.
+ * --------------------------------------------------------------------- */
+
+#define H_DEF(id, macro) \
+ ATF_TC_HEAD(h_ ## id, tc) \
+ { \
+ atf_tc_set_md_var(tc, "descr", "Helper test case"); \
+ } \
+ ATF_TC_BODY(h_ ## id, tc) \
+ { \
+ create_ctl_file(tc, "before"); \
+ macro; \
+ create_ctl_file(tc, "after"); \
+ }
+
+#define H_CHECK_HEAD_NAME(id) ATF_TC_HEAD_NAME(h_check_ ## id)
+#define H_CHECK_BODY_NAME(id) ATF_TC_BODY_NAME(h_check_ ## id)
+#define H_CHECK(id, condition) \
+ H_DEF(check_ ## id, ATF_CHECK(condition))
+
+#define H_CHECK_MSG_HEAD_NAME(id) ATF_TC_HEAD_NAME(h_check_msg_ ## id)
+#define H_CHECK_MSG_BODY_NAME(id) ATF_TC_BODY_NAME(h_check_msg_ ## id)
+#define H_CHECK_MSG(id, condition, msg) \
+ H_DEF(check_msg_ ## id, ATF_CHECK_MSG(condition, msg))
+
+#define H_CHECK_EQ_HEAD_NAME(id) ATF_TC_HEAD_NAME(h_check_eq_ ## id)
+#define H_CHECK_EQ_BODY_NAME(id) ATF_TC_BODY_NAME(h_check_eq_ ## id)
+#define H_CHECK_EQ(id, v1, v2) \
+ H_DEF(check_eq_ ## id, ATF_CHECK_EQ(v1, v2))
+
+#define H_CHECK_STREQ_HEAD_NAME(id) ATF_TC_HEAD_NAME(h_check_streq_ ## id)
+#define H_CHECK_STREQ_BODY_NAME(id) ATF_TC_BODY_NAME(h_check_streq_ ## id)
+#define H_CHECK_STREQ(id, v1, v2) \
+ H_DEF(check_streq_ ## id, ATF_CHECK_STREQ(v1, v2))
+
+#define H_CHECK_EQ_MSG_HEAD_NAME(id) \
+ ATF_TC_HEAD_NAME(h_check_eq_msg_ ## id)
+#define H_CHECK_EQ_MSG_BODY_NAME(id) \
+ ATF_TC_BODY_NAME(h_check_eq_msg_ ## id)
+#define H_CHECK_EQ_MSG(id, v1, v2, msg) \
+ H_DEF(check_eq_msg_ ## id, ATF_CHECK_EQ_MSG(v1, v2, msg))
+
+#define H_CHECK_STREQ_MSG_HEAD_NAME(id) \
+ ATF_TC_HEAD_NAME(h_check_streq_msg_ ## id)
+#define H_CHECK_STREQ_MSG_BODY_NAME(id) \
+ ATF_TC_BODY_NAME(h_check_streq_msg_ ## id)
+#define H_CHECK_STREQ_MSG(id, v1, v2, msg) \
+ H_DEF(check_streq_msg_ ## id, ATF_CHECK_STREQ_MSG(v1, v2, msg))
+
+#define H_CHECK_ERRNO_HEAD_NAME(id) ATF_TC_HEAD_NAME(h_check_errno_ ## id)
+#define H_CHECK_ERRNO_BODY_NAME(id) ATF_TC_BODY_NAME(h_check_errno_ ## id)
+#define H_CHECK_ERRNO(id, exp_errno, bool_expr) \
+ H_DEF(check_errno_ ## id, ATF_CHECK_ERRNO(exp_errno, bool_expr))
+
+#define H_REQUIRE_HEAD_NAME(id) ATF_TC_HEAD_NAME(h_require_ ## id)
+#define H_REQUIRE_BODY_NAME(id) ATF_TC_BODY_NAME(h_require_ ## id)
+#define H_REQUIRE(id, condition) \
+ H_DEF(require_ ## id, ATF_REQUIRE(condition))
+
+#define H_REQUIRE_MSG_HEAD_NAME(id) ATF_TC_HEAD_NAME(h_require_msg_ ## id)
+#define H_REQUIRE_MSG_BODY_NAME(id) ATF_TC_BODY_NAME(h_require_msg_ ## id)
+#define H_REQUIRE_MSG(id, condition, msg) \
+ H_DEF(require_msg_ ## id, ATF_REQUIRE_MSG(condition, msg))
+
+#define H_REQUIRE_EQ_HEAD_NAME(id) ATF_TC_HEAD_NAME(h_require_eq_ ## id)
+#define H_REQUIRE_EQ_BODY_NAME(id) ATF_TC_BODY_NAME(h_require_eq_ ## id)
+#define H_REQUIRE_EQ(id, v1, v2) \
+ H_DEF(require_eq_ ## id, ATF_REQUIRE_EQ(v1, v2))
+
+#define H_REQUIRE_STREQ_HEAD_NAME(id) ATF_TC_HEAD_NAME(h_require_streq_ ## id)
+#define H_REQUIRE_STREQ_BODY_NAME(id) ATF_TC_BODY_NAME(h_require_streq_ ## id)
+#define H_REQUIRE_STREQ(id, v1, v2) \
+ H_DEF(require_streq_ ## id, ATF_REQUIRE_STREQ(v1, v2))
+
+#define H_REQUIRE_EQ_MSG_HEAD_NAME(id) \
+ ATF_TC_HEAD_NAME(h_require_eq_msg_ ## id)
+#define H_REQUIRE_EQ_MSG_BODY_NAME(id) \
+ ATF_TC_BODY_NAME(h_require_eq_msg_ ## id)
+#define H_REQUIRE_EQ_MSG(id, v1, v2, msg) \
+ H_DEF(require_eq_msg_ ## id, ATF_REQUIRE_EQ_MSG(v1, v2, msg))
+
+#define H_REQUIRE_STREQ_MSG_HEAD_NAME(id) \
+ ATF_TC_HEAD_NAME(h_require_streq_msg_ ## id)
+#define H_REQUIRE_STREQ_MSG_BODY_NAME(id) \
+ ATF_TC_BODY_NAME(h_require_streq_msg_ ## id)
+#define H_REQUIRE_STREQ_MSG(id, v1, v2, msg) \
+ H_DEF(require_streq_msg_ ## id, ATF_REQUIRE_STREQ_MSG(v1, v2, msg))
+
+#define H_REQUIRE_ERRNO_HEAD_NAME(id) ATF_TC_HEAD_NAME(h_require_errno_ ## id)
+#define H_REQUIRE_ERRNO_BODY_NAME(id) ATF_TC_BODY_NAME(h_require_errno_ ## id)
+#define H_REQUIRE_ERRNO(id, exp_errno, bool_expr) \
+ H_DEF(require_errno_ ## id, ATF_REQUIRE_ERRNO(exp_errno, bool_expr))
+
+/* ---------------------------------------------------------------------
+ * Test cases for the ATF_{CHECK,REQUIRE}_ERRNO macros.
+ * --------------------------------------------------------------------- */
+
+static int
+errno_fail_stub(const int raised_errno)
+{
+ errno = raised_errno;
+ return -1;
+}
+
+static int
+errno_ok_stub(void)
+{
+ return 0;
+}
+
+H_CHECK_ERRNO(no_error, -1, errno_ok_stub() == -1);
+H_CHECK_ERRNO(errno_ok, 2, errno_fail_stub(2) == -1);
+H_CHECK_ERRNO(errno_fail, 3, errno_fail_stub(4) == -1);
+
+H_REQUIRE_ERRNO(no_error, -1, errno_ok_stub() == -1);
+H_REQUIRE_ERRNO(errno_ok, 2, errno_fail_stub(2) == -1);
+H_REQUIRE_ERRNO(errno_fail, 3, errno_fail_stub(4) == -1);
+
+ATF_TC(check_errno);
+ATF_TC_HEAD(check_errno, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests the ATF_CHECK_ERRNO macro");
+ atf_tc_set_md_var(tc, "use.fs", "true");
+}
+ATF_TC_BODY(check_errno, tc)
+{
+ struct test {
+ void (*head)(atf_tc_t *);
+ void (*body)(const atf_tc_t *);
+ bool ok;
+ const char *exp_regex;
+ } *t, tests[] = {
+ { H_CHECK_ERRNO_HEAD_NAME(no_error),
+ H_CHECK_ERRNO_BODY_NAME(no_error),
+ false, "Expected true value in errno_ok_stub\\(\\) == -1" },
+ { H_CHECK_ERRNO_HEAD_NAME(errno_ok),
+ H_CHECK_ERRNO_BODY_NAME(errno_ok),
+ true, NULL },
+ { H_CHECK_ERRNO_HEAD_NAME(errno_fail),
+ H_CHECK_ERRNO_BODY_NAME(errno_fail),
+ false, "Expected errno 3, got 4, in errno_fail_stub\\(4\\) == -1" },
+ { NULL, NULL, false, NULL }
+ };
+
+ for (t = &tests[0]; t->head != NULL; t++) {
+ init_and_run_h_tc("h_check_errno", t->head, t->body);
+
+ ATF_REQUIRE(exists("before"));
+ ATF_REQUIRE(exists("after"));
+
+ if (t->ok) {
+ ATF_REQUIRE(grep_file("result", "^passed"));
+ } else {
+ ATF_REQUIRE(grep_file("result", "^failed"));
+ ATF_REQUIRE(grep_file("error", "macros_test.c:[0-9]+: %s$",
+ t->exp_regex));
+ }
+
+ ATF_REQUIRE(unlink("before") != -1);
+ ATF_REQUIRE(unlink("after") != -1);
+ }
+}
+
+ATF_TC(require_errno);
+ATF_TC_HEAD(require_errno, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests the ATF_REQUIRE_ERRNO macro");
+ atf_tc_set_md_var(tc, "use.fs", "true");
+}
+ATF_TC_BODY(require_errno, tc)
+{
+ struct test {
+ void (*head)(atf_tc_t *);
+ void (*body)(const atf_tc_t *);
+ bool ok;
+ const char *exp_regex;
+ } *t, tests[] = {
+ { H_REQUIRE_ERRNO_HEAD_NAME(no_error),
+ H_REQUIRE_ERRNO_BODY_NAME(no_error),
+ false, "Expected true value in errno_ok_stub\\(\\) == -1" },
+ { H_REQUIRE_ERRNO_HEAD_NAME(errno_ok),
+ H_REQUIRE_ERRNO_BODY_NAME(errno_ok),
+ true, NULL },
+ { H_REQUIRE_ERRNO_HEAD_NAME(errno_fail),
+ H_REQUIRE_ERRNO_BODY_NAME(errno_fail),
+ false, "Expected errno 3, got 4, in errno_fail_stub\\(4\\) == -1" },
+ { NULL, NULL, false, NULL }
+ };
+
+ for (t = &tests[0]; t->head != NULL; t++) {
+ init_and_run_h_tc("h_require_errno", t->head, t->body);
+
+ ATF_REQUIRE(exists("before"));
+ if (t->ok) {
+ ATF_REQUIRE(grep_file("result", "^passed"));
+ ATF_REQUIRE(exists("after"));
+ } else {
+ ATF_REQUIRE(grep_file("result", "^failed: .*macros_test.c:[0-9]+: "
+ "%s$", t->exp_regex));
+ ATF_REQUIRE(!exists("after"));
+ }
+
+ ATF_REQUIRE(unlink("before") != -1);
+ if (t->ok)
+ ATF_REQUIRE(unlink("after") != -1);
+ }
+}
+
+/* ---------------------------------------------------------------------
+ * Test cases for the ATF_CHECK and ATF_CHECK_MSG macros.
+ * --------------------------------------------------------------------- */
+
+H_CHECK(0, 0);
+H_CHECK(1, 1);
+H_CHECK_MSG(0, 0, "expected a false value");
+H_CHECK_MSG(1, 1, "expected a true value");
+
+ATF_TC(check);
+ATF_TC_HEAD(check, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests the ATF_CHECK and "
+ "ATF_CHECK_MSG macros");
+ atf_tc_set_md_var(tc, "use.fs", "true");
+}
+ATF_TC_BODY(check, tc)
+{
+ struct test {
+ void (*head)(atf_tc_t *);
+ void (*body)(const atf_tc_t *);
+ bool value;
+ const char *msg;
+ bool ok;
+ } *t, tests[] = {
+ { H_CHECK_HEAD_NAME(0), H_CHECK_BODY_NAME(0), 0,
+ "0 not met", false },
+ { H_CHECK_HEAD_NAME(1), H_CHECK_BODY_NAME(1), 1,
+ "1 not met", true },
+ { H_CHECK_MSG_HEAD_NAME(0), H_CHECK_MSG_BODY_NAME(0), 0,
+ "expected a false value", false },
+ { H_CHECK_MSG_HEAD_NAME(1), H_CHECK_MSG_BODY_NAME(1), 1,
+ "expected a true value", true },
+ { NULL, NULL, false, NULL, false }
+ };
+
+ for (t = &tests[0]; t->head != NULL; t++) {
+ printf("Checking with a %d value\n", t->value);
+
+ init_and_run_h_tc("h_check", t->head, t->body);
+
+ ATF_REQUIRE(exists("before"));
+ ATF_REQUIRE(exists("after"));
+
+ if (t->ok) {
+ ATF_REQUIRE(grep_file("result", "^passed"));
+ } else {
+ ATF_REQUIRE(grep_file("result", "^failed"));
+ ATF_REQUIRE(grep_file("error", "Check failed: .*"
+ "macros_test.c:[0-9]+: %s$", t->msg));
+ }
+
+ ATF_REQUIRE(unlink("before") != -1);
+ ATF_REQUIRE(unlink("after") != -1);
+ }
+}
+
+/* ---------------------------------------------------------------------
+ * Test cases for the ATF_CHECK_*EQ_ macros.
+ * --------------------------------------------------------------------- */
+
+struct check_eq_test {
+ void (*head)(atf_tc_t *);
+ void (*body)(const atf_tc_t *);
+ const char *v1;
+ const char *v2;
+ const char *msg;
+ bool ok;
+};
+
+static
+void
+do_check_eq_tests(const struct check_eq_test *tests)
+{
+ const struct check_eq_test *t;
+
+ for (t = &tests[0]; t->head != NULL; t++) {
+ printf("Checking with %s, %s and expecting %s\n", t->v1, t->v2,
+ t->ok ? "true" : "false");
+
+ init_and_run_h_tc("h_check", t->head, t->body);
+
+ ATF_CHECK(exists("before"));
+ ATF_CHECK(exists("after"));
+
+ if (t->ok) {
+ ATF_REQUIRE(grep_file("result", "^passed"));
+ } else {
+ ATF_REQUIRE(grep_file("result", "^failed"));
+ ATF_CHECK(grep_file("error", "Check failed: .*"
+ "macros_test.c:[0-9]+: %s$", t->msg));
+ }
+
+ ATF_CHECK(unlink("before") != -1);
+ ATF_CHECK(unlink("after") != -1);
+ }
+}
+
+H_CHECK_EQ(1_1, 1, 1);
+H_CHECK_EQ(1_2, 1, 2);
+H_CHECK_EQ(2_1, 2, 1);
+H_CHECK_EQ(2_2, 2, 2);
+H_CHECK_EQ_MSG(1_1, 1, 1, "1 does not match 1");
+H_CHECK_EQ_MSG(1_2, 1, 2, "1 does not match 2");
+H_CHECK_EQ_MSG(2_1, 2, 1, "2 does not match 1");
+H_CHECK_EQ_MSG(2_2, 2, 2, "2 does not match 2");
+
+ATF_TC(check_eq);
+ATF_TC_HEAD(check_eq, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests the ATF_CHECK_EQ and "
+ "ATF_CHECK_EQ_MSG macros");
+ atf_tc_set_md_var(tc, "use.fs", "true");
+}
+ATF_TC_BODY(check_eq, tc)
+{
+ struct check_eq_test tests[] = {
+ { H_CHECK_EQ_HEAD_NAME(1_1), H_CHECK_EQ_BODY_NAME(1_1),
+ "1", "1", "1 != 1", true },
+ { H_CHECK_EQ_HEAD_NAME(1_2), H_CHECK_EQ_BODY_NAME(1_2),
+ "1", "2", "1 != 2", false },
+ { H_CHECK_EQ_HEAD_NAME(2_1), H_CHECK_EQ_BODY_NAME(2_1),
+ "2", "1", "2 != 1", false },
+ { H_CHECK_EQ_HEAD_NAME(2_2), H_CHECK_EQ_BODY_NAME(2_2),
+ "2", "2", "2 != 2", true },
+ { H_CHECK_EQ_MSG_HEAD_NAME(1_1), H_CHECK_EQ_MSG_BODY_NAME(1_1),
+ "1", "1", "1 != 1: 1 does not match 1", true },
+ { H_CHECK_EQ_MSG_HEAD_NAME(1_2), H_CHECK_EQ_MSG_BODY_NAME(1_2),
+ "1", "2", "1 != 2: 1 does not match 2", false },
+ { H_CHECK_EQ_MSG_HEAD_NAME(2_1), H_CHECK_EQ_MSG_BODY_NAME(2_1),
+ "2", "1", "2 != 1: 2 does not match 1", false },
+ { H_CHECK_EQ_MSG_HEAD_NAME(2_2), H_CHECK_EQ_MSG_BODY_NAME(2_2),
+ "2", "2", "2 != 2: 2 does not match 2", true },
+ { NULL, NULL, 0, 0, "", false }
+ };
+ do_check_eq_tests(tests);
+}
+
+H_CHECK_STREQ(1_1, "1", "1");
+H_CHECK_STREQ(1_2, "1", "2");
+H_CHECK_STREQ(2_1, "2", "1");
+H_CHECK_STREQ(2_2, "2", "2");
+H_CHECK_STREQ_MSG(1_1, "1", "1", "1 does not match 1");
+H_CHECK_STREQ_MSG(1_2, "1", "2", "1 does not match 2");
+H_CHECK_STREQ_MSG(2_1, "2", "1", "2 does not match 1");
+H_CHECK_STREQ_MSG(2_2, "2", "2", "2 does not match 2");
+#define CHECK_STREQ_VAR1 "5"
+#define CHECK_STREQ_VAR2 "9"
+const const char *check_streq_var1 = CHECK_STREQ_VAR1;
+const const char *check_streq_var2 = CHECK_STREQ_VAR2;
+H_CHECK_STREQ(vars, check_streq_var1, check_streq_var2);
+
+ATF_TC(check_streq);
+ATF_TC_HEAD(check_streq, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests the ATF_CHECK_STREQ and "
+ "ATF_CHECK_STREQ_MSG macros");
+ atf_tc_set_md_var(tc, "use.fs", "true");
+}
+ATF_TC_BODY(check_streq, tc)
+{
+ struct check_eq_test tests[] = {
+ { H_CHECK_STREQ_HEAD_NAME(1_1), H_CHECK_STREQ_BODY_NAME(1_1),
+ "1", "1", "\"1\" != \"1\" \\(1 != 1\\)", true },
+ { H_CHECK_STREQ_HEAD_NAME(1_2), H_CHECK_STREQ_BODY_NAME(1_2),
+ "1", "2", "\"1\" != \"2\" \\(1 != 2\\)", false },
+ { H_CHECK_STREQ_HEAD_NAME(2_1), H_CHECK_STREQ_BODY_NAME(2_1),
+ "2", "1", "\"2\" != \"1\" \\(2 != 1\\)", false },
+ { H_CHECK_STREQ_HEAD_NAME(2_2), H_CHECK_STREQ_BODY_NAME(2_2),
+ "2", "2", "\"2\" != \"2\" \\(2 != 2\\)", true },
+ { H_CHECK_STREQ_MSG_HEAD_NAME(1_1),
+ H_CHECK_STREQ_MSG_BODY_NAME(1_1),
+ "1", "1", "\"1\" != \"1\" \\(1 != 1\\): 1 does not match 1", true },
+ { H_CHECK_STREQ_MSG_HEAD_NAME(1_2),
+ H_CHECK_STREQ_MSG_BODY_NAME(1_2),
+ "1", "2", "\"1\" != \"2\" \\(1 != 2\\): 1 does not match 2", false },
+ { H_CHECK_STREQ_MSG_HEAD_NAME(2_1),
+ H_CHECK_STREQ_MSG_BODY_NAME(2_1),
+ "2", "1", "\"2\" != \"1\" \\(2 != 1\\): 2 does not match 1", false },
+ { H_CHECK_STREQ_MSG_HEAD_NAME(2_2),
+ H_CHECK_STREQ_MSG_BODY_NAME(2_2),
+ "2", "2", "\"2\" != \"2\" \\(2 != 2\\): 2 does not match 2", true },
+ { H_CHECK_STREQ_HEAD_NAME(vars), H_CHECK_STREQ_BODY_NAME(vars),
+ check_streq_var1, check_streq_var2,
+ "check_streq_var1 != check_streq_var2 \\("
+ CHECK_STREQ_VAR1 " != " CHECK_STREQ_VAR2 "\\)", false },
+ { NULL, NULL, 0, 0, "", false }
+ };
+ do_check_eq_tests(tests);
+}
+
+/* ---------------------------------------------------------------------
+ * Test cases for the ATF_REQUIRE and ATF_REQUIRE_MSG macros.
+ * --------------------------------------------------------------------- */
+
+H_REQUIRE(0, 0);
+H_REQUIRE(1, 1);
+H_REQUIRE_MSG(0, 0, "expected a false value");
+H_REQUIRE_MSG(1, 1, "expected a true value");
+
+ATF_TC(require);
+ATF_TC_HEAD(require, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests the ATF_REQUIRE and "
+ "ATF_REQUIRE_MSG macros");
+ atf_tc_set_md_var(tc, "use.fs", "true");
+}
+ATF_TC_BODY(require, tc)
+{
+ struct test {
+ void (*head)(atf_tc_t *);
+ void (*body)(const atf_tc_t *);
+ bool value;
+ const char *msg;
+ bool ok;
+ } *t, tests[] = {
+ { H_REQUIRE_HEAD_NAME(0), H_REQUIRE_BODY_NAME(0), 0,
+ "0 not met", false },
+ { H_REQUIRE_HEAD_NAME(1), H_REQUIRE_BODY_NAME(1), 1,
+ "1 not met", true },
+ { H_REQUIRE_MSG_HEAD_NAME(0), H_REQUIRE_MSG_BODY_NAME(0), 0,
+ "expected a false value", false },
+ { H_REQUIRE_MSG_HEAD_NAME(1), H_REQUIRE_MSG_BODY_NAME(1), 1,
+ "expected a true value", true },
+ { NULL, NULL, false, NULL, false }
+ };
+
+ for (t = &tests[0]; t->head != NULL; t++) {
+ printf("Checking with a %d value\n", t->value);
+
+ init_and_run_h_tc("h_require", t->head, t->body);
+
+ ATF_REQUIRE(exists("before"));
+ if (t->ok) {
+ ATF_REQUIRE(grep_file("result", "^passed"));
+ ATF_REQUIRE(exists("after"));
+ } else {
+ ATF_REQUIRE(grep_file("result", "^failed: .*macros_test.c:[0-9]+: "
+ "%s$", t->msg));
+ ATF_REQUIRE(!exists("after"));
+ }
+
+ ATF_REQUIRE(unlink("before") != -1);
+ if (t->ok)
+ ATF_REQUIRE(unlink("after") != -1);
+ }
+}
+
+/* ---------------------------------------------------------------------
+ * Test cases for the ATF_REQUIRE_*EQ_ macros.
+ * --------------------------------------------------------------------- */
+
+struct require_eq_test {
+ void (*head)(atf_tc_t *);
+ void (*body)(const atf_tc_t *);
+ const char *v1;
+ const char *v2;
+ const char *msg;
+ bool ok;
+};
+
+static
+void
+do_require_eq_tests(const struct require_eq_test *tests)
+{
+ const struct require_eq_test *t;
+
+ for (t = &tests[0]; t->head != NULL; t++) {
+ printf("Checking with %s, %s and expecting %s\n", t->v1, t->v2,
+ t->ok ? "true" : "false");
+
+ init_and_run_h_tc("h_require", t->head, t->body);
+
+ ATF_REQUIRE(exists("before"));
+ if (t->ok) {
+ ATF_REQUIRE(grep_file("result", "^passed"));
+ ATF_REQUIRE(exists("after"));
+ } else {
+ ATF_REQUIRE(grep_file("result", "^failed: .*macros_test.c"
+ ":[0-9]+: %s$", t->msg));
+ ATF_REQUIRE(!exists("after"));
+ }
+
+ ATF_REQUIRE(unlink("before") != -1);
+ if (t->ok)
+ ATF_REQUIRE(unlink("after") != -1);
+ }
+}
+
+H_REQUIRE_EQ(1_1, 1, 1);
+H_REQUIRE_EQ(1_2, 1, 2);
+H_REQUIRE_EQ(2_1, 2, 1);
+H_REQUIRE_EQ(2_2, 2, 2);
+H_REQUIRE_EQ_MSG(1_1, 1, 1, "1 does not match 1");
+H_REQUIRE_EQ_MSG(1_2, 1, 2, "1 does not match 2");
+H_REQUIRE_EQ_MSG(2_1, 2, 1, "2 does not match 1");
+H_REQUIRE_EQ_MSG(2_2, 2, 2, "2 does not match 2");
+
+ATF_TC(require_eq);
+ATF_TC_HEAD(require_eq, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests the ATF_REQUIRE_EQ and "
+ "ATF_REQUIRE_EQ_MSG macros");
+ atf_tc_set_md_var(tc, "use.fs", "true");
+}
+ATF_TC_BODY(require_eq, tc)
+{
+ struct require_eq_test tests[] = {
+ { H_REQUIRE_EQ_HEAD_NAME(1_1), H_REQUIRE_EQ_BODY_NAME(1_1),
+ "1", "1", "1 != 1", true },
+ { H_REQUIRE_EQ_HEAD_NAME(1_2), H_REQUIRE_EQ_BODY_NAME(1_2),
+ "1", "2", "1 != 2", false },
+ { H_REQUIRE_EQ_HEAD_NAME(2_1), H_REQUIRE_EQ_BODY_NAME(2_1),
+ "2", "1", "2 != 1", false },
+ { H_REQUIRE_EQ_HEAD_NAME(2_2), H_REQUIRE_EQ_BODY_NAME(2_2),
+ "2", "2", "2 != 2", true },
+ { H_REQUIRE_EQ_MSG_HEAD_NAME(1_1), H_REQUIRE_EQ_MSG_BODY_NAME(1_1),
+ "1", "1", "1 != 1: 1 does not match 1", true },
+ { H_REQUIRE_EQ_MSG_HEAD_NAME(1_2), H_REQUIRE_EQ_MSG_BODY_NAME(1_2),
+ "1", "2", "1 != 2: 1 does not match 2", false },
+ { H_REQUIRE_EQ_MSG_HEAD_NAME(2_1), H_REQUIRE_EQ_MSG_BODY_NAME(2_1),
+ "2", "1", "2 != 1: 2 does not match 1", false },
+ { H_REQUIRE_EQ_MSG_HEAD_NAME(2_2), H_REQUIRE_EQ_MSG_BODY_NAME(2_2),
+ "2", "2", "2 != 2: 2 does not match 2", true },
+ { NULL, NULL, 0, 0, "", false }
+ };
+ do_require_eq_tests(tests);
+}
+
+H_REQUIRE_STREQ(1_1, "1", "1");
+H_REQUIRE_STREQ(1_2, "1", "2");
+H_REQUIRE_STREQ(2_1, "2", "1");
+H_REQUIRE_STREQ(2_2, "2", "2");
+H_REQUIRE_STREQ_MSG(1_1, "1", "1", "1 does not match 1");
+H_REQUIRE_STREQ_MSG(1_2, "1", "2", "1 does not match 2");
+H_REQUIRE_STREQ_MSG(2_1, "2", "1", "2 does not match 1");
+H_REQUIRE_STREQ_MSG(2_2, "2", "2", "2 does not match 2");
+#define REQUIRE_STREQ_VAR1 "5"
+#define REQUIRE_STREQ_VAR2 "9"
+const const char *require_streq_var1 = REQUIRE_STREQ_VAR1;
+const const char *require_streq_var2 = REQUIRE_STREQ_VAR2;
+H_REQUIRE_STREQ(vars, require_streq_var1, require_streq_var2);
+
+ATF_TC(require_streq);
+ATF_TC_HEAD(require_streq, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests the ATF_REQUIRE_STREQ and "
+ "ATF_REQUIRE_STREQ_MSG macros");
+ atf_tc_set_md_var(tc, "use.fs", "true");
+}
+ATF_TC_BODY(require_streq, tc)
+{
+ struct require_eq_test tests[] = {
+ { H_REQUIRE_STREQ_HEAD_NAME(1_1), H_REQUIRE_STREQ_BODY_NAME(1_1),
+ "1", "1", "\"1\" != \"1\" \\(1 != 1\\)", true },
+ { H_REQUIRE_STREQ_HEAD_NAME(1_2), H_REQUIRE_STREQ_BODY_NAME(1_2),
+ "1", "2", "\"1\" != \"2\" \\(1 != 2\\)", false },
+ { H_REQUIRE_STREQ_HEAD_NAME(2_1), H_REQUIRE_STREQ_BODY_NAME(2_1),
+ "2", "1", "\"2\" != \"1\" \\(2 != 1\\)", false },
+ { H_REQUIRE_STREQ_HEAD_NAME(2_2), H_REQUIRE_STREQ_BODY_NAME(2_2),
+ "2", "2", "\"2\" != \"2\" \\(2 != 2\\)", true },
+ { H_REQUIRE_STREQ_MSG_HEAD_NAME(1_1),
+ H_REQUIRE_STREQ_MSG_BODY_NAME(1_1),
+ "1", "1", "\"1\" != \"1\" \\(1 != 1\\): 1 does not match 1", true },
+ { H_REQUIRE_STREQ_MSG_HEAD_NAME(1_2),
+ H_REQUIRE_STREQ_MSG_BODY_NAME(1_2),
+ "1", "2", "\"1\" != \"2\" \\(1 != 2\\): 1 does not match 2", false },
+ { H_REQUIRE_STREQ_MSG_HEAD_NAME(2_1),
+ H_REQUIRE_STREQ_MSG_BODY_NAME(2_1),
+ "2", "1", "\"2\" != \"1\" \\(2 != 1\\): 2 does not match 1", false },
+ { H_REQUIRE_STREQ_MSG_HEAD_NAME(2_2),
+ H_REQUIRE_STREQ_MSG_BODY_NAME(2_2),
+ "2", "2", "\"2\" != \"2\" \\(2 != 2\\): 2 does not match 2", true },
+ { H_REQUIRE_STREQ_HEAD_NAME(vars), H_REQUIRE_STREQ_BODY_NAME(vars),
+ require_streq_var1, require_streq_var2,
+ "require_streq_var1 != require_streq_var2 \\("
+ REQUIRE_STREQ_VAR1 " != " REQUIRE_STREQ_VAR2 "\\)", false },
+ { NULL, NULL, 0, 0, "", false }
+ };
+ do_require_eq_tests(tests);
+}
+
+/* ---------------------------------------------------------------------
+ * Miscellaneous test cases covering several macros.
+ * --------------------------------------------------------------------- */
+
+static
+bool
+aux_bool(const char *fmt)
+{
+ return false;
+}
+
+static
+const char *
+aux_str(const char *fmt)
+{
+ return "foo";
+}
+
+H_CHECK(msg, aux_bool("%d"));
+H_REQUIRE(msg, aux_bool("%d"));
+H_CHECK_STREQ(msg, aux_str("%d"), "");
+H_REQUIRE_STREQ(msg, aux_str("%d"), "");
+
+ATF_TC(msg_embedded_fmt);
+ATF_TC_HEAD(msg_embedded_fmt, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests that format strings passed "
+ "as part of the automatically-generated messages "
+ "do not get expanded");
+ atf_tc_set_md_var(tc, "use.fs", "true");
+}
+ATF_TC_BODY(msg_embedded_fmt, tc)
+{
+ struct test {
+ void (*head)(atf_tc_t *);
+ void (*body)(const atf_tc_t *);
+ bool fatal;
+ const char *msg;
+ } *t, tests[] = {
+ { H_CHECK_HEAD_NAME(msg), H_CHECK_BODY_NAME(msg), false,
+ "aux_bool\\(\"%d\"\\) not met" },
+ { H_REQUIRE_HEAD_NAME(msg), H_REQUIRE_BODY_NAME(msg), true,
+ "aux_bool\\(\"%d\"\\) not met" },
+ { H_CHECK_STREQ_HEAD_NAME(msg), H_CHECK_STREQ_BODY_NAME(msg), false,
+ "aux_str\\(\"%d\"\\) != \"\" \\(foo != \\)" },
+ { H_REQUIRE_STREQ_HEAD_NAME(msg), H_REQUIRE_STREQ_BODY_NAME(msg), true,
+ "aux_str\\(\"%d\"\\) != \"\" \\(foo != \\)" },
+ { NULL, NULL, false, NULL }
+ };
+
+ for (t = &tests[0]; t->head != NULL; t++) {
+ printf("Checking with an expected '%s' message\n", t->msg);
+
+ init_and_run_h_tc("h_check", t->head, t->body);
+
+ if (t->fatal) {
+ bool matched =
+ grep_file("result", "^failed: .*macros_test.c:[0-9]+: "
+ "%s$", t->msg);
+ ATF_CHECK_MSG(matched, "couldn't find error string in result");
+ } else {
+ bool matched = grep_file("error", "Check failed: .*"
+ "macros_test.c:[0-9]+: %s$", t->msg);
+ ATF_CHECK_MSG(matched, "couldn't find error string in output");
+ }
+ }
+}
+
+/* ---------------------------------------------------------------------
+ * Tests cases for the header file.
+ * --------------------------------------------------------------------- */
+
+HEADER_TC(include, "atf-c/macros.h");
+BUILD_TC(use, "macros_h_test.c",
+ "Tests that the macros provided by the atf-c/macros.h file "
+ "do not cause syntax errors when used",
+ "Build of macros_h_test.c failed; some macros in atf-c/macros.h "
+ "are broken");
+
+/* ---------------------------------------------------------------------
+ * Main.
+ * --------------------------------------------------------------------- */
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, check);
+ ATF_TP_ADD_TC(tp, check_eq);
+ ATF_TP_ADD_TC(tp, check_streq);
+ ATF_TP_ADD_TC(tp, check_errno);
+
+ ATF_TP_ADD_TC(tp, require);
+ ATF_TP_ADD_TC(tp, require_eq);
+ ATF_TP_ADD_TC(tp, require_streq);
+ ATF_TP_ADD_TC(tp, require_errno);
+
+ ATF_TP_ADD_TC(tp, msg_embedded_fmt);
+
+ /* Add the test cases for the header file. */
+ ATF_TP_ADD_TC(tp, include);
+ ATF_TP_ADD_TC(tp, use);
+
+ return atf_no_error();
+}
diff --git a/external/bsd/atf/dist/atf-c/map_test.c b/external/bsd/atf/dist/atf-c/map_test.c
new file mode 100644
index 00000000000..1d404167cca
--- /dev/null
+++ b/external/bsd/atf/dist/atf-c/map_test.c
@@ -0,0 +1,331 @@
+/*
+ * Automated Testing Framework (atf)
+ *
+ * Copyright (c) 2008, 2009, 2010 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include <atf-c.h>
+
+#include "atf-c/map.h"
+
+#include "test_helpers.h"
+
+/* ---------------------------------------------------------------------
+ * Tests for the "atf_map" type.
+ * --------------------------------------------------------------------- */
+
+/*
+ * Constructors and destructors.
+ */
+
+ATF_TC(map_init);
+ATF_TC_HEAD(map_init, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks the atf_map_init function");
+}
+ATF_TC_BODY(map_init, tc)
+{
+ atf_map_t map;
+
+ RE(atf_map_init(&map));
+ ATF_REQUIRE_EQ(atf_map_size(&map), 0);
+ atf_map_fini(&map);
+}
+
+/*
+ * Getters.
+ */
+
+ATF_TC(find);
+ATF_TC_HEAD(find, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks the atf_map_find function");
+}
+ATF_TC_BODY(find, tc)
+{
+ atf_map_t map;
+ char val1[] = "V1";
+ char val2[] = "V2";
+ atf_map_iter_t iter;
+
+ RE(atf_map_init(&map));
+ RE(atf_map_insert(&map, "K1", val1, false));
+ RE(atf_map_insert(&map, "K2", val2, false));
+
+ iter = atf_map_find(&map, "K0");
+ ATF_REQUIRE(atf_equal_map_iter_map_iter(iter, atf_map_end(&map)));
+
+ iter = atf_map_find(&map, "K1");
+ ATF_REQUIRE(!atf_equal_map_iter_map_iter(iter, atf_map_end(&map)));
+ ATF_REQUIRE(strcmp(atf_map_iter_key(iter), "K1") == 0);
+ ATF_REQUIRE(strcmp(atf_map_iter_data(iter), "V1") == 0);
+ strcpy(atf_map_iter_data(iter), "Z1");
+
+ iter = atf_map_find(&map, "K1");
+ ATF_REQUIRE(!atf_equal_map_iter_map_iter(iter, atf_map_end(&map)));
+ ATF_REQUIRE(strcmp(atf_map_iter_key(iter), "K1") == 0);
+ ATF_REQUIRE(strcmp(atf_map_iter_data(iter), "Z1") == 0);
+
+ iter = atf_map_find(&map, "K2");
+ ATF_REQUIRE(!atf_equal_map_iter_map_iter(iter, atf_map_end(&map)));
+ ATF_REQUIRE(strcmp(atf_map_iter_key(iter), "K2") == 0);
+ ATF_REQUIRE(strcmp(atf_map_iter_data(iter), "V2") == 0);
+
+ atf_map_fini(&map);
+}
+
+ATF_TC(find_c);
+ATF_TC_HEAD(find_c, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks the atf_map_find_c function");
+}
+ATF_TC_BODY(find_c, tc)
+{
+ atf_map_t map;
+ char val1[] = "V1";
+ char val2[] = "V2";
+ atf_map_citer_t iter;
+
+ RE(atf_map_init(&map));
+ RE(atf_map_insert(&map, "K1", val1, false));
+ RE(atf_map_insert(&map, "K2", val2, false));
+
+ iter = atf_map_find_c(&map, "K0");
+ ATF_REQUIRE(atf_equal_map_citer_map_citer(iter, atf_map_end_c(&map)));
+
+ iter = atf_map_find_c(&map, "K1");
+ ATF_REQUIRE(!atf_equal_map_citer_map_citer(iter, atf_map_end_c(&map)));
+ ATF_REQUIRE(strcmp(atf_map_citer_key(iter), "K1") == 0);
+ ATF_REQUIRE(strcmp(atf_map_citer_data(iter), "V1") == 0);
+
+ iter = atf_map_find_c(&map, "K2");
+ ATF_REQUIRE(!atf_equal_map_citer_map_citer(iter, atf_map_end_c(&map)));
+ ATF_REQUIRE(strcmp(atf_map_citer_key(iter), "K2") == 0);
+ ATF_REQUIRE(strcmp(atf_map_citer_data(iter), "V2") == 0);
+
+ atf_map_fini(&map);
+}
+
+/*
+ * Modifiers.
+ */
+
+ATF_TC(map_insert);
+ATF_TC_HEAD(map_insert, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks the atf_map_insert function");
+}
+ATF_TC_BODY(map_insert, tc)
+{
+ atf_map_t map;
+ char buf[] = "1st test string";
+ char buf2[] = "2nd test string";
+ const char *ptr;
+ atf_map_citer_t iter;
+
+ RE(atf_map_init(&map));
+
+ printf("Inserting some values\n");
+ ATF_REQUIRE_EQ(atf_map_size(&map), 0);
+ RE(atf_map_insert(&map, "K1", buf, false));
+ ATF_REQUIRE_EQ(atf_map_size(&map), 1);
+ RE(atf_map_insert(&map, "K2", buf, false));
+ ATF_REQUIRE_EQ(atf_map_size(&map), 2);
+ RE(atf_map_insert(&map, "K3", buf, false));
+ ATF_REQUIRE_EQ(atf_map_size(&map), 3);
+
+ printf("Replacing a value\n");
+ iter = atf_map_find_c(&map, "K3");
+ ATF_REQUIRE(!atf_equal_map_citer_map_citer(iter, atf_map_end_c(&map)));
+ ptr = atf_map_citer_data(iter);
+ ATF_REQUIRE_EQ(ptr, buf);
+ RE(atf_map_insert(&map, "K3", buf2, false));
+ ATF_REQUIRE_EQ(atf_map_size(&map), 3);
+ iter = atf_map_find_c(&map, "K3");
+ ATF_REQUIRE(!atf_equal_map_citer_map_citer(iter, atf_map_end_c(&map)));
+ ptr = atf_map_citer_data(iter);
+ ATF_REQUIRE_EQ(ptr, buf2);
+
+ atf_map_fini(&map);
+}
+
+/*
+ * Macros.
+ */
+
+ATF_TC(map_for_each);
+ATF_TC_HEAD(map_for_each, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks the atf_map_for_each macro");
+}
+ATF_TC_BODY(map_for_each, tc)
+{
+ atf_map_t map;
+ atf_map_iter_t iter;
+ size_t count, i, size;
+ char keys[10][5];
+ int nums[10];
+
+ printf("Iterating over empty map\n");
+ RE(atf_map_init(&map));
+ count = 0;
+ atf_map_for_each(iter, &map) {
+ count++;
+ printf("Item count is now %zd\n", count);
+ }
+ ATF_REQUIRE_EQ(count, 0);
+ atf_map_fini(&map);
+
+ for (size = 0; size <= 10; size++) {
+ printf("Iterating over map of %zd elements\n", size);
+ RE(atf_map_init(&map));
+ for (i = 0; i < size; i++) {
+ nums[i] = i + 1;
+ snprintf(keys[i], sizeof(keys[i]), "%d", nums[i]);
+ RE(atf_map_insert(&map, keys[i], &nums[i], false));
+ }
+ count = 0;
+ atf_map_for_each(iter, &map) {
+ printf("Retrieved item: %d\n", *(int *)atf_map_iter_data(iter));
+ count++;
+ }
+ ATF_REQUIRE_EQ(count, size);
+ atf_map_fini(&map);
+ }
+}
+
+ATF_TC(map_for_each_c);
+ATF_TC_HEAD(map_for_each_c, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks the atf_map_for_each_c macro");
+}
+ATF_TC_BODY(map_for_each_c, tc)
+{
+ atf_map_t map;
+ atf_map_citer_t iter;
+ size_t count, i, size;
+ char keys[10][5];
+ int nums[10];
+
+ printf("Iterating over empty map\n");
+ RE(atf_map_init(&map));
+ count = 0;
+ atf_map_for_each_c(iter, &map) {
+ count++;
+ printf("Item count is now %zd\n", count);
+ }
+ ATF_REQUIRE_EQ(count, 0);
+ atf_map_fini(&map);
+
+ for (size = 0; size <= 10; size++) {
+ printf("Iterating over map of %zd elements\n", size);
+ RE(atf_map_init(&map));
+ for (i = 0; i < size; i++) {
+ nums[i] = i + 1;
+ snprintf(keys[i], sizeof(keys[i]), "%d", nums[i]);
+ RE(atf_map_insert(&map, keys[i], &nums[i], false));
+ }
+ count = 0;
+ atf_map_for_each_c(iter, &map) {
+ printf("Retrieved item: %d\n",
+ *(const int *)atf_map_citer_data(iter));
+ count++;
+ }
+ ATF_REQUIRE_EQ(count, size);
+ atf_map_fini(&map);
+ }
+}
+
+/*
+ * Other.
+ */
+
+ATF_TC(stable_keys);
+ATF_TC_HEAD(stable_keys, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks that the keys do not change "
+ "even if their original values do");
+}
+ATF_TC_BODY(stable_keys, tc)
+{
+ atf_map_t map;
+ atf_map_citer_t iter;
+ char key[] = "K1";
+
+ RE(atf_map_init(&map));
+
+ RE(atf_map_insert(&map, key, strdup("test-value"), true));
+ iter = atf_map_find_c(&map, "K1");
+ ATF_REQUIRE(!atf_equal_map_citer_map_citer(iter, atf_map_end_c(&map)));
+ iter = atf_map_find_c(&map, "K2");
+ ATF_REQUIRE(atf_equal_map_citer_map_citer(iter, atf_map_end_c(&map)));
+
+ strcpy(key, "K2");
+ iter = atf_map_find_c(&map, "K1");
+ ATF_REQUIRE(!atf_equal_map_citer_map_citer(iter, atf_map_end_c(&map)));
+ iter = atf_map_find_c(&map, "K2");
+ ATF_REQUIRE(atf_equal_map_citer_map_citer(iter, atf_map_end_c(&map)));
+
+ atf_map_fini(&map);
+}
+
+/* ---------------------------------------------------------------------
+ * Tests cases for the header file.
+ * --------------------------------------------------------------------- */
+
+HEADER_TC(include, "atf-c/map.h");
+
+/* ---------------------------------------------------------------------
+ * Main.
+ * --------------------------------------------------------------------- */
+
+ATF_TP_ADD_TCS(tp)
+{
+ /* Constructors and destructors. */
+ ATF_TP_ADD_TC(tp, map_init);
+
+ /* Getters. */
+ ATF_TP_ADD_TC(tp, find);
+ ATF_TP_ADD_TC(tp, find_c);
+
+ /* Modifiers. */
+ ATF_TP_ADD_TC(tp, map_insert);
+
+ /* Macros. */
+ ATF_TP_ADD_TC(tp, map_for_each);
+ ATF_TP_ADD_TC(tp, map_for_each_c);
+
+ /* Other. */
+ ATF_TP_ADD_TC(tp, stable_keys);
+
+ /* Add the test cases for the header file. */
+ ATF_TP_ADD_TC(tp, include);
+
+ return atf_no_error();
+}
diff --git a/external/bsd/atf/dist/atf-c/pkg_config_test.sh b/external/bsd/atf/dist/atf-c/pkg_config_test.sh
new file mode 100644
index 00000000000..1327578a1de
--- /dev/null
+++ b/external/bsd/atf/dist/atf-c/pkg_config_test.sh
@@ -0,0 +1,151 @@
+#
+# Automated Testing Framework (atf)
+#
+# Copyright (c) 2008, 2010 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
+# CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+# The following tests assume that the atf-c.pc file is installed in a
+# directory that is known by pkg-config. Otherwise they will fail,
+# and you will be required to adjust PKG_CONFIG_PATH accordingly.
+#
+# It would be possible to bypass this requirement by setting the path
+# explicitly during the tests, but then this would not do a real check
+# to ensure that the installation is working.
+
+require_pc()
+{
+ pkg-config ${1} || atf_fail "pkg-config could not locate ${1}.pc;" \
+ "maybe need to set PKG_CONFIG_PATH?"
+}
+
+check_version()
+{
+ atf_check -s eq:0 -o save:stdout -e empty -x \
+ "atf-version | head -n 1 | cut -d ' ' -f 4"
+ ver1=$(cat stdout)
+ echo "Version reported by atf-version: ${ver1}"
+
+ atf_check -s eq:0 -o save:stdout -e empty pkg-config --modversion "${1}"
+ ver2=$(cat stdout)
+ echo "Version reported by pkg-config: ${ver2}"
+
+ atf_check_equal ${ver1} ${ver2}
+}
+
+atf_test_case version
+version_head()
+{
+ atf_set "descr" "Checks that the version in atf-c is correct"
+ atf_set "require.progs" "pkg-config"
+ atf_set "use.fs" "true"
+}
+version_body()
+{
+ require_pc "atf-c"
+
+ check_version "atf-c"
+}
+
+atf_test_case build
+build_head()
+{
+ atf_set "descr" "Checks that a test program can be built against" \
+ "the C library based on the pkg-config information"
+ atf_set "require.progs" "pkg-config"
+ atf_set "use.fs" "true"
+}
+build_body()
+{
+ require_pc "atf-c"
+
+ atf_check -s eq:0 -o save:stdout -e empty pkg-config --variable=cc atf-c
+ cc=$(cat stdout)
+ echo "Compiler is: ${cxx}"
+ atf_require_prog ${cxx}
+
+ cat >tp.c <<EOF
+#include <stdio.h>
+
+#include <atf-c.h>
+
+ATF_TC(tc);
+ATF_TC_HEAD(tc, tc) {
+ atf_tc_set_md_var(tc, "descr", "A test case");
+}
+ATF_TC_BODY(tc, tc) {
+ printf("Running\n");
+}
+
+ATF_TP_ADD_TCS(tp) {
+ ATF_TP_ADD_TC(tp, tc);
+
+ return atf_no_error();
+}
+EOF
+
+ atf_check -s eq:0 -o save:stdout -e empty pkg-config --cflags atf-c
+ cflags=$(cat stdout)
+ echo "CFLAGS are: ${cflags}"
+
+ atf_check -s eq:0 -o save:stdout -e empty \
+ pkg-config --libs-only-L --libs-only-other atf-c
+ ldflags=$(cat stdout)
+ atf_check -s eq:0 -o save:stdout -e empty pkg-config --libs-only-l atf-c
+ libs=$(cat stdout)
+ echo "LDFLAGS are: ${ldflags}"
+ echo "LIBS are: ${libs}"
+
+ atf_check -s eq:0 -o empty -e empty ${cc} ${cflags} -o tp.o -c tp.c
+ atf_check -s eq:0 -o empty -e empty ${cc} ${ldflags} -o tp tp.o ${libs}
+
+ libpath=
+ for f in ${ldflags}; do
+ case ${f} in
+ -L*)
+ dir=$(echo ${f} | sed -e 's,^-L,,')
+ if [ -z "${libpath}" ]; then
+ libpath="${dir}"
+ else
+ libpath="${libpath}:${dir}"
+ fi
+ ;;
+ *)
+ ;;
+ esac
+ done
+
+ atf_check -s eq:0 -o empty -e empty test -x tp
+ atf_check -s eq:0 -o match:'Running' -e empty -x \
+ "LD_LIBRARY_PATH=${libpath} ./tp tc"
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case version
+ atf_add_test_case build
+}
+
+# vim: syntax=sh:expandtab:shiftwidth=4:softtabstop=4
diff --git a/external/bsd/atf/dist/atf-c/process_helpers.c b/external/bsd/atf/dist/atf-c/process_helpers.c
new file mode 100644
index 00000000000..df87d0d579a
--- /dev/null
+++ b/external/bsd/atf/dist/atf-c/process_helpers.c
@@ -0,0 +1,117 @@
+/*
+ * Automated Testing Framework (atf)
+ *
+ * Copyright (c) 2008, 2009 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 <sys/types.h>
+
+#include <assert.h> /* NO_CHECK_STYLE */
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+static
+int
+h_echo(const char *msg)
+{
+ printf("%s\n", msg);
+ return EXIT_SUCCESS;
+}
+
+static
+int
+h_exit_failure(void)
+{
+ return EXIT_FAILURE;
+}
+
+static
+int
+h_exit_signal(void)
+{
+ kill(getpid(), SIGKILL);
+ assert(0); /* NO_CHECK_STYLE */
+ return EXIT_FAILURE;
+}
+
+static
+int
+h_exit_success(void)
+{
+ return EXIT_SUCCESS;
+}
+
+static
+int
+h_stdout_stderr(const char *id)
+{
+ fprintf(stdout, "Line 1 to stdout for %s\n", id);
+ fprintf(stdout, "Line 2 to stdout for %s\n", id);
+ fprintf(stderr, "Line 1 to stderr for %s\n", id);
+ fprintf(stderr, "Line 2 to stderr for %s\n", id);
+
+ return EXIT_SUCCESS;
+}
+
+static
+void
+check_args(const int argc, const char *const argv[], const int required)
+{
+ if (argc < required) {
+ fprintf(stderr, "Usage: %s helper-name [args]\n", argv[0]);
+ exit(EXIT_FAILURE);
+ }
+}
+
+int
+main(int argc, const char *const argv[])
+{
+ int exitcode;
+
+ check_args(argc, argv, 2);
+
+ if (strcmp(argv[1], "echo") == 0) {
+ check_args(argc, argv, 3);
+ exitcode = h_echo(argv[2]);
+ } else if (strcmp(argv[1], "exit-failure") == 0)
+ exitcode = h_exit_failure();
+ else if (strcmp(argv[1], "exit-signal") == 0)
+ exitcode = h_exit_signal();
+ else if (strcmp(argv[1], "exit-success") == 0)
+ exitcode = h_exit_success();
+ else if (strcmp(argv[1], "stdout-stderr") == 0) {
+ check_args(argc, argv, 3);
+ exitcode = h_stdout_stderr(argv[2]);
+ } else {
+ fprintf(stderr, "%s: Unknown helper %s\n", argv[0], argv[1]);
+ exitcode = EXIT_FAILURE;
+ }
+
+ return exitcode;
+}
diff --git a/external/bsd/atf/dist/atf-c/process_test.c b/external/bsd/atf/dist/atf-c/process_test.c
new file mode 100644
index 00000000000..c37bed4ce4e
--- /dev/null
+++ b/external/bsd/atf/dist/atf-c/process_test.c
@@ -0,0 +1,1159 @@
+/*
+ * Automated Testing Framework (atf)
+ *
+ * Copyright (c) 2008, 2009, 2010 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/types.h>
+#include <sys/resource.h>
+#include <sys/time.h>
+#include <sys/wait.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <atf-c.h>
+
+#include "atf-c/defs.h"
+#include "atf-c/process.h"
+#include "atf-c/sanity.h"
+
+#include "test_helpers.h"
+
+atf_error_t atf_process_status_init(atf_process_status_t *, int);
+
+/* ---------------------------------------------------------------------
+ * Auxiliary functions for testing of 'atf_process_fork'.
+ * --------------------------------------------------------------------- */
+
+/*
+ * Testing of atf_process_fork is quite messy. We want to be able to test
+ * all the possible combinations of stdout and stderr behavior to ensure
+ * that the streams are manipulated correctly.
+ *
+ * To do this, the do_fork function is a wrapper for atf_process_fork that
+ * issues stream-specific hooks before fork, while the child is running and
+ * after the child terminates. We then provide test cases that just call
+ * do_fork with different hooks.
+ *
+ * The hooks are described by base_stream, and we then have one *_stream
+ * type for ever possible stream behavior.
+ */
+
+enum out_type { stdout_type, stderr_type };
+
+struct base_stream {
+ void (*init)(void *);
+ void (*process)(void *, atf_process_child_t *);
+ void (*fini)(void *);
+
+ /* m_sb is initialized by subclasses that need it, but all consumers
+ * must use m_sb_ptr, which may or may not point to m_sb. This allows
+ * us to test the interface with a NULL value, which triggers a
+ * default behavior. */
+ atf_process_stream_t m_sb;
+ atf_process_stream_t *m_sb_ptr;
+ enum out_type m_type;
+};
+#define BASE_STREAM(ihook, phook, fhook, type) \
+ { .init = ihook, \
+ .process = phook, \
+ .fini = fhook, \
+ .m_type = type }
+
+static
+void
+check_file(const enum out_type type)
+{
+ switch (type) {
+ case stdout_type:
+ ATF_CHECK(grep_file("stdout", "stdout: msg"));
+ ATF_CHECK(!grep_file("stdout", "stderr: msg"));
+ break;
+ case stderr_type:
+ ATF_CHECK(grep_file("stderr", "stderr: msg"));
+ ATF_CHECK(!grep_file("stderr", "stdout: msg"));
+ break;
+ default:
+ UNREACHABLE;
+ }
+}
+
+struct capture_stream {
+ struct base_stream m_base;
+
+ atf_dynstr_t m_msg;
+};
+#define CAPTURE_STREAM(type) \
+ { .m_base = BASE_STREAM(capture_stream_init, \
+ capture_stream_process, \
+ capture_stream_fini, \
+ type) }
+
+static
+void
+capture_stream_init(void *v)
+{
+ struct capture_stream *s = v;
+
+ s->m_base.m_sb_ptr = &s->m_base.m_sb;
+ RE(atf_process_stream_init_capture(&s->m_base.m_sb));
+ RE(atf_dynstr_init(&s->m_msg));
+}
+
+static
+void
+capture_stream_process(void *v, atf_process_child_t *c)
+{
+ struct capture_stream *s = v;
+
+ bool eof;
+ switch (s->m_base.m_type) {
+ case stdout_type:
+ eof = read_line(atf_process_child_stdout(c), &s->m_msg);
+ break;
+ case stderr_type:
+ eof = read_line(atf_process_child_stderr(c), &s->m_msg);
+ break;
+ default:
+ UNREACHABLE;
+ }
+}
+
+static
+void
+capture_stream_fini(void *v)
+{
+ struct capture_stream *s = v;
+
+ switch (s->m_base.m_type) {
+ case stdout_type:
+ ATF_CHECK(grep_string(&s->m_msg, "stdout: msg"));
+ ATF_CHECK(!grep_string(&s->m_msg, "stderr: msg"));
+ break;
+ case stderr_type:
+ ATF_CHECK(!grep_string(&s->m_msg, "stdout: msg"));
+ ATF_CHECK(grep_string(&s->m_msg, "stderr: msg"));
+ break;
+ default:
+ UNREACHABLE;
+ }
+
+ atf_dynstr_fini(&s->m_msg);
+ atf_process_stream_fini(&s->m_base.m_sb);
+}
+
+struct connect_stream {
+ struct base_stream m_base;
+
+ int m_fd;
+};
+#define CONNECT_STREAM(type) \
+ { .m_base = BASE_STREAM(connect_stream_init, \
+ NULL, \
+ connect_stream_fini, \
+ type) }
+
+static
+void
+connect_stream_init(void *v)
+{
+ struct connect_stream *s = v;
+ int src_fd;
+
+ switch (s->m_base.m_type) {
+ case stdout_type:
+ src_fd = STDOUT_FILENO;
+ s->m_fd = open("stdout", O_WRONLY | O_CREAT | O_TRUNC, 0644);
+ break;
+ case stderr_type:
+ src_fd = STDERR_FILENO;
+ s->m_fd = open("stderr", O_WRONLY | O_CREAT | O_TRUNC, 0644);
+ break;
+ default:
+ UNREACHABLE;
+ src_fd = -1;
+ }
+ ATF_REQUIRE(s->m_fd != -1);
+
+ s->m_base.m_sb_ptr = &s->m_base.m_sb;
+ RE(atf_process_stream_init_connect(&s->m_base.m_sb, src_fd, s->m_fd));
+}
+
+static
+void
+connect_stream_fini(void *v)
+{
+ struct connect_stream *s = v;
+
+ ATF_REQUIRE(close(s->m_fd) != -1);
+
+ atf_process_stream_fini(&s->m_base.m_sb);
+
+ check_file(s->m_base.m_type);
+}
+
+struct inherit_stream {
+ struct base_stream m_base;
+ int m_fd;
+
+ int m_old_fd;
+};
+#define INHERIT_STREAM(type) \
+ { .m_base = BASE_STREAM(inherit_stream_init, \
+ NULL, \
+ inherit_stream_fini, \
+ type) }
+
+static
+void
+inherit_stream_init(void *v)
+{
+ struct inherit_stream *s = v;
+ const char *name;
+
+ s->m_base.m_sb_ptr = &s->m_base.m_sb;
+ RE(atf_process_stream_init_inherit(&s->m_base.m_sb));
+
+ switch (s->m_base.m_type) {
+ case stdout_type:
+ s->m_fd = STDOUT_FILENO;
+ name = "stdout";
+ break;
+ case stderr_type:
+ s->m_fd = STDERR_FILENO;
+ name = "stderr";
+ break;
+ default:
+ UNREACHABLE;
+ name = NULL;
+ }
+
+ s->m_old_fd = dup(s->m_fd);
+ ATF_REQUIRE(s->m_old_fd != -1);
+ ATF_REQUIRE(close(s->m_fd) != -1);
+ ATF_REQUIRE_EQ(open(name, O_WRONLY | O_CREAT | O_TRUNC, 0644),
+ s->m_fd);
+}
+
+static
+void
+inherit_stream_fini(void *v)
+{
+ struct inherit_stream *s = v;
+
+ ATF_REQUIRE(dup2(s->m_old_fd, s->m_fd) != -1);
+ ATF_REQUIRE(close(s->m_old_fd) != -1);
+
+ atf_process_stream_fini(&s->m_base.m_sb);
+
+ check_file(s->m_base.m_type);
+}
+
+#define default_stream inherit_stream
+#define DEFAULT_STREAM(type) \
+ { .m_base = BASE_STREAM(default_stream_init, \
+ NULL, \
+ default_stream_fini, \
+ type) }
+
+static
+void
+default_stream_init(void *v)
+{
+ struct inherit_stream *s = v;
+
+ inherit_stream_init(v);
+ s->m_base.m_sb_ptr = NULL;
+}
+
+static
+void
+default_stream_fini(void *v)
+{
+ inherit_stream_fini(v);
+}
+
+struct redirect_fd_stream {
+ struct base_stream m_base;
+
+ int m_fd;
+};
+#define REDIRECT_FD_STREAM(type) \
+ { .m_base = BASE_STREAM(redirect_fd_stream_init, \
+ NULL, \
+ redirect_fd_stream_fini, \
+ type) }
+
+static
+void
+redirect_fd_stream_init(void *v)
+{
+ struct redirect_fd_stream *s = v;
+
+ switch (s->m_base.m_type) {
+ case stdout_type:
+ s->m_fd = open("stdout", O_WRONLY | O_CREAT | O_TRUNC, 0644);
+ break;
+ case stderr_type:
+ s->m_fd = open("stderr", O_WRONLY | O_CREAT | O_TRUNC, 0644);
+ break;
+ default:
+ UNREACHABLE;
+ }
+ ATF_REQUIRE(s->m_fd != -1);
+
+ s->m_base.m_sb_ptr = &s->m_base.m_sb;
+ RE(atf_process_stream_init_redirect_fd(&s->m_base.m_sb, s->m_fd));
+}
+
+static
+void
+redirect_fd_stream_fini(void *v)
+{
+ struct redirect_fd_stream *s = v;
+
+ ATF_REQUIRE(close(s->m_fd) != -1);
+
+ atf_process_stream_fini(&s->m_base.m_sb);
+
+ check_file(s->m_base.m_type);
+}
+
+struct redirect_path_stream {
+ struct base_stream m_base;
+
+ atf_fs_path_t m_path;
+};
+#define REDIRECT_PATH_STREAM(type) \
+ { .m_base = BASE_STREAM(redirect_path_stream_init, \
+ NULL, \
+ redirect_path_stream_fini, \
+ type) }
+
+static
+void
+redirect_path_stream_init(void *v)
+{
+ struct redirect_path_stream *s = v;
+
+ switch (s->m_base.m_type) {
+ case stdout_type:
+ RE(atf_fs_path_init_fmt(&s->m_path, "stdout"));
+ break;
+ case stderr_type:
+ RE(atf_fs_path_init_fmt(&s->m_path, "stderr"));
+ break;
+ default:
+ UNREACHABLE;
+ }
+
+ s->m_base.m_sb_ptr = &s->m_base.m_sb;
+ RE(atf_process_stream_init_redirect_path(&s->m_base.m_sb, &s->m_path));
+}
+
+static
+void
+redirect_path_stream_fini(void *v)
+{
+ struct redirect_path_stream *s = v;
+
+ atf_process_stream_fini(&s->m_base.m_sb);
+
+ atf_fs_path_fini(&s->m_path);
+
+ check_file(s->m_base.m_type);
+}
+
+static void child_print(void *) ATF_DEFS_ATTRIBUTE_NORETURN;
+
+struct child_print_data {
+ const char *m_msg;
+};
+
+static
+void
+child_print(void *v)
+{
+ struct child_print_data *cpd = v;
+
+ fprintf(stdout, "stdout: %s\n", cpd->m_msg);
+ fprintf(stderr, "stderr: %s\n", cpd->m_msg);
+
+ exit(EXIT_SUCCESS);
+}
+
+static
+void
+do_fork(const struct base_stream *outfs, void *out,
+ const struct base_stream *errfs, void *err)
+{
+ atf_process_child_t child;
+ atf_process_status_t status;
+ struct child_print_data cpd = { "msg" };
+
+ outfs->init(out);
+ errfs->init(err);
+
+ RE(atf_process_fork(&child, child_print, outfs->m_sb_ptr,
+ errfs->m_sb_ptr, &cpd));
+ if (outfs->process != NULL)
+ outfs->process(out, &child);
+ if (errfs->process != NULL)
+ errfs->process(err, &child);
+ RE(atf_process_child_wait(&child, &status));
+
+ outfs->fini(out);
+ errfs->fini(err);
+
+ atf_process_status_fini(&status);
+}
+
+/* ---------------------------------------------------------------------
+ * Test cases for the "stream" type.
+ * --------------------------------------------------------------------- */
+
+ATF_TC(stream_init_capture);
+ATF_TC_HEAD(stream_init_capture, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests the "
+ "atf_process_stream_init_capture function");
+}
+ATF_TC_BODY(stream_init_capture, tc)
+{
+ atf_process_stream_t sb;
+
+ RE(atf_process_stream_init_capture(&sb));
+
+ ATF_CHECK_EQ(atf_process_stream_type(&sb),
+ atf_process_stream_type_capture);
+
+ atf_process_stream_fini(&sb);
+}
+
+ATF_TC(stream_init_connect);
+ATF_TC_HEAD(stream_init_connect, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests the "
+ "atf_process_stream_init_connect function");
+}
+ATF_TC_BODY(stream_init_connect, tc)
+{
+ atf_process_stream_t sb;
+
+ RE(atf_process_stream_init_connect(&sb, 1, 2));
+
+ ATF_CHECK_EQ(atf_process_stream_type(&sb),
+ atf_process_stream_type_connect);
+
+ atf_process_stream_fini(&sb);
+}
+
+ATF_TC(stream_init_inherit);
+ATF_TC_HEAD(stream_init_inherit, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests the "
+ "atf_process_stream_init_inherit function");
+}
+ATF_TC_BODY(stream_init_inherit, tc)
+{
+ atf_process_stream_t sb;
+
+ RE(atf_process_stream_init_inherit(&sb));
+
+ ATF_CHECK_EQ(atf_process_stream_type(&sb),
+ atf_process_stream_type_inherit);
+
+ atf_process_stream_fini(&sb);
+}
+
+ATF_TC(stream_init_redirect_fd);
+ATF_TC_HEAD(stream_init_redirect_fd, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests the "
+ "atf_process_stream_init_redirect_fd function");
+}
+ATF_TC_BODY(stream_init_redirect_fd, tc)
+{
+ atf_process_stream_t sb;
+
+ RE(atf_process_stream_init_redirect_fd(&sb, 1));
+
+ ATF_CHECK_EQ(atf_process_stream_type(&sb),
+ atf_process_stream_type_redirect_fd);
+
+ atf_process_stream_fini(&sb);
+}
+
+ATF_TC(stream_init_redirect_path);
+ATF_TC_HEAD(stream_init_redirect_path, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests the "
+ "atf_process_stream_init_redirect_path function");
+}
+ATF_TC_BODY(stream_init_redirect_path, tc)
+{
+ atf_process_stream_t sb;
+ atf_fs_path_t path;
+
+ RE(atf_fs_path_init_fmt(&path, "foo"));
+ RE(atf_process_stream_init_redirect_path(&sb, &path));
+
+ ATF_CHECK_EQ(atf_process_stream_type(&sb),
+ atf_process_stream_type_redirect_path);
+
+ atf_process_stream_fini(&sb);
+ atf_fs_path_fini(&path);
+}
+
+/* ---------------------------------------------------------------------
+ * Test cases for the "status" type.
+ * --------------------------------------------------------------------- */
+
+static void child_exit_success(void) ATF_DEFS_ATTRIBUTE_NORETURN;
+static void child_exit_failure(void) ATF_DEFS_ATTRIBUTE_NORETURN;
+static void child_sigkill(void) ATF_DEFS_ATTRIBUTE_NORETURN;
+static void child_sigquit(void) ATF_DEFS_ATTRIBUTE_NORETURN;
+static void child_sigterm(void) ATF_DEFS_ATTRIBUTE_NORETURN;
+
+void
+child_exit_success(void)
+{
+ exit(EXIT_SUCCESS);
+}
+
+void
+child_exit_failure(void)
+{
+ exit(EXIT_FAILURE);
+}
+
+void
+child_sigkill(void)
+{
+ kill(getpid(), SIGKILL);
+ abort();
+}
+
+void
+child_sigquit(void)
+{
+ kill(getpid(), SIGQUIT);
+ abort();
+}
+
+void
+child_sigterm(void)
+{
+ kill(getpid(), SIGTERM);
+ abort();
+}
+
+static
+int
+fork_and_wait_child(void (*child_func)(void))
+{
+ pid_t pid;
+ int status;
+
+ pid = fork();
+ ATF_REQUIRE(pid != -1);
+ if (pid == 0) {
+ status = 0; /* Silence compiler warnings */
+ child_func();
+ UNREACHABLE;
+ } else {
+ ATF_REQUIRE(waitpid(pid, &status, 0) != 0);
+ }
+
+ return status;
+}
+
+ATF_TC(status_exited);
+ATF_TC_HEAD(status_exited, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests the status type for processes "
+ "that exit cleanly");
+}
+ATF_TC_BODY(status_exited, tc)
+{
+ {
+ const int rawstatus = fork_and_wait_child(child_exit_success);
+ atf_process_status_t s;
+ RE(atf_process_status_init(&s, rawstatus));
+ ATF_CHECK(atf_process_status_exited(&s));
+ ATF_CHECK_EQ(atf_process_status_exitstatus(&s), EXIT_SUCCESS);
+ ATF_CHECK(!atf_process_status_signaled(&s));
+ atf_process_status_fini(&s);
+ }
+
+ {
+ const int rawstatus = fork_and_wait_child(child_exit_failure);
+ atf_process_status_t s;
+ RE(atf_process_status_init(&s, rawstatus));
+ ATF_CHECK(atf_process_status_exited(&s));
+ ATF_CHECK_EQ(atf_process_status_exitstatus(&s), EXIT_FAILURE);
+ ATF_CHECK(!atf_process_status_signaled(&s));
+ atf_process_status_fini(&s);
+ }
+}
+
+ATF_TC(status_signaled);
+ATF_TC_HEAD(status_signaled, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests the status type for processes "
+ "that end due to a signal");
+}
+ATF_TC_BODY(status_signaled, tc)
+{
+ {
+ const int rawstatus = fork_and_wait_child(child_sigkill);
+ atf_process_status_t s;
+ RE(atf_process_status_init(&s, rawstatus));
+ ATF_CHECK(!atf_process_status_exited(&s));
+ ATF_CHECK(atf_process_status_signaled(&s));
+ ATF_CHECK_EQ(atf_process_status_termsig(&s), SIGKILL);
+ ATF_CHECK(!atf_process_status_coredump(&s));
+ atf_process_status_fini(&s);
+ }
+
+ {
+ const int rawstatus = fork_and_wait_child(child_sigterm);
+ atf_process_status_t s;
+ RE(atf_process_status_init(&s, rawstatus));
+ ATF_CHECK(!atf_process_status_exited(&s));
+ ATF_CHECK(atf_process_status_signaled(&s));
+ ATF_CHECK_EQ(atf_process_status_termsig(&s), SIGTERM);
+ ATF_CHECK(!atf_process_status_coredump(&s));
+ atf_process_status_fini(&s);
+ }
+}
+
+ATF_TC(status_coredump);
+ATF_TC_HEAD(status_coredump, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests the status type for processes "
+ "that crash");
+ atf_tc_set_md_var(tc, "use.fs", "true");
+}
+ATF_TC_BODY(status_coredump, tc)
+{
+ struct rlimit rl;
+ rl.rlim_cur = RLIM_INFINITY;
+ rl.rlim_max = RLIM_INFINITY;
+ if (setrlimit(RLIMIT_CORE, &rl) == -1)
+ atf_tc_skip("Cannot unlimit the core file size; check limits "
+ "manually");
+
+ const int rawstatus = fork_and_wait_child(child_sigquit);
+ atf_process_status_t s;
+ RE(atf_process_status_init(&s, rawstatus));
+ ATF_CHECK(!atf_process_status_exited(&s));
+ ATF_CHECK(atf_process_status_signaled(&s));
+ ATF_CHECK_EQ(atf_process_status_termsig(&s), SIGQUIT);
+ ATF_CHECK(atf_process_status_coredump(&s));
+ atf_process_status_fini(&s);
+}
+
+/* ---------------------------------------------------------------------
+ * Test cases for the "child" type.
+ * --------------------------------------------------------------------- */
+
+static void child_report_pid(void *) ATF_DEFS_ATTRIBUTE_NORETURN;
+
+static
+void
+child_report_pid(void *v)
+{
+ const pid_t pid = getpid();
+ if (write(STDOUT_FILENO, &pid, sizeof(pid)) != sizeof(pid))
+ abort();
+ fprintf(stderr, "Reporting %d to parent\n", (int)getpid());
+ exit(EXIT_SUCCESS);
+}
+
+ATF_TC(child_pid);
+ATF_TC_HEAD(child_pid, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests the correctness of the pid "
+ "stored in the child type");
+}
+ATF_TC_BODY(child_pid, tc)
+{
+ atf_process_stream_t outsb, errsb;
+ atf_process_child_t child;
+ atf_process_status_t status;
+ pid_t pid;
+
+ RE(atf_process_stream_init_capture(&outsb));
+ RE(atf_process_stream_init_inherit(&errsb));
+
+ RE(atf_process_fork(&child, child_report_pid, &outsb, &errsb, NULL));
+ ATF_CHECK_EQ(read(atf_process_child_stdout(&child), &pid, sizeof(pid)),
+ sizeof(pid));
+ printf("Expected PID: %d\n", (int)atf_process_child_pid(&child));
+ printf("Actual PID: %d\n", (int)pid);
+ ATF_CHECK_EQ(atf_process_child_pid(&child), pid);
+
+ RE(atf_process_child_wait(&child, &status));
+ atf_process_status_fini(&status);
+
+ atf_process_stream_fini(&outsb);
+ atf_process_stream_fini(&errsb);
+}
+
+static
+void
+child_loop(void *v)
+{
+ for (;;)
+ sleep(1);
+}
+
+static
+void
+nop_signal(int sig)
+{
+}
+
+static
+void
+child_spawn_loop_and_wait_eintr(void *v)
+{
+ atf_process_child_t child;
+ atf_process_status_t status;
+ struct sigaction sighup, old_sighup;
+
+#define RE_ABORT(expr) \
+ do { \
+ atf_error_t _aux_err = expr; \
+ if (atf_is_error(_aux_err)) { \
+ atf_error_free(_aux_err); \
+ abort(); \
+ } \
+ } while (0)
+
+ {
+ atf_process_stream_t outsb, errsb;
+
+ RE_ABORT(atf_process_stream_init_capture(&outsb));
+ RE_ABORT(atf_process_stream_init_inherit(&errsb));
+ RE_ABORT(atf_process_fork(&child, child_loop, &outsb, &errsb, NULL));
+ atf_process_stream_fini(&outsb);
+ atf_process_stream_fini(&errsb);
+ }
+
+ sighup.sa_handler = nop_signal;
+ sigemptyset(&sighup.sa_mask);
+ sighup.sa_flags = 0;
+ if (sigaction(SIGHUP, &sighup, &old_sighup) == -1)
+ abort();
+
+ printf("waiting\n");
+ fflush(stdout);
+
+ fprintf(stderr, "Child entering wait(2)\n");
+ atf_error_t err = atf_process_child_wait(&child, &status);
+ fprintf(stderr, "Child's wait(2) terminated\n");
+ if (!atf_is_error(err)) {
+ fprintf(stderr, "wait completed successfully (not interrupted)\n");
+ abort();
+ }
+ if (!atf_error_is(err, "libc")) {
+ fprintf(stderr, "wait did not raise libc_error\n");
+ abort();
+ }
+ if (atf_libc_error_code(err) != EINTR) {
+ fprintf(stderr, "libc_error is not EINTR\n");
+ abort();
+ }
+ atf_error_free(err);
+
+ sigaction(SIGHUP, &old_sighup, NULL);
+
+ fprintf(stderr, "Child is killing subchild\n");
+ kill(atf_process_child_pid(&child), SIGTERM);
+
+ RE_ABORT(atf_process_child_wait(&child, &status));
+ atf_process_status_fini(&status);
+
+#undef RE_ABORT
+
+ exit(EXIT_SUCCESS);
+}
+
+ATF_TC(child_wait_eintr);
+ATF_TC_HEAD(child_wait_eintr, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests the interruption of the wait "
+ "method by an external signal, and the return of "
+ "an EINTR error");
+ atf_tc_set_md_var(tc, "timeout", "30");
+}
+ATF_TC_BODY(child_wait_eintr, tc)
+{
+ atf_process_child_t child;
+ atf_process_status_t status;
+
+ {
+ atf_process_stream_t outsb, errsb;
+
+ RE(atf_process_stream_init_capture(&outsb));
+ RE(atf_process_stream_init_inherit(&errsb));
+ RE(atf_process_fork(&child, child_spawn_loop_and_wait_eintr,
+ &outsb, &errsb, NULL));
+ atf_process_stream_fini(&outsb);
+ atf_process_stream_fini(&errsb);
+ }
+
+ {
+ /* Wait until the child process performs the wait call. This is
+ * racy, because the message we get from it is sent *before*
+ * doing the real system call... but I can't figure any other way
+ * to do this. */
+ char buf[16];
+ printf("Waiting for child to issue wait(2)\n");
+ ATF_REQUIRE(read(atf_process_child_stdout(&child), buf,
+ sizeof(buf)) > 0);
+ sleep(1);
+ }
+
+ printf("Interrupting child's wait(2) call\n");
+ kill(atf_process_child_pid(&child), SIGHUP);
+
+ printf("Waiting for child's completion\n");
+ RE(atf_process_child_wait(&child, &status));
+ ATF_REQUIRE(atf_process_status_exited(&status));
+ ATF_REQUIRE_EQ(atf_process_status_exitstatus(&status), EXIT_SUCCESS);
+ atf_process_status_fini(&status);
+}
+
+/* ---------------------------------------------------------------------
+ * Tests cases for the free functions.
+ * --------------------------------------------------------------------- */
+
+static
+void
+do_exec(const atf_tc_t *tc, const char *helper_name, atf_process_status_t *s)
+{
+ atf_fs_path_t process_helpers;
+ const char *argv[3];
+
+ get_process_helpers_path(tc, &process_helpers);
+
+ argv[0] = atf_fs_path_cstring(&process_helpers);
+ argv[1] = helper_name;
+ argv[2] = NULL;
+ printf("Executing %s %s\n", argv[0], argv[1]);
+
+ RE(atf_process_exec_array(s, &process_helpers, argv, NULL, NULL));
+ atf_fs_path_fini(&process_helpers);
+}
+
+static
+void
+check_line(int fd, const char *exp)
+{
+ atf_dynstr_t line;
+ bool eof;
+
+ atf_dynstr_init(&line);
+ eof = read_line(fd, &line);
+ ATF_CHECK(!eof);
+ ATF_CHECK_MSG(atf_equal_dynstr_cstring(&line, exp),
+ "read: '%s', expected: '%s'",
+ atf_dynstr_cstring(&line), exp);
+ atf_dynstr_fini(&line);
+}
+
+ATF_TC(exec_failure);
+ATF_TC_HEAD(exec_failure, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests execing a command");
+}
+ATF_TC_BODY(exec_failure, tc)
+{
+ atf_process_status_t status;
+
+ do_exec(tc, "exit-failure", &status);
+ ATF_CHECK(atf_process_status_exited(&status));
+ ATF_CHECK_EQ(atf_process_status_exitstatus(&status), EXIT_FAILURE);
+ atf_process_status_fini(&status);
+}
+
+ATF_TC(exec_list);
+ATF_TC_HEAD(exec_list, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests execing a command");
+ atf_tc_set_md_var(tc, "use.fs", "true");
+}
+ATF_TC_BODY(exec_list, tc)
+{
+ atf_fs_path_t process_helpers;
+ atf_list_t argv;
+ atf_process_status_t status;
+
+ RE(atf_list_init(&argv));
+
+ get_process_helpers_path(tc, &process_helpers);
+ atf_list_append(&argv, strdup(atf_fs_path_cstring(&process_helpers)), true);
+ atf_list_append(&argv, strdup("echo"), true);
+ atf_list_append(&argv, strdup("test-message"), true);
+ {
+ atf_fs_path_t outpath;
+ atf_process_stream_t outsb;
+
+ RE(atf_fs_path_init_fmt(&outpath, "stdout"));
+ RE(atf_process_stream_init_redirect_path(&outsb, &outpath));
+ RE(atf_process_exec_list(&status, &process_helpers, &argv, &outsb,
+ NULL));
+ atf_process_stream_fini(&outsb);
+ atf_fs_path_fini(&outpath);
+ }
+ atf_list_fini(&argv);
+
+ ATF_CHECK(atf_process_status_exited(&status));
+ ATF_CHECK_EQ(atf_process_status_exitstatus(&status), EXIT_SUCCESS);
+
+ {
+ int fd = open("stdout", O_RDONLY);
+ ATF_CHECK(fd != -1);
+ check_line(fd, "test-message");
+ close(fd);
+ }
+
+ atf_process_status_fini(&status);
+ atf_fs_path_fini(&process_helpers);
+}
+
+ATF_TC(exec_success);
+ATF_TC_HEAD(exec_success, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests execing a command");
+}
+ATF_TC_BODY(exec_success, tc)
+{
+ atf_process_status_t status;
+
+ do_exec(tc, "exit-success", &status);
+ ATF_CHECK(atf_process_status_exited(&status));
+ ATF_CHECK_EQ(atf_process_status_exitstatus(&status), EXIT_SUCCESS);
+ atf_process_status_fini(&status);
+}
+
+static const int exit_v_null = 1;
+static const int exit_v_notnull = 2;
+
+static
+void
+child_cookie(void *v)
+{
+ if (v == NULL)
+ exit(exit_v_null);
+ else
+ exit(exit_v_notnull);
+
+ UNREACHABLE;
+}
+
+ATF_TC(fork_cookie);
+ATF_TC_HEAD(fork_cookie, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests forking a child, with "
+ "a null and non-null data cookie");
+}
+ATF_TC_BODY(fork_cookie, tc)
+{
+ atf_process_stream_t outsb, errsb;
+
+ RE(atf_process_stream_init_inherit(&outsb));
+ RE(atf_process_stream_init_inherit(&errsb));
+
+ {
+ atf_process_child_t child;
+ atf_process_status_t status;
+
+ RE(atf_process_fork(&child, child_cookie, &outsb, &errsb, NULL));
+ RE(atf_process_child_wait(&child, &status));
+
+ ATF_CHECK(atf_process_status_exited(&status));
+ ATF_CHECK_EQ(atf_process_status_exitstatus(&status), exit_v_null);
+
+ atf_process_status_fini(&status);
+ }
+
+ {
+ atf_process_child_t child;
+ atf_process_status_t status;
+ int dummy_int;
+
+ RE(atf_process_fork(&child, child_cookie, &outsb, &errsb, &dummy_int));
+ RE(atf_process_child_wait(&child, &status));
+
+ ATF_CHECK(atf_process_status_exited(&status));
+ ATF_CHECK_EQ(atf_process_status_exitstatus(&status), exit_v_notnull);
+
+ atf_process_status_fini(&status);
+ }
+
+ atf_process_stream_fini(&errsb);
+ atf_process_stream_fini(&outsb);
+}
+
+#define TC_FORK_STREAMS(outlc, outuc, errlc, erruc) \
+ ATF_TC(fork_out_ ## outlc ## _err_ ## errlc); \
+ ATF_TC_HEAD(fork_out_ ## outlc ## _err_ ## errlc, tc) \
+ { \
+ atf_tc_set_md_var(tc, "descr", "Tests forking a child, with " \
+ "stdout " #outlc " and stderr " #errlc); \
+ atf_tc_set_md_var(tc, "use.fs", "true"); \
+ } \
+ ATF_TC_BODY(fork_out_ ## outlc ## _err_ ## errlc, tc) \
+ { \
+ struct outlc ## _stream out = outuc ## _STREAM(stdout_type); \
+ struct errlc ## _stream err = erruc ## _STREAM(stderr_type); \
+ do_fork(&out.m_base, &out, &err.m_base, &err); \
+ }
+
+TC_FORK_STREAMS(capture, CAPTURE, capture, CAPTURE);
+TC_FORK_STREAMS(capture, CAPTURE, connect, CONNECT);
+TC_FORK_STREAMS(capture, CAPTURE, default, DEFAULT);
+TC_FORK_STREAMS(capture, CAPTURE, inherit, INHERIT);
+TC_FORK_STREAMS(capture, CAPTURE, redirect_fd, REDIRECT_FD);
+TC_FORK_STREAMS(capture, CAPTURE, redirect_path, REDIRECT_PATH);
+TC_FORK_STREAMS(connect, CONNECT, capture, CAPTURE);
+TC_FORK_STREAMS(connect, CONNECT, connect, CONNECT);
+TC_FORK_STREAMS(connect, CONNECT, default, DEFAULT);
+TC_FORK_STREAMS(connect, CONNECT, inherit, INHERIT);
+TC_FORK_STREAMS(connect, CONNECT, redirect_fd, REDIRECT_FD);
+TC_FORK_STREAMS(connect, CONNECT, redirect_path, REDIRECT_PATH);
+TC_FORK_STREAMS(default, DEFAULT, capture, CAPTURE);
+TC_FORK_STREAMS(default, DEFAULT, connect, CONNECT);
+TC_FORK_STREAMS(default, DEFAULT, default, DEFAULT);
+TC_FORK_STREAMS(default, DEFAULT, inherit, INHERIT);
+TC_FORK_STREAMS(default, DEFAULT, redirect_fd, REDIRECT_FD);
+TC_FORK_STREAMS(default, DEFAULT, redirect_path, REDIRECT_PATH);
+TC_FORK_STREAMS(inherit, INHERIT, capture, CAPTURE);
+TC_FORK_STREAMS(inherit, INHERIT, connect, CONNECT);
+TC_FORK_STREAMS(inherit, INHERIT, default, DEFAULT);
+TC_FORK_STREAMS(inherit, INHERIT, inherit, INHERIT);
+TC_FORK_STREAMS(inherit, INHERIT, redirect_fd, REDIRECT_FD);
+TC_FORK_STREAMS(inherit, INHERIT, redirect_path, REDIRECT_PATH);
+TC_FORK_STREAMS(redirect_fd, REDIRECT_FD, capture, CAPTURE);
+TC_FORK_STREAMS(redirect_fd, REDIRECT_FD, connect, CONNECT);
+TC_FORK_STREAMS(redirect_fd, REDIRECT_FD, default, DEFAULT);
+TC_FORK_STREAMS(redirect_fd, REDIRECT_FD, inherit, INHERIT);
+TC_FORK_STREAMS(redirect_fd, REDIRECT_FD, redirect_fd, REDIRECT_FD);
+TC_FORK_STREAMS(redirect_fd, REDIRECT_FD, redirect_path, REDIRECT_PATH);
+TC_FORK_STREAMS(redirect_path, REDIRECT_PATH, capture, CAPTURE);
+TC_FORK_STREAMS(redirect_path, REDIRECT_PATH, connect, CONNECT);
+TC_FORK_STREAMS(redirect_path, REDIRECT_PATH, default, DEFAULT);
+TC_FORK_STREAMS(redirect_path, REDIRECT_PATH, inherit, INHERIT);
+TC_FORK_STREAMS(redirect_path, REDIRECT_PATH, redirect_fd, REDIRECT_FD);
+TC_FORK_STREAMS(redirect_path, REDIRECT_PATH, redirect_path, REDIRECT_PATH);
+
+#undef TC_FORK_STREAMS
+
+/* ---------------------------------------------------------------------
+ * Tests cases for the header file.
+ * --------------------------------------------------------------------- */
+
+HEADER_TC(include, "atf-c/process.h");
+
+/* ---------------------------------------------------------------------
+ * Main.
+ * --------------------------------------------------------------------- */
+
+ATF_TP_ADD_TCS(tp)
+{
+ /* Add the tests for the "stream" type. */
+ ATF_TP_ADD_TC(tp, stream_init_capture);
+ ATF_TP_ADD_TC(tp, stream_init_connect);
+ ATF_TP_ADD_TC(tp, stream_init_inherit);
+ ATF_TP_ADD_TC(tp, stream_init_redirect_fd);
+ ATF_TP_ADD_TC(tp, stream_init_redirect_path);
+
+ /* Add the tests for the "status" type. */
+ ATF_TP_ADD_TC(tp, status_exited);
+ ATF_TP_ADD_TC(tp, status_signaled);
+ ATF_TP_ADD_TC(tp, status_coredump);
+
+ /* Add the tests for the "child" type. */
+ ATF_TP_ADD_TC(tp, child_pid);
+ ATF_TP_ADD_TC(tp, child_wait_eintr);
+
+ /* Add the tests for the free functions. */
+ ATF_TP_ADD_TC(tp, exec_failure);
+ ATF_TP_ADD_TC(tp, exec_list);
+ ATF_TP_ADD_TC(tp, exec_success);
+ ATF_TP_ADD_TC(tp, fork_cookie);
+ ATF_TP_ADD_TC(tp, fork_out_capture_err_capture);
+ ATF_TP_ADD_TC(tp, fork_out_capture_err_connect);
+ ATF_TP_ADD_TC(tp, fork_out_capture_err_default);
+ ATF_TP_ADD_TC(tp, fork_out_capture_err_inherit);
+ ATF_TP_ADD_TC(tp, fork_out_capture_err_redirect_fd);
+ ATF_TP_ADD_TC(tp, fork_out_capture_err_redirect_path);
+ ATF_TP_ADD_TC(tp, fork_out_connect_err_capture);
+ ATF_TP_ADD_TC(tp, fork_out_connect_err_connect);
+ ATF_TP_ADD_TC(tp, fork_out_connect_err_default);
+ ATF_TP_ADD_TC(tp, fork_out_connect_err_inherit);
+ ATF_TP_ADD_TC(tp, fork_out_connect_err_redirect_fd);
+ ATF_TP_ADD_TC(tp, fork_out_connect_err_redirect_path);
+ ATF_TP_ADD_TC(tp, fork_out_default_err_capture);
+ ATF_TP_ADD_TC(tp, fork_out_default_err_connect);
+ ATF_TP_ADD_TC(tp, fork_out_default_err_default);
+ ATF_TP_ADD_TC(tp, fork_out_default_err_inherit);
+ ATF_TP_ADD_TC(tp, fork_out_default_err_redirect_fd);
+ ATF_TP_ADD_TC(tp, fork_out_default_err_redirect_path);
+ ATF_TP_ADD_TC(tp, fork_out_inherit_err_capture);
+ ATF_TP_ADD_TC(tp, fork_out_inherit_err_connect);
+ ATF_TP_ADD_TC(tp, fork_out_inherit_err_default);
+ ATF_TP_ADD_TC(tp, fork_out_inherit_err_inherit);
+ ATF_TP_ADD_TC(tp, fork_out_inherit_err_redirect_fd);
+ ATF_TP_ADD_TC(tp, fork_out_inherit_err_redirect_path);
+ ATF_TP_ADD_TC(tp, fork_out_redirect_fd_err_capture);
+ ATF_TP_ADD_TC(tp, fork_out_redirect_fd_err_connect);
+ ATF_TP_ADD_TC(tp, fork_out_redirect_fd_err_default);
+ ATF_TP_ADD_TC(tp, fork_out_redirect_fd_err_inherit);
+ ATF_TP_ADD_TC(tp, fork_out_redirect_fd_err_redirect_fd);
+ ATF_TP_ADD_TC(tp, fork_out_redirect_fd_err_redirect_path);
+ ATF_TP_ADD_TC(tp, fork_out_redirect_path_err_capture);
+ ATF_TP_ADD_TC(tp, fork_out_redirect_path_err_connect);
+ ATF_TP_ADD_TC(tp, fork_out_redirect_path_err_default);
+ ATF_TP_ADD_TC(tp, fork_out_redirect_path_err_inherit);
+ ATF_TP_ADD_TC(tp, fork_out_redirect_path_err_redirect_fd);
+ ATF_TP_ADD_TC(tp, fork_out_redirect_path_err_redirect_path);
+
+ /* Add the test cases for the header file. */
+ ATF_TP_ADD_TC(tp, include);
+
+ return atf_no_error();
+}
diff --git a/external/bsd/atf/dist/atf-c/sanity_test.c b/external/bsd/atf/dist/atf-c/sanity_test.c
new file mode 100644
index 00000000000..34a61f4a7ab
--- /dev/null
+++ b/external/bsd/atf/dist/atf-c/sanity_test.c
@@ -0,0 +1,263 @@
+/*
+ * Automated Testing Framework (atf)
+ *
+ * Copyright (c) 2008, 2009, 2010 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if defined(HAVE_CONFIG_H)
+#include "bconfig.h"
+#endif
+
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include <signal.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <atf-c.h>
+
+#include "atf-c/dynstr.h"
+#include "atf-c/process.h"
+#include "atf-c/sanity.h"
+
+#include "test_helpers.h"
+
+/* ---------------------------------------------------------------------
+ * Auxiliary functions.
+ * --------------------------------------------------------------------- */
+
+enum type { inv, pre, post, unreachable };
+
+static
+bool
+grep(const atf_dynstr_t *line, const char *text)
+{
+ const char *l = atf_dynstr_cstring(line);
+ bool found;
+
+ found = false;
+
+ if (strstr(l, text) != NULL)
+ found = true;
+
+ return found;
+}
+
+struct test_data {
+ enum type m_type;
+ bool m_cond;
+};
+
+static void do_test_child(void *) ATF_DEFS_ATTRIBUTE_NORETURN;
+
+static
+void
+do_test_child(void *v)
+{
+ struct test_data *td = v;
+
+ switch (td->m_type) {
+ case inv:
+ INV(td->m_cond);
+ break;
+
+ case pre:
+ PRE(td->m_cond);
+ break;
+
+ case post:
+ POST(td->m_cond);
+ break;
+
+ case unreachable:
+ if (!td->m_cond)
+ UNREACHABLE;
+ break;
+ }
+
+ exit(EXIT_SUCCESS);
+}
+
+static
+void
+do_test(enum type t, bool cond)
+{
+ atf_process_child_t child;
+ atf_process_status_t status;
+ bool eof;
+ int nlines;
+ atf_dynstr_t lines[3];
+
+ {
+ atf_process_stream_t outsb, errsb;
+ struct test_data td = { t, cond };
+
+ RE(atf_process_stream_init_inherit(&outsb));
+ RE(atf_process_stream_init_capture(&errsb));
+ RE(atf_process_fork(&child, do_test_child, &outsb, &errsb, &td));
+ atf_process_stream_fini(&errsb);
+ atf_process_stream_fini(&outsb);
+ }
+
+ nlines = 0;
+ eof = false;
+ do {
+ RE(atf_dynstr_init(&lines[nlines]));
+ if (!eof)
+ eof = read_line(atf_process_child_stderr(&child), &lines[nlines]);
+ nlines++;
+ } while (nlines < 3);
+ ATF_REQUIRE(nlines == 0 || nlines == 3);
+
+ RE(atf_process_child_wait(&child, &status));
+ if (!cond) {
+ ATF_REQUIRE(atf_process_status_signaled(&status));
+ ATF_REQUIRE(atf_process_status_termsig(&status) == SIGABRT);
+ } else {
+ ATF_REQUIRE(atf_process_status_exited(&status));
+ ATF_REQUIRE(atf_process_status_exitstatus(&status) == EXIT_SUCCESS);
+ }
+ atf_process_status_fini(&status);
+
+ if (!cond) {
+ switch (t) {
+ case inv:
+ ATF_REQUIRE(grep(&lines[0], "Invariant"));
+ break;
+
+ case pre:
+ ATF_REQUIRE(grep(&lines[0], "Precondition"));
+ break;
+
+ case post:
+ ATF_REQUIRE(grep(&lines[0], "Postcondition"));
+ break;
+
+ case unreachable:
+ ATF_REQUIRE(grep(&lines[0], "Invariant"));
+ break;
+ }
+
+ ATF_REQUIRE(grep(&lines[0], __FILE__));
+ ATF_REQUIRE(grep(&lines[2], PACKAGE_BUGREPORT));
+ }
+
+ while (nlines > 0) {
+ nlines--;
+ atf_dynstr_fini(&lines[nlines]);
+ }
+}
+
+static
+void
+require_ndebug(void)
+{
+#if defined(NDEBUG)
+ atf_tc_skip("Sanity checks not available; code built with -DNDEBUG");
+#endif
+}
+
+/* ---------------------------------------------------------------------
+ * Test cases for the free functions.
+ * --------------------------------------------------------------------- */
+
+ATF_TC(inv);
+ATF_TC_HEAD(inv, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests the INV macro");
+}
+ATF_TC_BODY(inv, tc)
+{
+ require_ndebug();
+
+ do_test(inv, false);
+ do_test(inv, true);
+}
+
+ATF_TC(pre);
+ATF_TC_HEAD(pre, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests the PRE macro");
+}
+ATF_TC_BODY(pre, tc)
+{
+ require_ndebug();
+
+ do_test(pre, false);
+ do_test(pre, true);
+}
+
+ATF_TC(post);
+ATF_TC_HEAD(post, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests the POST macro");
+}
+ATF_TC_BODY(post, tc)
+{
+ require_ndebug();
+
+ do_test(post, false);
+ do_test(post, true);
+}
+
+ATF_TC(unreachable);
+ATF_TC_HEAD(unreachable, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests the UNREACHABLE macro");
+}
+ATF_TC_BODY(unreachable, tc)
+{
+ require_ndebug();
+
+ do_test(unreachable, false);
+ do_test(unreachable, true);
+}
+
+/* ---------------------------------------------------------------------
+ * Tests cases for the header file.
+ * --------------------------------------------------------------------- */
+
+HEADER_TC(include, "atf-c/sanity.h");
+
+/* ---------------------------------------------------------------------
+ * Main.
+ * --------------------------------------------------------------------- */
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, inv);
+ ATF_TP_ADD_TC(tp, pre);
+ ATF_TP_ADD_TC(tp, post);
+ ATF_TP_ADD_TC(tp, unreachable);
+
+ /* Add the test cases for the header file. */
+ ATF_TP_ADD_TC(tp, include);
+
+ return atf_no_error();
+}
diff --git a/external/bsd/atf/dist/atf-c/tc.h b/external/bsd/atf/dist/atf-c/tc.h
index d13866556b2..0c9557fb9ae 100644
--- a/external/bsd/atf/dist/atf-c/tc.h
+++ b/external/bsd/atf/dist/atf-c/tc.h
@@ -108,10 +108,20 @@ void atf_tc_fail_nonfatal(const char *, ...);
void atf_tc_pass(void) ATF_DEFS_ATTRIBUTE_NORETURN;
void atf_tc_require_prog(const char *);
void atf_tc_skip(const char *, ...) ATF_DEFS_ATTRIBUTE_NORETURN;
+void atf_tc_expect_pass(void);
+void atf_tc_expect_fail(const char *, ...);
+void atf_tc_expect_exit(const int, const char *, ...);
+void atf_tc_expect_signal(const int, const char *, ...);
+void atf_tc_expect_death(const char *, ...);
+void atf_tc_expect_timeout(const char *, ...);
/* To be run from test case bodies only; internal to macros.h. */
-void atf_tc_fail_check(const char *, int, const char *, ...);
-void atf_tc_fail_requirement(const char *, int, const char *, ...)
+void atf_tc_fail_check(const char *, const size_t, const char *, ...);
+void atf_tc_fail_requirement(const char *, const size_t, const char *, ...)
ATF_DEFS_ATTRIBUTE_NORETURN;
+void atf_tc_check_errno(const char *, const size_t, const int,
+ const char *, const bool);
+void atf_tc_require_errno(const char *, const size_t, const int,
+ const char *, const bool);
#endif /* ATF_C_TC_H */
diff --git a/external/bsd/atf/dist/atf-c/tc_test.c b/external/bsd/atf/dist/atf-c/tc_test.c
new file mode 100644
index 00000000000..f32e6761b43
--- /dev/null
+++ b/external/bsd/atf/dist/atf-c/tc_test.c
@@ -0,0 +1,199 @@
+/*
+ * Automated Testing Framework (atf)
+ *
+ * Copyright (c) 2008, 2009 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 <stdbool.h>
+#include <string.h>
+
+#include <atf-c.h>
+
+#include "test_helpers.h"
+
+/* ---------------------------------------------------------------------
+ * Auxiliary test cases.
+ * --------------------------------------------------------------------- */
+
+ATF_TC_HEAD(empty, tc)
+{
+}
+
+ATF_TC_HEAD(test_var, tc)
+{
+ atf_tc_set_md_var(tc, "test-var", "Test text");
+}
+
+ATF_TC_BODY(empty, tc)
+{
+}
+
+/* ---------------------------------------------------------------------
+ * Test cases for the "atf_tc_t" type.
+ * --------------------------------------------------------------------- */
+
+ATF_TC(init);
+ATF_TC_HEAD(init, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests the atf_tc_init function");
+}
+ATF_TC_BODY(init, tcin)
+{
+ atf_tc_t tc;
+
+ RE(atf_tc_init(&tc, "test1", ATF_TC_HEAD_NAME(empty),
+ ATF_TC_BODY_NAME(empty), NULL, NULL));
+ ATF_REQUIRE(strcmp(atf_tc_get_ident(&tc), "test1") == 0);
+ ATF_REQUIRE(!atf_tc_has_md_var(&tc, "test-var"));
+ atf_tc_fini(&tc);
+
+ RE(atf_tc_init(&tc, "test2", ATF_TC_HEAD_NAME(test_var),
+ ATF_TC_BODY_NAME(empty), NULL, NULL));
+ ATF_REQUIRE(strcmp(atf_tc_get_ident(&tc), "test2") == 0);
+ ATF_REQUIRE(atf_tc_has_md_var(&tc, "test-var"));
+ atf_tc_fini(&tc);
+}
+
+ATF_TC(init_pack);
+ATF_TC_HEAD(init_pack, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests the atf_tc_init_pack function");
+}
+ATF_TC_BODY(init_pack, tcin)
+{
+ atf_tc_t tc;
+ atf_tc_pack_t tcp1 = {
+ .m_ident = "test1",
+ .m_head = ATF_TC_HEAD_NAME(empty),
+ .m_body = ATF_TC_BODY_NAME(empty),
+ .m_cleanup = NULL,
+ };
+ atf_tc_pack_t tcp2 = {
+ .m_ident = "test2",
+ .m_head = ATF_TC_HEAD_NAME(test_var),
+ .m_body = ATF_TC_BODY_NAME(empty),
+ .m_cleanup = NULL,
+ };
+
+ RE(atf_tc_init_pack(&tc, &tcp1, NULL));
+ ATF_REQUIRE(strcmp(atf_tc_get_ident(&tc), "test1") == 0);
+ ATF_REQUIRE(!atf_tc_has_md_var(&tc, "test-var"));
+ atf_tc_fini(&tc);
+
+ RE(atf_tc_init_pack(&tc, &tcp2, NULL));
+ ATF_REQUIRE(strcmp(atf_tc_get_ident(&tc), "test2") == 0);
+ ATF_REQUIRE(atf_tc_has_md_var(&tc, "test-var"));
+ atf_tc_fini(&tc);
+}
+
+ATF_TC(vars);
+ATF_TC_HEAD(vars, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests the atf_tc_get_md_var, "
+ "atf_tc_has_md_var and atf_tc_set_md_var functions");
+}
+ATF_TC_BODY(vars, tcin)
+{
+ atf_tc_t tc;
+
+ RE(atf_tc_init(&tc, "test1", ATF_TC_HEAD_NAME(empty),
+ ATF_TC_BODY_NAME(empty), NULL, NULL));
+ ATF_REQUIRE(!atf_tc_has_md_var(&tc, "test-var"));
+ RE(atf_tc_set_md_var(&tc, "test-var", "Test value"));
+ ATF_REQUIRE(atf_tc_has_md_var(&tc, "test-var"));
+ ATF_REQUIRE(strcmp(atf_tc_get_md_var(&tc, "test-var"), "Test value") == 0);
+ atf_tc_fini(&tc);
+}
+
+ATF_TC(config);
+ATF_TC_HEAD(config, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests the atf_tc_get_config_var, "
+ "atf_tc_get_config_var_wd and atf_tc_has_config_var "
+ "functions");
+}
+ATF_TC_BODY(config, tcin)
+{
+ atf_tc_t tc;
+ atf_map_t config;
+
+ RE(atf_map_init(&config));
+ RE(atf_map_insert(&config, "test-var", strdup("test-value"), true));
+
+ RE(atf_tc_init(&tc, "test1", ATF_TC_HEAD_NAME(empty),
+ ATF_TC_BODY_NAME(empty), NULL, NULL));
+ ATF_REQUIRE(!atf_tc_has_config_var(&tc, "test-var"));
+ ATF_REQUIRE(!atf_tc_has_md_var(&tc, "test-var"));
+ atf_tc_fini(&tc);
+
+ RE(atf_tc_init(&tc, "test1", ATF_TC_HEAD_NAME(empty),
+ ATF_TC_BODY_NAME(empty), NULL, &config));
+ ATF_REQUIRE(atf_tc_has_config_var(&tc, "test-var"));
+ ATF_REQUIRE(strcmp(atf_tc_get_config_var(&tc, "test-var"),
+ "test-value") == 0);
+ ATF_REQUIRE(!atf_tc_has_md_var(&tc, "test-var"));
+ ATF_REQUIRE(!atf_tc_has_config_var(&tc, "test-var2"));
+ ATF_REQUIRE(strcmp(atf_tc_get_config_var_wd(&tc, "test-var2", "def-value"),
+ "def-value") == 0);
+ atf_tc_fini(&tc);
+
+ atf_map_fini(&config);
+}
+
+/* ---------------------------------------------------------------------
+ * Test cases for the free functions.
+ * --------------------------------------------------------------------- */
+
+/* TODO: Add test cases for atf_tc_run. This is going to be very tough,
+ * but good tests here could allow us to avoid much of the indirect
+ * testing done later on. */
+
+/* ---------------------------------------------------------------------
+ * Tests cases for the header file.
+ * --------------------------------------------------------------------- */
+
+HEADER_TC(include, "atf-c/tc.h");
+
+/* ---------------------------------------------------------------------
+ * Main.
+ * --------------------------------------------------------------------- */
+
+ATF_TP_ADD_TCS(tp)
+{
+ /* Add the test cases for the "atf_tcr_t" type. */
+ ATF_TP_ADD_TC(tp, init);
+ ATF_TP_ADD_TC(tp, init_pack);
+ ATF_TP_ADD_TC(tp, vars);
+ ATF_TP_ADD_TC(tp, config);
+
+ /* Add the test cases for the free functions. */
+ /* TODO */
+
+ /* Add the test cases for the header file. */
+ ATF_TP_ADD_TC(tp, include);
+
+ return atf_no_error();
+}
diff --git a/external/bsd/atf/dist/atf-c/test_helpers.c b/external/bsd/atf/dist/atf-c/test_helpers.c
new file mode 100644
index 00000000000..8f7cd38ffce
--- /dev/null
+++ b/external/bsd/atf/dist/atf-c/test_helpers.c
@@ -0,0 +1,214 @@
+/*
+ * Automated Testing Framework (atf)
+ *
+ * Copyright (c) 2008, 2009, 2010 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <regex.h>
+#include <unistd.h>
+
+#include "atf-c/build.h"
+#include "atf-c/check.h"
+#include "atf-c/config.h"
+#include "atf-c/dynstr.h"
+#include "atf-c/error.h"
+#include "atf-c/fs.h"
+#include "atf-c/macros.h"
+
+#include "test_helpers.h"
+
+static
+void
+build_check_c_o_aux(const char *path, const char *failmsg)
+{
+ bool success;
+ atf_dynstr_t iflag;
+ const char *optargs[2];
+
+ RE(atf_dynstr_init_fmt(&iflag, "-I%s", atf_config_get("atf_includedir")));
+
+ optargs[0] = atf_dynstr_cstring(&iflag);
+ optargs[1] = NULL;
+
+ RE(atf_check_build_c_o(path, "test.o", optargs, &success));
+
+ atf_dynstr_fini(&iflag);
+
+ if (!success)
+ atf_tc_fail(failmsg);
+}
+
+void
+build_check_c_o(const atf_tc_t *tc, const char *sfile, const char *failmsg)
+{
+ atf_fs_path_t path;
+
+ RE(atf_fs_path_init_fmt(&path, "%s/%s",
+ atf_tc_get_config_var(tc, "srcdir"), sfile));
+ build_check_c_o_aux(atf_fs_path_cstring(&path), failmsg);
+ atf_fs_path_fini(&path);
+}
+
+void
+header_check(const atf_tc_t *tc, const char *hdrname)
+{
+ FILE *srcfile;
+ char failmsg[128];
+
+ srcfile = fopen("test.c", "w");
+ ATF_REQUIRE(srcfile != NULL);
+ fprintf(srcfile, "#include <%s>\n", hdrname);
+ fclose(srcfile);
+
+ snprintf(failmsg, sizeof(failmsg),
+ "Header check failed; %s is not self-contained", hdrname);
+
+ build_check_c_o_aux("test.c", failmsg);
+}
+
+void
+get_process_helpers_path(const atf_tc_t *tc, atf_fs_path_t *path)
+{
+ RE(atf_fs_path_init_fmt(path, "%s/process_helpers",
+ atf_tc_get_config_var(tc, "srcdir")));
+}
+
+bool
+grep_string(const atf_dynstr_t *str, const char *regex)
+{
+ int res;
+ regex_t preg;
+
+ printf("Looking for '%s' in '%s'\n", regex, atf_dynstr_cstring(str));
+ ATF_REQUIRE(regcomp(&preg, regex, REG_EXTENDED) == 0);
+
+ res = regexec(&preg, atf_dynstr_cstring(str), 0, NULL, 0);
+ ATF_REQUIRE(res == 0 || res == REG_NOMATCH);
+
+ regfree(&preg);
+
+ return res == 0;
+}
+
+bool
+grep_file(const char *file, const char *regex, ...)
+{
+ bool done, found;
+ int fd;
+ va_list ap;
+ atf_dynstr_t formatted;
+
+ va_start(ap, regex);
+ RE(atf_dynstr_init_ap(&formatted, regex, ap));
+ va_end(ap);
+
+ done = false;
+ found = false;
+ ATF_REQUIRE((fd = open(file, O_RDONLY)) != -1);
+ do {
+ atf_dynstr_t line;
+
+ RE(atf_dynstr_init(&line));
+
+ done = read_line(fd, &line);
+ if (!done)
+ found = grep_string(&line, atf_dynstr_cstring(&formatted));
+
+ atf_dynstr_fini(&line);
+ } while (!found && !done);
+ close(fd);
+
+ atf_dynstr_fini(&formatted);
+
+ return found;
+}
+
+bool
+read_line(int fd, atf_dynstr_t *dest)
+{
+ char ch;
+ ssize_t cnt;
+
+ while ((cnt = read(fd, &ch, sizeof(ch))) == sizeof(ch) &&
+ ch != '\n') {
+ const atf_error_t err = atf_dynstr_append_fmt(dest, "%c", ch);
+ ATF_REQUIRE(!atf_is_error(err));
+ }
+ ATF_REQUIRE(cnt != -1);
+
+ return cnt == 0;
+}
+
+struct run_h_tc_data {
+ atf_tc_t *m_tc;
+ const char *m_resname;
+};
+
+static
+void
+run_h_tc_child(void *v)
+{
+ struct run_h_tc_data *data = (struct run_h_tc_data *)v;
+ atf_fs_path_t respath;
+
+ RE(atf_fs_path_init_fmt(&respath, data->m_resname));
+ RE(atf_tc_run(data->m_tc, &respath));
+ atf_fs_path_fini(&respath);
+}
+
+/* TODO: Investigate if it's worth to add this functionality as part of
+ * the public API. I.e. a function to easily run a test case body in a
+ * subprocess. */
+void
+run_h_tc(atf_tc_t *tc, const char *outname, const char *errname,
+ const char *resname)
+{
+ atf_fs_path_t outpath, errpath;
+ atf_process_stream_t outb, errb;
+ atf_process_child_t child;
+ atf_process_status_t status;
+
+ RE(atf_fs_path_init_fmt(&outpath, outname));
+ RE(atf_fs_path_init_fmt(&errpath, errname));
+
+ struct run_h_tc_data data = { tc, resname };
+
+ RE(atf_process_stream_init_redirect_path(&outb, &outpath));
+ RE(atf_process_stream_init_redirect_path(&errb, &errpath));
+ RE(atf_process_fork(&child, run_h_tc_child, &outb, &errb, &data));
+ atf_process_stream_fini(&errb);
+ atf_process_stream_fini(&outb);
+
+ RE(atf_process_child_wait(&child, &status));
+ ATF_CHECK(atf_process_status_exited(&status));
+ atf_process_status_fini(&status);
+
+ atf_fs_path_fini(&errpath);
+ atf_fs_path_fini(&outpath);
+}
diff --git a/external/bsd/atf/dist/atf-c/test_helpers.h b/external/bsd/atf/dist/atf-c/test_helpers.h
new file mode 100644
index 00000000000..08edf922627
--- /dev/null
+++ b/external/bsd/atf/dist/atf-c/test_helpers.h
@@ -0,0 +1,77 @@
+/*
+ * Automated Testing Framework (atf)
+ *
+ * Copyright (c) 2008, 2009, 2010 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if defined(TESTS_ATF_ATF_C_TEST_HELPERS_H)
+# error "Cannot include test_helpers.h more than once."
+#else
+# define TESTS_ATF_ATF_C_TEST_HELPERS_H
+#endif
+
+#include <stdbool.h>
+
+#include "atf-c/error_fwd.h"
+
+struct atf_dynstr;
+struct atf_fs_path;
+
+#define CE(stm) ATF_CHECK(!atf_is_error(stm))
+#define RE(stm) ATF_REQUIRE(!atf_is_error(stm))
+
+#define HEADER_TC(name, hdrname) \
+ ATF_TC(name); \
+ ATF_TC_HEAD(name, tc) \
+ { \
+ atf_tc_set_md_var(tc, "descr", "Tests that the " hdrname " file can " \
+ "be included on its own, without any prerequisites"); \
+ atf_tc_set_md_var(tc, "use.fs", "true"); \
+ } \
+ ATF_TC_BODY(name, tc) \
+ { \
+ header_check(tc, hdrname); \
+ }
+
+#define BUILD_TC(name, sfile, descr, failmsg) \
+ ATF_TC(name); \
+ ATF_TC_HEAD(name, tc) \
+ { \
+ atf_tc_set_md_var(tc, "descr", descr); \
+ atf_tc_set_md_var(tc, "use.fs", "true"); \
+ } \
+ ATF_TC_BODY(name, tc) \
+ { \
+ build_check_c_o(tc, sfile, failmsg); \
+ }
+
+void build_check_c_o(const atf_tc_t *, const char *, const char *);
+void header_check(const atf_tc_t *, const char *);
+void get_process_helpers_path(const atf_tc_t *, struct atf_fs_path *);
+bool grep_string(const struct atf_dynstr *, const char *);
+bool grep_file(const char *, const char *, ...);
+bool read_line(int, struct atf_dynstr *);
+void run_h_tc(atf_tc_t *, const char *, const char *, const char *);
diff --git a/external/bsd/atf/dist/atf-c/test_helpers_test.c b/external/bsd/atf/dist/atf-c/test_helpers_test.c
new file mode 100644
index 00000000000..86095cab795
--- /dev/null
+++ b/external/bsd/atf/dist/atf-c/test_helpers_test.c
@@ -0,0 +1,188 @@
+/*
+ * Automated Testing Framework (atf)
+ *
+ * Copyright (c) 2009, 2010 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include <atf-c.h>
+
+#include "atf-c/dynstr.h"
+
+#include "test_helpers.h"
+
+/* ---------------------------------------------------------------------
+ * Test cases for the free functions.
+ * --------------------------------------------------------------------- */
+
+/* TODO: Add checks for build_check_c_o and the macros defined in the
+ * header file. */
+
+ATF_TC(grep_string);
+ATF_TC_HEAD(grep_string, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests the grep_string helper "
+ "function");
+}
+ATF_TC_BODY(grep_string, tc)
+{
+ atf_dynstr_t str;
+
+ atf_dynstr_init_fmt(&str, "a string - aaaabbbb");
+ ATF_CHECK(grep_string(&str, "a string"));
+ ATF_CHECK(grep_string(&str, "^a string"));
+ ATF_CHECK(grep_string(&str, "aaaabbbb$"));
+ ATF_CHECK(grep_string(&str, "aa.*bb"));
+ ATF_CHECK(!grep_string(&str, "foo"));
+ ATF_CHECK(!grep_string(&str, "bar"));
+ ATF_CHECK(!grep_string(&str, "aaaaa"));
+
+ atf_dynstr_fini(&str);
+}
+
+
+ATF_TC(grep_file);
+ATF_TC_HEAD(grep_file, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests the grep_file helper function");
+ atf_tc_set_md_var(tc, "use.fs", "true");
+}
+ATF_TC_BODY(grep_file, tc)
+{
+ FILE *f;
+
+ f = fopen("test.txt", "w");
+ ATF_CHECK(f != NULL);
+ fprintf(f, "line1\n");
+ fprintf(f, "the second line\n");
+ fprintf(f, "aaaabbbb\n");
+ fclose(f);
+
+ ATF_CHECK(grep_file("test.txt", "line1"));
+ ATF_CHECK(grep_file("test.txt", "line%d", 1));
+ ATF_CHECK(grep_file("test.txt", "second line"));
+ ATF_CHECK(grep_file("test.txt", "aa.*bb"));
+ ATF_CHECK(!grep_file("test.txt", "foo"));
+ ATF_CHECK(!grep_file("test.txt", "bar"));
+ ATF_CHECK(!grep_file("test.txt", "aaaaa"));
+}
+
+ATF_TC(read_line);
+ATF_TC_HEAD(read_line, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests the read_line function");
+ atf_tc_set_md_var(tc, "use.fs", "true");
+}
+ATF_TC_BODY(read_line, tc)
+{
+ const char *l1 = "First line with % formatting % characters %";
+ const char *l2 = "Second line; much longer than the first one";
+ const char *l3 = "Last line, without terminator";
+
+ {
+ FILE *f;
+
+ f = fopen("test", "w");
+ ATF_REQUIRE(f != NULL);
+ fclose(f);
+ }
+
+ {
+ int fd;
+ atf_dynstr_t dest;
+ bool eof;
+
+ fd = open("test", O_RDONLY);
+ ATF_REQUIRE(fd != -1);
+
+ RE(atf_dynstr_init(&dest));
+ eof = read_line(fd, &dest);
+ ATF_REQUIRE(eof);
+ atf_dynstr_fini(&dest);
+ }
+
+ {
+ FILE *f;
+
+ f = fopen("test", "w");
+ ATF_REQUIRE(f != NULL);
+
+ fprintf(f, "%s\n", l1);
+ fprintf(f, "%s\n", l2);
+ fprintf(f, "%s", l3);
+
+ fclose(f);
+ }
+
+ {
+ int fd;
+ atf_dynstr_t dest;
+ bool eof;
+
+ fd = open("test", O_RDONLY);
+ ATF_REQUIRE(fd != -1);
+
+ RE(atf_dynstr_init(&dest));
+ eof = read_line(fd, &dest);
+ ATF_REQUIRE(!eof);
+ printf("1st line: >%s<\n", atf_dynstr_cstring(&dest));
+ ATF_REQUIRE(atf_equal_dynstr_cstring(&dest, l1));
+ atf_dynstr_fini(&dest);
+
+ RE(atf_dynstr_init(&dest));
+ eof = read_line(fd, &dest);
+ ATF_REQUIRE(!eof);
+ printf("2nd line: >%s<\n", atf_dynstr_cstring(&dest));
+ ATF_REQUIRE(atf_equal_dynstr_cstring(&dest, l2));
+ atf_dynstr_fini(&dest);
+
+ RE(atf_dynstr_init(&dest));
+ eof = read_line(fd, &dest);
+ ATF_REQUIRE(eof);
+ printf("3rd line: >%s<\n", atf_dynstr_cstring(&dest));
+ ATF_REQUIRE(atf_equal_dynstr_cstring(&dest, l3));
+ atf_dynstr_fini(&dest);
+
+ close(fd);
+ }
+}
+
+/* ---------------------------------------------------------------------
+ * Main.
+ * --------------------------------------------------------------------- */
+
+ATF_TP_ADD_TCS(tp)
+{
+ /* Add the tests for the free functions. */
+ ATF_TP_ADD_TC(tp, grep_string);
+ ATF_TP_ADD_TC(tp, grep_file);
+ ATF_TP_ADD_TC(tp, read_line);
+
+ return atf_no_error();
+}
diff --git a/external/bsd/atf/dist/atf-c/text_test.c b/external/bsd/atf/dist/atf-c/text_test.c
new file mode 100644
index 00000000000..5b25ef41d0f
--- /dev/null
+++ b/external/bsd/atf/dist/atf-c/text_test.c
@@ -0,0 +1,434 @@
+/*
+ * Automated Testing Framework (atf)
+ *
+ * Copyright (c) 2008, 2009, 2010 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <atf-c.h>
+
+#include "atf-c/sanity.h"
+#include "atf-c/text.h"
+
+#include "test_helpers.h"
+
+/* ---------------------------------------------------------------------
+ * Auxiliary functions.
+ * --------------------------------------------------------------------- */
+
+#define REQUIRE_ERROR(exp) \
+ do { \
+ atf_error_t err = exp; \
+ ATF_REQUIRE(atf_is_error(err)); \
+ atf_error_free(err); \
+ } while (0)
+
+static
+size_t
+array_size(const char *words[])
+{
+ size_t count;
+ const char **word;
+
+ count = 0;
+ for (word = words; *word != NULL; word++)
+ count++;
+
+ return count;
+}
+
+static
+void
+check_split(const char *str, const char *delim, const char *words[])
+{
+ atf_list_t list;
+ const char **word;
+ size_t i;
+
+ printf("Splitting '%s' with delimiter '%s'\n", str, delim);
+ CE(atf_text_split(str, delim, &list));
+
+ printf("Expecting %zd words\n", array_size(words));
+ ATF_CHECK_EQ(atf_list_size(&list), array_size(words));
+
+ for (word = words, i = 0; *word != NULL; word++, i++) {
+ printf("Word at position %zd should be '%s'\n", i, words[i]);
+ ATF_CHECK_STREQ((const char *)atf_list_index_c(&list, i), words[i]);
+ }
+
+ atf_list_fini(&list);
+}
+
+static
+atf_error_t
+word_acum(const char *word, void *data)
+{
+ char *acum = data;
+
+ strcat(acum, word);
+
+ return atf_no_error();
+}
+
+static
+atf_error_t
+word_count(const char *word, void *data)
+{
+ size_t *counter = data;
+
+ (*counter)++;
+
+ return atf_no_error();
+}
+
+struct fail_at {
+ int failpos;
+ int curpos;
+};
+
+static
+atf_error_t
+word_fail_at(const char *word, void *data)
+{
+ struct fail_at *fa = data;
+ atf_error_t err;
+
+ if (fa->failpos == fa->curpos)
+ err = atf_no_memory_error(); /* Just a random error. */
+ else {
+ fa->curpos++;
+ err = atf_no_error();
+ }
+
+ return err;
+}
+
+/* ---------------------------------------------------------------------
+ * Test cases for the free functions.
+ * --------------------------------------------------------------------- */
+
+ATF_TC(for_each_word);
+ATF_TC_HEAD(for_each_word, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks the atf_text_for_each_word"
+ "function");
+}
+ATF_TC_BODY(for_each_word, tc)
+{
+ size_t cnt;
+ char acum[1024];
+
+ cnt = 0;
+ strcpy(acum, "");
+ RE(atf_text_for_each_word("1 2 3", " ", word_count, &cnt));
+ RE(atf_text_for_each_word("1 2 3", " ", word_acum, acum));
+ ATF_REQUIRE(cnt == 3);
+ ATF_REQUIRE(strcmp(acum, "123") == 0);
+
+ cnt = 0;
+ strcpy(acum, "");
+ RE(atf_text_for_each_word("1 2 3", ".", word_count, &cnt));
+ RE(atf_text_for_each_word("1 2 3", ".", word_acum, acum));
+ ATF_REQUIRE(cnt == 1);
+ ATF_REQUIRE(strcmp(acum, "1 2 3") == 0);
+
+ cnt = 0;
+ strcpy(acum, "");
+ RE(atf_text_for_each_word("1 2 3 4 5", " ", word_count, &cnt));
+ RE(atf_text_for_each_word("1 2 3 4 5", " ", word_acum, acum));
+ ATF_REQUIRE(cnt == 5);
+ ATF_REQUIRE(strcmp(acum, "12345") == 0);
+
+ cnt = 0;
+ strcpy(acum, "");
+ RE(atf_text_for_each_word("1 2.3.4 5", " .", word_count, &cnt));
+ RE(atf_text_for_each_word("1 2.3.4 5", " .", word_acum, acum));
+ ATF_REQUIRE(cnt == 5);
+ ATF_REQUIRE(strcmp(acum, "12345") == 0);
+
+ {
+ struct fail_at fa;
+ fa.failpos = 3;
+ fa.curpos = 0;
+ atf_error_t err = atf_text_for_each_word("a b c d e", " ",
+ word_fail_at, &fa);
+ ATF_REQUIRE(atf_is_error(err));
+ ATF_REQUIRE(atf_error_is(err, "no_memory"));
+ ATF_REQUIRE(fa.curpos == 3);
+ atf_error_free(err);
+ }
+}
+
+ATF_TC(format);
+ATF_TC_HEAD(format, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks the construction of free-form "
+ "strings using a variable parameters list");
+}
+ATF_TC_BODY(format, tc)
+{
+ char *str;
+ atf_error_t err;
+
+ err = atf_text_format(&str, "%s %s %d", "Test", "string", 1);
+ ATF_REQUIRE(!atf_is_error(err));
+ ATF_REQUIRE(strcmp(str, "Test string 1") == 0);
+ free(str);
+}
+
+static
+void
+format_ap(char **dest, const char *fmt, ...)
+{
+ va_list ap;
+ atf_error_t err;
+
+ va_start(ap, fmt);
+ err = atf_text_format_ap(dest, fmt, ap);
+ va_end(ap);
+
+ ATF_REQUIRE(!atf_is_error(err));
+}
+
+ATF_TC(format_ap);
+ATF_TC_HEAD(format_ap, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks the construction of free-form "
+ "strings using a va_list argument");
+}
+ATF_TC_BODY(format_ap, tc)
+{
+ char *str;
+
+ format_ap(&str, "%s %s %d", "Test", "string", 1);
+ ATF_REQUIRE(strcmp(str, "Test string 1") == 0);
+ free(str);
+}
+
+ATF_TC(split);
+ATF_TC_HEAD(split, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks the split function");
+}
+ATF_TC_BODY(split, tc)
+{
+ {
+ const char *words[] = { NULL };
+ check_split("", " ", words);
+ }
+
+ {
+ const char *words[] = { NULL };
+ check_split(" ", " ", words);
+ }
+
+ {
+ const char *words[] = { NULL };
+ check_split(" ", " ", words);
+ }
+
+ {
+ const char *words[] = { "a", "b", NULL };
+ check_split("a b", " ", words);
+ }
+
+ {
+ const char *words[] = { "a", "b", "c", "d", NULL };
+ check_split("a b c d", " ", words);
+ }
+
+ {
+ const char *words[] = { "foo", "bar", NULL };
+ check_split("foo bar", " ", words);
+ }
+
+ {
+ const char *words[] = { "foo", "bar", "baz", "foobar", NULL };
+ check_split("foo bar baz foobar", " ", words);
+ }
+
+ {
+ const char *words[] = { "foo", "bar", NULL };
+ check_split(" foo bar", " ", words);
+ }
+
+ {
+ const char *words[] = { "foo", "bar", NULL };
+ check_split("foo bar", " ", words);
+ }
+
+ {
+ const char *words[] = { "foo", "bar", NULL };
+ check_split("foo bar ", " ", words);
+ }
+
+ {
+ const char *words[] = { "foo", "bar", NULL };
+ check_split(" foo bar ", " ", words);
+ }
+}
+
+ATF_TC(split_delims);
+ATF_TC_HEAD(split_delims, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks the split function using "
+ "different delimiters");
+}
+ATF_TC_BODY(split_delims, tc)
+{
+
+ {
+ const char *words[] = { NULL };
+ check_split("", "/", words);
+ }
+
+ {
+ const char *words[] = { " ", NULL };
+ check_split(" ", "/", words);
+ }
+
+ {
+ const char *words[] = { " ", NULL };
+ check_split(" ", "/", words);
+ }
+
+ {
+ const char *words[] = { "a", "b", NULL };
+ check_split("a/b", "/", words);
+ }
+
+ {
+ const char *words[] = { "a", "bcd", "ef", NULL };
+ check_split("aLONGDELIMbcdLONGDELIMef", "LONGDELIM", words);
+ }
+}
+
+ATF_TC(to_bool);
+ATF_TC_HEAD(to_bool, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks the atf_text_to_bool function");
+}
+ATF_TC_BODY(to_bool, tc)
+{
+ bool b;
+
+ RE(atf_text_to_bool("true", &b)); ATF_REQUIRE(b);
+ RE(atf_text_to_bool("TRUE", &b)); ATF_REQUIRE(b);
+ RE(atf_text_to_bool("yes", &b)); ATF_REQUIRE(b);
+ RE(atf_text_to_bool("YES", &b)); ATF_REQUIRE(b);
+
+ RE(atf_text_to_bool("false", &b)); ATF_REQUIRE(!b);
+ RE(atf_text_to_bool("FALSE", &b)); ATF_REQUIRE(!b);
+ RE(atf_text_to_bool("no", &b)); ATF_REQUIRE(!b);
+ RE(atf_text_to_bool("NO", &b)); ATF_REQUIRE(!b);
+
+ b = false;
+ REQUIRE_ERROR(atf_text_to_bool("", &b));
+ ATF_REQUIRE(!b);
+ b = true;
+ REQUIRE_ERROR(atf_text_to_bool("", &b));
+ ATF_REQUIRE(b);
+
+ b = false;
+ REQUIRE_ERROR(atf_text_to_bool("tru", &b));
+ ATF_REQUIRE(!b);
+ b = true;
+ REQUIRE_ERROR(atf_text_to_bool("tru", &b));
+ ATF_REQUIRE(b);
+
+ b = false;
+ REQUIRE_ERROR(atf_text_to_bool("true2", &b));
+ ATF_REQUIRE(!b);
+ b = true;
+ REQUIRE_ERROR(atf_text_to_bool("true2", &b));
+ ATF_REQUIRE(b);
+
+ b = false;
+ REQUIRE_ERROR(atf_text_to_bool("fals", &b));
+ ATF_REQUIRE(!b);
+ b = true;
+ REQUIRE_ERROR(atf_text_to_bool("fals", &b));
+ ATF_REQUIRE(b);
+
+ b = false;
+ REQUIRE_ERROR(atf_text_to_bool("false2", &b));
+ ATF_REQUIRE(!b);
+ b = true;
+ REQUIRE_ERROR(atf_text_to_bool("false2", &b));
+ ATF_REQUIRE(b);
+}
+
+ATF_TC(to_long);
+ATF_TC_HEAD(to_long, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks the atf_text_to_long function");
+}
+ATF_TC_BODY(to_long, tc)
+{
+ long l;
+
+ RE(atf_text_to_long("0", &l)); ATF_REQUIRE_EQ(l, 0);
+ RE(atf_text_to_long("-5", &l)); ATF_REQUIRE_EQ(l, -5);
+ RE(atf_text_to_long("5", &l)); ATF_REQUIRE_EQ(l, 5);
+ RE(atf_text_to_long("123456789", &l)); ATF_REQUIRE_EQ(l, 123456789);
+
+ l = 1212;
+ REQUIRE_ERROR(atf_text_to_long("", &l));
+ ATF_REQUIRE_EQ(l, 1212);
+ REQUIRE_ERROR(atf_text_to_long("foo", &l));
+ ATF_REQUIRE_EQ(l, 1212);
+ REQUIRE_ERROR(atf_text_to_long("1234x", &l));
+ ATF_REQUIRE_EQ(l, 1212);
+}
+
+/* ---------------------------------------------------------------------
+ * Tests cases for the header file.
+ * --------------------------------------------------------------------- */
+
+HEADER_TC(include, "atf-c/text.h");
+
+/* ---------------------------------------------------------------------
+ * Main.
+ * --------------------------------------------------------------------- */
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, for_each_word);
+ ATF_TP_ADD_TC(tp, format);
+ ATF_TP_ADD_TC(tp, format_ap);
+ ATF_TP_ADD_TC(tp, split);
+ ATF_TP_ADD_TC(tp, split_delims);
+ ATF_TP_ADD_TC(tp, to_bool);
+ ATF_TP_ADD_TC(tp, to_long);
+
+ /* Add the test cases for the header file. */
+ ATF_TP_ADD_TC(tp, include);
+
+ return atf_no_error();
+}
diff --git a/external/bsd/atf/dist/atf-c/tp.c b/external/bsd/atf/dist/atf-c/tp.c
index 9dd6187b5ea..1a147d55a66 100644
--- a/external/bsd/atf/dist/atf-c/tp.c
+++ b/external/bsd/atf/dist/atf-c/tp.c
@@ -33,10 +33,8 @@
#include "atf-c/error.h"
#include "atf-c/fs.h"
-#include "atf-c/io.h"
#include "atf-c/sanity.h"
#include "atf-c/tc.h"
-#include "atf-c/tcr.h"
#include "atf-c/tp.h"
/* ---------------------------------------------------------------------
diff --git a/external/bsd/atf/dist/atf-c/tp_main.c b/external/bsd/atf/dist/atf-c/tp_main.c
index 872cfc32a09..7dc2bbf55a2 100644
--- a/external/bsd/atf/dist/atf-c/tp_main.c
+++ b/external/bsd/atf/dist/atf-c/tp_main.c
@@ -45,7 +45,6 @@
#include "atf-c/sanity.h"
#include "atf-c/tc.h"
#include "atf-c/tp.h"
-#include "atf-c/ui.h"
#if defined(HAVE_GNU_GETOPT)
# define GETOPT_POSIX "+"
@@ -110,66 +109,20 @@ FREE_FORM_ERROR(user);
* Printing functions.
* --------------------------------------------------------------------- */
-/* XXX: Why are these functions here? We have got a ui module, and it
- * seems the correct place to put these. Otherwise, the functions that
- * currently live there only format text, so they'd be moved to the text
- * module instead and kill ui completely. */
-
-static
-atf_error_t
-print_tag(FILE *f, const char *tag, bool repeat, size_t col,
- const char *fmt, ...)
-{
- atf_error_t err;
- va_list ap;
- atf_dynstr_t dest;
-
- err = atf_dynstr_init(&dest);
- if (atf_is_error(err))
- goto out;
-
- va_start(ap, fmt);
- err = atf_ui_format_ap(&dest, tag, repeat, col, fmt, ap);
- va_end(ap);
- if (atf_is_error(err))
- goto out_dest;
-
- fprintf(f, "%s\n", atf_dynstr_cstring(&dest));
-
-out_dest:
- atf_dynstr_fini(&dest);
-out:
- return err;
-}
-
static
void
print_error(const atf_error_t err)
{
- PRE(atf_is_error(err));
-
- if (atf_error_is(err, "no_memory")) {
- char buf[1024];
+ char buf[4096];
- atf_error_format(err, buf, sizeof(buf));
-
- fprintf(stderr, "%s: %s\n", progname, buf);
- } else {
- atf_dynstr_t tag;
- char buf[4096];
-
- atf_error_format(err, buf, sizeof(buf));
-
- atf_dynstr_init_fmt(&tag, "%s: ", progname);
- print_tag(stderr, atf_dynstr_cstring(&tag), true, 0,
- "ERROR: %s", buf);
+ PRE(atf_is_error(err));
- if (atf_error_is(err, "usage"))
- print_tag(stderr, atf_dynstr_cstring(&tag), true, 0,
- "Type `%s -h' for more details.", progname);
+ atf_error_format(err, buf, sizeof(buf));
+ fprintf(stderr, "%s: ERROR: %s\n", progname, buf);
- atf_dynstr_fini(&tag);
- }
+ if (atf_error_is(err, "usage"))
+ fprintf(stderr, "%s: See atf-test-program(1) for usage details.\n",
+ progname);
}
/* ---------------------------------------------------------------------
@@ -178,7 +131,6 @@ print_error(const atf_error_t err)
struct params {
bool m_do_list;
- bool m_do_usage;
atf_fs_path_t m_srcdir;
char *m_tcname;
enum tc_part m_tcpart;
@@ -211,7 +163,6 @@ params_init(struct params *p, const char *argv0)
atf_error_t err;
p->m_do_list = false;
- p->m_do_usage = false;
p->m_tcname = NULL;
p->m_tcpart = BODY;
@@ -219,7 +170,7 @@ params_init(struct params *p, const char *argv0)
if (atf_is_error(err))
return err;
- err = atf_fs_path_init_fmt(&p->m_resfile, "resfile"); /* XXX Bad default */
+ err = atf_fs_path_init_fmt(&p->m_resfile, "/dev/stdout");
if (atf_is_error(err)) {
atf_fs_path_fini(&p->m_srcdir);
return err;
@@ -326,33 +277,6 @@ list_tcs(const atf_tp_t *tp)
* --------------------------------------------------------------------- */
static
-void
-usage(void)
-{
- print_tag(stdout, "Usage: ", false, 0, "%s [options] test_case", progname);
- printf("\n");
- print_tag(stdout, "", false, 0, "This is an independent atf test "
- "program.");
- printf("\n");
- print_tag(stdout, "", false, 0, "Available options:");
- print_tag(stdout, " -h ", false, 0,
- "Shows this help message");
- print_tag(stdout, " -l ", false, 0,
- "List test cases and their purpose");
- print_tag(stdout, " -r resfile ", false, 0,
- "The file to which the test program will write the results "
- "of the executed test case");
- print_tag(stdout, " -s srcdir ", false, 0,
- "Directory where the test's data files are "
- "located");
- print_tag(stdout, " -v var=value ", false, 0,
- "Sets the configuration variable `var' to `value'");
- printf("\n");
- print_tag(stdout, "", false, 0, "For more details please see "
- "atf-test-program(1) and atf(7).");
-}
-
-static
atf_error_t
handle_tcarg(const char *tcarg, char **tcname, enum tc_part *tcpart)
{
@@ -389,7 +313,6 @@ static
atf_error_t
process_params(int argc, char **argv, struct params *p)
{
- const int original_argc = argc;
atf_error_t err;
int ch;
@@ -399,12 +322,8 @@ process_params(int argc, char **argv, struct params *p)
opterr = 0;
while (!atf_is_error(err) &&
- (ch = getopt(argc, argv, GETOPT_POSIX ":hlr:s:v:")) != -1) {
+ (ch = getopt(argc, argv, GETOPT_POSIX ":lr:s:v:")) != -1) {
switch (ch) {
- case 'h':
- p->m_do_usage = true;
- break;
-
case 'l':
p->m_do_list = true;
break;
@@ -434,10 +353,7 @@ process_params(int argc, char **argv, struct params *p)
argv += optind;
if (!atf_is_error(err)) {
- if (p->m_do_usage) {
- if (original_argc != 2)
- err = usage_error("-h must be given alone.");
- } else if (p->m_do_list) {
+ if (p->m_do_list) {
if (argc > 0)
err = usage_error("Cannot provide test case names with -l");
} else {
@@ -604,12 +520,6 @@ controlled_main(int argc, char **argv,
if (atf_is_error(err))
goto out;
- if (p.m_do_usage) {
- usage();
- *exitcode = EXIT_SUCCESS;
- goto out_p;
- }
-
err = handle_srcdir(&p);
if (atf_is_error(err))
goto out_p;
diff --git a/external/bsd/atf/dist/atf-c/tp_test.c b/external/bsd/atf/dist/atf-c/tp_test.c
new file mode 100644
index 00000000000..a91956336f3
--- /dev/null
+++ b/external/bsd/atf/dist/atf-c/tp_test.c
@@ -0,0 +1,50 @@
+/*
+ * Automated Testing Framework (atf)
+ *
+ * Copyright (c) 2010 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <atf-c.h>
+
+#include "test_helpers.h"
+
+/* ---------------------------------------------------------------------
+ * Tests cases for the header file.
+ * --------------------------------------------------------------------- */
+
+HEADER_TC(include, "atf-c/tp.h");
+
+/* ---------------------------------------------------------------------
+ * Main.
+ * --------------------------------------------------------------------- */
+
+ATF_TP_ADD_TCS(tp)
+{
+ /* Add the test cases for the header file. */
+ ATF_TP_ADD_TC(tp, include);
+
+ return atf_no_error();
+}
diff --git a/external/bsd/atf/dist/atf-c/user_test.c b/external/bsd/atf/dist/atf-c/user_test.c
new file mode 100644
index 00000000000..3443ff508b3
--- /dev/null
+++ b/external/bsd/atf/dist/atf-c/user_test.c
@@ -0,0 +1,151 @@
+/*
+ * Automated Testing Framework (atf)
+ *
+ * Copyright (c) 2007, 2008, 2009 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 <sys/param.h>
+#include <sys/types.h>
+
+#include <limits.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include <atf-c.h>
+
+#include "atf-c/user.h"
+
+#include "test_helpers.h"
+
+/* ---------------------------------------------------------------------
+ * Test cases for the free functions.
+ * --------------------------------------------------------------------- */
+
+ATF_TC(euid);
+ATF_TC_HEAD(euid, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests the atf_user_euid function");
+}
+ATF_TC_BODY(euid, tc)
+{
+ ATF_REQUIRE_EQ(atf_user_euid(), geteuid());
+}
+
+ATF_TC(is_member_of_group);
+ATF_TC_HEAD(is_member_of_group, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests the atf_user_is_member_of_group "
+ "function");
+}
+ATF_TC_BODY(is_member_of_group, tc)
+{
+ gid_t gids[NGROUPS_MAX];
+ gid_t g, maxgid;
+ int ngids;
+
+ {
+ int i;
+
+ ngids = getgroups(NGROUPS_MAX, gids);
+ if (ngids == -1)
+ atf_tc_fail("Call to getgroups failed");
+ maxgid = 0;
+ for (i = 0; i < ngids; i++) {
+ if (maxgid < gids[i])
+ maxgid = gids[i];
+ }
+ printf("User belongs to %d groups\n", ngids);
+ printf("Last GID is %d\n", maxgid);
+ }
+
+ for (g = 0; g < maxgid; g++) {
+ bool found = false;
+ int i;
+
+ for (i = 0; !found && i < ngids; i++) {
+ if (gids[i] == g)
+ found = true;
+ }
+
+ if (found) {
+ printf("Checking if user belongs to group %d\n", g);
+ ATF_REQUIRE(atf_user_is_member_of_group(g));
+ } else {
+ printf("Checking if user does not belong to group %d\n", g);
+ ATF_REQUIRE(!atf_user_is_member_of_group(g));
+ }
+ }
+}
+
+ATF_TC(is_root);
+ATF_TC_HEAD(is_root, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests the atf_user_is_root function");
+}
+ATF_TC_BODY(is_root, tc)
+{
+ if (geteuid() == 0)
+ ATF_REQUIRE(atf_user_is_root());
+ else
+ ATF_REQUIRE(!atf_user_is_root());
+}
+
+ATF_TC(is_unprivileged);
+ATF_TC_HEAD(is_unprivileged, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests the atf_user_is_unprivileged "
+ "function");
+}
+ATF_TC_BODY(is_unprivileged, tc)
+{
+ if (geteuid() != 0)
+ ATF_REQUIRE(atf_user_is_unprivileged());
+ else
+ ATF_REQUIRE(!atf_user_is_unprivileged());
+}
+
+/* ---------------------------------------------------------------------
+ * Tests cases for the header file.
+ * --------------------------------------------------------------------- */
+
+HEADER_TC(include, "atf-c/user.h");
+
+/* ---------------------------------------------------------------------
+ * Main.
+ * --------------------------------------------------------------------- */
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, euid);
+ ATF_TP_ADD_TC(tp, is_member_of_group);
+ ATF_TP_ADD_TC(tp, is_root);
+ ATF_TP_ADD_TC(tp, is_unprivileged);
+
+ /* Add the test cases for the header file. */
+ ATF_TP_ADD_TC(tp, include);
+
+ return atf_no_error();
+}
diff --git a/external/bsd/atf/dist/atf-check/Atffile b/external/bsd/atf/dist/atf-check/Atffile
new file mode 100644
index 00000000000..146211e000d
--- /dev/null
+++ b/external/bsd/atf/dist/atf-check/Atffile
@@ -0,0 +1,5 @@
+Content-Type: application/X-atf-atffile; version="1"
+
+prop: test-suite = atf
+
+tp-glob: *_test
diff --git a/external/bsd/atf/dist/atf-check/atf-check.cpp b/external/bsd/atf/dist/atf-check/atf-check.cpp
index e1ddea69481..24f649f1dff 100644
--- a/external/bsd/atf/dist/atf-check/atf-check.cpp
+++ b/external/bsd/atf/dist/atf-check/atf-check.cpp
@@ -1,7 +1,7 @@
//
// Automated Testing Framework (atf)
//
-// Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
+// Copyright (c) 2008, 2009, 2010 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@@ -30,6 +30,9 @@
extern "C" {
#include <sys/types.h>
#include <sys/wait.h>
+
+#include <limits.h>
+#include <signal.h>
}
#include <cerrno>
@@ -56,6 +59,196 @@ extern "C" {
// Auxiliary functions.
// ------------------------------------------------------------------------
+namespace {
+
+enum status_check_t {
+ sc_exit,
+ sc_ignore,
+ sc_signal,
+};
+
+struct status_check {
+ status_check_t type;
+ bool negated;
+ int value;
+
+ status_check(const status_check_t& p_type, const bool p_negated,
+ const int p_value) :
+ type(p_type),
+ negated(p_negated),
+ value(p_value)
+ {
+ }
+};
+
+enum output_check_t {
+ oc_ignore,
+ oc_inline,
+ oc_file,
+ oc_empty,
+ oc_match,
+ oc_save
+};
+
+struct output_check {
+ output_check_t type;
+ bool negated;
+ std::string value;
+
+ output_check(const output_check_t& p_type, const bool p_negated,
+ const std::string& p_value) :
+ type(p_type),
+ negated(p_negated),
+ value(p_value)
+ {
+ }
+};
+
+} // anonymous namespace
+
+static int
+parse_exit_code(const std::string& str)
+{
+ try {
+ const int value = atf::text::to_type< int >(str);
+ if (value < 0 || value > 255)
+ throw std::runtime_error("Unused reason");
+ return value;
+ } catch (const std::runtime_error& e) {
+ throw atf::application::usage_error("Invalid exit code for -s option; "
+ "must be an integer in range 0-255");
+ }
+}
+
+static struct name_number {
+ const char *name;
+ int signo;
+} signal_names_to_numbers[] = {
+ { "hup", SIGHUP },
+ { "int", SIGINT },
+ { "quit", SIGQUIT },
+ { "trap", SIGTRAP },
+ { "kill", SIGKILL },
+ { "segv", SIGSEGV },
+ { "pipe", SIGPIPE },
+ { "alrm", SIGALRM },
+ { "term", SIGTERM },
+ { "usr1", SIGUSR1 },
+ { "usr2", SIGUSR2 },
+ { NULL, INT_MIN },
+};
+
+static int
+signal_name_to_number(const std::string& str)
+{
+ struct name_number* iter = signal_names_to_numbers;
+ int signo = INT_MIN;
+ while (signo == INT_MIN && iter->name != NULL) {
+ if (str == iter->name || str == std::string("sig") + iter->name)
+ signo = iter->signo;
+ else
+ iter++;
+ }
+ return signo;
+}
+
+static int
+parse_signal(const std::string& str)
+{
+ const int signo = signal_name_to_number(str);
+ if (signo == INT_MIN) {
+ try {
+ return atf::text::to_type< int >(str);
+ } catch (std::runtime_error) {
+ throw atf::application::usage_error("Invalid signal name or number "
+ "in -s option");
+ }
+ }
+ INV(signo != INT_MIN);
+ return signo;
+}
+
+static status_check
+parse_status_check_arg(const std::string& arg)
+{
+ const std::string::size_type delimiter = arg.find(':');
+ bool negated = (arg.compare(0, 4, "not-") == 0);
+ const std::string action_str = arg.substr(0, delimiter);
+ const std::string action = negated ? action_str.substr(4) : action_str;
+ const std::string value_str = (
+ delimiter == std::string::npos ? "" : arg.substr(delimiter + 1));
+ int value;
+
+ status_check_t type;
+ if (action == "eq") {
+ // Deprecated; use exit instead. TODO: Remove after 0.10.
+ type = sc_exit;
+ if (negated)
+ throw atf::application::usage_error("Cannot negate eq checker");
+ negated = false;
+ value = parse_exit_code(value_str);
+ } else if (action == "exit") {
+ type = sc_exit;
+ if (value_str.empty())
+ value = INT_MIN;
+ else
+ value = parse_exit_code(value_str);
+ } else if (action == "ignore") {
+ if (negated)
+ throw atf::application::usage_error("Cannot negate ignore checker");
+ type = sc_ignore;
+ value = INT_MIN;
+ } else if (action == "ne") {
+ // Deprecated; use not-exit instead. TODO: Remove after 0.10.
+ type = sc_exit;
+ if (negated)
+ throw atf::application::usage_error("Cannot negate ne checker");
+ negated = true;
+ value = parse_exit_code(value_str);
+ } else if (action == "signal") {
+ type = sc_signal;
+ if (value_str.empty())
+ value = INT_MIN;
+ else
+ value = parse_signal(value_str);
+ } else
+ throw atf::application::usage_error("Invalid output checker");
+
+ return status_check(type, negated, value);
+}
+
+static
+output_check
+parse_output_check_arg(const std::string& arg)
+{
+ const std::string::size_type delimiter = arg.find(':');
+ const bool negated = (arg.compare(0, 4, "not-") == 0);
+ const std::string action_str = arg.substr(0, delimiter);
+ const std::string action = negated ? action_str.substr(4) : action_str;
+
+ output_check_t type;
+ if (action == "empty")
+ type = oc_empty;
+ else if (action == "file")
+ type = oc_file;
+ else if (action == "ignore") {
+ if (negated)
+ throw atf::application::usage_error("Cannot negate ignore checker");
+ type = oc_ignore;
+ } else if (action == "inline")
+ type = oc_inline;
+ else if (action == "match")
+ type = oc_match;
+ else if (action == "save") {
+ if (negated)
+ throw atf::application::usage_error("Cannot negate save checker");
+ type = oc_save;
+ } else
+ throw atf::application::usage_error("Invalid output checker");
+
+ return output_check(type, negated, arg.substr(delimiter + 1));
+}
+
static
std::string
flatten_argv(char* const* argv)
@@ -102,84 +295,55 @@ execute_with_shell(char* const* argv)
return execute(sh_argv);
}
-// ------------------------------------------------------------------------
-// The "atf_check" application.
-// ------------------------------------------------------------------------
-
-class atf_check : public atf::application::app {
- enum output_check_t {
- oc_ignore,
- oc_inline,
- oc_file,
- oc_empty,
- oc_save
- };
-
- enum status_check_t {
- sc_equal,
- sc_not_equal,
- sc_ignore
- };
-
- bool m_xflag;
-
- output_check_t m_stdout_check;
- std::string m_stdout_arg;
-
- output_check_t m_stderr_check;
- std::string m_stderr_arg;
+static
+void
+cat_file(const atf::fs::path& path)
+{
+ std::ifstream stream(path.c_str());
+ if (!stream)
+ throw std::runtime_error("Failed to open " + path.str());
- status_check_t m_status_check;
- int m_status_arg;
+ stream >> std::noskipws;
+ std::istream_iterator< char > begin(stream), end;
+ std::ostream_iterator< char > out(std::cerr);
+ std::copy(begin, end, out);
- static const char* m_description;
+ stream.close();
+}
- bool file_empty(const atf::fs::path&) const;
- void print_diff(const atf::fs::path&, const atf::fs::path&) const;
- void print_file(const atf::fs::path&) const;
- std::string decode(const std::string&) const;
+static
+bool
+grep_file(const atf::fs::path& path, const std::string& regexp)
+{
+ std::ifstream stream(path.c_str());
+ if (!stream)
+ throw std::runtime_error("Failed to open " + path.str());
- bool run_status_check(const atf::check::check_result&) const;
- bool run_output_check(const atf::check::check_result&,
- const std::string&) const;
+ bool found = false;
- std::string specific_args(void) const;
- options_set specific_options(void) const;
- void process_option(int, const char*);
- void process_option_s(const std::string&);
- void process_option_o(const std::string&);
- void process_option_e(const std::string&);
-
-public:
- atf_check(void);
- int main(void);
-};
+ std::string line;
+ while (!found && std::getline(stream, line).good()) {
+ if (atf::text::match(line, regexp))
+ found = true;
+ }
-const char* atf_check::m_description =
- "atf-check executes given command and analyzes its results.";
+ stream.close();
-atf_check::atf_check(void) :
- app(m_description, "atf-check(1)", "atf(7)"),
- m_xflag(false),
- m_stdout_check(oc_empty),
- m_stderr_check(oc_empty),
- m_status_check(sc_equal),
- m_status_arg(0)
-{
+ return found;
}
+static
bool
-atf_check::file_empty(const atf::fs::path& p)
- const
+file_empty(const atf::fs::path& p)
{
atf::fs::file_info f(p);
return (f.get_size() == 0);
}
+static
void
-atf_check::print_diff(const atf::fs::path& p1, const atf::fs::path& p2)
- const
+print_diff(const atf::fs::path& p1, const atf::fs::path& p2)
{
const atf::process::status s =
atf::process::exec(atf::fs::path("diff"),
@@ -196,20 +360,9 @@ atf_check::print_diff(const atf::fs::path& p1, const atf::fs::path& p2)
std::cerr << "Error while running diff(3)" << std::endl;
}
-void
-atf_check::print_file(const atf::fs::path& p)
- const
-{
- std::ifstream f(p.c_str());
- f >> std::noskipws;
- std::istream_iterator< char > begin(f), end;
- std::ostream_iterator< char > out(std::cerr);
- std::copy(begin, end, out);
-}
-
+static
std::string
-atf_check::decode(const std::string& s)
- const
+decode(const std::string& s)
{
size_t i;
std::string res;
@@ -252,216 +405,269 @@ atf_check::decode(const std::string& s)
return res;
}
+static
bool
-atf_check::run_status_check(const atf::check::check_result& r)
- const
+run_status_check(const status_check& sc, const atf::check::check_result& cr)
{
- bool retval = true;
+ bool result;
- if (!r.exited()) {
- std::cerr << "Fail: program did not exit cleanly" << std::endl;
- retval = false;
- } else {
- const int& status = r.exitcode();
+ if (sc.type == sc_exit) {
+ if (cr.exited() && sc.value != INT_MIN) {
+ const int status = cr.exitcode();
- if (m_status_check == sc_equal) {
- if (m_status_arg != status) {
+ if (!sc.negated && sc.value != status) {
std::cerr << "Fail: incorrect exit status: "
<< status << ", expected: "
- << m_status_arg << std::endl;
- retval = false;
- }
- } else if (m_status_check == sc_not_equal) {
- if (m_status_arg == status) {
+ << sc.value << std::endl;
+ result = false;
+ } else if (sc.negated && sc.value == status) {
std::cerr << "Fail: incorrect exit status: "
<< status << ", expected: "
- << "anything other" << std::endl;
- retval = false;
- }
+ << "anything else" << std::endl;
+ result = false;
+ } else
+ result = true;
+ } else if (cr.exited() && sc.value == INT_MIN) {
+ result = true;
+ } else {
+ std::cerr << "Fail: program did not exit cleanly" << std::endl;
+ result = false;
}
+ } else if (sc.type == sc_ignore) {
+ result = true;
+ } else if (sc.type == sc_signal) {
+ if (cr.signaled() && sc.value != INT_MIN) {
+ const int status = cr.termsig();
+
+ if (!sc.negated && sc.value != status) {
+ std::cerr << "Fail: incorrect signal received: "
+ << status << ", expected: "
+ << sc.value << std::endl;
+ result = false;
+ } else if (sc.negated && sc.value == status) {
+ std::cerr << "Fail: incorrect signal received: "
+ << status << ", expected: "
+ << "anything else" << std::endl;
+ result = false;
+ } else
+ result = true;
+ } else if (cr.signaled() && sc.value == INT_MIN) {
+ result = true;
+ } else {
+ std::cerr << "Fail: program did not receive a signal" << std::endl;
+ result = false;
+ }
+ } else {
+ UNREACHABLE;
+ result = false;
}
- if (retval == false) {
+ if (result == false) {
std::cerr << "stdout:" << std::endl;
- print_file(r.stdout_path());
+ cat_file(cr.stdout_path());
std::cerr << std::endl;
std::cerr << "stderr:" << std::endl;
- print_file(r.stderr_path());
+ cat_file(cr.stderr_path());
std::cerr << std::endl;
}
- return retval;
+ return result;
}
+static
bool
-atf_check::run_output_check(const atf::check::check_result& r,
- const std::string& stdxxx)
- const
+run_status_checks(const std::vector< status_check >& checks,
+ const atf::check::check_result& result)
{
- atf::fs::path path("/");
- std::string arg;
- output_check_t check = m_stdout_check;
+ bool ok = false;
- if (stdxxx == "stdout") {
- path = r.stdout_path();
- arg = m_stdout_arg.c_str();
- check = m_stdout_check;
- } else if (stdxxx == "stderr") {
- path = r.stderr_path();
- arg = m_stderr_arg.c_str();
- check = m_stderr_check;
- } else
- UNREACHABLE;
+ for (std::vector< status_check >::const_iterator iter = checks.begin();
+ !ok && iter != checks.end(); iter++) {
+ ok |= run_status_check(*iter, result);
+ }
- if (check == oc_empty) {
- if (!file_empty(path)) {
- std::cerr << "Fail: incorrect " << stdxxx << std::endl;
- print_diff(atf::fs::path("/dev/null"), path);
+ return ok;
+}
- return false;
- }
- } else if (check == oc_file) {
- if (atf::io::cmp(path, atf::fs::path(arg)) != 0) {
- std::cerr << "Fail: incorrect " << stdxxx << std::endl;
- print_diff(atf::fs::path(arg), path);
+static
+bool
+run_output_check(const output_check oc, const atf::fs::path& path,
+ const std::string& stdxxx)
+{
+ bool result;
- return false;
- }
- } else if (check == oc_inline) {
+ if (oc.type == oc_empty) {
+ const bool is_empty = file_empty(path);
+ if (!oc.negated && !is_empty) {
+ std::cerr << "Fail: " << stdxxx << " not empty" << std::endl;
+ print_diff(atf::fs::path("/dev/null"), path);
+ result = false;
+ } else if (oc.negated && is_empty) {
+ std::cerr << "Fail: " << stdxxx << " is empty" << std::endl;
+ result = false;
+ } else
+ result = true;
+ } else if (oc.type == oc_file) {
+ const bool equals = atf::io::cmp(path, atf::fs::path(oc.value));
+ if (!oc.negated && !equals) {
+ std::cerr << "Fail: " << stdxxx << " does not match golden output"
+ << std::endl;
+ print_diff(atf::fs::path(oc.value), path);
+ result = false;
+ } else if (oc.negated && equals) {
+ std::cerr << "Fail: " << stdxxx << " matches golden output"
+ << std::endl;
+ cat_file(atf::fs::path(oc.value));
+ result = false;
+ } else
+ result = true;
+ } else if (oc.type == oc_ignore) {
+ result = true;
+ } else if (oc.type == oc_inline) {
atf::fs::path path2 = atf::fs::path(atf::config::get("atf_workdir"))
/ "inline.XXXXXX";
atf::fs::temp_file temp(path2);
- temp << decode(arg);
+ temp << decode(oc.value);
temp.close();
- if (atf::io::cmp(path, temp.get_path()) != 0) {
- std::cerr << "Fail: incorrect " << stdxxx << std::endl;
+ const bool equals = atf::io::cmp(path, temp.get_path());
+ if (!oc.negated && !equals) {
+ std::cerr << "Fail: " << stdxxx << " does not match expected value"
+ << std::endl;
print_diff(temp.get_path(), path);
-
- return false;
- }
- } else if (check == oc_save) {
+ result = false;
+ } else if (oc.negated && equals) {
+ std::cerr << "Fail: " << stdxxx << " matches expected value"
+ << std::endl;
+ cat_file(temp.get_path());
+ result = false;
+ } else
+ result = true;
+ } else if (oc.type == oc_match) {
+ const bool matches = grep_file(path, oc.value);
+ if (!oc.negated && !matches) {
+ std::cerr << "Fail: regexp " + oc.value + " not in " << stdxxx
+ << std::endl;
+ cat_file(path);
+ result = false;
+ } else if (oc.negated && matches) {
+ std::cerr << "Fail: regexp " + oc.value + " is in " << stdxxx
+ << std::endl;
+ cat_file(path);
+ result = false;
+ } else
+ result = true;
+ } else if (oc.type == oc_save) {
+ INV(!oc.negated);
std::ifstream ifs(path.c_str(), std::fstream::binary);
ifs >> std::noskipws;
std::istream_iterator< char > begin(ifs), end;
- std::ofstream ofs(arg.c_str(), std::fstream::binary
+ std::ofstream ofs(oc.value.c_str(), std::fstream::binary
| std::fstream::trunc);
std::ostream_iterator <char> obegin(ofs);
std::copy(begin, end, obegin);
+ result = true;
+ } else {
+ UNREACHABLE;
+ result = false;
}
- return true;
+ return result;
}
-std::string
-atf_check::specific_args(void)
- const
-{
- return "<command>";
-}
-
-atf_check::options_set
-atf_check::specific_options(void)
- const
+static
+bool
+run_output_checks(const std::vector< output_check >& checks,
+ const atf::fs::path& path, const std::string& stdxxx)
{
- using atf::application::option;
- options_set opts;
+ bool ok = true;
- opts.insert(option('s', "qual:value", "Handle status. Qualifier "
- "must be one of: ignore eq:<num> ne:<num>"));
- opts.insert(option('o', "action:arg", "Handle stdout. Action must be "
- "one of: empty ignore file:<path> inline:<val> save:<path>"));
- opts.insert(option('e', "action:arg", "Handle stderr. Action must be "
- "one of: empty ignore file:<path> inline:<val> save:<path>"));
- opts.insert(option('x', "", "Execute command as a shell command"));
+ for (std::vector< output_check >::const_iterator iter = checks.begin();
+ iter != checks.end(); iter++) {
+ ok &= run_output_check(*iter, path, stdxxx);
+ }
- return opts;
+ return ok;
}
-void
-atf_check::process_option_s(const std::string& arg)
-{
- using atf::application::usage_error;
+// ------------------------------------------------------------------------
+// The "atf_check" application.
+// ------------------------------------------------------------------------
- if (arg == "ignore") {
- m_status_check = sc_ignore;
- return;
- }
+class atf_check : public atf::application::app {
+ bool m_xflag;
- std::string::size_type pos = arg.find(':');
- std::string action = arg.substr(0, pos);
+ std::vector< status_check > m_status_checks;
+ std::vector< output_check > m_stdout_checks;
+ std::vector< output_check > m_stderr_checks;
- if (action == "eq")
- m_status_check = sc_equal;
- else if (action == "ne")
- m_status_check = sc_not_equal;
- else
- throw usage_error("Invalid value for -s option");
+ static const char* m_description;
- std::string value = arg.substr(pos + 1);
+ bool run_output_checks(const atf::check::check_result&,
+ const std::string&) const;
- try {
- m_status_arg = atf::text::to_type< unsigned int >(value);
- } catch (std::runtime_error) {
- throw usage_error("Invalid value for -s option; must be an "
- "integer in range 0-255");
- }
+ std::string specific_args(void) const;
+ options_set specific_options(void) const;
+ void process_option(int, const char*);
+ void process_option_s(const std::string&);
- if ((m_status_arg < 0) || (m_status_arg > 255))
- throw usage_error("Invalid value for -s option; must be an "
- "integer in range 0-255");
+public:
+ atf_check(void);
+ int main(void);
+};
-}
+const char* atf_check::m_description =
+ "atf-check executes given command and analyzes its results.";
-void
-atf_check::process_option_o(const std::string& arg)
+atf_check::atf_check(void) :
+ app(m_description, "atf-check(1)", "atf(7)"),
+ m_xflag(false)
{
- using atf::application::usage_error;
-
- std::string::size_type pos = arg.find(':');
- std::string action = arg.substr(0, pos);
-
- if (action == "empty")
- m_stdout_check = oc_empty;
- else if (action == "ignore")
- m_stdout_check = oc_ignore;
- else if (action == "save")
- m_stdout_check = oc_save;
- else if (action == "inline")
- m_stdout_check = oc_inline;
- else if (action == "file")
- m_stdout_check = oc_file;
- else
- throw usage_error("Invalid value for -o option");
+}
- m_stdout_arg = arg.substr(pos + 1);
+bool
+atf_check::run_output_checks(const atf::check::check_result& r,
+ const std::string& stdxxx)
+ const
+{
+ if (stdxxx == "stdout") {
+ return ::run_output_checks(m_stdout_checks, r.stdout_path(), "stdout");
+ } else if (stdxxx == "stderr") {
+ return ::run_output_checks(m_stderr_checks, r.stderr_path(), "stderr");
+ } else {
+ UNREACHABLE;
+ return false;
+ }
}
-void
-atf_check::process_option_e(const std::string& arg)
+std::string
+atf_check::specific_args(void)
+ const
{
- using atf::application::usage_error;
+ return "<command>";
+}
- std::string::size_type pos = arg.find(':');
- std::string action = arg.substr(0, pos);
+atf_check::options_set
+atf_check::specific_options(void)
+ const
+{
+ using atf::application::option;
+ options_set opts;
- if (action == "empty")
- m_stderr_check = oc_empty;
- else if (action == "ignore")
- m_stderr_check = oc_ignore;
- else if (action == "save")
- m_stderr_check = oc_save;
- else if (action == "inline")
- m_stderr_check = oc_inline;
- else if (action == "file")
- m_stderr_check = oc_file;
- else
- throw usage_error("Invalid value for -e option");
+ opts.insert(option('s', "qual:value", "Handle status. Qualifier "
+ "must be one of: ignore exit:<num> signal:<name|num>"));
+ opts.insert(option('o', "action:arg", "Handle stdout. Action must be "
+ "one of: empty ignore file:<path> inline:<val> match:regexp "
+ "save:<path>"));
+ opts.insert(option('e', "action:arg", "Handle stderr. Action must be "
+ "one of: empty ignore file:<path> inline:<val> match:regexp "
+ "save:<path>"));
+ opts.insert(option('x', "", "Execute command as a shell command"));
- m_stderr_arg = arg.substr(pos + 1);
+ return opts;
}
void
@@ -469,15 +675,15 @@ atf_check::process_option(int ch, const char* arg)
{
switch (ch) {
case 's':
- process_option_s(arg);
+ m_status_checks.push_back(parse_status_check_arg(arg));
break;
case 'o':
- process_option_o(arg);
+ m_stdout_checks.push_back(parse_output_check_arg(arg));
break;
case 'e':
- process_option_e(arg);
+ m_stderr_checks.push_back(parse_output_check_arg(arg));
break;
case 'x':
@@ -500,9 +706,21 @@ atf_check::main(void)
atf::check::check_result r =
m_xflag ? execute_with_shell(m_argv) : execute(m_argv);
- if ((run_status_check(r) == false) ||
- (run_output_check(r, "stderr") == false) ||
- (run_output_check(r, "stdout") == false))
+ if (m_status_checks.empty())
+ m_status_checks.push_back(status_check(sc_exit, false, EXIT_SUCCESS));
+ else if (m_status_checks.size() > 1) {
+ // TODO: Remove this restriction.
+ throw atf::application::usage_error("Cannot specify -s more than once");
+ }
+
+ if (m_stdout_checks.empty())
+ m_stdout_checks.push_back(output_check(oc_empty, false, ""));
+ if (m_stderr_checks.empty())
+ m_stderr_checks.push_back(output_check(oc_empty, false, ""));
+
+ if ((run_status_checks(m_status_checks, r) == false) ||
+ (run_output_checks(r, "stderr") == false) ||
+ (run_output_checks(r, "stdout") == false))
status = EXIT_FAILURE;
else
status = EXIT_SUCCESS;
diff --git a/external/bsd/atf/dist/atf-check/integration_test.sh b/external/bsd/atf/dist/atf-check/integration_test.sh
new file mode 100644
index 00000000000..33f5bcd6c34
--- /dev/null
+++ b/external/bsd/atf/dist/atf-check/integration_test.sh
@@ -0,0 +1,462 @@
+#
+# Automated Testing Framework (atf)
+#
+# Copyright (c) 2008, 2009, 2010 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
+# CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+h_pass()
+{
+ cmd="$1"; shift
+
+ echo "Running [atf-check $*] against [${cmd}]"
+
+ cat >script.sh <<EOF
+#! $(atf-config -t atf_shell)
+${cmd}
+EOF
+ chmod +x script.sh
+
+ if ! atf-check "${@}" ./script.sh >tmp; then
+ cat tmp
+ atf_fail "atf-check failed"
+ fi
+}
+
+h_fail()
+{
+ cmd="$1"; shift
+
+ echo "Running [atf-check $*] against [${cmd}]"
+
+ cat >script.sh <<EOF
+#! $(atf-config -t atf_shell)
+${cmd}
+EOF
+ chmod +x script.sh
+
+ if atf-check "${@}" ./script.sh 2>tmp; then
+ cat tmp
+ atf_fail "atf-check succeeded but should fail"
+ fi
+}
+
+atf_test_case sflag_eq_ne
+sflag_eq_ne_head()
+{
+ atf_set "descr" "Tests for the -s option using the 'eq' and 'ne' qualifiers"
+ atf_set "use.fs" "true"
+}
+sflag_eq_ne_body()
+{
+ h_pass "true" -s eq:0
+ h_pass "false" -s ne:0
+ h_pass "exit 255" -s eq:255
+ h_pass "exit 0" -s ne:255
+
+ h_fail "exit 256" -s eq:256
+ h_fail "exit -1" -s eq:-1
+ h_fail "true" -s ne:256
+ h_fail "true" -s ne:-1
+}
+
+atf_test_case sflag_exit
+sflag_exit_head()
+{
+ atf_set "descr" "Tests for the -s option using the 'exit' qualifier"
+ atf_set "use.fs" "true"
+}
+sflag_exit_body()
+{
+ h_pass 'true' -s exit:0
+ h_pass 'false' -s not-exit:0
+ h_pass 'exit 255' -s exit:255
+ h_pass 'exit 0' -s not-exit:255
+
+ h_fail 'exit 256' -s exit:256
+ h_fail 'exit -1' -s exit:-1
+ h_fail 'true' -s not-exit:256
+ h_fail 'true' -s not-exit:-1
+
+ h_pass 'true' -s exit
+ h_pass 'false' -s exit
+ atf-check -s exit -x 'kill $$' && atf_fail "Signal detected as clean exit"
+}
+
+atf_test_case sflag_ignore
+sflag_ignore_head()
+{
+ atf_set "descr" "Tests for the -s option using the 'ignore' qualifier"
+ atf_set "use.fs" "true"
+}
+sflag_ignore_body()
+{
+ h_pass 'true' -s ignore
+ h_pass 'false' -s ignore
+ atf-check -s ignored -x 'kill $$' && atf_fail "Signal not ignored"
+}
+
+atf_test_case sflag_signal
+sflag_signal_head()
+{
+ atf_set "descr" "Tests for the -s option using the 'signal' qualifier"
+ atf_set "use.fs" "true"
+}
+sflag_signal_body()
+{
+ atf-check -s signal:hup -x 'kill -1 $$' || atf_fail "Signal not detected"
+ atf-check -s signal:sighup -x 'kill -1 $$' || atf_fail "Signal not detected"
+ atf-check -s signal:1 -x 'kill -1 $$' || atf_fail "Signal not detected"
+ atf-check -s signal -x 'kill -1 $$' || atf_fail "Signal not detected"
+
+ atf-check -s not-signal:kill -x 'kill -9 $$' && \
+ atf_fail "not-signal:kill matched kill -9"
+ atf-check -s not-signal:kill -x 'kill -1 $$' || \
+ atf_fail "not-signal:kill did not match kill -1"
+
+ h_fail 'true' -s signal
+ h_fail 'false' -s signal
+}
+
+atf_test_case xflag
+xflag_head()
+{
+ atf_set "descr" "Tests for the -x option"
+}
+xflag_body()
+{
+ atf-check -s ne:0 -o ignore -e ignore "echo foo 2>&1" || \
+ atf_fail "Shell command succeeded without -x"
+
+ atf-check -e inline:"foo\n" -x "echo foo 1>&2" || \
+ atf_fail "Cannot run command with -x"
+
+ atf-check -o inline:"foo\n" -x echo foo || \
+ atf_fail "Using -x does not respect all provided arguments"
+}
+
+atf_test_case oflag_empty
+oflag_empty_head()
+{
+ atf_set "descr" "Tests for the -o option using the 'empty' argument"
+ atf_set "use.fs" "true"
+}
+oflag_empty_body()
+{
+ h_pass "true" -o empty
+ h_fail "echo foo" -o empty
+}
+
+atf_test_case oflag_ignore
+oflag_ignore_head()
+{
+ atf_set "descr" "Tests for the -o option using the 'ignore' argument"
+ atf_set "use.fs" "true"
+}
+oflag_ignore_body()
+{
+ h_pass "true" -o ignore
+ h_pass "echo foo" -o ignore
+}
+
+atf_test_case oflag_file
+oflag_file_head()
+{
+ atf_set "descr" "Tests for the -o option using the 'file:' argument"
+ atf_set "use.fs" "true"
+}
+oflag_file_body()
+{
+ touch empty
+ h_pass "true" -o file:empty
+
+ echo foo >text
+ h_pass "echo foo" -o file:text
+ h_fail "echo bar" -o file:text
+
+ dd if=/dev/urandom of=bin bs=1k count=10
+ h_pass "cat bin" -o file:bin
+}
+
+atf_test_case oflag_inline
+oflag_inline_head()
+{
+ atf_set "descr" "Tests for the -o option using the 'inline:' argument"
+ atf_set "use.fs" "true"
+}
+oflag_inline_body()
+{
+ h_pass "true" -o inline:
+ h_pass "echo foo bar" -o inline:"foo bar\n"
+ h_pass "printf 'foo bar'" -o inline:"foo bar"
+ h_pass "printf '\t\n\t\n'" -o inline:"\t\n\t\n"
+ # XXX Ugly hack to workaround the lack of \e in FreeBSD. Look for a
+ # nicer solution...
+ case $(uname) in
+ FreeBSD)
+ h_pass "printf '\a\b\f\n\r\t\v'" -o inline:"\a\b\f\n\r\t\v"
+ ;;
+ *)
+ h_pass "printf '\a\b\e\f\n\r\t\v'" -o inline:"\a\b\e\f\n\r\t\v"
+ ;;
+ esac
+ h_pass "printf '\011\022\033\012'" -o inline:"\011\022\033\012"
+
+ h_fail "echo foo bar" -o inline:"foo bar"
+ h_fail "echo -n foo bar" -o inline:"foo bar\n"
+}
+
+atf_test_case oflag_match
+oflag_match_head()
+{
+ atf_set "descr" "Tests for the -o option using the 'match:' argument"
+ atf_set "use.fs" "true"
+}
+oflag_match_body()
+{
+ h_pass "echo line1; echo foo bar" -o "match:^foo"
+ h_pass "echo foo bar" -o "match:o b"
+ h_fail "echo foo bar" -o "match:baz"
+ h_fail "echo foo bar" -o "match:^bar"
+}
+
+atf_test_case oflag_save
+oflag_save_head()
+{
+ atf_set "descr" "Tests for the -o option using the 'save:' argument"
+ atf_set "use.fs" "true"
+}
+oflag_save_body()
+{
+ h_pass "echo foo" -o save:out
+ echo foo >exp
+ cmp -s out exp || atf_fail "Saved output does not match expected results"
+}
+
+atf_test_case oflag_multiple
+oflag_multiple_head()
+{
+ atf_set "descr" "Tests for multiple occurrences of the -o option"
+ atf_set "use.fs" "true"
+}
+oflag_multiple_body()
+{
+ h_pass "echo foo bar" -o match:foo -o match:bar
+ h_pass "echo foo; echo bar" -o match:foo -o match:bar
+ h_fail "echo foo baz" -o match:bar -o match:foo
+ h_fail "echo foo; echo baz" -o match:bar -o match:foo
+}
+
+atf_test_case oflag_negated
+oflag_negated_head()
+{
+ atf_set "descr" "Tests for negated occurrences of the -o option"
+ atf_set "use.fs" "true"
+}
+oflag_negated_body()
+{
+ h_fail "echo foo" -o empty
+ h_pass "echo foo" -o not-empty
+
+ h_pass "echo foo bar" -o match:foo
+ h_fail "echo foo bar" -o not-match:foo
+}
+
+atf_test_case eflag_empty
+eflag_empty_head()
+{
+ atf_set "descr" "Tests for the -e option using the 'empty' argument"
+ atf_set "use.fs" "true"
+}
+eflag_empty_body()
+{
+ h_pass "true 1>&2" -e empty
+ h_fail "echo foo 1>&2" -e empty
+}
+
+atf_test_case eflag_ignore
+eflag_ignore_head()
+{
+ atf_set "descr" "Tests for the -e option using the 'ignore' argument"
+ atf_set "use.fs" "true"
+}
+eflag_ignore_body()
+{
+ h_pass "true 1>&2" -e ignore
+ h_pass "echo foo 1>&2" -e ignore
+}
+
+atf_test_case eflag_file
+eflag_file_head()
+{
+ atf_set "descr" "Tests for the -e option using the 'file:' argument"
+ atf_set "use.fs" "true"
+}
+eflag_file_body()
+{
+ touch empty
+ h_pass "true 1>&2" -e file:empty
+
+ echo foo >text
+ h_pass "echo foo 1>&2" -e file:text
+ h_fail "echo bar 1>&2" -e file:text
+
+ dd if=/dev/urandom of=bin bs=1k count=10
+ h_pass "cat bin 1>&2" -e file:bin
+}
+
+atf_test_case eflag_inline
+eflag_inline_head()
+{
+ atf_set "descr" "Tests for the -e option using the 'inline:' argument"
+ atf_set "use.fs" "true"
+}
+eflag_inline_body()
+{
+ h_pass "true 1>&2" -e inline:
+ h_pass "echo foo bar 1>&2" -e inline:"foo bar\n"
+ h_pass "printf 'foo bar' 1>&2" -e inline:"foo bar"
+ h_pass "printf '\t\n\t\n' 1>&2" -e inline:"\t\n\t\n"
+ # XXX Ugly hack to workaround the lack of \e in FreeBSD. Look for a
+ # nicer solution...
+ case $(uname) in
+ FreeBSD)
+ h_pass "printf '\a\b\f\n\r\t\v' 1>&2" -e inline:"\a\b\f\n\r\t\v"
+ ;;
+ *)
+ h_pass "printf '\a\b\e\f\n\r\t\v' 1>&2" -e inline:"\a\b\e\f\n\r\t\v"
+ ;;
+ esac
+ h_pass "printf '\011\022\033\012' 1>&2" -e inline:"\011\022\033\012"
+
+ h_fail "echo foo bar 1>&2" -e inline:"foo bar"
+ h_fail "echo -n foo bar 1>&2" -e inline:"foo bar\n"
+}
+
+atf_test_case eflag_save
+eflag_save_head()
+{
+ atf_set "descr" "Tests for the -e option using the 'save:' argument"
+ atf_set "use.fs" "true"
+}
+eflag_save_body()
+{
+ h_pass "echo foo 1>&2" -e save:out
+ echo foo >exp
+ cmp -s out exp || atf_fail "Saved output does not match expected results"
+}
+
+atf_test_case eflag_match
+eflag_match_head()
+{
+ atf_set "descr" "Tests for the -e option using the 'match:' argument"
+ atf_set "use.fs" "true"
+}
+eflag_match_body()
+{
+ h_pass "echo line1 1>&2; echo foo bar 1>&2" -e "match:^foo"
+ h_pass "echo foo bar 1>&2" -e "match:o b"
+ h_fail "echo foo bar 1>&2" -e "match:baz"
+ h_fail "echo foo bar 1>&2" -e "match:^bar"
+}
+
+atf_test_case eflag_multiple
+eflag_multiple_head()
+{
+ atf_set "descr" "Tests for multiple occurrences of the -e option"
+ atf_set "use.fs" "true"
+}
+eflag_multiple_body()
+{
+ h_pass "echo foo bar 1>&2" -e match:foo -e match:bar
+ h_pass "echo foo 1>&2; echo bar 1>&2" -e match:foo -e match:bar
+ h_fail "echo foo baz 1>&2" -e match:bar -e match:foo
+ h_fail "echo foo 1>&2; echo baz 1>&2" -e match:bar -e match:foo
+}
+
+atf_test_case eflag_negated
+eflag_negated_head()
+{
+ atf_set "descr" "Tests for negated occurrences of the -e option"
+ atf_set "use.fs" "true"
+}
+eflag_negated_body()
+{
+ h_fail "echo foo 1>&2" -e empty
+ h_pass "echo foo 1>&2" -e not-empty
+
+ h_pass "echo foo bar 1>&2" -e match:foo
+ h_fail "echo foo bar 1>&2" -e not-match:foo
+}
+
+atf_test_case invalid_umask
+invalid_umask_head()
+{
+ atf_set "descr" "Tests for a correct error condition if the umask is" \
+ "too restrictive"
+ atf_set "use.fs" "true"
+}
+invalid_umask_body()
+{
+ umask 0222
+ atf-check false 2>stderr && \
+ atf_fail "atf-check returned 0 but it should have failed"
+ cat stderr
+ grep 'temporary.*current umask.*0222' stderr >/dev/null || \
+ atf_fail "atf-check did not report an error related to the" \
+ "current umask"
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case sflag_eq_ne
+ atf_add_test_case sflag_exit
+ atf_add_test_case sflag_ignore
+ atf_add_test_case sflag_signal
+
+ atf_add_test_case xflag
+
+ atf_add_test_case oflag_empty
+ atf_add_test_case oflag_ignore
+ atf_add_test_case oflag_file
+ atf_add_test_case oflag_inline
+ atf_add_test_case oflag_match
+ atf_add_test_case oflag_save
+ atf_add_test_case oflag_multiple
+ atf_add_test_case oflag_negated
+
+ atf_add_test_case eflag_empty
+ atf_add_test_case eflag_ignore
+ atf_add_test_case eflag_file
+ atf_add_test_case eflag_inline
+ atf_add_test_case eflag_match
+ atf_add_test_case eflag_save
+ atf_add_test_case eflag_multiple
+ atf_add_test_case eflag_negated
+
+ atf_add_test_case invalid_umask
+}
+
+# vim: syntax=sh:expandtab:shiftwidth=4:softtabstop=4
diff --git a/external/bsd/atf/dist/atf-config/Atffile b/external/bsd/atf/dist/atf-config/Atffile
new file mode 100644
index 00000000000..146211e000d
--- /dev/null
+++ b/external/bsd/atf/dist/atf-config/Atffile
@@ -0,0 +1,5 @@
+Content-Type: application/X-atf-atffile; version="1"
+
+prop: test-suite = atf
+
+tp-glob: *_test
diff --git a/external/bsd/atf/dist/atf-config/atf-config.1 b/external/bsd/atf/dist/atf-config/atf-config.1
index abdbe68d846..1b29552f84e 100644
--- a/external/bsd/atf/dist/atf-config/atf-config.1
+++ b/external/bsd/atf/dist/atf-config/atf-config.1
@@ -1,7 +1,7 @@
.\"
.\" Automated Testing Framework (atf)
.\"
-.\" Copyright (c) 2007, 2008, 2009 The NetBSD Foundation, Inc.
+.\" Copyright (c) 2007, 2008, 2009, 2010 The NetBSD Foundation, Inc.
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
@@ -26,7 +26,7 @@
.\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
.\" IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd March 14, 2009
+.Dd June 18, 2010
.Dt ATF-CONFIG 1
.Os
.Sh NAME
@@ -103,9 +103,6 @@ files for ATF.
The path to the directory that contains the ATF header files.
.It Va atf_libdir
The path to the directory that contains the ATF libraries.
-.It Va atf_libexecdir
-The path to the directory that contains the auxiliary utilities of ATF,
-used internally by the public tools.
.It Va atf_machine
The machine type name detected by ATF.
This should not be tunable but is provided for symmetry with
@@ -164,9 +161,6 @@ Overrides the built-in value of
.It Ev ATF_LIBDIR
Overrides the built-in value of
.Va atf_libdir .
-.It Ev ATF_LIBEXECDIR
-Overrides the built-in value of
-.Va atf_libexecdir .
.It Ev ATF_MACHINE
Overrides the built-in value of
.Va atf_machine .
diff --git a/external/bsd/atf/dist/atf-config/integration_test.sh b/external/bsd/atf/dist/atf-config/integration_test.sh
new file mode 100644
index 00000000000..834a97288db
--- /dev/null
+++ b/external/bsd/atf/dist/atf-config/integration_test.sh
@@ -0,0 +1,219 @@
+#
+# Automated Testing Framework (atf)
+#
+# Copyright (c) 2007, 2008, 2009, 2010 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
+# CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+all_vars="atf_arch \
+ atf_build_cc \
+ atf_build_cflags \
+ atf_build_cpp \
+ atf_build_cppflags \
+ atf_build_cxx \
+ atf_build_cxxflags \
+ atf_confdir \
+ atf_includedir \
+ atf_libdir \
+ atf_machine \
+ atf_m4 \
+ atf_pkgdatadir \
+ atf_shell \
+ atf_workdir"
+all_vars_no=15
+
+atf_test_case list_all
+list_all_head()
+{
+ atf_set "descr" "Tests that at atf-config prints all expected" \
+ "variables, and not more"
+ atf_set "use.fs" "true"
+}
+list_all_body()
+{
+ atf_check -s eq:0 -o save:stdout -e empty atf-config
+ atf_check -s eq:0 -o empty -e empty \
+ test "$(wc -l stdout | awk '{ print $1 }')" = "${all_vars_no}"
+ for v in ${all_vars}; do
+ atf_check -s eq:0 -o ignore -e empty grep "${v}" stdout
+ done
+}
+
+atf_test_case query_one
+query_one_head()
+{
+ atf_set "descr" "Tests that querying a single variable works"
+ atf_set "use.fs" "true"
+}
+query_one_body()
+{
+ for v in ${all_vars}; do
+ atf_check -s eq:0 -o save:stdout -o match:"${v}" -e empty \
+ atf-config "${v}"
+ atf_check -s eq:0 -o empty -e empty \
+ test "$(wc -l stdout | awk '{ print $1 }')" = 1
+ done
+}
+
+atf_test_case query_one_terse
+query_one_terse_head()
+{
+ atf_set "descr" "Tests that querying a single variable in terse mode" \
+ "works"
+ atf_set "use.fs" "true"
+}
+query_one_terse_body()
+{
+ for v in ${all_vars}; do
+ atf_check -s eq:0 -o save:stdout -o match:"${v}" -e empty \
+ atf-config "${v}"
+ atf_check -s eq:0 -o empty -e empty \
+ test "$(wc -l stdout | awk '{ print $1 }')" = 1
+ atf_check -s eq:0 -o save:stdout -e empty cut -d ' ' -f 3- stdout
+ atf_check -s eq:0 -o empty -e empty mv stdout expout
+ atf_check -s eq:0 -o file:expout -e empty atf-config -t "${v}"
+ done
+}
+
+atf_test_case query_multiple
+query_multiple_head()
+{
+ atf_set "descr" "Tests that querying multiple variables works"
+ atf_set "use.fs" "true"
+}
+query_multiple_body()
+{
+ atf_check -s eq:0 -o save:stdout -o match:'atf_includedir' \
+ -o match:'atf_shell' -e empty atf-config atf_includedir atf_shell
+ atf_check -s eq:0 -o empty -e empty \
+ test "$(wc -l stdout | awk '{ print $1 }')" = 2
+}
+
+atf_test_case query_unknown
+query_unknown_head()
+{
+ atf_set "descr" "Tests that querying an unknown variable delivers" \
+ "the correct error"
+ atf_set "use.fs" "true"
+}
+query_unknown_body()
+{
+ atf_check -s eq:1 -o empty -e match:'Unknown variable.*non_existent' \
+ atf-config non_existent
+}
+
+atf_test_case query_mixture
+query_mixture_head()
+{
+ atf_set "descr" "Tests that querying a known and an unknown variable" \
+ "delivers the correct error"
+ atf_set "use.fs" "true"
+}
+query_mixture_body()
+{
+ for v in ${all_vars}; do
+ atf_check -s eq:1 -o empty -e match:'Unknown variable.*non_existent' \
+ atf-config "${v}" non_existent
+ atf_check -s eq:1 -o empty -e match:'Unknown variable.*non_existent' \
+ atf-config non_existent "${v}"
+ done
+}
+
+atf_test_case override_env
+override_env_head()
+{
+ atf_set "descr" "Tests that build-time variables can be overriden" \
+ "through their corresponding environment variables"
+ atf_set "use.fs" "true"
+}
+override_env_body()
+{
+ for v in ${all_vars}; do
+ V=$(echo ${v} | tr '[a-z]' '[A-Z]')
+ atf_check -s eq:0 -o save:stdout -e empty -x "${V}=testval atf-config"
+ atf_check -s eq:0 -o empty -e empty mv stdout all
+
+ atf_check -s eq:0 -o save:stdout -e empty grep "^${v} : " all
+ atf_check -s eq:0 -o empty -e empty mv stdout affected
+ atf_check -s eq:0 -o save:stdout -e empty grep -v "^${v} : " all
+ atf_check -s eq:0 -o empty -e empty mv stdout unaffected
+
+ atf_check -s eq:0 -o empty -e empty \
+ test "$(wc -l affected | awk '{ print $1 }')" = 1
+ atf_check -s eq:0 -o empty -e empty \
+ test "$(wc -l unaffected | awk '{ print $1 }')" = \
+ "$((${all_vars_no} -1))"
+
+ atf_check -s eq:0 -o ignore -e empty grep "^${v} : testval$" affected
+ atf_check -s eq:1 -o empty -e empty grep ' : testval$' unaffected
+ done
+}
+
+# XXX: This does not seem to belong here...
+atf_test_case arch
+arch_head()
+{
+ atf_set "descr" "Tests that the current value of atf_arch is correct" \
+ "for the corresponding atf_machine"
+}
+arch_body()
+{
+ atf_check -s eq:0 -o save:stdout -e empty atf-config -t atf_arch
+ arch=$(cat stdout)
+ atf_check -s eq:0 -o save:stdout -e empty atf-config -t atf_machine
+ machine=$(cat stdout)
+ echo "Machine type ${machine}, architecture ${arch}"
+
+ case ${machine} in
+ i386|i486|i586|i686)
+ exp_arch=i386
+ ;;
+ x86_64)
+ exp_arch=amd64
+ ;;
+ *)
+ exp_arch=${machine}
+ esac
+ echo "Expected architecture ${exp_arch}"
+
+ atf_check_equal ${arch} ${exp_arch}
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case list_all
+
+ atf_add_test_case query_one
+ atf_add_test_case query_one_terse
+ atf_add_test_case query_multiple
+ atf_add_test_case query_unknown
+ atf_add_test_case query_mixture
+
+ atf_add_test_case override_env
+
+ atf_add_test_case arch
+}
+
+# vim: syntax=sh:expandtab:shiftwidth=4:softtabstop=4
diff --git a/external/bsd/atf/dist/atf-report/Atffile b/external/bsd/atf/dist/atf-report/Atffile
new file mode 100644
index 00000000000..146211e000d
--- /dev/null
+++ b/external/bsd/atf/dist/atf-report/Atffile
@@ -0,0 +1,5 @@
+Content-Type: application/X-atf-atffile; version="1"
+
+prop: test-suite = atf
+
+tp-glob: *_test
diff --git a/external/bsd/atf/dist/atf-report/fail_helper.cpp b/external/bsd/atf/dist/atf-report/fail_helper.cpp
new file mode 100644
index 00000000000..601753e4286
--- /dev/null
+++ b/external/bsd/atf/dist/atf-report/fail_helper.cpp
@@ -0,0 +1,45 @@
+//
+// Automated Testing Framework (atf)
+//
+// Copyright (c) 2007, 2008 The NetBSD Foundation, Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
+// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#include "atf-c++/macros.hpp"
+
+ATF_TEST_CASE(main);
+ATF_TEST_CASE_HEAD(main)
+{
+ set_md_var("descr", "Helper test case that always fails");
+}
+ATF_TEST_CASE_BODY(main)
+{
+ atf_tc_fail("This always fails");
+}
+
+ATF_INIT_TEST_CASES(tcs)
+{
+ ATF_ADD_TEST_CASE(tcs, main);
+}
diff --git a/external/bsd/atf/dist/atf-report/integration_test.sh b/external/bsd/atf/dist/atf-report/integration_test.sh
new file mode 100644
index 00000000000..ebd5befb10d
--- /dev/null
+++ b/external/bsd/atf/dist/atf-report/integration_test.sh
@@ -0,0 +1,427 @@
+#
+# Automated Testing Framework (atf)
+#
+# Copyright (c) 2007, 2008, 2009, 2010 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
+# CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+create_helpers()
+{
+ mkdir dir1
+ cp $(atf_get_srcdir)/pass_helper dir1/tp1
+ cp $(atf_get_srcdir)/fail_helper dir1/tp2
+ cp $(atf_get_srcdir)/pass_helper tp3
+ cp $(atf_get_srcdir)/fail_helper tp4
+
+ cat >tp5 <<EOF
+#! $(atf-config -t atf_shell)
+echo foo
+EOF
+ chmod +x tp5
+
+ cat >Atffile <<EOF
+Content-Type: application/X-atf-atffile; version="1"
+
+prop: test-suite = atf
+
+tp: dir1
+tp: tp3
+tp: tp4
+tp: tp5
+EOF
+
+ cat >dir1/Atffile <<EOF
+Content-Type: application/X-atf-atffile; version="1"
+
+prop: test-suite = atf
+
+tp: tp1
+tp: tp2
+EOF
+}
+
+run_helpers()
+{
+ mkdir etc
+ cat >etc/atf-run.hooks <<EOF
+#! $(atf-config -t atf_shell)
+
+info_start_hook()
+{
+ atf_tps_writer_info "startinfo" "A value"
+}
+
+info_end_hook()
+{
+ atf_tps_writer_info "endinfo" "Another value"
+}
+EOF
+ echo "Using atf-run to run helpers"
+ ATF_CONFDIR=$(pwd)/etc atf-run >tps.out 2>/dev/null
+ rm -rf etc
+}
+
+atf_test_case default
+default_head()
+{
+ atf_set "descr" "Checks that the default output uses the ticker" \
+ "format"
+ atf_set "use.fs" "true"
+}
+default_body()
+{
+ create_helpers
+ run_helpers
+
+ # Check that the default output uses the ticker format.
+ atf_check -s eq:0 -o match:'test cases' -o match:'Failed test cases' \
+ -o match:'Summary for' -e empty -x 'atf-report <tps.out'
+}
+
+# XXX The test for all expect_ values should be intermixed with the other
+# tests. However, to do that, we need to migrate to using C helpers for
+# simplicity in raising signals...
+atf_test_case expect
+expect_head()
+{
+ atf_set "use.fs" "true"
+}
+expect_body()
+{
+ ln -s "$(atf_get_srcdir)/../atf-run/expect_helpers" .
+ cat >Atffile <<EOF
+Content-Type: application/X-atf-atffile; version="1"
+
+prop: test-suite = atf
+
+tp: expect_helpers
+EOF
+ run_helpers
+
+# NO_CHECK_STYLE_BEGIN
+ cat >expout <<EOF
+tc, expect_helpers, death_and_exit, expected_death, Exit case
+tc, expect_helpers, death_and_signal, expected_death, Signal case
+tc, expect_helpers, death_but_pass, failed, Test case was expected to terminate abruptly but it continued execution
+tc, expect_helpers, exit_any_and_exit, expected_exit, Call will exit
+tc, expect_helpers, exit_but_pass, failed, Test case was expected to exit cleanly but it continued execution
+tc, expect_helpers, exit_code_and_exit, expected_exit, Call will exit
+tc, expect_helpers, fail_and_fail_check, expected_failure, And fail again: 2 checks failed as expected; see output for more details
+tc, expect_helpers, fail_and_fail_requirement, expected_failure, Fail reason: The failure
+tc, expect_helpers, fail_but_pass, failed, Test case was expecting a failure but none were raised
+tc, expect_helpers, pass_and_pass, passed
+tc, expect_helpers, pass_but_fail_check, failed, 1 checks failed; see output for more details
+tc, expect_helpers, pass_but_fail_requirement, failed, Some reason
+tc, expect_helpers, signal_any_and_signal, expected_signal, Call will signal
+tc, expect_helpers, signal_but_pass, failed, Test case was expected to receive a termination signal but it continued execution
+tc, expect_helpers, signal_no_and_signal, expected_signal, Call will signal
+tc, expect_helpers, timeout_and_hang, expected_timeout, Will overrun
+tc, expect_helpers, timeout_but_pass, failed, Test case was expected to hang but it continued execution
+tp, expect_helpers, failed
+EOF
+# NO_CHECK_STYLE_END
+ atf_check -s eq:0 -o file:expout -e empty -x "atf-report -o csv:- <tps.out"
+
+# NO_CHECK_STYLE_BEGIN
+ cat >expout <<EOF
+expect_helpers (1/1): 17 test cases
+ death_and_exit: Expected failure: Exit case
+ death_and_signal: Expected failure: Signal case
+ death_but_pass: Failed: Test case was expected to terminate abruptly but it continued execution
+ exit_any_and_exit: Expected failure: Call will exit
+ exit_but_pass: Failed: Test case was expected to exit cleanly but it continued execution
+ exit_code_and_exit: Expected failure: Call will exit
+ fail_and_fail_check: Expected failure: And fail again: 2 checks failed as expected; see output for more details
+ fail_and_fail_requirement: Expected failure: Fail reason: The failure
+ fail_but_pass: Failed: Test case was expecting a failure but none were raised
+ pass_and_pass: Passed.
+ pass_but_fail_check: Failed: 1 checks failed; see output for more details
+ pass_but_fail_requirement: Failed: Some reason
+ signal_any_and_signal: Expected failure: Call will signal
+ signal_but_pass: Failed: Test case was expected to receive a termination signal but it continued execution
+ signal_no_and_signal: Expected failure: Call will signal
+ timeout_and_hang: Expected failure: Will overrun
+ timeout_but_pass: Failed: Test case was expected to hang but it continued execution
+
+Test cases for known bugs:
+ expect_helpers:death_and_exit, expect_helpers:death_and_signal, expect_helpers:exit_any_and_exit, expect_helpers:exit_code_and_exit, expect_helpers:fail_and_fail_check, expect_helpers:fail_and_fail_requirement, expect_helpers:signal_any_and_signal, expect_helpers:signal_no_and_signal, expect_helpers:timeout_and_hang
+
+Failed test cases:
+ expect_helpers:death_but_pass, expect_helpers:exit_but_pass, expect_helpers:fail_but_pass, expect_helpers:pass_but_fail_check, expect_helpers:pass_but_fail_requirement, expect_helpers:signal_but_pass, expect_helpers:timeout_but_pass
+
+Summary for 1 test programs:
+ 1 passed test cases.
+ 7 failed test cases.
+ 9 expected failed test cases.
+ 0 skipped test cases.
+EOF
+# NO_CHECK_STYLE_END
+ atf_check -s eq:0 -o file:expout -e empty -x \
+ "atf-report -o ticker:- <tps.out"
+
+ # Just ensure that this does not crash for now...
+ atf_check -s eq:0 -o ignore -e empty -x "atf-report -o xml:- <tps.out"
+}
+
+atf_test_case oflag
+oflag_head()
+{
+ atf_set "descr" "Checks that the -o flag works"
+ atf_set "use.fs" "true"
+}
+oflag_body()
+{
+ create_helpers
+ run_helpers
+
+ # Get the default output.
+ atf_check -s eq:0 -o save:stdout -e empty -x 'atf-report <tps.out'
+ mv stdout defout
+
+ # Check that changing the stdout output works.
+ atf_check -s eq:0 -o save:stdout -e empty -x 'atf-report -o csv:- <tps.out'
+ atf_check -s eq:1 -o empty -e empty cmp -s defout stdout
+ cp stdout expcsv
+
+ # Check that sending the output to a file does not write to stdout.
+ atf_check -s eq:0 -o empty -e empty -x 'atf-report -o csv:fmt.out <tps.out'
+ atf_check -s eq:0 -o empty -e empty cmp -s expcsv fmt.out
+ rm -f fmt.out
+
+ # Check that defining two outputs using the same format works.
+ atf_check -s eq:0 -o empty -e empty -x \
+ 'atf-report -o csv:fmt.out -o csv:fmt2.out <tps.out'
+ atf_check -s eq:0 -o empty -e empty cmp -s expcsv fmt.out
+ atf_check -s eq:0 -o empty -e empty cmp -s fmt.out fmt2.out
+ rm -f fmt.out fmt2.out
+
+ # Check that defining two outputs using different formats works.
+ atf_check -s eq:0 -o empty -e empty -x \
+ 'atf-report -o csv:fmt.out -o ticker:fmt2.out <tps.out'
+ atf_check -s eq:0 -o empty -e empty cmp -s expcsv fmt.out
+ atf_check -s eq:1 -o empty -e empty cmp -s fmt.out fmt2.out
+ atf_check -s eq:0 -o ignore -e empty grep "test cases" fmt2.out
+ atf_check -s eq:0 -o ignore -e empty grep "Failed test cases" fmt2.out
+ atf_check -s eq:0 -o ignore -e empty grep "Summary for" fmt2.out
+ rm -f fmt.out fmt2.out
+
+ # Check that defining two outputs over the same file does not work.
+ atf_check -s eq:1 -o empty -e match:'more than once' -x \
+ 'atf-report -o csv:fmt.out -o ticker:fmt.out <tps.out'
+ rm -f fmt.out
+
+ # Check that defining two outputs over stdout (but using different
+ # paths) does not work.
+ atf_check -s eq:1 -o empty -e match:'more than once' -x \
+ 'atf-report -o csv:- -o ticker:/dev/stdout <tps.out'
+ rm -f fmt.out
+}
+
+atf_test_case output_csv
+output_csv_head()
+{
+ atf_set "descr" "Checks the CSV output format"
+ atf_set "use.fs" "true"
+}
+output_csv_body()
+{
+ create_helpers
+ run_helpers
+
+# NO_CHECK_STYLE_BEGIN
+ cat >expout <<EOF
+tc, dir1/tp1, main, passed
+tp, dir1/tp1, passed
+tc, dir1/tp2, main, failed, This always fails
+tp, dir1/tp2, failed
+tc, tp3, main, passed
+tp, tp3, passed
+tc, tp4, main, failed, This always fails
+tp, tp4, failed
+tp, tp5, bogus, Invalid format for test case list: 1: Unexpected token \`<<NEWLINE>>'; expected \`:'
+EOF
+# NO_CHECK_STYLE_END
+
+ atf_check -s eq:0 -o file:expout -e empty -x 'atf-report -o csv:- <tps.out'
+}
+
+atf_test_case output_ticker
+output_ticker_head()
+{
+ atf_set "descr" "Checks the ticker output format"
+ atf_set "use.fs" "true"
+}
+output_ticker_body()
+{
+ create_helpers
+ run_helpers
+
+# NO_CHECK_STYLE_BEGIN
+ cat >expout <<EOF
+dir1/tp1 (1/5): 1 test cases
+ main: Passed.
+
+dir1/tp2 (2/5): 1 test cases
+ main: Failed: This always fails
+
+tp3 (3/5): 1 test cases
+ main: Passed.
+
+tp4 (4/5): 1 test cases
+ main: Failed: This always fails
+
+tp5 (5/5): 0 test cases
+tp5: BOGUS TEST PROGRAM: Cannot trust its results because of \`Invalid format for test case list: 1: Unexpected token \`<<NEWLINE>>'; expected \`:''
+
+Failed (bogus) test programs:
+ tp5
+
+Failed test cases:
+ dir1/tp2:main, tp4:main
+
+Summary for 5 test programs:
+ 2 passed test cases.
+ 2 failed test cases.
+ 0 expected failed test cases.
+ 0 skipped test cases.
+EOF
+
+ atf_check -s eq:0 -o file:expout -e empty -x 'atf-report -o ticker:- <tps.out'
+}
+# NO_CHECK_STYLE_END
+
+atf_test_case output_xml
+output_xml_head()
+{
+ atf_set "descr" "Checks the XML output format"
+ atf_set "use.fs" "true"
+}
+output_xml_body()
+{
+ create_helpers
+ run_helpers
+
+# NO_CHECK_STYLE_BEGIN
+ cat >expout <<EOF
+<?xml version="1.0"?>
+<!DOCTYPE tests-results PUBLIC "-//NetBSD//DTD ATF Tests Results 0.1//EN" "http://www.NetBSD.org/XML/atf/tests-results.dtd">
+
+<tests-results>
+<info class="startinfo">A value</info>
+<tp id="dir1/tp1">
+<tc id="main">
+<passed />
+</tc>
+</tp>
+<tp id="dir1/tp2">
+<tc id="main">
+<failed>This always fails</failed>
+</tc>
+</tp>
+<tp id="tp3">
+<tc id="main">
+<passed />
+</tc>
+</tp>
+<tp id="tp4">
+<tc id="main">
+<failed>This always fails</failed>
+</tc>
+</tp>
+<tp id="tp5">
+<failed>Invalid format for test case list: 1: Unexpected token \`&lt;&lt;NEWLINE&gt;&gt;'; expected \`:'</failed>
+</tp>
+<info class="endinfo">Another value</info>
+</tests-results>
+EOF
+# NO_CHECK_STYLE_END
+
+ atf_check -s eq:0 -o file:expout -e empty -x 'atf-report -o xml:- <tps.out'
+}
+
+atf_test_case output_xml_space
+output_xml_space_head()
+{
+ atf_set "descr" "Checks that the XML output format properly preserves" \
+ "leading and trailing whitespace in stdout and stderr" \
+ "lines"
+ atf_set "use.fs" "true"
+}
+output_xml_space_body()
+{
+ cp $(atf_get_srcdir)/misc_helpers .
+ cat >Atffile <<EOF
+Content-Type: application/X-atf-atffile; version="1"
+
+prop: test-suite = atf
+
+tp: misc_helpers
+EOF
+
+# NO_CHECK_STYLE_BEGIN
+ cat >expout <<EOF
+<?xml version="1.0"?>
+<!DOCTYPE tests-results PUBLIC "-//NetBSD//DTD ATF Tests Results 0.1//EN" "http://www.NetBSD.org/XML/atf/tests-results.dtd">
+
+<tests-results>
+<info class="startinfo">A value</info>
+<tp id="misc_helpers">
+<tc id="diff">
+<so>--- a 2007-11-04 14:00:41.000000000 +0100</so>
+<so>+++ b 2007-11-04 14:00:48.000000000 +0100</so>
+<so>@@ -1,7 +1,7 @@</so>
+<so> This test is meant to simulate a diff.</so>
+<so> Blank space at beginning of context lines must be preserved.</so>
+<so> </so>
+<so>-First original line.</so>
+<so>-Second original line.</so>
+<so>+First modified line.</so>
+<so>+Second modified line.</so>
+<so> </so>
+<so> EOF</so>
+<passed />
+</tc>
+</tp>
+<info class="endinfo">Another value</info>
+</tests-results>
+EOF
+# NO_CHECK_STYLE_END
+
+ run_helpers
+ atf_check -s eq:0 -o file:expout -e empty -x 'atf-report -o xml:- <tps.out'
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case default
+ atf_add_test_case expect
+ atf_add_test_case oflag
+ atf_add_test_case output_csv
+ atf_add_test_case output_ticker
+ atf_add_test_case output_xml
+ atf_add_test_case output_xml_space
+}
+
+# vim: syntax=sh:expandtab:shiftwidth=4:softtabstop=4
diff --git a/external/bsd/atf/dist/atf-report/misc_helpers.cpp b/external/bsd/atf/dist/atf-report/misc_helpers.cpp
new file mode 100644
index 00000000000..0db916b31bb
--- /dev/null
+++ b/external/bsd/atf/dist/atf-report/misc_helpers.cpp
@@ -0,0 +1,68 @@
+//
+// Automated Testing Framework (atf)
+//
+// Copyright (c) 2007, 2008, 2010 The NetBSD Foundation, Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
+// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#include <iostream>
+
+#include "atf-c++/macros.hpp"
+
+// ------------------------------------------------------------------------
+// Helper tests for "t_integration".
+// ------------------------------------------------------------------------
+
+ATF_TEST_CASE(diff);
+ATF_TEST_CASE_HEAD(diff)
+{
+ set_md_var("descr", "Helper test case for the t_integration program");
+}
+ATF_TEST_CASE_BODY(diff)
+{
+ std::cout << "--- a 2007-11-04 14:00:41.000000000 +0100" << std::endl;
+ std::cout << "+++ b 2007-11-04 14:00:48.000000000 +0100" << std::endl;
+ std::cout << "@@ -1,7 +1,7 @@" << std::endl;
+ std::cout << " This test is meant to simulate a diff." << std::endl;
+ std::cout << " Blank space at beginning of context lines must be "
+ "preserved." << std::endl;
+ std::cout << " " << std::endl;
+ std::cout << "-First original line." << std::endl;
+ std::cout << "-Second original line." << std::endl;
+ std::cout << "+First modified line." << std::endl;
+ std::cout << "+Second modified line." << std::endl;
+ std::cout << " " << std::endl;
+ std::cout << " EOF" << std::endl;
+}
+
+// ------------------------------------------------------------------------
+// Main.
+// ------------------------------------------------------------------------
+
+ATF_INIT_TEST_CASES(tcs)
+{
+ // Add helper tests for t_integration.
+ ATF_ADD_TEST_CASE(tcs, diff);
+}
diff --git a/external/bsd/atf/dist/atf-report/pass_helper.cpp b/external/bsd/atf/dist/atf-report/pass_helper.cpp
new file mode 100644
index 00000000000..49f1e3217ac
--- /dev/null
+++ b/external/bsd/atf/dist/atf-report/pass_helper.cpp
@@ -0,0 +1,44 @@
+//
+// Automated Testing Framework (atf)
+//
+// Copyright (c) 2007, 2008 The NetBSD Foundation, Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
+// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#include "atf-c++/macros.hpp"
+
+ATF_TEST_CASE(main);
+ATF_TEST_CASE_HEAD(main)
+{
+ set_md_var("descr", "Helper test case that always passes");
+}
+ATF_TEST_CASE_BODY(main)
+{
+}
+
+ATF_INIT_TEST_CASES(tcs)
+{
+ ATF_ADD_TEST_CASE(tcs, main);
+}
diff --git a/external/bsd/atf/dist/atf-report/reader.cpp b/external/bsd/atf/dist/atf-report/reader.cpp
new file mode 100644
index 00000000000..2ab5640fd23
--- /dev/null
+++ b/external/bsd/atf/dist/atf-report/reader.cpp
@@ -0,0 +1,383 @@
+//
+// Automated Testing Framework (atf)
+//
+// Copyright (c) 2007, 2008, 2009, 2010 The NetBSD Foundation, Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
+// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#include <map>
+#include <sstream>
+#include <utility>
+
+#include "atf-c++/parser.hpp"
+#include "atf-c++/sanity.hpp"
+#include "atf-c++/text.hpp"
+
+#include "reader.hpp"
+
+namespace impl = atf::atf_report;
+#define IMPL_NAME "atf::atf_report"
+
+// ------------------------------------------------------------------------
+// Auxiliary functions.
+// ------------------------------------------------------------------------
+
+static
+size_t
+string_to_size_t(const std::string& str)
+{
+ std::istringstream ss(str);
+ size_t s;
+ ss >> s;
+
+ return s;
+}
+
+// ------------------------------------------------------------------------
+// The "atf_tps" auxiliary parser.
+// ------------------------------------------------------------------------
+
+namespace atf_tps {
+
+static const atf::parser::token_type& eof_type = 0;
+static const atf::parser::token_type& nl_type = 1;
+static const atf::parser::token_type& text_type = 2;
+static const atf::parser::token_type& colon_type = 3;
+static const atf::parser::token_type& comma_type = 4;
+static const atf::parser::token_type& tps_count_type = 5;
+static const atf::parser::token_type& tp_start_type = 6;
+static const atf::parser::token_type& tp_end_type = 7;
+static const atf::parser::token_type& tc_start_type = 8;
+static const atf::parser::token_type& tc_so_type = 9;
+static const atf::parser::token_type& tc_se_type = 10;
+static const atf::parser::token_type& tc_end_type = 11;
+static const atf::parser::token_type& passed_type = 12;
+static const atf::parser::token_type& failed_type = 13;
+static const atf::parser::token_type& skipped_type = 14;
+static const atf::parser::token_type& info_type = 16;
+static const atf::parser::token_type& expected_death_type = 17;
+static const atf::parser::token_type& expected_exit_type = 18;
+static const atf::parser::token_type& expected_failure_type = 19;
+static const atf::parser::token_type& expected_signal_type = 20;
+static const atf::parser::token_type& expected_timeout_type = 21;
+
+class tokenizer : public atf::parser::tokenizer< std::istream > {
+public:
+ tokenizer(std::istream& is, size_t curline) :
+ atf::parser::tokenizer< std::istream >
+ (is, true, eof_type, nl_type, text_type, curline)
+ {
+ add_delim(':', colon_type);
+ add_delim(',', comma_type);
+ add_keyword("tps-count", tps_count_type);
+ add_keyword("tp-start", tp_start_type);
+ add_keyword("tp-end", tp_end_type);
+ add_keyword("tc-start", tc_start_type);
+ add_keyword("tc-so", tc_so_type);
+ add_keyword("tc-se", tc_se_type);
+ add_keyword("tc-end", tc_end_type);
+ add_keyword("passed", passed_type);
+ add_keyword("failed", failed_type);
+ add_keyword("skipped", skipped_type);
+ add_keyword("info", info_type);
+ add_keyword("expected_death", expected_death_type);
+ add_keyword("expected_exit", expected_exit_type);
+ add_keyword("expected_failure", expected_failure_type);
+ add_keyword("expected_signal", expected_signal_type);
+ add_keyword("expected_timeout", expected_timeout_type);
+ }
+};
+
+} // namespace atf_tps
+
+// ------------------------------------------------------------------------
+// The "atf_tps_reader" class.
+// ------------------------------------------------------------------------
+
+impl::atf_tps_reader::atf_tps_reader(std::istream& is) :
+ m_is(is)
+{
+}
+
+impl::atf_tps_reader::~atf_tps_reader(void)
+{
+}
+
+void
+impl::atf_tps_reader::got_info(const std::string& what,
+ const std::string& val)
+{
+}
+
+void
+impl::atf_tps_reader::got_ntps(size_t ntps)
+{
+}
+
+void
+impl::atf_tps_reader::got_tp_start(const std::string& tp, size_t ntcs)
+{
+}
+
+void
+impl::atf_tps_reader::got_tp_end(const std::string& reason)
+{
+}
+
+void
+impl::atf_tps_reader::got_tc_start(const std::string& tcname)
+{
+}
+
+void
+impl::atf_tps_reader::got_tc_stdout_line(const std::string& line)
+{
+}
+
+void
+impl::atf_tps_reader::got_tc_stderr_line(const std::string& line)
+{
+}
+
+void
+impl::atf_tps_reader::got_tc_end(const std::string& state,
+ const std::string& reason)
+{
+}
+
+void
+impl::atf_tps_reader::got_eof(void)
+{
+}
+
+void
+impl::atf_tps_reader::read_info(void* pptr)
+{
+ using atf::parser::parse_error;
+ using namespace atf_tps;
+
+ atf::parser::parser< tokenizer >& p =
+ *reinterpret_cast< atf::parser::parser< tokenizer >* >
+ (pptr);
+
+ (void)p.expect(colon_type, "`:'");
+
+ atf::parser::token t = p.expect(text_type, "info property name");
+ (void)p.expect(comma_type, "`,'");
+ got_info(t.text(), atf::text::trim(p.rest_of_line()));
+
+ (void)p.expect(nl_type, "new line");
+}
+
+void
+impl::atf_tps_reader::read_tp(void* pptr)
+{
+ using atf::parser::parse_error;
+ using namespace atf_tps;
+
+ atf::parser::parser< tokenizer >& p =
+ *reinterpret_cast< atf::parser::parser< tokenizer >* >
+ (pptr);
+
+ atf::parser::token t = p.expect(tp_start_type,
+ "start of test program");
+
+ t = p.expect(colon_type, "`:'");
+
+ t = p.expect(text_type, "test program name");
+ std::string tpname = t.text();
+
+ t = p.expect(comma_type, "`,'");
+
+ t = p.expect(text_type, "number of test programs");
+ size_t ntcs = string_to_size_t(t.text());
+
+ t = p.expect(nl_type, "new line");
+
+ ATF_PARSER_CALLBACK(p, got_tp_start(tpname, ntcs));
+
+ size_t i = 0;
+ while (p.good() && i < ntcs) {
+ try {
+ read_tc(&p);
+ i++;
+ } catch (const parse_error& pe) {
+ p.add_error(pe);
+ p.reset(nl_type);
+ }
+ }
+ t = p.expect(tp_end_type, "end of test program");
+
+ t = p.expect(colon_type, "`:'");
+
+ t = p.expect(text_type, "test program name");
+ if (t.text() != tpname)
+ throw parse_error(t.lineno(), "Test program name used in "
+ "terminator does not match "
+ "opening");
+
+ t = p.expect(nl_type, comma_type,
+ "new line or comma_type");
+ std::string reason;
+ if (t.type() == comma_type) {
+ reason = text::trim(p.rest_of_line());
+ if (reason.empty())
+ throw parse_error(t.lineno(),
+ "Empty reason for failed test program");
+ t = p.next();
+ }
+
+ ATF_PARSER_CALLBACK(p, got_tp_end(reason));
+}
+
+void
+impl::atf_tps_reader::read_tc(void* pptr)
+{
+ using atf::parser::parse_error;
+ using namespace atf_tps;
+
+ atf::parser::parser< tokenizer >& p =
+ *reinterpret_cast< atf::parser::parser< tokenizer >* >
+ (pptr);
+
+ atf::parser::token t = p.expect(tc_start_type, "start of test case");
+
+ t = p.expect(colon_type, "`:'");
+
+ t = p.expect(text_type, "test case name");
+ std::string tcname = t.text();
+ ATF_PARSER_CALLBACK(p, got_tc_start(tcname));
+
+ t = p.expect(nl_type, "new line");
+
+ t = p.expect(tc_end_type, tc_so_type, tc_se_type,
+ "end of test case or test case's stdout/stderr line");
+ while (t.type() != tc_end_type &&
+ (t.type() == tc_so_type || t.type() == tc_se_type)) {
+ atf::parser::token t2 = t;
+
+ t = p.expect(colon_type, "`:'");
+
+ std::string line = p.rest_of_line();
+
+ if (t2.type() == tc_so_type) {
+ ATF_PARSER_CALLBACK(p, got_tc_stdout_line(line));
+ } else {
+ INV(t2.type() == tc_se_type);
+ ATF_PARSER_CALLBACK(p, got_tc_stderr_line(line));
+ }
+
+ t = p.expect(nl_type, "new line");
+
+ t = p.expect(tc_end_type, tc_so_type, tc_se_type,
+ "end of test case or test case's stdout/stderr line");
+ }
+
+ t = p.expect(colon_type, "`:'");
+
+ t = p.expect(text_type, "test case name");
+ if (t.text() != tcname)
+ throw parse_error(t.lineno(),
+ "Test case name used in terminator does not "
+ "match opening");
+
+ t = p.expect(comma_type, "`,'");
+
+ t = p.expect(expected_death_type, expected_exit_type, expected_failure_type,
+ expected_signal_type, expected_timeout_type, passed_type, failed_type,
+ skipped_type, "expected_{death,exit,failure,signal,timeout}, failed, "
+ "passed or skipped");
+ if (t.type() == passed_type) {
+ ATF_PARSER_CALLBACK(p, got_tc_end("passed", ""));
+ } else {
+ std::string state;
+ if (t.type() == expected_death_type) state = "expected_death";
+ else if (t.type() == expected_exit_type) state = "expected_exit";
+ else if (t.type() == expected_failure_type) state = "expected_failure";
+ else if (t.type() == expected_signal_type) state = "expected_signal";
+ else if (t.type() == expected_timeout_type) state = "expected_timeout";
+ else if (t.type() == failed_type) state = "failed";
+ else if (t.type() == skipped_type) state = "skipped";
+ else UNREACHABLE;
+
+ t = p.expect(comma_type, "`,'");
+ std::string reason = text::trim(p.rest_of_line());
+ if (reason.empty())
+ throw parse_error(t.lineno(), "Empty reason for " + state +
+ " test case result");
+ ATF_PARSER_CALLBACK(p, got_tc_end(state, reason));
+ }
+
+ t = p.expect(nl_type, "new line");
+}
+
+void
+impl::atf_tps_reader::read(void)
+{
+ using atf::parser::parse_error;
+ using namespace atf_tps;
+
+ std::pair< size_t, atf::parser::headers_map > hml =
+ atf::parser::read_headers(m_is, 1);
+ atf::parser::validate_content_type(hml.second, "application/X-atf-tps", 2);
+
+ tokenizer tkz(m_is, hml.first);
+ atf::parser::parser< tokenizer > p(tkz);
+
+ try {
+ atf::parser::token t;
+
+ while ((t = p.expect(tps_count_type, info_type, "tps-count or info "
+ "field")).type() == info_type)
+ read_info(&p);
+
+ t = p.expect(colon_type, "`:'");
+
+ t = p.expect(text_type, "number of test programs");
+ size_t ntps = string_to_size_t(t.text());
+ ATF_PARSER_CALLBACK(p, got_ntps(ntps));
+
+ t = p.expect(nl_type, "new line");
+
+ size_t i = 0;
+ while (p.good() && i < ntps) {
+ try {
+ read_tp(&p);
+ i++;
+ } catch (const parse_error& pe) {
+ p.add_error(pe);
+ p.reset(nl_type);
+ }
+ }
+
+ while ((t = p.expect(eof_type, info_type, "end of stream or info "
+ "field")).type() == info_type)
+ read_info(&p);
+ ATF_PARSER_CALLBACK(p, got_eof());
+ } catch (const parse_error& pe) {
+ p.add_error(pe);
+ p.reset(nl_type);
+ }
+}
diff --git a/external/bsd/atf/dist/atf-report/reader.hpp b/external/bsd/atf/dist/atf-report/reader.hpp
new file mode 100644
index 00000000000..fc6ce473502
--- /dev/null
+++ b/external/bsd/atf/dist/atf-report/reader.hpp
@@ -0,0 +1,86 @@
+//
+// Automated Testing Framework (atf)
+//
+// Copyright (c) 2007, 2008, 2009, 2010 The NetBSD Foundation, Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
+// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#if !defined(_ATF_REPORT_FORMATS_HPP_)
+#define _ATF_REPORT_FORMATS_HPP_
+
+#include <istream>
+#include <string>
+
+#include <atf-c++/tests.hpp>
+
+namespace atf {
+namespace atf_report {
+
+struct test_case_result {
+ enum state_enum {
+ PASSED,
+ FAILED,
+ SKIPPED,
+ };
+ const state_enum state;
+ const std::string& reason;
+
+ test_case_result(const state_enum p_state, const std::string& p_reason) :
+ state(p_state),
+ reason(p_reason)
+ {
+ }
+};
+
+class atf_tps_reader {
+ std::istream& m_is;
+
+ void read_info(void*);
+ void read_tp(void*);
+ void read_tc(void*);
+
+protected:
+ virtual void got_info(const std::string&, const std::string&);
+ virtual void got_ntps(size_t);
+ virtual void got_tp_start(const std::string&, size_t);
+ virtual void got_tp_end(const std::string&);
+
+ virtual void got_tc_start(const std::string&);
+ virtual void got_tc_stdout_line(const std::string&);
+ virtual void got_tc_stderr_line(const std::string&);
+ virtual void got_tc_end(const std::string&, const std::string&);
+ virtual void got_eof(void);
+
+public:
+ atf_tps_reader(std::istream&);
+ virtual ~atf_tps_reader(void);
+
+ void read(void);
+};
+
+} // namespace atf_report
+} // namespace atf
+
+#endif // !defined(_ATF_REPORT_FORMATS_HPP_)
diff --git a/external/bsd/atf/dist/atf-report/reader_test.cpp b/external/bsd/atf/dist/atf-report/reader_test.cpp
new file mode 100644
index 00000000000..5a664e8f2ad
--- /dev/null
+++ b/external/bsd/atf/dist/atf-report/reader_test.cpp
@@ -0,0 +1,943 @@
+//
+// Automated Testing Framework (atf)
+//
+// Copyright (c) 2010 The NetBSD Foundation, Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
+// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#include <iostream>
+#include <sstream>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "atf-c++/macros.hpp"
+#include "atf-c++/parser.hpp"
+#include "atf-c++/sanity.hpp"
+#include "atf-c++/text.hpp"
+
+#include "reader.hpp"
+
+#include "test_helpers.hpp"
+
+namespace impl = atf::atf_report;
+
+class tps_reader : protected impl::atf_tps_reader {
+ void
+ got_info(const std::string& what, const std::string& val)
+ {
+ m_calls.push_back("got_info(" + what + ", " + val + ")");
+ }
+
+ void
+ got_ntps(size_t ntps)
+ {
+ m_calls.push_back("got_ntps(" + atf::text::to_string(ntps) + ")");
+ }
+
+ void
+ got_tp_start(const std::string& tpname, size_t ntcs)
+ {
+ m_calls.push_back("got_tp_start(" + tpname + ", " +
+ atf::text::to_string(ntcs) + ")");
+ }
+
+ void
+ got_tp_end(const std::string& reason)
+ {
+ m_calls.push_back("got_tp_end(" + reason + ")");
+ }
+
+ void
+ got_tc_start(const std::string& tcname)
+ {
+ m_calls.push_back("got_tc_start(" + tcname + ")");
+ }
+
+ void
+ got_tc_end(const std::string& state, const std::string& reason)
+ {
+ const std::string r = state + (reason.empty() ? "" : ", " + reason);
+ m_calls.push_back("got_tc_end(" + r + ")");
+ }
+
+ void
+ got_tc_stdout_line(const std::string& line)
+ {
+ m_calls.push_back("got_tc_stdout_line(" + line + ")");
+ }
+
+ void
+ got_tc_stderr_line(const std::string& line)
+ {
+ m_calls.push_back("got_tc_stderr_line(" + line + ")");
+ }
+
+ void
+ got_eof(void)
+ {
+ m_calls.push_back("got_eof()");
+ }
+
+public:
+ tps_reader(std::istream& is) :
+ impl::atf_tps_reader(is)
+ {
+ }
+
+ void
+ read(void)
+ {
+ atf_tps_reader::read();
+ }
+
+ std::vector< std::string > m_calls;
+};
+
+ATF_TEST_CASE_WITHOUT_HEAD(tps_1);
+ATF_TEST_CASE_BODY(tps_1)
+{
+ const char* input =
+ "Content-Type: application/X-atf-tps; version=\"2\"\n"
+ "\n"
+ "tps-count: 0\n"
+ ;
+
+ const char* exp_calls[] = {
+ "got_ntps(0)",
+ "got_eof()",
+ NULL
+ };
+
+ const char* exp_errors[] = {
+ NULL
+ };
+
+ do_parser_test< tps_reader >(input, exp_calls, exp_errors);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(tps_2);
+ATF_TEST_CASE_BODY(tps_2)
+{
+ const char* input =
+ "Content-Type: application/X-atf-tps; version=\"2\"\n"
+ "\n"
+ "tps-count: 2\n"
+ "tp-start: first-prog, 0\n"
+ "tp-end: first-prog\n"
+ "tp-start: second-prog, 0\n"
+ "tp-end: second-prog, This program failed\n"
+ ;
+
+ const char* exp_calls[] = {
+ "got_ntps(2)",
+ "got_tp_start(first-prog, 0)",
+ "got_tp_end()",
+ "got_tp_start(second-prog, 0)",
+ "got_tp_end(This program failed)",
+ "got_eof()",
+ NULL
+ };
+
+ const char* exp_errors[] = {
+ NULL
+ };
+
+ do_parser_test< tps_reader >(input, exp_calls, exp_errors);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(tps_3);
+ATF_TEST_CASE_BODY(tps_3)
+{
+ const char* input =
+ "Content-Type: application/X-atf-tps; version=\"2\"\n"
+ "\n"
+ "tps-count: 2\n"
+ "tp-start: first-prog, 3\n"
+ "tc-start: first-test\n"
+ "tc-end: first-test, passed\n"
+ "tc-start: second-test\n"
+ "tc-end: second-test, skipped, Testing skipped reason\n"
+ "tc-start: third-test\n"
+ "tc-end: third-test, failed, Testing failed reason\n"
+ "tp-end: first-prog\n"
+ "tp-start: second-prog, 3\n"
+ "tc-start: first-test\n"
+ "tc-so:first stdout line for 1st test\n"
+ "tc-se:first stderr line for 1st test\n"
+ "tc-so:second stdout line for 1st test\n"
+ "tc-se:second stderr line for 1st test\n"
+ "tc-end: first-test, passed\n"
+ "tc-start: second-test\n"
+ "tc-so:first stdout line for 2nd test\n"
+ "tc-se:first stderr line for 2nd test\n"
+ "tc-so:second stdout line for 2nd test\n"
+ "tc-se:second stderr line for 2nd test\n"
+ "tc-end: second-test, skipped, Testing skipped reason\n"
+ "tc-start: third-test\n"
+ "tc-so:first stdout line for 3rd test\n"
+ "tc-se:first stderr line for 3rd test\n"
+ "tc-so:second stdout line for 3rd test\n"
+ "tc-se:second stderr line for 3rd test\n"
+ "tc-end: third-test, failed, Testing failed reason\n"
+ "tp-end: second-prog, This program failed\n"
+ ;
+
+ const char* exp_calls[] = {
+ "got_ntps(2)",
+ "got_tp_start(first-prog, 3)",
+ "got_tc_start(first-test)",
+ "got_tc_end(passed)",
+ "got_tc_start(second-test)",
+ "got_tc_end(skipped, Testing skipped reason)",
+ "got_tc_start(third-test)",
+ "got_tc_end(failed, Testing failed reason)",
+ "got_tp_end()",
+ "got_tp_start(second-prog, 3)",
+ "got_tc_start(first-test)",
+ "got_tc_stdout_line(first stdout line for 1st test)",
+ "got_tc_stderr_line(first stderr line for 1st test)",
+ "got_tc_stdout_line(second stdout line for 1st test)",
+ "got_tc_stderr_line(second stderr line for 1st test)",
+ "got_tc_end(passed)",
+ "got_tc_start(second-test)",
+ "got_tc_stdout_line(first stdout line for 2nd test)",
+ "got_tc_stderr_line(first stderr line for 2nd test)",
+ "got_tc_stdout_line(second stdout line for 2nd test)",
+ "got_tc_stderr_line(second stderr line for 2nd test)",
+ "got_tc_end(skipped, Testing skipped reason)",
+ "got_tc_start(third-test)",
+ "got_tc_stdout_line(first stdout line for 3rd test)",
+ "got_tc_stderr_line(first stderr line for 3rd test)",
+ "got_tc_stdout_line(second stdout line for 3rd test)",
+ "got_tc_stderr_line(second stderr line for 3rd test)",
+ "got_tc_end(failed, Testing failed reason)",
+ "got_tp_end(This program failed)",
+ "got_eof()",
+ NULL
+ };
+
+ const char* exp_errors[] = {
+ NULL
+ };
+
+ do_parser_test< tps_reader >(input, exp_calls, exp_errors);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(tps_4);
+ATF_TEST_CASE_BODY(tps_4)
+{
+ const char* input =
+ "Content-Type: application/X-atf-tps; version=\"2\"\n"
+ "\n"
+ "info: a, foo\n"
+ "info: b, bar\n"
+ "info: c, baz\n"
+ "tps-count: 2\n"
+ "tp-start: first-prog, 3\n"
+ "tc-start: first-test\n"
+ "tc-end: first-test, passed\n"
+ "tc-start: second-test\n"
+ "tc-end: second-test, skipped, Testing skipped reason\n"
+ "tc-start: third-test\n"
+ "tc-end: third-test, failed, Testing failed reason\n"
+ "tp-end: first-prog\n"
+ "tp-start: second-prog, 3\n"
+ "tc-start: first-test\n"
+ "tc-so:first stdout line for 1st test\n"
+ "tc-se:first stderr line for 1st test\n"
+ "tc-so:second stdout line for 1st test\n"
+ "tc-se:second stderr line for 1st test\n"
+ "tc-end: first-test, passed\n"
+ "tc-start: second-test\n"
+ "tc-so:first stdout line for 2nd test\n"
+ "tc-se:first stderr line for 2nd test\n"
+ "tc-so:second stdout line for 2nd test\n"
+ "tc-se:second stderr line for 2nd test\n"
+ "tc-end: second-test, skipped, Testing skipped reason\n"
+ "tc-start: third-test\n"
+ "tc-so:first stdout line for 3rd test\n"
+ "tc-se:first stderr line for 3rd test\n"
+ "tc-so:second stdout line for 3rd test\n"
+ "tc-se:second stderr line for 3rd test\n"
+ "tc-end: third-test, failed, Testing failed reason\n"
+ "tp-end: second-prog, This program failed\n"
+ "info: d, foo\n"
+ "info: e, bar\n"
+ "info: f, baz\n"
+ ;
+
+ const char* exp_calls[] = {
+ "got_info(a, foo)",
+ "got_info(b, bar)",
+ "got_info(c, baz)",
+ "got_ntps(2)",
+ "got_tp_start(first-prog, 3)",
+ "got_tc_start(first-test)",
+ "got_tc_end(passed)",
+ "got_tc_start(second-test)",
+ "got_tc_end(skipped, Testing skipped reason)",
+ "got_tc_start(third-test)",
+ "got_tc_end(failed, Testing failed reason)",
+ "got_tp_end()",
+ "got_tp_start(second-prog, 3)",
+ "got_tc_start(first-test)",
+ "got_tc_stdout_line(first stdout line for 1st test)",
+ "got_tc_stderr_line(first stderr line for 1st test)",
+ "got_tc_stdout_line(second stdout line for 1st test)",
+ "got_tc_stderr_line(second stderr line for 1st test)",
+ "got_tc_end(passed)",
+ "got_tc_start(second-test)",
+ "got_tc_stdout_line(first stdout line for 2nd test)",
+ "got_tc_stderr_line(first stderr line for 2nd test)",
+ "got_tc_stdout_line(second stdout line for 2nd test)",
+ "got_tc_stderr_line(second stderr line for 2nd test)",
+ "got_tc_end(skipped, Testing skipped reason)",
+ "got_tc_start(third-test)",
+ "got_tc_stdout_line(first stdout line for 3rd test)",
+ "got_tc_stderr_line(first stderr line for 3rd test)",
+ "got_tc_stdout_line(second stdout line for 3rd test)",
+ "got_tc_stderr_line(second stderr line for 3rd test)",
+ "got_tc_end(failed, Testing failed reason)",
+ "got_tp_end(This program failed)",
+ "got_info(d, foo)",
+ "got_info(e, bar)",
+ "got_info(f, baz)",
+ "got_eof()",
+ NULL
+ };
+
+ const char* exp_errors[] = {
+ NULL
+ };
+
+ do_parser_test< tps_reader >(input, exp_calls, exp_errors);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(tps_5);
+ATF_TEST_CASE_BODY(tps_5)
+{
+ const char* input =
+ "Content-Type: application/X-atf-tps; version=\"2\"\n"
+ "\n"
+ "tps-count: 1\n"
+ "tp-start: the-prog, 1\n"
+ "tc-start: the-test\n"
+ "tc-so:--- a 2007-11-04 14:00:41.000000000 +0100\n"
+ "tc-so:+++ b 2007-11-04 14:00:48.000000000 +0100\n"
+ "tc-so:@@ -1,7 +1,7 @@\n"
+ "tc-so: This test is meant to simulate a diff.\n"
+ "tc-so: Blank space at beginning of context lines must be preserved.\n"
+ "tc-so: \n"
+ "tc-so:-First original line.\n"
+ "tc-so:-Second original line.\n"
+ "tc-so:+First modified line.\n"
+ "tc-so:+Second modified line.\n"
+ "tc-so: \n"
+ "tc-so: EOF\n"
+ "tc-end: the-test, passed\n"
+ "tp-end: the-prog\n"
+ ;
+
+ // NO_CHECK_STYLE_BEGIN
+ const char* exp_calls[] = {
+ "got_ntps(1)",
+ "got_tp_start(the-prog, 1)",
+ "got_tc_start(the-test)",
+ "got_tc_stdout_line(--- a 2007-11-04 14:00:41.000000000 +0100)",
+ "got_tc_stdout_line(+++ b 2007-11-04 14:00:48.000000000 +0100)",
+ "got_tc_stdout_line(@@ -1,7 +1,7 @@)",
+ "got_tc_stdout_line( This test is meant to simulate a diff.)",
+ "got_tc_stdout_line( Blank space at beginning of context lines must be preserved.)",
+ "got_tc_stdout_line( )",
+ "got_tc_stdout_line(-First original line.)",
+ "got_tc_stdout_line(-Second original line.)",
+ "got_tc_stdout_line(+First modified line.)",
+ "got_tc_stdout_line(+Second modified line.)",
+ "got_tc_stdout_line( )",
+ "got_tc_stdout_line( EOF)",
+ "got_tc_end(passed)",
+ "got_tp_end()",
+ "got_eof()",
+ NULL
+ };
+ // NO_CHECK_STYLE_END
+
+ const char* exp_errors[] = {
+ NULL
+ };
+
+ do_parser_test< tps_reader >(input, exp_calls, exp_errors);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(tps_6);
+ATF_TEST_CASE_BODY(tps_6)
+{
+ const char* input =
+ "Content-Type: application/X-atf-tps; version=\"2\"\n"
+ "\n"
+ "tps-count: 1\n"
+ "tp-start: the-prog, 8\n"
+ "tc-start: one\n"
+ "tc-end: one, expected_death, The reason\n"
+ "tc-start: two\n"
+ "tc-end: two, expected_exit, This would be an exit\n"
+ "tc-start: three\n"
+ "tc-end: three, expected_failure, And this a failure\n"
+ "tc-start: four\n"
+ "tc-end: four, expected_signal, And this a signal\n"
+ "tc-start: five\n"
+ "tc-end: five, failed, Another reason\n"
+ "tc-start: six\n"
+ "tc-end: six, passed\n"
+ "tc-start: seven\n"
+ "tc-end: seven, skipped, Skipping it\n"
+ "tc-start: eight\n"
+ "tc-end: eight, expected_timeout, Some hang reason\n"
+ "tp-end: the-prog\n"
+ ;
+
+ // NO_CHECK_STYLE_BEGIN
+ const char* exp_calls[] = {
+ "got_ntps(1)",
+ "got_tp_start(the-prog, 8)",
+ "got_tc_start(one)",
+ "got_tc_end(expected_death, The reason)",
+ "got_tc_start(two)",
+ "got_tc_end(expected_exit, This would be an exit)",
+ "got_tc_start(three)",
+ "got_tc_end(expected_failure, And this a failure)",
+ "got_tc_start(four)",
+ "got_tc_end(expected_signal, And this a signal)",
+ "got_tc_start(five)",
+ "got_tc_end(failed, Another reason)",
+ "got_tc_start(six)",
+ "got_tc_end(passed)",
+ "got_tc_start(seven)",
+ "got_tc_end(skipped, Skipping it)",
+ "got_tc_start(eight)",
+ "got_tc_end(expected_timeout, Some hang reason)",
+ "got_tp_end()",
+ "got_eof()",
+ NULL
+ };
+ // NO_CHECK_STYLE_END
+
+ const char* exp_errors[] = {
+ NULL
+ };
+
+ do_parser_test< tps_reader >(input, exp_calls, exp_errors);
+}
+
+
+ATF_TEST_CASE_WITHOUT_HEAD(tps_50);
+ATF_TEST_CASE_BODY(tps_50)
+{
+ const char* input =
+ "Content-Type: application/X-atf-tps; version=\"2\"\n"
+ "\n"
+ "foo\n"
+ ;
+
+ const char* exp_calls[] = {
+ NULL
+ };
+
+ const char* exp_errors[] = {
+ "3: Unexpected token `foo'; expected tps-count or info field",
+ NULL
+ };
+
+ do_parser_test< tps_reader >(input, exp_calls, exp_errors);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(tps_51);
+ATF_TEST_CASE_BODY(tps_51)
+{
+ const char* input =
+ "Content-Type: application/X-atf-tps; version=\"2\"\n"
+ "\n"
+ "tps-count\n"
+ ;
+
+ const char* exp_calls[] = {
+ NULL
+ };
+
+ const char* exp_errors[] = {
+ "3: Unexpected token `<<NEWLINE>>'; expected `:'",
+ NULL
+ };
+
+ do_parser_test< tps_reader >(input, exp_calls, exp_errors);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(tps_52);
+ATF_TEST_CASE_BODY(tps_52)
+{
+ const char* input =
+ "Content-Type: application/X-atf-tps; version=\"2\"\n"
+ "\n"
+ "tps-count:\n"
+ ;
+
+ const char* exp_calls[] = {
+ NULL
+ };
+
+ const char* exp_errors[] = {
+ "3: Unexpected token `<<NEWLINE>>'; expected number of test programs",
+ NULL
+ };
+
+ do_parser_test< tps_reader >(input, exp_calls, exp_errors);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(tps_53);
+ATF_TEST_CASE_BODY(tps_53)
+{
+ const char* input =
+ "Content-Type: application/X-atf-tps; version=\"2\"\n"
+ "\n"
+ "tps-count: 1\n"
+ "foo\n"
+ ;
+
+ const char* exp_calls[] = {
+ "got_ntps(1)",
+ NULL
+ };
+
+ const char* exp_errors[] = {
+ "4: Unexpected token `foo'; expected start of test program",
+ NULL
+ };
+
+ do_parser_test< tps_reader >(input, exp_calls, exp_errors);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(tps_54);
+ATF_TEST_CASE_BODY(tps_54)
+{
+ const char* input =
+ "Content-Type: application/X-atf-tps; version=\"2\"\n"
+ "\n"
+ "tps-count: 1\n"
+ "foo\n"
+ "tp-start\n"
+ "tp-start:\n"
+ "tp-start: foo\n"
+ "tp-start: foo,\n"
+ "tp-start: foo, 0\n"
+ "bar\n"
+ "tp-start: foo, 0\n"
+ "tp-end\n"
+ "tp-start: foo, 0\n"
+ "tp-end:\n"
+ "tp-start: foo, 0\n"
+ "tp-end: bar\n"
+ "tp-start: foo, 0\n"
+ "tp-end: foo,\n"
+ ;
+
+ const char* exp_calls[] = {
+ "got_ntps(1)",
+ NULL
+ };
+
+ const char* exp_errors[] = {
+ "4: Unexpected token `foo'; expected start of test program",
+ "5: Unexpected token `<<NEWLINE>>'; expected `:'",
+ "6: Unexpected token `<<NEWLINE>>'; expected test program name",
+ "7: Unexpected token `<<NEWLINE>>'; expected `,'",
+ "8: Unexpected token `<<NEWLINE>>'; expected number of test programs",
+ "10: Unexpected token `bar'; expected end of test program",
+ "12: Unexpected token `<<NEWLINE>>'; expected `:'",
+ "14: Unexpected token `<<NEWLINE>>'; expected test program name",
+ "16: Test program name used in terminator does not match opening",
+ "18: Empty reason for failed test program",
+ NULL
+ };
+
+ do_parser_test< tps_reader >(input, exp_calls, exp_errors);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(tps_55);
+ATF_TEST_CASE_BODY(tps_55)
+{
+ const char* input =
+ "Content-Type: application/X-atf-tps; version=\"2\"\n"
+ "\n"
+ "tps-count: 1\n"
+ "tp-start: foo, 1\n"
+ "foo\n"
+ "tc-start\n"
+ "tc-start:\n"
+ "tc-start: foo\n"
+ "bar\n"
+ "tc-start: foo\n"
+ "tc-end\n"
+ "tc-start: foo\n"
+ "tc-end:\n"
+ "tc-start: foo\n"
+ "tc-end: bar\n"
+ "tc-start: foo\n"
+ "tc-end: foo\n"
+ "tc-start: foo\n"
+ "tc-end: foo,\n"
+ "tp-end: foo\n"
+ ;
+
+ const char* exp_calls[] = {
+ "got_ntps(1)",
+ "got_tp_start(foo, 1)",
+ NULL
+ };
+
+ // NO_CHECK_STYLE_BEGIN
+ const char* exp_errors[] = {
+ "5: Unexpected token `foo'; expected start of test case",
+ "6: Unexpected token `<<NEWLINE>>'; expected `:'",
+ "7: Unexpected token `<<NEWLINE>>'; expected test case name",
+ "9: Unexpected token `bar'; expected end of test case or test case's stdout/stderr line",
+ "11: Unexpected token `<<NEWLINE>>'; expected `:'",
+ "13: Unexpected token `<<NEWLINE>>'; expected test case name",
+ "15: Test case name used in terminator does not match opening",
+ "17: Unexpected token `<<NEWLINE>>'; expected `,'",
+ "19: Unexpected token `<<NEWLINE>>'; expected expected_{death,exit,failure,signal,timeout}, failed, passed or skipped",
+ "20: Unexpected token `tp-end'; expected start of test case",
+ NULL
+ };
+ // NO_CHECK_STYLE_END
+
+ do_parser_test< tps_reader >(input, exp_calls, exp_errors);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(tps_56);
+ATF_TEST_CASE_BODY(tps_56)
+{
+ const char* input =
+ "Content-Type: application/X-atf-tps; version=\"2\"\n"
+ "\n"
+ "tps-count: 1\n"
+ "tp-start: foo, 1\n"
+ "tc-start: foo\n"
+ "tc-end: foo, passe\n"
+ "tc-start: foo\n"
+ "tc-end: foo, passed,\n"
+ "tc-start: bar\n"
+ "tc-end: bar, failed\n"
+ "tc-start: bar\n"
+ "tc-end: bar, failed,\n"
+ "tc-start: baz\n"
+ "tc-end: baz, skipped\n"
+ "tc-start: baz\n"
+ "tc-end: baz, skipped,\n"
+ "tp-end: foo\n"
+ ;
+
+ const char* exp_calls[] = {
+ "got_ntps(1)",
+ "got_tp_start(foo, 1)",
+ "got_tc_start(foo)",
+ NULL
+ };
+
+ // NO_CHECK_STYLE_BEGIN
+ const char* exp_errors[] = {
+ "6: Unexpected token `passe'; expected expected_{death,exit,failure,signal,timeout}, failed, passed or skipped",
+ "8: Unexpected token `,'; expected new line",
+ "10: Unexpected token `<<NEWLINE>>'; expected `,'",
+ "12: Empty reason for failed test case result",
+ "14: Unexpected token `<<NEWLINE>>'; expected `,'",
+ "16: Empty reason for skipped test case result",
+ "17: Unexpected token `tp-end'; expected start of test case",
+ NULL
+ };
+ // NO_CHECK_STYLE_END
+
+ do_parser_test< tps_reader >(input, exp_calls, exp_errors);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(tps_57);
+ATF_TEST_CASE_BODY(tps_57)
+{
+ const char* input =
+ "Content-Type: application/X-atf-tps; version=\"2\"\n"
+ "\n"
+ "tps-count: 2\n"
+ "tp-start: foo, 0\n"
+ "tp-end: foo\n"
+ ;
+
+ const char* exp_calls[] = {
+ "got_ntps(2)",
+ "got_tp_start(foo, 0)",
+ "got_tp_end()",
+ NULL
+ };
+
+ const char* exp_errors[] = {
+ "6: Unexpected token `<<EOF>>'; expected start of test program",
+ NULL
+ };
+
+ do_parser_test< tps_reader >(input, exp_calls, exp_errors);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(tps_58);
+ATF_TEST_CASE_BODY(tps_58)
+{
+ const char* input =
+ "Content-Type: application/X-atf-tps; version=\"2\"\n"
+ "\n"
+ "tps-count: 1\n"
+ "tp-start: foo, 0\n"
+ "tp-end: foo\n"
+ "tp-start: bar, 0\n"
+ "tp-end: bar\n"
+ ;
+
+ const char* exp_calls[] = {
+ "got_ntps(1)",
+ "got_tp_start(foo, 0)",
+ "got_tp_end()",
+ NULL
+ };
+
+ const char* exp_errors[] = {
+ "6: Unexpected token `tp-start'; expected end of stream or info field",
+ NULL
+ };
+
+ do_parser_test< tps_reader >(input, exp_calls, exp_errors);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(tps_59);
+ATF_TEST_CASE_BODY(tps_59)
+{
+ const char* input =
+ "Content-Type: application/X-atf-tps; version=\"2\"\n"
+ "\n"
+ "info\n"
+ ;
+
+ const char* exp_calls[] = {
+ NULL
+ };
+
+ const char* exp_errors[] = {
+ "3: Unexpected token `<<NEWLINE>>'; expected `:'",
+ NULL
+ };
+
+ do_parser_test< tps_reader >(input, exp_calls, exp_errors);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(tps_60);
+ATF_TEST_CASE_BODY(tps_60)
+{
+ const char* input =
+ "Content-Type: application/X-atf-tps; version=\"2\"\n"
+ "\n"
+ "info:\n"
+ ;
+
+ const char* exp_calls[] = {
+ NULL
+ };
+
+ const char* exp_errors[] = {
+ "3: Unexpected token `<<NEWLINE>>'; expected info property name",
+ NULL
+ };
+
+ do_parser_test< tps_reader >(input, exp_calls, exp_errors);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(tps_61);
+ATF_TEST_CASE_BODY(tps_61)
+{
+ const char* input =
+ "Content-Type: application/X-atf-tps; version=\"2\"\n"
+ "\n"
+ "info: a\n"
+ ;
+
+ const char* exp_calls[] = {
+ NULL
+ };
+
+ const char* exp_errors[] = {
+ "3: Unexpected token `<<NEWLINE>>'; expected `,'",
+ NULL
+ };
+
+ do_parser_test< tps_reader >(input, exp_calls, exp_errors);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(tps_62);
+ATF_TEST_CASE_BODY(tps_62)
+{
+ const char* input =
+ "Content-Type: application/X-atf-tps; version=\"2\"\n"
+ "\n"
+ "info: a,\n"
+ ;
+
+ const char* exp_calls[] = {
+ "got_info(a, )",
+ NULL
+ };
+
+ const char* exp_errors[] = {
+ "4: Unexpected token `<<EOF>>'; expected tps-count or info field",
+ NULL
+ };
+
+ do_parser_test< tps_reader >(input, exp_calls, exp_errors);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(tps_63);
+ATF_TEST_CASE_BODY(tps_63)
+{
+ const char* input =
+ "Content-Type: application/X-atf-tps; version=\"2\"\n"
+ "\n"
+ "info: a, b\n"
+ ;
+
+ const char* exp_calls[] = {
+ "got_info(a, b)",
+ NULL
+ };
+
+ const char* exp_errors[] = {
+ "4: Unexpected token `<<EOF>>'; expected tps-count or info field",
+ NULL
+ };
+
+ do_parser_test< tps_reader >(input, exp_calls, exp_errors);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(tps_64);
+ATF_TEST_CASE_BODY(tps_64)
+{
+ const char* input =
+ "Content-Type: application/X-atf-tps; version=\"2\"\n"
+ "\n"
+ "info: a, b\n"
+ "tps-count\n"
+ ;
+
+ const char* exp_calls[] = {
+ "got_info(a, b)",
+ NULL
+ };
+
+ const char* exp_errors[] = {
+ "4: Unexpected token `<<NEWLINE>>'; expected `:'",
+ NULL
+ };
+
+ do_parser_test< tps_reader >(input, exp_calls, exp_errors);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(tps_65);
+ATF_TEST_CASE_BODY(tps_65)
+{
+ const char* input =
+ "Content-Type: application/X-atf-tps; version=\"2\"\n"
+ "\n"
+ "info: a, b\n"
+ "tps-count:\n"
+ ;
+
+ const char* exp_calls[] = {
+ "got_info(a, b)",
+ NULL
+ };
+
+ const char* exp_errors[] = {
+ "4: Unexpected token `<<NEWLINE>>'; expected number of test programs",
+ NULL
+ };
+
+ do_parser_test< tps_reader >(input, exp_calls, exp_errors);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(tps_66);
+ATF_TEST_CASE_BODY(tps_66)
+{
+ const char* input =
+ "Content-Type: application/X-atf-tps; version=\"2\"\n"
+ "\n"
+ "info: a, b\n"
+ "tps-count: 0\n"
+ "info\n"
+ ;
+
+ const char* exp_calls[] = {
+ "got_info(a, b)",
+ "got_ntps(0)",
+ NULL
+ };
+
+ const char* exp_errors[] = {
+ "5: Unexpected token `<<NEWLINE>>'; expected `:'",
+ NULL
+ };
+
+ do_parser_test< tps_reader >(input, exp_calls, exp_errors);
+}
+
+ATF_INIT_TEST_CASES(tcs)
+{
+ ATF_ADD_TEST_CASE(tcs, tps_1);
+ ATF_ADD_TEST_CASE(tcs, tps_2);
+ ATF_ADD_TEST_CASE(tcs, tps_3);
+ ATF_ADD_TEST_CASE(tcs, tps_4);
+ ATF_ADD_TEST_CASE(tcs, tps_5);
+ ATF_ADD_TEST_CASE(tcs, tps_6);
+ ATF_ADD_TEST_CASE(tcs, tps_50);
+ ATF_ADD_TEST_CASE(tcs, tps_51);
+ ATF_ADD_TEST_CASE(tcs, tps_52);
+ ATF_ADD_TEST_CASE(tcs, tps_53);
+ ATF_ADD_TEST_CASE(tcs, tps_54);
+ ATF_ADD_TEST_CASE(tcs, tps_55);
+ ATF_ADD_TEST_CASE(tcs, tps_56);
+ ATF_ADD_TEST_CASE(tcs, tps_57);
+ ATF_ADD_TEST_CASE(tcs, tps_58);
+ ATF_ADD_TEST_CASE(tcs, tps_59);
+ ATF_ADD_TEST_CASE(tcs, tps_60);
+ ATF_ADD_TEST_CASE(tcs, tps_61);
+ ATF_ADD_TEST_CASE(tcs, tps_62);
+ ATF_ADD_TEST_CASE(tcs, tps_63);
+ ATF_ADD_TEST_CASE(tcs, tps_64);
+ ATF_ADD_TEST_CASE(tcs, tps_65);
+ ATF_ADD_TEST_CASE(tcs, tps_66);
+}
+
diff --git a/external/bsd/atf/dist/atf-run/Atffile b/external/bsd/atf/dist/atf-run/Atffile
new file mode 100644
index 00000000000..146211e000d
--- /dev/null
+++ b/external/bsd/atf/dist/atf-run/Atffile
@@ -0,0 +1,5 @@
+Content-Type: application/X-atf-atffile; version="1"
+
+prop: test-suite = atf
+
+tp-glob: *_test
diff --git a/external/bsd/atf/dist/atf-run/atf-run.1 b/external/bsd/atf/dist/atf-run/atf-run.1
index ace7f557f4a..1ad987719bb 100644
--- a/external/bsd/atf/dist/atf-run/atf-run.1
+++ b/external/bsd/atf/dist/atf-run/atf-run.1
@@ -126,7 +126,7 @@ option.
.El
.Pp
The value of
-.Va ATF_CONFIG
+.Va ATF_CONFDIR
in the above list determined as detailed in
.Xr atf-config 1 .
.Ss Hooks
diff --git a/external/bsd/atf/dist/atf-run/atffile.cpp b/external/bsd/atf/dist/atf-run/atffile.cpp
new file mode 100644
index 00000000000..92550abe2a9
--- /dev/null
+++ b/external/bsd/atf/dist/atf-run/atffile.cpp
@@ -0,0 +1,337 @@
+//
+// Automated Testing Framework (atf)
+//
+// Copyright (c) 2007, 2008, 2010 The NetBSD Foundation, Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
+// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#include <fstream>
+
+#include "atf-c++/exceptions.hpp"
+#include "atf-c++/expand.hpp"
+#include "atf-c++/parser.hpp"
+#include "atf-c++/sanity.hpp"
+
+#include "atffile.hpp"
+
+namespace impl = atf::atf_run;
+namespace detail = atf::atf_run::detail;
+
+// ------------------------------------------------------------------------
+// The "atf_atffile" auxiliary parser.
+// ------------------------------------------------------------------------
+
+namespace atf_atffile {
+
+static const atf::parser::token_type eof_type = 0;
+static const atf::parser::token_type nl_type = 1;
+static const atf::parser::token_type text_type = 2;
+static const atf::parser::token_type colon_type = 3;
+static const atf::parser::token_type conf_type = 4;
+static const atf::parser::token_type dblquote_type = 5;
+static const atf::parser::token_type equal_type = 6;
+static const atf::parser::token_type hash_type = 7;
+static const atf::parser::token_type prop_type = 8;
+static const atf::parser::token_type tp_type = 9;
+static const atf::parser::token_type tp_glob_type = 10;
+
+class tokenizer : public atf::parser::tokenizer< std::istream > {
+public:
+ tokenizer(std::istream& is, size_t curline) :
+ atf::parser::tokenizer< std::istream >
+ (is, true, eof_type, nl_type, text_type, curline)
+ {
+ add_delim(':', colon_type);
+ add_delim('=', equal_type);
+ add_delim('#', hash_type);
+ add_quote('"', dblquote_type);
+ add_keyword("conf", conf_type);
+ add_keyword("prop", prop_type);
+ add_keyword("tp", tp_type);
+ add_keyword("tp-glob", tp_glob_type);
+ }
+};
+
+} // namespace atf_atffile
+
+// ------------------------------------------------------------------------
+// The "atf_atffile_reader" class.
+// ------------------------------------------------------------------------
+
+detail::atf_atffile_reader::atf_atffile_reader(std::istream& is) :
+ m_is(is)
+{
+}
+
+detail::atf_atffile_reader::~atf_atffile_reader(void)
+{
+}
+
+void
+detail::atf_atffile_reader::got_conf(const std::string& name,
+ const std::string& val)
+{
+}
+
+void
+detail::atf_atffile_reader::got_prop(const std::string& name,
+ const std::string& val)
+{
+}
+
+void
+detail::atf_atffile_reader::got_tp(const std::string& name, bool isglob)
+{
+}
+
+void
+detail::atf_atffile_reader::got_eof(void)
+{
+}
+
+void
+detail::atf_atffile_reader::read(void)
+{
+ using atf::parser::parse_error;
+ using namespace atf_atffile;
+
+ std::pair< size_t, atf::parser::headers_map > hml =
+ atf::parser::read_headers(m_is, 1);
+ atf::parser::validate_content_type(hml.second,
+ "application/X-atf-atffile", 1);
+
+ tokenizer tkz(m_is, hml.first);
+ atf::parser::parser< tokenizer > p(tkz);
+
+ for (;;) {
+ try {
+ atf::parser::token t =
+ p.expect(conf_type, hash_type, prop_type, tp_type,
+ tp_glob_type, nl_type, eof_type,
+ "conf, #, prop, tp, tp-glob, a new line or eof");
+ if (t.type() == eof_type)
+ break;
+
+ if (t.type() == conf_type) {
+ t = p.expect(colon_type, "`:'");
+
+ t = p.expect(text_type, "variable name");
+ std::string var = t.text();
+
+ t = p.expect(equal_type, "equal sign");
+
+ t = p.expect(text_type, "word or quoted string");
+ ATF_PARSER_CALLBACK(p, got_conf(var, t.text()));
+ } else if (t.type() == hash_type) {
+ (void)p.rest_of_line();
+ } else if (t.type() == prop_type) {
+ t = p.expect(colon_type, "`:'");
+
+ t = p.expect(text_type, "property name");
+ std::string name = t.text();
+
+ t = p.expect(equal_type, "equale sign");
+
+ t = p.expect(text_type, "word or quoted string");
+ ATF_PARSER_CALLBACK(p, got_prop(name, t.text()));
+ } else if (t.type() == tp_type) {
+ t = p.expect(colon_type, "`:'");
+
+ t = p.expect(text_type, "word or quoted string");
+ ATF_PARSER_CALLBACK(p, got_tp(t.text(), false));
+ } else if (t.type() == tp_glob_type) {
+ t = p.expect(colon_type, "`:'");
+
+ t = p.expect(text_type, "word or quoted string");
+ ATF_PARSER_CALLBACK(p, got_tp(t.text(), true));
+ } else if (t.type() == nl_type) {
+ continue;
+ } else
+ UNREACHABLE;
+
+ t = p.expect(nl_type, hash_type, eof_type,
+ "new line or comment");
+ if (t.type() == hash_type) {
+ (void)p.rest_of_line();
+ t = p.next();
+ } else if (t.type() == eof_type)
+ break;
+ } catch (const parse_error& pe) {
+ p.add_error(pe);
+ p.reset(nl_type);
+ }
+ }
+
+ ATF_PARSER_CALLBACK(p, got_eof());
+}
+
+// ------------------------------------------------------------------------
+// The "reader" helper class.
+// ------------------------------------------------------------------------
+
+class reader : public detail::atf_atffile_reader {
+ const atf::fs::directory& m_dir;
+ atf::tests::vars_map m_conf, m_props;
+ std::vector< std::string > m_tps;
+
+ void
+ got_tp(const std::string& name, bool isglob)
+ {
+ if (isglob) {
+ std::vector< std::string > ms =
+ atf::expand::expand_glob(name, m_dir.names());
+ // Cannot use m_tps.insert(iterator, begin, end) here because it
+ // does not work under Solaris.
+ for (std::vector< std::string >::const_iterator iter = ms.begin();
+ iter != ms.end(); iter++)
+ m_tps.push_back(*iter);
+ } else {
+ if (m_dir.find(name) == m_dir.end())
+ throw atf::not_found_error< atf::fs::path >
+ ("Cannot locate the " + name + " file",
+ atf::fs::path(name));
+ m_tps.push_back(name);
+ }
+ }
+
+ void
+ got_prop(const std::string& name, const std::string& val)
+ {
+ m_props[name] = val;
+ }
+
+ void
+ got_conf(const std::string& var, const std::string& val)
+ {
+ m_conf[var] = val;
+ }
+
+public:
+ reader(std::istream& is, const atf::fs::directory& dir) :
+ detail::atf_atffile_reader(is),
+ m_dir(dir)
+ {
+ }
+
+ const atf::tests::vars_map&
+ conf(void)
+ const
+ {
+ return m_conf;
+ }
+
+ const atf::tests::vars_map&
+ props(void)
+ const
+ {
+ return m_props;
+ }
+
+ const std::vector< std::string >&
+ tps(void)
+ const
+ {
+ return m_tps;
+ }
+};
+
+// ------------------------------------------------------------------------
+// The "atffile" class.
+// ------------------------------------------------------------------------
+
+impl::atffile::atffile(const atf::tests::vars_map& config_vars,
+ const std::vector< std::string >& test_program_names,
+ const atf::tests::vars_map& properties) :
+ m_conf(config_vars),
+ m_tps(test_program_names),
+ m_props(properties)
+{
+ PRE(properties.find("test-suite") != properties.end());
+}
+
+const std::vector< std::string >&
+impl::atffile::tps(void)
+ const
+{
+ return m_tps;
+}
+
+const atf::tests::vars_map&
+impl::atffile::conf(void)
+ const
+{
+ return m_conf;
+}
+
+const atf::tests::vars_map&
+impl::atffile::props(void)
+ const
+{
+ return m_props;
+}
+
+// ------------------------------------------------------------------------
+// Free functions.
+// ------------------------------------------------------------------------
+
+// XXX Glob expansion and file existance checks certainly do not belong in
+// a *parser*. This needs to be taken out...
+impl::atffile
+impl::read_atffile(const atf::fs::path& filename)
+{
+ // Scan the directory where the atffile lives in to gather a list of
+ // all possible test programs in it.
+ fs::directory dir(filename.branch_path());
+ dir.erase(filename.leaf_name());
+ fs::directory::iterator iter = dir.begin();
+ while (iter != dir.end()) {
+ const std::string& name = (*iter).first;
+ const fs::file_info& fi = (*iter).second;
+
+ // Discard hidden files and non-executable ones so that they are
+ // not candidates for glob matching.
+ if (name[0] == '.' || (!fi.is_owner_executable() &&
+ !fi.is_group_executable()))
+ dir.erase(iter++);
+ else
+ iter++;
+ }
+
+ // Parse the atffile.
+ std::ifstream is(filename.c_str());
+ if (!is)
+ throw atf::not_found_error< fs::path >
+ ("Cannot open Atffile", filename);
+ reader r(is, dir);
+ r.read();
+ is.close();
+
+ // Sanity checks.
+ if (r.props().find("test-suite") == r.props().end())
+ throw atf::not_found_error< std::string >
+ ("Undefined property `test-suite'", "test-suite");
+
+ return atffile(r.conf(), r.tps(), r.props());
+}
diff --git a/external/bsd/atf/dist/atf-run/atffile.hpp b/external/bsd/atf/dist/atf-run/atffile.hpp
new file mode 100644
index 00000000000..3098434d317
--- /dev/null
+++ b/external/bsd/atf/dist/atf-run/atffile.hpp
@@ -0,0 +1,94 @@
+//
+// Automated Testing Framework (atf)
+//
+// Copyright (c) 2007, 2008, 2010 The NetBSD Foundation, Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
+// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#if !defined(_ATF_RUN_ATFFILE_HPP_)
+#define _ATF_RUN_ATFFILE_HPP_
+
+#include <string>
+#include <vector>
+
+#include <atf-c++/fs.hpp>
+#include <atf-c++/tests.hpp>
+
+namespace atf {
+namespace atf_run {
+
+// ------------------------------------------------------------------------
+// The "atf_atffile_reader" class.
+// ------------------------------------------------------------------------
+
+namespace detail {
+
+class atf_atffile_reader {
+ std::istream& m_is;
+
+protected:
+ virtual void got_conf(const std::string&, const std::string &);
+ virtual void got_prop(const std::string&, const std::string &);
+ virtual void got_tp(const std::string&, bool);
+ virtual void got_eof(void);
+
+public:
+ atf_atffile_reader(std::istream&);
+ virtual ~atf_atffile_reader(void);
+
+ void read(void);
+};
+
+} // namespace detail
+
+// ------------------------------------------------------------------------
+// The "atffile" class.
+// ------------------------------------------------------------------------
+
+class atffile {
+ atf::tests::vars_map m_conf;
+ std::vector< std::string > m_tps;
+ atf::tests::vars_map m_props;
+
+public:
+ atffile(const atf::tests::vars_map&,
+ const std::vector< std::string >&,
+ const atf::tests::vars_map&);
+
+ const atf::tests::vars_map& conf(void) const;
+ const std::vector< std::string >& tps(void) const;
+ const atf::tests::vars_map& props(void) const;
+};
+
+// ------------------------------------------------------------------------
+// Free functions.
+// ------------------------------------------------------------------------
+
+atffile read_atffile(const fs::path&);
+
+} // namespace atf_run
+} // namespace atf
+
+#endif // !defined(_ATF_RUN_ATFFILE_HPP_)
diff --git a/external/bsd/atf/dist/atf-run/atffile_test.cpp b/external/bsd/atf/dist/atf-run/atffile_test.cpp
new file mode 100644
index 00000000000..908be96046f
--- /dev/null
+++ b/external/bsd/atf/dist/atf-run/atffile_test.cpp
@@ -0,0 +1,648 @@
+//
+// Automated Testing Framework (atf)
+//
+// Copyright (c) 2009, 2010 The NetBSD Foundation, Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
+// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+extern "C" {
+#include <sys/types.h>
+#include <sys/stat.h>
+}
+
+#include <algorithm>
+#include <fstream>
+#include <memory>
+
+#include "atf-c++/exceptions.hpp"
+#include "atf-c++/macros.hpp"
+
+#include "atffile.hpp"
+
+#include "test_helpers.hpp"
+
+namespace detail = atf::atf_run::detail;
+
+// ------------------------------------------------------------------------
+// Auxiliary functions.
+// ------------------------------------------------------------------------
+
+namespace {
+
+static
+std::auto_ptr< std::ofstream >
+new_atffile(void)
+{
+ std::auto_ptr< std::ofstream > os(new std::ofstream("Atffile"));
+ ATF_CHECK(*os);
+
+ (*os) << "Content-Type: application/X-atf-atffile; version=\"1\"\n\n";
+ return os;
+}
+
+static
+void
+touch_exec(const char* name)
+{
+ std::ofstream os(name);
+ ATF_CHECK(os);
+ os.close();
+ ATF_CHECK(::chmod(name, S_IRWXU) != -1);
+}
+
+static inline
+bool
+is_in(const std::string& value, const std::vector< std::string >& v)
+{
+ return std::find(v.begin(), v.end(), value) != v.end();
+}
+
+} // anonymous namespace
+
+// ------------------------------------------------------------------------
+// Tests cases for the "atffile" parser.
+// ------------------------------------------------------------------------
+
+class atffile_reader : protected detail::atf_atffile_reader {
+ void
+ got_conf(const std::string& name, const std::string& val)
+ {
+ m_calls.push_back("got_conf(" + name + ", " + val + ")");
+ }
+
+ void
+ got_prop(const std::string& name, const std::string& val)
+ {
+ m_calls.push_back("got_prop(" + name + ", " + val + ")");
+ }
+
+ void
+ got_tp(const std::string& name, bool isglob)
+ {
+ m_calls.push_back("got_tp(" + name + ", " + (isglob ? "true" : "false")
+ + ")");
+ }
+
+ void
+ got_eof(void)
+ {
+ m_calls.push_back("got_eof()");
+ }
+
+public:
+ atffile_reader(std::istream& is) :
+ detail::atf_atffile_reader(is)
+ {
+ }
+
+ void
+ read(void)
+ {
+ atf_atffile_reader::read();
+ }
+
+ std::vector< std::string > m_calls;
+};
+
+ATF_TEST_CASE_WITHOUT_HEAD(atffile_1);
+ATF_TEST_CASE_BODY(atffile_1)
+{
+ const char* input =
+ "Content-Type: application/X-atf-atffile; version=\"1\"\n"
+ "\n"
+ ;
+
+ const char* exp_calls[] = {
+ "got_eof()",
+ NULL
+ };
+
+ const char* exp_errors[] = {
+ NULL
+ };
+
+ do_parser_test< atffile_reader >(input, exp_calls, exp_errors);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(atffile_2);
+ATF_TEST_CASE_BODY(atffile_2)
+{
+ const char* input =
+ "Content-Type: application/X-atf-atffile; version=\"1\"\n"
+ "\n"
+ "# This is a comment on a line of its own.\n"
+ "# And this is another one.\n"
+ "\n"
+ " # Another after some whitespace.\n"
+ "\n"
+ "# The last one after an empty line.\n"
+ ;
+
+ const char* exp_calls[] = {
+ "got_eof()",
+ NULL
+ };
+
+ const char* exp_errors[] = {
+ NULL
+ };
+
+ do_parser_test< atffile_reader >(input, exp_calls, exp_errors);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(atffile_3);
+ATF_TEST_CASE_BODY(atffile_3)
+{
+ const char* input =
+ "Content-Type: application/X-atf-atffile; version=\"1\"\n"
+ "\n"
+ "conf: var1=value1\n"
+ "conf: var2 = value2\n"
+ "conf: var3 = value3\n"
+ "conf: var4 = value4\n"
+ "\n"
+ "conf:var5=value5\n"
+ " conf:var6=value6\n"
+ "\n"
+ "conf: var7 = \"This is a long value.\"\n"
+ "conf: var8 = \"Single-word\"\n"
+ "conf: var9 = \" Single-word \"\n"
+ "conf: var10 = Single-word\n"
+ ;
+
+ const char* exp_calls[] = {
+ "got_conf(var1, value1)",
+ "got_conf(var2, value2)",
+ "got_conf(var3, value3)",
+ "got_conf(var4, value4)",
+ "got_conf(var5, value5)",
+ "got_conf(var6, value6)",
+ "got_conf(var7, This is a long value.)",
+ "got_conf(var8, Single-word)",
+ "got_conf(var9, Single-word )",
+ "got_conf(var10, Single-word)",
+ "got_eof()",
+ NULL
+ };
+
+ const char* exp_errors[] = {
+ NULL
+ };
+
+ do_parser_test< atffile_reader >(input, exp_calls, exp_errors);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(atffile_4);
+ATF_TEST_CASE_BODY(atffile_4)
+{
+ const char* input =
+ "Content-Type: application/X-atf-atffile; version=\"1\"\n"
+ "\n"
+ "prop: var1=value1\n"
+ "prop: var2 = value2\n"
+ "prop: var3 = value3\n"
+ "prop: var4 = value4\n"
+ "\n"
+ "prop:var5=value5\n"
+ " prop:var6=value6\n"
+ "\n"
+ "prop: var7 = \"This is a long value.\"\n"
+ "prop: var8 = \"Single-word\"\n"
+ "prop: var9 = \" Single-word \"\n"
+ "prop: var10 = Single-word\n"
+ ;
+
+ const char* exp_calls[] = {
+ "got_prop(var1, value1)",
+ "got_prop(var2, value2)",
+ "got_prop(var3, value3)",
+ "got_prop(var4, value4)",
+ "got_prop(var5, value5)",
+ "got_prop(var6, value6)",
+ "got_prop(var7, This is a long value.)",
+ "got_prop(var8, Single-word)",
+ "got_prop(var9, Single-word )",
+ "got_prop(var10, Single-word)",
+ "got_eof()",
+ NULL
+ };
+
+ const char* exp_errors[] = {
+ NULL
+ };
+
+ do_parser_test< atffile_reader >(input, exp_calls, exp_errors);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(atffile_5);
+ATF_TEST_CASE_BODY(atffile_5)
+{
+ const char* input =
+ "Content-Type: application/X-atf-atffile; version=\"1\"\n"
+ "\n"
+ "tp:foo\n"
+ "tp: foo\n"
+ "tp: foo\n"
+ "tp: foo\n"
+ "tp: foo\n"
+ "tp: \"name with spaces\"\n"
+ "tp: \"single-word\"\n"
+ "tp: single-word\n"
+ "\n"
+ "tp-glob:foo*?bar\n"
+ "tp-glob: foo*?bar\n"
+ "tp-glob: foo*?bar\n"
+ "tp-glob: foo*?bar\n"
+ "tp-glob: foo*?bar\n"
+ "tp-glob: \"glob * with ? spaces\"\n"
+ "tp-glob: \"single-*-word\"\n"
+ "tp-glob: single-*-word\n"
+ ;
+
+ const char* exp_calls[] = {
+ "got_tp(foo, false)",
+ "got_tp(foo, false)",
+ "got_tp(foo, false)",
+ "got_tp(foo, false)",
+ "got_tp(foo, false)",
+ "got_tp(name with spaces, false)",
+ "got_tp(single-word, false)",
+ "got_tp(single-word, false)",
+ "got_tp(foo*?bar, true)",
+ "got_tp(foo*?bar, true)",
+ "got_tp(foo*?bar, true)",
+ "got_tp(foo*?bar, true)",
+ "got_tp(foo*?bar, true)",
+ "got_tp(glob * with ? spaces, true)",
+ "got_tp(single-*-word, true)",
+ "got_tp(single-*-word, true)",
+ "got_eof()",
+ NULL
+ };
+
+ const char* exp_errors[] = {
+ NULL
+ };
+
+ do_parser_test< atffile_reader >(input, exp_calls, exp_errors);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(atffile_6);
+ATF_TEST_CASE_BODY(atffile_6)
+{
+ const char* input =
+ "Content-Type: application/X-atf-atffile; version=\"1\"\n"
+ "\n"
+ "prop: foo = bar # A comment.\n"
+ "conf: foo = bar # A comment.\n"
+ "tp: foo # A comment.\n"
+ "tp-glob: foo # A comment.\n"
+ ;
+
+ const char* exp_calls[] = {
+ "got_prop(foo, bar)",
+ "got_conf(foo, bar)",
+ "got_tp(foo, false)",
+ "got_tp(foo, true)",
+ "got_eof()",
+ NULL
+ };
+
+ const char* exp_errors[] = {
+ NULL
+ };
+
+ do_parser_test< atffile_reader >(input, exp_calls, exp_errors);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(atffile_50);
+ATF_TEST_CASE_BODY(atffile_50)
+{
+ const char* input =
+ "Content-Type: application/X-atf-atffile; version=\"1\"\n"
+ "\n"
+ "foo\n"
+ ;
+
+ const char* exp_calls[] = {
+ NULL
+ };
+
+ // NO_CHECK_STYLE_BEGIN
+ const char* exp_errors[] = {
+ "3: Unexpected token `foo'; expected conf, #, prop, tp, tp-glob, a new line or eof",
+ NULL
+ };
+ // NO_CHECK_STYLE_END
+
+ do_parser_test< atffile_reader >(input, exp_calls, exp_errors);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(atffile_51);
+ATF_TEST_CASE_BODY(atffile_51)
+{
+ const char* input =
+ "Content-Type: application/X-atf-atffile; version=\"1\"\n"
+ "\n"
+ "foo bar\n"
+ "baz\n"
+ ;
+
+ const char* exp_calls[] = {
+ NULL
+ };
+
+ // NO_CHECK_STYLE_BEGIN
+ const char* exp_errors[] = {
+ "3: Unexpected token `foo'; expected conf, #, prop, tp, tp-glob, a new line or eof",
+ "4: Unexpected token `baz'; expected conf, #, prop, tp, tp-glob, a new line or eof",
+ NULL
+ };
+ // NO_CHECK_STYLE_END
+
+ do_parser_test< atffile_reader >(input, exp_calls, exp_errors);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(atffile_52);
+ATF_TEST_CASE_BODY(atffile_52)
+{
+ const char* input =
+ "Content-Type: application/X-atf-atffile; version=\"1\"\n"
+ "\n"
+ "conf\n"
+ "conf:\n"
+ "conf: foo =\n"
+ "conf: bar = # A comment.\n"
+ "\n"
+ "prop\n"
+ "prop:\n"
+ "prop: foo =\n"
+ "prop: bar = # A comment.\n"
+ "\n"
+ "tp\n"
+ "tp:\n"
+ "tp: # A comment.\n"
+ "\n"
+ "tp-glob\n"
+ "tp-glob:\n"
+ "tp-glob: # A comment.\n"
+ ;
+
+ const char* exp_calls[] = {
+ NULL
+ };
+
+ const char* exp_errors[] = {
+ "3: Unexpected token `<<NEWLINE>>'; expected `:'",
+ "4: Unexpected token `<<NEWLINE>>'; expected variable name",
+ "5: Unexpected token `<<NEWLINE>>'; expected word or quoted string",
+ "6: Unexpected token `#'; expected word or quoted string",
+ "8: Unexpected token `<<NEWLINE>>'; expected `:'",
+ "9: Unexpected token `<<NEWLINE>>'; expected property name",
+ "10: Unexpected token `<<NEWLINE>>'; expected word or quoted string",
+ "11: Unexpected token `#'; expected word or quoted string",
+ "13: Unexpected token `<<NEWLINE>>'; expected `:'",
+ "14: Unexpected token `<<NEWLINE>>'; expected word or quoted string",
+ "15: Unexpected token `#'; expected word or quoted string",
+ "17: Unexpected token `<<NEWLINE>>'; expected `:'",
+ "18: Unexpected token `<<NEWLINE>>'; expected word or quoted string",
+ "19: Unexpected token `#'; expected word or quoted string",
+ NULL
+ };
+
+ do_parser_test< atffile_reader >(input, exp_calls, exp_errors);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(atffile_53);
+ATF_TEST_CASE_BODY(atffile_53)
+{
+ const char* input =
+ "Content-Type: application/X-atf-atffile; version=\"1\"\n"
+ "\n"
+ "prop: foo = \"Correct value\" # With comment.\n"
+ "\n"
+ "prop: bar = # A comment.\n"
+ "\n"
+ "prop: baz = \"Last variable\"\n"
+ "\n"
+ "# End of file.\n"
+ ;
+
+ const char* exp_calls[] = {
+ "got_prop(foo, Correct value)",
+ NULL
+ };
+
+ const char* exp_errors[] = {
+ "5: Unexpected token `#'; expected word or quoted string",
+ NULL
+ };
+
+ do_parser_test< atffile_reader >(input, exp_calls, exp_errors);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(atffile_54);
+ATF_TEST_CASE_BODY(atffile_54)
+{
+ const char* input =
+ "Content-Type: application/X-atf-atffile; version=\"1\"\n"
+ "\n"
+ "prop: foo = \"\n"
+ "prop: bar = \"text\n"
+ "prop: baz = \"te\\\"xt\n"
+ "prop: last = \"\\\"\n"
+ ;
+
+ const char* exp_calls[] = {
+ NULL
+ };
+
+ const char* exp_errors[] = {
+ "3: Missing double quotes before end of line",
+ "4: Missing double quotes before end of line",
+ "5: Missing double quotes before end of line",
+ "6: Missing double quotes before end of line",
+ NULL
+ };
+
+ do_parser_test< atffile_reader >(input, exp_calls, exp_errors);
+}
+
+// ------------------------------------------------------------------------
+// Tests cases for the "atffile" class.
+// ------------------------------------------------------------------------
+
+ATF_TEST_CASE(atffile_getters);
+ATF_TEST_CASE_HEAD(atffile_getters) {}
+ATF_TEST_CASE_BODY(atffile_getters) {
+ atf::tests::vars_map config_vars;
+ config_vars["config-var-1"] = "value 1";
+
+ std::vector< std::string > test_program_names;
+ test_program_names.push_back("test-program-1");
+
+ atf::tests::vars_map properties;
+ properties["test-suite"] = "a test name";
+
+ const atf::atf_run::atffile atffile(config_vars, test_program_names,
+ properties);
+ ATF_CHECK(config_vars == atffile.conf());
+ ATF_CHECK(test_program_names == atffile.tps());
+ ATF_CHECK(properties == atffile.props());
+}
+
+// ------------------------------------------------------------------------
+// Tests cases for the free functions.
+// ------------------------------------------------------------------------
+
+ATF_TEST_CASE(read_ok_simple);
+ATF_TEST_CASE_HEAD(read_ok_simple) {
+ set_md_var("use.fs", "true");
+}
+ATF_TEST_CASE_BODY(read_ok_simple) {
+ std::auto_ptr< std::ofstream > os = new_atffile();
+ (*os) << "prop: test-suite = foo\n";
+ (*os) << "tp: tp-1\n";
+ (*os) << "conf: var1 = value1\n";
+ (*os) << "tp: tp-2\n";
+ (*os) << "tp: tp-3\n";
+ (*os) << "prop: prop1 = propvalue1\n";
+ (*os) << "conf: var2 = value2\n";
+ (*os).close();
+
+ touch_exec("tp-1");
+ touch_exec("tp-2");
+ touch_exec("tp-3");
+
+ const atf::atf_run::atffile atffile = atf::atf_run::read_atffile(
+ atf::fs::path("Atffile"));
+ ATF_CHECK_EQUAL(2, atffile.conf().size());
+ ATF_CHECK_EQUAL("value1", atffile.conf().find("var1")->second);
+ ATF_CHECK_EQUAL("value2", atffile.conf().find("var2")->second);
+ ATF_CHECK_EQUAL(3, atffile.tps().size());
+ ATF_CHECK(is_in("tp-1", atffile.tps()));
+ ATF_CHECK(is_in("tp-2", atffile.tps()));
+ ATF_CHECK(is_in("tp-3", atffile.tps()));
+ ATF_CHECK_EQUAL(2, atffile.props().size());
+ ATF_CHECK_EQUAL("foo", atffile.props().find("test-suite")->second);
+ ATF_CHECK_EQUAL("propvalue1", atffile.props().find("prop1")->second);
+}
+
+ATF_TEST_CASE(read_ok_some_globs);
+ATF_TEST_CASE_HEAD(read_ok_some_globs) {
+ set_md_var("use.fs", "true");
+}
+ATF_TEST_CASE_BODY(read_ok_some_globs) {
+ std::auto_ptr< std::ofstream > os = new_atffile();
+ (*os) << "prop: test-suite = foo\n";
+ (*os) << "tp: foo\n";
+ (*os) << "tp-glob: *K*\n";
+ (*os) << "tp: bar\n";
+ (*os) << "tp-glob: t_*\n";
+ (*os).close();
+
+ touch_exec("foo");
+ touch_exec("bar");
+ touch_exec("aK");
+ touch_exec("KKKKK");
+ touch_exec("t_hello");
+ touch_exec("zzzt_hello");
+
+ const atf::atf_run::atffile atffile = atf::atf_run::read_atffile(
+ atf::fs::path("Atffile"));
+ ATF_CHECK_EQUAL(5, atffile.tps().size());
+ ATF_CHECK(is_in("foo", atffile.tps()));
+ ATF_CHECK(is_in("bar", atffile.tps()));
+ ATF_CHECK(is_in("aK", atffile.tps()));
+ ATF_CHECK(is_in("KKKKK", atffile.tps()));
+ ATF_CHECK(is_in("t_hello", atffile.tps()));
+}
+
+ATF_TEST_CASE(read_missing_test_suite);
+ATF_TEST_CASE_HEAD(read_missing_test_suite) {
+ set_md_var("use.fs", "true");
+}
+ATF_TEST_CASE_BODY(read_missing_test_suite) {
+ std::auto_ptr< std::ofstream > os = new_atffile();
+ (*os).close();
+
+ try {
+ (void)atf::atf_run::read_atffile(atf::fs::path("Atffile"));
+ ATF_FAIL("Missing property 'test-suite' did not raise an error");
+ } catch (const atf::not_found_error< std::string >& e) {
+ ATF_CHECK_EQUAL("test-suite", e.get_value());
+ }
+}
+
+ATF_TEST_CASE(read_missing_test_program);
+ATF_TEST_CASE_HEAD(read_missing_test_program) {
+ set_md_var("use.fs", "true");
+}
+ATF_TEST_CASE_BODY(read_missing_test_program) {
+ std::auto_ptr< std::ofstream > os = new_atffile();
+ (*os) << "tp: foo\n";
+ (*os) << "tp: bar\n";
+ (*os) << "tp: baz\n";
+ (*os).close();
+
+ touch_exec("foo");
+ touch_exec("baz");
+
+ try {
+ (void)atf::atf_run::read_atffile(atf::fs::path("Atffile"));
+ ATF_FAIL("Missing file 'bar' did not raise an error");
+ } catch (const atf::not_found_error< atf::fs::path >& e) {
+ ATF_CHECK_EQUAL("bar", e.get_value().str());
+ }
+}
+
+// ------------------------------------------------------------------------
+// Main.
+// ------------------------------------------------------------------------
+
+ATF_INIT_TEST_CASES(tcs)
+{
+ // Add the test cases for the parser class.
+ ATF_ADD_TEST_CASE(tcs, atffile_1);
+ ATF_ADD_TEST_CASE(tcs, atffile_2);
+ ATF_ADD_TEST_CASE(tcs, atffile_3);
+ ATF_ADD_TEST_CASE(tcs, atffile_4);
+ ATF_ADD_TEST_CASE(tcs, atffile_5);
+ ATF_ADD_TEST_CASE(tcs, atffile_6);
+ ATF_ADD_TEST_CASE(tcs, atffile_50);
+ ATF_ADD_TEST_CASE(tcs, atffile_51);
+ ATF_ADD_TEST_CASE(tcs, atffile_52);
+ ATF_ADD_TEST_CASE(tcs, atffile_53);
+ ATF_ADD_TEST_CASE(tcs, atffile_54);
+
+ // Add the test cases for the atffile class.
+ ATF_ADD_TEST_CASE(tcs, atffile_getters);
+
+ // Add the test cases for the free functions.
+ ATF_ADD_TEST_CASE(tcs, read_ok_simple);
+ ATF_ADD_TEST_CASE(tcs, read_ok_some_globs);
+ ATF_ADD_TEST_CASE(tcs, read_missing_test_suite);
+ ATF_ADD_TEST_CASE(tcs, read_missing_test_program);
+}
diff --git a/external/bsd/atf/dist/atf-run/bad_metadata_helper.c b/external/bsd/atf/dist/atf-run/bad_metadata_helper.c
new file mode 100644
index 00000000000..0f7fcb926ac
--- /dev/null
+++ b/external/bsd/atf/dist/atf-run/bad_metadata_helper.c
@@ -0,0 +1,38 @@
+/*
+ * Automated Testing Framework (atf)
+ *
+ * Copyright (c) 2010 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+int
+main(void)
+{
+ printf("incorrectly formatted metadata\n");
+ return EXIT_SUCCESS;
+}
diff --git a/external/bsd/atf/dist/atf-run/config.cpp b/external/bsd/atf/dist/atf-run/config.cpp
index 4af9b1812ee..481b882ccaf 100644
--- a/external/bsd/atf/dist/atf-run/config.cpp
+++ b/external/bsd/atf/dist/atf-run/config.cpp
@@ -32,16 +32,41 @@
#include "atf-c++/config.hpp"
#include "atf-c++/env.hpp"
-#include "atf-c++/formats.hpp"
#include "atf-c++/fs.hpp"
+#include "atf-c++/sanity.hpp"
+#include "atf-c++/parser.hpp"
#include "config.hpp"
namespace impl = atf::atf_run;
+namespace detail = atf::atf_run::detail;
namespace {
-class config_reader : public atf::formats::atf_config_reader {
+namespace atf_config {
+
+static const atf::parser::token_type& eof_type = 0;
+static const atf::parser::token_type& nl_type = 1;
+static const atf::parser::token_type& text_type = 2;
+static const atf::parser::token_type& dblquote_type = 3;
+static const atf::parser::token_type& equal_type = 4;
+static const atf::parser::token_type& hash_type = 5;
+
+class tokenizer : public atf::parser::tokenizer< std::istream > {
+public:
+ tokenizer(std::istream& is, size_t curline) :
+ atf::parser::tokenizer< std::istream >
+ (is, true, eof_type, nl_type, text_type, curline)
+ {
+ add_delim('=', equal_type);
+ add_delim('#', hash_type);
+ add_quote('"', dblquote_type);
+ }
+};
+
+} // namespace atf_config
+
+class config_reader : public detail::atf_config_reader {
atf::tests::vars_map m_vars;
void
@@ -52,7 +77,7 @@ class config_reader : public atf::formats::atf_config_reader {
public:
config_reader(std::istream& is) :
- atf::formats::atf_config_reader(is)
+ atf_config_reader(is)
{
}
@@ -100,6 +125,76 @@ get_config_dirs(void)
} // anonymous namespace
+detail::atf_config_reader::atf_config_reader(std::istream& is) :
+ m_is(is)
+{
+}
+
+detail::atf_config_reader::~atf_config_reader(void)
+{
+}
+
+void
+detail::atf_config_reader::got_var(const std::string& var,
+ const std::string& val)
+{
+}
+
+void
+detail::atf_config_reader::got_eof(void)
+{
+}
+
+void
+detail::atf_config_reader::read(void)
+{
+ using atf::parser::parse_error;
+ using namespace atf_config;
+
+ std::pair< size_t, atf::parser::headers_map > hml =
+ atf::parser::read_headers(m_is, 1);
+ atf::parser::validate_content_type(hml.second,
+ "application/X-atf-config", 1);
+
+ tokenizer tkz(m_is, hml.first);
+ atf::parser::parser< tokenizer > p(tkz);
+
+ for (;;) {
+ try {
+ atf::parser::token t = p.expect(eof_type, hash_type, text_type,
+ nl_type,
+ "eof, #, new line or text");
+ if (t.type() == eof_type)
+ break;
+
+ if (t.type() == hash_type) {
+ (void)p.rest_of_line();
+ t = p.expect(nl_type, "new line");
+ } else if (t.type() == text_type) {
+ std::string name = t.text();
+
+ t = p.expect(equal_type, "equal sign");
+
+ t = p.expect(text_type, "word or quoted string");
+ ATF_PARSER_CALLBACK(p, got_var(name, t.text()));
+
+ t = p.expect(nl_type, hash_type, "new line or comment");
+ if (t.type() == hash_type) {
+ (void)p.rest_of_line();
+ t = p.expect(nl_type, "new line");
+ }
+ } else if (t.type() == nl_type) {
+ } else
+ UNREACHABLE;
+ } catch (const parse_error& pe) {
+ p.add_error(pe);
+ p.reset(nl_type);
+ }
+ }
+
+ ATF_PARSER_CALLBACK(p, got_eof());
+}
+
atf::tests::vars_map
impl::merge_configs(const atf::tests::vars_map& lower,
const atf::tests::vars_map& upper)
diff --git a/external/bsd/atf/dist/atf-run/config.hpp b/external/bsd/atf/dist/atf-run/config.hpp
index 203040a6109..c4f08b743f0 100644
--- a/external/bsd/atf/dist/atf-run/config.hpp
+++ b/external/bsd/atf/dist/atf-run/config.hpp
@@ -35,6 +35,24 @@
namespace atf {
namespace atf_run {
+namespace detail {
+
+class atf_config_reader {
+ std::istream& m_is;
+
+protected:
+ virtual void got_var(const std::string&, const std::string &);
+ virtual void got_eof(void);
+
+public:
+ atf_config_reader(std::istream&);
+ virtual ~atf_config_reader(void);
+
+ void read(void);
+};
+
+} // namespace detail
+
atf::tests::vars_map merge_configs(const atf::tests::vars_map&,
const atf::tests::vars_map&);
atf::tests::vars_map read_config_files(const std::string&);
diff --git a/external/bsd/atf/dist/atf-run/config_test.cpp b/external/bsd/atf/dist/atf-run/config_test.cpp
new file mode 100644
index 00000000000..c5d260cf037
--- /dev/null
+++ b/external/bsd/atf/dist/atf-run/config_test.cpp
@@ -0,0 +1,380 @@
+//
+// Automated Testing Framework (atf)
+//
+// Copyright (c) 2010 The NetBSD Foundation, Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
+// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#include "atf-c++/macros.hpp"
+
+#include "config.hpp"
+
+#include "test_helpers.hpp"
+
+namespace impl = atf::atf_run;
+namespace detail = atf::atf_run::detail;
+
+using atf::tests::vars_map;
+
+// -------------------------------------------------------------------------
+// Tests for the "config" parser.
+// -------------------------------------------------------------------------
+
+class config_reader : protected detail::atf_config_reader {
+ void
+ got_var(const std::string& name, const std::string& val)
+ {
+ m_calls.push_back("got_var(" + name + ", " + val + ")");
+ }
+
+ void
+ got_eof(void)
+ {
+ m_calls.push_back("got_eof()");
+ }
+
+public:
+ config_reader(std::istream& is) :
+ detail::atf_config_reader(is)
+ {
+ }
+
+ void
+ read(void)
+ {
+ atf_config_reader::read();
+ }
+
+ std::vector< std::string > m_calls;
+};
+
+ATF_TEST_CASE_WITHOUT_HEAD(config_1);
+ATF_TEST_CASE_BODY(config_1)
+{
+ const char* input =
+ "Content-Type: application/X-atf-config; version=\"1\"\n"
+ "\n"
+ ;
+
+ const char* exp_calls[] = {
+ "got_eof()",
+ NULL
+ };
+
+ const char* exp_errors[] = {
+ NULL
+ };
+
+ do_parser_test< config_reader >(input, exp_calls, exp_errors);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(config_2);
+ATF_TEST_CASE_BODY(config_2)
+{
+ const char* input =
+ "Content-Type: application/X-atf-config; version=\"1\"\n"
+ "\n"
+ "# This is a comment on a line of its own.\n"
+ "# And this is another one.\n"
+ "\n"
+ " # Another after some whitespace.\n"
+ "\n"
+ "# The last one after an empty line.\n"
+ ;
+
+ const char* exp_calls[] = {
+ "got_eof()",
+ NULL
+ };
+
+ const char* exp_errors[] = {
+ NULL
+ };
+
+ do_parser_test< config_reader >(input, exp_calls, exp_errors);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(config_3);
+ATF_TEST_CASE_BODY(config_3)
+{
+ const char* input =
+ "Content-Type: application/X-atf-config; version=\"1\"\n"
+ "\n"
+ "var1=value1\n"
+ "var2 = value2\n"
+ "var3 = value3\n"
+ "var4 = value4\n"
+ "\n"
+ "var5=value5\n"
+ " var6=value6\n"
+ "\n"
+ "var7 = \"This is a long value.\"\n"
+ "var8 = \"Single-word\"\n"
+ "var9 = \" Single-word \"\n"
+ "var10 = Single-word\n"
+ ;
+
+ const char* exp_calls[] = {
+ "got_var(var1, value1)",
+ "got_var(var2, value2)",
+ "got_var(var3, value3)",
+ "got_var(var4, value4)",
+ "got_var(var5, value5)",
+ "got_var(var6, value6)",
+ "got_var(var7, This is a long value.)",
+ "got_var(var8, Single-word)",
+ "got_var(var9, Single-word )",
+ "got_var(var10, Single-word)",
+ "got_eof()",
+ NULL
+ };
+
+ const char* exp_errors[] = {
+ NULL
+ };
+
+ do_parser_test< config_reader >(input, exp_calls, exp_errors);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(config_4);
+ATF_TEST_CASE_BODY(config_4)
+{
+ const char* input =
+ "Content-Type: application/X-atf-config; version=\"1\"\n"
+ "\n"
+ "foo = bar # A comment.\n"
+ ;
+
+ const char* exp_calls[] = {
+ "got_var(foo, bar)",
+ "got_eof()",
+ NULL
+ };
+
+ const char* exp_errors[] = {
+ NULL
+ };
+
+ do_parser_test< config_reader >(input, exp_calls, exp_errors);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(config_50);
+ATF_TEST_CASE_BODY(config_50)
+{
+ const char* input =
+ "Content-Type: application/X-atf-config; version=\"1\"\n"
+ "\n"
+ "foo\n"
+ ;
+
+ const char* exp_calls[] = {
+ NULL
+ };
+
+ const char* exp_errors[] = {
+ "3: Unexpected token `<<NEWLINE>>'; expected equal sign",
+ NULL
+ };
+
+ do_parser_test< config_reader >(input, exp_calls, exp_errors);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(config_51);
+ATF_TEST_CASE_BODY(config_51)
+{
+ const char* input =
+ "Content-Type: application/X-atf-config; version=\"1\"\n"
+ "\n"
+ "foo bar\n"
+ "baz\n"
+ ;
+
+ const char* exp_calls[] = {
+ NULL
+ };
+
+ const char* exp_errors[] = {
+ "3: Unexpected token `bar'; expected equal sign",
+ "4: Unexpected token `<<NEWLINE>>'; expected equal sign",
+ NULL
+ };
+
+ do_parser_test< config_reader >(input, exp_calls, exp_errors);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(config_52);
+ATF_TEST_CASE_BODY(config_52)
+{
+ const char* input =
+ "Content-Type: application/X-atf-config; version=\"1\"\n"
+ "\n"
+ "foo =\n"
+ "bar = # A comment.\n"
+ ;
+
+ const char* exp_calls[] = {
+ NULL
+ };
+
+ const char* exp_errors[] = {
+ "3: Unexpected token `<<NEWLINE>>'; expected word or quoted string",
+ "4: Unexpected token `#'; expected word or quoted string",
+ NULL
+ };
+
+ do_parser_test< config_reader >(input, exp_calls, exp_errors);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(config_53);
+ATF_TEST_CASE_BODY(config_53)
+{
+ const char* input =
+ "Content-Type: application/X-atf-config; version=\"1\"\n"
+ "\n"
+ "foo = \"Correct value\" # With comment.\n"
+ "\n"
+ "bar = # A comment.\n"
+ "\n"
+ "baz = \"Last variable\"\n"
+ "\n"
+ "# End of file.\n"
+ ;
+
+ const char* exp_calls[] = {
+ "got_var(foo, Correct value)",
+ NULL
+ };
+
+ const char* exp_errors[] = {
+ "5: Unexpected token `#'; expected word or quoted string",
+ NULL
+ };
+
+ do_parser_test< config_reader >(input, exp_calls, exp_errors);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(config_54);
+ATF_TEST_CASE_BODY(config_54)
+{
+ const char* input =
+ "Content-Type: application/X-atf-config; version=\"1\"\n"
+ "\n"
+ "foo = \"\n"
+ "bar = \"text\n"
+ "baz = \"te\\\"xt\n"
+ "last = \"\\\"\n"
+ ;
+
+ const char* exp_calls[] = {
+ NULL
+ };
+
+ const char* exp_errors[] = {
+ "3: Missing double quotes before end of line",
+ "4: Missing double quotes before end of line",
+ "5: Missing double quotes before end of line",
+ "6: Missing double quotes before end of line",
+ NULL
+ };
+
+ do_parser_test< config_reader >(input, exp_calls, exp_errors);
+}
+
+// -------------------------------------------------------------------------
+// Tests for the free functions.
+// -------------------------------------------------------------------------
+
+ATF_TEST_CASE(merge_configs_both_empty);
+ATF_TEST_CASE_HEAD(merge_configs_both_empty) {}
+ATF_TEST_CASE_BODY(merge_configs_both_empty) {
+ vars_map lower, upper;
+
+ ATF_CHECK(impl::merge_configs(lower, upper).empty());
+}
+
+ATF_TEST_CASE(merge_configs_lower_empty);
+ATF_TEST_CASE_HEAD(merge_configs_lower_empty) {}
+ATF_TEST_CASE_BODY(merge_configs_lower_empty) {
+ vars_map lower, upper;
+ upper["var"] = "value";
+
+ vars_map merged = impl::merge_configs(lower, upper);
+ ATF_CHECK_EQUAL("value", merged["var"]);
+}
+
+ATF_TEST_CASE(merge_configs_upper_empty);
+ATF_TEST_CASE_HEAD(merge_configs_upper_empty) {}
+ATF_TEST_CASE_BODY(merge_configs_upper_empty) {
+ vars_map lower, upper;
+ lower["var"] = "value";
+
+ vars_map merged = impl::merge_configs(lower, upper);
+ ATF_CHECK_EQUAL("value", merged["var"]);
+}
+
+ATF_TEST_CASE(merge_configs_mixed);
+ATF_TEST_CASE_HEAD(merge_configs_mixed) {}
+ATF_TEST_CASE_BODY(merge_configs_mixed) {
+ vars_map lower, upper;
+ lower["var1"] = "value1";
+ lower["var2"] = "value2-l";
+ upper["var2"] = "value2-u";
+ upper["var3"] = "value3";
+
+ vars_map merged = impl::merge_configs(lower, upper);
+ ATF_CHECK_EQUAL("value1", merged["var1"]);
+ ATF_CHECK_EQUAL("value2-u", merged["var2"]);
+ ATF_CHECK_EQUAL("value3", merged["var3"]);
+}
+
+ATF_TEST_CASE(read_config_files_none);
+ATF_TEST_CASE_HEAD(read_config_files_none) {}
+ATF_TEST_CASE_BODY(read_config_files_none) {
+ ATF_CHECK(vars_map() == impl::read_config_files("test-suite"));
+}
+
+// -------------------------------------------------------------------------
+// Main.
+// -------------------------------------------------------------------------
+
+ATF_INIT_TEST_CASES(tcs)
+{
+ ATF_ADD_TEST_CASE(tcs, config_1);
+ ATF_ADD_TEST_CASE(tcs, config_2);
+ ATF_ADD_TEST_CASE(tcs, config_3);
+ ATF_ADD_TEST_CASE(tcs, config_4);
+ ATF_ADD_TEST_CASE(tcs, config_50);
+ ATF_ADD_TEST_CASE(tcs, config_51);
+ ATF_ADD_TEST_CASE(tcs, config_52);
+ ATF_ADD_TEST_CASE(tcs, config_53);
+ ATF_ADD_TEST_CASE(tcs, config_54);
+
+ ATF_ADD_TEST_CASE(tcs, merge_configs_both_empty);
+ ATF_ADD_TEST_CASE(tcs, merge_configs_lower_empty);
+ ATF_ADD_TEST_CASE(tcs, merge_configs_upper_empty);
+ ATF_ADD_TEST_CASE(tcs, merge_configs_mixed);
+
+ ATF_ADD_TEST_CASE(tcs, read_config_files_none);
+}
diff --git a/external/bsd/atf/dist/atf-run/expect_helpers.c b/external/bsd/atf/dist/atf-run/expect_helpers.c
new file mode 100644
index 00000000000..b38ccf574bc
--- /dev/null
+++ b/external/bsd/atf/dist/atf-run/expect_helpers.c
@@ -0,0 +1,193 @@
+/*
+ * Automated Testing Framework (atf)
+ *
+ * Copyright (c) 2010 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <signal.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <atf-c.h>
+
+ATF_TC_WITHOUT_HEAD(pass_and_pass);
+ATF_TC_BODY(pass_and_pass, tc)
+{
+ atf_tc_expect_pass();
+}
+
+ATF_TC_WITHOUT_HEAD(pass_but_fail_requirement);
+ATF_TC_BODY(pass_but_fail_requirement, tc)
+{
+ atf_tc_expect_pass();
+ atf_tc_fail("Some reason");
+}
+
+ATF_TC_WITHOUT_HEAD(pass_but_fail_check);
+ATF_TC_BODY(pass_but_fail_check, tc)
+{
+ atf_tc_expect_pass();
+ atf_tc_fail_nonfatal("Some reason");
+}
+
+ATF_TC_WITHOUT_HEAD(fail_and_fail_requirement);
+ATF_TC_BODY(fail_and_fail_requirement, tc)
+{
+ atf_tc_expect_fail("Fail %s", "reason");
+ atf_tc_fail("The failure");
+ atf_tc_expect_pass();
+}
+
+ATF_TC_WITHOUT_HEAD(fail_and_fail_check);
+ATF_TC_BODY(fail_and_fail_check, tc)
+{
+ atf_tc_expect_fail("Fail first");
+ atf_tc_fail_nonfatal("abc");
+ atf_tc_expect_pass();
+
+ atf_tc_expect_fail("And fail again");
+ atf_tc_fail_nonfatal("def");
+ atf_tc_expect_pass();
+}
+
+ATF_TC_WITHOUT_HEAD(fail_but_pass);
+ATF_TC_BODY(fail_but_pass, tc)
+{
+ atf_tc_expect_fail("Fail first");
+ atf_tc_fail_nonfatal("abc");
+ atf_tc_expect_pass();
+
+ atf_tc_expect_fail("Will not fail");
+ atf_tc_expect_pass();
+
+ atf_tc_expect_fail("And fail again");
+ atf_tc_fail_nonfatal("def");
+ atf_tc_expect_pass();
+}
+
+ATF_TC_WITHOUT_HEAD(exit_any_and_exit);
+ATF_TC_BODY(exit_any_and_exit, tc)
+{
+ atf_tc_expect_exit(-1, "Call will exit");
+ exit(EXIT_SUCCESS);
+}
+
+ATF_TC_WITHOUT_HEAD(exit_code_and_exit);
+ATF_TC_BODY(exit_code_and_exit, tc)
+{
+ atf_tc_expect_exit(123, "Call will exit");
+ exit(123);
+}
+
+ATF_TC_WITHOUT_HEAD(exit_but_pass);
+ATF_TC_BODY(exit_but_pass, tc)
+{
+ atf_tc_expect_exit(-1, "Call won't exit");
+}
+
+ATF_TC_WITHOUT_HEAD(signal_any_and_signal);
+ATF_TC_BODY(signal_any_and_signal, tc)
+{
+ atf_tc_expect_signal(-1, "Call will signal");
+ kill(getpid(), SIGKILL);
+}
+
+ATF_TC_WITHOUT_HEAD(signal_no_and_signal);
+ATF_TC_BODY(signal_no_and_signal, tc)
+{
+ atf_tc_expect_signal(SIGHUP, "Call will signal");
+ kill(getpid(), SIGHUP);
+}
+
+ATF_TC_WITHOUT_HEAD(signal_but_pass);
+ATF_TC_BODY(signal_but_pass, tc)
+{
+ atf_tc_expect_signal(-1, "Call won't signal");
+}
+
+ATF_TC_WITHOUT_HEAD(death_and_exit);
+ATF_TC_BODY(death_and_exit, tc)
+{
+ atf_tc_expect_death("Exit case");
+ exit(123);
+}
+
+ATF_TC_WITHOUT_HEAD(death_and_signal);
+ATF_TC_BODY(death_and_signal, tc)
+{
+ atf_tc_expect_death("Signal case");
+ kill(getpid(), SIGKILL);
+}
+
+ATF_TC_WITHOUT_HEAD(death_but_pass);
+ATF_TC_BODY(death_but_pass, tc)
+{
+ atf_tc_expect_death("Call won't die");
+}
+
+ATF_TC(timeout_and_hang);
+ATF_TC_HEAD(timeout_and_hang, tc)
+{
+ atf_tc_set_md_var(tc, "timeout", "1");
+}
+ATF_TC_BODY(timeout_and_hang, tc)
+{
+ atf_tc_expect_timeout("Will overrun");
+ sleep(5);
+}
+
+ATF_TC(timeout_but_pass);
+ATF_TC_HEAD(timeout_but_pass, tc)
+{
+ atf_tc_set_md_var(tc, "timeout", "1");
+}
+ATF_TC_BODY(timeout_but_pass, tc)
+{
+ atf_tc_expect_timeout("Will just exit");
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, pass_and_pass);
+ ATF_TP_ADD_TC(tp, pass_but_fail_requirement);
+ ATF_TP_ADD_TC(tp, pass_but_fail_check);
+ ATF_TP_ADD_TC(tp, fail_and_fail_requirement);
+ ATF_TP_ADD_TC(tp, fail_and_fail_check);
+ ATF_TP_ADD_TC(tp, fail_but_pass);
+ ATF_TP_ADD_TC(tp, exit_any_and_exit);
+ ATF_TP_ADD_TC(tp, exit_code_and_exit);
+ ATF_TP_ADD_TC(tp, exit_but_pass);
+ ATF_TP_ADD_TC(tp, signal_any_and_signal);
+ ATF_TP_ADD_TC(tp, signal_no_and_signal);
+ ATF_TP_ADD_TC(tp, signal_but_pass);
+ ATF_TP_ADD_TC(tp, death_and_exit);
+ ATF_TP_ADD_TC(tp, death_and_signal);
+ ATF_TP_ADD_TC(tp, death_but_pass);
+ ATF_TP_ADD_TC(tp, timeout_and_hang);
+ ATF_TP_ADD_TC(tp, timeout_but_pass);
+
+ return atf_no_error();
+}
diff --git a/external/bsd/atf/dist/atf-run/fs.cpp b/external/bsd/atf/dist/atf-run/fs.cpp
new file mode 100644
index 00000000000..f7bec1a01ac
--- /dev/null
+++ b/external/bsd/atf/dist/atf-run/fs.cpp
@@ -0,0 +1,255 @@
+//
+// Automated Testing Framework (atf)
+//
+// Copyright (c) 2007, 2008, 2009 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(HAVE_CONFIG_H)
+#include "bconfig.h"
+#endif
+
+extern "C" {
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/mount.h>
+#include <sys/stat.h>
+
+#include <unistd.h>
+}
+
+#include <cerrno>
+#include <cstdlib>
+#include <cstring>
+
+#include "atf-c++/process.hpp"
+#include "atf-c++/user.hpp"
+
+#include "fs.hpp"
+
+namespace impl = atf::atf_run;
+#define IMPL_NAME "atf::atf_run"
+
+// ------------------------------------------------------------------------
+// Auxiliary functions.
+// ------------------------------------------------------------------------
+
+static void cleanup_aux(const atf::fs::path&, dev_t, bool);
+static void cleanup_aux_dir(const atf::fs::path&, const atf::fs::file_info&,
+ bool);
+static void do_unmount(const atf::fs::path&);
+
+// The erase parameter in this routine is to control nested mount points.
+// We want to descend into a mount point to unmount anything that is
+// mounted under it, but we do not want to delete any files while doing
+// this traversal. In other words, we erase files until we cross the
+// first mount point, and after that point we only scan and unmount.
+static
+void
+cleanup_aux(const atf::fs::path& p, dev_t parent_device, bool erase)
+{
+ atf::fs::file_info fi(p);
+
+ if (fi.get_type() == atf::fs::file_info::dir_type)
+ cleanup_aux_dir(p, fi, fi.get_device() == parent_device);
+
+ if (fi.get_device() != parent_device)
+ do_unmount(p);
+
+ if (erase) {
+ if (fi.get_type() == atf::fs::file_info::dir_type)
+ atf::fs::rmdir(p);
+ else
+ atf::fs::remove(p);
+ }
+}
+
+static
+void
+cleanup_aux_dir(const atf::fs::path& p, const atf::fs::file_info& fi,
+ bool erase)
+{
+ if (erase && ((fi.get_mode() & S_IRWXU) != S_IRWXU)) {
+ (void)impl::set_immutable(p, false);
+
+ if (chmod(p.c_str(), fi.get_mode() | S_IRWXU) == -1)
+ throw atf::system_error(IMPL_NAME "::cleanup(" +
+ p.str() + ")", "chmod(2) failed", errno);
+ }
+
+ std::set< std::string > subdirs;
+ {
+ const atf::fs::directory d(p);
+ subdirs = d.names();
+ }
+
+ for (std::set< std::string >::const_iterator iter = subdirs.begin();
+ iter != subdirs.end(); iter++) {
+ const std::string& name = *iter;
+ if (name != "." && name != "..")
+ cleanup_aux(p / name, fi.get_device(), erase);
+ }
+}
+
+static
+void
+do_unmount(const atf::fs::path& in_path)
+{
+ // At least, FreeBSD's unmount(2) requires the path to be absolute.
+ // Let's make it absolute in all cases just to be safe that this does
+ // not affect other systems.
+ const atf::fs::path& abs_path = in_path.is_absolute() ?
+ in_path : in_path.to_absolute();
+
+#if defined(HAVE_UNMOUNT)
+ if (unmount(abs_path.c_str(), 0) == -1)
+ throw atf::system_error(IMPL_NAME "::cleanup(" + in_path.str() + ")",
+ "unmount(2) failed", errno);
+#else
+ // We could use umount(2) instead if it was available... but
+ // trying to do so under, e.g. Linux, is a nightmare because we
+ // also have to update /etc/mtab to match what we did. It is
+ // satf::fser to just leave the system-specific umount(8) tool deal
+ // with it, at least for now.
+
+ const atf::fs::path prog("umount");
+ atf::process::argv_array argv("umount", abs_path.c_str(), NULL);
+
+ atf::process::status s = atf::process::exec(prog, argv,
+ atf::process::stream_inherit(), atf::process::stream_inherit());
+ if (!s.exited() || s.exitstatus() != EXIT_SUCCESS)
+ throw std::runtime_error("Call to unmount failed");
+#endif
+}
+
+// ------------------------------------------------------------------------
+// The "temp_dir" class.
+// ------------------------------------------------------------------------
+
+impl::temp_dir::temp_dir(const atf::fs::path& p)
+{
+ atf::utils::auto_array< char > buf(new char[p.str().length() + 1]);
+ std::strcpy(buf.get(), p.c_str());
+ if (::mkdtemp(buf.get()) == NULL)
+ throw system_error(IMPL_NAME "::temp_dir::temp_dir(" +
+ p.str() + ")", "mkdtemp(3) failed",
+ errno);
+
+ m_path.reset(new atf::fs::path(buf.get()));
+}
+
+impl::temp_dir::~temp_dir(void)
+{
+ cleanup(*m_path);
+}
+
+const atf::fs::path&
+impl::temp_dir::get_path(void)
+ const
+{
+ return *m_path;
+}
+
+// ------------------------------------------------------------------------
+// Free functions.
+// ------------------------------------------------------------------------
+
+atf::fs::path
+impl::change_directory(const atf::fs::path& dir)
+{
+ atf::fs::path olddir = get_current_dir();
+
+ if (olddir != dir) {
+ if (::chdir(dir.c_str()) == -1)
+ throw system_error(IMPL_NAME "::chdir(" + dir.str() + ")",
+ "chdir(2) failed", errno);
+ }
+
+ return olddir;
+}
+
+void
+impl::cleanup(const atf::fs::path& p)
+{
+ atf::fs::file_info fi(p);
+ cleanup_aux(p, fi.get_device(), true);
+}
+
+atf::fs::path
+impl::get_current_dir(void)
+{
+ std::auto_ptr< char > cwd;
+#if defined(HAVE_GETCWD_DYN)
+ cwd.reset(getcwd(NULL, 0));
+#else
+ cwd.reset(getcwd(NULL, MAXPATHLEN));
+#endif
+ if (cwd.get() == NULL)
+ throw atf::system_error(IMPL_NAME "::get_current_dir()",
+ "getcwd() failed", errno);
+
+ return atf::fs::path(cwd.get());
+}
+
+bool
+impl::set_immutable(const atf::fs::path& p, bool value)
+{
+#if HAVE_CHFLAGS
+ struct stat sb;
+ if (::lstat(p.c_str(), &sb) == -1)
+ throw atf::system_error(IMPL_NAME "::set_immutable(" + p.str() + ")",
+ "lstat(" + p.str() + ") failed", errno);
+
+ unsigned long new_flags = sb.st_flags;
+ if (value)
+ new_flags |= UF_IMMUTABLE;
+ else
+ new_flags &= ~UF_IMMUTABLE;
+
+ if (::chflags(p.c_str(), new_flags) == -1)
+ throw atf::system_error(IMPL_NAME "::set_immutable(" + p.str() + ")",
+ "chflags(" + p.str() + ") failed", errno);
+ return true;
+#elif HAVE_CHATTR
+ if (atf::user::is_root()) {
+ const atf::fs::path prog(CHATTR);
+ const atf::process::argv_array argv("chattr", value ? "+i" : "-i",
+ p.c_str(), NULL);
+
+ const atf::process::status s =
+ atf::process::exec(prog, argv, atf::process::stream_inherit(),
+ atf::process::stream_inherit());
+
+ if (!s.exited() || s.exitstatus() != EXIT_SUCCESS)
+ throw std::runtime_error("Failed to exec chattr");
+
+ return true;
+ } else {
+ return false;
+ }
+#else
+ return false;
+#endif
+}
diff --git a/external/bsd/atf/dist/atf-run/fs.hpp b/external/bsd/atf/dist/atf-run/fs.hpp
new file mode 100644
index 00000000000..fa80276de43
--- /dev/null
+++ b/external/bsd/atf/dist/atf-run/fs.hpp
@@ -0,0 +1,58 @@
+//
+// Automated Testing Framework (atf)
+//
+// Copyright (c) 2007, 2008, 2009 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_RUN_FS_HPP_)
+#define _ATF_RUN_FS_HPP_
+
+#include <memory>
+
+#include <atf-c++/fs.hpp>
+
+namespace atf {
+namespace atf_run {
+
+class temp_dir {
+ std::auto_ptr< atf::fs::path > m_path;
+
+public:
+ temp_dir(const atf::fs::path&);
+ ~temp_dir(void);
+
+ const atf::fs::path& get_path(void) const;
+};
+
+atf::fs::path change_directory(const atf::fs::path&);
+void cleanup(const atf::fs::path&);
+atf::fs::path get_current_dir(void);
+bool set_immutable(const atf::fs::path&, bool);
+
+} // namespace atf_run
+} // namespace atf
+
+#endif // !defined(_ATF_RUN_FS_HPP_)
diff --git a/external/bsd/atf/dist/atf-run/fs_test.cpp b/external/bsd/atf/dist/atf-run/fs_test.cpp
new file mode 100644
index 00000000000..fb2ba3daa4c
--- /dev/null
+++ b/external/bsd/atf/dist/atf-run/fs_test.cpp
@@ -0,0 +1,292 @@
+//
+// Automated Testing Framework (atf)
+//
+// Copyright (c) 2007, 2008, 2009, 2010 The NetBSD Foundation, Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
+// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+extern "C" {
+#include <sys/types.h>
+#include <sys/stat.h>
+}
+
+#include <cerrno>
+#include <fstream>
+
+#include "atf-c++/exceptions.hpp"
+#include "atf-c++/fs.hpp"
+#include "atf-c++/macros.hpp"
+#include "atf-c++/user.hpp"
+
+#include "fs.hpp"
+
+// ------------------------------------------------------------------------
+// Auxiliary functions.
+// ------------------------------------------------------------------------
+
+static
+void
+create_file(const char *name)
+{
+ std::ofstream os(name);
+ os.close();
+}
+
+// ------------------------------------------------------------------------
+// Test cases for the "temp_dir" class.
+// ------------------------------------------------------------------------
+
+ATF_TEST_CASE(temp_dir_raii);
+ATF_TEST_CASE_HEAD(temp_dir_raii)
+{
+ set_md_var("descr", "Tests the RAII behavior of the temp_dir class");
+ set_md_var("use.fs", "true");
+}
+ATF_TEST_CASE_BODY(temp_dir_raii)
+{
+ using atf::atf_run::temp_dir;
+
+ atf::fs::path t1("non-existent");
+ atf::fs::path t2("non-existent");
+
+ {
+ atf::fs::path tmpl("testdir.XXXXXX");
+ temp_dir td1(tmpl);
+ temp_dir td2(tmpl);
+ t1 = td1.get_path();
+ t2 = td2.get_path();
+ ATF_CHECK(t1.str().find("XXXXXX") == std::string::npos);
+ ATF_CHECK(t2.str().find("XXXXXX") == std::string::npos);
+ ATF_CHECK(t1 != t2);
+ ATF_CHECK(!atf::fs::exists(tmpl));
+ ATF_CHECK( atf::fs::exists(t1));
+ ATF_CHECK( atf::fs::exists(t2));
+
+ atf::fs::file_info fi1(t1);
+ ATF_CHECK( fi1.is_owner_readable());
+ ATF_CHECK( fi1.is_owner_writable());
+ ATF_CHECK( fi1.is_owner_executable());
+ ATF_CHECK(!fi1.is_group_readable());
+ ATF_CHECK(!fi1.is_group_writable());
+ ATF_CHECK(!fi1.is_group_executable());
+ ATF_CHECK(!fi1.is_other_readable());
+ ATF_CHECK(!fi1.is_other_writable());
+ ATF_CHECK(!fi1.is_other_executable());
+
+ atf::fs::file_info fi2(t2);
+ ATF_CHECK( fi2.is_owner_readable());
+ ATF_CHECK( fi2.is_owner_writable());
+ ATF_CHECK( fi2.is_owner_executable());
+ ATF_CHECK(!fi2.is_group_readable());
+ ATF_CHECK(!fi2.is_group_writable());
+ ATF_CHECK(!fi2.is_group_executable());
+ ATF_CHECK(!fi2.is_other_readable());
+ ATF_CHECK(!fi2.is_other_writable());
+ ATF_CHECK(!fi2.is_other_executable());
+ }
+
+ ATF_CHECK(t1.str() != "non-existent");
+ ATF_CHECK(!atf::fs::exists(t1));
+ ATF_CHECK(t2.str() != "non-existent");
+ ATF_CHECK(!atf::fs::exists(t2));
+}
+
+
+// ------------------------------------------------------------------------
+// Test cases for the free functions.
+// ------------------------------------------------------------------------
+
+ATF_TEST_CASE(cleanup);
+ATF_TEST_CASE_HEAD(cleanup)
+{
+ set_md_var("descr", "Tests the cleanup function");
+ set_md_var("use.fs", "true");
+}
+ATF_TEST_CASE_BODY(cleanup)
+{
+ using atf::atf_run::cleanup;
+
+ ::mkdir("root", 0755);
+ ::mkdir("root/dir", 0755);
+ ::mkdir("root/dir/1", 0100);
+ ::mkdir("root/dir/2", 0644);
+ create_file("root/reg");
+
+ atf::fs::path p("root");
+ ATF_CHECK(atf::fs::exists(p));
+ ATF_CHECK(atf::fs::exists(p / "dir"));
+ ATF_CHECK(atf::fs::exists(p / "dir/1"));
+ ATF_CHECK(atf::fs::exists(p / "dir/2"));
+ ATF_CHECK(atf::fs::exists(p / "reg"));
+ cleanup(p);
+ ATF_CHECK(!atf::fs::exists(p));
+}
+
+ATF_TEST_CASE(cleanup_eacces_on_root);
+ATF_TEST_CASE_HEAD(cleanup_eacces_on_root)
+{
+ set_md_var("descr", "Tests the cleanup function");
+ set_md_var("use.fs", "true");
+}
+ATF_TEST_CASE_BODY(cleanup_eacces_on_root)
+{
+ using atf::atf_run::cleanup;
+
+ ::mkdir("aux", 0755);
+ ::mkdir("aux/root", 0755);
+ ATF_CHECK(::chmod("aux", 0555) != -1);
+
+ try {
+ cleanup(atf::fs::path("aux/root"));
+ ATF_CHECK(atf::user::is_root());
+ } catch (const atf::system_error& e) {
+ ATF_CHECK(!atf::user::is_root());
+ ATF_CHECK_EQUAL(EACCES, e.code());
+ }
+}
+
+ATF_TEST_CASE(cleanup_eacces_on_subdir);
+ATF_TEST_CASE_HEAD(cleanup_eacces_on_subdir)
+{
+ set_md_var("descr", "Tests the cleanup function");
+ set_md_var("use.fs", "true");
+}
+ATF_TEST_CASE_BODY(cleanup_eacces_on_subdir)
+{
+ using atf::atf_run::cleanup;
+
+ ::mkdir("root", 0755);
+ ::mkdir("root/1", 0755);
+ ::mkdir("root/1/2", 0755);
+ ::mkdir("root/1/2/3", 0755);
+ ATF_CHECK(::chmod("root/1/2", 0555) != -1);
+ ATF_CHECK(::chmod("root/1", 0555) != -1);
+
+ const atf::fs::path p("root");
+ cleanup(p);
+ ATF_CHECK(!atf::fs::exists(p));
+}
+
+ATF_TEST_CASE(change_directory);
+ATF_TEST_CASE_HEAD(change_directory)
+{
+ set_md_var("descr", "Tests the change_directory function");
+ set_md_var("use.fs", "true");
+}
+ATF_TEST_CASE_BODY(change_directory)
+{
+ using atf::atf_run::change_directory;
+ using atf::atf_run::get_current_dir;
+
+ ::mkdir("files", 0755);
+ ::mkdir("files/dir", 0755);
+ create_file("files/reg");
+
+ const atf::fs::path old = get_current_dir();
+
+ ATF_CHECK_THROW(atf::system_error,
+ change_directory(atf::fs::path("files/reg")));
+ ATF_CHECK(get_current_dir() == old);
+
+ atf::fs::path old2 = change_directory(atf::fs::path("files"));
+ ATF_CHECK(old2 == old);
+ atf::fs::path old3 = change_directory(atf::fs::path("dir"));
+ ATF_CHECK(old3 == old2 / "files");
+ atf::fs::path old4 = change_directory(atf::fs::path("../.."));
+ ATF_CHECK(old4 == old3 / "dir");
+ ATF_CHECK(get_current_dir() == old);
+}
+
+ATF_TEST_CASE(get_current_dir);
+ATF_TEST_CASE_HEAD(get_current_dir)
+{
+ set_md_var("descr", "Tests the get_current_dir function");
+ set_md_var("use.fs", "true");
+}
+ATF_TEST_CASE_BODY(get_current_dir)
+{
+ using atf::atf_run::change_directory;
+ using atf::atf_run::get_current_dir;
+
+ ::mkdir("files", 0755);
+ ::mkdir("files/dir", 0755);
+ create_file("files/reg");
+
+ atf::fs::path curdir = get_current_dir();
+ change_directory(atf::fs::path("."));
+ ATF_CHECK(get_current_dir() == curdir);
+ change_directory(atf::fs::path("files"));
+ ATF_CHECK(get_current_dir() == curdir / "files");
+ change_directory(atf::fs::path("dir"));
+ ATF_CHECK(get_current_dir() == curdir / "files/dir");
+ change_directory(atf::fs::path(".."));
+ ATF_CHECK(get_current_dir() == curdir / "files");
+ change_directory(atf::fs::path(".."));
+ ATF_CHECK(get_current_dir() == curdir);
+}
+
+ATF_TEST_CASE(set_immutable);
+ATF_TEST_CASE_HEAD(set_immutable)
+{
+ set_md_var("descr", "Tests the set_immutable function");
+ set_md_var("use.fs", "true");
+}
+ATF_TEST_CASE_BODY(set_immutable)
+{
+ using atf::atf_run::set_immutable;
+
+ if (::mkdir("dir", 0755) == -1)
+ ATF_FAIL("Failed to create test directory");
+
+ if (!set_immutable(atf::fs::path("dir"), true))
+ ATF_SKIP("Don't know how to set the immutable flag");
+
+ if (::mkdir("dir/other", 0755) != -1)
+ ATF_FAIL("Immutable flag was not correctly set");
+
+ if (!set_immutable(atf::fs::path("dir"), false))
+ ATF_SKIP("Don't know how to unset the immutable flag");
+
+ if (::mkdir("dir/other", 0755) == -1)
+ ATF_FAIL("Immutable flag was not correctly unset");
+}
+
+// ------------------------------------------------------------------------
+// Main.
+// ------------------------------------------------------------------------
+
+ATF_INIT_TEST_CASES(tcs)
+{
+ // Add the tests for the "temp_dir" class.
+ ATF_ADD_TEST_CASE(tcs, temp_dir_raii);
+
+ // Add the tests for the free functions.
+ ATF_ADD_TEST_CASE(tcs, cleanup);
+ ATF_ADD_TEST_CASE(tcs, cleanup_eacces_on_root);
+ ATF_ADD_TEST_CASE(tcs, cleanup_eacces_on_subdir);
+ ATF_ADD_TEST_CASE(tcs, change_directory);
+ ATF_ADD_TEST_CASE(tcs, get_current_dir);
+ ATF_ADD_TEST_CASE(tcs, set_immutable);
+}
diff --git a/external/bsd/atf/dist/atf-run/integration_test.sh b/external/bsd/atf/dist/atf-run/integration_test.sh
new file mode 100644
index 00000000000..b086be1435e
--- /dev/null
+++ b/external/bsd/atf/dist/atf-run/integration_test.sh
@@ -0,0 +1,1067 @@
+#
+# Automated Testing Framework (atf)
+#
+# Copyright (c) 2007, 2008, 2009, 2010 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
+# CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+create_atffile()
+{
+ cat >Atffile <<EOF
+Content-Type: application/X-atf-atffile; version="1"
+
+prop: test-suite = atf
+
+EOF
+ for f in "${@}"; do
+ echo "tp: ${f}" >>Atffile
+ done
+}
+
+create_helper()
+{
+ cp $(atf_get_srcdir)/misc_helpers helper
+ create_atffile helper
+ TESTCASE=${1}; export TESTCASE
+}
+
+create_helper_stdin()
+{
+ # TODO: This really, really, really must use real test programs.
+ cat >${1} <<EOF
+#! $(atf-config -t atf_shell)
+while [ \${#} -gt 0 ]; do
+ case \${1} in
+ -l)
+ echo 'Content-Type: application/X-atf-tp; version="1"'
+ echo
+EOF
+ cnt=1
+ while [ ${cnt} -le ${2} ]; do
+ echo "echo 'ident: tc${cnt}'" >>${1}
+ [ ${cnt} -lt ${2} ] && echo "echo" >>${1}
+ cnt=$((${cnt} + 1))
+ done
+cat >>${1} <<EOF
+ exit 0
+ ;;
+ -r*)
+ resfile=\$(echo \${1} | cut -d r -f 2-)
+ ;;
+ esac
+ testcase=\$(echo \${1} | cut -d : -f 1)
+ shift
+done
+EOF
+ cat >>${1}
+}
+
+create_mount_helper()
+{
+ cat >${1} <<EOF
+#! /usr/bin/env atf-sh
+
+do_mount() {
+ platform=\$(uname)
+ case \${platform} in
+ Linux|NetBSD)
+ mount -t tmpfs tmpfs \${1} || atf_fail "Mount failed"
+ ;;
+ FreeBSD)
+ mdmfs -s 16m md \${1} || atf_fail "Mount failed"
+ ;;
+ SunOS)
+ mount -F tmpfs tmpfs \$(pwd)/\${1} || atf_fail "Mount failed"
+ ;;
+ *)
+ atf_fail "create_mount_helper called for an unsupported platform."
+ ;;
+ esac
+}
+
+atf_test_case main
+main_head() {
+ atf_set "use.fs" "true"
+ atf_set "require.user" "root"
+}
+main_body() {
+EOF
+ cat >>${1}
+ cat >>${1} <<EOF
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case main
+}
+EOF
+}
+
+atf_test_case config
+config_head()
+{
+ atf_set "descr" "Tests that the config files are read in the correct" \
+ "order"
+ atf_set "use.fs" "true"
+}
+config_body()
+{
+ create_helper config
+
+ mkdir etc
+ mkdir .atf
+
+ echo "First: read system-wide common.conf."
+ cat >etc/common.conf <<EOF
+Content-Type: application/X-atf-config; version="1"
+
+1st = "sw common"
+2nd = "sw common"
+3rd = "sw common"
+4th = "sw common"
+EOF
+ atf_check -s eq:0 \
+ -o match:'1st: sw common' \
+ -o match:'2nd: sw common' \
+ -o match:'3rd: sw common' \
+ -o match:'4th: sw common' \
+ -e ignore -x \
+ "ATF_CONFDIR=$(pwd)/etc HOME=$(pwd) atf-run helper"
+
+ echo "Second: read system-wide <test-suite>.conf."
+ cat >etc/atf.conf <<EOF
+Content-Type: application/X-atf-config; version="1"
+
+1st = "sw atf"
+EOF
+ atf_check -s eq:0 \
+ -o match:'1st: sw atf' \
+ -o match:'2nd: sw common' \
+ -o match:'3rd: sw common' \
+ -o match:'4th: sw common' \
+ -e ignore -x \
+ "ATF_CONFDIR=$(pwd)/etc HOME=$(pwd) atf-run helper"
+
+ echo "Third: read user-specific common.conf."
+ cat >.atf/common.conf <<EOF
+Content-Type: application/X-atf-config; version="1"
+
+2nd = "us common"
+EOF
+ atf_check -s eq:0 \
+ -o match:'1st: sw atf' \
+ -o match:'2nd: us common' \
+ -o match:'3rd: sw common' \
+ -o match:'4th: sw common' \
+ -e ignore -x \
+ "ATF_CONFDIR=$(pwd)/etc HOME=$(pwd) atf-run helper"
+
+ echo "Fourth: read user-specific <test-suite>.conf."
+ cat >.atf/atf.conf <<EOF
+Content-Type: application/X-atf-config; version="1"
+
+3rd = "us atf"
+EOF
+ atf_check -s eq:0 \
+ -o match:'1st: sw atf' \
+ -o match:'2nd: us common' \
+ -o match:'3rd: us atf' \
+ -o match:'4th: sw common' \
+ -e ignore -x \
+ "ATF_CONFDIR=$(pwd)/etc HOME=$(pwd) atf-run helper"
+}
+
+atf_test_case vflag
+vflag_head()
+{
+ atf_set "descr" "Tests that the -v flag works and that it properly" \
+ "overrides the values in configuration files"
+ atf_set "use.fs" "true"
+}
+vflag_body()
+{
+ create_helper testvar
+
+ echo "Checking that 'testvar' is not defined."
+ atf_check -s eq:1 -o ignore -e ignore -x \
+ "ATF_CONFDIR=$(pwd)/etc atf-run helper"
+
+ echo "Checking that defining 'testvar' trough '-v' works."
+ atf_check -s eq:0 -o match:'testvar: a value' -e ignore -x \
+ "ATF_CONFDIR=$(pwd)/etc atf-run -v testvar='a value' helper"
+
+ echo "Checking that defining 'testvar' trough the configuration" \
+ "file works."
+ mkdir etc
+ cat >etc/common.conf <<EOF
+Content-Type: application/X-atf-config; version="1"
+
+testvar = "value in conf file"
+EOF
+ atf_check -s eq:0 -o match:'testvar: value in conf file' -e ignore -x \
+ "ATF_CONFDIR=$(pwd)/etc atf-run helper"
+
+ echo "Checking that defining 'testvar' trough -v overrides the" \
+ "configuration file."
+ atf_check -s eq:0 -o match:'testvar: a value' -e ignore -x \
+ "ATF_CONFDIR=$(pwd)/etc atf-run -v testvar='a value' helper"
+}
+
+atf_test_case atffile
+atffile_head()
+{
+ atf_set "descr" "Tests that the variables defined by the Atffile" \
+ "are recognized and that they take the lowest priority"
+ atf_set "use.fs" "true"
+}
+atffile_body()
+{
+ create_helper testvar
+
+ echo "Checking that 'testvar' is not defined."
+ atf_check -s eq:1 -o ignore -e ignore -x \
+ "ATF_CONFDIR=$(pwd)/etc atf-run helper"
+
+ echo "Checking that defining 'testvar' trough the Atffile works."
+ echo 'conf: testvar = "a value"' >>Atffile
+ atf_check -s eq:0 -o match:'testvar: a value' -e ignore -x \
+ "ATF_CONFDIR=$(pwd)/etc atf-run helper"
+
+ echo "Checking that defining 'testvar' trough the configuration" \
+ "file overrides the one in the Atffile."
+ mkdir etc
+ cat >etc/common.conf <<EOF
+Content-Type: application/X-atf-config; version="1"
+
+testvar = "value in conf file"
+EOF
+ atf_check -s eq:0 -o match:'testvar: value in conf file' -e ignore -x \
+ "ATF_CONFDIR=$(pwd)/etc atf-run helper"
+ rm -rf etc
+
+ echo "Checking that defining 'testvar' trough -v overrides the" \
+ "one in the Atffile."
+ atf_check -s eq:0 -o match:'testvar: new value' -e ignore -x \
+ "ATF_CONFDIR=$(pwd)/etc atf-run -v testvar='new value' helper"
+}
+
+atf_test_case atffile_recursive
+atffile_recursive_head()
+{
+ atf_set "descr" "Tests that variables defined by an Atffile are not" \
+ "inherited by other Atffiles."
+ atf_set "use.fs" "true"
+}
+atffile_recursive_body()
+{
+ create_helper testvar
+
+ mkdir dir
+ mv Atffile helper dir
+
+ echo "Checking that 'testvar' is not inherited."
+ create_atffile dir
+ echo 'conf: testvar = "a value"' >> Atffile
+ atf_check -s eq:1 -o ignore -e ignore -x "ATF_CONFDIR=$(pwd)/etc atf-run"
+
+ echo "Checking that defining 'testvar' in the correct Atffile works."
+ echo 'conf: testvar = "a value"' >>dir/Atffile
+ atf_check -s eq:0 -o match:'testvar: a value' -e ignore -x \
+ "ATF_CONFDIR=$(pwd)/etc atf-run"
+}
+
+atf_test_case fds
+fds_head()
+{
+ atf_set "descr" "Tests that all streams are properly captured"
+ atf_set "use.fs" "true"
+}
+fds_body()
+{
+ create_helper fds
+
+ atf_check -s eq:0 \
+ -o match:'^tc-so:msg1 to stdout$' \
+ -o match:'^tc-so:msg2 to stdout$' \
+ -o match:'^tc-se:msg1 to stderr$' \
+ -o match:'^tc-se:msg2 to stderr$' \
+ -e empty atf-run
+}
+
+atf_test_case expect
+expect_head()
+{
+ atf_set "descr" "Tests the processing of test case results and the" \
+ "expect features"
+ atf_set "use.fs" "true"
+}
+expect_body()
+{
+ ln -s "$(atf_get_srcdir)/expect_helpers" .
+ create_atffile expect_helpers
+
+ atf_check -s eq:1 \
+ -o match:'death_and_exit, expected_death' \
+ -o match:'death_and_signal, expected_death' \
+ -o match:'death_but_pass, failed' \
+ -o match:'exit_any_and_exit, expected_exit' \
+ -o match:'exit_but_pass, failed' \
+ -o match:'exit_code_and_exit, expected_exit' \
+ -o match:'fail_and_fail_check, expected_failure' \
+ -o match:'fail_and_fail_requirement, expected_failure' \
+ -o match:'fail_but_pass, failed' \
+ -o match:'pass_and_pass, passed' \
+ -o match:'pass_but_fail_check, failed' \
+ -o match:'pass_but_fail_requirement, failed' \
+ -o match:'signal_any_and_signal, expected_signal' \
+ -o match:'signal_but_pass, failed' \
+ -o match:'signal_no_and_signal, expected_signal' \
+ -o match:'timeout_and_hang, expected_timeout' \
+ -o match:'timeout_but_pass, failed' \
+ -e empty atf-run
+}
+
+atf_test_case missing_results
+missing_results_head()
+{
+ atf_set "descr" "Ensures that atf-run correctly handles test cases that " \
+ "do not create the results file"
+ atf_set "use.fs" "true"
+}
+missing_results_body()
+{
+ create_helper_stdin helper 1 <<EOF
+test -f \${resfile} && echo "resfile found"
+exit 0
+EOF
+ chmod +x helper
+
+ create_atffile helper
+
+ atf_check -s eq:1 \
+ -o match:'^tc-end: tc1, failed,.*failed to create' \
+ -o not-match:'resfile found' \
+ -e empty atf-run
+}
+
+atf_test_case broken_results
+broken_results_head()
+{
+ atf_set "descr" "Ensures that atf-run reports test programs that" \
+ "provide a bogus results output as broken programs"
+ atf_set "use.fs" "true"
+}
+broken_results_body()
+{
+ # We produce two errors from the header to ensure that the parse
+ # errors are printed on a single line on the output file. Printing
+ # them on separate lines would be incorrect.
+ create_helper_stdin helper 1 <<EOF
+echo 'line 1' >\${resfile}
+echo 'line 2' >>\${resfile}
+exit 0
+EOF
+ chmod +x helper
+
+ create_atffile helper
+
+ atf_check -s eq:1 -o match:'^tc-end: tc1, .*line 1.*line 2' -e empty atf-run
+}
+
+atf_test_case broken_tp_list
+broken_tp_list_head()
+{
+ atf_set "descr" "Ensures that atf-run reports test programs that" \
+ "provide a bogus test case list"
+ atf_set "use.fs" "true"
+}
+broken_tp_list_body()
+{
+ cat >helper <<EOF
+#! $(atf-config -t atf_shell)
+while [ \${#} -gt 0 ]; do
+ if [ \${1} = -l ]; then
+ echo 'Content-Type: application/X-atf-tp; version="1"'
+ echo
+ echo 'foo: bar'
+ exit 0
+ else
+ shift
+ fi
+done
+exit 0
+EOF
+ chmod +x helper
+
+ create_atffile helper
+
+ re='^tp-end: helper,'
+ re="${re} Invalid format for test case list:.*First property.*ident"
+ atf_check -s eq:1 -o match:"${re}" -e empty atf-run
+}
+
+atf_test_case zero_tcs
+zero_tcs_head()
+{
+ atf_set "descr" "Ensures that atf-run reports test programs without" \
+ "test cases as errors"
+ atf_set "use.fs" "true"
+}
+zero_tcs_body()
+{
+ create_helper_stdin helper 0 <<EOF
+echo 'Content-Type: application/X-atf-tp; version="1"'
+echo
+exit 1
+EOF
+ chmod +x helper
+
+ create_atffile helper
+
+ atf_check -s eq:1 \
+ -o match:'^tp-end: helper,.*Invalid format for test case list' \
+ -e empty atf-run
+}
+
+atf_test_case exit_codes
+exit_codes_head()
+{
+ atf_set "descr" "Ensures that atf-run reports bogus exit codes for" \
+ "programs correctly"
+ atf_set "use.fs" "true"
+}
+exit_codes_body()
+{
+ create_helper_stdin helper 1 <<EOF
+echo "failed: Yes, it failed" >\${resfile}
+exit 0
+EOF
+ chmod +x helper
+
+ create_atffile helper
+
+ atf_check -s eq:1 \
+ -o match:'^tc-end: tc1,.*exited successfully.*reported failure' \
+ -e empty atf-run
+}
+
+atf_test_case signaled
+signaled_head()
+{
+ atf_set "descr" "Ensures that atf-run reports test program's crashes" \
+ "correctly regardless of their actual results"
+ atf_set "use.fs" "true"
+}
+signaled_body()
+{
+ create_helper_stdin helper 2 <<EOF
+echo "passed" >\${resfile}
+case \${testcase} in
+ tc1) ;;
+ tc2) echo "Killing myself!" ; kill -9 \$\$ ;;
+esac
+EOF
+ chmod +x helper
+
+ create_atffile helper
+
+ atf_check -s eq:1 -o match:'^tc-end: tc2,.*received signal 9' \
+ -e empty atf-run
+}
+
+atf_test_case hooks
+hooks_head()
+{
+ atf_set "descr" "Checks that the default hooks work and that they" \
+ "can be overriden by the user"
+ atf_set "use.fs" "true"
+}
+hooks_body()
+{
+ cp $(atf_get_srcdir)/pass_helper helper
+ create_atffile helper
+
+ mkdir atf
+ mkdir .atf
+
+ echo "Checking default hooks"
+ atf_check -s eq:0 -o match:'^info: time.start, ' \
+ -o match:'^info: time.end, ' -e empty -x \
+ "ATF_CONFDIR=$(pwd)/atf atf-run"
+
+ echo "Checking the system-wide info_start hook"
+ cat >atf/atf-run.hooks <<EOF
+info_start_hook()
+{
+ atf_tps_writer_info "test" "sw value"
+}
+EOF
+ atf_check -s eq:0 \
+ -o match:'^info: test, sw value' \
+ -o not-match:'^info: time.start, ' \
+ -o match:'^info: time.end, ' \
+ -e empty -x \
+ "ATF_CONFDIR=$(pwd)/atf atf-run"
+
+ echo "Checking the user-specific info_start hook"
+ cat >.atf/atf-run.hooks <<EOF
+info_start_hook()
+{
+ atf_tps_writer_info "test" "user value"
+}
+EOF
+ atf_check -s eq:0 \
+ -o match:'^info: test, user value' \
+ -o not-match:'^info: time.start, ' \
+ -o match:'^info: time.end, ' \
+ -e empty -x \
+ "ATF_CONFDIR=$(pwd)/atf atf-run"
+
+ rm atf/atf-run.hooks
+ rm .atf/atf-run.hooks
+
+ echo "Checking the system-wide info_end hook"
+ cat >atf/atf-run.hooks <<EOF
+info_end_hook()
+{
+ atf_tps_writer_info "test" "sw value"
+}
+EOF
+ atf_check -s eq:0 \
+ -o match:'^info: time.start, ' \
+ -o not-match:'^info: time.end, ' \
+ -o match:'^info: test, sw value' \
+ -e empty -x \
+ "ATF_CONFDIR=$(pwd)/atf atf-run"
+
+ echo "Checking the user-specific info_end hook"
+ cat >.atf/atf-run.hooks <<EOF
+info_end_hook()
+{
+ atf_tps_writer_info "test" "user value"
+}
+EOF
+ atf_check -s eq:0 \
+ -o match:'^info: time.start, ' \
+ -o not-match:'^info: time.end, ' \
+ -o match:'^info: test, user value' \
+ -e empty -x \
+ "ATF_CONFDIR=$(pwd)/atf atf-run"
+}
+
+atf_test_case isolation_env
+isolation_env_head()
+{
+ atf_set "descr" "Tests that atf-run sets a set of environment variables" \
+ "to known sane values"
+ atf_set "use.fs" "true"
+}
+isolation_env_body()
+{
+ undef_vars="LANG LC_ALL LC_COLLATE LC_CTYPE LC_MESSAGES LC_MONETARY \
+ LC_NUMERIC LC_TIME TZ"
+ def_vars="HOME"
+
+ mangleenv="env"
+ for v in ${undef_vars} ${def_vars}; do
+ mangleenv="${mangleenv} ${v}=bogus-value"
+ done
+
+ create_helper env_list
+ create_atffile helper
+
+ # We must ignore stderr in this call (instead of specifying -e empty)
+ # because, when atf-run invokes the shell to run the hooks, we may get
+ # error messages about an invalid locale. This happens, at least, when
+ # the shell is bash 4.x.
+ atf_check -s eq:0 -o save:stdout -e ignore ${mangleenv} atf-run helper
+
+ for v in ${undef_vars}; do
+ atf_check -s eq:1 -o empty -e empty grep "^tc-so:${v}=" stdout
+ done
+
+ for v in ${def_vars}; do
+ atf_check -s eq:0 -o ignore -e empty grep "^tc-so:${v}=" stdout
+ done
+}
+
+atf_test_case isolation_home
+isolation_home_head()
+{
+ atf_set "descr" "Tests that atf-run sets HOME to a sane and valid value"
+ atf_set "use.fs" "true"
+}
+isolation_home_body()
+{
+ create_helper env_home
+ create_atffile helper
+ atf_check -s eq:0 -o ignore -e ignore env HOME=foo atf-run helper
+}
+
+atf_test_case isolation_umask
+isolation_umask_head()
+{
+ atf_set "descr" "Tests that atf-run sets the umask to a known value"
+ atf_set "use.fs" "true"
+}
+isolation_umask_body()
+{
+ create_helper umask
+ create_atffile helper
+
+ atf_check -s eq:0 -o match:'umask: 0022' -e ignore -x \
+ "umask 0000 && atf-run helper"
+}
+
+atf_test_case cleanup_pass
+cleanup_pass_head()
+{
+ atf_set "descr" "Tests that atf-run calls the cleanup routine of the test" \
+ "case when the test case result is passed"
+ atf_set "use.fs" "true"
+}
+cleanup_pass_body()
+{
+ create_helper cleanup_states
+ create_atffile helper
+
+ atf_check -s eq:0 -o match:'cleanup_states, passed' -e ignore atf-run \
+ -v state=pass -v statedir=$(pwd) helper
+ test -f to-stay || atf_fail "Test case body did not run correctly"
+ test -f to-delete && atf_fail "Test case cleanup did not run correctly"
+}
+
+atf_test_case cleanup_fail
+cleanup_fail_head()
+{
+ atf_set "descr" "Tests that atf-run calls the cleanup routine of the test" \
+ "case when the test case result is failed"
+ atf_set "use.fs" "true"
+}
+cleanup_fail_body()
+{
+ create_helper cleanup_states
+ create_atffile helper
+
+ atf_check -s eq:1 -o match:'cleanup_states, failed' -e ignore atf-run \
+ -v state=fail -v statedir=$(pwd) helper
+ test -f to-stay || atf_fail "Test case body did not run correctly"
+ test -f to-delete && atf_fail "Test case cleanup did not run correctly"
+}
+
+atf_test_case cleanup_skip
+cleanup_skip_head()
+{
+ atf_set "descr" "Tests that atf-run calls the cleanup routine of the test" \
+ "case when the test case result is skipped"
+ atf_set "use.fs" "true"
+}
+cleanup_skip_body()
+{
+ create_helper cleanup_states
+ create_atffile helper
+
+ atf_check -s eq:0 -o match:'cleanup_states, skipped' -e ignore atf-run \
+ -v state=skip -v statedir=$(pwd) helper
+ test -f to-stay || atf_fail "Test case body did not run correctly"
+ test -f to-delete && atf_fail "Test case cleanup did not run correctly"
+}
+
+atf_test_case cleanup_curdir
+cleanup_curdir_head()
+{
+ atf_set "descr" "Tests that atf-run calls the cleanup routine in the same" \
+ "work directory as the body so that they can share data"
+ atf_set "use.fs" "true"
+}
+cleanup_curdir_body()
+{
+ create_helper cleanup_curdir
+ create_atffile helper
+
+ atf_check -s eq:0 -o match:'cleanup_curdir, passed' \
+ -o match:'Old value: 1234' -e ignore atf-run helper
+}
+
+atf_test_case cleanup_signal
+cleanup_signal_head()
+{
+ atf_set "descr" "Tests that atf-run calls the cleanup routine if it gets" \
+ "a termination signal while running the body"
+}
+cleanup_signal_body()
+{
+ : # TODO: Write this.
+}
+
+atf_test_case cleanup_mount
+cleanup_mount_head()
+{
+ atf_set "descr" "Tests that the removal algorithm does not cross" \
+ "mount points"
+ atf_set "require.user" "root"
+ atf_set "use.fs" "true"
+}
+cleanup_mount_body()
+{
+ ROOT="$(pwd)/root"; export ROOT
+
+ create_mount_helper helper <<EOF
+echo \$(pwd) >\${ROOT}
+mkdir foo
+mkdir foo/bar
+mkdir foo/bar/mnt
+do_mount foo/bar/mnt
+mkdir foo/baz
+do_mount foo/baz
+mkdir foo/baz/foo
+mkdir foo/baz/foo/bar
+do_mount foo/baz/foo/bar
+EOF
+ create_atffile helper
+ chmod +x helper
+
+ platform=$(uname)
+ case ${platform} in
+ Linux|FreeBSD|NetBSD|SunOS)
+ ;;
+ *)
+ # XXX Possibly specify in meta-data too.
+ atf_skip "Test unimplemented in this platform (${platform})"
+ ;;
+ esac
+
+ atf_check -s eq:0 -o match:"main, passed" -e ignore atf-run helper
+ mount | grep $(cat root) && atf_fail "Some file systems remain mounted"
+ atf_check -s eq:1 -o empty -e empty test -d $(cat root)/foo
+}
+
+atf_test_case cleanup_symlink
+cleanup_symlink_head()
+{
+ atf_set "descr" "Tests that the removal algorithm does not follow" \
+ "symlinks, which may live in another device and thus" \
+ "be treated as mount points"
+ atf_set "require.user" "root"
+ atf_set "use.fs" "true"
+}
+cleanup_symlink_body()
+{
+ ROOT="$(pwd)/root"; export ROOT
+
+ create_mount_helper helper <<EOF
+echo \$(pwd) >\${ROOT}
+atf_check -s eq:0 -o empty -e empty mkdir foo
+atf_check -s eq:0 -o empty -e empty mkdir foo/bar
+do_mount foo/bar
+atf_check -s eq:0 -o empty -e empty touch a
+atf_check -s eq:0 -o empty -e empty ln -s "\$(pwd)/a" foo/bar
+EOF
+ create_atffile helper
+ chmod +x helper
+
+ platform=$(uname)
+ case ${platform} in
+ Linux|FreeBSD|NetBSD|SunOS)
+ ;;
+ *)
+ # XXX Possibly specify in meta-data too.
+ atf_skip "Test unimplemented in this platform (${platform})"
+ ;;
+ esac
+
+ atf_check -s eq:0 -o match:"main, passed" -e ignore atf-run helper
+ mount | grep $(cat root) && atf_fail "Some file systems remain mounted"
+ atf_check -s eq:1 -o empty -e empty test -d $(cat root)/foo
+}
+
+atf_test_case require_arch
+require_arch_head()
+{
+ atf_set "descr" "Tests that atf-run validates the require.arch property"
+ atf_set "use.fs" "true"
+}
+require_arch_body()
+{
+ create_helper require_arch
+ create_atffile helper
+
+ echo "Checking for the real architecture"
+ arch=$(atf-config -t atf_arch)
+ atf_check -s eq:0 -o match:"${TESTCASE}, passed" -e ignore atf-run \
+ -v arch="${arch}" helper
+ atf_check -s eq:0 -o match:"${TESTCASE}, passed" -e ignore atf-run \
+ -v arch="foo ${arch}" helper
+ atf_check -s eq:0 -o match:"${TESTCASE}, passed" -e ignore atf-run \
+ -v arch="${arch} foo" helper
+
+ echo "Checking for a fictitious architecture"
+ arch=fictitious
+ export ATF_ARCH=fictitious
+ atf_check -s eq:0 -o match:"${TESTCASE}, passed" -e ignore atf-run \
+ -v arch="${arch}" helper
+ atf_check -s eq:0 -o match:"${TESTCASE}, passed" -e ignore atf-run \
+ -v arch="foo ${arch}" helper
+ atf_check -s eq:0 -o match:"${TESTCASE}, passed" -e ignore atf-run \
+ -v arch="${arch} foo" helper
+
+ echo "Triggering some failures"
+ atf_check -s eq:0 -o match:"${TESTCASE}, skipped, .*foo.*architecture" \
+ -e ignore atf-run -v arch="foo" helper
+ atf_check -s eq:0 \
+ -o match:"${TESTCASE}, skipped, .*foo bar.*architectures" -e ignore \
+ atf-run -v arch="foo bar" helper
+ atf_check -s eq:0 \
+ -o match:"${TESTCASE}, skipped, .*fictitiousxxx.*architecture" \
+ -e ignore atf-run -v arch="${arch}xxx" helper
+}
+
+atf_test_case require_config
+require_config_head()
+{
+ atf_set "descr" "Tests that atf-run validates the require.config property"
+ atf_set "use.fs" "true"
+}
+require_config_body()
+{
+ create_helper require_config
+ create_atffile helper
+
+ atf_check -s eq:0 -o match:"${TESTCASE}, skipped, .*var1.*not defined" \
+ -e ignore atf-run helper
+ atf_check -s eq:0 -o match:"${TESTCASE}, skipped, .*var2.*not defined" \
+ -e ignore atf-run -v var1=foo helper
+ atf_check -s eq:0 -o match:"${TESTCASE}, passed" -e ignore atf-run \
+ -v var1=a -v var2=' ' helper
+}
+
+atf_test_case require_machine
+require_machine_head()
+{
+ atf_set "descr" "Tests that atf-run validates the require.machine property"
+ atf_set "use.fs" "true"
+}
+require_machine_body()
+{
+ create_helper require_machine
+ create_atffile helper
+
+ echo "Checking for the real machine type"
+ machine=$(atf-config -t atf_machine)
+ atf_check -s eq:0 -o match:"${TESTCASE}, passed" -e ignore atf-run \
+ -v machine="${machine}" helper
+ atf_check -s eq:0 -o match:"${TESTCASE}, passed" -e ignore atf-run \
+ -v machine="foo ${machine}" helper
+ atf_check -s eq:0 -o match:"${TESTCASE}, passed" -e ignore atf-run \
+ -v machine="${machine} foo" helper
+
+ echo "Checking for a fictitious machine type"
+ machine=fictitious
+ export ATF_MACHINE=fictitious
+ atf_check -s eq:0 -o match:"${TESTCASE}, passed" -e ignore atf-run \
+ -v machine="${machine}" helper
+ atf_check -s eq:0 -o match:"${TESTCASE}, passed" -e ignore atf-run \
+ -v machine="foo ${machine}" helper
+ atf_check -s eq:0 -o match:"${TESTCASE}, passed" -e ignore atf-run \
+ -v machine="${machine} foo" helper
+
+ echo "Triggering some failures"
+ atf_check -s eq:0 -o match:"${TESTCASE}, skipped, .*foo.*machine type" \
+ -e ignore atf-run -v machine="foo" helper
+ atf_check -s eq:0 \
+ -o match:"${TESTCASE}, skipped, .*foo bar.*machine types" -e ignore \
+ atf-run -v machine="foo bar" helper
+ atf_check -s eq:0 \
+ -o match:"${TESTCASE}, skipped, .*fictitiousxxx.*machine type" \
+ -e ignore atf-run -v machine="${machine}xxx" helper
+}
+
+atf_test_case require_progs
+require_progs_head()
+{
+ atf_set "descr" "Tests that atf-run validates the require.progs property"
+ atf_set "use.fs" "true"
+}
+require_progs_body()
+{
+ create_helper require_progs
+ create_atffile helper
+
+ echo "Checking absolute paths"
+ atf_check -s eq:0 -o match:"${TESTCASE}, passed" -e ignore atf-run \
+ -v progs='/bin/cp' helper
+ atf_check -s eq:0 \
+ -o match:"${TESTCASE}, skipped, .*/bin/__non-existent__.*PATH" \
+ -e ignore atf-run -v progs='/bin/__non-existent__' helper
+
+ echo "Checking that relative paths are not allowed"
+ atf_check -s eq:1 \
+ -o match:"${TESTCASE}, failed, Relative paths.*not allowed.*bin/cp" \
+ -e ignore atf-run -v progs='bin/cp' helper
+
+ echo "Check plain file names, searching them in the PATH."
+ atf_check -s eq:0 -o match:"${TESTCASE}, passed" -e ignore atf-run \
+ -v progs='cp' helper
+ atf_check -s eq:0 \
+ -o match:"${TESTCASE}, skipped, .*__non-existent__.*PATH" -e ignore \
+ atf-run -v progs='__non-existent__' helper
+}
+
+atf_test_case require_user_root
+require_user_root_head()
+{
+ atf_set "descr" "Tests that atf-run validates the require.user property" \
+ "when it is set to 'root'"
+ atf_set "use.fs" "true"
+}
+require_user_root_body()
+{
+ create_helper require_user
+ create_atffile helper
+
+ if [ $(id -u) -eq 0 ]; then
+ exp=passed
+ else
+ exp=skipped
+ fi
+ atf_check -s eq:0 -o match:"${TESTCASE}, ${exp}" -e ignore atf-run \
+ -v user=root helper
+}
+
+atf_test_case require_user_unprivileged
+require_user_unprivileged_head()
+{
+ atf_set "descr" "Tests that atf-run validates the require.user property" \
+ "when it is set to 'root'"
+ atf_set "use.fs" "true"
+}
+require_user_unprivileged_body()
+{
+ create_helper require_user
+ create_atffile helper
+
+ if [ $(id -u) -eq 0 ]; then
+ exp=skipped
+ else
+ exp=passed
+ fi
+ atf_check -s eq:0 -o match:"${TESTCASE}, ${exp}" -e ignore atf-run \
+ -v user=unprivileged helper
+}
+
+atf_test_case require_user_bad
+require_user_bad_head()
+{
+ atf_set "descr" "Tests that atf-run validates the require.user property" \
+ "when it is set to 'root'"
+ atf_set "use.fs" "true"
+}
+require_user_bad_body()
+{
+ create_helper require_user
+ create_atffile helper
+
+ atf_check -s eq:1 -o match:"${TESTCASE}, failed, Invalid value.*foobar" \
+ -e ignore atf-run -v user=foobar helper
+}
+
+atf_test_case timeout
+timeout_head()
+{
+ atf_set "descr" "Tests that atf-run kills a test case that times out"
+ atf_set "use.fs" "true"
+}
+timeout_body()
+{
+ create_helper timeout
+ create_atffile helper
+
+ atf_check -s eq:1 \
+ -o match:"${TESTCASE}, failed, .*timed out after 1 second" -e ignore \
+ atf-run -v statedir=$(pwd) helper
+ test -f finished && atf_fail "Test case was not killed after time out"
+}
+
+atf_test_case use_fs
+use_fs_head()
+{
+ atf_set "descr" "Tests that atf-run correctly handles the use.fs property"
+ atf_set "use.fs" "true"
+}
+use_fs_body()
+{
+ create_helper use_fs
+ create_atffile helper
+
+ atf_check -s eq:0 -o ignore -e ignore atf-run \
+ -v allowed=false -v access=false helper
+
+ atf_check -s eq:1 -o ignore -e ignore atf-run \
+ -v allowed=false -v access=true helper
+
+ atf_check -s eq:0 -o ignore -e ignore atf-run \
+ -v allowed=true -v access=false helper
+
+ atf_check -s eq:0 -o ignore -e ignore atf-run \
+ -v allowed=true -v access=true helper
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case config
+ atf_add_test_case vflag
+ atf_add_test_case atffile
+ atf_add_test_case atffile_recursive
+ atf_add_test_case expect
+ atf_add_test_case fds
+ atf_add_test_case missing_results
+ atf_add_test_case broken_results
+ atf_add_test_case broken_tp_list
+ atf_add_test_case zero_tcs
+ atf_add_test_case exit_codes
+ atf_add_test_case signaled
+ atf_add_test_case hooks
+ atf_add_test_case isolation_env
+ atf_add_test_case isolation_home
+ atf_add_test_case isolation_umask
+ atf_add_test_case cleanup_pass
+ atf_add_test_case cleanup_fail
+ atf_add_test_case cleanup_skip
+ atf_add_test_case cleanup_curdir
+ atf_add_test_case cleanup_signal
+ atf_add_test_case cleanup_mount
+ atf_add_test_case cleanup_symlink
+ atf_add_test_case require_arch
+ atf_add_test_case require_config
+ atf_add_test_case require_machine
+ atf_add_test_case require_progs
+ atf_add_test_case require_user_root
+ atf_add_test_case require_user_unprivileged
+ atf_add_test_case require_user_bad
+ atf_add_test_case timeout
+ atf_add_test_case use_fs
+}
+
+# vim: syntax=sh:expandtab:shiftwidth=4:softtabstop=4
diff --git a/external/bsd/atf/dist/atf-run/misc_helpers.cpp b/external/bsd/atf/dist/atf-run/misc_helpers.cpp
new file mode 100644
index 00000000000..36d276c0a1d
--- /dev/null
+++ b/external/bsd/atf/dist/atf-run/misc_helpers.cpp
@@ -0,0 +1,307 @@
+//
+// Automated Testing Framework (atf)
+//
+// Copyright (c) 2007, 2008, 2010 The NetBSD Foundation, Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
+// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+extern "C" {
+#include <sys/stat.h>
+
+#include <unistd.h>
+}
+
+#include <cstdlib>
+#include <fstream>
+#include <iomanip>
+#include <iostream>
+#include <string>
+
+#include "atf-c++/env.hpp"
+#include "atf-c++/fs.hpp"
+#include "atf-c++/macros.hpp"
+#include "atf-c++/process.hpp"
+
+// ------------------------------------------------------------------------
+// Auxiliary functions.
+// ------------------------------------------------------------------------
+
+static
+void
+touch(const std::string& path)
+{
+ std::ofstream os(path.c_str());
+ if (!os)
+ ATF_FAIL("Could not create file " + path);
+ os.close();
+}
+
+// ------------------------------------------------------------------------
+// Helper tests for "t_integration".
+// ------------------------------------------------------------------------
+
+ATF_TEST_CASE(config);
+ATF_TEST_CASE_HEAD(config)
+{
+ set_md_var("descr", "Helper test case for the t_integration test program");
+}
+ATF_TEST_CASE_BODY(config)
+{
+ std::cout << "1st: " << get_config_var("1st") << std::endl;
+ std::cout << "2nd: " << get_config_var("2nd") << std::endl;
+ std::cout << "3rd: " << get_config_var("3rd") << std::endl;
+ std::cout << "4th: " << get_config_var("4th") << std::endl;
+}
+
+ATF_TEST_CASE(fds);
+ATF_TEST_CASE_HEAD(fds)
+{
+ set_md_var("descr", "Helper test case for the t_integration test program");
+}
+ATF_TEST_CASE_BODY(fds)
+{
+ std::cout << "msg1 to stdout" << std::endl;
+ std::cout << "msg2 to stdout" << std::endl;
+ std::cerr << "msg1 to stderr" << std::endl;
+ std::cerr << "msg2 to stderr" << std::endl;
+}
+
+ATF_TEST_CASE(testvar);
+ATF_TEST_CASE_HEAD(testvar)
+{
+ set_md_var("descr", "Helper test case for the t_integration test program");
+}
+ATF_TEST_CASE_BODY(testvar)
+{
+ if (!has_config_var("testvar"))
+ atf_tc_fail("testvar variable not defined");
+ std::cout << "testvar: " << get_config_var("testvar") << std::endl;
+}
+
+ATF_TEST_CASE(env_list);
+ATF_TEST_CASE_HEAD(env_list)
+{
+ set_md_var("descr", "Helper test case for the t_integration test program");
+}
+ATF_TEST_CASE_BODY(env_list)
+{
+ const atf::process::status s =
+ atf::process::exec(atf::fs::path("env"),
+ atf::process::argv_array("env", NULL),
+ atf::process::stream_inherit(),
+ atf::process::stream_inherit());
+ ATF_CHECK(s.exited());
+ ATF_CHECK(s.exitstatus() == EXIT_SUCCESS);
+}
+
+ATF_TEST_CASE(env_home);
+ATF_TEST_CASE_HEAD(env_home)
+{
+ set_md_var("descr", "Helper test case for the t_integration test program");
+}
+ATF_TEST_CASE_BODY(env_home)
+{
+ ATF_CHECK(atf::env::has("HOME"));
+ atf::fs::path p(atf::env::get("HOME"));
+ atf::fs::file_info fi1(p);
+ atf::fs::file_info fi2(atf::fs::path("."));
+ ATF_CHECK_EQUAL(fi1.get_device(), fi2.get_device());
+ ATF_CHECK_EQUAL(fi1.get_inode(), fi2.get_inode());
+}
+
+ATF_TEST_CASE(umask);
+ATF_TEST_CASE_HEAD(umask)
+{
+ set_md_var("descr", "Helper test case for the t_integration test program");
+}
+ATF_TEST_CASE_BODY(umask)
+{
+ mode_t m = ::umask(0);
+ std::cout << "umask: " << std::setw(4) << std::setfill('0')
+ << std::oct << m << std::endl;
+ (void)::umask(m);
+}
+
+ATF_TEST_CASE_WITH_CLEANUP(cleanup_states);
+ATF_TEST_CASE_HEAD(cleanup_states)
+{
+ set_md_var("descr", "Helper test case for the t_integration test program");
+}
+ATF_TEST_CASE_BODY(cleanup_states)
+{
+ touch(get_config_var("statedir") + "/to-delete");
+ touch(get_config_var("statedir") + "/to-stay");
+
+ if (get_config_var("state") == "fail")
+ ATF_FAIL("On purpose");
+ else if (get_config_var("state") == "skip")
+ ATF_SKIP("On purpose");
+}
+ATF_TEST_CASE_CLEANUP(cleanup_states)
+{
+ atf::fs::remove(atf::fs::path(get_config_var("statedir") + "/to-delete"));
+}
+
+ATF_TEST_CASE_WITH_CLEANUP(cleanup_curdir);
+ATF_TEST_CASE_HEAD(cleanup_curdir)
+{
+ set_md_var("descr", "Helper test case for the t_integration test program");
+ set_md_var("use.fs", "true");
+}
+ATF_TEST_CASE_BODY(cleanup_curdir)
+{
+ std::ofstream os("oldvalue");
+ if (!os)
+ ATF_FAIL("Failed to create oldvalue file");
+ os << 1234;
+ os.close();
+}
+ATF_TEST_CASE_CLEANUP(cleanup_curdir)
+{
+ std::ifstream is("oldvalue");
+ if (is) {
+ int i;
+ is >> i;
+ std::cout << "Old value: " << i << std::endl;
+ is.close();
+ }
+}
+
+ATF_TEST_CASE(require_arch);
+ATF_TEST_CASE_HEAD(require_arch)
+{
+ set_md_var("descr", "Helper test case for the t_integration test program");
+ set_md_var("require.arch", get_config_var("arch", "not-set"));
+}
+ATF_TEST_CASE_BODY(require_arch)
+{
+}
+
+ATF_TEST_CASE(require_config);
+ATF_TEST_CASE_HEAD(require_config)
+{
+ set_md_var("descr", "Helper test case for the t_integration test program");
+ set_md_var("require.config", "var1 var2");
+}
+ATF_TEST_CASE_BODY(require_config)
+{
+ std::cout << "var1: " << get_config_var("var1") << std::endl;
+ std::cout << "var2: " << get_config_var("var2") << std::endl;
+}
+
+ATF_TEST_CASE(require_machine);
+ATF_TEST_CASE_HEAD(require_machine)
+{
+ set_md_var("descr", "Helper test case for the t_integration test program");
+ set_md_var("require.machine", get_config_var("machine", "not-set"));
+}
+ATF_TEST_CASE_BODY(require_machine)
+{
+}
+
+ATF_TEST_CASE(require_progs);
+ATF_TEST_CASE_HEAD(require_progs)
+{
+ set_md_var("descr", "Helper test case for the t_integration test program");
+ set_md_var("require.progs", get_config_var("progs", "not-set"));
+}
+ATF_TEST_CASE_BODY(require_progs)
+{
+}
+
+ATF_TEST_CASE(require_user);
+ATF_TEST_CASE_HEAD(require_user)
+{
+ set_md_var("descr", "Helper test case for the t_integration test program");
+ set_md_var("require.user", get_config_var("user", "not-set"));
+}
+ATF_TEST_CASE_BODY(require_user)
+{
+}
+
+ATF_TEST_CASE(timeout);
+ATF_TEST_CASE_HEAD(timeout)
+{
+ set_md_var("descr", "Helper test case for the t_integration test program");
+ set_md_var("timeout", "1");
+}
+ATF_TEST_CASE_BODY(timeout)
+{
+ sleep(10);
+ touch(get_config_var("statedir") + "/finished");
+}
+
+ATF_TEST_CASE(use_fs);
+ATF_TEST_CASE_HEAD(use_fs)
+{
+ set_md_var("descr", "Helper test case for the t_integration test program");
+ set_md_var("use.fs", get_config_var("allowed", "not-set"));
+}
+ATF_TEST_CASE_BODY(use_fs)
+{
+ if (get_config_var("access") == "true")
+ touch("test-file");
+}
+
+// ------------------------------------------------------------------------
+// Main.
+// ------------------------------------------------------------------------
+
+ATF_INIT_TEST_CASES(tcs)
+{
+ std::string which = atf::env::get("TESTCASE");
+
+ // Add helper tests for t_integration.
+ if (which == "config")
+ ATF_ADD_TEST_CASE(tcs, config);
+ if (which == "fds")
+ ATF_ADD_TEST_CASE(tcs, fds);
+ if (which == "testvar")
+ ATF_ADD_TEST_CASE(tcs, testvar);
+ if (which == "env_list")
+ ATF_ADD_TEST_CASE(tcs, env_list);
+ if (which == "env_home")
+ ATF_ADD_TEST_CASE(tcs, env_home);
+ if (which == "umask")
+ ATF_ADD_TEST_CASE(tcs, umask);
+ if (which == "cleanup_states")
+ ATF_ADD_TEST_CASE(tcs, cleanup_states);
+ if (which == "cleanup_curdir")
+ ATF_ADD_TEST_CASE(tcs, cleanup_curdir);
+ if (which == "require_arch")
+ ATF_ADD_TEST_CASE(tcs, require_arch);
+ if (which == "require_config")
+ ATF_ADD_TEST_CASE(tcs, require_config);
+ if (which == "require_machine")
+ ATF_ADD_TEST_CASE(tcs, require_machine);
+ if (which == "require_progs")
+ ATF_ADD_TEST_CASE(tcs, require_progs);
+ if (which == "require_user")
+ ATF_ADD_TEST_CASE(tcs, require_user);
+ if (which == "timeout")
+ ATF_ADD_TEST_CASE(tcs, timeout);
+ if (which == "use_fs")
+ ATF_ADD_TEST_CASE(tcs, use_fs);
+}
diff --git a/external/bsd/atf/dist/atf-run/pass_helper.cpp b/external/bsd/atf/dist/atf-run/pass_helper.cpp
new file mode 100644
index 00000000000..49f1e3217ac
--- /dev/null
+++ b/external/bsd/atf/dist/atf-run/pass_helper.cpp
@@ -0,0 +1,44 @@
+//
+// Automated Testing Framework (atf)
+//
+// Copyright (c) 2007, 2008 The NetBSD Foundation, Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
+// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#include "atf-c++/macros.hpp"
+
+ATF_TEST_CASE(main);
+ATF_TEST_CASE_HEAD(main)
+{
+ set_md_var("descr", "Helper test case that always passes");
+}
+ATF_TEST_CASE_BODY(main)
+{
+}
+
+ATF_INIT_TEST_CASES(tcs)
+{
+ ATF_ADD_TEST_CASE(tcs, main);
+}
diff --git a/external/bsd/atf/dist/atf-run/requirements_test.cpp b/external/bsd/atf/dist/atf-run/requirements_test.cpp
new file mode 100644
index 00000000000..19f3e9f9e43
--- /dev/null
+++ b/external/bsd/atf/dist/atf-run/requirements_test.cpp
@@ -0,0 +1,304 @@
+//
+// Automated Testing Framework (atf)
+//
+// Copyright (c) 2010 The NetBSD Foundation, Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
+// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#include "atf-c++/config.hpp"
+#include "atf-c++/macros.hpp"
+#include "atf-c++/user.hpp"
+
+#include "requirements.hpp"
+
+namespace impl = atf::atf_run;
+
+// -------------------------------------------------------------------------
+// Auxiliary functions.
+// -------------------------------------------------------------------------
+
+namespace {
+
+const atf::tests::vars_map no_config;
+
+void
+do_check(const std::string& expected, const atf::tests::vars_map& metadata,
+ const atf::tests::vars_map& config = no_config)
+{
+ const std::string actual = impl::check_requirements(metadata, config);
+ if (actual != expected)
+ ATF_FAIL("Requirements failure reason \"" + actual + "\" does not "
+ "match \"" + expected + "\"");
+}
+
+} // anonymous namespace
+
+// -------------------------------------------------------------------------
+// Tests for the require.arch metadata property.
+// -------------------------------------------------------------------------
+
+ATF_TEST_CASE(require_arch_one_ok);
+ATF_TEST_CASE_HEAD(require_arch_one_ok) {}
+ATF_TEST_CASE_BODY(require_arch_one_ok) {
+ atf::tests::vars_map metadata;
+ metadata["require.arch"] = atf::config::get("atf_arch");
+ do_check("", metadata);
+}
+
+ATF_TEST_CASE(require_arch_one_fail);
+ATF_TEST_CASE_HEAD(require_arch_one_fail) {}
+ATF_TEST_CASE_BODY(require_arch_one_fail) {
+ atf::tests::vars_map metadata;
+ metadata["require.arch"] = "__fake_arch__";
+ do_check("Requires the '__fake_arch__' architecture", metadata);
+}
+
+ATF_TEST_CASE(require_arch_many_ok);
+ATF_TEST_CASE_HEAD(require_arch_many_ok) {}
+ATF_TEST_CASE_BODY(require_arch_many_ok) {
+ atf::tests::vars_map metadata;
+ metadata["require.arch"] = "__foo__ " + atf::config::get("atf_arch") +
+ " __bar__";
+ do_check("", metadata);
+}
+
+ATF_TEST_CASE(require_arch_many_fail);
+ATF_TEST_CASE_HEAD(require_arch_many_fail) {}
+ATF_TEST_CASE_BODY(require_arch_many_fail) {
+ atf::tests::vars_map metadata;
+ metadata["require.arch"] = "__foo__ __bar__ __baz__";
+ do_check("Requires one of the '__foo__ __bar__ __baz__' architectures",
+ metadata);
+}
+
+// -------------------------------------------------------------------------
+// Tests for the require.config metadata property.
+// -------------------------------------------------------------------------
+
+ATF_TEST_CASE(require_config_one_ok);
+ATF_TEST_CASE_HEAD(require_config_one_ok) {}
+ATF_TEST_CASE_BODY(require_config_one_ok) {
+ atf::tests::vars_map metadata, config;
+ metadata["require.config"] = "var1";
+ config["var1"] = "some-value";
+ do_check("", metadata, config);
+}
+
+ATF_TEST_CASE(require_config_one_fail);
+ATF_TEST_CASE_HEAD(require_config_one_fail) {}
+ATF_TEST_CASE_BODY(require_config_one_fail) {
+ atf::tests::vars_map metadata, config;
+ metadata["require.config"] = "var1";
+ do_check("Required configuration variable 'var1' not defined", metadata,
+ config);
+}
+
+ATF_TEST_CASE(require_config_many_ok);
+ATF_TEST_CASE_HEAD(require_config_many_ok) {}
+ATF_TEST_CASE_BODY(require_config_many_ok) {
+ atf::tests::vars_map metadata, config;
+ metadata["require.config"] = "var1 var2 var3";
+ config["var1"] = "first-value";
+ config["var2"] = "second-value";
+ config["var3"] = "third-value";
+ do_check("", metadata, config);
+}
+
+ATF_TEST_CASE(require_config_many_fail);
+ATF_TEST_CASE_HEAD(require_config_many_fail) {}
+ATF_TEST_CASE_BODY(require_config_many_fail) {
+ atf::tests::vars_map metadata, config;
+ metadata["require.config"] = "var1 var2 var3";
+ config["var1"] = "first-value";
+ config["var3"] = "third-value";
+ do_check("Required configuration variable 'var2' not defined", metadata,
+ config);
+}
+
+// -------------------------------------------------------------------------
+// Tests for the require.machine metadata property.
+// -------------------------------------------------------------------------
+
+ATF_TEST_CASE(require_machine_one_ok);
+ATF_TEST_CASE_HEAD(require_machine_one_ok) {}
+ATF_TEST_CASE_BODY(require_machine_one_ok) {
+ atf::tests::vars_map metadata;
+ metadata["require.machine"] = atf::config::get("atf_machine");
+ do_check("", metadata);
+}
+
+ATF_TEST_CASE(require_machine_one_fail);
+ATF_TEST_CASE_HEAD(require_machine_one_fail) {}
+ATF_TEST_CASE_BODY(require_machine_one_fail) {
+ atf::tests::vars_map metadata;
+ metadata["require.machine"] = "__fake_machine__";
+ do_check("Requires the '__fake_machine__' machine type", metadata);
+}
+
+ATF_TEST_CASE(require_machine_many_ok);
+ATF_TEST_CASE_HEAD(require_machine_many_ok) {}
+ATF_TEST_CASE_BODY(require_machine_many_ok) {
+ atf::tests::vars_map metadata;
+ metadata["require.machine"] = "__foo__ " + atf::config::get("atf_machine") +
+ " __bar__";
+ do_check("", metadata);
+}
+
+ATF_TEST_CASE(require_machine_many_fail);
+ATF_TEST_CASE_HEAD(require_machine_many_fail) {}
+ATF_TEST_CASE_BODY(require_machine_many_fail) {
+ atf::tests::vars_map metadata;
+ metadata["require.machine"] = "__foo__ __bar__ __baz__";
+ do_check("Requires one of the '__foo__ __bar__ __baz__' machine types",
+ metadata);
+}
+
+// -------------------------------------------------------------------------
+// Tests for the require.progs metadata property.
+// -------------------------------------------------------------------------
+
+ATF_TEST_CASE(require_progs_one_ok);
+ATF_TEST_CASE_HEAD(require_progs_one_ok) {}
+ATF_TEST_CASE_BODY(require_progs_one_ok) {
+ atf::tests::vars_map metadata;
+ metadata["require.progs"] = "cp";
+ do_check("", metadata);
+}
+
+ATF_TEST_CASE(require_progs_one_missing);
+ATF_TEST_CASE_HEAD(require_progs_one_missing) {}
+ATF_TEST_CASE_BODY(require_progs_one_missing) {
+ atf::tests::vars_map metadata;
+ metadata["require.progs"] = "cp __non-existent__";
+ do_check("Required program '__non-existent__' not found in the PATH",
+ metadata);
+}
+
+ATF_TEST_CASE(require_progs_one_fail);
+ATF_TEST_CASE_HEAD(require_progs_one_fail) {}
+ATF_TEST_CASE_BODY(require_progs_one_fail) {
+ atf::tests::vars_map metadata;
+ metadata["require.progs"] = "bin/cp";
+ ATF_CHECK_THROW(std::runtime_error,
+ impl::check_requirements(metadata, no_config));
+}
+
+ATF_TEST_CASE(require_progs_many_ok);
+ATF_TEST_CASE_HEAD(require_progs_many_ok) {}
+ATF_TEST_CASE_BODY(require_progs_many_ok) {
+ atf::tests::vars_map metadata;
+ metadata["require.progs"] = "cp ls mv";
+ do_check("", metadata);
+}
+
+ATF_TEST_CASE(require_progs_many_missing);
+ATF_TEST_CASE_HEAD(require_progs_many_missing) {}
+ATF_TEST_CASE_BODY(require_progs_many_missing) {
+ atf::tests::vars_map metadata;
+ metadata["require.progs"] = "mv ls __foo__ cp";
+ do_check("Required program '__foo__' not found in the PATH", metadata);
+}
+
+ATF_TEST_CASE(require_progs_many_fail);
+ATF_TEST_CASE_HEAD(require_progs_many_fail) {}
+ATF_TEST_CASE_BODY(require_progs_many_fail) {
+ atf::tests::vars_map metadata;
+ metadata["require.progs"] = "ls cp ../bin/cp";
+ ATF_CHECK_THROW(std::runtime_error,
+ impl::check_requirements(metadata, no_config));
+}
+
+// -------------------------------------------------------------------------
+// Tests for the require.user metadata property.
+// -------------------------------------------------------------------------
+
+ATF_TEST_CASE(require_user_root);
+ATF_TEST_CASE_HEAD(require_user_root) {}
+ATF_TEST_CASE_BODY(require_user_root) {
+ atf::tests::vars_map metadata;
+ metadata["require.user"] = "root";
+ if (atf::user::is_root())
+ do_check("", metadata);
+ else
+ do_check("Requires root privileges", metadata);
+}
+
+ATF_TEST_CASE(require_user_unprivileged);
+ATF_TEST_CASE_HEAD(require_user_unprivileged) {}
+ATF_TEST_CASE_BODY(require_user_unprivileged) {
+ atf::tests::vars_map metadata;
+ metadata["require.user"] = "unprivileged";
+ if (atf::user::is_root())
+ do_check("Requires an unprivileged user", metadata);
+ else
+ do_check("", metadata);
+}
+
+ATF_TEST_CASE(require_user_fail);
+ATF_TEST_CASE_HEAD(require_user_fail) {}
+ATF_TEST_CASE_BODY(require_user_fail) {
+ atf::tests::vars_map metadata;
+ metadata["require.user"] = "nobody";
+ ATF_CHECK_THROW(std::runtime_error,
+ impl::check_requirements(metadata, no_config));
+}
+
+// -------------------------------------------------------------------------
+// Main.
+// -------------------------------------------------------------------------
+
+ATF_INIT_TEST_CASES(tcs)
+{
+ // Add test cases for require.arch.
+ ATF_ADD_TEST_CASE(tcs, require_arch_one_ok);
+ ATF_ADD_TEST_CASE(tcs, require_arch_one_fail);
+ ATF_ADD_TEST_CASE(tcs, require_arch_many_ok);
+ ATF_ADD_TEST_CASE(tcs, require_arch_many_fail);
+
+ // Add test cases for require.config.
+ ATF_ADD_TEST_CASE(tcs, require_config_one_ok);
+ ATF_ADD_TEST_CASE(tcs, require_config_one_fail);
+ ATF_ADD_TEST_CASE(tcs, require_config_many_ok);
+ ATF_ADD_TEST_CASE(tcs, require_config_many_fail);
+
+ // Add test cases for require.machine.
+ ATF_ADD_TEST_CASE(tcs, require_machine_one_ok);
+ ATF_ADD_TEST_CASE(tcs, require_machine_one_fail);
+ ATF_ADD_TEST_CASE(tcs, require_machine_many_ok);
+ ATF_ADD_TEST_CASE(tcs, require_machine_many_fail);
+
+ // Add test cases for require.progs.
+ ATF_ADD_TEST_CASE(tcs, require_progs_one_ok);
+ ATF_ADD_TEST_CASE(tcs, require_progs_one_missing);
+ ATF_ADD_TEST_CASE(tcs, require_progs_one_fail);
+ ATF_ADD_TEST_CASE(tcs, require_progs_many_ok);
+ ATF_ADD_TEST_CASE(tcs, require_progs_many_missing);
+ ATF_ADD_TEST_CASE(tcs, require_progs_many_fail);
+
+ // Add test cases for require.user.
+ ATF_ADD_TEST_CASE(tcs, require_user_root);
+ ATF_ADD_TEST_CASE(tcs, require_user_unprivileged);
+ ATF_ADD_TEST_CASE(tcs, require_user_fail);
+}
diff --git a/external/bsd/atf/dist/atf-run/several_tcs_helper.c b/external/bsd/atf/dist/atf-run/several_tcs_helper.c
new file mode 100644
index 00000000000..defff953242
--- /dev/null
+++ b/external/bsd/atf/dist/atf-run/several_tcs_helper.c
@@ -0,0 +1,71 @@
+/*
+ * Automated Testing Framework (atf)
+ *
+ * Copyright (c) 2010 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <atf-c.h>
+
+ATF_TC(first);
+ATF_TC_HEAD(first, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Description 1");
+}
+ATF_TC_BODY(first, tc)
+{
+}
+
+ATF_TC_WITH_CLEANUP(second);
+ATF_TC_HEAD(second, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Description 2");
+ atf_tc_set_md_var(tc, "timeout", "500");
+ atf_tc_set_md_var(tc, "use.fs", "true");
+ atf_tc_set_md_var(tc, "X-property", "Custom property");
+}
+ATF_TC_BODY(second, tc)
+{
+}
+ATF_TC_CLEANUP(second, tc)
+{
+}
+
+ATF_TC(third);
+ATF_TC_HEAD(third, tc)
+{
+}
+ATF_TC_BODY(third, tc)
+{
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, first);
+ ATF_TP_ADD_TC(tp, second);
+ ATF_TP_ADD_TC(tp, third);
+
+ return atf_no_error();
+}
diff --git a/external/bsd/atf/dist/atf-run/test_program_test.cpp b/external/bsd/atf/dist/atf-run/test_program_test.cpp
new file mode 100644
index 00000000000..0c76b265df6
--- /dev/null
+++ b/external/bsd/atf/dist/atf-run/test_program_test.cpp
@@ -0,0 +1,1018 @@
+//
+// Automated Testing Framework (atf)
+//
+// Copyright (c) 2010 The NetBSD Foundation, Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
+// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#include <fstream>
+#include <iostream>
+
+#include "atf-c++/macros.hpp"
+#include "atf-c++/parser.hpp"
+#include "atf-c++/text.hpp"
+
+#include "test-program.hpp"
+
+#include "test_helpers.hpp"
+
+namespace impl = atf::atf_run;
+namespace detail = atf::atf_run::detail;
+
+using atf::tests::vars_map;
+
+// -------------------------------------------------------------------------
+// Auxiliary functions.
+// -------------------------------------------------------------------------
+
+static
+atf::fs::path
+get_helper(const atf::tests::tc& tc, const char* name)
+{
+ return atf::fs::path(tc.get_config_var("srcdir")) / name;
+}
+
+static
+void
+check_property(const vars_map& props, const char* name, const char* value)
+{
+ const vars_map::const_iterator iter = props.find(name);
+ ATF_CHECK(iter != props.end());
+ ATF_CHECK_EQUAL(value, (*iter).second);
+}
+
+static void
+check_result(const char* exp_state, const int exp_value, const char* exp_reason,
+ const impl::test_case_result& tcr)
+{
+ ATF_CHECK_EQUAL(exp_state, tcr.state());
+ ATF_CHECK_EQUAL(exp_value, tcr.value());
+ ATF_CHECK_EQUAL(exp_reason, tcr.reason());
+}
+
+static
+void
+write_test_case_result(const char *results_path, const std::string& contents)
+{
+ std::ofstream results_file(results_path);
+ ATF_CHECK(results_file);
+
+ results_file << contents;
+}
+
+static
+void
+print_indented(const std::string& str)
+{
+ std::vector< std::string > ws = atf::text::split(str, "\n");
+ for (std::vector< std::string >::const_iterator iter = ws.begin();
+ iter != ws.end(); iter++)
+ std::cout << ">>" << *iter << "<<" << std::endl;
+}
+
+// XXX Should this string handling and verbosity level be part of the
+// ATF_CHECK_EQUAL macro? It may be hard to predict sometimes that a
+// string can have newlines in it, and so the error message generated
+// at the moment will be bogus if there are some.
+static
+void
+check_equal(const std::string& str, const std::string& exp)
+{
+ if (str != exp) {
+ std::cout << "String equality check failed." << std::endl
+ << "Adding >> and << to delimit the string boundaries "
+ "below." << std::endl;
+ std::cout << "GOT:" << std::endl;
+ print_indented(str);
+ std::cout << "EXPECTED:" << std::endl;
+ print_indented(exp);
+ atf_tc_fail("Constructed string differs from the expected one");
+ }
+}
+
+// -------------------------------------------------------------------------
+// Tests for the "tp" reader.
+// -------------------------------------------------------------------------
+
+class tp_reader : protected detail::atf_tp_reader {
+ void
+ got_tc(const std::string& ident,
+ const std::map< std::string, std::string >& md)
+ {
+ std::string call = "got_tc(" + ident + ", {";
+ for (std::map< std::string, std::string >::const_iterator iter =
+ md.begin(); iter != md.end(); iter++) {
+ if (iter != md.begin())
+ call += ", ";
+ call += (*iter).first + '=' + (*iter).second;
+ }
+ call += "})";
+ m_calls.push_back(call);
+ }
+
+ void
+ got_eof(void)
+ {
+ m_calls.push_back("got_eof()");
+ }
+
+public:
+ tp_reader(std::istream& is) :
+ detail::atf_tp_reader(is)
+ {
+ }
+
+ void
+ read(void)
+ {
+ atf_tp_reader::read();
+ }
+
+ std::vector< std::string > m_calls;
+};
+
+ATF_TEST_CASE_WITHOUT_HEAD(tp_1);
+ATF_TEST_CASE_BODY(tp_1)
+{
+ const char* input =
+ "Content-Type: application/X-atf-tp; version=\"1\"\n"
+ "\n"
+ "ident: test_case_1\n"
+ "\n"
+ "ident: test_case_2\n"
+ "\n"
+ "ident: test_case_3\n"
+ ;
+
+ const char* exp_calls[] = {
+ "got_tc(test_case_1, {ident=test_case_1})",
+ "got_tc(test_case_2, {ident=test_case_2})",
+ "got_tc(test_case_3, {ident=test_case_3})",
+ "got_eof()",
+ NULL
+ };
+
+ const char* exp_errors[] = {
+ NULL
+ };
+
+ do_parser_test< tp_reader >(input, exp_calls, exp_errors);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(tp_2);
+ATF_TEST_CASE_BODY(tp_2)
+{
+ const char* input =
+ "Content-Type: application/X-atf-tp; version=\"1\"\n"
+ "\n"
+ "ident: test_case_1\n"
+ "descr: This is the description\n"
+ "timeout: 300\n"
+ "\n"
+ "ident: test_case_2\n"
+ "\n"
+ "ident: test_case_3\n"
+ "X-prop1: A custom property\n"
+ "descr: Third test case\n"
+ ;
+
+ // NO_CHECK_STYLE_BEGIN
+ const char* exp_calls[] = {
+ "got_tc(test_case_1, {descr=This is the description, ident=test_case_1, timeout=300})",
+ "got_tc(test_case_2, {ident=test_case_2})",
+ "got_tc(test_case_3, {X-prop1=A custom property, descr=Third test case, ident=test_case_3})",
+ "got_eof()",
+ NULL
+ };
+ // NO_CHECK_STYLE_END
+
+ const char* exp_errors[] = {
+ NULL
+ };
+
+ do_parser_test< tp_reader >(input, exp_calls, exp_errors);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(tp_3);
+ATF_TEST_CASE_BODY(tp_3)
+{
+ const char* input =
+ "Content-Type: application/X-atf-tp; version=\"1\"\n"
+ "\n"
+ "ident: single_test\n"
+ "descr: Some description\n"
+ "timeout: 300\n"
+ "require.arch: thearch\n"
+ "require.config: foo-bar\n"
+ "require.machine: themachine\n"
+ "require.progs: /bin/cp mv\n"
+ "require.user: root\n"
+ ;
+
+ // NO_CHECK_STYLE_BEGIN
+ const char* exp_calls[] = {
+ "got_tc(single_test, {descr=Some description, ident=single_test, require.arch=thearch, require.config=foo-bar, require.machine=themachine, require.progs=/bin/cp mv, require.user=root, timeout=300})",
+ "got_eof()",
+ NULL
+ };
+ // NO_CHECK_STYLE_END
+
+ const char* exp_errors[] = {
+ NULL
+ };
+
+ do_parser_test< tp_reader >(input, exp_calls, exp_errors);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(tp_4);
+ATF_TEST_CASE_BODY(tp_4)
+{
+ const char* input =
+ "Content-Type: application/X-atf-tp; version=\"1\"\n"
+ "\n"
+ "ident: single_test \n"
+ "descr: Some description \n"
+ ;
+
+ const char* exp_calls[] = {
+ "got_tc(single_test, {descr=Some description, ident=single_test})",
+ "got_eof()",
+ NULL
+ };
+
+ const char* exp_errors[] = {
+ NULL
+ };
+
+ do_parser_test< tp_reader >(input, exp_calls, exp_errors);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(tp_50);
+ATF_TEST_CASE_BODY(tp_50)
+{
+ const char* input =
+ "Content-Type: application/X-atf-tp; version=\"1\"\n"
+ "\n"
+ ;
+
+ const char* exp_calls[] = {
+ NULL
+ };
+
+ const char* exp_errors[] = {
+ "3: Unexpected token `<<EOF>>'; expected property name",
+ NULL
+ };
+
+ do_parser_test< tp_reader >(input, exp_calls, exp_errors);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(tp_51);
+ATF_TEST_CASE_BODY(tp_51)
+{
+ const char* input =
+ "Content-Type: application/X-atf-tp; version=\"1\"\n"
+ "\n"
+ "\n"
+ "\n"
+ "\n"
+ ;
+
+ const char* exp_calls[] = {
+ NULL
+ };
+
+ const char* exp_errors[] = {
+ "3: Unexpected token `<<NEWLINE>>'; expected property name",
+ NULL
+ };
+
+ do_parser_test< tp_reader >(input, exp_calls, exp_errors);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(tp_52);
+ATF_TEST_CASE_BODY(tp_52)
+{
+ const char* input =
+ "Content-Type: application/X-atf-tp; version=\"1\"\n"
+ "\n"
+ "ident: test1\n"
+ "ident: test2\n"
+ ;
+
+ const char* exp_calls[] = {
+ "got_tc(test1, {ident=test1})",
+ "got_eof()",
+ NULL
+ };
+
+ const char* exp_errors[] = {
+ NULL
+ };
+
+ do_parser_test< tp_reader >(input, exp_calls, exp_errors);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(tp_53);
+ATF_TEST_CASE_BODY(tp_53)
+{
+ const char* input =
+ "Content-Type: application/X-atf-tp; version=\"1\"\n"
+ "\n"
+ "descr: Out of order\n"
+ "ident: test1\n"
+ ;
+
+ const char* exp_calls[] = {
+ NULL
+ };
+
+ const char* exp_errors[] = {
+ "3: First property of a test case must be 'ident'",
+ NULL
+ };
+
+ do_parser_test< tp_reader >(input, exp_calls, exp_errors);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(tp_54);
+ATF_TEST_CASE_BODY(tp_54)
+{
+ const char* input =
+ "Content-Type: application/X-atf-tp; version=\"1\"\n"
+ "\n"
+ "ident:\n"
+ ;
+
+ const char* exp_calls[] = {
+ NULL
+ };
+
+ const char* exp_errors[] = {
+ "3: The value for 'ident' cannot be empty",
+ NULL
+ };
+
+ do_parser_test< tp_reader >(input, exp_calls, exp_errors);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(tp_55);
+ATF_TEST_CASE_BODY(tp_55)
+{
+ const char* input =
+ "Content-Type: application/X-atf-tp; version=\"1\"\n"
+ "\n"
+ "ident: +*,\n"
+ ;
+
+ const char* exp_calls[] = {
+ NULL
+ };
+
+ const char* exp_errors[] = {
+ "3: The identifier must match ^[_A-Za-z0-9]+$; was '+*,'",
+ NULL
+ };
+
+ do_parser_test< tp_reader >(input, exp_calls, exp_errors);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(tp_56);
+ATF_TEST_CASE_BODY(tp_56)
+{
+ const char* input =
+ "Content-Type: application/X-atf-tp; version=\"1\"\n"
+ "\n"
+ "ident: test\n"
+ "timeout: hello\n"
+ ;
+
+ const char* exp_calls[] = {
+ NULL
+ };
+
+ const char* exp_errors[] = {
+ "4: The timeout property requires an integer value",
+ NULL
+ };
+
+ do_parser_test< tp_reader >(input, exp_calls, exp_errors);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(tp_57);
+ATF_TEST_CASE_BODY(tp_57)
+{
+ const char* input =
+ "Content-Type: application/X-atf-tp; version=\"1\"\n"
+ "\n"
+ "ident: test\n"
+ "unknown: property\n"
+ ;
+
+ const char* exp_calls[] = {
+ NULL
+ };
+
+ const char* exp_errors[] = {
+ "4: Unknown property 'unknown'",
+ NULL
+ };
+
+ do_parser_test< tp_reader >(input, exp_calls, exp_errors);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(tp_58);
+ATF_TEST_CASE_BODY(tp_58)
+{
+ const char* input =
+ "Content-Type: application/X-atf-tp; version=\"1\"\n"
+ "\n"
+ "ident: test\n"
+ "X-foo:\n"
+ ;
+
+ const char* exp_calls[] = {
+ NULL
+ };
+
+ const char* exp_errors[] = {
+ "4: The value for 'X-foo' cannot be empty",
+ NULL
+ };
+
+ do_parser_test< tp_reader >(input, exp_calls, exp_errors);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(tp_59);
+ATF_TEST_CASE_BODY(tp_59)
+{
+ const char* input =
+ "Content-Type: application/X-atf-tp; version=\"1\"\n"
+ "\n"
+ "\n"
+ "ident: test\n"
+ "timeout: 300\n"
+ ;
+
+ const char* exp_calls[] = {
+ NULL
+ };
+
+ const char* exp_errors[] = {
+ "3: Unexpected token `<<NEWLINE>>'; expected property name",
+ NULL
+ };
+
+ do_parser_test< tp_reader >(input, exp_calls, exp_errors);
+}
+
+// -------------------------------------------------------------------------
+// Tests for the "tps" writer.
+// -------------------------------------------------------------------------
+
+ATF_TEST_CASE(atf_tps_writer);
+ATF_TEST_CASE_HEAD(atf_tps_writer)
+{
+ set_md_var("descr", "Verifies the application/X-atf-tps writer");
+}
+ATF_TEST_CASE_BODY(atf_tps_writer)
+{
+ std::ostringstream expss;
+ std::ostringstream ss;
+
+#define RESET \
+ expss.str(""); \
+ ss.str("")
+
+#define CHECK \
+ check_equal(ss.str(), expss.str())
+
+ {
+ RESET;
+
+ impl::atf_tps_writer w(ss);
+ expss << "Content-Type: application/X-atf-tps; version=\"2\""
+ << std::endl << std::endl;
+ CHECK;
+ }
+
+ {
+ RESET;
+
+ impl::atf_tps_writer w(ss);
+ expss << "Content-Type: application/X-atf-tps; version=\"2\""
+ << std::endl << std::endl;
+ CHECK;
+
+ w.info("foo", "bar");
+ expss << "info: foo, bar" << std::endl;
+ CHECK;
+
+ w.info("baz", "second info");
+ expss << "info: baz, second info" << std::endl;
+ CHECK;
+ }
+
+ {
+ RESET;
+
+ impl::atf_tps_writer w(ss);
+ expss << "Content-Type: application/X-atf-tps; version=\"2\""
+ << std::endl << std::endl;
+ CHECK;
+
+ w.ntps(0);
+ expss << "tps-count: 0" << std::endl;
+ CHECK;
+ }
+
+ {
+ RESET;
+
+ impl::atf_tps_writer w(ss);
+ expss << "Content-Type: application/X-atf-tps; version=\"2\""
+ << std::endl << std::endl;
+ CHECK;
+
+ w.ntps(123);
+ expss << "tps-count: 123" << std::endl;
+ CHECK;
+ }
+
+ {
+ RESET;
+
+ impl::atf_tps_writer w(ss);
+ expss << "Content-Type: application/X-atf-tps; version=\"2\""
+ << std::endl << std::endl;
+ CHECK;
+
+ w.ntps(2);
+ expss << "tps-count: 2" << std::endl;
+ CHECK;
+
+ w.start_tp("foo", 0);
+ expss << "tp-start: foo, 0" << std::endl;
+ CHECK;
+
+ w.end_tp("");
+ expss << "tp-end: foo" << std::endl;
+ CHECK;
+
+ w.start_tp("bar", 0);
+ expss << "tp-start: bar, 0" << std::endl;
+ CHECK;
+
+ w.end_tp("failed program");
+ expss << "tp-end: bar, failed program" << std::endl;
+ CHECK;
+ }
+
+ {
+ RESET;
+
+ impl::atf_tps_writer w(ss);
+ expss << "Content-Type: application/X-atf-tps; version=\"2\""
+ << std::endl << std::endl;
+ CHECK;
+
+ w.ntps(1);
+ expss << "tps-count: 1" << std::endl;
+ CHECK;
+
+ w.start_tp("foo", 1);
+ expss << "tp-start: foo, 1" << std::endl;
+ CHECK;
+
+ w.start_tc("brokentc");
+ expss << "tc-start: brokentc" << std::endl;
+ CHECK;
+
+ w.end_tp("aborted");
+ expss << "tp-end: foo, aborted" << std::endl;
+ CHECK;
+ }
+
+ {
+ RESET;
+
+ impl::atf_tps_writer w(ss);
+ expss << "Content-Type: application/X-atf-tps; version=\"2\""
+ << std::endl << std::endl;
+ CHECK;
+
+ w.ntps(1);
+ expss << "tps-count: 1" << std::endl;
+ CHECK;
+
+ w.start_tp("thetp", 3);
+ expss << "tp-start: thetp, 3" << std::endl;
+ CHECK;
+
+ w.start_tc("passtc");
+ expss << "tc-start: passtc" << std::endl;
+ CHECK;
+
+ w.end_tc("passed", "");
+ expss << "tc-end: passtc, passed" << std::endl;
+ CHECK;
+
+ w.start_tc("failtc");
+ expss << "tc-start: failtc" << std::endl;
+ CHECK;
+
+ w.end_tc("failed", "The reason");
+ expss << "tc-end: failtc, failed, The reason" << std::endl;
+ CHECK;
+
+ w.start_tc("skiptc");
+ expss << "tc-start: skiptc" << std::endl;
+ CHECK;
+
+ w.end_tc("skipped", "The reason");
+ expss << "tc-end: skiptc, skipped, The reason" << std::endl;
+ CHECK;
+
+ w.end_tp("");
+ expss << "tp-end: thetp" << std::endl;
+ CHECK;
+ }
+
+ {
+ RESET;
+
+ impl::atf_tps_writer w(ss);
+ expss << "Content-Type: application/X-atf-tps; version=\"2\""
+ << std::endl << std::endl;
+ CHECK;
+
+ w.ntps(1);
+ expss << "tps-count: 1" << std::endl;
+ CHECK;
+
+ w.start_tp("thetp", 1);
+ expss << "tp-start: thetp, 1" << std::endl;
+ CHECK;
+
+ w.start_tc("thetc");
+ expss << "tc-start: thetc" << std::endl;
+ CHECK;
+
+ w.stdout_tc("a line");
+ expss << "tc-so:a line" << std::endl;
+ CHECK;
+
+ w.stdout_tc("another line");
+ expss << "tc-so:another line" << std::endl;
+ CHECK;
+
+ w.stderr_tc("an error message");
+ expss << "tc-se:an error message" << std::endl;
+ CHECK;
+
+ w.end_tc("passed", "");
+ expss << "tc-end: thetc, passed" << std::endl;
+ CHECK;
+
+ w.end_tp("");
+ expss << "tp-end: thetp" << std::endl;
+ CHECK;
+ }
+
+ {
+ RESET;
+
+ impl::atf_tps_writer w(ss);
+ expss << "Content-Type: application/X-atf-tps; version=\"2\""
+ << std::endl << std::endl;
+ CHECK;
+
+ w.ntps(1);
+ expss << "tps-count: 1" << std::endl;
+ CHECK;
+
+ w.start_tp("thetp", 0);
+ expss << "tp-start: thetp, 0" << std::endl;
+ CHECK;
+
+ w.end_tp("");
+ expss << "tp-end: thetp" << std::endl;
+ CHECK;
+
+ w.info("foo", "bar");
+ expss << "info: foo, bar" << std::endl;
+ CHECK;
+
+ w.info("baz", "second value");
+ expss << "info: baz, second value" << std::endl;
+ CHECK;
+ }
+
+#undef CHECK
+#undef RESET
+}
+
+// -------------------------------------------------------------------------
+// Tests for the free functions.
+// -------------------------------------------------------------------------
+
+ATF_TEST_CASE(get_metadata_bad);
+ATF_TEST_CASE_HEAD(get_metadata_bad) {}
+ATF_TEST_CASE_BODY(get_metadata_bad) {
+ const atf::fs::path executable = get_helper(*this, "bad_metadata_helper");
+ ATF_CHECK_THROW(atf::parser::parse_errors,
+ impl::get_metadata(executable, vars_map()));
+}
+
+ATF_TEST_CASE(get_metadata_zero_tcs);
+ATF_TEST_CASE_HEAD(get_metadata_zero_tcs) {}
+ATF_TEST_CASE_BODY(get_metadata_zero_tcs) {
+ const atf::fs::path executable = get_helper(*this, "zero_tcs_helper");
+ ATF_CHECK_THROW(atf::parser::parse_errors,
+ impl::get_metadata(executable, vars_map()));
+}
+
+ATF_TEST_CASE(get_metadata_several_tcs);
+ATF_TEST_CASE_HEAD(get_metadata_several_tcs) {}
+ATF_TEST_CASE_BODY(get_metadata_several_tcs) {
+ const atf::fs::path executable = get_helper(*this, "several_tcs_helper");
+ const impl::metadata md = impl::get_metadata(executable, vars_map());
+ ATF_CHECK_EQUAL(3, md.test_cases.size());
+
+ {
+ const impl::test_cases_map::const_iterator iter =
+ md.test_cases.find("first");
+ ATF_CHECK(iter != md.test_cases.end());
+
+ ATF_CHECK_EQUAL(5, (*iter).second.size());
+ check_property((*iter).second, "descr", "Description 1");
+ check_property((*iter).second, "has.cleanup", "false");
+ check_property((*iter).second, "ident", "first");
+ check_property((*iter).second, "timeout", "300");
+ check_property((*iter).second, "use.fs", "false");
+ }
+
+ {
+ const impl::test_cases_map::const_iterator iter =
+ md.test_cases.find("second");
+ ATF_CHECK(iter != md.test_cases.end());
+
+ ATF_CHECK_EQUAL(6, (*iter).second.size());
+ check_property((*iter).second, "descr", "Description 2");
+ check_property((*iter).second, "has.cleanup", "true");
+ check_property((*iter).second, "ident", "second");
+ check_property((*iter).second, "timeout", "500");
+ check_property((*iter).second, "use.fs", "true");
+ check_property((*iter).second, "X-property", "Custom property");
+ }
+
+ {
+ const impl::test_cases_map::const_iterator iter =
+ md.test_cases.find("third");
+ ATF_CHECK(iter != md.test_cases.end());
+
+ ATF_CHECK_EQUAL(4, (*iter).second.size());
+ check_property((*iter).second, "has.cleanup", "false");
+ check_property((*iter).second, "ident", "third");
+ check_property((*iter).second, "timeout", "300");
+ check_property((*iter).second, "use.fs", "false");
+ }
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(parse_test_case_result_expected_death);
+ATF_TEST_CASE_BODY(parse_test_case_result_expected_death) {
+ check_result("expected_death", -1, "foo bar",
+ detail::parse_test_case_result("expected_death: foo bar"));
+
+ ATF_CHECK_THROW(std::runtime_error,
+ detail::parse_test_case_result("expected_death"));
+ ATF_CHECK_THROW(std::runtime_error,
+ detail::parse_test_case_result("expected_death(3): foo"));
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(parse_test_case_result_expected_exit);
+ATF_TEST_CASE_BODY(parse_test_case_result_expected_exit) {
+ check_result("expected_exit", -1, "foo bar",
+ detail::parse_test_case_result("expected_exit: foo bar"));
+ check_result("expected_exit", -1, "foo bar",
+ detail::parse_test_case_result("expected_exit(): foo bar"));
+ check_result("expected_exit", 5, "foo bar",
+ detail::parse_test_case_result("expected_exit(5): foo bar"));
+
+ ATF_CHECK_THROW(std::runtime_error,
+ detail::parse_test_case_result("expected_exit"));
+ ATF_CHECK_THROW(std::runtime_error,
+ detail::parse_test_case_result("expected_exit("));
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(parse_test_case_result_expected_failure);
+ATF_TEST_CASE_BODY(parse_test_case_result_expected_failure) {
+ check_result("expected_failure", -1, "foo bar",
+ detail::parse_test_case_result("expected_failure: foo bar"));
+
+ ATF_CHECK_THROW(std::runtime_error,
+ detail::parse_test_case_result("expected_failure"));
+ ATF_CHECK_THROW(std::runtime_error,
+ detail::parse_test_case_result("expected_failure(3): foo"));
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(parse_test_case_result_expected_signal);
+ATF_TEST_CASE_BODY(parse_test_case_result_expected_signal) {
+ check_result("expected_signal", -1, "foo bar",
+ detail::parse_test_case_result("expected_signal: foo bar"));
+ check_result("expected_signal", -1, "foo bar",
+ detail::parse_test_case_result("expected_signal(): foo bar"));
+ check_result("expected_signal", 5, "foo bar",
+ detail::parse_test_case_result("expected_signal(5): foo bar"));
+
+ ATF_CHECK_THROW(std::runtime_error,
+ detail::parse_test_case_result("expected_signal"));
+ ATF_CHECK_THROW(std::runtime_error,
+ detail::parse_test_case_result("expected_signal("));
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(parse_test_case_result_expected_timeout);
+ATF_TEST_CASE_BODY(parse_test_case_result_expected_timeout) {
+ check_result("expected_timeout", -1, "foo bar",
+ detail::parse_test_case_result("expected_timeout: foo bar"));
+
+ ATF_CHECK_THROW(std::runtime_error,
+ detail::parse_test_case_result("expected_timeout"));
+ ATF_CHECK_THROW(std::runtime_error,
+ detail::parse_test_case_result("expected_timeout(3): foo"));
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(parse_test_case_result_failed);
+ATF_TEST_CASE_BODY(parse_test_case_result_failed) {
+ check_result("failed", -1, "foo bar",
+ detail::parse_test_case_result("failed: foo bar"));
+
+ ATF_CHECK_THROW(std::runtime_error,
+ detail::parse_test_case_result("failed"));
+ ATF_CHECK_THROW(std::runtime_error,
+ detail::parse_test_case_result("failed(3): foo"));
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(parse_test_case_result_passed);
+ATF_TEST_CASE_BODY(parse_test_case_result_passed) {
+ check_result("passed", -1, "",
+ detail::parse_test_case_result("passed"));
+
+ ATF_CHECK_THROW(std::runtime_error,
+ detail::parse_test_case_result("passed: foo"));
+ ATF_CHECK_THROW(std::runtime_error,
+ detail::parse_test_case_result("passed(3): foo"));
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(parse_test_case_result_skipped);
+ATF_TEST_CASE_BODY(parse_test_case_result_skipped) {
+ check_result("skipped", -1, "foo bar",
+ detail::parse_test_case_result("skipped: foo bar"));
+
+ ATF_CHECK_THROW(std::runtime_error,
+ detail::parse_test_case_result("skipped"));
+ ATF_CHECK_THROW(std::runtime_error,
+ detail::parse_test_case_result("skipped(3): foo"));
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(parse_test_case_result_unknown);
+ATF_TEST_CASE_BODY(parse_test_case_result_unknown) {
+ ATF_CHECK_THROW(std::runtime_error,
+ detail::parse_test_case_result("foo"));
+ ATF_CHECK_THROW(std::runtime_error,
+ detail::parse_test_case_result("bar: foo"));
+ ATF_CHECK_THROW(std::runtime_error,
+ detail::parse_test_case_result("baz: foo"));
+}
+
+ATF_TEST_CASE(read_test_case_result_failed);
+ATF_TEST_CASE_HEAD(read_test_case_result_failed) {
+ set_md_var("use.fs", "true");
+}
+ATF_TEST_CASE_BODY(read_test_case_result_failed) {
+ write_test_case_result("resfile", "failed: foo bar\n");
+ const impl::test_case_result tcr = impl::read_test_case_result(
+ atf::fs::path("resfile"));
+ ATF_CHECK_EQUAL("failed", tcr.state());
+ ATF_CHECK_EQUAL("foo bar", tcr.reason());
+}
+
+ATF_TEST_CASE(read_test_case_result_skipped);
+ATF_TEST_CASE_HEAD(read_test_case_result_skipped) {
+ set_md_var("use.fs", "true");
+}
+ATF_TEST_CASE_BODY(read_test_case_result_skipped) {
+ write_test_case_result("resfile", "skipped: baz bar\n");
+ const impl::test_case_result tcr = impl::read_test_case_result(
+ atf::fs::path("resfile"));
+ ATF_CHECK_EQUAL("skipped", tcr.state());
+ ATF_CHECK_EQUAL("baz bar", tcr.reason());
+}
+
+
+ATF_TEST_CASE(read_test_case_result_no_file);
+ATF_TEST_CASE_HEAD(read_test_case_result_no_file) {}
+ATF_TEST_CASE_BODY(read_test_case_result_no_file) {
+ ATF_CHECK_THROW(std::runtime_error,
+ impl::read_test_case_result(atf::fs::path("resfile")));
+}
+
+ATF_TEST_CASE(read_test_case_result_empty_file);
+ATF_TEST_CASE_HEAD(read_test_case_result_empty_file) {
+ set_md_var("use.fs", "true");
+}
+ATF_TEST_CASE_BODY(read_test_case_result_empty_file) {
+ write_test_case_result("resfile", "");
+ ATF_CHECK_THROW(std::runtime_error,
+ impl::read_test_case_result(atf::fs::path("resfile")));
+}
+
+ATF_TEST_CASE(read_test_case_result_invalid);
+ATF_TEST_CASE_HEAD(read_test_case_result_invalid) {
+ set_md_var("use.fs", "true");
+}
+ATF_TEST_CASE_BODY(read_test_case_result_invalid) {
+ write_test_case_result("resfile", "passed: hello\n");
+ ATF_CHECK_THROW(std::runtime_error,
+ impl::read_test_case_result(atf::fs::path("resfile")));
+}
+
+ATF_TEST_CASE(read_test_case_result_multiline);
+ATF_TEST_CASE_HEAD(read_test_case_result_multiline) {
+ set_md_var("use.fs", "true");
+}
+ATF_TEST_CASE_BODY(read_test_case_result_multiline) {
+ write_test_case_result("resfile", "skipped: foo\nbar\n");
+ const impl::test_case_result tcr = impl::read_test_case_result(
+ atf::fs::path("resfile"));
+ ATF_CHECK_EQUAL("skipped", tcr.state());
+ ATF_CHECK_EQUAL("foo<<NEWLINE UNEXPECTED>>bar", tcr.reason());
+}
+
+// -------------------------------------------------------------------------
+// Main.
+// -------------------------------------------------------------------------
+
+ATF_INIT_TEST_CASES(tcs)
+{
+ ATF_ADD_TEST_CASE(tcs, tp_1);
+ ATF_ADD_TEST_CASE(tcs, tp_2);
+ ATF_ADD_TEST_CASE(tcs, tp_3);
+ ATF_ADD_TEST_CASE(tcs, tp_4);
+ ATF_ADD_TEST_CASE(tcs, tp_50);
+ ATF_ADD_TEST_CASE(tcs, tp_51);
+ ATF_ADD_TEST_CASE(tcs, tp_52);
+ ATF_ADD_TEST_CASE(tcs, tp_53);
+ ATF_ADD_TEST_CASE(tcs, tp_54);
+ ATF_ADD_TEST_CASE(tcs, tp_55);
+ ATF_ADD_TEST_CASE(tcs, tp_56);
+ ATF_ADD_TEST_CASE(tcs, tp_57);
+ ATF_ADD_TEST_CASE(tcs, tp_58);
+ ATF_ADD_TEST_CASE(tcs, tp_59);
+
+ ATF_ADD_TEST_CASE(tcs, atf_tps_writer);
+
+ ATF_ADD_TEST_CASE(tcs, get_metadata_bad);
+ ATF_ADD_TEST_CASE(tcs, get_metadata_zero_tcs);
+ ATF_ADD_TEST_CASE(tcs, get_metadata_several_tcs);
+
+ ATF_ADD_TEST_CASE(tcs, parse_test_case_result_expected_death);
+ ATF_ADD_TEST_CASE(tcs, parse_test_case_result_expected_exit);
+ ATF_ADD_TEST_CASE(tcs, parse_test_case_result_expected_failure);
+ ATF_ADD_TEST_CASE(tcs, parse_test_case_result_expected_signal);
+ ATF_ADD_TEST_CASE(tcs, parse_test_case_result_expected_timeout);
+ ATF_ADD_TEST_CASE(tcs, parse_test_case_result_failed);
+ ATF_ADD_TEST_CASE(tcs, parse_test_case_result_passed);
+ ATF_ADD_TEST_CASE(tcs, parse_test_case_result_skipped);
+ ATF_ADD_TEST_CASE(tcs, parse_test_case_result_unknown);
+
+ ATF_ADD_TEST_CASE(tcs, read_test_case_result_no_file);
+ ATF_ADD_TEST_CASE(tcs, read_test_case_result_empty_file);
+ ATF_ADD_TEST_CASE(tcs, read_test_case_result_multiline);
+ ATF_ADD_TEST_CASE(tcs, read_test_case_result_invalid);
+
+ // TODO: Add tests for run_test_case once all the missing functionality
+ // is implemented.
+}
diff --git a/external/bsd/atf/dist/atf-run/zero_tcs_helper.c b/external/bsd/atf/dist/atf-run/zero_tcs_helper.c
new file mode 100644
index 00000000000..1533e317bc7
--- /dev/null
+++ b/external/bsd/atf/dist/atf-run/zero_tcs_helper.c
@@ -0,0 +1,35 @@
+/*
+ * Automated Testing Framework (atf)
+ *
+ * Copyright (c) 2010 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <atf-c.h>
+
+ATF_TP_ADD_TCS(tp)
+{
+ return atf_no_error();
+}
diff --git a/external/bsd/atf/dist/atf-sh/Atffile b/external/bsd/atf/dist/atf-sh/Atffile
new file mode 100644
index 00000000000..e18faa7b790
--- /dev/null
+++ b/external/bsd/atf/dist/atf-sh/Atffile
@@ -0,0 +1,10 @@
+Content-Type: application/X-atf-atffile; version="1"
+
+prop: test-suite = atf
+
+tp: tc_test
+tp: tp_test
+tp: normalize_test
+tp: config_test
+tp: atf_check_test
+tp: integration_test
diff --git a/external/bsd/atf/dist/atf-sh/atf-sh-api.3 b/external/bsd/atf/dist/atf-sh/atf-sh-api.3
index e509aa693c2..aca5717a52f 100644
--- a/external/bsd/atf/dist/atf-sh/atf-sh-api.3
+++ b/external/bsd/atf/dist/atf-sh/atf-sh-api.3
@@ -26,7 +26,7 @@
.\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
.\" IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd May 9, 2010
+.Dd June 28, 2010
.Dt ATF-SH-API 3
.Os
.Sh NAME
@@ -35,13 +35,20 @@
.Nm atf_check_equal ,
.Nm atf_config_get ,
.Nm atf_config_has ,
+.Nm atf_expect_death ,
+.Nm atf_expect_exit ,
+.Nm atf_expect_fail ,
+.Nm atf_expect_pass ,
+.Nm atf_expect_signal ,
+.Nm atf_expect_timeout ,
.Nm atf_fail ,
.Nm atf_get ,
.Nm atf_get_srcdir ,
.Nm atf_pass ,
.Nm atf_require_prog ,
.Nm atf_set ,
-.Nm atf_skip
+.Nm atf_skip ,
+.Fn atf_test_case
.Nd POSIX shell API to write ATF-based test programs
.Sh SYNOPSIS
.Fn atf_add_test_case "name"
@@ -49,6 +56,12 @@
.Fn atf_check_equal "expr1" "expr2"
.Fn atf_config_get "var_name"
.Fn atf_config_has "var_name"
+.Fn atf_expect_death "reason" "..."
+.Fn atf_expect_exit "exitcode" "reason" "..."
+.Fn atf_expect_fail "reason" "..."
+.Fn atf_expect_pass
+.Fn atf_expect_signal "signo" "reason" "..."
+.Fn atf_expect_timeout "reason" "..."
.Fn atf_fail "reason"
.Fn atf_get "var_name"
.Fn atf_get_srcdir
@@ -56,6 +69,7 @@
.Fn atf_require_prog "prog_name"
.Fn atf_set "var_name" "value"
.Fn atf_skip "reason"
+.Fn atf_test_case "name" "cleanup"
.Sh DESCRIPTION
ATF
provides a simple but powerful interface to easily write test programs in
@@ -81,7 +95,7 @@ tc1_body() {
... first test case's body ...
}
-atf_test_case tc2
+atf_test_case tc2 cleanup
tc2_head() {
... second test case's header ...
}
@@ -104,13 +118,17 @@ atf_init_test_cases() {
Test cases have an identifier and are composed of three different parts:
the header, the body and an optional cleanup routine, all of which are
described in
-.Xr atf-test-case 8 .
+.Xr atf-test-case 4 .
To define test cases, one can use the
.Fn atf_test_case
-function, which takes a single parameter specifiying the test case's
+function, which takes a first parameter specifiying the test case's
name and instructs the library to set things up to accept it as a valid
test case.
-It is important to note that it
+The second parameter is optional and, if provided, must be
+.Sq cleanup ;
+providing this parameter allows defining a cleanup routine for the test
+case.
+It is important to note that this function
.Em does not
set the test case up for execution when the program is run.
In order to do so, a later registration is needed through the
@@ -188,6 +206,65 @@ take a single string parameter that describes why the test case failed or
was skipped, respectively.
It is very important to provide a clear error message in both cases so that
the user can quickly know why the test did not pass.
+.Ss Expectations
+Everything explained in the previous section changes when the test case
+expectations are redefined by the programmer.
+.Pp
+Each test case has an internal state called
+.Sq expect
+that describes what the test case expectations are at any point in time.
+The value of this property can change during execution by any of:
+.Bl -tag -width indent
+.It Fn atf_expect_death "reason" "..."
+Expects the test case to exit prematurely regardless of the nature of the
+exit.
+.It Fn atf_expect_exit "exitcode" "reason" "..."
+Expects the test case to exit cleanly.
+If
+.Va exitcode
+is not
+.Sq -1 ,
+.Xr atf-run 1
+will validate that the exit code of the test case matches the one provided
+in this call.
+Otherwise, the exact value will be ignored.
+.It Fn atf_expect_fail "reason"
+Any failure raised in this mode is recorded, but such failures do not report
+the test case as failed; instead, the test case finalizes cleanly and is
+reported as
+.Sq expected failure ;
+this report includes the provided
+.Fa reason
+as part of it.
+If no error is raised while running in this mode, then the test case is
+reported as
+.Sq failed .
+.Pp
+This mode is useful to reproduce actual known bugs in tests.
+Whenever the developer fixes the bug later on, the test case will start
+reporting a failure, signaling the developer that the test case must be
+adjusted to the new conditions.
+In this situation, it is useful, for example, to set
+.Fa reason
+as the bug number for tracking purposes.
+.It Fn atf_expect_pass
+This is the normal mode of execution.
+In this mode, any failure is reported as such to the user and the test case
+is marked as
+.Sq failed .
+.It Fn atf_expect_signal "signo" "reason" "..."
+Expects the test case to terminate due to the reception of a signal.
+If
+.Va signo
+is not
+.Sq -1 ,
+.Xr atf-run 1
+will validate that the signal that terminated the test case matches the one
+provided in this call.
+Otherwise, the exact value will be ignored.
+.It Fn atf_expect_timeout "reason" "..."
+Expects the test case to execute for longer than its timeout.
+.El
.Ss Helper functions for common checks
.Fn atf_check [options] command [args]
.Pp
@@ -259,5 +336,5 @@ grep foo ls || atf_fail "foo file not found in listing"
.Sh SEE ALSO
.Xr atf-sh 1 ,
.Xr atf-test-program 1 ,
-.Xr atf 7 ,
-.Xr atf-test-case 8
+.Xr atf-test-case 4 ,
+.Xr atf 7
diff --git a/external/bsd/atf/dist/atf-sh/atf_check_test.sh b/external/bsd/atf/dist/atf-sh/atf_check_test.sh
new file mode 100644
index 00000000000..1d6cdff36db
--- /dev/null
+++ b/external/bsd/atf/dist/atf-sh/atf_check_test.sh
@@ -0,0 +1,187 @@
+#
+# Automated Testing Framework (atf)
+#
+# Copyright (c) 2007, 2008, 2010 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
+# CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+# TODO: Bring in the checks in the bootstrap testsuite for atf_check.
+
+atf_test_case info_ok
+info_ok_head()
+{
+ atf_set "descr" "Verifies that atf_check prints an informative" \
+ "message even when the command is successful"
+ atf_set "use.fs" "true"
+}
+info_ok_body()
+{
+ h="$(atf_get_srcdir)/misc_helpers -s $(atf_get_srcdir)"
+
+ atf_check -s eq:0 -o save:stdout -e save:stderr -x \
+ "${h} atf_check_info_ok"
+ grep 'Executing command.*true' stdout >/dev/null || \
+ atf_fail "atf_check does not print an informative message"
+
+ atf_check -s eq:0 -o save:stdout -e save:stderr -x \
+ "${h} atf_check_info_fail"
+ grep 'Executing command.*false' stdout >/dev/null || \
+ atf_fail "atf_check does not print an informative message"
+}
+
+atf_test_case expout_mismatch
+expout_mismatch_head()
+{
+ atf_set "descr" "Verifies that atf_check prints a diff of the" \
+ "stdout and the expected stdout if the two do no" \
+ "match"
+ atf_set "use.fs" "true"
+}
+expout_mismatch_body()
+{
+ h="$(atf_get_srcdir)/misc_helpers -s $(atf_get_srcdir)"
+
+ atf_check -s eq:1 -o save:stdout -e save:stderr -x \
+ "${h} atf_check_expout_mismatch"
+ grep 'Executing command.*echo bar' stdout >/dev/null || \
+ atf_fail "atf_check does not print an informative message"
+ grep 'stdout does not match golden output' stderr >/dev/null || \
+ atf_fail "atf_check does not print the stdout header"
+ grep 'stderr' stderr >/dev/null && \
+ atf_fail "atf_check prints the stderr header"
+ grep '^-foo' stderr >/dev/null || \
+ atf_fail "atf_check does not print the stdout's diff"
+ grep '^+bar' stderr >/dev/null || \
+ atf_fail "atf_check does not print the stdout's diff"
+}
+
+atf_test_case experr_mismatch
+experr_mismatch_head()
+{
+ atf_set "descr" "Verifies that atf_check prints a diff of the" \
+ "stderr and the expected stderr if the two do no" \
+ "match"
+ atf_set "use.fs" "true"
+}
+experr_mismatch_body()
+{
+ h="$(atf_get_srcdir)/misc_helpers -s $(atf_get_srcdir)"
+
+ atf_check -s eq:1 -o save:stdout -e save:stderr -x \
+ "${h} atf_check_experr_mismatch"
+ grep 'Executing command.*echo bar' stdout >/dev/null || \
+ atf_fail "atf_check does not print an informative message"
+ grep 'stdout' stderr >/dev/null && \
+ atf_fail "atf_check prints the stdout header"
+ grep 'stderr does not match golden output' stderr >/dev/null || \
+ atf_fail "atf_check does not print the stderr header"
+ grep '^-foo' stderr >/dev/null || \
+ atf_fail "atf_check does not print the stderr's diff"
+ grep '^+bar' stderr >/dev/null || \
+ atf_fail "atf_check does not print the stderr's diff"
+}
+
+atf_test_case null_stdout
+null_stdout_head()
+{
+ atf_set "descr" "Verifies that atf_check prints a the stdout it got" \
+ "when it was supposed to be null"
+ atf_set "use.fs" "true"
+}
+null_stdout_body()
+{
+ h="$(atf_get_srcdir)/misc_helpers -s $(atf_get_srcdir)"
+
+ atf_check -s eq:1 -o save:stdout -e save:stderr -x \
+ "${h} atf_check_null_stdout"
+ grep 'Executing command.*echo.*These.*contents' stdout >/dev/null || \
+ atf_fail "atf_check does not print an informative message"
+ grep 'stdout not empty' stderr >/dev/null || \
+ atf_fail "atf_check does not print the stdout header"
+ grep 'stderr' stderr >/dev/null && \
+ atf_fail "atf_check prints the stderr header"
+ grep 'These are the contents' stderr >/dev/null || \
+ atf_fail "atf_check does not print stdout's contents"
+}
+
+atf_test_case null_stderr
+null_stderr_head()
+{
+ atf_set "descr" "Verifies that atf_check prints a the stderr it got" \
+ "when it was supposed to be null"
+ atf_set "use.fs" "true"
+}
+null_stderr_body()
+{
+ h="$(atf_get_srcdir)/misc_helpers -s $(atf_get_srcdir)"
+
+ atf_check -s eq:1 -o save:stdout -e save:stderr -x \
+ "${h} atf_check_null_stderr"
+ grep 'Executing command.*echo.*These.*contents' stdout >/dev/null || \
+ atf_fail "atf_check does not print an informative message"
+ grep 'stdout' stderr >/dev/null && \
+ atf_fail "atf_check prints the stdout header"
+ grep 'stderr not empty' stderr >/dev/null || \
+ atf_fail "atf_check does not print the stderr header"
+ grep 'These are the contents' stderr >/dev/null || \
+ atf_fail "atf_check does not print stderr's contents"
+}
+
+atf_test_case equal
+equal_head()
+{
+ atf_set "descr" "Verifies that atf_check_equal works"
+ atf_set "use.fs" "true"
+}
+equal_body()
+{
+ h="$(atf_get_srcdir)/misc_helpers -s $(atf_get_srcdir)"
+
+ atf_check -s eq:0 -o ignore -e ignore -x "${h} atf_check_equal_ok"
+
+ atf_check -s eq:1 -o ignore -e ignore -x \
+ "${h} -r resfile atf_check_equal_fail"
+ atf_check -s eq:0 -o ignore -e empty grep '^failed: a != b (a != b)$' \
+ resfile
+
+ atf_check -s eq:0 -o ignore -e ignore -x "${h} atf_check_equal_eval_ok"
+
+ atf_check -s eq:1 -o ignore -e ignore -x \
+ "${h} -r resfile atf_check_equal_eval_fail"
+ atf_check -s eq:0 -o ignore -e empty \
+ grep '^failed: \${x} != \${y} (a != b)$' resfile
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case info_ok
+ atf_add_test_case expout_mismatch
+ atf_add_test_case experr_mismatch
+ atf_add_test_case null_stdout
+ atf_add_test_case null_stderr
+ atf_add_test_case equal
+}
+
+# vim: syntax=sh:expandtab:shiftwidth=4:softtabstop=4
diff --git a/external/bsd/atf/dist/atf-sh/config_test.sh b/external/bsd/atf/dist/atf-sh/config_test.sh
new file mode 100644
index 00000000000..5662374fa83
--- /dev/null
+++ b/external/bsd/atf/dist/atf-sh/config_test.sh
@@ -0,0 +1,85 @@
+#
+# Automated Testing Framework (atf)
+#
+# Copyright (c) 2007, 2008, 2010 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
+# CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+atf_test_case has
+has_head()
+{
+ atf_set "descr" "Verifies that atf_config_has works"
+ atf_set "use.fs" "true"
+}
+has_body()
+{
+ h="$(atf_get_srcdir)/misc_helpers -s $(atf_get_srcdir)"
+
+ atf_check -s eq:0 -o match:'foo not found' -e empty -x \
+ "TEST_VARIABLE=foo ${h} config_has"
+
+ atf_check -s eq:0 -o match:'foo found' -e empty -x \
+ "TEST_VARIABLE=foo ${h} -v foo=bar config_has"
+
+ echo "Checking for deprecated variables"
+ atf_check -s eq:0 -o match:'workdir not found' -e empty -x \
+ "TEST_VARIABLE=workdir ${h} config_has"
+}
+
+atf_test_case get
+get_head()
+{
+ atf_set "descr" "Verifies that atf_config_get works"
+ atf_set "use.fs" "true"
+}
+get_body()
+{
+ h="$(atf_get_srcdir)/misc_helpers -s $(atf_get_srcdir)"
+
+ echo "Querying an undefined variable"
+ ( atf_config_get "undefined" ) >out 2>err && \
+ atf_fail "Getting an undefined variable succeeded"
+ grep 'not find' err || \
+ atf_fail "Getting an undefined variable did not report an error"
+
+ echo "Querying an undefined variable using a default value"
+ v=$(atf_config_get "undefined" "the default value")
+ [ "${v}" = "the default value" ] || \
+ atf_fail "Default value does not work"
+
+ atf_check -s eq:0 -o match:'foo = bar' -e empty -x \
+ "TEST_VARIABLE=foo ${h} -v foo=bar config_get"
+
+ atf_check -s eq:0 -o match:'foo = baz' -e empty -x \
+ "TEST_VARIABLE=foo ${h} -v foo=baz config_get"
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case has
+ atf_add_test_case get
+}
+
+# vim: syntax=sh:expandtab:shiftwidth=4:softtabstop=4
diff --git a/external/bsd/atf/dist/atf-sh/integration_test.sh b/external/bsd/atf/dist/atf-sh/integration_test.sh
new file mode 100644
index 00000000000..822316d89b8
--- /dev/null
+++ b/external/bsd/atf/dist/atf-sh/integration_test.sh
@@ -0,0 +1,100 @@
+#
+# Automated Testing Framework (atf)
+#
+# Copyright (c) 2010 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
+# CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+create_test_program() {
+ echo '#! /usr/bin/env atf-sh' >"${1}"
+ cat >>"${1}"
+ chmod +x "${1}"
+}
+
+atf_test_case no_args
+no_args_head() {
+ atf_set "use.fs" "true"
+}
+no_args_body()
+{
+ cat >experr <<EOF
+atf-sh: ERROR: No test program provided
+atf-sh: Type \`atf-sh -h' for more details.
+EOF
+ atf_check -s eq:1 -o ignore -e file:experr atf-sh
+}
+
+atf_test_case missing_script
+missing_script_head() {
+ atf_set "use.fs" "true"
+}
+missing_script_body()
+{
+ cat >experr <<EOF
+atf-sh: ERROR: The test program 'non-existent' does not exist
+EOF
+ atf_check -s eq:1 -o ignore -e file:experr atf-sh non-existent
+}
+
+atf_test_case arguments
+arguments_head() {
+ atf_set "use.fs" "true"
+}
+arguments_body()
+{
+ create_test_program tp <<EOF
+main() {
+ echo ">>>\${0}<<<"
+ while test \${#} -gt 0; do
+ echo ">>>\${1}<<<"
+ shift
+ done
+ true
+}
+EOF
+
+ cat >expout <<EOF
+>>>./tp<<<
+>>> a b <<<
+>>>foo<<<
+EOF
+ atf_check -s eq:0 -o file:expout -e empty ./tp ' a b ' foo
+
+ cat >expout <<EOF
+>>>tp<<<
+>>> hello bye <<<
+>>>foo bar<<<
+EOF
+ atf_check -s eq:0 -o file:expout -e empty atf-sh tp ' hello bye ' 'foo bar'
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case no_args
+ atf_add_test_case missing_script
+ atf_add_test_case arguments
+}
+
+# vim: syntax=sh:expandtab:shiftwidth=4:softtabstop=4
diff --git a/external/bsd/atf/dist/atf-sh/libatf-sh.subr b/external/bsd/atf/dist/atf-sh/libatf-sh.subr
index aa8410c20c2..d4c03959fee 100644
--- a/external/bsd/atf/dist/atf-sh/libatf-sh.subr
+++ b/external/bsd/atf/dist/atf-sh/libatf-sh.subr
@@ -33,13 +33,15 @@
# Values of configuration variables obtained from atf-config.
Atf_Arch=$(atf-config -t atf_arch)
-Atf_Cleanup=$(atf-config -t atf_libexecdir)/atf-cleanup
-Atf_Format=$(atf-config -t atf_libexecdir)/atf-format
Atf_Machine=$(atf-config -t atf_machine)
# The list of all test cases defined by the test program.
Defined_Test_Cases=
+# Values for the expect property.
+Expect=pass
+Expect_Reason=
+
# A boolean variable that indicates whether we are parsing a test case's
# head or not.
Parsing_Head=false
@@ -48,7 +50,7 @@ Parsing_Head=false
Prog_Name=${0##*/}
# The file to which the test case will print its result.
-Results_File=resfile # XXX
+Results_File=
# The test program's source directory: i.e. where its auxiliary data files
# and helper utilities can be found. Can be overriden through the '-s' flag.
@@ -63,6 +65,7 @@ Test_Case_Vars=
# The list of all test cases provided by the test program.
# Subset of ${Defined_Test_Cases}.
Test_Cases=
+Test_Cases_With_Cleanup=
# ------------------------------------------------------------------------
# PUBLIC INTERFACE
@@ -147,6 +150,101 @@ atf_config_has()
}
#
+# atf_expect_death reason
+#
+# Sets the expectations to 'death'.
+#
+atf_expect_death()
+{
+ _atf_validate_expect
+
+ Expect=death
+ _atf_create_resfile expected_death -1 "${@}"
+}
+
+#
+# atf_expect_timeout reason
+#
+# Sets the expectations to 'timeout'.
+#
+atf_expect_timeout()
+{
+ _atf_validate_expect
+
+ Expect=timeout
+ _atf_create_resfile expected_timeout -1 "${@}"
+}
+
+#
+# atf_expect_exit exitcode reason
+#
+# Sets the expectations to 'exit'.
+#
+atf_expect_exit()
+{
+ _exitcode="${1}"; shift
+
+ _atf_validate_expect
+
+ Expect=exit
+ _atf_create_resfile expected_exit "${_exitcode}" "${@}"
+}
+
+#
+# atf_expect_fail reason
+#
+# Sets the expectations to 'fail'.
+#
+atf_expect_fail()
+{
+ _atf_validate_expect
+
+ Expect=fail
+ Expect_Reason="${*}"
+}
+
+#
+# atf_expect_pass
+#
+# Sets the expectations to 'pass'.
+#
+atf_expect_pass()
+{
+ _atf_validate_expect
+
+ Expect=pass
+ Expect_Reason=
+}
+
+#
+# atf_expect_signal signo reason
+#
+# Sets the expectations to 'signal'.
+#
+atf_expect_signal()
+{
+ _signo="${1}"; shift
+
+ _atf_validate_expect
+
+ Expect=signal
+ _atf_create_resfile expected_signal "${_signo}" "${@}"
+}
+
+#
+# atf_expected_failure msg1 [.. msgN]
+#
+# Makes the test case report an expected failure with the given error
+# message. Multiple words can be provided, which are concatenated with
+# a single blank space.
+#
+atf_expected_failure()
+{
+ _atf_create_resfile expected_failure -1 "${Expect_Reason}:" "${@}"
+ exit 0
+}
+
+#
# atf_fail msg1 [.. msgN]
#
# Makes the test case fail with the given error message. Multiple
@@ -155,13 +253,18 @@ atf_config_has()
#
atf_fail()
{
- cat >${Results_File} <<EOF
-Content-Type: application/X-atf-tcr; version="1"
-
-result: failed
-reason: ${*}
-EOF
- exit 1
+ case "${Expect}" in
+ fail)
+ atf_expected_failure "${@}"
+ ;;
+ pass)
+ _atf_create_resfile failed -1 "${@}"
+ exit 1
+ ;;
+ *)
+ _atf_error 128 "Unreachable"
+ ;;
+ esac
}
#
@@ -205,16 +308,19 @@ atf_init_test_cases()
#
atf_pass()
{
- _create_pass_file
- exit 0
-}
-
-_create_pass_file() {
- cat >${Results_File} <<EOF
-Content-Type: application/X-atf-tcr; version="1"
-
-result: passed
-EOF
+ case "${Expect}" in
+ fail)
+ Expect=pass
+ atf_fail "Test case was expecting a failure but got a pass instead"
+ ;;
+ pass)
+ _atf_create_resfile passed -1
+ exit 0
+ ;;
+ *)
+ _atf_error 128 "Unreachable"
+ ;;
+ esac
}
#
@@ -273,22 +379,17 @@ atf_set()
#
atf_skip()
{
- cat >${Results_File} <<EOF
-Content-Type: application/X-atf-tcr; version="1"
-
-result: skipped
-reason: ${*}
-EOF
+ _atf_create_resfile skipped -1 "${@}"
exit 0
}
#
-# atf_test_case tc-name
+# atf_test_case tc-name cleanup
#
# Defines a new test case named tc-name. The name provided here must be
# accompanied by two functions named after it: <tc-name>_head and
-# <tc-name>_body, and may also be accompanied by a <tc-name>_cleanup
-# function.
+# <tc-name>_body. If cleanup is set to 'cleanup', then this also expects
+# a <tc-name>_cleanup function to be defined.
#
atf_test_case()
{
@@ -296,7 +397,13 @@ atf_test_case()
eval "${1}_head() { :; }"
eval "${1}_body() { :; }"
- eval "${1}_cleanup() { :; }"
+ if [ "${2}" = cleanup ]; then
+ Test_Cases_With_Cleanup="${Test_Cases_With_Cleanup} ${1}"
+ eval "${1}_cleanup() { :; }"
+ else
+ eval "${1}_cleanup() {
+ _atf_error 1 'Test case ${1} declared without a cleanup routine'; }"
+ fi
}
# ------------------------------------------------------------------------
@@ -335,14 +442,32 @@ _atf_config_set_from_str()
}
#
-# _atf_echo [-l indent] [-t tag] [msg1 [.. msgN]]
+# _atf_create_resfile result arg [reason ...]
#
-# Prints a formatted message using atf-format(1). See its manual
-# page for details on the syntax of this function.
+# Creates the results file.
#
-_atf_echo()
+_atf_create_resfile()
{
- ${Atf_Format} "${@}"
+ _result="${1}"; shift
+ if [ "${1}" -eq -1 ]; then
+ _arg=""
+ shift
+ else
+ _arg="(${1})"
+ shift
+ fi
+ if [ ${#} -gt 0 ]; then
+ _reason=": ${*}"
+ else
+ _reason=""
+ fi
+
+ if [ -n "${Results_File}" ]; then
+ echo "${_result}${_arg}${_reason}" >"${Results_File}" || \
+ _atf_error 128 "Cannot create results file '${Results_File}'"
+ else
+ echo "${_result}${_arg}${_reason}"
+ fi
}
#
@@ -395,7 +520,7 @@ _atf_error()
{
_error_code="${1}"; shift
- _atf_echo -r -t "${Prog_Name}: " "ERROR:" "$@" 1>&2
+ echo "${Prog_Name}: ERROR:" "$@" 1>&2
exit ${_error_code}
}
@@ -523,6 +648,10 @@ _atf_parse_head()
Test_Case="${1}"
Test_Case_Vars=
+ if _atf_has_cleanup "${1}"; then
+ atf_set has.cleanup "true"
+ fi
+
atf_set ident "${1}"
${1}_head
_atf_ensure_not_empty ident
@@ -565,10 +694,13 @@ _atf_run_tc()
case ${_tcpart} in
body)
${_tcname}_body
- _create_pass_file
+ _atf_validate_expect
+ _atf_create_resfile passed -1
;;
cleanup)
- ${_tcname}_cleanup
+ if _atf_has_cleanup "${_tcname}"; then
+ ${_tcname}_cleanup
+ fi
;;
*)
_atf_error 128 "Unknown test case part"
@@ -620,9 +752,8 @@ _atf_sigterm_handler()
#
_atf_syntax_error()
{
- _atf_echo -r -t "${Prog_Name}: " "ERROR: ${@}" 1>&2
- _atf_echo -r -t "${Prog_Name}: " "Type \`${Prog_Name} -h' for more" \
- "details." 1>&2
+ echo "${Prog_Name}: ERROR: ${@}" 1>&2
+ echo "${Prog_Name}: See atf-test-program(1) for usage details." 1>&2
exit 1
}
@@ -641,28 +772,57 @@ _atf_is_tc_defined()
}
#
-# _atf_usage
+# _atf_has_cleanup tc-name
#
-# Prints usage information and exits the program.
+# Returns a boolean indicating if the given test case has a cleanup
+# routine or not.
#
-_atf_usage()
+_atf_has_cleanup()
{
- _atf_echo -t "Usage: " "${Prog_Name} [options] test_case"
- echo
- _atf_echo "This is an independent atf test program."
- echo
- _atf_echo "Available options:"
- _atf_echo -t " -h " "Shows this help message"
- _atf_echo -t " -l " "List test cases and their purpose"
- _atf_echo -t " -r resfile " "The file to which the test program " \
- "will write the results of the " \
- "executed test case"
- _atf_echo -t " -s srcdir " "Directory where the test's data" \
- "files are located"
- _atf_echo -t " -v var=value " "Sets the configuration variable" \
- "\`var' to \`value'"
- echo
- _atf_echo "For more details please see atf-test-program(1) and atf(7)."
+ for _tc in ${Test_Cases_With_Cleanup}; do
+ [ ${_tc} = ${1} ] && return 0
+ done
+ return 1
+}
+
+#
+# _atf_validate_expect
+#
+# Ensures that the current test case state is correct regarding the expect
+# status.
+#
+_atf_validate_expect()
+{
+ case "${Expect}" in
+ death)
+ Expect=pass
+ atf_fail "Test case was expected to terminate abruptly but it" \
+ "continued execution"
+ ;;
+ exit)
+ Expect=pass
+ atf_fail "Test case was expected to exit cleanly but it continued" \
+ "execution"
+ ;;
+ fail)
+ Expect=pass
+ atf_fail "Test case was expecting a failure but none were raised"
+ ;;
+ pass)
+ ;;
+ signal)
+ Expect=pass
+ atf_fail "Test case was expected to receive a termination signal" \
+ "but it continued execution"
+ ;;
+ timeout)
+ Expect=pass
+ atf_fail "Test case was expected to hang but it continued execution"
+ ;;
+ *)
+ _atf_error 128 "Unreachable"
+ ;;
+ esac
}
#
@@ -676,7 +836,7 @@ _atf_usage()
#
_atf_warning()
{
- _atf_echo -r -t "${Prog_Name}: " "WARNING:" "$@" 1>&2
+ echo "${Prog_Name}: WARNING:" "$@" 1>&2
}
#
@@ -688,14 +848,9 @@ main()
{
# Process command-line options first.
_numargs=${#}
- _hflag=false
_lflag=false
- while getopts :hlr:s:v: arg; do
+ while getopts :lr:s:v: arg; do
case ${arg} in
- h)
- _hflag=true
- ;;
-
l)
_lflag=true
;;
@@ -720,13 +875,6 @@ main()
done
shift `expr ${OPTIND} - 1`
- if [ ${_hflag} = true ]; then
- [ ${_numargs} -eq 1 ] || _atf_syntax_error "-h must be given alone."
- _atf_usage
- true
- return
- fi
-
# First of all, make sure that the source directory is correct. It
# doesn't matter if the user did not change it, because the default
# value may not work. (TODO: It possibly should, even though it is
diff --git a/external/bsd/atf/dist/atf-sh/misc_helpers.sh b/external/bsd/atf/dist/atf-sh/misc_helpers.sh
new file mode 100644
index 00000000000..1e3d1f2b8d1
--- /dev/null
+++ b/external/bsd/atf/dist/atf-sh/misc_helpers.sh
@@ -0,0 +1,278 @@
+#
+# Automated Testing Framework (atf)
+#
+# Copyright (c) 2007, 2008 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
+# CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+# -------------------------------------------------------------------------
+# Helper tests for "t_atf_check".
+# -------------------------------------------------------------------------
+
+atf_test_case atf_check_info_ok
+atf_check_info_ok_head()
+{
+ atf_set "descr" "Helper test case for the t_atf_check test program"
+}
+atf_check_info_ok_body()
+{
+ atf_check -s eq:0 -o empty -e empty true
+}
+
+atf_test_case atf_check_info_fail
+atf_check_info_fail_head()
+{
+ atf_set "descr" "Helper test case for the t_atf_check test program"
+}
+atf_check_info_fail_body()
+{
+ # In Solaris, /usr/bin/false returns 255 rather than 1. Use the
+ # built-in version for the check.
+ atf_check -s eq:1 -o empty -e empty sh -c "false"
+}
+
+atf_test_case atf_check_expout_mismatch
+atf_check_expout_mismatch_head()
+{
+ atf_set "descr" "Helper test case for the t_atf_check test program"
+}
+atf_check_expout_mismatch_body()
+{
+ cat >expout <<SECONDEOF
+foo
+SECONDEOF
+ atf_check -s eq:0 -o file:expout -e empty echo bar
+}
+
+atf_test_case atf_check_experr_mismatch
+atf_check_experr_mismatch_head()
+{
+ atf_set "descr" "Helper test case for the t_atf_check test program"
+}
+atf_check_experr_mismatch_body()
+{
+ cat >experr <<SECONDEOF
+foo
+SECONDEOF
+ atf_check -s eq:0 -o empty -e file:experr -x 'echo bar 1>&2'
+}
+
+atf_test_case atf_check_null_stdout
+atf_check_null_stdout_head()
+{
+ atf_set "descr" "Helper test case for the t_atf_check test program"
+}
+atf_check_null_stdout_body()
+{
+ atf_check -s eq:0 -o empty -e empty echo "These are the contents"
+}
+
+atf_test_case atf_check_null_stderr
+atf_check_null_stderr_head()
+{
+ atf_set "descr" "Helper test case for the t_atf_check test program"
+}
+atf_check_null_stderr_body()
+{
+ atf_check -s eq:0 -o empty -e empty -x 'echo "These are the contents" 1>&2'
+}
+
+atf_test_case atf_check_equal_ok
+atf_check_equal_ok_head()
+{
+ atf_set "descr" "Helper test case for the t_atf_check test program"
+}
+atf_check_equal_ok_body()
+{
+ atf_check_equal a a
+}
+
+atf_test_case atf_check_equal_fail
+atf_check_equal_fail_head()
+{
+ atf_set "descr" "Helper test case for the t_atf_check test program"
+}
+atf_check_equal_fail_body()
+{
+ atf_check_equal a b
+}
+
+atf_test_case atf_check_equal_eval_ok
+atf_check_equal_eval_ok_head()
+{
+ atf_set "descr" "Helper test case for the t_atf_check test program"
+}
+atf_check_equal_eval_ok_body()
+{
+ x=a
+ y=a
+ atf_check_equal '${x}' '${y}'
+}
+
+atf_test_case atf_check_equal_eval_fail
+atf_check_equal_eval_fail_head()
+{
+ atf_set "descr" "Helper test case for the t_atf_check test program"
+}
+atf_check_equal_eval_fail_body()
+{
+ x=a
+ y=b
+ atf_check_equal '${x}' '${y}'
+}
+
+# -------------------------------------------------------------------------
+# Helper tests for "t_config".
+# -------------------------------------------------------------------------
+
+atf_test_case config_get
+config_get_head()
+{
+ atf_set "descr" "Helper test case for the t_config test program"
+}
+config_get_body()
+{
+ if atf_config_has ${TEST_VARIABLE}; then
+ echo "${TEST_VARIABLE} = $(atf_config_get ${TEST_VARIABLE})"
+ fi
+}
+
+atf_test_case config_has
+config_has_head()
+{
+ atf_set "descr" "Helper test case for the t_config test program"
+}
+config_has_body()
+{
+ if atf_config_has ${TEST_VARIABLE}; then
+ echo "${TEST_VARIABLE} found"
+ else
+ echo "${TEST_VARIABLE} not found"
+ fi
+}
+
+# -------------------------------------------------------------------------
+# Helper tests for "t_normalize".
+# -------------------------------------------------------------------------
+
+atf_test_case normalize
+normalize_head()
+{
+ atf_set "descr" "Helper test case for the t_normalize test program"
+ atf_set "a.b" "test value 1"
+ atf_set "c-d" "test value 2"
+}
+normalize_body()
+{
+ echo "a.b: $(atf_get a.b)"
+ echo "c-d: $(atf_get c-d)"
+}
+
+# -------------------------------------------------------------------------
+# Helper tests for "t_tc".
+# -------------------------------------------------------------------------
+
+atf_test_case tc_pass_true
+tc_pass_true_head()
+{
+ atf_set "descr" "Helper test case for the t_tc test program"
+}
+tc_pass_true_body()
+{
+ true
+}
+
+atf_test_case tc_pass_false
+tc_pass_false_head()
+{
+ atf_set "descr" "Helper test case for the t_tc test program"
+}
+tc_pass_false_body()
+{
+ false
+}
+
+atf_test_case tc_fail
+tc_fail_head()
+{
+ atf_set "descr" "Helper test case for the t_tc test program"
+}
+tc_fail_body()
+{
+ echo "An error" 1>&2
+ exit 1
+}
+
+# -------------------------------------------------------------------------
+# Helper tests for "t_tp".
+# -------------------------------------------------------------------------
+
+atf_test_case tp_srcdir
+tp_srcdir_head()
+{
+ atf_set "descr" "Helper test case for the t_tp test program"
+}
+tp_srcdir_body()
+{
+ echo "Calling helper"
+ helper_subr || atf_fail "Could not call helper subroutine"
+}
+
+# -------------------------------------------------------------------------
+# Main.
+# -------------------------------------------------------------------------
+
+atf_init_test_cases()
+{
+ # Add helper tests for t_atf_check.
+ atf_add_test_case atf_check_info_ok
+ atf_add_test_case atf_check_info_fail
+ atf_add_test_case atf_check_expout_mismatch
+ atf_add_test_case atf_check_experr_mismatch
+ atf_add_test_case atf_check_null_stdout
+ atf_add_test_case atf_check_null_stderr
+ atf_add_test_case atf_check_equal_ok
+ atf_add_test_case atf_check_equal_fail
+ atf_add_test_case atf_check_equal_eval_ok
+ atf_add_test_case atf_check_equal_eval_fail
+
+ # Add helper tests for t_config.
+ atf_add_test_case config_get
+ atf_add_test_case config_has
+
+ # Add helper tests for t_normalize.
+ atf_add_test_case normalize
+
+ # Add helper tests for t_tc.
+ atf_add_test_case tc_pass_true
+ atf_add_test_case tc_pass_false
+ atf_add_test_case tc_fail
+
+ # Add helper tests for t_tp.
+ [ -f $(atf_get_srcdir)/subrs ] && . $(atf_get_srcdir)/subrs
+ atf_add_test_case tp_srcdir
+}
+
+# vim: syntax=sh:expandtab:shiftwidth=4:softtabstop=4
diff --git a/external/bsd/atf/dist/atf-sh/normalize_test.sh b/external/bsd/atf/dist/atf-sh/normalize_test.sh
new file mode 100644
index 00000000000..8380976fbf5
--- /dev/null
+++ b/external/bsd/atf/dist/atf-sh/normalize_test.sh
@@ -0,0 +1,49 @@
+#
+# Automated Testing Framework (atf)
+#
+# Copyright (c) 2007, 2008, 2010 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
+# CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+atf_test_case main
+main_head()
+{
+ atf_set "descr" "Verifies that variable names with symbols not" \
+ "allowed as part of shell variable names work"
+ atf_set "use.fs" "true"
+}
+main_body()
+{
+ h="$(atf_get_srcdir)/misc_helpers -s $(atf_get_srcdir)"
+ atf_check -s eq:0 -o match:'a.b: test value 1' \
+ -o match:'c-d: test value 2' -e ignore ${h} normalize
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case main
+}
+
+# vim: syntax=sh:expandtab:shiftwidth=4:softtabstop=4
diff --git a/external/bsd/atf/dist/atf-sh/tc_test.sh b/external/bsd/atf/dist/atf-sh/tc_test.sh
new file mode 100644
index 00000000000..c58634707b5
--- /dev/null
+++ b/external/bsd/atf/dist/atf-sh/tc_test.sh
@@ -0,0 +1,50 @@
+#
+# Automated Testing Framework (atf)
+#
+# Copyright (c) 2007, 2008, 2010 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
+# CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+atf_test_case default_status
+default_status_head()
+{
+ atf_set "descr" "Verifies that test cases get the correct default" \
+ "status if they did not provide any"
+ atf_set "use.fs" "true"
+}
+default_status_body()
+{
+ h="$(atf_get_srcdir)/misc_helpers -s $(atf_get_srcdir)"
+ atf_check -s eq:0 -o ignore -e ignore ${h} tc_pass_true
+ atf_check -s eq:0 -o ignore -e ignore ${h} tc_pass_false
+ atf_check -s eq:1 -o ignore -e match:'An error' ${h} tc_fail
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case default_status
+}
+
+# vim: syntax=sh:expandtab:shiftwidth=4:softtabstop=4
diff --git a/external/bsd/atf/dist/atf-sh/tp_test.sh b/external/bsd/atf/dist/atf-sh/tp_test.sh
new file mode 100644
index 00000000000..5c7d1657be6
--- /dev/null
+++ b/external/bsd/atf/dist/atf-sh/tp_test.sh
@@ -0,0 +1,57 @@
+#
+# Automated Testing Framework (atf)
+#
+# Copyright (c) 2007, 2008, 2010 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
+# CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+atf_test_case srcdir
+srcdir_head()
+{
+ atf_set "descr" "Verifies that the source directory can be queried" \
+ "from the initialization function"
+ atf_set "use.fs" "true"
+}
+srcdir_body()
+{
+ mkdir work
+ atf_check -s eq:0 -o empty -e empty cp "$(atf_get_srcdir)/misc_helpers" work
+ cat >work/subrs <<EOF
+helper_subr() {
+ echo "This is a helper subroutine"
+}
+EOF
+
+ atf_check -s eq:0 -o match:'Calling helper' \
+ -o match:'This is a helper subroutine' -e empty ./work/misc_helpers \
+ -s "$(pwd)"/work tp_srcdir
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case srcdir
+}
+
+# vim: syntax=sh:expandtab:shiftwidth=4:softtabstop=4
diff --git a/external/bsd/atf/dist/atf-version/generate-revision.sh b/external/bsd/atf/dist/atf-version/generate-revision.sh
new file mode 100755
index 00000000000..e7d4d3dab99
--- /dev/null
+++ b/external/bsd/atf/dist/atf-version/generate-revision.sh
@@ -0,0 +1,182 @@
+#! /bin/sh
+#
+# Automated Testing Framework (atf)
+#
+# Copyright (c) 2007, 2008, 2009, 2010 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
+# CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+#
+# Generates a header file with information about the revision used to
+# build ATF.
+#
+
+set -e
+
+Prog_Name=${0##*/}
+
+MTN=
+ROOT=
+
+#
+# err message
+#
+err() {
+ echo "${Prog_Name}: ${@}" 1>&2
+ exit 1
+}
+
+#
+# call_mtn args
+#
+call_mtn() {
+ ${MTN} --root=${ROOT} "${@}"
+}
+
+# extract_certs rev
+#
+extract_certs() {
+ call_mtn automate certs ${1} | awk '
+BEGIN {
+ current_cert = ""
+}
+
+/^[ \t]*name "([^"]*)"[ \t]*$/ {
+ current_cert = substr($2, 2, length($2) - 2)
+ next
+}
+
+/^[ \t]*value "([^"]*)"[ \t]*$/ {
+ value = substr($2, 2, length($2) - 2)
+ if (current_cert == "branch") {
+ print "rev_branch=\"" value "\""
+ } else if (current_cert == "date") {
+ print "rev_date=\"" value "\""
+ }
+ next
+}
+'
+}
+
+#
+# get_rev_info_into_vars
+#
+# Sets the following variables to describe the current revision of the tree:
+# rev_base_id: The base revision identifier.
+# rev_branch: The branch name.
+# rev_modified: true if the tree has been locally modified.
+# rev_date: The date of the revision.
+#
+get_rev_info_into_vars() {
+ rev_base_id=$(call_mtn automate get_base_revision_id)
+
+ if call_mtn status | grep "no changes" >/dev/null; then
+ rev_modified=false
+ else
+ rev_modified=true
+ fi
+
+ # The following defines several rev_* variables.
+ eval $(extract_certs ${rev_base_id})
+}
+
+#
+# generate_from_dist revfile version
+#
+generate_from_dist() {
+ revfile=${1}; shift
+ version=${1}; shift
+
+ >${revfile}
+
+ echo "#define PACKAGE_REVISION_TYPE_DIST" >>${revfile}
+}
+
+#
+# generate_from_mtn revfile
+#
+generate_from_mtn() {
+ revfile=${1}
+
+ get_rev_info_into_vars
+
+ >${revfile}
+
+ echo "#define PACKAGE_REVISION_TYPE_MTN" >>${revfile}
+
+ echo "#define PACKAGE_REVISION_BRANCH \"${rev_branch}\"" >>${revfile}
+ echo "#define PACKAGE_REVISION_BASE \"${rev_base_id}\"" >>${revfile}
+
+ if [ ${rev_modified} = true ]; then
+ echo "#define PACKAGE_REVISION_MODIFIED 1" >>${revfile}
+ fi
+
+ echo "#define PACKAGE_REVISION_DATE \"${rev_date}\"" >>${revfile}
+}
+
+#
+# main
+#
+# Entry point.
+#
+main() {
+ outfile=
+ version=
+ while getopts :m:r:o:v: arg; do
+ case ${arg} in
+ m)
+ MTN=${OPTARG}
+ ;;
+ o)
+ outfile=${OPTARG}
+ ;;
+ r)
+ ROOT=${OPTARG}
+ ;;
+ v)
+ version=${OPTARG}
+ ;;
+ *)
+ err "Unknown option ${arg}"
+ ;;
+ esac
+ done
+ [ -n "${ROOT}" ] || \
+ err "Must specify the top-level source directory with -r"
+ [ -n "${outfile}" ] || \
+ err "Must specify an output file with -o"
+ [ -n "${version}" ] || \
+ err "Must specify a version number with -v"
+
+ if [ -n "${MTN}" -a -d ${ROOT}/_MTN ]; then
+ generate_from_mtn ${outfile}
+ else
+ generate_from_dist ${outfile} ${version}
+ fi
+}
+
+main "${@}"
+
+# vim: syntax=sh:expandtab:shiftwidth=4:softtabstop=4
diff --git a/external/bsd/atf/dist/atf-version/revision.h b/external/bsd/atf/dist/atf-version/revision.h
new file mode 100644
index 00000000000..ba7fbae0ec1
--- /dev/null
+++ b/external/bsd/atf/dist/atf-version/revision.h
@@ -0,0 +1,4 @@
+#define PACKAGE_REVISION_TYPE_MTN
+#define PACKAGE_REVISION_BRANCH "org.NetBSD.atf.src"
+#define PACKAGE_REVISION_BASE "bab5e0f99e767de2e6650bf3c1aa7a7aad23a915"
+#define PACKAGE_REVISION_DATE "2010-07-02T14:45:21"
diff --git a/external/bsd/atf/dist/doc/atf-formats.5 b/external/bsd/atf/dist/doc/atf-formats.5
index c5d8a2fec96..1d5edd5b352 100644
--- a/external/bsd/atf/dist/doc/atf-formats.5
+++ b/external/bsd/atf/dist/doc/atf-formats.5
@@ -26,7 +26,7 @@
.\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
.\" IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd January 4, 2010
+.Dd June 7, 2010
.Dt ATF-FORMATS 5
.Os
.Sh NAME
@@ -149,36 +149,6 @@ An example:
var1 = this is a variable value
var2 = this is another one # Optional comment at the end.
.Ed
-.Ss Format: application/X-atf-tcr, version: 1
-The
-.Sq application/X-atf-tcr
-format is used to represent the result of a single test case.
-It is composed of a mandatory result type and an optional reason fields.
-Its grammar is as follows:
-.Bd -literal -offset indent
-DATA ::= RESULT REASON? EOF
-RESULT ::= 'result' COLON ('passed' | 'failed' | 'skipped')
-REASON ::= 'reason' COLON STRING
-.Ed
-.Pp
-The reason string is a free-format string ending at the first encountered
-newline character; it should not be quoted, as otherwise the quotation
-characters will appear as part of the reason message.
-.Pp
-The reason field can only appear when the result is not
-.Sq passed .
-.Pp
-An example:
-An example:
-.Bd -literal -offset indent
-result: passed
-.Ed
-.Pp
-Another example:
-.Bd -literal -offset indent
-result: skipped
-reason: This test requires superuser privileges
-.Ed
.Ss Format: application/X-atf-tps, version: 2
The
.Sq application/X-atf-tps
diff --git a/external/bsd/atf/dist/doc/atf-test-case.4 b/external/bsd/atf/dist/doc/atf-test-case.4
index 68bb7165578..115a9efdbda 100644
--- a/external/bsd/atf/dist/doc/atf-test-case.4
+++ b/external/bsd/atf/dist/doc/atf-test-case.4
@@ -26,8 +26,8 @@
.\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
.\" IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd June 1, 2010
-.Dt ATF-TEST-CASE 8
+.Dd June 28, 2010
+.Dt ATF-TEST-CASE 4
.Os
.Sh NAME
.Nm atf-test-case
@@ -79,10 +79,29 @@ At last, test cases are always contained into test programs.
The test programs act as a front-end to them, providing a consistent
interface to the user and several APIs to ease their implementation.
.Ss Results
-A test case always exits with one of the following results:
-.Bl -tag -width skippedXX
+Upon termination, a test case reports a status and, optionally, a textual
+reason describing why the test reported such status.
+The caller must ensure that the test case really performed the task that its
+status describes, as the test program may be bogus and therefore providing a
+misleading result (e.g. providing a result that indicates success but the
+error code of the program says otherwise).
+.Pp
+The possible exit status of a test case are one of the following:
+.Bl -tag -width expectedXfailureXX
+.It expected_death
+The test case expects to terminate abruptly.
+.It expected_exit
+The test case expects to exit cleanly.
+.It expected_failure
+The test case expects to exit with a controller fatal/non-fatal failure.
+If this happens, the test program exits with a success error code.
+.It expected_signal
+The test case expects to receive a signal that makes it terminate.
+.It expected_timeout
+The test case expects to execute for longer than its timeout.
.It passed
The test case was executed successfully.
+The test program exits with a success error code.
.It skipped
The test case could not be executed because some preconditions were not
met.
@@ -91,12 +110,30 @@ the system to meet the necessary conditions.
This is always accompanied by a
.Em reason ,
a message describing why the test was skipped.
+The test program exits with a success error code.
.It failed
An error appeared during the execution of the test case.
This is always accompanied by a
.Em reason ,
a message describing why the test failed.
+The test program exits with a failure error code.
.El
+.Pp
+The usefulness of the
+.Sq expected_*
+results comes when writing test cases that verify known failures caused,
+in general, due to programming errors (aka bugs).
+Whenever the faulty condition that the expectation is trying to convery is
+fixed, then the test case will be reported as
+.Sq failed
+and the developer will have to adjust it to match its new condition.
+.Pp
+It is important to note that all
+.Sq expected_*
+results are only provided as a
+.Em hint
+to the caller; the caller must verify that the test case did actually terminate
+as the expected condition says.
.Ss Input/output
Test cases are free to print whatever they want to their
.Xr stdout 4
@@ -124,6 +161,16 @@ Required.
A brief textual description of the test case's purpose.
Will be shown to the user in reports.
Also good for documentation purposes.
+.It has.cleanup
+Type: boolean.
+Optional.
+.Pp
+If set to true, specifies that the test case has a cleanup routine that has
+to be executed by
+.Xr atf-run 1
+during the cleanup phase of the execution.
+This property is automatically set by the framework when defining a test case
+with a cleanup routine, so it should never be set by hand.
.It ident
Type: textual.
Required.
diff --git a/external/bsd/atf/dist/doc/atf-test-program.1 b/external/bsd/atf/dist/doc/atf-test-program.1
index 3081681ddcd..fe6ab989844 100644
--- a/external/bsd/atf/dist/doc/atf-test-program.1
+++ b/external/bsd/atf/dist/doc/atf-test-program.1
@@ -1,7 +1,7 @@
.\"
.\" Automated Testing Framework (atf)
.\"
-.\" Copyright (c) 2007, 2008 The NetBSD Foundation, Inc.
+.\" Copyright (c) 2007, 2008, 2010 The NetBSD Foundation, Inc.
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
@@ -26,7 +26,7 @@
.\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
.\" IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd August 18, 2007
+.Dd June 18, 2010
.Dt ATF-TEST-PROGRAM 1
.Os
.Sh NAME
@@ -34,47 +34,54 @@
.Nd common interface to ATF test programs
.Sh SYNOPSIS
.Nm
-.Op Fl r Ar fd
+.Op Fl r Ar resfile
.Op Fl s Ar srcdir
.Op Fl v Ar var1=value1 Op .. Fl v Ar varN=valueN
-.Op Ar test_case1 Op Ar .. test_caseN
+.Ar test_case
.Nm
.Fl l
-.Ar test_case1
-.Op Ar test_case1 Op Ar .. test_caseN
-.Nm
-.Fl h
.Sh DESCRIPTION
Test programs written using the ATF libraries all share a common user
interface, which is what this manual page describes.
.Pp
-In the first synopsis form, the test program will execute the listed
-test cases, or all of them if none are provided as arguments.
-The test cases' names can be given as glob patterns.
+In the first synopsis form, the test program will execute the provided
+test case and print its results to the standard output, unless otherwise
+stated by the
+.Fl r
+flag.
+Optionally, the test case name can be suffixed by
+.Sq :cleanup ,
+in which case the cleanup routine of the test case will be executed
+instead of the test case body; see
+.Xr atf-test-case 4 .
+Note that the test case is
+.Em executed without isolation ,
+so it can and probably will create and modify files in the current directory.
+To execute test cases in a controller manner, refer to
+.Xr atf-run 1 ,
+which is the preferred way to run test cases.
+You should only execute test cases by hand for debugging purposes.
.Pp
In the second synopsis form, the test program will list all available
-test cases alongside a brief description of what they do.
-If any arguments are specified, the list will be restricted to the
-matching test cases.
-The test cases' names can be given as glob patterns.
-.Pp
-In the third synopsis form, the test program will print information
-about all supported options and their purpose.
+test cases alongside their meta-data properties in a format that is
+machine parseable.
+This list is processed by
+.Xr atf-run 1
+to know how to execute the test cases of a given test program.
.Pp
The following options are available:
.Bl -tag -width XvXvarXvalueXX
-.It Fl h
-Shows a short summary of all available options and their purpose.
.It Fl l
Lists available test cases alongside a brief description for each of them.
-.It Fl r Ar fd
-Specifies the file descriptor to which the test case will redirect its
-results.
-These results follow a machine-parseable standardized format, and are not
-meant for direct user consumption.
-See
-.Xr atf-formats 5
-for more details.
+.It Fl r Ar resfile
+Specifies the file that will receive the test case result.
+If not specified, the test case prints its results to stdout.
+If the result of a test case needs to be parsed by another program, you must
+use this option to redirect the result to a file and then read the resulting
+file from the other program.
+Note:
+.Em do not try to process the stdout of the test case
+because your program may break in the future.
.It Fl s Ar srcdir
The path to the directory where the test program is located.
This is needed in all cases, except when the test program is being executed
diff --git a/external/bsd/atf/dist/doc/atf.7.in b/external/bsd/atf/dist/doc/atf.7.in
index d284219c378..6178caf9bea 100644
--- a/external/bsd/atf/dist/doc/atf.7.in
+++ b/external/bsd/atf/dist/doc/atf.7.in
@@ -26,7 +26,7 @@
.\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
.\" IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd May 9, 2010
+.Dd June 27, 2010
.Dt ATF 7
.Os
.Sh NAME
@@ -54,6 +54,12 @@ have source trees around nor any other development tools installed to be
able to certify that a given piece of software works on their machine as
advertised.
.Pp
+If your operating systems distributes
+.Nm ,
+it is possible that it provides an introductory
+.Xr tests 7
+manual page.
+You are encouraged to read it now.
.Ss License
.Nm
is distributed under the terms of the TNF License, a 2-clause BSD license.
@@ -89,14 +95,6 @@ results in a unified report.
Shell interpreter for shell-based test programs.
.El
.Pp
-Internal utilities:
-.Bl -tag -width atfXtestXprogramXXXXX
-.It Xr atf-cleanup 1
-Safely cleans up a work directory after a test case terminates.
-.It Xr atf-format 1
-Reformats a text string to not overflow terminal boundaries.
-.El
-.Pp
Programming interfaces:
.Bl -tag -width atfXtestXprogramXXXXX
.It Xr atf-c-api 3
@@ -123,6 +121,9 @@ libraries.
For end users wishing to run tests:
.Bl -enum -compact
.It
+.Xr tests 7
+(only if provided by your operating system).
+.It
.Xr atf-test-program 1
.It
.Xr atf-run 1
@@ -160,11 +161,9 @@ Everything recommended to users.
Everything recommended to developers.
.It
.Xr atf-formats 5
-.It
-.Xr atf-cleanup 1
-.It
-.Xr atf-format 1
.El
+.Sh SEE ALSO
+.Xr tests 7
.Sh HISTORY
.Nm
started as a Google Summer of Code 2007 project mentored by The NetBSD
diff --git a/external/bsd/atf/dist/test-programs/Atffile b/external/bsd/atf/dist/test-programs/Atffile
new file mode 100644
index 00000000000..253d3e8ab55
--- /dev/null
+++ b/external/bsd/atf/dist/test-programs/Atffile
@@ -0,0 +1,10 @@
+Content-Type: application/X-atf-atffile; version="1"
+
+prop: test-suite = atf
+
+tp: config_test
+tp: expect_test
+tp: fork_test
+tp: meta_data_test
+tp: srcdir_test
+tp: result_test
diff --git a/external/bsd/atf/dist/test-programs/c_helpers.c b/external/bsd/atf/dist/test-programs/c_helpers.c
new file mode 100644
index 00000000000..e38d0734da0
--- /dev/null
+++ b/external/bsd/atf/dist/test-programs/c_helpers.c
@@ -0,0 +1,577 @@
+/*
+ * Automated Testing Framework (atf)
+ *
+ * Copyright (c) 2007, 2008, 2009, 2010 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <atf-c.h>
+
+#include "atf-c/env.h"
+#include "atf-c/error.h"
+#include "atf-c/fs.h"
+#include "atf-c/text.h"
+
+#include "atf-c/test_helpers.h"
+
+/* ---------------------------------------------------------------------
+ * Auxiliary functions.
+ * --------------------------------------------------------------------- */
+
+static
+void
+safe_remove(const char* path)
+{
+ if (unlink(path) == -1)
+ atf_tc_fail("unlink(2) of %s failed", path);
+}
+
+static
+void
+touch(const char *path)
+{
+ int fd;
+ fd = open(path, O_WRONLY | O_TRUNC | O_CREAT, 0644);
+ if (fd == -1)
+ atf_tc_fail("Could not create file %s", path);
+ close(fd);
+}
+
+/* ---------------------------------------------------------------------
+ * Helper tests for "t_cleanup".
+ * --------------------------------------------------------------------- */
+
+ATF_TC_WITH_CLEANUP(cleanup_pass);
+ATF_TC_HEAD(cleanup_pass, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Helper test case for the t_cleanup test "
+ "program");
+}
+ATF_TC_BODY(cleanup_pass, tc)
+{
+ touch(atf_tc_get_config_var(tc, "tmpfile"));
+}
+ATF_TC_CLEANUP(cleanup_pass, tc)
+{
+ bool cleanup;
+
+ RE(atf_text_to_bool(atf_tc_get_config_var(tc, "cleanup"), &cleanup));
+
+ if (cleanup)
+ safe_remove(atf_tc_get_config_var(tc, "tmpfile"));
+}
+
+ATF_TC_WITH_CLEANUP(cleanup_fail);
+ATF_TC_HEAD(cleanup_fail, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Helper test case for the t_cleanup test "
+ "program");
+}
+ATF_TC_BODY(cleanup_fail, tc)
+{
+ touch(atf_tc_get_config_var(tc, "tmpfile"));
+ atf_tc_fail("On purpose");
+}
+ATF_TC_CLEANUP(cleanup_fail, tc)
+{
+ bool cleanup;
+
+ RE(atf_text_to_bool(atf_tc_get_config_var(tc, "cleanup"), &cleanup));
+
+ if (cleanup)
+ safe_remove(atf_tc_get_config_var(tc, "tmpfile"));
+}
+
+ATF_TC_WITH_CLEANUP(cleanup_skip);
+ATF_TC_HEAD(cleanup_skip, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Helper test case for the t_cleanup test "
+ "program");
+}
+ATF_TC_BODY(cleanup_skip, tc)
+{
+ touch(atf_tc_get_config_var(tc, "tmpfile"));
+ atf_tc_skip("On purpose");
+}
+ATF_TC_CLEANUP(cleanup_skip, tc)
+{
+ bool cleanup;
+
+ RE(atf_text_to_bool(atf_tc_get_config_var(tc, "cleanup"), &cleanup));
+
+ if (cleanup)
+ safe_remove(atf_tc_get_config_var(tc, "tmpfile"));
+}
+
+ATF_TC_WITH_CLEANUP(cleanup_curdir);
+ATF_TC_HEAD(cleanup_curdir, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Helper test case for the t_cleanup test "
+ "program");
+}
+ATF_TC_BODY(cleanup_curdir, tc)
+{
+ FILE *f;
+
+ f = fopen("oldvalue", "w");
+ if (f == NULL)
+ atf_tc_fail("Failed to create oldvalue file");
+ fprintf(f, "1234");
+ fclose(f);
+}
+ATF_TC_CLEANUP(cleanup_curdir, tc)
+{
+ FILE *f;
+
+ f = fopen("oldvalue", "r");
+ if (f != NULL) {
+ int i;
+ if (fscanf(f, "%d", &i) != 1)
+ fprintf(stderr, "Failed to read old value\n");
+ else
+ printf("Old value: %d", i);
+ fclose(f);
+ }
+}
+
+ATF_TC_WITH_CLEANUP(cleanup_sigterm);
+ATF_TC_HEAD(cleanup_sigterm, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Helper test case for the t_cleanup test "
+ "program");
+}
+ATF_TC_BODY(cleanup_sigterm, tc)
+{
+ char *nofile;
+
+ touch(atf_tc_get_config_var(tc, "tmpfile"));
+ kill(getpid(), SIGTERM);
+
+ RE(atf_text_format(&nofile, "%s.no",
+ atf_tc_get_config_var(tc, "tmpfile")));
+ touch(nofile);
+ free(nofile);
+}
+ATF_TC_CLEANUP(cleanup_sigterm, tc)
+{
+ safe_remove(atf_tc_get_config_var(tc, "tmpfile"));
+}
+
+ATF_TC_WITH_CLEANUP(cleanup_fork);
+ATF_TC_HEAD(cleanup_fork, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Helper test case for the t_cleanup test "
+ "program");
+}
+ATF_TC_BODY(cleanup_fork, tc)
+{
+}
+ATF_TC_CLEANUP(cleanup_fork, tc)
+{
+ close(STDOUT_FILENO);
+ close(STDERR_FILENO);
+ close(3);
+}
+
+/* ---------------------------------------------------------------------
+ * Helper tests for "t_config".
+ * --------------------------------------------------------------------- */
+
+ATF_TC(config_unset);
+ATF_TC_HEAD(config_unset, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Helper test case for the t_config test "
+ "program");
+}
+ATF_TC_BODY(config_unset, tc)
+{
+ ATF_REQUIRE(!atf_tc_has_config_var(tc, "test"));
+}
+
+ATF_TC(config_empty);
+ATF_TC_HEAD(config_empty, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Helper test case for the t_config test "
+ "program");
+}
+ATF_TC_BODY(config_empty, tc)
+{
+ ATF_REQUIRE(atf_tc_has_config_var(tc, "test"));
+ ATF_REQUIRE(strlen(atf_tc_get_config_var(tc, "test")) == 0);
+}
+
+ATF_TC(config_value);
+ATF_TC_HEAD(config_value, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Helper test case for the t_config test "
+ "program");
+}
+ATF_TC_BODY(config_value, tc)
+{
+ ATF_REQUIRE(atf_tc_has_config_var(tc, "test"));
+ ATF_REQUIRE(strcmp(atf_tc_get_config_var(tc, "test"), "foo") == 0);
+}
+
+ATF_TC(config_multi_value);
+ATF_TC_HEAD(config_multi_value, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Helper test case for the t_config test "
+ "program");
+}
+ATF_TC_BODY(config_multi_value, tc)
+{
+ ATF_REQUIRE(atf_tc_has_config_var(tc, "test"));
+ ATF_REQUIRE(strcmp(atf_tc_get_config_var(tc, "test"), "foo bar") == 0);
+}
+
+/* ---------------------------------------------------------------------
+ * Helper tests for "t_expect".
+ * --------------------------------------------------------------------- */
+
+ATF_TC_WITHOUT_HEAD(expect_pass_and_pass);
+ATF_TC_BODY(expect_pass_and_pass, tc)
+{
+ atf_tc_expect_pass();
+
+}
+
+ATF_TC_WITHOUT_HEAD(expect_pass_but_fail_requirement);
+ATF_TC_BODY(expect_pass_but_fail_requirement, tc)
+{
+ atf_tc_expect_pass();
+ atf_tc_fail("Some reason");
+}
+
+ATF_TC_WITHOUT_HEAD(expect_pass_but_fail_check);
+ATF_TC_BODY(expect_pass_but_fail_check, tc)
+{
+ atf_tc_expect_pass();
+ atf_tc_fail_nonfatal("Some reason");
+}
+
+ATF_TC_WITHOUT_HEAD(expect_fail_and_fail_requirement);
+ATF_TC_BODY(expect_fail_and_fail_requirement, tc)
+{
+ atf_tc_expect_fail("Fail %s", "reason");
+ atf_tc_fail("The failure");
+ atf_tc_expect_pass();
+}
+
+ATF_TC_WITHOUT_HEAD(expect_fail_and_fail_check);
+ATF_TC_BODY(expect_fail_and_fail_check, tc)
+{
+ atf_tc_expect_fail("Fail first");
+ atf_tc_fail_nonfatal("abc");
+ atf_tc_expect_pass();
+
+ atf_tc_expect_fail("And fail again");
+ atf_tc_fail_nonfatal("def");
+ atf_tc_expect_pass();
+}
+
+ATF_TC_WITHOUT_HEAD(expect_fail_but_pass);
+ATF_TC_BODY(expect_fail_but_pass, tc)
+{
+ atf_tc_expect_fail("Fail first");
+ atf_tc_fail_nonfatal("abc");
+ atf_tc_expect_pass();
+
+ atf_tc_expect_fail("Will not fail");
+ atf_tc_expect_pass();
+
+ atf_tc_expect_fail("And fail again");
+ atf_tc_fail_nonfatal("def");
+ atf_tc_expect_pass();
+}
+
+ATF_TC_WITHOUT_HEAD(expect_exit_any_and_exit);
+ATF_TC_BODY(expect_exit_any_and_exit, tc)
+{
+ atf_tc_expect_exit(-1, "Call will exit");
+ exit(EXIT_SUCCESS);
+}
+
+ATF_TC_WITHOUT_HEAD(expect_exit_code_and_exit);
+ATF_TC_BODY(expect_exit_code_and_exit, tc)
+{
+ atf_tc_expect_exit(123, "Call will exit");
+ exit(123);
+}
+
+ATF_TC_WITHOUT_HEAD(expect_exit_but_pass);
+ATF_TC_BODY(expect_exit_but_pass, tc)
+{
+ atf_tc_expect_exit(-1, "Call won't exit");
+}
+
+ATF_TC_WITHOUT_HEAD(expect_signal_any_and_signal);
+ATF_TC_BODY(expect_signal_any_and_signal, tc)
+{
+ atf_tc_expect_signal(-1, "Call will signal");
+ kill(getpid(), SIGKILL);
+}
+
+ATF_TC_WITHOUT_HEAD(expect_signal_no_and_signal);
+ATF_TC_BODY(expect_signal_no_and_signal, tc)
+{
+ atf_tc_expect_signal(SIGHUP, "Call will signal");
+ kill(getpid(), SIGHUP);
+}
+
+ATF_TC_WITHOUT_HEAD(expect_signal_but_pass);
+ATF_TC_BODY(expect_signal_but_pass, tc)
+{
+ atf_tc_expect_signal(-1, "Call won't signal");
+}
+
+ATF_TC_WITHOUT_HEAD(expect_death_and_exit);
+ATF_TC_BODY(expect_death_and_exit, tc)
+{
+ atf_tc_expect_death("Exit case");
+ exit(123);
+}
+
+ATF_TC_WITHOUT_HEAD(expect_death_and_signal);
+ATF_TC_BODY(expect_death_and_signal, tc)
+{
+ atf_tc_expect_death("Signal case");
+ kill(getpid(), SIGKILL);
+}
+
+ATF_TC_WITHOUT_HEAD(expect_death_but_pass);
+ATF_TC_BODY(expect_death_but_pass, tc)
+{
+ atf_tc_expect_death("Call won't die");
+}
+
+ATF_TC(expect_timeout_and_hang);
+ATF_TC_HEAD(expect_timeout_and_hang, tc)
+{
+ atf_tc_set_md_var(tc, "timeout", "1");
+}
+ATF_TC_BODY(expect_timeout_and_hang, tc)
+{
+ atf_tc_expect_timeout("Will overrun");
+ sleep(5);
+}
+
+ATF_TC(expect_timeout_but_pass);
+ATF_TC_HEAD(expect_timeout_but_pass, tc)
+{
+ atf_tc_set_md_var(tc, "timeout", "1");
+}
+ATF_TC_BODY(expect_timeout_but_pass, tc)
+{
+ atf_tc_expect_timeout("Will just exit");
+}
+
+/* ---------------------------------------------------------------------
+ * Helper tests for "t_fork".
+ * --------------------------------------------------------------------- */
+
+ATF_TC(fork_stop);
+ATF_TC_HEAD(fork_stop, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Helper test case for the t_fork test "
+ "program");
+}
+ATF_TC_BODY(fork_stop, tc)
+{
+ FILE *f;
+ const char *dfstr, *pfstr;
+
+ dfstr = atf_tc_get_config_var(tc, "donefile");
+ pfstr = atf_tc_get_config_var(tc, "pidfile");
+
+ f = fopen(pfstr, "w");
+ if (f == NULL)
+ atf_tc_fail("Failed to create pidfile %s", pfstr);
+ fprintf(f, "%d", (int)getpid());
+ fclose(f);
+ printf("Wrote pid file\n");
+
+ printf("Waiting for done file\n");
+ while (access(dfstr, F_OK) != 0)
+ usleep(10000);
+ printf("Exiting\n");
+}
+
+/* ---------------------------------------------------------------------
+ * Helper tests for "t_meta_data".
+ * --------------------------------------------------------------------- */
+
+ATF_TC(metadata_no_descr);
+ATF_TC_HEAD(metadata_no_descr, tc)
+{
+}
+ATF_TC_BODY(metadata_no_descr, tc)
+{
+}
+
+ATF_TC_WITHOUT_HEAD(metadata_no_head);
+ATF_TC_BODY(metadata_no_head, tc)
+{
+}
+
+/* ---------------------------------------------------------------------
+ * Helper tests for "t_srcdir".
+ * --------------------------------------------------------------------- */
+
+ATF_TC(srcdir_exists);
+ATF_TC_HEAD(srcdir_exists, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Helper test case for the t_srcdir test "
+ "program");
+}
+ATF_TC_BODY(srcdir_exists, tc)
+{
+ atf_fs_path_t p;
+ bool b;
+
+ RE(atf_fs_path_init_fmt(&p, "%s/datafile",
+ atf_tc_get_config_var(tc, "srcdir")));
+ RE(atf_fs_exists(&p, &b));
+ atf_fs_path_fini(&p);
+ if (!b)
+ atf_tc_fail("Cannot find datafile");
+}
+
+/* ---------------------------------------------------------------------
+ * Helper tests for "t_result".
+ * --------------------------------------------------------------------- */
+
+ATF_TC(result_pass);
+ATF_TC_HEAD(result_pass, tc) { }
+ATF_TC_BODY(result_pass, tc)
+{
+ printf("msg\n");
+}
+
+ATF_TC(result_fail);
+ATF_TC_HEAD(result_fail, tc) { }
+ATF_TC_BODY(result_fail, tc)
+{
+ printf("msg\n");
+ atf_tc_fail("Failure reason");
+}
+
+ATF_TC(result_skip);
+ATF_TC_HEAD(result_skip, tc) { }
+ATF_TC_BODY(result_skip, tc)
+{
+ printf("msg\n");
+ atf_tc_skip("Skipped reason");
+}
+
+ATF_TC(result_newlines_fail);
+ATF_TC_HEAD(result_newlines_fail, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Helper test case for the t_result test "
+ "program");
+}
+ATF_TC_BODY(result_newlines_fail, tc)
+{
+ atf_tc_fail("First line\nSecond line");
+}
+
+ATF_TC(result_newlines_skip);
+ATF_TC_HEAD(result_newlines_skip, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Helper test case for the t_result test "
+ "program");
+}
+ATF_TC_BODY(result_newlines_skip, tc)
+{
+ atf_tc_skip("First line\nSecond line");
+}
+
+/* ---------------------------------------------------------------------
+ * Main.
+ * --------------------------------------------------------------------- */
+
+ATF_TP_ADD_TCS(tp)
+{
+ /* Add helper tests for t_cleanup. */
+ ATF_TP_ADD_TC(tp, cleanup_pass);
+ ATF_TP_ADD_TC(tp, cleanup_fail);
+ ATF_TP_ADD_TC(tp, cleanup_skip);
+ ATF_TP_ADD_TC(tp, cleanup_curdir);
+ ATF_TP_ADD_TC(tp, cleanup_sigterm);
+ ATF_TP_ADD_TC(tp, cleanup_fork);
+
+ /* Add helper tests for t_config. */
+ ATF_TP_ADD_TC(tp, config_unset);
+ ATF_TP_ADD_TC(tp, config_empty);
+ ATF_TP_ADD_TC(tp, config_value);
+ ATF_TP_ADD_TC(tp, config_multi_value);
+
+ /* Add helper tests for t_expect. */
+ ATF_TP_ADD_TC(tp, expect_pass_and_pass);
+ ATF_TP_ADD_TC(tp, expect_pass_but_fail_requirement);
+ ATF_TP_ADD_TC(tp, expect_pass_but_fail_check);
+ ATF_TP_ADD_TC(tp, expect_fail_and_fail_requirement);
+ ATF_TP_ADD_TC(tp, expect_fail_and_fail_check);
+ ATF_TP_ADD_TC(tp, expect_fail_but_pass);
+ ATF_TP_ADD_TC(tp, expect_exit_any_and_exit);
+ ATF_TP_ADD_TC(tp, expect_exit_code_and_exit);
+ ATF_TP_ADD_TC(tp, expect_exit_but_pass);
+ ATF_TP_ADD_TC(tp, expect_signal_any_and_signal);
+ ATF_TP_ADD_TC(tp, expect_signal_no_and_signal);
+ ATF_TP_ADD_TC(tp, expect_signal_but_pass);
+ ATF_TP_ADD_TC(tp, expect_death_and_exit);
+ ATF_TP_ADD_TC(tp, expect_death_and_signal);
+ ATF_TP_ADD_TC(tp, expect_death_but_pass);
+ ATF_TP_ADD_TC(tp, expect_timeout_and_hang);
+ ATF_TP_ADD_TC(tp, expect_timeout_but_pass);
+
+ /* Add helper tests for t_fork. */
+ ATF_TP_ADD_TC(tp, fork_stop);
+
+ /* Add helper tests for t_meta_data. */
+ ATF_TP_ADD_TC(tp, metadata_no_descr);
+ ATF_TP_ADD_TC(tp, metadata_no_head);
+
+ /* Add helper tests for t_srcdir. */
+ ATF_TP_ADD_TC(tp, srcdir_exists);
+
+ /* Add helper tests for t_result. */
+ ATF_TP_ADD_TC(tp, result_pass);
+ ATF_TP_ADD_TC(tp, result_fail);
+ ATF_TP_ADD_TC(tp, result_skip);
+ ATF_TP_ADD_TC(tp, result_newlines_fail);
+ ATF_TP_ADD_TC(tp, result_newlines_skip);
+
+ return atf_no_error();
+}
diff --git a/external/bsd/atf/dist/test-programs/common.sh b/external/bsd/atf/dist/test-programs/common.sh
new file mode 100644
index 00000000000..ebeebdb2dfc
--- /dev/null
+++ b/external/bsd/atf/dist/test-programs/common.sh
@@ -0,0 +1,43 @@
+#
+# Automated Testing Framework (atf)
+#
+# Copyright (c) 2008 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
+# CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+get_helpers()
+{
+ srcdir=$(atf_get_srcdir)
+
+ if [ ${#} -eq 0 ]; then
+ set -- c_helpers cpp_helpers sh_helpers
+ fi
+
+ for h_name in "${@}"; do
+ echo ${srcdir}/${h_name}
+ done
+}
+
+# vim: syntax=sh:expandtab:shiftwidth=4:softtabstop=4
diff --git a/external/bsd/atf/dist/test-programs/config_test.sh b/external/bsd/atf/dist/test-programs/config_test.sh
new file mode 100644
index 00000000000..85e6a80befb
--- /dev/null
+++ b/external/bsd/atf/dist/test-programs/config_test.sh
@@ -0,0 +1,63 @@
+#
+# Automated Testing Framework (atf)
+#
+# Copyright (c) 2007, 2008, 2010 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
+# CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+atf_test_case vflag
+vflag_head()
+{
+ atf_set "descr" "Tests that the -v flag works correctly to set" \
+ "configuration variables"
+ atf_set "use.fs" "true"
+}
+vflag_body()
+{
+ for h in $(get_helpers); do
+ atf_check -s eq:0 -o ignore -e ignore ${h} -s $(atf_get_srcdir) \
+ -r resfile config_unset
+ atf_check -s eq:0 -o ignore -e empty grep 'passed' resfile
+
+ atf_check -s eq:0 -o ignore -e ignore ${h} -s $(atf_get_srcdir) \
+ -r resfile -v 'test=' config_empty
+ atf_check -s eq:0 -o ignore -e empty grep 'passed' resfile
+
+ atf_check -s eq:0 -o ignore -e ignore ${h} -s $(atf_get_srcdir) \
+ -r resfile -v 'test=foo' config_value
+ atf_check -s eq:0 -o ignore -e empty grep 'passed' resfile
+
+ atf_check -s eq:0 -o ignore -e ignore -x ${h} -s $(atf_get_srcdir) \
+ -r resfile -v \'test=foo bar\' config_multi_value
+ atf_check -s eq:0 -o ignore -e empty grep 'passed' resfile
+ done
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case vflag
+}
+
+# vim: syntax=sh:expandtab:shiftwidth=4:softtabstop=4
diff --git a/external/bsd/atf/dist/test-programs/cpp_helpers.cpp b/external/bsd/atf/dist/test-programs/cpp_helpers.cpp
new file mode 100644
index 00000000000..ac39d0597e8
--- /dev/null
+++ b/external/bsd/atf/dist/test-programs/cpp_helpers.cpp
@@ -0,0 +1,382 @@
+//
+// Automated Testing Framework (atf)
+//
+// Copyright (c) 2007, 2008, 2009, 2010 The NetBSD Foundation, Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
+// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+extern "C" {
+#include <signal.h>
+#include <unistd.h>
+}
+
+#include <cstdlib>
+#include <fstream>
+#include <iostream>
+
+#include "atf-c++/fs.hpp"
+#include "atf-c++/macros.hpp"
+
+// ------------------------------------------------------------------------
+// Helper tests for "t_config".
+// ------------------------------------------------------------------------
+
+ATF_TEST_CASE(config_unset);
+ATF_TEST_CASE_HEAD(config_unset)
+{
+ set_md_var("descr", "Helper test case for the t_config test program");
+}
+ATF_TEST_CASE_BODY(config_unset)
+{
+ ATF_CHECK(!has_config_var("test"));
+}
+
+ATF_TEST_CASE(config_empty);
+ATF_TEST_CASE_HEAD(config_empty)
+{
+ set_md_var("descr", "Helper test case for the t_config test program");
+}
+ATF_TEST_CASE_BODY(config_empty)
+{
+ ATF_CHECK_EQUAL(get_config_var("test"), "");
+}
+
+ATF_TEST_CASE(config_value);
+ATF_TEST_CASE_HEAD(config_value)
+{
+ set_md_var("descr", "Helper test case for the t_config test program");
+}
+ATF_TEST_CASE_BODY(config_value)
+{
+ ATF_CHECK_EQUAL(get_config_var("test"), "foo");
+}
+
+ATF_TEST_CASE(config_multi_value);
+ATF_TEST_CASE_HEAD(config_multi_value)
+{
+ set_md_var("descr", "Helper test case for the t_config test program");
+}
+ATF_TEST_CASE_BODY(config_multi_value)
+{
+ ATF_CHECK_EQUAL(get_config_var("test"), "foo bar");
+}
+
+// ------------------------------------------------------------------------
+// Helper tests for "t_expect".
+// ------------------------------------------------------------------------
+
+ATF_TEST_CASE_WITHOUT_HEAD(expect_pass_and_pass);
+ATF_TEST_CASE_BODY(expect_pass_and_pass)
+{
+ expect_pass();
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(expect_pass_but_fail_requirement);
+ATF_TEST_CASE_BODY(expect_pass_but_fail_requirement)
+{
+ expect_pass();
+ fail("Some reason");
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(expect_pass_but_fail_check);
+ATF_TEST_CASE_BODY(expect_pass_but_fail_check)
+{
+ expect_pass();
+ fail_nonfatal("Some reason");
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(expect_fail_and_fail_requirement);
+ATF_TEST_CASE_BODY(expect_fail_and_fail_requirement)
+{
+ expect_fail("Fail reason");
+ fail("The failure");
+ expect_pass();
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(expect_fail_and_fail_check);
+ATF_TEST_CASE_BODY(expect_fail_and_fail_check)
+{
+ expect_fail("Fail first");
+ fail_nonfatal("abc");
+ expect_pass();
+
+ expect_fail("And fail again");
+ fail_nonfatal("def");
+ expect_pass();
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(expect_fail_but_pass);
+ATF_TEST_CASE_BODY(expect_fail_but_pass)
+{
+ expect_fail("Fail first");
+ fail_nonfatal("abc");
+ expect_pass();
+
+ expect_fail("Will not fail");
+ expect_pass();
+
+ expect_fail("And fail again");
+ fail_nonfatal("def");
+ expect_pass();
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(expect_exit_any_and_exit);
+ATF_TEST_CASE_BODY(expect_exit_any_and_exit)
+{
+ expect_exit(-1, "Call will exit");
+ std::exit(EXIT_SUCCESS);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(expect_exit_code_and_exit);
+ATF_TEST_CASE_BODY(expect_exit_code_and_exit)
+{
+ expect_exit(123, "Call will exit");
+ std::exit(123);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(expect_exit_but_pass);
+ATF_TEST_CASE_BODY(expect_exit_but_pass)
+{
+ expect_exit(-1, "Call won't exit");
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(expect_signal_any_and_signal);
+ATF_TEST_CASE_BODY(expect_signal_any_and_signal)
+{
+ expect_signal(-1, "Call will signal");
+ ::kill(getpid(), SIGKILL);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(expect_signal_no_and_signal);
+ATF_TEST_CASE_BODY(expect_signal_no_and_signal)
+{
+ expect_signal(SIGHUP, "Call will signal");
+ ::kill(getpid(), SIGHUP);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(expect_signal_but_pass);
+ATF_TEST_CASE_BODY(expect_signal_but_pass)
+{
+ expect_signal(-1, "Call won't signal");
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(expect_death_and_exit);
+ATF_TEST_CASE_BODY(expect_death_and_exit)
+{
+ expect_death("Exit case");
+ std::exit(123);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(expect_death_and_signal);
+ATF_TEST_CASE_BODY(expect_death_and_signal)
+{
+ expect_death("Signal case");
+ kill(getpid(), SIGKILL);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(expect_death_but_pass);
+ATF_TEST_CASE_BODY(expect_death_but_pass)
+{
+ expect_death("Call won't die");
+}
+
+ATF_TEST_CASE(expect_timeout_and_hang);
+ATF_TEST_CASE_HEAD(expect_timeout_and_hang)
+{
+ set_md_var("timeout", "1");
+}
+ATF_TEST_CASE_BODY(expect_timeout_and_hang)
+{
+ expect_timeout("Will overrun");
+ ::sleep(5);
+}
+
+ATF_TEST_CASE(expect_timeout_but_pass);
+ATF_TEST_CASE_HEAD(expect_timeout_but_pass)
+{
+ set_md_var("timeout", "1");
+}
+ATF_TEST_CASE_BODY(expect_timeout_but_pass)
+{
+ expect_timeout("Will just exit");
+}
+
+// ------------------------------------------------------------------------
+// Helper tests for "t_fork".
+// ------------------------------------------------------------------------
+
+ATF_TEST_CASE(fork_stop);
+ATF_TEST_CASE_HEAD(fork_stop)
+{
+ set_md_var("descr", "Helper test case for the t_fork test program");
+}
+ATF_TEST_CASE_BODY(fork_stop)
+{
+ std::ofstream os(get_config_var("pidfile").c_str());
+ os << ::getpid() << std::endl;
+ os.close();
+ std::cout << "Wrote pid file" << std::endl;
+ std::cout << "Waiting for done file" << std::endl;
+ while (::access(get_config_var("donefile").c_str(), F_OK) != 0)
+ ::usleep(10000);
+ std::cout << "Exiting" << std::endl;
+}
+
+// ------------------------------------------------------------------------
+// Helper tests for "t_meta_data".
+// ------------------------------------------------------------------------
+
+ATF_TEST_CASE(metadata_no_descr);
+ATF_TEST_CASE_HEAD(metadata_no_descr)
+{
+}
+ATF_TEST_CASE_BODY(metadata_no_descr)
+{
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(metadata_no_head);
+ATF_TEST_CASE_BODY(metadata_no_head)
+{
+}
+
+// ------------------------------------------------------------------------
+// Helper tests for "t_srcdir".
+// ------------------------------------------------------------------------
+
+ATF_TEST_CASE(srcdir_exists);
+ATF_TEST_CASE_HEAD(srcdir_exists)
+{
+ set_md_var("descr", "Helper test case for the t_srcdir test program");
+}
+ATF_TEST_CASE_BODY(srcdir_exists)
+{
+ if (!atf::fs::exists(atf::fs::path(get_config_var("srcdir")) /
+ "datafile"))
+ ATF_FAIL("Cannot find datafile");
+}
+
+// ------------------------------------------------------------------------
+// Helper tests for "t_result".
+// ------------------------------------------------------------------------
+
+ATF_TEST_CASE(result_pass);
+ATF_TEST_CASE_HEAD(result_pass) { }
+ATF_TEST_CASE_BODY(result_pass)
+{
+ std::cout << "msg\n";
+}
+
+ATF_TEST_CASE(result_fail);
+ATF_TEST_CASE_HEAD(result_fail) { }
+ATF_TEST_CASE_BODY(result_fail)
+{
+ std::cout << "msg\n";
+ ATF_FAIL("Failure reason");
+}
+
+ATF_TEST_CASE(result_skip);
+ATF_TEST_CASE_HEAD(result_skip) { }
+ATF_TEST_CASE_BODY(result_skip)
+{
+ std::cout << "msg\n";
+ ATF_SKIP("Skipped reason");
+}
+
+ATF_TEST_CASE(result_newlines_fail);
+ATF_TEST_CASE_HEAD(result_newlines_fail)
+{
+ set_md_var("descr", "Helper test case for the t_result test program");
+}
+ATF_TEST_CASE_BODY(result_newlines_fail)
+{
+ ATF_FAIL("First line\nSecond line");
+}
+
+ATF_TEST_CASE(result_newlines_skip);
+ATF_TEST_CASE_HEAD(result_newlines_skip)
+{
+ set_md_var("descr", "Helper test case for the t_result test program");
+}
+ATF_TEST_CASE_BODY(result_newlines_skip)
+{
+ ATF_SKIP("First line\nSecond line");
+}
+
+ATF_TEST_CASE(result_exception);
+ATF_TEST_CASE_HEAD(result_exception) { }
+ATF_TEST_CASE_BODY(result_exception)
+{
+ throw std::runtime_error("This is unhandled");
+}
+
+// ------------------------------------------------------------------------
+// Main.
+// ------------------------------------------------------------------------
+
+ATF_INIT_TEST_CASES(tcs)
+{
+ // Add helper tests for t_config.
+ ATF_ADD_TEST_CASE(tcs, config_unset);
+ ATF_ADD_TEST_CASE(tcs, config_empty);
+ ATF_ADD_TEST_CASE(tcs, config_value);
+ ATF_ADD_TEST_CASE(tcs, config_multi_value);
+
+ // Add helper tests for t_expect.
+ ATF_ADD_TEST_CASE(tcs, expect_pass_and_pass);
+ ATF_ADD_TEST_CASE(tcs, expect_pass_but_fail_requirement);
+ ATF_ADD_TEST_CASE(tcs, expect_pass_but_fail_check);
+ ATF_ADD_TEST_CASE(tcs, expect_fail_and_fail_requirement);
+ ATF_ADD_TEST_CASE(tcs, expect_fail_and_fail_check);
+ ATF_ADD_TEST_CASE(tcs, expect_fail_but_pass);
+ ATF_ADD_TEST_CASE(tcs, expect_exit_any_and_exit);
+ ATF_ADD_TEST_CASE(tcs, expect_exit_code_and_exit);
+ ATF_ADD_TEST_CASE(tcs, expect_exit_but_pass);
+ ATF_ADD_TEST_CASE(tcs, expect_signal_any_and_signal);
+ ATF_ADD_TEST_CASE(tcs, expect_signal_no_and_signal);
+ ATF_ADD_TEST_CASE(tcs, expect_signal_but_pass);
+ ATF_ADD_TEST_CASE(tcs, expect_death_and_exit);
+ ATF_ADD_TEST_CASE(tcs, expect_death_and_signal);
+ ATF_ADD_TEST_CASE(tcs, expect_death_but_pass);
+ ATF_ADD_TEST_CASE(tcs, expect_timeout_and_hang);
+ ATF_ADD_TEST_CASE(tcs, expect_timeout_but_pass);
+
+ // Add helper tests for t_fork.
+ ATF_ADD_TEST_CASE(tcs, fork_stop);
+
+ // Add helper tests for t_meta_data.
+ ATF_ADD_TEST_CASE(tcs, metadata_no_descr);
+ ATF_ADD_TEST_CASE(tcs, metadata_no_head);
+
+ // Add helper tests for t_srcdir.
+ ATF_ADD_TEST_CASE(tcs, srcdir_exists);
+
+ // Add helper tests for t_result.
+ ATF_ADD_TEST_CASE(tcs, result_pass);
+ ATF_ADD_TEST_CASE(tcs, result_fail);
+ ATF_ADD_TEST_CASE(tcs, result_skip);
+ ATF_ADD_TEST_CASE(tcs, result_newlines_fail);
+ ATF_ADD_TEST_CASE(tcs, result_newlines_skip);
+ ATF_ADD_TEST_CASE(tcs, result_exception);
+}
diff --git a/external/bsd/atf/dist/test-programs/expect_test.sh b/external/bsd/atf/dist/test-programs/expect_test.sh
new file mode 100644
index 00000000000..1e09038a651
--- /dev/null
+++ b/external/bsd/atf/dist/test-programs/expect_test.sh
@@ -0,0 +1,167 @@
+#
+# Automated Testing Framework (atf)
+#
+# Copyright (c) 2007, 2008, 2010 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
+# CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+check_result() {
+ file="${1}"; shift
+
+ atf_check -s eq:0 -o match:"${*}" -e empty cat "${file}"
+ rm "${file}"
+}
+
+atf_test_case expect_pass
+expect_pass_head() {
+ atf_set "use.fs" "true"
+}
+expect_pass_body() {
+ for h in $(get_helpers); do
+ atf_check -s eq:0 "${h}" -r result expect_pass_and_pass
+ check_result result "passed"
+
+ atf_check -s eq:1 "${h}" -r result expect_pass_but_fail_requirement
+ check_result result "failed: Some reason"
+
+ # atf-sh does not support non-fatal failures yet; skip checks for
+ # such conditions.
+ case "${h}" in *sh_helpers*) continue ;; esac
+
+ atf_check -s eq:1 -o empty -e match:"Some reason" \
+ "${h}" -r result expect_pass_but_fail_check
+ check_result result "failed: 1 checks failed"
+ done
+}
+
+atf_test_case expect_fail
+expect_fail_head() {
+ atf_set "use.fs" "true"
+}
+expect_fail_body() {
+ for h in $(get_helpers c_helpers cpp_helpers); do
+ atf_check -s eq:0 "${h}" -r result expect_fail_and_fail_requirement
+ check_result result "expected_failure: Fail reason: The failure"
+
+ atf_check -s eq:1 -e match:"Expected check failure: Fail first: abc" \
+ -e not-match:"And fail again" "${h}" -r result expect_fail_but_pass
+ check_result result "failed: .*expecting a failure"
+
+ # atf-sh does not support non-fatal failures yet; skip checks for
+ # such conditions.
+ case "${h}" in *sh_helpers*) continue ;; esac
+
+ atf_check -s eq:0 -e match:"Expected check failure: Fail first: abc" \
+ -e match:"Expected check failure: And fail again: def" \
+ "${h}" -r result expect_fail_and_fail_check
+ check_result result "expected_failure: And fail again: 2 checks" \
+ "failed as expected"
+ done
+
+ # atf-sh does not support non-fatal failures yet; skip checks for
+ # such conditions.
+ for h in $(get_helpers sh_helpers); do
+ atf_check -s eq:0 "${h}" -r result expect_fail_and_fail_requirement
+ check_result result "expected_failure: Fail reason: The failure"
+
+ atf_check -s eq:1 "${h}" -r result expect_fail_but_pass
+ check_result result "failed: .*expecting a failure"
+ done
+}
+
+atf_test_case expect_exit
+expect_exit_head() {
+ atf_set "use.fs" "true"
+}
+expect_exit_body() {
+ for h in $(get_helpers); do
+ atf_check -s eq:0 "${h}" -r result expect_exit_any_and_exit
+ check_result result "expected_exit: Call will exit"
+
+ atf_check -s eq:123 "${h}" -r result expect_exit_code_and_exit
+ check_result result "expected_exit\(123\): Call will exit"
+
+ atf_check -s eq:1 "${h}" -r result expect_exit_but_pass
+ check_result result "failed: .*expected to exit"
+ done
+}
+
+atf_test_case expect_signal
+expect_signal_head() {
+ atf_set "use.fs" "true"
+}
+expect_signal_body() {
+ for h in $(get_helpers); do
+ atf_check -s signal:9 "${h}" -r result expect_signal_any_and_signal
+ check_result result "expected_signal: Call will signal"
+
+ atf_check -s signal:hup "${h}" -r result expect_signal_no_and_signal
+ check_result result "expected_signal\(1\): Call will signal"
+
+ atf_check -s eq:1 "${h}" -r result expect_signal_but_pass
+ check_result result "failed: .*termination signal"
+ done
+}
+
+atf_test_case expect_death
+expect_death_head() {
+ atf_set "use.fs" "true"
+}
+expect_death_body() {
+ for h in $(get_helpers); do
+ atf_check -s eq:123 "${h}" -r result expect_death_and_exit
+ check_result result "expected_death: Exit case"
+
+ atf_check -s signal:kill "${h}" -r result expect_death_and_signal
+ check_result result "expected_death: Signal case"
+
+ atf_check -s eq:1 "${h}" -r result expect_death_but_pass
+ check_result result "failed: .*terminate abruptly"
+ done
+}
+
+atf_test_case expect_timeout
+expect_timeout_head() {
+ atf_set "use.fs" "true"
+}
+expect_timeout_body() {
+ for h in $(get_helpers); do
+ atf_check -s eq:1 "${h}" -r result expect_timeout_but_pass
+ check_result result "failed: Test case was expected to hang but it" \
+ "continued execution"
+ done
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case expect_pass
+ atf_add_test_case expect_fail
+ atf_add_test_case expect_exit
+ atf_add_test_case expect_signal
+ atf_add_test_case expect_death
+ atf_add_test_case expect_timeout
+}
+
+# vim: syntax=sh:expandtab:shiftwidth=4:softtabstop=4
diff --git a/external/bsd/atf/dist/test-programs/fork_test.sh b/external/bsd/atf/dist/test-programs/fork_test.sh
new file mode 100644
index 00000000000..0c885b0e035
--- /dev/null
+++ b/external/bsd/atf/dist/test-programs/fork_test.sh
@@ -0,0 +1,65 @@
+#
+# Automated Testing Framework (atf)
+#
+# Copyright (c) 2007, 2008, 2010 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
+# CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+# TODO: This test program is about checking the test case's "environment"
+# (not the variables). Should be named something else than t_fork.
+
+atf_test_case stop
+stop_head()
+{
+ atf_set "descr" "Tests that sending a stop signal to a test case does" \
+ "not report it as failed"
+ atf_set "use.fs" "true"
+}
+stop_body()
+{
+ for h in $(get_helpers); do
+ ${h} -s $(atf_get_srcdir) -v pidfile=$(pwd)/pid \
+ -v donefile=$(pwd)/done -r resfile fork_stop &
+ ppid=${!}
+ echo "Waiting for pid file for test program ${ppid}"
+ while test ! -f pid; do sleep 1; done
+ pid=$(cat pid)
+ echo "Test case's pid is ${pid}"
+ kill -STOP ${pid}
+ touch done
+ echo "Wrote done file"
+ kill -CONT ${pid}
+ wait ${ppid}
+ atf_check -s eq:0 -o ignore -e empty grep '^passed$' resfile
+ rm -f pid done
+ done
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case stop
+}
+
+# vim: syntax=sh:expandtab:shiftwidth=4:softtabstop=4
diff --git a/external/bsd/atf/dist/test-programs/meta_data_test.sh b/external/bsd/atf/dist/test-programs/meta_data_test.sh
new file mode 100644
index 00000000000..0562b537d1b
--- /dev/null
+++ b/external/bsd/atf/dist/test-programs/meta_data_test.sh
@@ -0,0 +1,66 @@
+#
+# Automated Testing Framework (atf)
+#
+# Copyright (c) 2010 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
+# CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+atf_test_case no_descr
+no_descr_head()
+{
+ atf_set "descr" "Tests that the description may not be present"
+ atf_set "use.fs" "true"
+}
+no_descr_body()
+{
+ for h in $(get_helpers); do
+ atf_check -s eq:0 -o ignore -e empty ${h} -s $(atf_get_srcdir) -l
+ atf_check -s eq:0 -o match:passed -e empty ${h} -s $(atf_get_srcdir) \
+ metadata_no_descr
+ done
+}
+
+atf_test_case no_head
+no_head_head()
+{
+ atf_set "descr" "Tests that the head may not be present"
+ atf_set "use.fs" "true"
+}
+no_head_body()
+{
+ for h in $(get_helpers); do
+ atf_check -s eq:0 -o ignore -e empty ${h} -s $(atf_get_srcdir) -l
+ atf_check -s eq:0 -o match:passed -e empty ${h} -s $(atf_get_srcdir) \
+ metadata_no_head
+ done
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case no_descr
+ atf_add_test_case no_head
+}
+
+# vim: syntax=sh:expandtab:shiftwidth=4:softtabstop=4
diff --git a/external/bsd/atf/dist/test-programs/result_test.sh b/external/bsd/atf/dist/test-programs/result_test.sh
new file mode 100644
index 00000000000..fd768b85b0e
--- /dev/null
+++ b/external/bsd/atf/dist/test-programs/result_test.sh
@@ -0,0 +1,124 @@
+#
+# Automated Testing Framework (atf)
+#
+# Copyright (c) 2007, 2008, 2010 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
+# CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+atf_test_case result_on_stdout
+result_on_stdout_head()
+{
+ atf_set "descr" "Tests that the test case result is printed on stdout" \
+ "by default"
+}
+result_on_stdout_body()
+{
+ srcdir="$(atf_get_srcdir)"
+ for h in $(get_helpers); do
+ atf_check -s eq:0 -o match:"passed" -o match:"msg" \
+ -e empty "${h}" -s "${srcdir}" result_pass
+ atf_check -s eq:1 -o match:"failed: Failure reason" -o match:"msg" \
+ -e empty "${h}" -s "${srcdir}" result_fail
+ atf_check -s eq:0 -o match:"skipped: Skipped reason" -o match:"msg" \
+ -e empty "${h}" -s "${srcdir}" result_skip
+ done
+}
+
+atf_test_case result_to_file
+result_to_file_head()
+{
+ atf_set "descr" "Tests that the test case result is sent to a file if -r" \
+ "is used"
+ atf_set "use.fs" "true"
+}
+result_to_file_body()
+{
+ srcdir="$(atf_get_srcdir)"
+ for h in $(get_helpers); do
+ atf_check -s eq:0 -o inline:"msg\n" -e empty "${h}" -s "${srcdir}" \
+ -r resfile result_pass
+ atf_check -o inline:"passed\n" cat resfile
+
+ atf_check -s eq:1 -o inline:"msg\n" -e empty "${h}" -s "${srcdir}" \
+ -r resfile result_fail
+ atf_check -o inline:"failed: Failure reason\n" cat resfile
+
+ atf_check -s eq:0 -o inline:"msg\n" -e empty "${h}" -s "${srcdir}" \
+ -r resfile result_skip
+ atf_check -o inline:"skipped: Skipped reason\n" cat resfile
+ done
+}
+
+atf_test_case result_to_file_fail
+result_to_file_fail_head()
+{
+ atf_set "descr" "Tests controlled failure if the test program fails to" \
+ "create the results file"
+ atf_set "require.user" "unprivileged"
+ atf_set "use.fs" "true"
+}
+result_to_file_fail_body()
+{
+ mkdir dir
+ chmod 444 dir
+
+ srcdir="$(atf_get_srcdir)"
+
+ for h in $(get_helpers c_helpers cpp_helpers); do
+ atf_check -s signal -o ignore \
+ -e match:"FATAL ERROR: Cannot create.*'dir/resfile'" \
+ "${h}" -s "${srcdir}" -r dir/resfile result_pass
+ done
+
+ for h in $(get_helpers sh_helpers); do
+ atf_check -s exit -o ignore \
+ -e match:"ERROR: Cannot create.*'dir/resfile'" \
+ "${h}" -s "${srcdir}" -r dir/resfile result_pass
+ done
+}
+
+atf_test_case result_exception
+result_exception_head()
+{
+ atf_set "descr" "Tests that an unhandled exception is correctly captured"
+ atf_set "use.fs" "true"
+}
+result_exception_body()
+{
+ for h in $(get_helpers cpp_helpers); do
+ atf_check -s exit:1 -o match:'failed: .*This is unhandled' \
+ "${h}" -s "${srcdir}" result_exception
+ done
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case result_on_stdout
+ atf_add_test_case result_to_file
+ atf_add_test_case result_to_file_fail
+ atf_add_test_case result_exception
+}
+
+# vim: syntax=sh:expandtab:shiftwidth=4:softtabstop=4
diff --git a/external/bsd/atf/dist/test-programs/sh_helpers.sh b/external/bsd/atf/dist/test-programs/sh_helpers.sh
new file mode 100644
index 00000000000..547ead55712
--- /dev/null
+++ b/external/bsd/atf/dist/test-programs/sh_helpers.sh
@@ -0,0 +1,431 @@
+#
+# Automated Testing Framework (atf)
+#
+# Copyright (c) 2007, 2008, 2010 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
+# CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+# -------------------------------------------------------------------------
+# Helper tests for "t_cleanup".
+# -------------------------------------------------------------------------
+
+atf_test_case cleanup_pass cleanup
+cleanup_pass_head()
+{
+ atf_set "descr" "Helper test case for the t_cleanup test program"
+}
+cleanup_pass_body()
+{
+ touch $(atf_config_get tmpfile)
+}
+cleanup_pass_cleanup()
+{
+ if [ $(atf_config_get cleanup no) = yes ]; then
+ rm $(atf_config_get tmpfile)
+ fi
+}
+
+atf_test_case cleanup_fail cleanup
+cleanup_fail_head()
+{
+ atf_set "descr" "Helper test case for the t_cleanup test program"
+}
+cleanup_fail_body()
+{
+ touch $(atf_config_get tmpfile)
+ atf_fail "On purpose"
+}
+cleanup_fail_cleanup()
+{
+ if [ $(atf_config_get cleanup no) = yes ]; then
+ rm $(atf_config_get tmpfile)
+ fi
+}
+
+atf_test_case cleanup_skip cleanup
+cleanup_skip_head()
+{
+ atf_set "descr" "Helper test case for the t_cleanup test program"
+}
+cleanup_skip_body()
+{
+ touch $(atf_config_get tmpfile)
+ atf_skip "On purpose"
+}
+cleanup_skip_cleanup()
+{
+ if [ $(atf_config_get cleanup no) = yes ]; then
+ rm $(atf_config_get tmpfile)
+ fi
+}
+
+atf_test_case cleanup_curdir cleanup
+cleanup_curdir_head()
+{
+ atf_set "descr" "Helper test case for the t_cleanup test program"
+}
+cleanup_curdir_body()
+{
+ echo 1234 >oldvalue
+}
+cleanup_curdir_cleanup()
+{
+ test -f oldvalue && echo "Old value: $(cat oldvalue)"
+}
+
+atf_test_case cleanup_sigterm cleanup
+cleanup_sigterm_head()
+{
+ atf_set "descr" "Helper test case for the t_cleanup test program"
+}
+cleanup_sigterm_body()
+{
+ touch $(atf_config_get tmpfile)
+ kill $$
+ touch $(atf_config_get tmpfile).no
+}
+cleanup_sigterm_cleanup()
+{
+ rm $(atf_config_get tmpfile)
+}
+
+atf_test_case cleanup_fork cleanup
+cleanup_fork_head()
+{
+ atf_set "descr" "Helper test case for the t_cleanup test program"
+}
+cleanup_fork_body()
+{
+ :
+}
+cleanup_fork_cleanup()
+{
+ exec 1>out
+ exec 2>err
+ exec 3>res
+ rm -f out err res
+}
+
+# -------------------------------------------------------------------------
+# Helper tests for "t_config".
+# -------------------------------------------------------------------------
+
+atf_test_case config_unset
+config_unset_head()
+{
+ atf_set "descr" "Helper test case for the t_config test program"
+}
+config_unset_body()
+{
+ atf_config_has 'test' && atf_fail "Test variable already defined"
+}
+
+atf_test_case config_empty
+config_empty_head()
+{
+ atf_set "descr" "Helper test case for the t_config test program"
+}
+config_empty_body()
+{
+ atf_check_equal "$(atf_config_get 'test')" ""
+}
+
+atf_test_case config_value
+config_value_head()
+{
+ atf_set "descr" "Helper test case for the t_config test program"
+}
+config_value_body()
+{
+ atf_check_equal "$(atf_config_get 'test')" "foo"
+}
+
+atf_test_case config_multi_value
+config_multi_value_head()
+{
+ atf_set "descr" "Helper test case for the t_config test program"
+}
+config_multi_value_body()
+{
+ atf_check_equal "$(atf_config_get 'test')" "foo bar"
+}
+
+# -------------------------------------------------------------------------
+# Helper tests for "t_fork".
+# -------------------------------------------------------------------------
+
+atf_test_case fork_stop
+fork_stop_head()
+{
+ atf_set "descr" "Helper test case for the t_fork test program"
+}
+fork_stop_body()
+{
+ echo ${$} >$(atf_config_get pidfile)
+ echo "Wrote pid file"
+ echo "Waiting for done file"
+ while ! test -f $(atf_config_get donefile); do sleep 1; done
+ echo "Exiting"
+}
+
+# -------------------------------------------------------------------------
+# Helper tests for "t_expect".
+# -------------------------------------------------------------------------
+
+atf_test_case expect_pass_and_pass
+expect_pass_and_pass_body()
+{
+ atf_expect_pass
+}
+
+atf_test_case expect_pass_but_fail_requirement
+expect_pass_but_fail_requirement_body()
+{
+ atf_expect_pass
+ atf_fail "Some reason"
+}
+
+atf_test_case expect_pass_but_fail_check
+expect_pass_but_fail_check_body()
+{
+ atf_fail "Non-fatal failures not implemented"
+}
+
+atf_test_case expect_fail_and_fail_requirement
+expect_fail_and_fail_requirement_body()
+{
+ atf_expect_fail "Fail reason"
+ atf_fail "The failure"
+ atf_expect_pass
+}
+
+atf_test_case expect_fail_and_fail_check
+expect_fail_and_fail_check_body()
+{
+ atf_fail "Non-fatal failures not implemented"
+}
+
+atf_test_case expect_fail_but_pass
+expect_fail_but_pass_body()
+{
+ atf_expect_fail "Fail first"
+ atf_expect_pass
+}
+
+atf_test_case expect_exit_any_and_exit
+expect_exit_any_and_exit_body()
+{
+ atf_expect_exit -1 "Call will exit"
+ exit 0
+}
+
+atf_test_case expect_exit_code_and_exit
+expect_exit_code_and_exit_body()
+{
+ atf_expect_exit 123 "Call will exit"
+ exit 123
+}
+
+atf_test_case expect_exit_but_pass
+expect_exit_but_pass_body()
+{
+ atf_expect_exit -1 "Call won't exit"
+}
+
+atf_test_case expect_signal_any_and_signal
+expect_signal_any_and_signal_body()
+{
+ atf_expect_signal -1 "Call will signal"
+ kill -9 $$
+}
+
+atf_test_case expect_signal_no_and_signal
+expect_signal_no_and_signal_body()
+{
+ atf_expect_signal 1 "Call will signal"
+ kill -1 $$
+}
+
+atf_test_case expect_signal_but_pass
+expect_signal_but_pass_body()
+{
+ atf_expect_signal -1 "Call won't signal"
+}
+
+atf_test_case expect_death_and_exit
+expect_death_and_exit_body()
+{
+ atf_expect_death "Exit case"
+ exit 123
+}
+
+atf_test_case expect_death_and_signal
+expect_death_and_signal_body()
+{
+ atf_expect_death "Signal case"
+ kill -9 $$
+}
+
+atf_test_case expect_death_but_pass
+expect_death_but_pass_body()
+{
+ atf_expect_death "Call won't die"
+}
+
+atf_test_case expect_timeout_and_hang
+expect_timeout_and_hang_head()
+{
+ atf_set "timeout" "1"
+}
+expect_timeout_and_hang_body()
+{
+ atf_expect_timeout "Will overrun"
+ sleep 5
+}
+
+atf_test_case expect_timeout_but_pass
+expect_timeout_but_pass_head()
+{
+ atf_set "timeout" "1"
+}
+expect_timeout_but_pass_body()
+{
+ atf_expect_timeout "Will just exit"
+}
+
+# -------------------------------------------------------------------------
+# Helper tests for "t_meta_data".
+# -------------------------------------------------------------------------
+
+atf_test_case metadata_no_descr
+metadata_no_descr_head()
+{
+ :
+}
+metadata_no_descr_body()
+{
+ :
+}
+
+atf_test_case metadata_no_head
+metadata_no_head_body()
+{
+ :
+}
+
+# -------------------------------------------------------------------------
+# Helper tests for "t_srcdir".
+# -------------------------------------------------------------------------
+
+atf_test_case srcdir_exists
+srcdir_exists_head()
+{
+ atf_set "descr" "Helper test case for the t_srcdir test program"
+}
+srcdir_exists_body()
+{
+ [ -f "$(atf_get_srcdir)/datafile" ] || atf_fail "Cannot find datafile"
+}
+
+# -------------------------------------------------------------------------
+# Helper tests for "t_result".
+# -------------------------------------------------------------------------
+
+atf_test_case result_pass
+result_pass_body()
+{
+ echo "msg"
+}
+
+atf_test_case result_fail
+result_fail_body()
+{
+ echo "msg"
+ atf_fail "Failure reason"
+}
+
+atf_test_case result_skip
+result_skip_body()
+{
+ echo "msg"
+ atf_skip "Skipped reason"
+}
+
+# -------------------------------------------------------------------------
+# Main.
+# -------------------------------------------------------------------------
+
+atf_init_test_cases()
+{
+ # Add helper tests for t_cleanup.
+ atf_add_test_case cleanup_pass
+ atf_add_test_case cleanup_fail
+ atf_add_test_case cleanup_skip
+ atf_add_test_case cleanup_curdir
+ atf_add_test_case cleanup_sigterm
+ atf_add_test_case cleanup_fork
+
+ # Add helper tests for t_config.
+ atf_add_test_case config_unset
+ atf_add_test_case config_empty
+ atf_add_test_case config_value
+ atf_add_test_case config_multi_value
+
+ # Add helper tests for t_expect.
+ atf_add_test_case expect_pass_and_pass
+ atf_add_test_case expect_pass_but_fail_requirement
+ atf_add_test_case expect_pass_but_fail_check
+ atf_add_test_case expect_fail_and_fail_requirement
+ atf_add_test_case expect_fail_and_fail_check
+ atf_add_test_case expect_fail_but_pass
+ atf_add_test_case expect_exit_any_and_exit
+ atf_add_test_case expect_exit_code_and_exit
+ atf_add_test_case expect_exit_but_pass
+ atf_add_test_case expect_signal_any_and_signal
+ atf_add_test_case expect_signal_no_and_signal
+ atf_add_test_case expect_signal_but_pass
+ atf_add_test_case expect_death_and_exit
+ atf_add_test_case expect_death_and_signal
+ atf_add_test_case expect_death_but_pass
+ atf_add_test_case expect_timeout_and_hang
+ atf_add_test_case expect_timeout_but_pass
+
+ # Add helper tests for t_fork.
+ atf_add_test_case fork_stop
+
+ # Add helper tests for t_meta_data.
+ atf_add_test_case metadata_no_descr
+ atf_add_test_case metadata_no_head
+
+ # Add helper tests for t_srcdir.
+ atf_add_test_case srcdir_exists
+
+ # Add helper tests for t_result.
+ atf_add_test_case result_pass
+ atf_add_test_case result_fail
+ atf_add_test_case result_skip
+}
+
+# vim: syntax=sh:expandtab:shiftwidth=4:softtabstop=4
diff --git a/external/bsd/atf/dist/test-programs/srcdir_test.sh b/external/bsd/atf/dist/test-programs/srcdir_test.sh
new file mode 100644
index 00000000000..eb1df539cb5
--- /dev/null
+++ b/external/bsd/atf/dist/test-programs/srcdir_test.sh
@@ -0,0 +1,153 @@
+#
+# Automated Testing Framework (atf)
+#
+# Copyright (c) 2007, 2008, 2010 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
+# CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+create_files()
+{
+ mkdir tmp
+ touch tmp/datafile
+}
+
+atf_test_case default
+default_head()
+{
+ atf_set "descr" "Checks that the program can find its files if" \
+ "executed from the same directory"
+ atf_set "use.fs" "true"
+}
+default_body()
+{
+ create_files
+
+ for hp in $(get_helpers); do
+ h=${hp##*/}
+ cp ${hp} tmp
+ atf_check -s eq:0 -o ignore -e ignore -x \
+ "cd tmp && ./${h} srcdir_exists"
+ atf_check -s eq:1 -o empty -e empty "${hp}" -r res srcdir_exists
+ atf_check -s eq:0 -o ignore -e empty grep "Cannot find datafile" res
+ done
+}
+
+atf_test_case libtool
+libtool_head()
+{
+ atf_set "descr" "Checks that the program can find its files if" \
+ "executed from the source directory and if it" \
+ "was built with libtool"
+ atf_set "use.fs" "true"
+}
+libtool_body()
+{
+ create_files
+ mkdir tmp/.libs
+
+ for hp in $(get_helpers c_helpers cpp_helpers); do
+ h=${hp##*/}
+ cp ${hp} tmp
+ cp ${hp} tmp/.libs
+ atf_check -s eq:0 -o ignore -e ignore -x \
+ "cd tmp && ./.libs/${h} srcdir_exists"
+ atf_check -s eq:1 -o empty -e empty "${hp}" -r res srcdir_exists
+ atf_check -s eq:0 -o ignore -e empty grep "Cannot find datafile" res
+ done
+
+ for hp in $(get_helpers c_helpers cpp_helpers); do
+ h=${hp##*/}
+ cp ${hp} tmp
+ cp ${hp} tmp/.libs/lt-${h}
+ atf_check -s eq:0 -o ignore -e ignore -x \
+ "cd tmp && ./.libs/lt-${h} srcdir_exists"
+ atf_check -s eq:1 -o empty -e empty "${hp}" -r res srcdir_exists
+ atf_check -s eq:0 -o ignore -e empty grep "Cannot find datafile" res
+ done
+}
+
+atf_test_case sflag
+sflag_head()
+{
+ atf_set "descr" "Checks that the program can find its files when" \
+ "using the -s flag"
+ atf_set "use.fs" "true"
+}
+sflag_body()
+{
+ create_files
+
+ for hp in $(get_helpers); do
+ h=${hp##*/}
+ cp ${hp} tmp
+ atf_check -s eq:0 -o ignore -e ignore -x \
+ "cd tmp && ./${h} -s $(pwd)/tmp \
+ srcdir_exists"
+ atf_check -s eq:1 -o empty -e save:stderr "${hp}" -r res srcdir_exists
+ atf_check -s eq:0 -o ignore -e empty grep "Cannot find datafile" res
+ atf_check -s eq:0 -o ignore -e ignore \
+ "${hp}" -s "$(pwd)"/tmp srcdir_exists
+ done
+}
+
+atf_test_case relative
+relative_head()
+{
+ atf_set "descr" "Checks that passing a relative path through -s" \
+ "works"
+ atf_set "use.fs" "true"
+}
+relative_body()
+{
+ create_files
+
+ for hp in $(get_helpers); do
+ h=${hp##*/}
+ cp ${hp} tmp
+
+ for p in tmp tmp/. ./tmp; do
+ echo "Helper is: ${h}"
+ echo "Using source directory: ${p}"
+
+ atf_check -s eq:0 -o ignore -e ignore \
+ "./tmp/${h}" -s "${p}" srcdir_exists
+ atf_check -s eq:1 -o empty -e save:stderr "${hp}" -r res \
+ srcdir_exists
+ atf_check -s eq:0 -o ignore -e empty grep "Cannot find datafile" res
+ atf_check -s eq:0 -o ignore -e ignore \
+ "${hp}" -s "${p}" srcdir_exists
+ done
+ done
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case default
+ atf_add_test_case libtool
+ atf_add_test_case sflag
+ atf_add_test_case relative
+}
+
+# vim: syntax=sh:expandtab:shiftwidth=4:softtabstop=4