111be35a1SLionel Sambuc.\" 211be35a1SLionel Sambuc.\" Automated Testing Framework (atf) 311be35a1SLionel Sambuc.\" 411be35a1SLionel Sambuc.\" Copyright (c) 2008 The NetBSD Foundation, Inc. 511be35a1SLionel Sambuc.\" All rights reserved. 611be35a1SLionel Sambuc.\" 711be35a1SLionel Sambuc.\" Redistribution and use in source and binary forms, with or without 811be35a1SLionel Sambuc.\" modification, are permitted provided that the following conditions 911be35a1SLionel Sambuc.\" are met: 1011be35a1SLionel Sambuc.\" 1. Redistributions of source code must retain the above copyright 1111be35a1SLionel Sambuc.\" notice, this list of conditions and the following disclaimer. 1211be35a1SLionel Sambuc.\" 2. Redistributions in binary form must reproduce the above copyright 1311be35a1SLionel Sambuc.\" notice, this list of conditions and the following disclaimer in the 1411be35a1SLionel Sambuc.\" documentation and/or other materials provided with the distribution. 1511be35a1SLionel Sambuc.\" 1611be35a1SLionel Sambuc.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND 1711be35a1SLionel Sambuc.\" CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 1811be35a1SLionel Sambuc.\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 1911be35a1SLionel Sambuc.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2011be35a1SLionel Sambuc.\" IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY 2111be35a1SLionel Sambuc.\" DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2211be35a1SLionel Sambuc.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 2311be35a1SLionel Sambuc.\" GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2411be35a1SLionel Sambuc.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 2511be35a1SLionel Sambuc.\" IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 2611be35a1SLionel Sambuc.\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 2711be35a1SLionel Sambuc.\" IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2811be35a1SLionel Sambuc.\" 29*0a6a1f1dSLionel Sambuc.Dd November 15, 2013 3011be35a1SLionel Sambuc.Dt ATF-C++-API 3 3111be35a1SLionel Sambuc.Os 3211be35a1SLionel Sambuc.Sh NAME 3311be35a1SLionel Sambuc.Nm atf-c++-api , 3411be35a1SLionel Sambuc.Nm ATF_ADD_TEST_CASE , 3511be35a1SLionel Sambuc.Nm ATF_CHECK_ERRNO , 3611be35a1SLionel Sambuc.Nm ATF_FAIL , 3711be35a1SLionel Sambuc.Nm ATF_INIT_TEST_CASES , 3811be35a1SLionel Sambuc.Nm ATF_PASS , 3911be35a1SLionel Sambuc.Nm ATF_REQUIRE , 4011be35a1SLionel Sambuc.Nm ATF_REQUIRE_EQ , 4111be35a1SLionel Sambuc.Nm ATF_REQUIRE_ERRNO , 4211be35a1SLionel Sambuc.Nm ATF_REQUIRE_IN , 4311be35a1SLionel Sambuc.Nm ATF_REQUIRE_MATCH , 4411be35a1SLionel Sambuc.Nm ATF_REQUIRE_NOT_IN , 4511be35a1SLionel Sambuc.Nm ATF_REQUIRE_THROW , 4611be35a1SLionel Sambuc.Nm ATF_REQUIRE_THROW_RE , 4711be35a1SLionel Sambuc.Nm ATF_SKIP , 4811be35a1SLionel Sambuc.Nm ATF_TEST_CASE , 4911be35a1SLionel Sambuc.Nm ATF_TEST_CASE_BODY , 5011be35a1SLionel Sambuc.Nm ATF_TEST_CASE_CLEANUP , 5111be35a1SLionel Sambuc.Nm ATF_TEST_CASE_HEAD , 5211be35a1SLionel Sambuc.Nm ATF_TEST_CASE_NAME , 5311be35a1SLionel Sambuc.Nm ATF_TEST_CASE_USE , 5411be35a1SLionel Sambuc.Nm ATF_TEST_CASE_WITH_CLEANUP , 5511be35a1SLionel Sambuc.Nm ATF_TEST_CASE_WITHOUT_HEAD , 5611be35a1SLionel Sambuc.Nm atf::utils::cat_file , 5711be35a1SLionel Sambuc.Nm atf::utils::compare_file , 5811be35a1SLionel Sambuc.Nm atf::utils::copy_file , 5911be35a1SLionel Sambuc.Nm atf::utils::create_file , 6011be35a1SLionel Sambuc.Nm atf::utils::file_exists , 6111be35a1SLionel Sambuc.Nm atf::utils::fork , 6211be35a1SLionel Sambuc.Nm atf::utils::grep_collection , 6311be35a1SLionel Sambuc.Nm atf::utils::grep_file , 6411be35a1SLionel Sambuc.Nm atf::utils::grep_string , 6511be35a1SLionel Sambuc.Nm atf::utils::redirect , 6611be35a1SLionel Sambuc.Nm atf::utils::wait 6711be35a1SLionel Sambuc.Nd C++ API to write ATF-based test programs 6811be35a1SLionel Sambuc.Sh SYNOPSIS 6911be35a1SLionel Sambuc.In atf-c++.hpp 7011be35a1SLionel Sambuc.Fn ATF_ADD_TEST_CASE "tcs" "name" 7111be35a1SLionel Sambuc.Fn ATF_CHECK_ERRNO "exp_errno" "bool_expression" 7211be35a1SLionel Sambuc.Fn ATF_FAIL "reason" 7311be35a1SLionel Sambuc.Fn ATF_INIT_TEST_CASES "tcs" 7411be35a1SLionel Sambuc.Fn ATF_PASS 7511be35a1SLionel Sambuc.Fn ATF_REQUIRE "expression" 7611be35a1SLionel Sambuc.Fn ATF_REQUIRE_EQ "expression_1" "expression_2" 7711be35a1SLionel Sambuc.Fn ATF_REQUIRE_ERRNO "exp_errno" "bool_expression" 7811be35a1SLionel Sambuc.Fn ATF_REQUIRE_IN "element" "collection" 7911be35a1SLionel Sambuc.Fn ATF_REQUIRE_MATCH "regexp" "string_expression" 8011be35a1SLionel Sambuc.Fn ATF_REQUIRE_NOT_IN "element" "collection" 8111be35a1SLionel Sambuc.Fn ATF_REQUIRE_THROW "expected_exception" "statement" 8211be35a1SLionel Sambuc.Fn ATF_REQUIRE_THROW_RE "expected_exception" "regexp" "statement" 8311be35a1SLionel Sambuc.Fn ATF_SKIP "reason" 8411be35a1SLionel Sambuc.Fn ATF_TEST_CASE "name" 8511be35a1SLionel Sambuc.Fn ATF_TEST_CASE_BODY "name" 8611be35a1SLionel Sambuc.Fn ATF_TEST_CASE_CLEANUP "name" 8711be35a1SLionel Sambuc.Fn ATF_TEST_CASE_HEAD "name" 8811be35a1SLionel Sambuc.Fn ATF_TEST_CASE_NAME "name" 8911be35a1SLionel Sambuc.Fn ATF_TEST_CASE_USE "name" 9011be35a1SLionel Sambuc.Fn ATF_TEST_CASE_WITH_CLEANUP "name" 9111be35a1SLionel Sambuc.Fn ATF_TEST_CASE_WITHOUT_HEAD "name" 9211be35a1SLionel Sambuc.Ft void 9311be35a1SLionel Sambuc.Fo atf::utils::cat_file 9411be35a1SLionel Sambuc.Fa "const std::string& path" 9511be35a1SLionel Sambuc.Fa "const std::string& prefix" 9611be35a1SLionel Sambuc.Fc 9711be35a1SLionel Sambuc.Ft bool 9811be35a1SLionel Sambuc.Fo atf::utils::compare_file 9911be35a1SLionel Sambuc.Fa "const std::string& path" 10011be35a1SLionel Sambuc.Fa "const std::string& contents" 10111be35a1SLionel Sambuc.Fc 10211be35a1SLionel Sambuc.Ft void 10311be35a1SLionel Sambuc.Fo atf::utils::copy_file 10411be35a1SLionel Sambuc.Fa "const std::string& source" 10511be35a1SLionel Sambuc.Fa "const std::string& destination" 10611be35a1SLionel Sambuc.Fc 10711be35a1SLionel Sambuc.Ft void 10811be35a1SLionel Sambuc.Fo atf::utils::create_file 10911be35a1SLionel Sambuc.Fa "const std::string& path" 11011be35a1SLionel Sambuc.Fa "const std::string& contents" 11111be35a1SLionel Sambuc.Fc 11211be35a1SLionel Sambuc.Ft void 11311be35a1SLionel Sambuc.Fo atf::utils::file_exists 11411be35a1SLionel Sambuc.Fa "const std::string& path" 11511be35a1SLionel Sambuc.Fc 11611be35a1SLionel Sambuc.Ft pid_t 11711be35a1SLionel Sambuc.Fo atf::utils::fork 11811be35a1SLionel Sambuc.Fa "void" 11911be35a1SLionel Sambuc.Fc 12011be35a1SLionel Sambuc.Ft bool 12111be35a1SLionel Sambuc.Fo atf::utils::grep_collection 12211be35a1SLionel Sambuc.Fa "const std::string& regexp" 12311be35a1SLionel Sambuc.Fa "const Collection& collection" 12411be35a1SLionel Sambuc.Fc 12511be35a1SLionel Sambuc.Ft bool 12611be35a1SLionel Sambuc.Fo atf::utils::grep_file 12711be35a1SLionel Sambuc.Fa "const std::string& regexp" 12811be35a1SLionel Sambuc.Fa "const std::string& path" 12911be35a1SLionel Sambuc.Fc 13011be35a1SLionel Sambuc.Ft bool 13111be35a1SLionel Sambuc.Fo atf::utils::grep_string 13211be35a1SLionel Sambuc.Fa "const std::string& regexp" 13311be35a1SLionel Sambuc.Fa "const std::string& path" 13411be35a1SLionel Sambuc.Fc 13511be35a1SLionel Sambuc.Ft void 13611be35a1SLionel Sambuc.Fo atf::utils::redirect 13711be35a1SLionel Sambuc.Fa "const int fd" 13811be35a1SLionel Sambuc.Fa "const std::string& path" 13911be35a1SLionel Sambuc.Fc 14011be35a1SLionel Sambuc.Ft void 14111be35a1SLionel Sambuc.Fo atf::utils::wait 14211be35a1SLionel Sambuc.Fa "const pid_t pid" 14311be35a1SLionel Sambuc.Fa "const int expected_exit_status" 14411be35a1SLionel Sambuc.Fa "const std::string& expected_stdout" 14511be35a1SLionel Sambuc.Fa "const std::string& expected_stderr" 14611be35a1SLionel Sambuc.Fc 14711be35a1SLionel Sambuc.Sh DESCRIPTION 148*0a6a1f1dSLionel SambucATF provides a C++ programming interface to implement test programs. 149*0a6a1f1dSLionel SambucC++-based test programs follow this template: 15011be35a1SLionel Sambuc.Bd -literal -offset indent 15111be35a1SLionel Sambucextern "C" { 15211be35a1SLionel Sambuc.Ns ... C-specific includes go here ... 15311be35a1SLionel Sambuc} 15411be35a1SLionel Sambuc 15511be35a1SLionel Sambuc.Ns ... C++-specific includes go here ... 15611be35a1SLionel Sambuc 15711be35a1SLionel Sambuc#include <atf-c++.hpp> 15811be35a1SLionel Sambuc 15911be35a1SLionel SambucATF_TEST_CASE(tc1); 16011be35a1SLionel SambucATF_TEST_CASE_HEAD(tc1) 16111be35a1SLionel Sambuc{ 16211be35a1SLionel Sambuc ... first test case's header ... 16311be35a1SLionel Sambuc} 16411be35a1SLionel SambucATF_TEST_CASE_BODY(tc1) 16511be35a1SLionel Sambuc{ 16611be35a1SLionel Sambuc ... first test case's body ... 16711be35a1SLionel Sambuc} 16811be35a1SLionel Sambuc 16911be35a1SLionel SambucATF_TEST_CASE_WITH_CLEANUP(tc2); 17011be35a1SLionel SambucATF_TEST_CASE_HEAD(tc2) 17111be35a1SLionel Sambuc{ 17211be35a1SLionel Sambuc ... second test case's header ... 17311be35a1SLionel Sambuc} 17411be35a1SLionel SambucATF_TEST_CASE_BODY(tc2) 17511be35a1SLionel Sambuc{ 17611be35a1SLionel Sambuc ... second test case's body ... 17711be35a1SLionel Sambuc} 17811be35a1SLionel SambucATF_TEST_CASE_CLEANUP(tc2) 17911be35a1SLionel Sambuc{ 18011be35a1SLionel Sambuc ... second test case's cleanup ... 18111be35a1SLionel Sambuc} 18211be35a1SLionel Sambuc 18311be35a1SLionel SambucATF_TEST_CASE(tc3); 18411be35a1SLionel SambucATF_TEST_CASE_BODY(tc3) 18511be35a1SLionel Sambuc{ 18611be35a1SLionel Sambuc ... third test case's body ... 18711be35a1SLionel Sambuc} 18811be35a1SLionel Sambuc 18911be35a1SLionel Sambuc.Ns ... additional test cases ... 19011be35a1SLionel Sambuc 19111be35a1SLionel SambucATF_INIT_TEST_CASES(tcs) 19211be35a1SLionel Sambuc{ 19311be35a1SLionel Sambuc ATF_ADD_TEST_CASE(tcs, tc1); 19411be35a1SLionel Sambuc ATF_ADD_TEST_CASE(tcs, tc2); 19511be35a1SLionel Sambuc ATF_ADD_TEST_CASE(tcs, tc3); 19611be35a1SLionel Sambuc ... add additional test cases ... 19711be35a1SLionel Sambuc} 19811be35a1SLionel Sambuc.Ed 19911be35a1SLionel Sambuc.Ss Definition of test cases 20011be35a1SLionel SambucTest cases have an identifier and are composed of three different parts: 20111be35a1SLionel Sambucthe header, the body and an optional cleanup routine, all of which are 20211be35a1SLionel Sambucdescribed in 20311be35a1SLionel Sambuc.Xr atf-test-case 4 . 20411be35a1SLionel SambucTo define test cases, one can use the 20511be35a1SLionel Sambuc.Fn ATF_TEST_CASE , 20611be35a1SLionel Sambuc.Fn ATF_TEST_CASE_WITH_CLEANUP 20711be35a1SLionel Sambucor the 20811be35a1SLionel Sambuc.Fn ATF_TEST_CASE_WITHOUT_HEAD 20911be35a1SLionel Sambucmacros, which take a single parameter specifiying the test case's 21011be35a1SLionel Sambucname. 21111be35a1SLionel Sambuc.Fn ATF_TEST_CASE , 21211be35a1SLionel Sambucrequires to define a head and a body for the test case, 21311be35a1SLionel Sambuc.Fn ATF_TEST_CASE_WITH_CLEANUP 21411be35a1SLionel Sambucrequires to define a head, a body and a cleanup for the test case and 21511be35a1SLionel Sambuc.Fn ATF_TEST_CASE_WITHOUT_HEAD 21611be35a1SLionel Sambucrequires only a body for the test case. 21711be35a1SLionel SambucIt is important to note that these 21811be35a1SLionel Sambuc.Em do not 21911be35a1SLionel Sambucset the test case up for execution when the program is run. 22011be35a1SLionel SambucIn order to do so, a later registration is needed through the 22111be35a1SLionel Sambuc.Fn ATF_ADD_TEST_CASE 22211be35a1SLionel Sambucmacro detailed in 22311be35a1SLionel Sambuc.Sx Program initialization . 22411be35a1SLionel Sambuc.Pp 22511be35a1SLionel SambucLater on, one must define the three parts of the body by means of three 22611be35a1SLionel Sambucfunctions. 22711be35a1SLionel SambucTheir headers are given by the 22811be35a1SLionel Sambuc.Fn ATF_TEST_CASE_HEAD , 22911be35a1SLionel Sambuc.Fn ATF_TEST_CASE_BODY 23011be35a1SLionel Sambucand 23111be35a1SLionel Sambuc.Fn ATF_TEST_CASE_CLEANUP 23211be35a1SLionel Sambucmacros, all of which take the test case's name. 23311be35a1SLionel SambucFollowing each of these, a block of code is expected, surrounded by the 23411be35a1SLionel Sambucopening and closing brackets. 23511be35a1SLionel Sambuc.Pp 23611be35a1SLionel SambucAdditionally, the 23711be35a1SLionel Sambuc.Fn ATF_TEST_CASE_NAME 23811be35a1SLionel Sambucmacro can be used to obtain the name of the class corresponding to a 23911be35a1SLionel Sambucparticular test case, as the name is internally manged by the library to 24011be35a1SLionel Sambucprevent clashes with other user identifiers. 24111be35a1SLionel SambucSimilarly, the 24211be35a1SLionel Sambuc.Fn ATF_TEST_CASE_USE 24311be35a1SLionel Sambucmacro can be executed on a particular test case to mark it as "used" and 24411be35a1SLionel Sambucthus prevent compiler warnings regarding unused symbols. 24511be35a1SLionel SambucNote that 24611be35a1SLionel Sambuc.Em you should never have to use these macros during regular operation. 24711be35a1SLionel Sambuc.Ss Program initialization 24811be35a1SLionel SambucThe library provides a way to easily define the test program's 24911be35a1SLionel Sambuc.Fn main 25011be35a1SLionel Sambucfunction. 25111be35a1SLionel SambucYou should never define one on your own, but rely on the 25211be35a1SLionel Sambuclibrary to do it for you. 25311be35a1SLionel SambucThis is done by using the 25411be35a1SLionel Sambuc.Fn ATF_INIT_TEST_CASES 25511be35a1SLionel Sambucmacro, which is passed the name of the list that will hold the test cases. 25611be35a1SLionel SambucThis name can be whatever you want as long as it is a valid variable value. 25711be35a1SLionel Sambuc.Pp 25811be35a1SLionel SambucAfter the macro, you are supposed to provide the body of a function, which 25911be35a1SLionel Sambucshould only use the 26011be35a1SLionel Sambuc.Fn ATF_ADD_TEST_CASE 26111be35a1SLionel Sambucmacro to register the test cases the test program will execute. 26211be35a1SLionel SambucThe first parameter of this macro matches the name you provided in the 26311be35a1SLionel Sambucformer call. 26411be35a1SLionel Sambuc.Ss Header definitions 26511be35a1SLionel SambucThe test case's header can define the meta-data by using the 26611be35a1SLionel Sambuc.Fn set_md_var 26711be35a1SLionel Sambucmethod, which takes two parameters: the first one specifies the 26811be35a1SLionel Sambucmeta-data variable to be set and the second one specifies its value. 26911be35a1SLionel SambucBoth of them are strings. 27011be35a1SLionel Sambuc.Ss Configuration variables 27111be35a1SLionel SambucThe test case has read-only access to the current configuration variables 27211be35a1SLionel Sambucby means of the 27311be35a1SLionel Sambuc.Ft bool 27411be35a1SLionel Sambuc.Fn has_config_var 27511be35a1SLionel Sambucand the 27611be35a1SLionel Sambuc.Ft std::string 27711be35a1SLionel Sambuc.Fn get_config_var 27811be35a1SLionel Sambucmethods, which can be called in any of the three parts of a test case. 27911be35a1SLionel Sambuc.Ss Access to the source directory 28011be35a1SLionel SambucIt is possible to get the path to the test case's source directory from any 28111be35a1SLionel Sambucof its three components by querying the 28211be35a1SLionel Sambuc.Sq srcdir 28311be35a1SLionel Sambucconfiguration variable. 28411be35a1SLionel Sambuc.Ss Requiring programs 28511be35a1SLionel SambucAside from the 28611be35a1SLionel Sambuc.Va require.progs 28711be35a1SLionel Sambucmeta-data variable available in the header only, one can also check for 28811be35a1SLionel Sambucadditional programs in the test case's body by using the 28911be35a1SLionel Sambuc.Fn require_prog 29011be35a1SLionel Sambucfunction, which takes the base name or full path of a single binary. 29111be35a1SLionel SambucRelative paths are forbidden. 29211be35a1SLionel SambucIf it is not found, the test case will be automatically skipped. 29311be35a1SLionel Sambuc.Ss Test case finalization 29411be35a1SLionel SambucThe test case finalizes either when the body reaches its end, at which 29511be35a1SLionel Sambucpoint the test is assumed to have 29611be35a1SLionel Sambuc.Em passed , 29711be35a1SLionel Sambucor at any explicit call to 29811be35a1SLionel Sambuc.Fn ATF_PASS , 29911be35a1SLionel Sambuc.Fn ATF_FAIL 30011be35a1SLionel Sambucor 30111be35a1SLionel Sambuc.Fn ATF_SKIP . 30211be35a1SLionel SambucThese three macros terminate the execution of the test case immediately. 30311be35a1SLionel SambucThe cleanup routine will be processed afterwards in a completely automated 30411be35a1SLionel Sambucway, regardless of the test case's termination reason. 30511be35a1SLionel Sambuc.Pp 30611be35a1SLionel Sambuc.Fn ATF_PASS 30711be35a1SLionel Sambucdoes not take any parameters. 30811be35a1SLionel Sambuc.Fn ATF_FAIL 30911be35a1SLionel Sambucand 31011be35a1SLionel Sambuc.Fn ATF_SKIP 31111be35a1SLionel Sambuctake a single string that describes why the test case failed or 31211be35a1SLionel Sambucwas skipped, respectively. 31311be35a1SLionel SambucIt is very important to provide a clear error message in both cases so that 31411be35a1SLionel Sambucthe user can quickly know why the test did not pass. 31511be35a1SLionel Sambuc.Ss Expectations 31611be35a1SLionel SambucEverything explained in the previous section changes when the test case 31711be35a1SLionel Sambucexpectations are redefined by the programmer. 31811be35a1SLionel Sambuc.Pp 31911be35a1SLionel SambucEach test case has an internal state called 32011be35a1SLionel Sambuc.Sq expect 32111be35a1SLionel Sambucthat describes what the test case expectations are at any point in time. 32211be35a1SLionel SambucThe value of this property can change during execution by any of: 32311be35a1SLionel Sambuc.Bl -tag -width indent 32411be35a1SLionel Sambuc.It Fn expect_death "reason" 32511be35a1SLionel SambucExpects the test case to exit prematurely regardless of the nature of the 32611be35a1SLionel Sambucexit. 32711be35a1SLionel Sambuc.It Fn expect_exit "exitcode" "reason" 32811be35a1SLionel SambucExpects the test case to exit cleanly. 32911be35a1SLionel SambucIf 33011be35a1SLionel Sambuc.Va exitcode 33111be35a1SLionel Sambucis not 33211be35a1SLionel Sambuc.Sq -1 , 33311be35a1SLionel Sambuc.Xr atf-run 1 33411be35a1SLionel Sambucwill validate that the exit code of the test case matches the one provided 33511be35a1SLionel Sambucin this call. 33611be35a1SLionel SambucOtherwise, the exact value will be ignored. 33711be35a1SLionel Sambuc.It Fn expect_fail "reason" 33811be35a1SLionel SambucAny failure (be it fatal or non-fatal) raised in this mode is recorded. 33911be35a1SLionel SambucHowever, such failures do not report the test case as failed; instead, the 34011be35a1SLionel Sambuctest case finalizes cleanly and is reported as 34111be35a1SLionel Sambuc.Sq expected failure ; 34211be35a1SLionel Sambucthis report includes the provided 34311be35a1SLionel Sambuc.Fa reason 34411be35a1SLionel Sambucas part of it. 34511be35a1SLionel SambucIf no error is raised while running in this mode, then the test case is 34611be35a1SLionel Sambucreported as 34711be35a1SLionel Sambuc.Sq failed . 34811be35a1SLionel Sambuc.Pp 34911be35a1SLionel SambucThis mode is useful to reproduce actual known bugs in tests. 35011be35a1SLionel SambucWhenever the developer fixes the bug later on, the test case will start 35111be35a1SLionel Sambucreporting a failure, signaling the developer that the test case must be 35211be35a1SLionel Sambucadjusted to the new conditions. 35311be35a1SLionel SambucIn this situation, it is useful, for example, to set 35411be35a1SLionel Sambuc.Fa reason 35511be35a1SLionel Sambucas the bug number for tracking purposes. 35611be35a1SLionel Sambuc.It Fn expect_pass 35711be35a1SLionel SambucThis is the normal mode of execution. 35811be35a1SLionel SambucIn this mode, any failure is reported as such to the user and the test case 35911be35a1SLionel Sambucis marked as 36011be35a1SLionel Sambuc.Sq failed . 36111be35a1SLionel Sambuc.It Fn expect_race "reason" 36211be35a1SLionel SambucAny failure or timeout during the execution of the test case will be 36311be35a1SLionel Sambucconsidered as if a race condition has been triggered and reported as such. 36411be35a1SLionel SambucIf no problems arise, the test will continue execution as usual. 36511be35a1SLionel Sambuc.It Fn expect_signal "signo" "reason" 36611be35a1SLionel SambucExpects the test case to terminate due to the reception of a signal. 36711be35a1SLionel SambucIf 36811be35a1SLionel Sambuc.Va signo 36911be35a1SLionel Sambucis not 37011be35a1SLionel Sambuc.Sq -1 , 37111be35a1SLionel Sambuc.Xr atf-run 1 37211be35a1SLionel Sambucwill validate that the signal that terminated the test case matches the one 37311be35a1SLionel Sambucprovided in this call. 37411be35a1SLionel SambucOtherwise, the exact value will be ignored. 37511be35a1SLionel Sambuc.It Fn expect_timeout "reason" 37611be35a1SLionel SambucExpects the test case to execute for longer than its timeout. 37711be35a1SLionel Sambuc.El 37811be35a1SLionel Sambuc.Ss Helper macros for common checks 37911be35a1SLionel SambucThe library provides several macros that are very handy in multiple 38011be35a1SLionel Sambucsituations. 38111be35a1SLionel SambucThese basically check some condition after executing a given statement or 38211be35a1SLionel Sambucprocessing a given expression and, if the condition is not met, they 38311be35a1SLionel Sambucautomatically call 38411be35a1SLionel Sambuc.Fn ATF_FAIL 38511be35a1SLionel Sambucwith an appropriate error message. 38611be35a1SLionel Sambuc.Pp 38711be35a1SLionel Sambuc.Fn ATF_REQUIRE 38811be35a1SLionel Sambuctakes an expression and raises a failure if it evaluates to false. 38911be35a1SLionel Sambuc.Pp 39011be35a1SLionel Sambuc.Fn ATF_REQUIRE_EQ 39111be35a1SLionel Sambuctakes two expressions and raises a failure if the two do not evaluate to 39211be35a1SLionel Sambucthe same exact value. 39311be35a1SLionel Sambuc.Pp 39411be35a1SLionel Sambuc.Fn ATF_REQUIRE_IN 39511be35a1SLionel Sambuctakes an element and a collection and validates that the element is present in 39611be35a1SLionel Sambucthe collection. 39711be35a1SLionel Sambuc.Pp 39811be35a1SLionel Sambuc.Fn ATF_REQUIRE_MATCH 39911be35a1SLionel Sambuctakes a regular expression and a string and raises a failure if the regular 40011be35a1SLionel Sambucexpression does not match the string. 40111be35a1SLionel Sambuc.Pp 40211be35a1SLionel Sambuc.Fn ATF_REQUIRE_NOT_IN 40311be35a1SLionel Sambuctakes an element and a collection and validates that the element is not present 40411be35a1SLionel Sambucin the collection. 40511be35a1SLionel Sambuc.Pp 40611be35a1SLionel Sambuc.Fn ATF_REQUIRE_THROW 40711be35a1SLionel Sambuctakes the name of an exception and a statement and raises a failure if 40811be35a1SLionel Sambucthe statement does not throw the specified exception. 40911be35a1SLionel Sambuc.Fn ATF_REQUIRE_THROW_RE 41011be35a1SLionel Sambuctakes the name of an exception, a regular expresion and a statement and raises a 41111be35a1SLionel Sambucfailure if the statement does not throw the specified exception and if the 41211be35a1SLionel Sambucmessage of the exception does not match the regular expression. 41311be35a1SLionel Sambuc.Pp 41411be35a1SLionel Sambuc.Fn ATF_CHECK_ERRNO 41511be35a1SLionel Sambucand 41611be35a1SLionel Sambuc.Fn ATF_REQUIRE_ERRNO 41711be35a1SLionel Sambuctake, first, the error code that the check is expecting to find in the 41811be35a1SLionel Sambuc.Va errno 41911be35a1SLionel Sambucvariable and, second, a boolean expression that, if evaluates to true, 42011be35a1SLionel Sambucmeans that a call failed and 42111be35a1SLionel Sambuc.Va errno 42211be35a1SLionel Sambuchas to be checked against the first value. 42311be35a1SLionel Sambuc.Ss Utility functions 42411be35a1SLionel SambucThe following functions are provided as part of the 42511be35a1SLionel Sambuc.Nm 42611be35a1SLionel SambucAPI to simplify the creation of a variety of tests. 42711be35a1SLionel SambucIn particular, these are useful to write tests for command-line interfaces. 42811be35a1SLionel Sambuc.Pp 42911be35a1SLionel Sambuc.Ft void 43011be35a1SLionel Sambuc.Fo atf::utils::cat_file 43111be35a1SLionel Sambuc.Fa "const std::string& path" 43211be35a1SLionel Sambuc.Fa "const std::string& prefix" 43311be35a1SLionel Sambuc.Fc 434*0a6a1f1dSLionel Sambuc.Bd -ragged -offset indent 43511be35a1SLionel SambucPrints the contents of 43611be35a1SLionel Sambuc.Fa path 43711be35a1SLionel Sambucto the standard output, prefixing every line with the string in 43811be35a1SLionel Sambuc.Fa prefix . 43911be35a1SLionel Sambuc.Ed 44011be35a1SLionel Sambuc.Pp 44111be35a1SLionel Sambuc.Ft bool 44211be35a1SLionel Sambuc.Fo atf::utils::compare_file 44311be35a1SLionel Sambuc.Fa "const std::string& path" 44411be35a1SLionel Sambuc.Fa "const std::string& contents" 44511be35a1SLionel Sambuc.Fc 446*0a6a1f1dSLionel Sambuc.Bd -ragged -offset indent 44711be35a1SLionel SambucReturns true if the given 44811be35a1SLionel Sambuc.Fa path 44911be35a1SLionel Sambucmatches exactly the expected inlined 45011be35a1SLionel Sambuc.Fa contents . 45111be35a1SLionel Sambuc.Ed 45211be35a1SLionel Sambuc.Pp 45311be35a1SLionel Sambuc.Ft void 45411be35a1SLionel Sambuc.Fo atf::utils::copy_file 45511be35a1SLionel Sambuc.Fa "const std::string& source" 45611be35a1SLionel Sambuc.Fa "const std::string& destination" 45711be35a1SLionel Sambuc.Fc 458*0a6a1f1dSLionel Sambuc.Bd -ragged -offset indent 45911be35a1SLionel SambucCopies the file 46011be35a1SLionel Sambuc.Fa source 46111be35a1SLionel Sambucto 46211be35a1SLionel Sambuc.Fa destination . 46311be35a1SLionel SambucThe permissions of the file are preserved during the code. 46411be35a1SLionel Sambuc.Ed 46511be35a1SLionel Sambuc.Pp 46611be35a1SLionel Sambuc.Ft void 46711be35a1SLionel Sambuc.Fo atf::utils::create_file 46811be35a1SLionel Sambuc.Fa "const std::string& path" 46911be35a1SLionel Sambuc.Fa "const std::string& contents" 47011be35a1SLionel Sambuc.Fc 471*0a6a1f1dSLionel Sambuc.Bd -ragged -offset indent 47211be35a1SLionel SambucCreates 47311be35a1SLionel Sambuc.Fa file 47411be35a1SLionel Sambucwith the text given in 47511be35a1SLionel Sambuc.Fa contents . 47611be35a1SLionel Sambuc.Ed 47711be35a1SLionel Sambuc.Pp 47811be35a1SLionel Sambuc.Ft void 47911be35a1SLionel Sambuc.Fo atf::utils::file_exists 48011be35a1SLionel Sambuc.Fa "const std::string& path" 48111be35a1SLionel Sambuc.Fc 482*0a6a1f1dSLionel Sambuc.Bd -ragged -offset indent 48311be35a1SLionel SambucChecks if 48411be35a1SLionel Sambuc.Fa path 48511be35a1SLionel Sambucexists. 48611be35a1SLionel Sambuc.Ed 48711be35a1SLionel Sambuc.Pp 48811be35a1SLionel Sambuc.Ft pid_t 48911be35a1SLionel Sambuc.Fo atf::utils::fork 49011be35a1SLionel Sambuc.Fa "void" 49111be35a1SLionel Sambuc.Fc 492*0a6a1f1dSLionel Sambuc.Bd -ragged -offset indent 49311be35a1SLionel SambucForks a process and redirects the standard output and standard error of the 49411be35a1SLionel Sambucchild to files for later validation with 49511be35a1SLionel Sambuc.Fn atf::utils::wait . 49611be35a1SLionel SambucFails the test case if the fork fails, so this does not return an error. 49711be35a1SLionel Sambuc.Ed 49811be35a1SLionel Sambuc.Pp 49911be35a1SLionel Sambuc.Ft bool 50011be35a1SLionel Sambuc.Fo atf::utils::grep_collection 50111be35a1SLionel Sambuc.Fa "const std::string& regexp" 50211be35a1SLionel Sambuc.Fa "const Collection& collection" 50311be35a1SLionel Sambuc.Fc 504*0a6a1f1dSLionel Sambuc.Bd -ragged -offset indent 50511be35a1SLionel SambucSearches for the regular expression 50611be35a1SLionel Sambuc.Fa regexp 50711be35a1SLionel Sambucin any of the strings contained in the 50811be35a1SLionel Sambuc.Fa collection . 50911be35a1SLionel SambucThis is a template that accepts any one-dimensional container of strings. 51011be35a1SLionel Sambuc.Ed 51111be35a1SLionel Sambuc.Pp 51211be35a1SLionel Sambuc.Ft bool 51311be35a1SLionel Sambuc.Fo atf::utils::grep_file 51411be35a1SLionel Sambuc.Fa "const std::string& regexp" 51511be35a1SLionel Sambuc.Fa "const std::string& path" 51611be35a1SLionel Sambuc.Fc 517*0a6a1f1dSLionel Sambuc.Bd -ragged -offset indent 51811be35a1SLionel SambucSearches for the regular expression 51911be35a1SLionel Sambuc.Fa regexp 52011be35a1SLionel Sambucin the file 52111be35a1SLionel Sambuc.Fa path . 52211be35a1SLionel SambucThe variable arguments are used to construct the regular expression. 52311be35a1SLionel Sambuc.Ed 52411be35a1SLionel Sambuc.Pp 52511be35a1SLionel Sambuc.Ft bool 52611be35a1SLionel Sambuc.Fo atf::utils::grep_string 52711be35a1SLionel Sambuc.Fa "const std::string& regexp" 52811be35a1SLionel Sambuc.Fa "const std::string& str" 52911be35a1SLionel Sambuc.Fc 530*0a6a1f1dSLionel Sambuc.Bd -ragged -offset indent 53111be35a1SLionel SambucSearches for the regular expression 53211be35a1SLionel Sambuc.Fa regexp 53311be35a1SLionel Sambucin the string 53411be35a1SLionel Sambuc.Fa str . 53511be35a1SLionel Sambuc.Ed 53611be35a1SLionel Sambuc.Ft void 53711be35a1SLionel Sambuc.Fo atf::utils::redirect 53811be35a1SLionel Sambuc.Fa "const int fd" 53911be35a1SLionel Sambuc.Fa "const std::string& path" 54011be35a1SLionel Sambuc.Fc 541*0a6a1f1dSLionel Sambuc.Bd -ragged -offset indent 54211be35a1SLionel SambucRedirects the given file descriptor 54311be35a1SLionel Sambuc.Fa fd 54411be35a1SLionel Sambucto the file 54511be35a1SLionel Sambuc.Fa path . 54611be35a1SLionel SambucThis function exits the process in case of an error and does not properly mark 54711be35a1SLionel Sambucthe test case as failed. 54811be35a1SLionel SambucAs a result, it should only be used in subprocesses of the test case; specially 54911be35a1SLionel Sambucthose spawned by 55011be35a1SLionel Sambuc.Fn atf::utils::fork . 55111be35a1SLionel Sambuc.Ed 55211be35a1SLionel Sambuc.Pp 55311be35a1SLionel Sambuc.Ft void 55411be35a1SLionel Sambuc.Fo atf::utils::wait 55511be35a1SLionel Sambuc.Fa "const pid_t pid" 55611be35a1SLionel Sambuc.Fa "const int expected_exit_status" 55711be35a1SLionel Sambuc.Fa "const std::string& expected_stdout" 55811be35a1SLionel Sambuc.Fa "const std::string& expected_stderr" 55911be35a1SLionel Sambuc.Fc 560*0a6a1f1dSLionel Sambuc.Bd -ragged -offset indent 56111be35a1SLionel SambucWaits and validates the result of a subprocess spawned with 56211be35a1SLionel Sambuc.Fn atf::utils::wait . 56311be35a1SLionel SambucThe validation involves checking that the subprocess exited cleanly and returned 56411be35a1SLionel Sambucthe code specified in 56511be35a1SLionel Sambuc.Fa expected_exit_status 56611be35a1SLionel Sambucand that its standard output and standard error match the strings given in 56711be35a1SLionel Sambuc.Fa expected_stdout 56811be35a1SLionel Sambucand 56911be35a1SLionel Sambuc.Fa expected_stderr . 57011be35a1SLionel Sambuc.Pp 57111be35a1SLionel SambucIf any of the 57211be35a1SLionel Sambuc.Fa expected_stdout 57311be35a1SLionel Sambucor 57411be35a1SLionel Sambuc.Fa expected_stderr 57511be35a1SLionel Sambucstrings are prefixed with 57611be35a1SLionel Sambuc.Sq save: , 57711be35a1SLionel Sambucthen they specify the name of the file into which to store the stdout or stderr 57811be35a1SLionel Sambucof the subprocess, and no comparison is performed. 57911be35a1SLionel Sambuc.Ed 58011be35a1SLionel Sambuc.Sh EXAMPLES 58111be35a1SLionel SambucThe following shows a complete test program with a single test case that 58211be35a1SLionel Sambucvalidates the addition operator: 58311be35a1SLionel Sambuc.Bd -literal -offset indent 58411be35a1SLionel Sambuc#include <atf-c++.hpp> 58511be35a1SLionel Sambuc 58611be35a1SLionel SambucATF_TEST_CASE(addition); 58711be35a1SLionel SambucATF_TEST_CASE_HEAD(addition) 58811be35a1SLionel Sambuc{ 58911be35a1SLionel Sambuc set_md_var("descr", "Sample tests for the addition operator"); 59011be35a1SLionel Sambuc} 59111be35a1SLionel SambucATF_TEST_CASE_BODY(addition) 59211be35a1SLionel Sambuc{ 59311be35a1SLionel Sambuc ATF_REQUIRE_EQ(0 + 0, 0); 59411be35a1SLionel Sambuc ATF_REQUIRE_EQ(0 + 1, 1); 59511be35a1SLionel Sambuc ATF_REQUIRE_EQ(1 + 0, 1); 59611be35a1SLionel Sambuc 59711be35a1SLionel Sambuc ATF_REQUIRE_EQ(1 + 1, 2); 59811be35a1SLionel Sambuc 59911be35a1SLionel Sambuc ATF_REQUIRE_EQ(100 + 200, 300); 60011be35a1SLionel Sambuc} 60111be35a1SLionel Sambuc 60211be35a1SLionel SambucATF_TEST_CASE(open_failure); 60311be35a1SLionel SambucATF_TEST_CASE_HEAD(open_failure) 60411be35a1SLionel Sambuc{ 60511be35a1SLionel Sambuc set_md_var("descr", "Sample tests for the open function"); 60611be35a1SLionel Sambuc} 60711be35a1SLionel SambucATF_TEST_CASE_BODY(open_failure) 60811be35a1SLionel Sambuc{ 60911be35a1SLionel Sambuc ATF_REQUIRE_ERRNO(ENOENT, open("non-existent", O_RDONLY) == -1); 61011be35a1SLionel Sambuc} 61111be35a1SLionel Sambuc 61211be35a1SLionel SambucATF_TEST_CASE(known_bug); 61311be35a1SLionel SambucATF_TEST_CASE_HEAD(known_bug) 61411be35a1SLionel Sambuc{ 61511be35a1SLionel Sambuc set_md_var("descr", "Reproduces a known bug"); 61611be35a1SLionel Sambuc} 61711be35a1SLionel SambucATF_TEST_CASE_BODY(known_bug) 61811be35a1SLionel Sambuc{ 61911be35a1SLionel Sambuc expect_fail("See bug number foo/bar"); 62011be35a1SLionel Sambuc ATF_REQUIRE_EQ(3, 1 + 1); 62111be35a1SLionel Sambuc expect_pass(); 62211be35a1SLionel Sambuc ATF_REQUIRE_EQ(3, 1 + 2); 62311be35a1SLionel Sambuc} 62411be35a1SLionel Sambuc 62511be35a1SLionel SambucATF_INIT_TEST_CASES(tcs) 62611be35a1SLionel Sambuc{ 62711be35a1SLionel Sambuc ATF_ADD_TEST_CASE(tcs, addition); 62811be35a1SLionel Sambuc ATF_ADD_TEST_CASE(tcs, open_failure); 62911be35a1SLionel Sambuc ATF_ADD_TEST_CASE(tcs, known_bug); 63011be35a1SLionel Sambuc} 63111be35a1SLionel Sambuc.Ed 63211be35a1SLionel Sambuc.Sh SEE ALSO 63311be35a1SLionel Sambuc.Xr atf-test-program 1 , 63411be35a1SLionel Sambuc.Xr atf-test-case 4 , 63511be35a1SLionel Sambuc.Xr atf 7 636