1*00b67f09SDavid van Moolenbroek.\" $NetBSD: atf-c-api.3,v 1.3 2014/12/10 04:38:03 christos Exp $ 2*00b67f09SDavid van Moolenbroek.\" 3*00b67f09SDavid van Moolenbroek.\" 4*00b67f09SDavid van Moolenbroek.\" Automated Testing Framework (atf) 5*00b67f09SDavid van Moolenbroek.\" 6*00b67f09SDavid van Moolenbroek.\" Copyright (c) 2008 The NetBSD Foundation, Inc. 7*00b67f09SDavid van Moolenbroek.\" All rights reserved. 8*00b67f09SDavid van Moolenbroek.\" 9*00b67f09SDavid van Moolenbroek.\" Redistribution and use in source and binary forms, with or without 10*00b67f09SDavid van Moolenbroek.\" modification, are permitted provided that the following conditions 11*00b67f09SDavid van Moolenbroek.\" are met: 12*00b67f09SDavid van Moolenbroek.\" 1. Redistributions of source code must retain the above copyright 13*00b67f09SDavid van Moolenbroek.\" notice, this list of conditions and the following disclaimer. 14*00b67f09SDavid van Moolenbroek.\" 2. Redistributions in binary form must reproduce the above copyright 15*00b67f09SDavid van Moolenbroek.\" notice, this list of conditions and the following disclaimer in the 16*00b67f09SDavid van Moolenbroek.\" documentation and/or other materials provided with the distribution. 17*00b67f09SDavid van Moolenbroek.\" 18*00b67f09SDavid van Moolenbroek.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND 19*00b67f09SDavid van Moolenbroek.\" CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 20*00b67f09SDavid van Moolenbroek.\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 21*00b67f09SDavid van Moolenbroek.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22*00b67f09SDavid van Moolenbroek.\" IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY 23*00b67f09SDavid van Moolenbroek.\" DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24*00b67f09SDavid van Moolenbroek.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 25*00b67f09SDavid van Moolenbroek.\" GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26*00b67f09SDavid van Moolenbroek.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 27*00b67f09SDavid van Moolenbroek.\" IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 28*00b67f09SDavid van Moolenbroek.\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 29*00b67f09SDavid van Moolenbroek.\" IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30*00b67f09SDavid van Moolenbroek.\" 31*00b67f09SDavid van Moolenbroek.Dd November 30, 2012 32*00b67f09SDavid van Moolenbroek.Dt ATF-C-API 3 33*00b67f09SDavid van Moolenbroek.Os 34*00b67f09SDavid van Moolenbroek.Sh NAME 35*00b67f09SDavid van Moolenbroek.Nm atf-c-api , 36*00b67f09SDavid van Moolenbroek.Nm ATF_CHECK , 37*00b67f09SDavid van Moolenbroek.Nm ATF_CHECK_MSG , 38*00b67f09SDavid van Moolenbroek.Nm ATF_CHECK_EQ , 39*00b67f09SDavid van Moolenbroek.Nm ATF_CHECK_EQ_MSG , 40*00b67f09SDavid van Moolenbroek.Nm ATF_CHECK_MATCH , 41*00b67f09SDavid van Moolenbroek.Nm ATF_CHECK_MATCH_MSG , 42*00b67f09SDavid van Moolenbroek.Nm ATF_CHECK_STREQ , 43*00b67f09SDavid van Moolenbroek.Nm ATF_CHECK_STREQ_MSG , 44*00b67f09SDavid van Moolenbroek.Nm ATF_CHECK_ERRNO , 45*00b67f09SDavid van Moolenbroek.Nm ATF_REQUIRE , 46*00b67f09SDavid van Moolenbroek.Nm ATF_REQUIRE_MSG , 47*00b67f09SDavid van Moolenbroek.Nm ATF_REQUIRE_EQ , 48*00b67f09SDavid van Moolenbroek.Nm ATF_REQUIRE_EQ_MSG , 49*00b67f09SDavid van Moolenbroek.Nm ATF_REQUIRE_MATCH , 50*00b67f09SDavid van Moolenbroek.Nm ATF_REQUIRE_MATCH_MSG , 51*00b67f09SDavid van Moolenbroek.Nm ATF_REQUIRE_STREQ , 52*00b67f09SDavid van Moolenbroek.Nm ATF_REQUIRE_STREQ_MSG , 53*00b67f09SDavid van Moolenbroek.Nm ATF_REQUIRE_ERRNO , 54*00b67f09SDavid van Moolenbroek.Nm ATF_TC , 55*00b67f09SDavid van Moolenbroek.Nm ATF_TC_BODY , 56*00b67f09SDavid van Moolenbroek.Nm ATF_TC_BODY_NAME , 57*00b67f09SDavid van Moolenbroek.Nm ATF_TC_CLEANUP , 58*00b67f09SDavid van Moolenbroek.Nm ATF_TC_CLEANUP_NAME , 59*00b67f09SDavid van Moolenbroek.Nm ATF_TC_HEAD , 60*00b67f09SDavid van Moolenbroek.Nm ATF_TC_HEAD_NAME , 61*00b67f09SDavid van Moolenbroek.Nm ATF_TC_NAME , 62*00b67f09SDavid van Moolenbroek.Nm ATF_TC_WITH_CLEANUP , 63*00b67f09SDavid van Moolenbroek.Nm ATF_TC_WITHOUT_HEAD , 64*00b67f09SDavid van Moolenbroek.Nm ATF_TP_ADD_TC , 65*00b67f09SDavid van Moolenbroek.Nm ATF_TP_ADD_TCS , 66*00b67f09SDavid van Moolenbroek.Nm atf_tc_get_config_var , 67*00b67f09SDavid van Moolenbroek.Nm atf_tc_get_config_var_wd , 68*00b67f09SDavid van Moolenbroek.Nm atf_tc_get_config_var_as_bool , 69*00b67f09SDavid van Moolenbroek.Nm atf_tc_get_config_var_as_bool_wd , 70*00b67f09SDavid van Moolenbroek.Nm atf_tc_get_config_var_as_long , 71*00b67f09SDavid van Moolenbroek.Nm atf_tc_get_config_var_as_long_wd , 72*00b67f09SDavid van Moolenbroek.Nm atf_no_error , 73*00b67f09SDavid van Moolenbroek.Nm atf_tc_expect_death , 74*00b67f09SDavid van Moolenbroek.Nm atf_tc_expect_exit , 75*00b67f09SDavid van Moolenbroek.Nm atf_tc_expect_fail , 76*00b67f09SDavid van Moolenbroek.Nm atf_tc_expect_pass , 77*00b67f09SDavid van Moolenbroek.Nm atf_tc_expect_signal , 78*00b67f09SDavid van Moolenbroek.Nm atf_tc_expect_timeout , 79*00b67f09SDavid van Moolenbroek.Nm atf_tc_fail , 80*00b67f09SDavid van Moolenbroek.Nm atf_tc_fail_nonfatal , 81*00b67f09SDavid van Moolenbroek.Nm atf_tc_pass , 82*00b67f09SDavid van Moolenbroek.Nm atf_tc_skip , 83*00b67f09SDavid van Moolenbroek.Nm atf_utils_cat_file , 84*00b67f09SDavid van Moolenbroek.Nm atf_utils_compare_file , 85*00b67f09SDavid van Moolenbroek.Nm atf_utils_copy_file , 86*00b67f09SDavid van Moolenbroek.Nm atf_utils_create_file , 87*00b67f09SDavid van Moolenbroek.Nm atf_utils_file_exists , 88*00b67f09SDavid van Moolenbroek.Nm atf_utils_fork , 89*00b67f09SDavid van Moolenbroek.Nm atf_utils_free_charpp , 90*00b67f09SDavid van Moolenbroek.Nm atf_utils_grep_file , 91*00b67f09SDavid van Moolenbroek.Nm atf_utils_grep_string , 92*00b67f09SDavid van Moolenbroek.Nm atf_utils_readline , 93*00b67f09SDavid van Moolenbroek.Nm atf_utils_redirect , 94*00b67f09SDavid van Moolenbroek.Nm atf_utils_wait 95*00b67f09SDavid van Moolenbroek.Nd C API to write ATF-based test programs 96*00b67f09SDavid van Moolenbroek.Sh SYNOPSIS 97*00b67f09SDavid van Moolenbroek.In atf-c.h 98*00b67f09SDavid van Moolenbroek.Fn ATF_CHECK "expression" 99*00b67f09SDavid van Moolenbroek.Fn ATF_CHECK_MSG "expression" "fail_msg_fmt" ... 100*00b67f09SDavid van Moolenbroek.Fn ATF_CHECK_EQ "expression_1" "expression_2" 101*00b67f09SDavid van Moolenbroek.Fn ATF_CHECK_EQ_MSG "expression_1" "expression_2" "fail_msg_fmt" ... 102*00b67f09SDavid van Moolenbroek.Fn ATF_CHECK_MATCH "regexp" "string" 103*00b67f09SDavid van Moolenbroek.Fn ATF_CHECK_MATCH_MSG "regexp" "string" "fail_msg_fmt" ... 104*00b67f09SDavid van Moolenbroek.Fn ATF_CHECK_STREQ "string_1" "string_2" 105*00b67f09SDavid van Moolenbroek.Fn ATF_CHECK_STREQ_MSG "string_1" "string_2" "fail_msg_fmt" ... 106*00b67f09SDavid van Moolenbroek.Fn ATF_CHECK_ERRNO "exp_errno" "bool_expression" 107*00b67f09SDavid van Moolenbroek.Fn ATF_REQUIRE "expression" 108*00b67f09SDavid van Moolenbroek.Fn ATF_REQUIRE_MSG "expression" "fail_msg_fmt" ... 109*00b67f09SDavid van Moolenbroek.Fn ATF_REQUIRE_EQ "expression_1" "expression_2" 110*00b67f09SDavid van Moolenbroek.Fn ATF_REQUIRE_EQ_MSG "expression_1" "expression_2" "fail_msg_fmt" ... 111*00b67f09SDavid van Moolenbroek.Fn ATF_REQUIRE_MATCH "regexp" "string" 112*00b67f09SDavid van Moolenbroek.Fn ATF_REQUIRE_MATCH_MSG "regexp" "string" "fail_msg_fmt" ... 113*00b67f09SDavid van Moolenbroek.Fn ATF_REQUIRE_STREQ "string_1" "string_2" 114*00b67f09SDavid van Moolenbroek.Fn ATF_REQUIRE_STREQ_MSG "string_1" "string_2" "fail_msg_fmt" ... 115*00b67f09SDavid van Moolenbroek.Fn ATF_REQUIRE_ERRNO "exp_errno" "bool_expression" 116*00b67f09SDavid van Moolenbroek.Fn ATF_TC "name" 117*00b67f09SDavid van Moolenbroek.Fn ATF_TC_BODY "name" "tc" 118*00b67f09SDavid van Moolenbroek.Fn ATF_TC_BODY_NAME "name" 119*00b67f09SDavid van Moolenbroek.Fn ATF_TC_CLEANUP "name" "tc" 120*00b67f09SDavid van Moolenbroek.Fn ATF_TC_CLEANUP_NAME "name" 121*00b67f09SDavid van Moolenbroek.Fn ATF_TC_HEAD "name" "tc" 122*00b67f09SDavid van Moolenbroek.Fn ATF_TC_HEAD_NAME "name" 123*00b67f09SDavid van Moolenbroek.Fn ATF_TC_NAME "name" 124*00b67f09SDavid van Moolenbroek.Fn ATF_TC_WITH_CLEANUP "name" 125*00b67f09SDavid van Moolenbroek.Fn ATF_TC_WITHOUT_HEAD "name" 126*00b67f09SDavid van Moolenbroek.Fn ATF_TP_ADD_TC "tp_name" "tc_name" 127*00b67f09SDavid van Moolenbroek.Fn ATF_TP_ADD_TCS "tp_name" 128*00b67f09SDavid van Moolenbroek.Fn atf_tc_get_config_var "tc" "varname" 129*00b67f09SDavid van Moolenbroek.Fn atf_tc_get_config_var_wd "tc" "variable_name" "default_value" 130*00b67f09SDavid van Moolenbroek.Fn atf_tc_get_config_var_as_bool "tc" "variable_name" 131*00b67f09SDavid van Moolenbroek.Fn atf_tc_get_config_var_as_bool_wd "tc" "variable_name" "default_value" 132*00b67f09SDavid van Moolenbroek.Fn atf_tc_get_config_var_as_long "tc" "variable_name" 133*00b67f09SDavid van Moolenbroek.Fn atf_tc_get_config_var_as_long_wd "tc" "variable_name" "default_value" 134*00b67f09SDavid van Moolenbroek.Fn atf_no_error 135*00b67f09SDavid van Moolenbroek.Fn atf_tc_expect_death "reason" "..." 136*00b67f09SDavid van Moolenbroek.Fn atf_tc_expect_exit "exitcode" "reason" "..." 137*00b67f09SDavid van Moolenbroek.Fn atf_tc_expect_fail "reason" "..." 138*00b67f09SDavid van Moolenbroek.Fn atf_tc_expect_pass 139*00b67f09SDavid van Moolenbroek.Fn atf_tc_expect_signal "signo" "reason" "..." 140*00b67f09SDavid van Moolenbroek.Fn atf_tc_expect_timeout "reason" "..." 141*00b67f09SDavid van Moolenbroek.Fn atf_tc_fail "reason" 142*00b67f09SDavid van Moolenbroek.Fn atf_tc_fail_nonfatal "reason" 143*00b67f09SDavid van Moolenbroek.Fn atf_tc_pass 144*00b67f09SDavid van Moolenbroek.Fn atf_tc_skip "reason" 145*00b67f09SDavid van Moolenbroek.Ft void 146*00b67f09SDavid van Moolenbroek.Fo atf_utils_cat_file 147*00b67f09SDavid van Moolenbroek.Fa "const char *file" 148*00b67f09SDavid van Moolenbroek.Fa "const char *prefix" 149*00b67f09SDavid van Moolenbroek.Fc 150*00b67f09SDavid van Moolenbroek.Ft bool 151*00b67f09SDavid van Moolenbroek.Fo atf_utils_compare_file 152*00b67f09SDavid van Moolenbroek.Fa "const char *file" 153*00b67f09SDavid van Moolenbroek.Fa "const char *contents" 154*00b67f09SDavid van Moolenbroek.Fc 155*00b67f09SDavid van Moolenbroek.Ft void 156*00b67f09SDavid van Moolenbroek.Fo atf_utils_copy_file 157*00b67f09SDavid van Moolenbroek.Fa "const char *source" 158*00b67f09SDavid van Moolenbroek.Fa "const char *destination" 159*00b67f09SDavid van Moolenbroek.Fc 160*00b67f09SDavid van Moolenbroek.Ft void 161*00b67f09SDavid van Moolenbroek.Fo atf_utils_create_file 162*00b67f09SDavid van Moolenbroek.Fa "const char *file" 163*00b67f09SDavid van Moolenbroek.Fa "const char *contents" 164*00b67f09SDavid van Moolenbroek.Fa "..." 165*00b67f09SDavid van Moolenbroek.Fc 166*00b67f09SDavid van Moolenbroek.Ft void 167*00b67f09SDavid van Moolenbroek.Fo atf_utils_file_exists 168*00b67f09SDavid van Moolenbroek.Fa "const char *file" 169*00b67f09SDavid van Moolenbroek.Fc 170*00b67f09SDavid van Moolenbroek.Ft pid_t 171*00b67f09SDavid van Moolenbroek.Fo atf_utils_fork 172*00b67f09SDavid van Moolenbroek.Fa "void" 173*00b67f09SDavid van Moolenbroek.Fc 174*00b67f09SDavid van Moolenbroek.Ft void 175*00b67f09SDavid van Moolenbroek.Fo atf_utils_free_charpp 176*00b67f09SDavid van Moolenbroek.Fa "char **argv" 177*00b67f09SDavid van Moolenbroek.Fc 178*00b67f09SDavid van Moolenbroek.Ft bool 179*00b67f09SDavid van Moolenbroek.Fo atf_utils_grep_file 180*00b67f09SDavid van Moolenbroek.Fa "const char *regexp" 181*00b67f09SDavid van Moolenbroek.Fa "const char *file" 182*00b67f09SDavid van Moolenbroek.Fa "..." 183*00b67f09SDavid van Moolenbroek.Fc 184*00b67f09SDavid van Moolenbroek.Ft bool 185*00b67f09SDavid van Moolenbroek.Fo atf_utils_grep_string 186*00b67f09SDavid van Moolenbroek.Fa "const char *regexp" 187*00b67f09SDavid van Moolenbroek.Fa "const char *str" 188*00b67f09SDavid van Moolenbroek.Fa "..." 189*00b67f09SDavid van Moolenbroek.Fc 190*00b67f09SDavid van Moolenbroek.Ft char * 191*00b67f09SDavid van Moolenbroek.Fo atf_utils_readline 192*00b67f09SDavid van Moolenbroek.Fa "int fd" 193*00b67f09SDavid van Moolenbroek.Fc 194*00b67f09SDavid van Moolenbroek.Ft void 195*00b67f09SDavid van Moolenbroek.Fo atf_utils_redirect 196*00b67f09SDavid van Moolenbroek.Fa "const int fd" 197*00b67f09SDavid van Moolenbroek.Fa "const char *file" 198*00b67f09SDavid van Moolenbroek.Fc 199*00b67f09SDavid van Moolenbroek.Ft void 200*00b67f09SDavid van Moolenbroek.Fo atf_utils_wait 201*00b67f09SDavid van Moolenbroek.Fa "const pid_t pid" 202*00b67f09SDavid van Moolenbroek.Fa "const int expected_exit_status" 203*00b67f09SDavid van Moolenbroek.Fa "const char *expected_stdout" 204*00b67f09SDavid van Moolenbroek.Fa "const char *expected_stderr" 205*00b67f09SDavid van Moolenbroek.Fc 206*00b67f09SDavid van Moolenbroek.Sh DESCRIPTION 207*00b67f09SDavid van MoolenbroekThe ATF 208*00b67f09SDavid van Moolenbroek.Pp 209*00b67f09SDavid van MoolenbroekC-based test programs always follow this template: 210*00b67f09SDavid van Moolenbroek.Bd -literal -offset indent 211*00b67f09SDavid van Moolenbroek.Ns ... C-specific includes go here ... 212*00b67f09SDavid van Moolenbroek 213*00b67f09SDavid van Moolenbroek#include <atf-c.h> 214*00b67f09SDavid van Moolenbroek 215*00b67f09SDavid van MoolenbroekATF_TC(tc1); 216*00b67f09SDavid van MoolenbroekATF_TC_HEAD(tc1, tc) 217*00b67f09SDavid van Moolenbroek{ 218*00b67f09SDavid van Moolenbroek ... first test case's header ... 219*00b67f09SDavid van Moolenbroek} 220*00b67f09SDavid van MoolenbroekATF_TC_BODY(tc1, tc) 221*00b67f09SDavid van Moolenbroek{ 222*00b67f09SDavid van Moolenbroek ... first test case's body ... 223*00b67f09SDavid van Moolenbroek} 224*00b67f09SDavid van Moolenbroek 225*00b67f09SDavid van MoolenbroekATF_TC_WITH_CLEANUP(tc2); 226*00b67f09SDavid van MoolenbroekATF_TC_HEAD(tc2, tc) 227*00b67f09SDavid van Moolenbroek{ 228*00b67f09SDavid van Moolenbroek ... second test case's header ... 229*00b67f09SDavid van Moolenbroek} 230*00b67f09SDavid van MoolenbroekATF_TC_BODY(tc2, tc) 231*00b67f09SDavid van Moolenbroek{ 232*00b67f09SDavid van Moolenbroek ... second test case's body ... 233*00b67f09SDavid van Moolenbroek} 234*00b67f09SDavid van MoolenbroekATF_TC_CLEANUP(tc2, tc) 235*00b67f09SDavid van Moolenbroek{ 236*00b67f09SDavid van Moolenbroek ... second test case's cleanup ... 237*00b67f09SDavid van Moolenbroek} 238*00b67f09SDavid van Moolenbroek 239*00b67f09SDavid van MoolenbroekATF_TC_WITHOUT_HEAD(tc3); 240*00b67f09SDavid van MoolenbroekATF_TC_BODY(tc3, tc) 241*00b67f09SDavid van Moolenbroek{ 242*00b67f09SDavid van Moolenbroek ... third test case's body ... 243*00b67f09SDavid van Moolenbroek} 244*00b67f09SDavid van Moolenbroek 245*00b67f09SDavid van Moolenbroek.Ns ... additional test cases ... 246*00b67f09SDavid van Moolenbroek 247*00b67f09SDavid van MoolenbroekATF_TP_ADD_TCS(tp) 248*00b67f09SDavid van Moolenbroek{ 249*00b67f09SDavid van Moolenbroek ATF_TP_ADD_TC(tcs, tc1); 250*00b67f09SDavid van Moolenbroek ATF_TP_ADD_TC(tcs, tc2); 251*00b67f09SDavid van Moolenbroek ATF_TP_ADD_TC(tcs, tc3); 252*00b67f09SDavid van Moolenbroek ... add additional test cases ... 253*00b67f09SDavid van Moolenbroek 254*00b67f09SDavid van Moolenbroek return atf_no_error(); 255*00b67f09SDavid van Moolenbroek} 256*00b67f09SDavid van Moolenbroek.Ed 257*00b67f09SDavid van Moolenbroek.Ss Definition of test cases 258*00b67f09SDavid van MoolenbroekTest cases have an identifier and are composed of three different parts: 259*00b67f09SDavid van Moolenbroekthe header, the body and an optional cleanup routine, all of which are 260*00b67f09SDavid van Moolenbroekdescribed in 261*00b67f09SDavid van Moolenbroek.Xr atf-test-case 4 . 262*00b67f09SDavid van MoolenbroekTo define test cases, one can use the 263*00b67f09SDavid van Moolenbroek.Fn ATF_TC , 264*00b67f09SDavid van Moolenbroek.Fn ATF_TC_WITH_CLEANUP 265*00b67f09SDavid van Moolenbroekor the 266*00b67f09SDavid van Moolenbroek.Fn ATF_TC_WITHOUT_HEAD 267*00b67f09SDavid van Moolenbroekmacros, which take a single parameter specifiying the test case's name. 268*00b67f09SDavid van Moolenbroek.Fn ATF_TC , 269*00b67f09SDavid van Moolenbroekrequires to define a head and a body for the test case, 270*00b67f09SDavid van Moolenbroek.Fn ATF_TC_WITH_CLEANUP 271*00b67f09SDavid van Moolenbroekrequires to define a head, a body and a cleanup for the test case and 272*00b67f09SDavid van Moolenbroek.Fn ATF_TC_WITHOUT_HEAD 273*00b67f09SDavid van Moolenbroekrequires only a body for the test case. 274*00b67f09SDavid van MoolenbroekIt is important to note that these 275*00b67f09SDavid van Moolenbroek.Em do not 276*00b67f09SDavid van Moolenbroekset the test case up for execution when the program is run. 277*00b67f09SDavid van MoolenbroekIn order to do so, a later registration is needed with the 278*00b67f09SDavid van Moolenbroek.Fn ATF_TP_ADD_TC 279*00b67f09SDavid van Moolenbroekmacro detailed in 280*00b67f09SDavid van Moolenbroek.Sx Program initialization . 281*00b67f09SDavid van Moolenbroek.Pp 282*00b67f09SDavid van MoolenbroekLater on, one must define the three parts of the body by means of three 283*00b67f09SDavid van Moolenbroekfunctions. 284*00b67f09SDavid van MoolenbroekTheir headers are given by the 285*00b67f09SDavid van Moolenbroek.Fn ATF_TC_HEAD , 286*00b67f09SDavid van Moolenbroek.Fn ATF_TC_BODY 287*00b67f09SDavid van Moolenbroekand 288*00b67f09SDavid van Moolenbroek.Fn ATF_TC_CLEANUP 289*00b67f09SDavid van Moolenbroekmacros, all of which take the test case name provided to the 290*00b67f09SDavid van Moolenbroek.Fn ATF_TC 291*00b67f09SDavid van Moolenbroek.Fn ATF_TC_WITH_CLEANUP , 292*00b67f09SDavid van Moolenbroekor 293*00b67f09SDavid van Moolenbroek.Fn ATF_TC_WITHOUT_HEAD 294*00b67f09SDavid van Moolenbroekmacros and the name of the variable that will hold a pointer to the 295*00b67f09SDavid van Moolenbroektest case data. 296*00b67f09SDavid van MoolenbroekFollowing each of these, a block of code is expected, surrounded by the 297*00b67f09SDavid van Moolenbroekopening and closing brackets. 298*00b67f09SDavid van Moolenbroek.Ss Program initialization 299*00b67f09SDavid van MoolenbroekThe library provides a way to easily define the test program's 300*00b67f09SDavid van Moolenbroek.Fn main 301*00b67f09SDavid van Moolenbroekfunction. 302*00b67f09SDavid van MoolenbroekYou should never define one on your own, but rely on the 303*00b67f09SDavid van Moolenbroeklibrary to do it for you. 304*00b67f09SDavid van MoolenbroekThis is done by using the 305*00b67f09SDavid van Moolenbroek.Fn ATF_TP_ADD_TCS 306*00b67f09SDavid van Moolenbroekmacro, which is passed the name of the object that will hold the test 307*00b67f09SDavid van Moolenbroekcases; i.e. the test program instance. 308*00b67f09SDavid van MoolenbroekThis name can be whatever you want as long as it is a valid variable 309*00b67f09SDavid van Moolenbroekidentifier. 310*00b67f09SDavid van Moolenbroek.Pp 311*00b67f09SDavid van MoolenbroekAfter the macro, you are supposed to provide the body of a function, which 312*00b67f09SDavid van Moolenbroekshould only use the 313*00b67f09SDavid van Moolenbroek.Fn ATF_TP_ADD_TC 314*00b67f09SDavid van Moolenbroekmacro to register the test cases the test program will execute and return 315*00b67f09SDavid van Moolenbroeka success error code. 316*00b67f09SDavid van MoolenbroekThe first parameter of this macro matches the name you provided in the 317*00b67f09SDavid van Moolenbroekformer call. 318*00b67f09SDavid van MoolenbroekThe success status can be returned using the 319*00b67f09SDavid van Moolenbroek.Fn atf_no_error 320*00b67f09SDavid van Moolenbroekfunction. 321*00b67f09SDavid van Moolenbroek.Ss Header definitions 322*00b67f09SDavid van MoolenbroekThe test case's header can define the meta-data by using the 323*00b67f09SDavid van Moolenbroek.Fn atf_tc_set_md_var 324*00b67f09SDavid van Moolenbroekmethod, which takes three parameters: the first one points to the test 325*00b67f09SDavid van Moolenbroekcase data, the second one specifies the meta-data variable to be set 326*00b67f09SDavid van Moolenbroekand the third one specifies its value. 327*00b67f09SDavid van MoolenbroekBoth of them are strings. 328*00b67f09SDavid van Moolenbroek.Ss Configuration variables 329*00b67f09SDavid van MoolenbroekThe test case has read-only access to the current configuration variables 330*00b67f09SDavid van Moolenbroekby means of the 331*00b67f09SDavid van Moolenbroek.Ft bool 332*00b67f09SDavid van Moolenbroek.Fn atf_tc_has_config_var , 333*00b67f09SDavid van Moolenbroek.Ft const char * 334*00b67f09SDavid van Moolenbroek.Fn atf_tc_get_config_var , 335*00b67f09SDavid van Moolenbroek.Ft const char * 336*00b67f09SDavid van Moolenbroek.Fn atf_tc_get_config_var_wd , 337*00b67f09SDavid van Moolenbroek.Ft bool 338*00b67f09SDavid van Moolenbroek.Fn atf_tc_get_config_var_as_bool , 339*00b67f09SDavid van Moolenbroek.Ft bool 340*00b67f09SDavid van Moolenbroek.Fn atf_tc_get_config_var_as_bool_wd , 341*00b67f09SDavid van Moolenbroek.Ft long 342*00b67f09SDavid van Moolenbroek.Fn atf_tc_get_config_var_as_long , 343*00b67f09SDavid van Moolenbroekand the 344*00b67f09SDavid van Moolenbroek.Ft long 345*00b67f09SDavid van Moolenbroek.Fn atf_tc_get_config_var_as_long_wd 346*00b67f09SDavid van Moolenbroekfunctions, which can be called in any of the three parts of a test case. 347*00b67f09SDavid van Moolenbroek.Pp 348*00b67f09SDavid van MoolenbroekThe 349*00b67f09SDavid van Moolenbroek.Sq _wd 350*00b67f09SDavid van Moolenbroekvariants take a default value for the variable which is returned if the 351*00b67f09SDavid van Moolenbroekvariable is not defined. 352*00b67f09SDavid van MoolenbroekThe other functions without the 353*00b67f09SDavid van Moolenbroek.Sq _wd 354*00b67f09SDavid van Moolenbroeksuffix 355*00b67f09SDavid van Moolenbroek.Em require 356*00b67f09SDavid van Moolenbroekthe variable to be defined. 357*00b67f09SDavid van Moolenbroek.Ss Access to the source directory 358*00b67f09SDavid van MoolenbroekIt is possible to get the path to the test case's source directory from any 359*00b67f09SDavid van Moolenbroekof its three components by querying the 360*00b67f09SDavid van Moolenbroek.Sq srcdir 361*00b67f09SDavid van Moolenbroekconfiguration variable. 362*00b67f09SDavid van Moolenbroek.Ss Requiring programs 363*00b67f09SDavid van MoolenbroekAside from the 364*00b67f09SDavid van Moolenbroek.Va require.progs 365*00b67f09SDavid van Moolenbroekmeta-data variable available in the header only, one can also check for 366*00b67f09SDavid van Moolenbroekadditional programs in the test case's body by using the 367*00b67f09SDavid van Moolenbroek.Fn atf_tc_require_prog 368*00b67f09SDavid van Moolenbroekfunction, which takes the base name or full path of a single binary. 369*00b67f09SDavid van MoolenbroekRelative paths are forbidden. 370*00b67f09SDavid van MoolenbroekIf it is not found, the test case will be automatically skipped. 371*00b67f09SDavid van Moolenbroek.Ss Test case finalization 372*00b67f09SDavid van MoolenbroekThe test case finalizes either when the body reaches its end, at which 373*00b67f09SDavid van Moolenbroekpoint the test is assumed to have 374*00b67f09SDavid van Moolenbroek.Em passed , 375*00b67f09SDavid van Moolenbroekunless any non-fatal errors were raised using 376*00b67f09SDavid van Moolenbroek.Fn atf_tc_fail_nonfatal , 377*00b67f09SDavid van Moolenbroekor at any explicit call to 378*00b67f09SDavid van Moolenbroek.Fn atf_tc_pass , 379*00b67f09SDavid van Moolenbroek.Fn atf_tc_fail 380*00b67f09SDavid van Moolenbroekor 381*00b67f09SDavid van Moolenbroek.Fn atf_tc_skip . 382*00b67f09SDavid van MoolenbroekThese three functions terminate the execution of the test case immediately. 383*00b67f09SDavid van MoolenbroekThe cleanup routine will be processed afterwards in a completely automated 384*00b67f09SDavid van Moolenbroekway, regardless of the test case's termination reason. 385*00b67f09SDavid van Moolenbroek.Pp 386*00b67f09SDavid van Moolenbroek.Fn atf_tc_pass 387*00b67f09SDavid van Moolenbroekdoes not take any parameters. 388*00b67f09SDavid van Moolenbroek.Fn atf_tc_fail , 389*00b67f09SDavid van Moolenbroek.Fn atf_tc_fail_nonfatal 390*00b67f09SDavid van Moolenbroekand 391*00b67f09SDavid van Moolenbroek.Fn atf_tc_skip 392*00b67f09SDavid van Moolenbroektake a format string and a variable list of parameters, which describe, in 393*00b67f09SDavid van Moolenbroeka user-friendly manner, why the test case failed or was skipped, 394*00b67f09SDavid van Moolenbroekrespectively. 395*00b67f09SDavid van MoolenbroekIt is very important to provide a clear error message in both cases so that 396*00b67f09SDavid van Moolenbroekthe user can quickly know why the test did not pass. 397*00b67f09SDavid van Moolenbroek.Ss Expectations 398*00b67f09SDavid van MoolenbroekEverything explained in the previous section changes when the test case 399*00b67f09SDavid van Moolenbroekexpectations are redefined by the programmer. 400*00b67f09SDavid van Moolenbroek.Pp 401*00b67f09SDavid van MoolenbroekEach test case has an internal state called 402*00b67f09SDavid van Moolenbroek.Sq expect 403*00b67f09SDavid van Moolenbroekthat describes what the test case expectations are at any point in time. 404*00b67f09SDavid van MoolenbroekThe value of this property can change during execution by any of: 405*00b67f09SDavid van Moolenbroek.Bl -tag -width indent 406*00b67f09SDavid van Moolenbroek.It Fn atf_tc_expect_death "reason" "..." 407*00b67f09SDavid van MoolenbroekExpects the test case to exit prematurely regardless of the nature of the 408*00b67f09SDavid van Moolenbroekexit. 409*00b67f09SDavid van Moolenbroek.It Fn atf_tc_expect_exit "exitcode" "reason" "..." 410*00b67f09SDavid van MoolenbroekExpects the test case to exit cleanly. 411*00b67f09SDavid van MoolenbroekIf 412*00b67f09SDavid van Moolenbroek.Va exitcode 413*00b67f09SDavid van Moolenbroekis not 414*00b67f09SDavid van Moolenbroek.Sq -1 , 415*00b67f09SDavid van Moolenbroek.Xr atf-run 1 416*00b67f09SDavid van Moolenbroekwill validate that the exit code of the test case matches the one provided 417*00b67f09SDavid van Moolenbroekin this call. 418*00b67f09SDavid van MoolenbroekOtherwise, the exact value will be ignored. 419*00b67f09SDavid van Moolenbroek.It Fn atf_tc_expect_fail "reason" "..." 420*00b67f09SDavid van MoolenbroekAny failure (be it fatal or non-fatal) raised in this mode is recorded. 421*00b67f09SDavid van MoolenbroekHowever, such failures do not report the test case as failed; instead, the 422*00b67f09SDavid van Moolenbroektest case finalizes cleanly and is reported as 423*00b67f09SDavid van Moolenbroek.Sq expected failure ; 424*00b67f09SDavid van Moolenbroekthis report includes the provided 425*00b67f09SDavid van Moolenbroek.Fa reason 426*00b67f09SDavid van Moolenbroekas part of it. 427*00b67f09SDavid van MoolenbroekIf no error is raised while running in this mode, then the test case is 428*00b67f09SDavid van Moolenbroekreported as 429*00b67f09SDavid van Moolenbroek.Sq failed . 430*00b67f09SDavid van Moolenbroek.Pp 431*00b67f09SDavid van MoolenbroekThis mode is useful to reproduce actual known bugs in tests. 432*00b67f09SDavid van MoolenbroekWhenever the developer fixes the bug later on, the test case will start 433*00b67f09SDavid van Moolenbroekreporting a failure, signaling the developer that the test case must be 434*00b67f09SDavid van Moolenbroekadjusted to the new conditions. 435*00b67f09SDavid van MoolenbroekIn this situation, it is useful, for example, to set 436*00b67f09SDavid van Moolenbroek.Fa reason 437*00b67f09SDavid van Moolenbroekas the bug number for tracking purposes. 438*00b67f09SDavid van Moolenbroek.It Fn atf_tc_expect_pass 439*00b67f09SDavid van MoolenbroekThis is the normal mode of execution. 440*00b67f09SDavid van MoolenbroekIn this mode, any failure is reported as such to the user and the test case 441*00b67f09SDavid van Moolenbroekis marked as 442*00b67f09SDavid van Moolenbroek.Sq failed . 443*00b67f09SDavid van Moolenbroek.It Fn atf_tc_expect_signal "signo" "reason" "..." 444*00b67f09SDavid van MoolenbroekExpects the test case to terminate due to the reception of a signal. 445*00b67f09SDavid van MoolenbroekIf 446*00b67f09SDavid van Moolenbroek.Va signo 447*00b67f09SDavid van Moolenbroekis not 448*00b67f09SDavid van Moolenbroek.Sq -1 , 449*00b67f09SDavid van Moolenbroek.Xr atf-run 1 450*00b67f09SDavid van Moolenbroekwill validate that the signal that terminated the test case matches the one 451*00b67f09SDavid van Moolenbroekprovided in this call. 452*00b67f09SDavid van MoolenbroekOtherwise, the exact value will be ignored. 453*00b67f09SDavid van Moolenbroek.It Fn atf_tc_expect_timeout "reason" "..." 454*00b67f09SDavid van MoolenbroekExpects the test case to execute for longer than its timeout. 455*00b67f09SDavid van Moolenbroek.El 456*00b67f09SDavid van Moolenbroek.Ss Helper macros for common checks 457*00b67f09SDavid van MoolenbroekThe library provides several macros that are very handy in multiple 458*00b67f09SDavid van Moolenbroeksituations. 459*00b67f09SDavid van MoolenbroekThese basically check some condition after executing a given statement or 460*00b67f09SDavid van Moolenbroekprocessing a given expression and, if the condition is not met, they 461*00b67f09SDavid van Moolenbroekreport the test case as failed. 462*00b67f09SDavid van Moolenbroek.Pp 463*00b67f09SDavid van MoolenbroekThe 464*00b67f09SDavid van Moolenbroek.Sq REQUIRE 465*00b67f09SDavid van Moolenbroekvariant of the macros immediately abort the test case as soon as an error 466*00b67f09SDavid van Moolenbroekcondition is detected by calling the 467*00b67f09SDavid van Moolenbroek.Fn atf_tc_fail 468*00b67f09SDavid van Moolenbroekfunction. 469*00b67f09SDavid van MoolenbroekUse this variant whenever it makes no sense to continue the execution of a 470*00b67f09SDavid van Moolenbroektest case when the checked condition is not met. 471*00b67f09SDavid van MoolenbroekThe 472*00b67f09SDavid van Moolenbroek.Sq CHECK 473*00b67f09SDavid van Moolenbroekvariant, on the other hand, reports a failure as soon as it is encountered 474*00b67f09SDavid van Moolenbroekusing the 475*00b67f09SDavid van Moolenbroek.Fn atf_tc_fail_nonfatal 476*00b67f09SDavid van Moolenbroekfunction, but the execution of the test case continues as if nothing had 477*00b67f09SDavid van Moolenbroekhappened. 478*00b67f09SDavid van MoolenbroekUse this variant whenever the checked condition is important as a result of 479*00b67f09SDavid van Moolenbroekthe test case, but there are other conditions that can be subsequently 480*00b67f09SDavid van Moolenbroekchecked on the same run without aborting. 481*00b67f09SDavid van Moolenbroek.Pp 482*00b67f09SDavid van MoolenbroekAdditionally, the 483*00b67f09SDavid van Moolenbroek.Sq MSG 484*00b67f09SDavid van Moolenbroekvariants take an extra set of parameters to explicitly specify the failure 485*00b67f09SDavid van Moolenbroekmessage. 486*00b67f09SDavid van MoolenbroekThis failure message is formatted according to the 487*00b67f09SDavid van Moolenbroek.Xr printf 3 488*00b67f09SDavid van Moolenbroekformatters. 489*00b67f09SDavid van Moolenbroek.Pp 490*00b67f09SDavid van Moolenbroek.Fn ATF_CHECK , 491*00b67f09SDavid van Moolenbroek.Fn ATF_CHECK_MSG , 492*00b67f09SDavid van Moolenbroek.Fn ATF_REQUIRE 493*00b67f09SDavid van Moolenbroekand 494*00b67f09SDavid van Moolenbroek.Fn ATF_REQUIRE_MSG 495*00b67f09SDavid van Moolenbroektake an expression and fail if the expression evaluates to false. 496*00b67f09SDavid van Moolenbroek.Pp 497*00b67f09SDavid van Moolenbroek.Fn ATF_CHECK_EQ , 498*00b67f09SDavid van Moolenbroek.Fn ATF_CHECK_EQ_MSG , 499*00b67f09SDavid van Moolenbroek.Fn ATF_REQUIRE_EQ 500*00b67f09SDavid van Moolenbroekand 501*00b67f09SDavid van Moolenbroek.Fn ATF_REQUIRE_EQ_MSG 502*00b67f09SDavid van Moolenbroektake two expressions and fail if the two evaluated values are not equal. 503*00b67f09SDavid van Moolenbroek.Pp 504*00b67f09SDavid van Moolenbroek.Fn ATF_CHECK_MATCH , 505*00b67f09SDavid van Moolenbroek.Fn ATF_CHECK_MATCH_MSG , 506*00b67f09SDavid van Moolenbroek.Fn ATF_REQUIRE_MATCH 507*00b67f09SDavid van Moolenbroekand 508*00b67f09SDavid van Moolenbroek.Fn ATF_REQUIRE_MATCH_MSG 509*00b67f09SDavid van Moolenbroektake a regular expression and a string and fail if the regular expression does 510*00b67f09SDavid van Moolenbroeknot match the given string. 511*00b67f09SDavid van MoolenbroekNote that the regular expression is not anchored, so it will match anywhere in 512*00b67f09SDavid van Moolenbroekthe string. 513*00b67f09SDavid van Moolenbroek.Pp 514*00b67f09SDavid van Moolenbroek.Fn ATF_CHECK_STREQ , 515*00b67f09SDavid van Moolenbroek.Fn ATF_CHECK_STREQ_MSG , 516*00b67f09SDavid van Moolenbroek.Fn ATF_REQUIRE_STREQ 517*00b67f09SDavid van Moolenbroekand 518*00b67f09SDavid van Moolenbroek.Fn ATF_REQUIRE_STREQ_MSG 519*00b67f09SDavid van Moolenbroektake two strings and fail if the two are not equal character by character. 520*00b67f09SDavid van Moolenbroek.Pp 521*00b67f09SDavid van Moolenbroek.Fn ATF_CHECK_ERRNO 522*00b67f09SDavid van Moolenbroekand 523*00b67f09SDavid van Moolenbroek.Fn ATF_REQUIRE_ERRNO 524*00b67f09SDavid van Moolenbroektake, first, the error code that the check is expecting to find in the 525*00b67f09SDavid van Moolenbroek.Va errno 526*00b67f09SDavid van Moolenbroekvariable and, second, a boolean expression that, if evaluates to true, 527*00b67f09SDavid van Moolenbroekmeans that a call failed and 528*00b67f09SDavid van Moolenbroek.Va errno 529*00b67f09SDavid van Moolenbroekhas to be checked against the first value. 530*00b67f09SDavid van Moolenbroek.Ss Utility functions 531*00b67f09SDavid van MoolenbroekThe following functions are provided as part of the 532*00b67f09SDavid van Moolenbroek.Nm 533*00b67f09SDavid van MoolenbroekAPI to simplify the creation of a variety of tests. 534*00b67f09SDavid van MoolenbroekIn particular, these are useful to write tests for command-line interfaces. 535*00b67f09SDavid van Moolenbroek.Pp 536*00b67f09SDavid van Moolenbroek.Ft void 537*00b67f09SDavid van Moolenbroek.Fo atf_utils_cat_file 538*00b67f09SDavid van Moolenbroek.Fa "const char *file" 539*00b67f09SDavid van Moolenbroek.Fa "const char *prefix" 540*00b67f09SDavid van Moolenbroek.Fc 541*00b67f09SDavid van Moolenbroek.Bd -offset indent 542*00b67f09SDavid van MoolenbroekPrints the contents of 543*00b67f09SDavid van Moolenbroek.Fa file 544*00b67f09SDavid van Moolenbroekto the standard output, prefixing every line with the string in 545*00b67f09SDavid van Moolenbroek.Fa prefix . 546*00b67f09SDavid van Moolenbroek.Ed 547*00b67f09SDavid van Moolenbroek.Pp 548*00b67f09SDavid van Moolenbroek.Ft bool 549*00b67f09SDavid van Moolenbroek.Fo atf_utils_compare_file 550*00b67f09SDavid van Moolenbroek.Fa "const char *file" 551*00b67f09SDavid van Moolenbroek.Fa "const char *contents" 552*00b67f09SDavid van Moolenbroek.Fc 553*00b67f09SDavid van Moolenbroek.Bd -offset indent 554*00b67f09SDavid van MoolenbroekReturns true if the given 555*00b67f09SDavid van Moolenbroek.Fa file 556*00b67f09SDavid van Moolenbroekmatches exactly the expected inlined 557*00b67f09SDavid van Moolenbroek.Fa contents . 558*00b67f09SDavid van Moolenbroek.Ed 559*00b67f09SDavid van Moolenbroek.Pp 560*00b67f09SDavid van Moolenbroek.Ft void 561*00b67f09SDavid van Moolenbroek.Fo atf_utils_copy_file 562*00b67f09SDavid van Moolenbroek.Fa "const char *source" 563*00b67f09SDavid van Moolenbroek.Fa "const char *destination" 564*00b67f09SDavid van Moolenbroek.Fc 565*00b67f09SDavid van Moolenbroek.Bd -offset indent 566*00b67f09SDavid van MoolenbroekCopies the file 567*00b67f09SDavid van Moolenbroek.Fa source 568*00b67f09SDavid van Moolenbroekto 569*00b67f09SDavid van Moolenbroek.Fa destination . 570*00b67f09SDavid van MoolenbroekThe permissions of the file are preserved during the code. 571*00b67f09SDavid van Moolenbroek.Ed 572*00b67f09SDavid van Moolenbroek.Pp 573*00b67f09SDavid van Moolenbroek.Ft void 574*00b67f09SDavid van Moolenbroek.Fo atf_utils_create_file 575*00b67f09SDavid van Moolenbroek.Fa "const char *file" 576*00b67f09SDavid van Moolenbroek.Fa "const char *contents" 577*00b67f09SDavid van Moolenbroek.Fa "..." 578*00b67f09SDavid van Moolenbroek.Fc 579*00b67f09SDavid van Moolenbroek.Bd -offset indent 580*00b67f09SDavid van MoolenbroekCreates 581*00b67f09SDavid van Moolenbroek.Fa file 582*00b67f09SDavid van Moolenbroekwith the text given in 583*00b67f09SDavid van Moolenbroek.Fa contents , 584*00b67f09SDavid van Moolenbroekwhich is a formatting string that uses the rest of the variable arguments. 585*00b67f09SDavid van Moolenbroek.Ed 586*00b67f09SDavid van Moolenbroek.Pp 587*00b67f09SDavid van Moolenbroek.Ft void 588*00b67f09SDavid van Moolenbroek.Fo atf_utils_file_exists 589*00b67f09SDavid van Moolenbroek.Fa "const char *file" 590*00b67f09SDavid van Moolenbroek.Fc 591*00b67f09SDavid van Moolenbroek.Bd -offset indent 592*00b67f09SDavid van MoolenbroekChecks if 593*00b67f09SDavid van Moolenbroek.Fa file 594*00b67f09SDavid van Moolenbroekexists. 595*00b67f09SDavid van Moolenbroek.Ed 596*00b67f09SDavid van Moolenbroek.Pp 597*00b67f09SDavid van Moolenbroek.Ft pid_t 598*00b67f09SDavid van Moolenbroek.Fo atf_utils_fork 599*00b67f09SDavid van Moolenbroek.Fa "void" 600*00b67f09SDavid van Moolenbroek.Fc 601*00b67f09SDavid van Moolenbroek.Bd -offset indent 602*00b67f09SDavid van MoolenbroekForks a process and redirects the standard output and standard error of the 603*00b67f09SDavid van Moolenbroekchild to files for later validation with 604*00b67f09SDavid van Moolenbroek.Fn atf_utils_wait . 605*00b67f09SDavid van MoolenbroekFails the test case if the fork fails, so this does not return an error. 606*00b67f09SDavid van Moolenbroek.Ed 607*00b67f09SDavid van Moolenbroek.Pp 608*00b67f09SDavid van Moolenbroek.Ft void 609*00b67f09SDavid van Moolenbroek.Fo atf_utils_free_charpp 610*00b67f09SDavid van Moolenbroek.Fa "char **argv" 611*00b67f09SDavid van Moolenbroek.Fc 612*00b67f09SDavid van Moolenbroek.Bd -offset indent 613*00b67f09SDavid van MoolenbroekFrees a dynamically-allocated array of dynamically-allocated strings. 614*00b67f09SDavid van Moolenbroek.Ed 615*00b67f09SDavid van Moolenbroek.Pp 616*00b67f09SDavid van Moolenbroek.Ft bool 617*00b67f09SDavid van Moolenbroek.Fo atf_utils_grep_file 618*00b67f09SDavid van Moolenbroek.Fa "const char *regexp" 619*00b67f09SDavid van Moolenbroek.Fa "const char *file" 620*00b67f09SDavid van Moolenbroek.Fa "..." 621*00b67f09SDavid van Moolenbroek.Fc 622*00b67f09SDavid van Moolenbroek.Bd -offset indent 623*00b67f09SDavid van MoolenbroekSearches for the 624*00b67f09SDavid van Moolenbroek.Fa regexp , 625*00b67f09SDavid van Moolenbroekwhich is a formatting string representing the regular expression, 626*00b67f09SDavid van Moolenbroekin the 627*00b67f09SDavid van Moolenbroek.Fa file . 628*00b67f09SDavid van MoolenbroekThe variable arguments are used to construct the regular expression. 629*00b67f09SDavid van Moolenbroek.Ed 630*00b67f09SDavid van Moolenbroek.Pp 631*00b67f09SDavid van Moolenbroek.Ft bool 632*00b67f09SDavid van Moolenbroek.Fo atf_utils_grep_string 633*00b67f09SDavid van Moolenbroek.Fa "const char *regexp" 634*00b67f09SDavid van Moolenbroek.Fa "const char *str" 635*00b67f09SDavid van Moolenbroek.Fa "..." 636*00b67f09SDavid van Moolenbroek.Fc 637*00b67f09SDavid van Moolenbroek.Bd -offset indent 638*00b67f09SDavid van MoolenbroekSearches for the 639*00b67f09SDavid van Moolenbroek.Fa regexp , 640*00b67f09SDavid van Moolenbroekwhich is a formatting string representing the regular expression, 641*00b67f09SDavid van Moolenbroekin the literal string 642*00b67f09SDavid van Moolenbroek.Fa str . 643*00b67f09SDavid van MoolenbroekThe variable arguments are used to construct the regular expression. 644*00b67f09SDavid van Moolenbroek.Ed 645*00b67f09SDavid van Moolenbroek.Pp 646*00b67f09SDavid van Moolenbroek.Ft char * 647*00b67f09SDavid van Moolenbroek.Fo atf_utils_readline 648*00b67f09SDavid van Moolenbroek.Fa "int fd" 649*00b67f09SDavid van Moolenbroek.Fc 650*00b67f09SDavid van Moolenbroek.Bd -offset indent 651*00b67f09SDavid van MoolenbroekReads a line from the file descriptor 652*00b67f09SDavid van Moolenbroek.Fa fd . 653*00b67f09SDavid van MoolenbroekThe line, if any, is returned as a dynamically-allocated buffer that must be 654*00b67f09SDavid van Moolenbroekreleased with 655*00b67f09SDavid van Moolenbroek.Xr free 3 . 656*00b67f09SDavid van MoolenbroekIf there was nothing to read, returns 657*00b67f09SDavid van Moolenbroek.Sq NULL . 658*00b67f09SDavid van Moolenbroek.Ed 659*00b67f09SDavid van Moolenbroek.Pp 660*00b67f09SDavid van Moolenbroek.Ft void 661*00b67f09SDavid van Moolenbroek.Fo atf_utils_redirect 662*00b67f09SDavid van Moolenbroek.Fa "const int fd" 663*00b67f09SDavid van Moolenbroek.Fa "const char *file" 664*00b67f09SDavid van Moolenbroek.Fc 665*00b67f09SDavid van Moolenbroek.Bd -offset indent 666*00b67f09SDavid van MoolenbroekRedirects the given file descriptor 667*00b67f09SDavid van Moolenbroek.Fa fd 668*00b67f09SDavid van Moolenbroekto 669*00b67f09SDavid van Moolenbroek.Fa file . 670*00b67f09SDavid van MoolenbroekThis function exits the process in case of an error and does not properly mark 671*00b67f09SDavid van Moolenbroekthe test case as failed. 672*00b67f09SDavid van MoolenbroekAs a result, it should only be used in subprocesses of the test case; specially 673*00b67f09SDavid van Moolenbroekthose spawned by 674*00b67f09SDavid van Moolenbroek.Fn atf_utils_fork . 675*00b67f09SDavid van Moolenbroek.Ed 676*00b67f09SDavid van Moolenbroek.Pp 677*00b67f09SDavid van Moolenbroek.Ft void 678*00b67f09SDavid van Moolenbroek.Fo atf_utils_wait 679*00b67f09SDavid van Moolenbroek.Fa "const pid_t pid" 680*00b67f09SDavid van Moolenbroek.Fa "const int expected_exit_status" 681*00b67f09SDavid van Moolenbroek.Fa "const char *expected_stdout" 682*00b67f09SDavid van Moolenbroek.Fa "const char *expected_stderr" 683*00b67f09SDavid van Moolenbroek.Fc 684*00b67f09SDavid van Moolenbroek.Bd -offset indent 685*00b67f09SDavid van MoolenbroekWaits and validates the result of a subprocess spawned with 686*00b67f09SDavid van Moolenbroek.Fn atf_utils_wait . 687*00b67f09SDavid van MoolenbroekThe validation involves checking that the subprocess exited cleanly and returned 688*00b67f09SDavid van Moolenbroekthe code specified in 689*00b67f09SDavid van Moolenbroek.Fa expected_exit_status 690*00b67f09SDavid van Moolenbroekand that its standard output and standard error match the strings given in 691*00b67f09SDavid van Moolenbroek.Fa expected_stdout 692*00b67f09SDavid van Moolenbroekand 693*00b67f09SDavid van Moolenbroek.Fa expected_stderr . 694*00b67f09SDavid van Moolenbroek.Pp 695*00b67f09SDavid van MoolenbroekIf any of the 696*00b67f09SDavid van Moolenbroek.Fa expected_stdout 697*00b67f09SDavid van Moolenbroekor 698*00b67f09SDavid van Moolenbroek.Fa expected_stderr 699*00b67f09SDavid van Moolenbroekstrings are prefixed with 700*00b67f09SDavid van Moolenbroek.Sq save: , 701*00b67f09SDavid van Moolenbroekthen they specify the name of the file into which to store the stdout or stderr 702*00b67f09SDavid van Moolenbroekof the subprocess, and no comparison is performed. 703*00b67f09SDavid van Moolenbroek.Ed 704*00b67f09SDavid van Moolenbroek.Sh EXAMPLES 705*00b67f09SDavid van MoolenbroekThe following shows a complete test program with a single test case that 706*00b67f09SDavid van Moolenbroekvalidates the addition operator: 707*00b67f09SDavid van Moolenbroek.Bd -literal -offset indent 708*00b67f09SDavid van Moolenbroek#include <atf-c.h> 709*00b67f09SDavid van Moolenbroek 710*00b67f09SDavid van MoolenbroekATF_TC(addition); 711*00b67f09SDavid van MoolenbroekATF_TC_HEAD(addition, tc) 712*00b67f09SDavid van Moolenbroek{ 713*00b67f09SDavid van Moolenbroek atf_tc_set_md_var(tc, "descr", 714*00b67f09SDavid van Moolenbroek "Sample tests for the addition operator"); 715*00b67f09SDavid van Moolenbroek} 716*00b67f09SDavid van MoolenbroekATF_TC_BODY(addition, tc) 717*00b67f09SDavid van Moolenbroek{ 718*00b67f09SDavid van Moolenbroek ATF_CHECK_EQ(0 + 0, 0); 719*00b67f09SDavid van Moolenbroek ATF_CHECK_EQ(0 + 1, 1); 720*00b67f09SDavid van Moolenbroek ATF_CHECK_EQ(1 + 0, 1); 721*00b67f09SDavid van Moolenbroek 722*00b67f09SDavid van Moolenbroek ATF_CHECK_EQ(1 + 1, 2); 723*00b67f09SDavid van Moolenbroek 724*00b67f09SDavid van Moolenbroek ATF_CHECK_EQ(100 + 200, 300); 725*00b67f09SDavid van Moolenbroek} 726*00b67f09SDavid van Moolenbroek 727*00b67f09SDavid van MoolenbroekATF_TC(string_formatting); 728*00b67f09SDavid van MoolenbroekATF_TC_HEAD(string_formatting, tc) 729*00b67f09SDavid van Moolenbroek{ 730*00b67f09SDavid van Moolenbroek atf_tc_set_md_var(tc, "descr", 731*00b67f09SDavid van Moolenbroek "Sample tests for the snprintf"); 732*00b67f09SDavid van Moolenbroek} 733*00b67f09SDavid van MoolenbroekATF_TC_BODY(string_formatting, tc) 734*00b67f09SDavid van Moolenbroek{ 735*00b67f09SDavid van Moolenbroek char buf[1024]; 736*00b67f09SDavid van Moolenbroek snprintf(buf, sizeof(buf), "a %s", "string"); 737*00b67f09SDavid van Moolenbroek ATF_CHECK_STREQ_MSG("a string", buf, "%s is not working"); 738*00b67f09SDavid van Moolenbroek} 739*00b67f09SDavid van Moolenbroek 740*00b67f09SDavid van MoolenbroekATF_TC(open_failure); 741*00b67f09SDavid van MoolenbroekATF_TC_HEAD(open_failure, tc) 742*00b67f09SDavid van Moolenbroek{ 743*00b67f09SDavid van Moolenbroek atf_tc_set_md_var(tc, "descr", 744*00b67f09SDavid van Moolenbroek "Sample tests for the open function"); 745*00b67f09SDavid van Moolenbroek} 746*00b67f09SDavid van MoolenbroekATF_TC_BODY(open_failure, tc) 747*00b67f09SDavid van Moolenbroek{ 748*00b67f09SDavid van Moolenbroek ATF_CHECK_ERRNO(ENOENT, open("non-existent", O_RDONLY) == -1); 749*00b67f09SDavid van Moolenbroek} 750*00b67f09SDavid van Moolenbroek 751*00b67f09SDavid van MoolenbroekATF_TC(known_bug); 752*00b67f09SDavid van MoolenbroekATF_TC_HEAD(known_bug, tc) 753*00b67f09SDavid van Moolenbroek{ 754*00b67f09SDavid van Moolenbroek atf_tc_set_md_var(tc, "descr", 755*00b67f09SDavid van Moolenbroek "Reproduces a known bug"); 756*00b67f09SDavid van Moolenbroek} 757*00b67f09SDavid van MoolenbroekATF_TC_BODY(known_bug, tc) 758*00b67f09SDavid van Moolenbroek{ 759*00b67f09SDavid van Moolenbroek atf_tc_expect_fail("See bug number foo/bar"); 760*00b67f09SDavid van Moolenbroek ATF_CHECK_EQ(3, 1 + 1); 761*00b67f09SDavid van Moolenbroek atf_tc_expect_pass(); 762*00b67f09SDavid van Moolenbroek ATF_CHECK_EQ(3, 1 + 2); 763*00b67f09SDavid van Moolenbroek} 764*00b67f09SDavid van Moolenbroek 765*00b67f09SDavid van MoolenbroekATF_TP_ADD_TCS(tp) 766*00b67f09SDavid van Moolenbroek{ 767*00b67f09SDavid van Moolenbroek ATF_TP_ADD_TC(tp, addition); 768*00b67f09SDavid van Moolenbroek ATF_TP_ADD_TC(tp, string_formatting); 769*00b67f09SDavid van Moolenbroek ATF_TP_ADD_TC(tp, open_failure); 770*00b67f09SDavid van Moolenbroek ATF_TP_ADD_TC(tp, known_bug); 771*00b67f09SDavid van Moolenbroek 772*00b67f09SDavid van Moolenbroek return atf_no_error(); 773*00b67f09SDavid van Moolenbroek} 774*00b67f09SDavid van Moolenbroek.Ed 775*00b67f09SDavid van Moolenbroek.Sh SEE ALSO 776*00b67f09SDavid van Moolenbroek.Xr atf-test-program 1 , 777*00b67f09SDavid van Moolenbroek.Xr atf-test-case 4 , 778*00b67f09SDavid van Moolenbroek.Xr atf 7 779