xref: /minix3/external/bsd/bind/dist/unit/atf-src/atf-c/atf-c-api.3 (revision 00b67f09dd46474d133c95011a48590a8e8f94c7)
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