1 .\" $NetBSD: atf-c-api.3,v 1.3 2014/12/10 04:38:03 christos Exp $
4 .\" Automated Testing Framework (atf)
6 .\" Copyright (c) 2008 The NetBSD Foundation, Inc.
7 .\" All rights reserved.
9 .\" Redistribution and use in source and binary forms, with or without
10 .\" modification, are permitted provided that the following conditions
12 .\" 1. Redistributions of source code must retain the above copyright
13 .\" notice, this list of conditions and the following disclaimer.
14 .\" 2. Redistributions in binary form must reproduce the above copyright
15 .\" notice, this list of conditions and the following disclaimer in the
16 .\" documentation and/or other materials provided with the distribution.
18 .\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
19 .\" CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
20 .\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21 .\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 .\" IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
23 .\" DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
25 .\" GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 .\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
27 .\" IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28 .\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
29 .\" IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 .Nm ATF_CHECK_EQ_MSG ,
41 .Nm ATF_CHECK_MATCH_MSG ,
43 .Nm ATF_CHECK_STREQ_MSG ,
48 .Nm ATF_REQUIRE_EQ_MSG ,
49 .Nm ATF_REQUIRE_MATCH ,
50 .Nm ATF_REQUIRE_MATCH_MSG ,
51 .Nm ATF_REQUIRE_STREQ ,
52 .Nm ATF_REQUIRE_STREQ_MSG ,
53 .Nm ATF_REQUIRE_ERRNO ,
56 .Nm ATF_TC_BODY_NAME ,
58 .Nm ATF_TC_CLEANUP_NAME ,
60 .Nm ATF_TC_HEAD_NAME ,
62 .Nm ATF_TC_WITH_CLEANUP ,
63 .Nm ATF_TC_WITHOUT_HEAD ,
66 .Nm atf_tc_get_config_var ,
67 .Nm atf_tc_get_config_var_wd ,
68 .Nm atf_tc_get_config_var_as_bool ,
69 .Nm atf_tc_get_config_var_as_bool_wd ,
70 .Nm atf_tc_get_config_var_as_long ,
71 .Nm atf_tc_get_config_var_as_long_wd ,
73 .Nm atf_tc_expect_death ,
74 .Nm atf_tc_expect_exit ,
75 .Nm atf_tc_expect_fail ,
76 .Nm atf_tc_expect_pass ,
77 .Nm atf_tc_expect_signal ,
78 .Nm atf_tc_expect_timeout ,
80 .Nm atf_tc_fail_nonfatal ,
83 .Nm atf_utils_cat_file ,
84 .Nm atf_utils_compare_file ,
85 .Nm atf_utils_copy_file ,
86 .Nm atf_utils_create_file ,
87 .Nm atf_utils_file_exists ,
89 .Nm atf_utils_free_charpp ,
90 .Nm atf_utils_grep_file ,
91 .Nm atf_utils_grep_string ,
92 .Nm atf_utils_readline ,
93 .Nm atf_utils_redirect ,
95 .Nd C API to write ATF-based test programs
98 .Fn ATF_CHECK "expression"
99 .Fn ATF_CHECK_MSG "expression" "fail_msg_fmt" ...
100 .Fn ATF_CHECK_EQ "expression_1" "expression_2"
101 .Fn ATF_CHECK_EQ_MSG "expression_1" "expression_2" "fail_msg_fmt" ...
102 .Fn ATF_CHECK_MATCH "regexp" "string"
103 .Fn ATF_CHECK_MATCH_MSG "regexp" "string" "fail_msg_fmt" ...
104 .Fn ATF_CHECK_STREQ "string_1" "string_2"
105 .Fn ATF_CHECK_STREQ_MSG "string_1" "string_2" "fail_msg_fmt" ...
106 .Fn ATF_CHECK_ERRNO "exp_errno" "bool_expression"
107 .Fn ATF_REQUIRE "expression"
108 .Fn ATF_REQUIRE_MSG "expression" "fail_msg_fmt" ...
109 .Fn ATF_REQUIRE_EQ "expression_1" "expression_2"
110 .Fn ATF_REQUIRE_EQ_MSG "expression_1" "expression_2" "fail_msg_fmt" ...
111 .Fn ATF_REQUIRE_MATCH "regexp" "string"
112 .Fn ATF_REQUIRE_MATCH_MSG "regexp" "string" "fail_msg_fmt" ...
113 .Fn ATF_REQUIRE_STREQ "string_1" "string_2"
114 .Fn ATF_REQUIRE_STREQ_MSG "string_1" "string_2" "fail_msg_fmt" ...
115 .Fn ATF_REQUIRE_ERRNO "exp_errno" "bool_expression"
117 .Fn ATF_TC_BODY "name" "tc"
118 .Fn ATF_TC_BODY_NAME "name"
119 .Fn ATF_TC_CLEANUP "name" "tc"
120 .Fn ATF_TC_CLEANUP_NAME "name"
121 .Fn ATF_TC_HEAD "name" "tc"
122 .Fn ATF_TC_HEAD_NAME "name"
123 .Fn ATF_TC_NAME "name"
124 .Fn ATF_TC_WITH_CLEANUP "name"
125 .Fn ATF_TC_WITHOUT_HEAD "name"
126 .Fn ATF_TP_ADD_TC "tp_name" "tc_name"
127 .Fn ATF_TP_ADD_TCS "tp_name"
128 .Fn atf_tc_get_config_var "tc" "varname"
129 .Fn atf_tc_get_config_var_wd "tc" "variable_name" "default_value"
130 .Fn atf_tc_get_config_var_as_bool "tc" "variable_name"
131 .Fn atf_tc_get_config_var_as_bool_wd "tc" "variable_name" "default_value"
132 .Fn atf_tc_get_config_var_as_long "tc" "variable_name"
133 .Fn atf_tc_get_config_var_as_long_wd "tc" "variable_name" "default_value"
135 .Fn atf_tc_expect_death "reason" "..."
136 .Fn atf_tc_expect_exit "exitcode" "reason" "..."
137 .Fn atf_tc_expect_fail "reason" "..."
138 .Fn atf_tc_expect_pass
139 .Fn atf_tc_expect_signal "signo" "reason" "..."
140 .Fn atf_tc_expect_timeout "reason" "..."
141 .Fn atf_tc_fail "reason"
142 .Fn atf_tc_fail_nonfatal "reason"
144 .Fn atf_tc_skip "reason"
146 .Fo atf_utils_cat_file
147 .Fa "const char *file"
148 .Fa "const char *prefix"
151 .Fo atf_utils_compare_file
152 .Fa "const char *file"
153 .Fa "const char *contents"
156 .Fo atf_utils_copy_file
157 .Fa "const char *source"
158 .Fa "const char *destination"
161 .Fo atf_utils_create_file
162 .Fa "const char *file"
163 .Fa "const char *contents"
167 .Fo atf_utils_file_exists
168 .Fa "const char *file"
175 .Fo atf_utils_free_charpp
179 .Fo atf_utils_grep_file
180 .Fa "const char *regexp"
181 .Fa "const char *file"
185 .Fo atf_utils_grep_string
186 .Fa "const char *regexp"
187 .Fa "const char *str"
191 .Fo atf_utils_readline
195 .Fo atf_utils_redirect
197 .Fa "const char *file"
201 .Fa "const pid_t pid"
202 .Fa "const int expected_exit_status"
203 .Fa "const char *expected_stdout"
204 .Fa "const char *expected_stderr"
209 C-based test programs always follow this template:
210 .Bd -literal -offset indent
211 .Ns ... C-specific includes go here ...
218 ... first test case's header ...
222 ... first test case's body ...
225 ATF_TC_WITH_CLEANUP(tc2);
228 ... second test case's header ...
232 ... second test case's body ...
234 ATF_TC_CLEANUP(tc2, tc)
236 ... second test case's cleanup ...
239 ATF_TC_WITHOUT_HEAD(tc3);
242 ... third test case's body ...
245 .Ns ... additional test cases ...
249 ATF_TP_ADD_TC(tcs, tc1);
250 ATF_TP_ADD_TC(tcs, tc2);
251 ATF_TP_ADD_TC(tcs, tc3);
252 ... add additional test cases ...
254 return atf_no_error();
257 .Ss Definition of test cases
258 Test cases have an identifier and are composed of three different parts:
259 the header, the body and an optional cleanup routine, all of which are
261 .Xr atf-test-case 4 .
262 To define test cases, one can use the
264 .Fn ATF_TC_WITH_CLEANUP
266 .Fn ATF_TC_WITHOUT_HEAD
267 macros, which take a single parameter specifiying the test case's name.
269 requires to define a head and a body for the test case,
270 .Fn ATF_TC_WITH_CLEANUP
271 requires to define a head, a body and a cleanup for the test case and
272 .Fn ATF_TC_WITHOUT_HEAD
273 requires only a body for the test case.
274 It is important to note that these
276 set the test case up for execution when the program is run.
277 In order to do so, a later registration is needed with the
280 .Sx Program initialization .
282 Later on, one must define the three parts of the body by means of three
284 Their headers are given by the
289 macros, all of which take the test case name provided to the
291 .Fn ATF_TC_WITH_CLEANUP ,
293 .Fn ATF_TC_WITHOUT_HEAD
294 macros and the name of the variable that will hold a pointer to the
296 Following each of these, a block of code is expected, surrounded by the
297 opening and closing brackets.
298 .Ss Program initialization
299 The library provides a way to easily define the test program's
302 You should never define one on your own, but rely on the
303 library to do it for you.
304 This is done by using the
306 macro, which is passed the name of the object that will hold the test
307 cases; i.e. the test program instance.
308 This name can be whatever you want as long as it is a valid variable
311 After the macro, you are supposed to provide the body of a function, which
314 macro to register the test cases the test program will execute and return
315 a success error code.
316 The first parameter of this macro matches the name you provided in the
318 The success status can be returned using the
321 .Ss Header definitions
322 The test case's header can define the meta-data by using the
323 .Fn atf_tc_set_md_var
324 method, which takes three parameters: the first one points to the test
325 case data, the second one specifies the meta-data variable to be set
326 and the third one specifies its value.
327 Both of them are strings.
328 .Ss Configuration variables
329 The test case has read-only access to the current configuration variables
332 .Fn atf_tc_has_config_var ,
334 .Fn atf_tc_get_config_var ,
336 .Fn atf_tc_get_config_var_wd ,
338 .Fn atf_tc_get_config_var_as_bool ,
340 .Fn atf_tc_get_config_var_as_bool_wd ,
342 .Fn atf_tc_get_config_var_as_long ,
345 .Fn atf_tc_get_config_var_as_long_wd
346 functions, which can be called in any of the three parts of a test case.
350 variants take a default value for the variable which is returned if the
351 variable is not defined.
352 The other functions without the
356 the variable to be defined.
357 .Ss Access to the source directory
358 It is possible to get the path to the test case's source directory from any
359 of its three components by querying the
361 configuration variable.
362 .Ss Requiring programs
365 meta-data variable available in the header only, one can also check for
366 additional programs in the test case's body by using the
367 .Fn atf_tc_require_prog
368 function, which takes the base name or full path of a single binary.
369 Relative paths are forbidden.
370 If it is not found, the test case will be automatically skipped.
371 .Ss Test case finalization
372 The test case finalizes either when the body reaches its end, at which
373 point the test is assumed to have
375 unless any non-fatal errors were raised using
376 .Fn atf_tc_fail_nonfatal ,
377 or at any explicit call to
382 These three functions terminate the execution of the test case immediately.
383 The cleanup routine will be processed afterwards in a completely automated
384 way, regardless of the test case's termination reason.
387 does not take any parameters.
389 .Fn atf_tc_fail_nonfatal
392 take a format string and a variable list of parameters, which describe, in
393 a user-friendly manner, why the test case failed or was skipped,
395 It is very important to provide a clear error message in both cases so that
396 the user can quickly know why the test did not pass.
398 Everything explained in the previous section changes when the test case
399 expectations are redefined by the programmer.
401 Each test case has an internal state called
403 that describes what the test case expectations are at any point in time.
404 The value of this property can change during execution by any of:
405 .Bl -tag -width indent
406 .It Fn atf_tc_expect_death "reason" "..."
407 Expects the test case to exit prematurely regardless of the nature of the
409 .It Fn atf_tc_expect_exit "exitcode" "reason" "..."
410 Expects the test case to exit cleanly.
416 will validate that the exit code of the test case matches the one provided
418 Otherwise, the exact value will be ignored.
419 .It Fn atf_tc_expect_fail "reason" "..."
420 Any failure (be it fatal or non-fatal) raised in this mode is recorded.
421 However, such failures do not report the test case as failed; instead, the
422 test case finalizes cleanly and is reported as
423 .Sq expected failure ;
424 this report includes the provided
427 If no error is raised while running in this mode, then the test case is
431 This mode is useful to reproduce actual known bugs in tests.
432 Whenever the developer fixes the bug later on, the test case will start
433 reporting a failure, signaling the developer that the test case must be
434 adjusted to the new conditions.
435 In this situation, it is useful, for example, to set
437 as the bug number for tracking purposes.
438 .It Fn atf_tc_expect_pass
439 This is the normal mode of execution.
440 In this mode, any failure is reported as such to the user and the test case
443 .It Fn atf_tc_expect_signal "signo" "reason" "..."
444 Expects the test case to terminate due to the reception of a signal.
450 will validate that the signal that terminated the test case matches the one
451 provided in this call.
452 Otherwise, the exact value will be ignored.
453 .It Fn atf_tc_expect_timeout "reason" "..."
454 Expects the test case to execute for longer than its timeout.
456 .Ss Helper macros for common checks
457 The library provides several macros that are very handy in multiple
459 These basically check some condition after executing a given statement or
460 processing a given expression and, if the condition is not met, they
461 report the test case as failed.
465 variant of the macros immediately abort the test case as soon as an error
466 condition is detected by calling the
469 Use this variant whenever it makes no sense to continue the execution of a
470 test case when the checked condition is not met.
473 variant, on the other hand, reports a failure as soon as it is encountered
475 .Fn atf_tc_fail_nonfatal
476 function, but the execution of the test case continues as if nothing had
478 Use this variant whenever the checked condition is important as a result of
479 the test case, but there are other conditions that can be subsequently
480 checked on the same run without aborting.
484 variants take an extra set of parameters to explicitly specify the failure
486 This failure message is formatted according to the
495 take an expression and fail if the expression evaluates to false.
498 .Fn ATF_CHECK_EQ_MSG ,
501 .Fn ATF_REQUIRE_EQ_MSG
502 take two expressions and fail if the two evaluated values are not equal.
504 .Fn ATF_CHECK_MATCH ,
505 .Fn ATF_CHECK_MATCH_MSG ,
506 .Fn ATF_REQUIRE_MATCH
508 .Fn ATF_REQUIRE_MATCH_MSG
509 take a regular expression and a string and fail if the regular expression does
510 not match the given string.
511 Note that the regular expression is not anchored, so it will match anywhere in
514 .Fn ATF_CHECK_STREQ ,
515 .Fn ATF_CHECK_STREQ_MSG ,
516 .Fn ATF_REQUIRE_STREQ
518 .Fn ATF_REQUIRE_STREQ_MSG
519 take two strings and fail if the two are not equal character by character.
523 .Fn ATF_REQUIRE_ERRNO
524 take, first, the error code that the check is expecting to find in the
526 variable and, second, a boolean expression that, if evaluates to true,
527 means that a call failed and
529 has to be checked against the first value.
530 .Ss Utility functions
531 The following functions are provided as part of the
533 API to simplify the creation of a variety of tests.
534 In particular, these are useful to write tests for command-line interfaces.
537 .Fo atf_utils_cat_file
538 .Fa "const char *file"
539 .Fa "const char *prefix"
542 Prints the contents of
544 to the standard output, prefixing every line with the string in
549 .Fo atf_utils_compare_file
550 .Fa "const char *file"
551 .Fa "const char *contents"
554 Returns true if the given
556 matches exactly the expected inlined
561 .Fo atf_utils_copy_file
562 .Fa "const char *source"
563 .Fa "const char *destination"
570 The permissions of the file are preserved during the code.
574 .Fo atf_utils_create_file
575 .Fa "const char *file"
576 .Fa "const char *contents"
582 with the text given in
584 which is a formatting string that uses the rest of the variable arguments.
588 .Fo atf_utils_file_exists
589 .Fa "const char *file"
602 Forks a process and redirects the standard output and standard error of the
603 child to files for later validation with
605 Fails the test case if the fork fails, so this does not return an error.
609 .Fo atf_utils_free_charpp
613 Frees a dynamically-allocated array of dynamically-allocated strings.
617 .Fo atf_utils_grep_file
618 .Fa "const char *regexp"
619 .Fa "const char *file"
625 which is a formatting string representing the regular expression,
628 The variable arguments are used to construct the regular expression.
632 .Fo atf_utils_grep_string
633 .Fa "const char *regexp"
634 .Fa "const char *str"
640 which is a formatting string representing the regular expression,
641 in the literal string
643 The variable arguments are used to construct the regular expression.
647 .Fo atf_utils_readline
651 Reads a line from the file descriptor
653 The line, if any, is returned as a dynamically-allocated buffer that must be
656 If there was nothing to read, returns
661 .Fo atf_utils_redirect
663 .Fa "const char *file"
666 Redirects the given file descriptor
670 This function exits the process in case of an error and does not properly mark
671 the test case as failed.
672 As a result, it should only be used in subprocesses of the test case; specially
679 .Fa "const pid_t pid"
680 .Fa "const int expected_exit_status"
681 .Fa "const char *expected_stdout"
682 .Fa "const char *expected_stderr"
685 Waits and validates the result of a subprocess spawned with
687 The validation involves checking that the subprocess exited cleanly and returned
688 the code specified in
689 .Fa expected_exit_status
690 and that its standard output and standard error match the strings given in
693 .Fa expected_stderr .
699 strings are prefixed with
701 then they specify the name of the file into which to store the stdout or stderr
702 of the subprocess, and no comparison is performed.
705 The following shows a complete test program with a single test case that
706 validates the addition operator:
707 .Bd -literal -offset indent
711 ATF_TC_HEAD(addition, tc)
713 atf_tc_set_md_var(tc, "descr",
714 "Sample tests for the addition operator");
716 ATF_TC_BODY(addition, tc)
718 ATF_CHECK_EQ(0 + 0, 0);
719 ATF_CHECK_EQ(0 + 1, 1);
720 ATF_CHECK_EQ(1 + 0, 1);
722 ATF_CHECK_EQ(1 + 1, 2);
724 ATF_CHECK_EQ(100 + 200, 300);
727 ATF_TC(string_formatting);
728 ATF_TC_HEAD(string_formatting, tc)
730 atf_tc_set_md_var(tc, "descr",
731 "Sample tests for the snprintf");
733 ATF_TC_BODY(string_formatting, tc)
736 snprintf(buf, sizeof(buf), "a %s", "string");
737 ATF_CHECK_STREQ_MSG("a string", buf, "%s is not working");
740 ATF_TC(open_failure);
741 ATF_TC_HEAD(open_failure, tc)
743 atf_tc_set_md_var(tc, "descr",
744 "Sample tests for the open function");
746 ATF_TC_BODY(open_failure, tc)
748 ATF_CHECK_ERRNO(ENOENT, open("non-existent", O_RDONLY) == -1);
752 ATF_TC_HEAD(known_bug, tc)
754 atf_tc_set_md_var(tc, "descr",
755 "Reproduces a known bug");
757 ATF_TC_BODY(known_bug, tc)
759 atf_tc_expect_fail("See bug number foo/bar");
760 ATF_CHECK_EQ(3, 1 + 1);
761 atf_tc_expect_pass();
762 ATF_CHECK_EQ(3, 1 + 2);
767 ATF_TP_ADD_TC(tp, addition);
768 ATF_TP_ADD_TC(tp, string_formatting);
769 ATF_TP_ADD_TC(tp, open_failure);
770 ATF_TP_ADD_TC(tp, known_bug);
772 return atf_no_error();
776 .Xr atf-test-program 1 ,
777 .Xr atf-test-case 4 ,