xref: /netbsd-src/external/bsd/atf/dist/atf-c/atf-c-api.3 (revision a5847cc334d9a7029f6352b847e9e8d71a0f9e0c)
1.\"
2.\" Automated Testing Framework (atf)
3.\"
4.\" Copyright (c) 2008, 2009, 2010 The NetBSD Foundation, Inc.
5.\" All rights reserved.
6.\"
7.\" Redistribution and use in source and binary forms, with or without
8.\" modification, are permitted provided that the following conditions
9.\" are met:
10.\" 1. Redistributions of source code must retain the above copyright
11.\"    notice, this list of conditions and the following disclaimer.
12.\" 2. Redistributions in binary form must reproduce the above copyright
13.\"    notice, this list of conditions and the following disclaimer in the
14.\"    documentation and/or other materials provided with the distribution.
15.\"
16.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
17.\" CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
18.\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20.\" IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
21.\" DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
23.\" GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25.\" IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26.\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27.\" IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28.\"
29.Dd December 26, 2010
30.Dt ATF-C-API 3
31.Os
32.Sh NAME
33.Nm ATF_CHECK ,
34.Nm ATF_CHECK_MSG ,
35.Nm ATF_CHECK_EQ ,
36.Nm ATF_CHECK_EQ_MSG ,
37.Nm ATF_CHECK_STREQ ,
38.Nm ATF_CHECK_STREQ_MSG ,
39.Nm ATF_CHECK_ERRNO ,
40.Nm ATF_REQUIRE ,
41.Nm ATF_REQUIRE_MSG ,
42.Nm ATF_REQUIRE_EQ ,
43.Nm ATF_REQUIRE_EQ_MSG ,
44.Nm ATF_REQUIRE_STREQ ,
45.Nm ATF_REQUIRE_STREQ_MSG ,
46.Nm ATF_REQUIRE_ERRNO ,
47.Nm ATF_TC ,
48.Nm ATF_TC_BODY ,
49.Nm ATF_TC_BODY_NAME ,
50.Nm ATF_TC_CLEANUP ,
51.Nm ATF_TC_CLEANUP_NAME ,
52.Nm ATF_TC_HEAD ,
53.Nm ATF_TC_HEAD_NAME ,
54.Nm ATF_TC_NAME ,
55.Nm ATF_TC_WITH_CLEANUP ,
56.Nm ATF_TC_WITHOUT_HEAD ,
57.Nm ATF_TP_ADD_TC ,
58.Nm ATF_TP_ADD_TCS ,
59.Nm atf_tc_get_config_var ,
60.Nm atf_tc_get_config_var_wd ,
61.Nm atf_tc_get_config_var_as_bool ,
62.Nm atf_tc_get_config_var_as_bool_wd ,
63.Nm atf_tc_get_config_var_as_long ,
64.Nm atf_tc_get_config_var_as_long_wd ,
65.Nm atf_no_error ,
66.Nm atf_tc_expect_death ,
67.Nm atf_tc_expect_exit ,
68.Nm atf_tc_expect_fail ,
69.Nm atf_tc_expect_pass ,
70.Nm atf_tc_expect_signal ,
71.Nm atf_tc_expect_timeout ,
72.Nm atf_tc_fail ,
73.Nm atf_tc_fail_nonfatal ,
74.Nm atf_tc_pass ,
75.Nm atf_tc_skip
76.Nd C API to write ATF-based test programs
77.Sh SYNOPSIS
78.In atf-c.h
79.Fn ATF_CHECK "expression"
80.Fn ATF_CHECK_MSG "expression" "fail_msg_fmt" ...
81.Fn ATF_CHECK_EQ "expression_1" "expression_2"
82.Fn ATF_CHECK_EQ_MSG "expression_1" "expression_2" "fail_msg_fmt" ...
83.Fn ATF_CHECK_STREQ "string_1" "string_2"
84.Fn ATF_CHECK_STREQ_MSG "string_1" "string_2" "fail_msg_fmt" ...
85.Fn ATF_CHECK_ERRNO "exp_errno" "bool_expression"
86.Fn ATF_REQUIRE "expression"
87.Fn ATF_REQUIRE_MSG "expression" "fail_msg_fmt" ...
88.Fn ATF_REQUIRE_EQ "expression_1" "expression_2"
89.Fn ATF_REQUIRE_EQ_MSG "expression_1" "expression_2" "fail_msg_fmt" ...
90.Fn ATF_REQUIRE_STREQ "string_1" "string_2"
91.Fn ATF_REQUIRE_STREQ_MSG "string_1" "string_2" "fail_msg_fmt" ...
92.Fn ATF_REQUIRE_ERRNO "exp_errno" "bool_expression"
93.Fn ATF_TC "name"
94.Fn ATF_TC_BODY "name" "tc"
95.Fn ATF_TC_BODY_NAME "name"
96.Fn ATF_TC_CLEANUP "name" "tc"
97.Fn ATF_TC_CLEANUP_NAME "name"
98.Fn ATF_TC_HEAD "name" "tc"
99.Fn ATF_TC_HEAD_NAME "name"
100.Fn ATF_TC_NAME "name"
101.Fn ATF_TC_WITH_CLEANUP "name"
102.Fn ATF_TC_WITHOUT_HEAD "name"
103.Fn ATF_TP_ADD_TC "tp_name" "tc_name"
104.Fn ATF_TP_ADD_TCS "tp_name"
105.Fn atf_tc_get_config_var "tc" "varname"
106.Fn atf_tc_get_config_var_wd "tc" "variable_name" "default_value"
107.Fn atf_tc_get_config_var_as_bool "tc" "variable_name"
108.Fn atf_tc_get_config_var_as_bool_wd "tc" "variable_name" "default_value"
109.Fn atf_tc_get_config_var_as_long "tc" "variable_name"
110.Fn atf_tc_get_config_var_as_long_wd "tc" "variable_name" "default_value"
111.Fn atf_no_error
112.Fn atf_tc_expect_death "reason" "..."
113.Fn atf_tc_expect_exit "exitcode" "reason" "..."
114.Fn atf_tc_expect_fail "reason" "..."
115.Fn atf_tc_expect_pass
116.Fn atf_tc_expect_signal "signo" "reason" "..."
117.Fn atf_tc_expect_timeout "reason" "..."
118.Fn atf_tc_fail "reason"
119.Fn atf_tc_fail_nonfatal "reason"
120.Fn atf_tc_pass
121.Fn atf_tc_skip "reason"
122.Sh DESCRIPTION
123The ATF
124.Pp
125C-based test programs always follow this template:
126.Bd -literal -offset indent
127.Ns ... C-specific includes go here ...
128
129#include <atf-c.h>
130
131ATF_TC(tc1);
132ATF_TC_HEAD(tc1, tc)
133{
134    ... first test case's header ...
135}
136ATF_TC_BODY(tc1, tc)
137{
138    ... first test case's body ...
139}
140
141ATF_TC_WITH_CLEANUP(tc2);
142ATF_TC_HEAD(tc2, tc)
143{
144    ... second test case's header ...
145}
146ATF_TC_BODY(tc2, tc)
147{
148    ... second test case's body ...
149}
150ATF_TC_CLEANUP(tc2, tc)
151{
152    ... second test case's cleanup ...
153}
154
155ATF_TC_WITHOUT_HEAD(tc3);
156ATF_TC_BODY(tc3, tc)
157{
158    ... third test case's body ...
159}
160
161.Ns ... additional test cases ...
162
163ATF_TP_ADD_TCS(tp)
164{
165    ATF_TP_ADD_TC(tcs, tc1);
166    ATF_TP_ADD_TC(tcs, tc2);
167    ATF_TP_ADD_TC(tcs, tc3);
168    ... add additional test cases ...
169
170    return atf_no_error();
171}
172.Ed
173.Ss Definition of test cases
174Test cases have an identifier and are composed of three different parts:
175the header, the body and an optional cleanup routine, all of which are
176described in
177.Xr atf-test-case 4 .
178To define test cases, one can use the
179.Fn ATF_TC ,
180.Fn ATF_TC_WITH_CLEANUP
181or the
182.Fn ATF_TC_WITHOUT_HEAD
183macros, which take a single parameter specifiying the test case's name.
184.Fn ATF_TC ,
185requires to define a head and a body for the test case,
186.Fn ATF_TC_WITH_CLEANUP
187requires to define a head, a body and a cleanup for the test case and
188.Fn ATF_TC_WITHOUT_HEAD
189requires only a body for the test case.
190It is important to note that these
191.Em do not
192set the test case up for execution when the program is run.
193In order to do so, a later registration is needed with the
194.Fn ATF_TP_ADD_TC
195macro detailed in
196.Sx Program initialization .
197.Pp
198Later on, one must define the three parts of the body by means of three
199functions.
200Their headers are given by the
201.Fn ATF_TC_HEAD ,
202.Fn ATF_TC_BODY
203and
204.Fn ATF_TC_CLEANUP
205macros, all of which take the test case name provided to the
206.Fn ATF_TC
207.Fn ATF_TC_WITH_CLEANUP ,
208or
209.Fn ATF_TC_WITHOUT_HEAD
210macros and the name of the variable that will hold a pointer to the
211test case data.
212Following each of these, a block of code is expected, surrounded by the
213opening and closing brackets.
214.Ss Program initialization
215The library provides a way to easily define the test program's
216.Fn main
217function.
218You should never define one on your own, but rely on the
219library to do it for you.
220This is done by using the
221.Fn ATF_TP_ADD_TCS
222macro, which is passed the name of the object that will hold the test
223cases; i.e. the test program instance.
224This name can be whatever you want as long as it is a valid variable
225identifier.
226.Pp
227After the macro, you are supposed to provide the body of a function, which
228should only use the
229.Fn ATF_TP_ADD_TC
230macro to register the test cases the test program will execute and return
231a success error code.
232The first parameter of this macro matches the name you provided in the
233former call.
234The success status can be returned using the
235.Fn atf_no_error
236function.
237.Ss Header definitions
238The test case's header can define the meta-data by using the
239.Fn atf_tc_set_md_var
240method, which takes three parameters: the first one points to the test
241case data, the second one specifies the meta-data variable to be set
242and the third one specifies its value.
243Both of them are strings.
244.Ss Configuration variables
245The test case has read-only access to the current configuration variables
246by means of the
247.Ft bool
248.Fn atf_tc_has_config_var ,
249.Ft const char *
250.Fn atf_tc_get_config_var ,
251.Ft const char *
252.Fn atf_tc_get_config_var_wd ,
253.Ft bool
254.Fn atf_tc_get_config_var_as_bool ,
255.Ft bool
256.Fn atf_tc_get_config_var_as_bool_wd ,
257.Ft long
258.Fn atf_tc_get_config_var_as_long ,
259and the
260.Ft long
261.Fn atf_tc_get_config_var_as_long_wd
262functions, which can be called in any of the three parts of a test case.
263.Pp
264The
265.Sq _wd
266variants take a default value for the variable which is returned if the
267variable is not defined.
268The other functions without the
269.Sq _wd
270suffix
271.Em require
272the variable to be defined.
273.Ss Access to the source directory
274It is possible to get the path to the test case's source directory from any
275of its three components by querying the
276.Sq srcdir
277configuration variable.
278.Ss Requiring programs
279Aside from the
280.Va require.progs
281meta-data variable available in the header only, one can also check for
282additional programs in the test case's body by using the
283.Fn atf_tc_require_prog
284function, which takes the base name or full path of a single binary.
285Relative paths are forbidden.
286If it is not found, the test case will be automatically skipped.
287.Ss Test case finalization
288The test case finalizes either when the body reaches its end, at which
289point the test is assumed to have
290.Em passed ,
291unless any non-fatal errors were raised using
292.Fn atf_tc_fail_nonfatal ,
293or at any explicit call to
294.Fn atf_tc_pass ,
295.Fn atf_tc_fail
296or
297.Fn atf_tc_skip .
298These three functions terminate the execution of the test case immediately.
299The cleanup routine will be processed afterwards in a completely automated
300way, regardless of the test case's termination reason.
301.Pp
302.Fn atf_tc_pass
303does not take any parameters.
304.Fn atf_tc_fail ,
305.Fn atf_tc_fail_nonfatal
306and
307.Fn atf_tc_skip
308take a format string and a variable list of parameters, which describe, in
309a user-friendly manner, why the test case failed or was skipped,
310respectively.
311It is very important to provide a clear error message in both cases so that
312the user can quickly know why the test did not pass.
313.Ss Expectations
314Everything explained in the previous section changes when the test case
315expectations are redefined by the programmer.
316.Pp
317Each test case has an internal state called
318.Sq expect
319that describes what the test case expectations are at any point in time.
320The value of this property can change during execution by any of:
321.Bl -tag -width indent
322.It Fn atf_tc_expect_death "reason" "..."
323Expects the test case to exit prematurely regardless of the nature of the
324exit.
325.It Fn atf_tc_expect_exit "exitcode" "reason" "..."
326Expects the test case to exit cleanly.
327If
328.Va exitcode
329is not
330.Sq -1 ,
331.Xr atf-run 1
332will validate that the exit code of the test case matches the one provided
333in this call.
334Otherwise, the exact value will be ignored.
335.It Fn atf_tc_expect_fail "reason" "..."
336Any failure (be it fatal or non-fatal) raised in this mode is recorded.
337However, such failures do not report the test case as failed; instead, the
338test case finalizes cleanly and is reported as
339.Sq expected failure ;
340this report includes the provided
341.Fa reason
342as part of it.
343If no error is raised while running in this mode, then the test case is
344reported as
345.Sq failed .
346.Pp
347This mode is useful to reproduce actual known bugs in tests.
348Whenever the developer fixes the bug later on, the test case will start
349reporting a failure, signaling the developer that the test case must be
350adjusted to the new conditions.
351In this situation, it is useful, for example, to set
352.Fa reason
353as the bug number for tracking purposes.
354.It Fn atf_tc_expect_pass
355This is the normal mode of execution.
356In this mode, any failure is reported as such to the user and the test case
357is marked as
358.Sq failed .
359.It Fn atf_tc_expect_signal "signo" "reason" "..."
360Expects the test case to terminate due to the reception of a signal.
361If
362.Va signo
363is not
364.Sq -1 ,
365.Xr atf-run 1
366will validate that the signal that terminated the test case matches the one
367provided in this call.
368Otherwise, the exact value will be ignored.
369.It Fn atf_tc_expect_timeout "reason" "..."
370Expects the test case to execute for longer than its timeout.
371.El
372.Ss Helper macros for common checks
373The library provides several macros that are very handy in multiple
374situations.
375These basically check some condition after executing a given statement or
376processing a given expression and, if the condition is not met, they
377report the test case as failed.
378.Pp
379The
380.Sq REQUIRE
381variant of the macros immediately abort the test case as soon as an error
382condition is detected by calling the
383.Fn atf_tc_fail
384function.
385Use this variant whenever it makes now sense to continue the execution of a
386test case when the checked condition is not met.
387The
388.Sq CHECK
389variant, on the other hand, reports a failure as soon as it is encountered
390using the
391.Fn atf_tc_fail_nonfatal
392function, but the execution of the test case continues as if nothing had
393happened.
394Use this variant whenever the checked condition is important as a result of
395the test case, but there are other conditions that can be subsequently
396checked on the same run without aborting.
397.Pp
398Additionally, the
399.Sq MSG
400variants take an extra set of parameters to explicitly specify the failure
401message.
402This failure message is formatted according to the
403.Xr printf 3
404formatters.
405.Pp
406.Fn ATF_CHECK ,
407.Fn ATF_CHECK_MSG ,
408.Fn ATF_REQUIRE
409and
410.Fn ATF_REQUIRE_MSG
411take an expression and fail if the expression evaluates to false.
412.Pp
413.Fn ATF_CHECK_EQ ,
414.Fn ATF_CHECK_EQ_MSG ,
415.Fn ATF_REQUIRE_EQ
416and
417.Fn ATF_REQUIRE_EQ_MSG
418take two expressions and fail if the two evaluated values are not equal.
419.Pp
420.Fn ATF_CHECK_STREQ ,
421.Fn ATF_CHECK_STREQ_MSG ,
422.Fn ATF_REQUIRE_STREQ
423and
424.Fn ATF_REQUIRE_STREQ_MSG
425take two strings and fail if the two are not equal character by character.
426.Pp
427.Fn ATF_CHECK_ERRNO
428and
429.Fn ATF_REQUIRE_ERRNO
430take, first, the error code that the check is expecting to find in the
431.Va errno
432variable and, second, a boolean expression that, if evaluates to true,
433means that a call failed and
434.Va errno
435has to be checked against the first value.
436.Sh EXAMPLES
437The following shows a complete test program with a single test case that
438validates the addition operator:
439.Bd -literal -offset indent
440#include <atf-c.h>
441
442ATF_TC(addition);
443ATF_TC_HEAD(addition, tc)
444{
445    atf_tc_set_md_var(tc, "descr",
446                      "Sample tests for the addition operator");
447}
448ATF_TC_BODY(addition, tc)
449{
450    ATF_CHECK_EQ(0 + 0, 0);
451    ATF_CHECK_EQ(0 + 1, 1);
452    ATF_CHECK_EQ(1 + 0, 1);
453
454    ATF_CHECK_EQ(1 + 1, 2);
455
456    ATF_CHECK_EQ(100 + 200, 300);
457}
458
459ATF_TC(string_formatting);
460ATF_TC_HEAD(string_formatting, tc)
461{
462    atf_tc_set_md_var(tc, "descr",
463                      "Sample tests for the snprintf");
464}
465ATF_TC_BODY(string_formatting, tc)
466{
467    char buf[1024];
468    snprintf(buf, sizeof(buf), "a %s", "string");
469    ATF_CHECK_STREQ_MSG("a string", buf, "%s is not working");
470}
471
472ATF_TC(open_failure);
473ATF_TC_HEAD(open_failure, tc)
474{
475    atf_tc_set_md_var(tc, "descr",
476                      "Sample tests for the open function");
477}
478ATF_TC_BODY(open_failure, tc)
479{
480    ATF_CHECK_ERRNO(ENOENT, open("non-existent", O_RDONLY) == -1);
481}
482
483ATF_TC(known_bug);
484ATF_TC_HEAD(known_bug, tc)
485{
486    atf_tc_set_md_var(tc, "descr",
487                      "Reproduces a known bug");
488}
489ATF_TC_BODY(known_bug, tc)
490{
491    atf_tc_expect_fail("See bug number foo/bar");
492    ATF_CHECK_EQ(3, 1 + 1);
493    atf_tc_expect_pass();
494    ATF_CHECK_EQ(3, 1 + 2);
495}
496
497ATF_TP_ADD_TCS(tp)
498{
499    ATF_TP_ADD_TC(tp, addition);
500    ATF_TP_ADD_TC(tp, string_formatting);
501    ATF_TP_ADD_TC(tp, open_failure);
502    ATF_TP_ADD_TC(tp, known_bug);
503
504    return atf_no_error();
505}
506.Ed
507.Sh SEE ALSO
508.Xr atf-test-program 1 ,
509.Xr atf-test-case 4 ,
510.Xr atf 7
511