xref: /freebsd/contrib/atf/atf-c++/atf-c++.3 (revision 83a1ee578c9d1ab7013e997289c7cd470c0e6902)
10677dfd1SJulio Merino.\" Copyright (c) 2008 The NetBSD Foundation, Inc.
20677dfd1SJulio Merino.\" All rights reserved.
30677dfd1SJulio Merino.\"
40677dfd1SJulio Merino.\" Redistribution and use in source and binary forms, with or without
50677dfd1SJulio Merino.\" modification, are permitted provided that the following conditions
60677dfd1SJulio Merino.\" are met:
70677dfd1SJulio Merino.\" 1. Redistributions of source code must retain the above copyright
80677dfd1SJulio Merino.\"    notice, this list of conditions and the following disclaimer.
90677dfd1SJulio Merino.\" 2. Redistributions in binary form must reproduce the above copyright
100677dfd1SJulio Merino.\"    notice, this list of conditions and the following disclaimer in the
110677dfd1SJulio Merino.\"    documentation and/or other materials provided with the distribution.
120677dfd1SJulio Merino.\"
130677dfd1SJulio Merino.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
140677dfd1SJulio Merino.\" CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
150677dfd1SJulio Merino.\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
160677dfd1SJulio Merino.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
170677dfd1SJulio Merino.\" IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
180677dfd1SJulio Merino.\" DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
190677dfd1SJulio Merino.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
200677dfd1SJulio Merino.\" GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
210677dfd1SJulio Merino.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
220677dfd1SJulio Merino.\" IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
230677dfd1SJulio Merino.\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
240677dfd1SJulio Merino.\" IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25*83a1ee57SDag-Erling Smørgrav.Dd May 11, 2025
260677dfd1SJulio Merino.Dt ATF-C++ 3
270677dfd1SJulio Merino.Os
280677dfd1SJulio Merino.Sh NAME
290677dfd1SJulio Merino.Nm atf-c++ ,
300677dfd1SJulio Merino.Nm ATF_ADD_TEST_CASE ,
310677dfd1SJulio Merino.Nm ATF_CHECK_ERRNO ,
320677dfd1SJulio Merino.Nm ATF_FAIL ,
330677dfd1SJulio Merino.Nm ATF_INIT_TEST_CASES ,
340677dfd1SJulio Merino.Nm ATF_PASS ,
350677dfd1SJulio Merino.Nm ATF_REQUIRE ,
360677dfd1SJulio Merino.Nm ATF_REQUIRE_EQ ,
370677dfd1SJulio Merino.Nm ATF_REQUIRE_ERRNO ,
380677dfd1SJulio Merino.Nm ATF_REQUIRE_IN ,
390677dfd1SJulio Merino.Nm ATF_REQUIRE_MATCH ,
400677dfd1SJulio Merino.Nm ATF_REQUIRE_NOT_IN ,
410677dfd1SJulio Merino.Nm ATF_REQUIRE_THROW ,
420677dfd1SJulio Merino.Nm ATF_REQUIRE_THROW_RE ,
430677dfd1SJulio Merino.Nm ATF_SKIP ,
440677dfd1SJulio Merino.Nm ATF_TEST_CASE ,
450677dfd1SJulio Merino.Nm ATF_TEST_CASE_BODY ,
460677dfd1SJulio Merino.Nm ATF_TEST_CASE_CLEANUP ,
470677dfd1SJulio Merino.Nm ATF_TEST_CASE_HEAD ,
480677dfd1SJulio Merino.Nm ATF_TEST_CASE_NAME ,
490677dfd1SJulio Merino.Nm ATF_TEST_CASE_USE ,
500677dfd1SJulio Merino.Nm ATF_TEST_CASE_WITH_CLEANUP ,
510677dfd1SJulio Merino.Nm ATF_TEST_CASE_WITHOUT_HEAD ,
520677dfd1SJulio Merino.Nm atf::utils::cat_file ,
530677dfd1SJulio Merino.Nm atf::utils::compare_file ,
540677dfd1SJulio Merino.Nm atf::utils::copy_file ,
550677dfd1SJulio Merino.Nm atf::utils::create_file ,
560677dfd1SJulio Merino.Nm atf::utils::file_exists ,
570677dfd1SJulio Merino.Nm atf::utils::fork ,
580677dfd1SJulio Merino.Nm atf::utils::grep_collection ,
590677dfd1SJulio Merino.Nm atf::utils::grep_file ,
600677dfd1SJulio Merino.Nm atf::utils::grep_string ,
610677dfd1SJulio Merino.Nm atf::utils::redirect ,
620677dfd1SJulio Merino.Nm atf::utils::wait
630677dfd1SJulio Merino.Nd C++ API to write ATF-based test programs
640677dfd1SJulio Merino.Sh SYNOPSIS
650677dfd1SJulio Merino.In atf-c++.hpp
660677dfd1SJulio Merino.Fn ATF_ADD_TEST_CASE "tcs" "name"
670677dfd1SJulio Merino.Fn ATF_CHECK_ERRNO "expected_errno" "bool_expression"
680677dfd1SJulio Merino.Fn ATF_FAIL "reason"
690677dfd1SJulio Merino.Fn ATF_INIT_TEST_CASES "tcs"
700677dfd1SJulio Merino.Fn ATF_PASS
710677dfd1SJulio Merino.Fn ATF_REQUIRE "expression"
720677dfd1SJulio Merino.Fn ATF_REQUIRE_EQ "expected_expression" "actual_expression"
730677dfd1SJulio Merino.Fn ATF_REQUIRE_ERRNO "expected_errno" "bool_expression"
740677dfd1SJulio Merino.Fn ATF_REQUIRE_IN "element" "collection"
750677dfd1SJulio Merino.Fn ATF_REQUIRE_MATCH "regexp" "string_expression"
760677dfd1SJulio Merino.Fn ATF_REQUIRE_NOT_IN "element" "collection"
770677dfd1SJulio Merino.Fn ATF_REQUIRE_THROW "expected_exception" "statement"
780677dfd1SJulio Merino.Fn ATF_REQUIRE_THROW_RE "expected_exception" "regexp" "statement"
790677dfd1SJulio Merino.Fn ATF_SKIP "reason"
800677dfd1SJulio Merino.Fn ATF_TEST_CASE "name"
810677dfd1SJulio Merino.Fn ATF_TEST_CASE_BODY "name"
820677dfd1SJulio Merino.Fn ATF_TEST_CASE_CLEANUP "name"
830677dfd1SJulio Merino.Fn ATF_TEST_CASE_HEAD "name"
840677dfd1SJulio Merino.Fn ATF_TEST_CASE_NAME "name"
850677dfd1SJulio Merino.Fn ATF_TEST_CASE_USE "name"
860677dfd1SJulio Merino.Fn ATF_TEST_CASE_WITH_CLEANUP "name"
870677dfd1SJulio Merino.Fn ATF_TEST_CASE_WITHOUT_HEAD "name"
880677dfd1SJulio Merino.Ft void
890677dfd1SJulio Merino.Fo atf::utils::cat_file
900677dfd1SJulio Merino.Fa "const std::string& path"
910677dfd1SJulio Merino.Fa "const std::string& prefix"
920677dfd1SJulio Merino.Fc
930677dfd1SJulio Merino.Ft bool
940677dfd1SJulio Merino.Fo atf::utils::compare_file
950677dfd1SJulio Merino.Fa "const std::string& path"
960677dfd1SJulio Merino.Fa "const std::string& contents"
970677dfd1SJulio Merino.Fc
980677dfd1SJulio Merino.Ft void
990677dfd1SJulio Merino.Fo atf::utils::copy_file
1000677dfd1SJulio Merino.Fa "const std::string& source"
1010677dfd1SJulio Merino.Fa "const std::string& destination"
1020677dfd1SJulio Merino.Fc
1030677dfd1SJulio Merino.Ft void
1040677dfd1SJulio Merino.Fo atf::utils::create_file
1050677dfd1SJulio Merino.Fa "const std::string& path"
1060677dfd1SJulio Merino.Fa "const std::string& contents"
1070677dfd1SJulio Merino.Fc
1080677dfd1SJulio Merino.Ft void
1090677dfd1SJulio Merino.Fo atf::utils::file_exists
1100677dfd1SJulio Merino.Fa "const std::string& path"
1110677dfd1SJulio Merino.Fc
1120677dfd1SJulio Merino.Ft pid_t
1130677dfd1SJulio Merino.Fo atf::utils::fork
1140677dfd1SJulio Merino.Fa "void"
1150677dfd1SJulio Merino.Fc
1160677dfd1SJulio Merino.Ft bool
1170677dfd1SJulio Merino.Fo atf::utils::grep_collection
1180677dfd1SJulio Merino.Fa "const std::string& regexp"
1190677dfd1SJulio Merino.Fa "const Collection& collection"
1200677dfd1SJulio Merino.Fc
1210677dfd1SJulio Merino.Ft bool
1220677dfd1SJulio Merino.Fo atf::utils::grep_file
1230677dfd1SJulio Merino.Fa "const std::string& regexp"
1240677dfd1SJulio Merino.Fa "const std::string& path"
1250677dfd1SJulio Merino.Fc
1260677dfd1SJulio Merino.Ft bool
1270677dfd1SJulio Merino.Fo atf::utils::grep_string
1280677dfd1SJulio Merino.Fa "const std::string& regexp"
1290677dfd1SJulio Merino.Fa "const std::string& path"
1300677dfd1SJulio Merino.Fc
1310677dfd1SJulio Merino.Ft void
1320677dfd1SJulio Merino.Fo atf::utils::redirect
1330677dfd1SJulio Merino.Fa "const int fd"
1340677dfd1SJulio Merino.Fa "const std::string& path"
1350677dfd1SJulio Merino.Fc
1360677dfd1SJulio Merino.Ft void
1370677dfd1SJulio Merino.Fo atf::utils::wait
1380677dfd1SJulio Merino.Fa "const pid_t pid"
1390677dfd1SJulio Merino.Fa "const int expected_exit_status"
1400677dfd1SJulio Merino.Fa "const std::string& expected_stdout"
1410677dfd1SJulio Merino.Fa "const std::string& expected_stderr"
1420677dfd1SJulio Merino.Fc
1430677dfd1SJulio Merino.Sh DESCRIPTION
1440677dfd1SJulio MerinoATF provides a C++ programming interface to implement test programs.
1450677dfd1SJulio MerinoC++-based test programs follow this template:
1460677dfd1SJulio Merino.Bd -literal -offset indent
1470677dfd1SJulio Merinoextern "C" {
148af6edc1bSEnji Cooper\&... C-specific includes go here ...
1490677dfd1SJulio Merino}
1500677dfd1SJulio Merino
151af6edc1bSEnji Cooper\&... C++-specific includes go here ...
1520677dfd1SJulio Merino
1530677dfd1SJulio Merino#include <atf-c++.hpp>
1540677dfd1SJulio Merino
1550677dfd1SJulio MerinoATF_TEST_CASE(tc1);
1560677dfd1SJulio MerinoATF_TEST_CASE_HEAD(tc1)
1570677dfd1SJulio Merino{
1580677dfd1SJulio Merino    ... first test case's header ...
1590677dfd1SJulio Merino}
1600677dfd1SJulio MerinoATF_TEST_CASE_BODY(tc1)
1610677dfd1SJulio Merino{
1620677dfd1SJulio Merino    ... first test case's body ...
1630677dfd1SJulio Merino}
1640677dfd1SJulio Merino
1650677dfd1SJulio MerinoATF_TEST_CASE_WITH_CLEANUP(tc2);
1660677dfd1SJulio MerinoATF_TEST_CASE_HEAD(tc2)
1670677dfd1SJulio Merino{
1680677dfd1SJulio Merino    ... second test case's header ...
1690677dfd1SJulio Merino}
1700677dfd1SJulio MerinoATF_TEST_CASE_BODY(tc2)
1710677dfd1SJulio Merino{
1720677dfd1SJulio Merino    ... second test case's body ...
1730677dfd1SJulio Merino}
1740677dfd1SJulio MerinoATF_TEST_CASE_CLEANUP(tc2)
1750677dfd1SJulio Merino{
1760677dfd1SJulio Merino    ... second test case's cleanup ...
1770677dfd1SJulio Merino}
1780677dfd1SJulio Merino
1790677dfd1SJulio MerinoATF_TEST_CASE(tc3);
1800677dfd1SJulio MerinoATF_TEST_CASE_BODY(tc3)
1810677dfd1SJulio Merino{
1820677dfd1SJulio Merino    ... third test case's body ...
1830677dfd1SJulio Merino}
1840677dfd1SJulio Merino
185af6edc1bSEnji Cooper\&... additional test cases ...
1860677dfd1SJulio Merino
1870677dfd1SJulio MerinoATF_INIT_TEST_CASES(tcs)
1880677dfd1SJulio Merino{
1890677dfd1SJulio Merino    ATF_ADD_TEST_CASE(tcs, tc1);
1900677dfd1SJulio Merino    ATF_ADD_TEST_CASE(tcs, tc2);
1910677dfd1SJulio Merino    ATF_ADD_TEST_CASE(tcs, tc3);
1920677dfd1SJulio Merino    ... add additional test cases ...
1930677dfd1SJulio Merino}
1940677dfd1SJulio Merino.Ed
1950677dfd1SJulio Merino.Ss Definition of test cases
1960677dfd1SJulio MerinoTest cases have an identifier and are composed of three different parts:
1970677dfd1SJulio Merinothe header, the body and an optional cleanup routine, all of which are
1980677dfd1SJulio Merinodescribed in
1990677dfd1SJulio Merino.Xr atf-test-case 4 .
2000677dfd1SJulio MerinoTo define test cases, one can use the
2010677dfd1SJulio Merino.Fn ATF_TEST_CASE ,
2020677dfd1SJulio Merino.Fn ATF_TEST_CASE_WITH_CLEANUP
2030677dfd1SJulio Merinoor the
2040677dfd1SJulio Merino.Fn ATF_TEST_CASE_WITHOUT_HEAD
205af6edc1bSEnji Coopermacros, which take a single parameter specifying the test case's
2060677dfd1SJulio Merinoname.
2070677dfd1SJulio Merino.Fn ATF_TEST_CASE ,
2080677dfd1SJulio Merinorequires to define a head and a body for the test case,
2090677dfd1SJulio Merino.Fn ATF_TEST_CASE_WITH_CLEANUP
2100677dfd1SJulio Merinorequires to define a head, a body and a cleanup for the test case and
2110677dfd1SJulio Merino.Fn ATF_TEST_CASE_WITHOUT_HEAD
2120677dfd1SJulio Merinorequires only a body for the test case.
2130677dfd1SJulio MerinoIt is important to note that these
2140677dfd1SJulio Merino.Em do not
2150677dfd1SJulio Merinoset the test case up for execution when the program is run.
2160677dfd1SJulio MerinoIn order to do so, a later registration is needed through the
2170677dfd1SJulio Merino.Fn ATF_ADD_TEST_CASE
2180677dfd1SJulio Merinomacro detailed in
2190677dfd1SJulio Merino.Sx Program initialization .
2200677dfd1SJulio Merino.Pp
2210677dfd1SJulio MerinoLater on, one must define the three parts of the body by means of three
2220677dfd1SJulio Merinofunctions.
2230677dfd1SJulio MerinoTheir headers are given by the
2240677dfd1SJulio Merino.Fn ATF_TEST_CASE_HEAD ,
2250677dfd1SJulio Merino.Fn ATF_TEST_CASE_BODY
2260677dfd1SJulio Merinoand
2270677dfd1SJulio Merino.Fn ATF_TEST_CASE_CLEANUP
2280677dfd1SJulio Merinomacros, all of which take the test case's name.
2290677dfd1SJulio MerinoFollowing each of these, a block of code is expected, surrounded by the
2300677dfd1SJulio Merinoopening and closing brackets.
2310677dfd1SJulio Merino.Pp
2320677dfd1SJulio MerinoAdditionally, the
2330677dfd1SJulio Merino.Fn ATF_TEST_CASE_NAME
2340677dfd1SJulio Merinomacro can be used to obtain the name of the class corresponding to a
235af6edc1bSEnji Cooperparticular test case, as the name is internally managed by the library to
2360677dfd1SJulio Merinoprevent clashes with other user identifiers.
2370677dfd1SJulio MerinoSimilarly, the
2380677dfd1SJulio Merino.Fn ATF_TEST_CASE_USE
2390677dfd1SJulio Merinomacro can be executed on a particular test case to mark it as "used" and
2400677dfd1SJulio Merinothus prevent compiler warnings regarding unused symbols.
2410677dfd1SJulio MerinoNote that
2420677dfd1SJulio Merino.Em you should never have to use these macros during regular operation.
2430677dfd1SJulio Merino.Ss Program initialization
2440677dfd1SJulio MerinoThe library provides a way to easily define the test program's
2450677dfd1SJulio Merino.Fn main
2460677dfd1SJulio Merinofunction.
2470677dfd1SJulio MerinoYou should never define one on your own, but rely on the
2480677dfd1SJulio Merinolibrary to do it for you.
2490677dfd1SJulio MerinoThis is done by using the
2500677dfd1SJulio Merino.Fn ATF_INIT_TEST_CASES
2510677dfd1SJulio Merinomacro, which is passed the name of the list that will hold the test cases.
2520677dfd1SJulio MerinoThis name can be whatever you want as long as it is a valid variable value.
2530677dfd1SJulio Merino.Pp
2540677dfd1SJulio MerinoAfter the macro, you are supposed to provide the body of a function, which
2550677dfd1SJulio Merinoshould only use the
2560677dfd1SJulio Merino.Fn ATF_ADD_TEST_CASE
2570677dfd1SJulio Merinomacro to register the test cases the test program will execute.
2580677dfd1SJulio MerinoThe first parameter of this macro matches the name you provided in the
2590677dfd1SJulio Merinoformer call.
2600677dfd1SJulio Merino.Ss Header definitions
2610677dfd1SJulio MerinoThe test case's header can define the meta-data by using the
2620677dfd1SJulio Merino.Fn set_md_var
2630677dfd1SJulio Merinomethod, which takes two parameters: the first one specifies the
2640677dfd1SJulio Merinometa-data variable to be set and the second one specifies its value.
2650677dfd1SJulio MerinoBoth of them are strings.
2660677dfd1SJulio Merino.Ss Configuration variables
2670677dfd1SJulio MerinoThe test case has read-only access to the current configuration variables
2680677dfd1SJulio Merinoby means of the
2690677dfd1SJulio Merino.Ft bool
2700677dfd1SJulio Merino.Fn has_config_var
2710677dfd1SJulio Merinoand the
2720677dfd1SJulio Merino.Ft std::string
2730677dfd1SJulio Merino.Fn get_config_var
2740677dfd1SJulio Merinomethods, which can be called in any of the three parts of a test case.
2750677dfd1SJulio Merino.Ss Access to the source directory
2760677dfd1SJulio MerinoIt is possible to get the path to the test case's source directory from any
2770677dfd1SJulio Merinoof its three components by querying the
2780677dfd1SJulio Merino.Sq srcdir
2790677dfd1SJulio Merinoconfiguration variable.
280*83a1ee57SDag-Erling Smørgrav.Ss Requiring kernel modules
281*83a1ee57SDag-Erling SmørgravAside from the
282*83a1ee57SDag-Erling Smørgrav.Va require.kmods
283*83a1ee57SDag-Erling Smørgravmeta-data variable available in the header only, one can also check for
284*83a1ee57SDag-Erling Smørgravadditional kernel modules in the test case's body by using the
285*83a1ee57SDag-Erling Smørgrav.Fn require_kmod
286*83a1ee57SDag-Erling Smørgravfunction, which takes the name of a single module.
287*83a1ee57SDag-Erling SmørgravIf it is not found, the test case will be automatically skipped.
2880677dfd1SJulio Merino.Ss Requiring programs
2890677dfd1SJulio MerinoAside from the
2900677dfd1SJulio Merino.Va require.progs
2910677dfd1SJulio Merinometa-data variable available in the header only, one can also check for
2920677dfd1SJulio Merinoadditional programs in the test case's body by using the
2930677dfd1SJulio Merino.Fn require_prog
2940677dfd1SJulio Merinofunction, which takes the base name or full path of a single binary.
2950677dfd1SJulio MerinoRelative paths are forbidden.
2960677dfd1SJulio MerinoIf it is not found, the test case will be automatically skipped.
2970677dfd1SJulio Merino.Ss Test case finalization
2980677dfd1SJulio MerinoThe test case finalizes either when the body reaches its end, at which
2990677dfd1SJulio Merinopoint the test is assumed to have
3000677dfd1SJulio Merino.Em passed ,
3010677dfd1SJulio Merinoor at any explicit call to
3020677dfd1SJulio Merino.Fn ATF_PASS ,
3030677dfd1SJulio Merino.Fn ATF_FAIL
3040677dfd1SJulio Merinoor
3050677dfd1SJulio Merino.Fn ATF_SKIP .
3060677dfd1SJulio MerinoThese three macros terminate the execution of the test case immediately.
3070677dfd1SJulio MerinoThe cleanup routine will be processed afterwards in a completely automated
3080677dfd1SJulio Merinoway, regardless of the test case's termination reason.
3090677dfd1SJulio Merino.Pp
3100677dfd1SJulio Merino.Fn ATF_PASS
3110677dfd1SJulio Merinodoes not take any parameters.
3120677dfd1SJulio Merino.Fn ATF_FAIL
3130677dfd1SJulio Merinoand
3140677dfd1SJulio Merino.Fn ATF_SKIP
3150677dfd1SJulio Merinotake a single string that describes why the test case failed or
3160677dfd1SJulio Merinowas skipped, respectively.
3170677dfd1SJulio MerinoIt is very important to provide a clear error message in both cases so that
3180677dfd1SJulio Merinothe user can quickly know why the test did not pass.
3190677dfd1SJulio Merino.Ss Expectations
3200677dfd1SJulio MerinoEverything explained in the previous section changes when the test case
3210677dfd1SJulio Merinoexpectations are redefined by the programmer.
3220677dfd1SJulio Merino.Pp
3230677dfd1SJulio MerinoEach test case has an internal state called
3240677dfd1SJulio Merino.Sq expect
3250677dfd1SJulio Merinothat describes what the test case expectations are at any point in time.
3260677dfd1SJulio MerinoThe value of this property can change during execution by any of:
3270677dfd1SJulio Merino.Bl -tag -width indent
3280677dfd1SJulio Merino.It Fn expect_death "reason"
3290677dfd1SJulio MerinoExpects the test case to exit prematurely regardless of the nature of the
3300677dfd1SJulio Merinoexit.
3310677dfd1SJulio Merino.It Fn expect_exit "exitcode" "reason"
3320677dfd1SJulio MerinoExpects the test case to exit cleanly.
3330677dfd1SJulio MerinoIf
3340677dfd1SJulio Merino.Va exitcode
3350677dfd1SJulio Merinois not
3360677dfd1SJulio Merino.Sq -1 ,
3370677dfd1SJulio Merinothe runtime engine will validate that the exit code of the test case
3380677dfd1SJulio Merinomatches the one provided in this call.
3390677dfd1SJulio MerinoOtherwise, the exact value will be ignored.
3400677dfd1SJulio Merino.It Fn expect_fail "reason"
3410677dfd1SJulio MerinoAny failure (be it fatal or non-fatal) raised in this mode is recorded.
3420677dfd1SJulio MerinoHowever, such failures do not report the test case as failed; instead, the
3430677dfd1SJulio Merinotest case finalizes cleanly and is reported as
3440677dfd1SJulio Merino.Sq expected failure ;
3450677dfd1SJulio Merinothis report includes the provided
3460677dfd1SJulio Merino.Fa reason
3470677dfd1SJulio Merinoas part of it.
3480677dfd1SJulio MerinoIf no error is raised while running in this mode, then the test case is
3490677dfd1SJulio Merinoreported as
3500677dfd1SJulio Merino.Sq failed .
3510677dfd1SJulio Merino.Pp
3520677dfd1SJulio MerinoThis mode is useful to reproduce actual known bugs in tests.
3530677dfd1SJulio MerinoWhenever the developer fixes the bug later on, the test case will start
3540677dfd1SJulio Merinoreporting a failure, signaling the developer that the test case must be
3550677dfd1SJulio Merinoadjusted to the new conditions.
3560677dfd1SJulio MerinoIn this situation, it is useful, for example, to set
3570677dfd1SJulio Merino.Fa reason
3580677dfd1SJulio Merinoas the bug number for tracking purposes.
3590677dfd1SJulio Merino.It Fn expect_pass
3600677dfd1SJulio MerinoThis is the normal mode of execution.
3610677dfd1SJulio MerinoIn this mode, any failure is reported as such to the user and the test case
3620677dfd1SJulio Merinois marked as
3630677dfd1SJulio Merino.Sq failed .
3640677dfd1SJulio Merino.It Fn expect_race "reason"
3650677dfd1SJulio MerinoAny failure or timeout during the execution of the test case will be
3660677dfd1SJulio Merinoconsidered as if a race condition has been triggered and reported as such.
3670677dfd1SJulio MerinoIf no problems arise, the test will continue execution as usual.
3680677dfd1SJulio Merino.It Fn expect_signal "signo" "reason"
3690677dfd1SJulio MerinoExpects the test case to terminate due to the reception of a signal.
3700677dfd1SJulio MerinoIf
3710677dfd1SJulio Merino.Va signo
3720677dfd1SJulio Merinois not
3730677dfd1SJulio Merino.Sq -1 ,
3740677dfd1SJulio Merinothe runtime engine will validate that the signal that terminated the test
3750677dfd1SJulio Merinocase matches the one provided in this call.
3760677dfd1SJulio MerinoOtherwise, the exact value will be ignored.
3770677dfd1SJulio Merino.It Fn expect_timeout "reason"
3780677dfd1SJulio MerinoExpects the test case to execute for longer than its timeout.
3790677dfd1SJulio Merino.El
3800677dfd1SJulio Merino.Ss Helper macros for common checks
3810677dfd1SJulio MerinoThe library provides several macros that are very handy in multiple
3820677dfd1SJulio Merinosituations.
3830677dfd1SJulio MerinoThese basically check some condition after executing a given statement or
3840677dfd1SJulio Merinoprocessing a given expression and, if the condition is not met, they
3850677dfd1SJulio Merinoautomatically call
3860677dfd1SJulio Merino.Fn ATF_FAIL
3870677dfd1SJulio Merinowith an appropriate error message.
3880677dfd1SJulio Merino.Pp
3890677dfd1SJulio Merino.Fn ATF_REQUIRE
3900677dfd1SJulio Merinotakes an expression and raises a failure if it evaluates to false.
3910677dfd1SJulio Merino.Pp
3920677dfd1SJulio Merino.Fn ATF_REQUIRE_EQ
3930677dfd1SJulio Merinotakes two expressions and raises a failure if the two do not evaluate to
3940677dfd1SJulio Merinothe same exact value.
3950677dfd1SJulio MerinoThe common style is to put the expected value in the first parameter and the
3960677dfd1SJulio Merinoactual value in the second parameter.
3970677dfd1SJulio Merino.Pp
3980677dfd1SJulio Merino.Fn ATF_REQUIRE_IN
3990677dfd1SJulio Merinotakes an element and a collection and validates that the element is present in
4000677dfd1SJulio Merinothe collection.
4010677dfd1SJulio Merino.Pp
4020677dfd1SJulio Merino.Fn ATF_REQUIRE_MATCH
4030677dfd1SJulio Merinotakes a regular expression and a string and raises a failure if the regular
4040677dfd1SJulio Merinoexpression does not match the string.
4050677dfd1SJulio Merino.Pp
4060677dfd1SJulio Merino.Fn ATF_REQUIRE_NOT_IN
4070677dfd1SJulio Merinotakes an element and a collection and validates that the element is not present
4080677dfd1SJulio Merinoin the collection.
4090677dfd1SJulio Merino.Pp
4100677dfd1SJulio Merino.Fn ATF_REQUIRE_THROW
4110677dfd1SJulio Merinotakes the name of an exception and a statement and raises a failure if
4120677dfd1SJulio Merinothe statement does not throw the specified exception.
4130677dfd1SJulio Merino.Fn ATF_REQUIRE_THROW_RE
414c203bd70SAlex Richardsontakes the name of an exception, a regular expression and a statement, and raises
415c203bd70SAlex Richardsona failure if the statement does not throw the specified exception and if the
4160677dfd1SJulio Merinomessage of the exception does not match the regular expression.
4170677dfd1SJulio Merino.Pp
4180677dfd1SJulio Merino.Fn ATF_CHECK_ERRNO
4190677dfd1SJulio Merinoand
4200677dfd1SJulio Merino.Fn ATF_REQUIRE_ERRNO
4210677dfd1SJulio Merinotake, first, the error code that the check is expecting to find in the
4220677dfd1SJulio Merino.Va errno
4230677dfd1SJulio Merinovariable and, second, a boolean expression that, if evaluates to true,
4240677dfd1SJulio Merinomeans that a call failed and
4250677dfd1SJulio Merino.Va errno
4260677dfd1SJulio Merinohas to be checked against the first value.
4270677dfd1SJulio Merino.Ss Utility functions
4280677dfd1SJulio MerinoThe following functions are provided as part of the
4290677dfd1SJulio Merino.Nm
4300677dfd1SJulio MerinoAPI to simplify the creation of a variety of tests.
4310677dfd1SJulio MerinoIn particular, these are useful to write tests for command-line interfaces.
4320677dfd1SJulio Merino.Pp
4330677dfd1SJulio Merino.Ft void
4340677dfd1SJulio Merino.Fo atf::utils::cat_file
4350677dfd1SJulio Merino.Fa "const std::string& path"
4360677dfd1SJulio Merino.Fa "const std::string& prefix"
4370677dfd1SJulio Merino.Fc
4380677dfd1SJulio Merino.Bd -ragged -offset indent
4390677dfd1SJulio MerinoPrints the contents of
4400677dfd1SJulio Merino.Fa path
4410677dfd1SJulio Merinoto the standard output, prefixing every line with the string in
4420677dfd1SJulio Merino.Fa prefix .
4430677dfd1SJulio Merino.Ed
4440677dfd1SJulio Merino.Pp
4450677dfd1SJulio Merino.Ft bool
4460677dfd1SJulio Merino.Fo atf::utils::compare_file
4470677dfd1SJulio Merino.Fa "const std::string& path"
4480677dfd1SJulio Merino.Fa "const std::string& contents"
4490677dfd1SJulio Merino.Fc
4500677dfd1SJulio Merino.Bd -ragged -offset indent
4510677dfd1SJulio MerinoReturns true if the given
4520677dfd1SJulio Merino.Fa path
4530677dfd1SJulio Merinomatches exactly the expected inlined
4540677dfd1SJulio Merino.Fa contents .
4550677dfd1SJulio Merino.Ed
4560677dfd1SJulio Merino.Pp
4570677dfd1SJulio Merino.Ft void
4580677dfd1SJulio Merino.Fo atf::utils::copy_file
4590677dfd1SJulio Merino.Fa "const std::string& source"
4600677dfd1SJulio Merino.Fa "const std::string& destination"
4610677dfd1SJulio Merino.Fc
4620677dfd1SJulio Merino.Bd -ragged -offset indent
4630677dfd1SJulio MerinoCopies the file
4640677dfd1SJulio Merino.Fa source
4650677dfd1SJulio Merinoto
4660677dfd1SJulio Merino.Fa destination .
4670677dfd1SJulio MerinoThe permissions of the file are preserved during the code.
4680677dfd1SJulio Merino.Ed
4690677dfd1SJulio Merino.Pp
4700677dfd1SJulio Merino.Ft void
4710677dfd1SJulio Merino.Fo atf::utils::create_file
4720677dfd1SJulio Merino.Fa "const std::string& path"
4730677dfd1SJulio Merino.Fa "const std::string& contents"
4740677dfd1SJulio Merino.Fc
4750677dfd1SJulio Merino.Bd -ragged -offset indent
4760677dfd1SJulio MerinoCreates
4770677dfd1SJulio Merino.Fa file
4780677dfd1SJulio Merinowith the text given in
4790677dfd1SJulio Merino.Fa contents .
4800677dfd1SJulio Merino.Ed
4810677dfd1SJulio Merino.Pp
4820677dfd1SJulio Merino.Ft void
4830677dfd1SJulio Merino.Fo atf::utils::file_exists
4840677dfd1SJulio Merino.Fa "const std::string& path"
4850677dfd1SJulio Merino.Fc
4860677dfd1SJulio Merino.Bd -ragged -offset indent
4870677dfd1SJulio MerinoChecks if
4880677dfd1SJulio Merino.Fa path
4890677dfd1SJulio Merinoexists.
4900677dfd1SJulio Merino.Ed
4910677dfd1SJulio Merino.Pp
4920677dfd1SJulio Merino.Ft pid_t
4930677dfd1SJulio Merino.Fo atf::utils::fork
4940677dfd1SJulio Merino.Fa "void"
4950677dfd1SJulio Merino.Fc
4960677dfd1SJulio Merino.Bd -ragged -offset indent
4970677dfd1SJulio MerinoForks a process and redirects the standard output and standard error of the
4980677dfd1SJulio Merinochild to files for later validation with
4990677dfd1SJulio Merino.Fn atf::utils::wait .
5000677dfd1SJulio MerinoFails the test case if the fork fails, so this does not return an error.
5010677dfd1SJulio Merino.Ed
5020677dfd1SJulio Merino.Pp
5030677dfd1SJulio Merino.Ft bool
5040677dfd1SJulio Merino.Fo atf::utils::grep_collection
5050677dfd1SJulio Merino.Fa "const std::string& regexp"
5060677dfd1SJulio Merino.Fa "const Collection& collection"
5070677dfd1SJulio Merino.Fc
5080677dfd1SJulio Merino.Bd -ragged -offset indent
5090677dfd1SJulio MerinoSearches for the regular expression
5100677dfd1SJulio Merino.Fa regexp
5110677dfd1SJulio Merinoin any of the strings contained in the
5120677dfd1SJulio Merino.Fa collection .
5130677dfd1SJulio MerinoThis is a template that accepts any one-dimensional container of strings.
5140677dfd1SJulio Merino.Ed
5150677dfd1SJulio Merino.Pp
5160677dfd1SJulio Merino.Ft bool
5170677dfd1SJulio Merino.Fo atf::utils::grep_file
5180677dfd1SJulio Merino.Fa "const std::string& regexp"
5190677dfd1SJulio Merino.Fa "const std::string& path"
5200677dfd1SJulio Merino.Fc
5210677dfd1SJulio Merino.Bd -ragged -offset indent
5220677dfd1SJulio MerinoSearches for the regular expression
5230677dfd1SJulio Merino.Fa regexp
5240677dfd1SJulio Merinoin the file
5250677dfd1SJulio Merino.Fa path .
5260677dfd1SJulio MerinoThe variable arguments are used to construct the regular expression.
5270677dfd1SJulio Merino.Ed
5280677dfd1SJulio Merino.Pp
5290677dfd1SJulio Merino.Ft bool
5300677dfd1SJulio Merino.Fo atf::utils::grep_string
5310677dfd1SJulio Merino.Fa "const std::string& regexp"
5320677dfd1SJulio Merino.Fa "const std::string& str"
5330677dfd1SJulio Merino.Fc
5340677dfd1SJulio Merino.Bd -ragged -offset indent
5350677dfd1SJulio MerinoSearches for the regular expression
5360677dfd1SJulio Merino.Fa regexp
5370677dfd1SJulio Merinoin the string
5380677dfd1SJulio Merino.Fa str .
5390677dfd1SJulio Merino.Ed
5400677dfd1SJulio Merino.Ft void
5410677dfd1SJulio Merino.Fo atf::utils::redirect
5420677dfd1SJulio Merino.Fa "const int fd"
5430677dfd1SJulio Merino.Fa "const std::string& path"
5440677dfd1SJulio Merino.Fc
5450677dfd1SJulio Merino.Bd -ragged -offset indent
5460677dfd1SJulio MerinoRedirects the given file descriptor
5470677dfd1SJulio Merino.Fa fd
5480677dfd1SJulio Merinoto the file
5490677dfd1SJulio Merino.Fa path .
5500677dfd1SJulio MerinoThis function exits the process in case of an error and does not properly mark
5510677dfd1SJulio Merinothe test case as failed.
5520677dfd1SJulio MerinoAs a result, it should only be used in subprocesses of the test case; specially
5530677dfd1SJulio Merinothose spawned by
5540677dfd1SJulio Merino.Fn atf::utils::fork .
5550677dfd1SJulio Merino.Ed
5560677dfd1SJulio Merino.Pp
5570677dfd1SJulio Merino.Ft void
5580677dfd1SJulio Merino.Fo atf::utils::wait
5590677dfd1SJulio Merino.Fa "const pid_t pid"
5600677dfd1SJulio Merino.Fa "const int expected_exit_status"
5610677dfd1SJulio Merino.Fa "const std::string& expected_stdout"
5620677dfd1SJulio Merino.Fa "const std::string& expected_stderr"
5630677dfd1SJulio Merino.Fc
5640677dfd1SJulio Merino.Bd -ragged -offset indent
5650677dfd1SJulio MerinoWaits and validates the result of a subprocess spawned with
5660677dfd1SJulio Merino.Fn atf::utils::wait .
5670677dfd1SJulio MerinoThe validation involves checking that the subprocess exited cleanly and returned
5680677dfd1SJulio Merinothe code specified in
5690677dfd1SJulio Merino.Fa expected_exit_status
5700677dfd1SJulio Merinoand that its standard output and standard error match the strings given in
5710677dfd1SJulio Merino.Fa expected_stdout
5720677dfd1SJulio Merinoand
5730677dfd1SJulio Merino.Fa expected_stderr .
5740677dfd1SJulio Merino.Pp
5750677dfd1SJulio MerinoIf any of the
5760677dfd1SJulio Merino.Fa expected_stdout
5770677dfd1SJulio Merinoor
5780677dfd1SJulio Merino.Fa expected_stderr
5790677dfd1SJulio Merinostrings are prefixed with
5800677dfd1SJulio Merino.Sq save: ,
5810677dfd1SJulio Merinothen they specify the name of the file into which to store the stdout or stderr
5820677dfd1SJulio Merinoof the subprocess, and no comparison is performed.
5830677dfd1SJulio Merino.Ed
5840677dfd1SJulio Merino.Sh ENVIRONMENT
5850677dfd1SJulio MerinoThe following variables are recognized by
5860677dfd1SJulio Merino.Nm
5870677dfd1SJulio Merinobut should not be overridden other than for testing purposes:
5880677dfd1SJulio Merino.Pp
5890677dfd1SJulio Merino.Bl -tag -width ATFXBUILDXCXXFLAGSXX -compact
5900677dfd1SJulio Merino.It Va ATF_BUILD_CC
5910677dfd1SJulio MerinoPath to the C compiler.
5920677dfd1SJulio Merino.It Va ATF_BUILD_CFLAGS
5930677dfd1SJulio MerinoC compiler flags.
5940677dfd1SJulio Merino.It Va ATF_BUILD_CPP
5950677dfd1SJulio MerinoPath to the C/C++ preprocessor.
5960677dfd1SJulio Merino.It Va ATF_BUILD_CPPFLAGS
5970677dfd1SJulio MerinoC/C++ preprocessor flags.
5980677dfd1SJulio Merino.It Va ATF_BUILD_CXX
5990677dfd1SJulio MerinoPath to the C++ compiler.
6000677dfd1SJulio Merino.It Va ATF_BUILD_CXXFLAGS
6010677dfd1SJulio MerinoC++ compiler flags.
6020677dfd1SJulio Merino.El
6030677dfd1SJulio Merino.Sh EXAMPLES
6040677dfd1SJulio MerinoThe following shows a complete test program with a single test case that
6050677dfd1SJulio Merinovalidates the addition operator:
6060677dfd1SJulio Merino.Bd -literal -offset indent
6070677dfd1SJulio Merino#include <atf-c++.hpp>
6080677dfd1SJulio Merino
6090677dfd1SJulio MerinoATF_TEST_CASE(addition);
6100677dfd1SJulio MerinoATF_TEST_CASE_HEAD(addition)
6110677dfd1SJulio Merino{
6120677dfd1SJulio Merino    set_md_var("descr", "Sample tests for the addition operator");
6130677dfd1SJulio Merino}
6140677dfd1SJulio MerinoATF_TEST_CASE_BODY(addition)
6150677dfd1SJulio Merino{
6160677dfd1SJulio Merino    ATF_REQUIRE_EQ(0, 0 + 0);
6170677dfd1SJulio Merino    ATF_REQUIRE_EQ(1, 0 + 1);
6180677dfd1SJulio Merino    ATF_REQUIRE_EQ(1, 1 + 0);
6190677dfd1SJulio Merino
6200677dfd1SJulio Merino    ATF_REQUIRE_EQ(2, 1 + 1);
6210677dfd1SJulio Merino
6220677dfd1SJulio Merino    ATF_REQUIRE_EQ(300, 100 + 200);
6230677dfd1SJulio Merino}
6240677dfd1SJulio Merino
6250677dfd1SJulio MerinoATF_TEST_CASE(open_failure);
6260677dfd1SJulio MerinoATF_TEST_CASE_HEAD(open_failure)
6270677dfd1SJulio Merino{
6280677dfd1SJulio Merino    set_md_var("descr", "Sample tests for the open function");
6290677dfd1SJulio Merino}
6300677dfd1SJulio MerinoATF_TEST_CASE_BODY(open_failure)
6310677dfd1SJulio Merino{
6320677dfd1SJulio Merino    ATF_REQUIRE_ERRNO(ENOENT, open("non-existent", O_RDONLY) == -1);
6330677dfd1SJulio Merino}
6340677dfd1SJulio Merino
6350677dfd1SJulio MerinoATF_TEST_CASE(known_bug);
6360677dfd1SJulio MerinoATF_TEST_CASE_HEAD(known_bug)
6370677dfd1SJulio Merino{
6380677dfd1SJulio Merino    set_md_var("descr", "Reproduces a known bug");
6390677dfd1SJulio Merino}
6400677dfd1SJulio MerinoATF_TEST_CASE_BODY(known_bug)
6410677dfd1SJulio Merino{
6420677dfd1SJulio Merino    expect_fail("See bug number foo/bar");
6430677dfd1SJulio Merino    ATF_REQUIRE_EQ(3, 1 + 1);
6440677dfd1SJulio Merino    expect_pass();
6450677dfd1SJulio Merino    ATF_REQUIRE_EQ(3, 1 + 2);
6460677dfd1SJulio Merino}
6470677dfd1SJulio Merino
6480677dfd1SJulio MerinoATF_INIT_TEST_CASES(tcs)
6490677dfd1SJulio Merino{
6500677dfd1SJulio Merino    ATF_ADD_TEST_CASE(tcs, addition);
6510677dfd1SJulio Merino    ATF_ADD_TEST_CASE(tcs, open_failure);
6520677dfd1SJulio Merino    ATF_ADD_TEST_CASE(tcs, known_bug);
6530677dfd1SJulio Merino}
6540677dfd1SJulio Merino.Ed
6550677dfd1SJulio Merino.Sh SEE ALSO
6560677dfd1SJulio Merino.Xr atf-test-program 1 ,
6570677dfd1SJulio Merino.Xr atf-test-case 4
658