xref: /freebsd/contrib/atf/atf-c/atf-c.3 (revision 2a678ff8907fa0197e65bd9b9f0e4b5a3b236b20)
1.\" Copyright (c) 2008 The NetBSD Foundation, Inc.
2.\" All rights reserved.
3.\"
4.\" Redistribution and use in source and binary forms, with or without
5.\" modification, are permitted provided that the following conditions
6.\" are met:
7.\" 1. Redistributions of source code must retain the above copyright
8.\"    notice, this list of conditions and the following disclaimer.
9.\" 2. Redistributions in binary form must reproduce the above copyright
10.\"    notice, this list of conditions and the following disclaimer in the
11.\"    documentation and/or other materials provided with the distribution.
12.\"
13.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
14.\" CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
15.\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17.\" IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
18.\" DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
20.\" GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
22.\" IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23.\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
24.\" IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25.Dd June 12, 2025
26.Dt ATF-C 3
27.Os
28.Sh NAME
29.Nm atf-c ,
30.Nm ATF_CHECK ,
31.Nm ATF_CHECK_MSG ,
32.Nm ATF_CHECK_EQ ,
33.Nm ATF_CHECK_EQ_MSG ,
34.Nm ATF_CHECK_MATCH ,
35.Nm ATF_CHECK_MATCH_MSG ,
36.Nm ATF_CHECK_STREQ ,
37.Nm ATF_CHECK_STREQ_MSG ,
38.Nm ATF_CHECK_INTEQ ,
39.Nm ATF_CHECK_INTEQ_MSG ,
40.Nm ATF_CHECK_ERRNO ,
41.Nm ATF_REQUIRE ,
42.Nm ATF_REQUIRE_MSG ,
43.Nm ATF_REQUIRE_EQ ,
44.Nm ATF_REQUIRE_EQ_MSG ,
45.Nm ATF_REQUIRE_MATCH ,
46.Nm ATF_REQUIRE_MATCH_MSG ,
47.Nm ATF_REQUIRE_STREQ ,
48.Nm ATF_REQUIRE_STREQ_MSG ,
49.Nm ATF_REQUIRE_INTEQ ,
50.Nm ATF_REQUIRE_INTEQ_MSG ,
51.Nm ATF_REQUIRE_ERRNO ,
52.Nm ATF_TC ,
53.Nm ATF_TC_BODY ,
54.Nm ATF_TC_BODY_NAME ,
55.Nm ATF_TC_CLEANUP ,
56.Nm ATF_TC_CLEANUP_NAME ,
57.Nm ATF_TC_HEAD ,
58.Nm ATF_TC_HEAD_NAME ,
59.Nm ATF_TC_NAME ,
60.Nm ATF_TC_WITH_CLEANUP ,
61.Nm ATF_TC_WITHOUT_HEAD ,
62.Nm ATF_TP_ADD_TC ,
63.Nm ATF_TP_ADD_TCS ,
64.Nm atf_tc_get_config_var ,
65.Nm atf_tc_get_config_var_wd ,
66.Nm atf_tc_get_config_var_as_bool ,
67.Nm atf_tc_get_config_var_as_bool_wd ,
68.Nm atf_tc_get_config_var_as_long ,
69.Nm atf_tc_get_config_var_as_long_wd ,
70.Nm atf_no_error ,
71.Nm atf_tc_expect_death ,
72.Nm atf_tc_expect_exit ,
73.Nm atf_tc_expect_fail ,
74.Nm atf_tc_expect_pass ,
75.Nm atf_tc_expect_signal ,
76.Nm atf_tc_expect_timeout ,
77.Nm atf_tc_fail ,
78.Nm atf_tc_fail_nonfatal ,
79.Nm atf_tc_pass ,
80.Nm atf_tc_require_kmod ,
81.Nm atf_tc_require_prog ,
82.Nm atf_tc_skip ,
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 ,
88.Nm atf_utils_fork ,
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 ,
94.Nm atf_utils_wait
95.Nd C API to write ATF-based test programs
96.Sh SYNOPSIS
97.In atf-c.h
98.\" NO_CHECK_STYLE_BEGIN
99.Fn ATF_CHECK "expression"
100.Fn ATF_CHECK_MSG "expression" "fail_msg_fmt" ...
101.Fn ATF_CHECK_EQ "expected_expression" "actual_expression"
102.Fn ATF_CHECK_EQ_MSG "expected_expression" "actual_expression" "fail_msg_fmt" ...
103.Fn ATF_CHECK_MATCH "regexp" "string"
104.Fn ATF_CHECK_MATCH_MSG "regexp" "string" "fail_msg_fmt" ...
105.Fn ATF_CHECK_STREQ "expected_string" "actual_string"
106.Fn ATF_CHECK_STREQ_MSG "expected_string" "actual_string" "fail_msg_fmt" ...
107.Fn ATF_CHECK_INTEQ "expected_int" "actual_int"
108.Fn ATF_CHECK_INTEQ_MSG "expected_int" "actual_int" "fail_msg_fmt" ...
109.Fn ATF_CHECK_ERRNO "expected_errno" "bool_expression"
110.Fn ATF_REQUIRE "expression"
111.Fn ATF_REQUIRE_MSG "expression" "fail_msg_fmt" ...
112.Fn ATF_REQUIRE_EQ "expected_expression" "actual_expression"
113.Fn ATF_REQUIRE_EQ_MSG "expected_expression" "actual_expression" "fail_msg_fmt" ...
114.Fn ATF_REQUIRE_MATCH "regexp" "string"
115.Fn ATF_REQUIRE_MATCH_MSG "regexp" "string" "fail_msg_fmt" ...
116.Fn ATF_REQUIRE_STREQ "expected_string" "actual_string"
117.Fn ATF_REQUIRE_STREQ_MSG "expected_string" "actual_string" "fail_msg_fmt" ...
118.Fn ATF_REQUIRE_INTEQ "expected_int" "actual_int"
119.Fn ATF_REQUIRE_INTEQ_MSG "expected_int" "actual_int" "fail_msg_fmt" ...
120.Fn ATF_REQUIRE_ERRNO "expected_errno" "bool_expression"
121.\" NO_CHECK_STYLE_END
122.Fn ATF_TC "name"
123.Fn ATF_TC_BODY "name" "tc"
124.Fn ATF_TC_BODY_NAME "name"
125.Fn ATF_TC_CLEANUP "name" "tc"
126.Fn ATF_TC_CLEANUP_NAME "name"
127.Fn ATF_TC_HEAD "name" "tc"
128.Fn ATF_TC_HEAD_NAME "name"
129.Fn ATF_TC_NAME "name"
130.Fn ATF_TC_WITH_CLEANUP "name"
131.Fn ATF_TC_WITHOUT_HEAD "name"
132.Fn ATF_TP_ADD_TC "tp_name" "tc_name"
133.Fn ATF_TP_ADD_TCS "tp_name"
134.Ft const char*
135.Fo atf_tc_get_config_var
136.Fa "const atf_tc_t *tc"
137.Fa "const char *name"
138.Fc
139.Ft const char*
140.Fo atf_tc_get_config_var_wd
141.Fa "const atf_tc_t *tc"
142.Fa "const char *name"
143.Fa "const char *defval"
144.Fc
145.Ft bool
146.Fo atf_tc_get_config_var_as_bool
147.Fa "const atf_tc_t *tc"
148.Fa "const char *name"
149.Fc
150.Ft bool
151.Fo atf_tc_get_config_var_as_bool_wd
152.Fa "const atf_tc_t *tc"
153.Fa "const char *name"
154.Fa "const bool defval"
155.Fc
156.Ft long
157.Fo atf_tc_get_config_var_as_long
158.Fa "const atf_tc_t *tc"
159.Fa "const char *name"
160.Fc
161.Ft long
162.Fo atf_tc_get_config_var_as_long_wd
163.Fa "const atf_tc_t *tc"
164.Fa "const char *name"
165.Fa "const long defval"
166.Fc
167.Ft void
168.Fo atf_no_error
169.Fa "void"
170.Fc
171.Ft void
172.Fo atf_tc_expect_death
173.Fa "const char *reason"
174.Fa "..."
175.Fc
176.Ft void
177.Fo atf_tc_expect_exit
178.Fa "const int exitcode"
179.Fa "const char *reason"
180.Fa "..."
181.Fc
182.Ft void
183.Fo atf_tc_expect_fail
184.Fa "const char *reason"
185.Fa "..."
186.Fc
187.Ft void
188.Fo atf_tc_expect_pass
189.Fa "void"
190.Fc
191.Ft void
192.Fo atf_tc_expect_signal
193.Fa "const int signo"
194.Fa "const char *reason"
195.Fa "..."
196.Fc
197.Ft void
198.Fo atf_tc_expect_timeout
199.Fa "const char *reason"
200.Fa "..."
201.Fc
202.Ft void
203.Fo atf_tc_fail
204.Fa "const char *reason"
205.Fc
206.Ft void
207.Fo atf_tc_fail_nonfatal
208.Fa "const char *reason"
209.Fc
210.Ft void
211.Fo atf_tc_pass
212.Fa "void"
213.Fc
214.Ft void
215.Fo atf_tc_require_kmod
216.Fa "const char *kmod"
217.Fc
218.Ft void
219.Fo atf_tc_require_prog
220.Fa "const char *prog"
221.Fc
222.Ft void
223.Fo atf_tc_skip
224.Fa "const char *reason"
225.Fc
226.Ft void
227.Fo atf_utils_cat_file
228.Fa "const char *file"
229.Fa "const char *prefix"
230.Fc
231.Ft bool
232.Fo atf_utils_compare_file
233.Fa "const char *file"
234.Fa "const char *contents"
235.Fc
236.Ft void
237.Fo atf_utils_copy_file
238.Fa "const char *source"
239.Fa "const char *destination"
240.Fc
241.Ft void
242.Fo atf_utils_create_file
243.Fa "const char *file"
244.Fa "const char *contents"
245.Fa "..."
246.Fc
247.Ft void
248.Fo atf_utils_file_exists
249.Fa "const char *file"
250.Fc
251.Ft pid_t
252.Fo atf_utils_fork
253.Fa "void"
254.Fc
255.Ft void
256.Fo atf_utils_free_charpp
257.Fa "char **argv"
258.Fc
259.Ft bool
260.Fo atf_utils_grep_file
261.Fa "const char *regexp"
262.Fa "const char *file"
263.Fa "..."
264.Fc
265.Ft bool
266.Fo atf_utils_grep_string
267.Fa "const char *regexp"
268.Fa "const char *str"
269.Fa "..."
270.Fc
271.Ft char *
272.Fo atf_utils_readline
273.Fa "int fd"
274.Fc
275.Ft void
276.Fo atf_utils_redirect
277.Fa "const int fd"
278.Fa "const char *file"
279.Fc
280.Ft void
281.Fo atf_utils_wait
282.Fa "const pid_t pid"
283.Fa "const int expected_exit_status"
284.Fa "const char *expected_stdout"
285.Fa "const char *expected_stderr"
286.Fc
287.Sh DESCRIPTION
288ATF provides a C programming interface to implement test programs.
289C-based test programs follow this template:
290.Bd -literal -offset indent
291\&... C-specific includes go here ...
292
293#include <atf-c.h>
294
295ATF_TC(tc1);
296ATF_TC_HEAD(tc1, tc)
297{
298    ... first test case's header ...
299}
300ATF_TC_BODY(tc1, tc)
301{
302    ... first test case's body ...
303}
304
305ATF_TC_WITH_CLEANUP(tc2);
306ATF_TC_HEAD(tc2, tc)
307{
308    ... second test case's header ...
309}
310ATF_TC_BODY(tc2, tc)
311{
312    ... second test case's body ...
313}
314ATF_TC_CLEANUP(tc2, tc)
315{
316    ... second test case's cleanup ...
317}
318
319ATF_TC_WITHOUT_HEAD(tc3);
320ATF_TC_BODY(tc3, tc)
321{
322    ... third test case's body ...
323}
324
325\&... additional test cases ...
326
327ATF_TP_ADD_TCS(tp)
328{
329    ATF_TP_ADD_TC(tcs, tc1);
330    ATF_TP_ADD_TC(tcs, tc2);
331    ATF_TP_ADD_TC(tcs, tc3);
332    ... add additional test cases ...
333
334    return atf_no_error();
335}
336.Ed
337.Ss Definition of test cases
338Test cases have an identifier and are composed of three different parts:
339the header, the body and an optional cleanup routine, all of which are
340described in
341.Xr atf-test-case 4 .
342To define test cases, one can use the
343.Fn ATF_TC ,
344.Fn ATF_TC_WITH_CLEANUP
345or the
346.Fn ATF_TC_WITHOUT_HEAD
347macros, which take a single parameter specifying the test case's name.
348.Fn ATF_TC ,
349requires to define a head and a body for the test case,
350.Fn ATF_TC_WITH_CLEANUP
351requires to define a head, a body and a cleanup for the test case and
352.Fn ATF_TC_WITHOUT_HEAD
353requires only a body for the test case.
354It is important to note that these
355.Em do not
356set the test case up for execution when the program is run.
357In order to do so, a later registration is needed with the
358.Fn ATF_TP_ADD_TC
359macro detailed in
360.Sx Program initialization .
361.Pp
362Later on, one must define the three parts of the body by means of three
363functions.
364Their headers are given by the
365.Fn ATF_TC_HEAD ,
366.Fn ATF_TC_BODY
367and
368.Fn ATF_TC_CLEANUP
369macros, all of which take the test case name provided to the
370.Fn ATF_TC
371.Fn ATF_TC_WITH_CLEANUP ,
372or
373.Fn ATF_TC_WITHOUT_HEAD
374macros and the name of the variable that will hold a pointer to the
375test case data.
376Following each of these, a block of code is expected, surrounded by the
377opening and closing brackets.
378.Ss Program initialization
379The library provides a way to easily define the test program's
380.Fn main
381function.
382You should never define one on your own, but rely on the
383library to do it for you.
384This is done by using the
385.Fn ATF_TP_ADD_TCS
386macro, which is passed the name of the object that will hold the test
387cases, i.e., the test program instance.
388This name can be whatever you want as long as it is a valid variable
389identifier.
390.Pp
391After the macro, you are supposed to provide the body of a function, which
392should only use the
393.Fn ATF_TP_ADD_TC
394macro to register the test cases the test program will execute and return
395a success error code.
396The first parameter of this macro matches the name you provided in the
397former call.
398The success status can be returned using the
399.Fn atf_no_error
400function.
401.Ss Header definitions
402The test case's header can define the meta-data by using the
403.Fn atf_tc_set_md_var
404method, which takes three parameters: the first one points to the test
405case data, the second one specifies the meta-data variable to be set
406and the third one specifies its value.
407Both of them are strings.
408.Ss Configuration variables
409The test case has read-only access to the current configuration variables
410by means of the
411.Ft bool
412.Fn atf_tc_has_config_var ,
413.Ft const char *
414.Fn atf_tc_get_config_var ,
415.Ft const char *
416.Fn atf_tc_get_config_var_wd ,
417.Ft bool
418.Fn atf_tc_get_config_var_as_bool ,
419.Ft bool
420.Fn atf_tc_get_config_var_as_bool_wd ,
421.Ft long
422.Fn atf_tc_get_config_var_as_long ,
423and the
424.Ft long
425.Fn atf_tc_get_config_var_as_long_wd
426functions, which can be called in any of the three parts of a test case.
427.Pp
428The
429.Sq _wd
430variants take a default value for the variable which is returned if the
431variable is not defined.
432The other functions without the
433.Sq _wd
434suffix
435.Em require
436the variable to be defined.
437.Ss Access to the source directory
438It is possible to get the path to the test case's source directory from any
439of its three components by querying the
440.Sq srcdir
441configuration variable.
442.Ss Requiring kernel modules
443Aside from the
444.Va require.kmods
445meta-data variable available in the header only, one can also check for
446additional kernel modules in the test case's body by using the
447.Fn atf_tc_require_kmod
448function, which takes the name of a single kernel module.
449If it is not found, the test case will be automatically skipped.
450.Ss Requiring programs
451Aside from the
452.Va require.progs
453meta-data variable available in the header only, one can also check for
454additional programs in the test case's body by using the
455.Fn atf_tc_require_prog
456function, which takes the base name or full path of a single binary.
457Relative paths are forbidden.
458If it is not found, the test case will be automatically skipped.
459.Ss Test case finalization
460The test case finalizes either when the body reaches its end, at which
461point the test is assumed to have
462.Em passed ,
463unless any non-fatal errors were raised using
464.Fn atf_tc_fail_nonfatal ,
465or at any explicit call to
466.Fn atf_tc_pass ,
467.Fn atf_tc_fail
468or
469.Fn atf_tc_skip .
470These three functions terminate the execution of the test case immediately.
471The cleanup routine will be processed afterwards in a completely automated
472way, regardless of the test case's termination reason.
473.Pp
474.Fn atf_tc_pass
475does not take any parameters.
476.Fn atf_tc_fail ,
477.Fn atf_tc_fail_nonfatal
478and
479.Fn atf_tc_skip
480take a format string and a variable list of parameters, which describe, in
481a user-friendly manner, why the test case failed or was skipped,
482respectively.
483It is very important to provide a clear error message in both cases so that
484the user can quickly know why the test did not pass.
485.Ss Expectations
486Everything explained in the previous section changes when the test case
487expectations are redefined by the programmer.
488.Pp
489Each test case has an internal state called
490.Sq expect
491that describes what the test case expectations are at any point in time.
492The value of this property can change during execution by any of:
493.Bl -tag -width indent
494.It Fn atf_tc_expect_death "reason" "..."
495Expects the test case to exit prematurely regardless of the nature of the
496exit.
497.It Fn atf_tc_expect_exit "exitcode" "reason" "..."
498Expects the test case to exit cleanly.
499If
500.Va exitcode
501is not
502.Sq -1 ,
503the runtime engine will validate that the exit code of the test case
504matches the one provided in this call.
505Otherwise, the exact value will be ignored.
506.It Fn atf_tc_expect_fail "reason" "..."
507Any failure (be it fatal or non-fatal) raised in this mode is recorded.
508However, such failures do not report the test case as failed; instead, the
509test case finalizes cleanly and is reported as
510.Sq expected failure ;
511this report includes the provided
512.Fa reason
513as part of it.
514If no error is raised while running in this mode, then the test case is
515reported as
516.Sq failed .
517.Pp
518This mode is useful to reproduce actual known bugs in tests.
519Whenever the developer fixes the bug later on, the test case will start
520reporting a failure, signaling the developer that the test case must be
521adjusted to the new conditions.
522In this situation, it is useful, for example, to set
523.Fa reason
524as the bug number for tracking purposes.
525.It Fn atf_tc_expect_pass
526This is the normal mode of execution.
527In this mode, any failure is reported as such to the user and the test case
528is marked as
529.Sq failed .
530.It Fn atf_tc_expect_signal "signo" "reason" "..."
531Expects the test case to terminate due to the reception of a signal.
532If
533.Va signo
534is not
535.Sq -1 ,
536the runtime engine will validate that the signal that terminated the test
537case matches the one provided in this call.
538Otherwise, the exact value will be ignored.
539.It Fn atf_tc_expect_timeout "reason" "..."
540Expects the test case to execute for longer than its timeout.
541.El
542.Ss Helper macros for common checks
543The library provides several macros that are very handy in multiple
544situations.
545These basically check some condition after executing a given statement or
546processing a given expression and, if the condition is not met, they
547report the test case as failed.
548.Pp
549The
550.Sq REQUIRE
551variant of the macros immediately abort the test case as soon as an error
552condition is detected by calling the
553.Fn atf_tc_fail
554function.
555Use this variant whenever it makes no sense to continue the execution of a
556test case when the checked condition is not met.
557The
558.Sq CHECK
559variant, on the other hand, reports a failure as soon as it is encountered
560using the
561.Fn atf_tc_fail_nonfatal
562function, but the execution of the test case continues as if nothing had
563happened.
564Use this variant whenever the checked condition is important as a result of
565the test case, but there are other conditions that can be subsequently
566checked on the same run without aborting.
567.Pp
568Additionally, the
569.Sq MSG
570variants take an extra set of parameters to explicitly specify the failure
571message.
572This failure message is formatted according to the
573.Xr printf 3
574formatters.
575.Pp
576.Fn ATF_CHECK ,
577.Fn ATF_CHECK_MSG ,
578.Fn ATF_REQUIRE
579and
580.Fn ATF_REQUIRE_MSG
581take an expression and fail if the expression evaluates to false.
582.Pp
583.Fn ATF_CHECK_EQ ,
584.Fn ATF_CHECK_EQ_MSG ,
585.Fn ATF_REQUIRE_EQ
586and
587.Fn ATF_REQUIRE_EQ_MSG
588take two expressions and fail if the two evaluated values are not equal.
589The common style is to put the expected value in the first parameter and the
590observed value in the second parameter.
591.Pp
592.Fn ATF_CHECK_MATCH ,
593.Fn ATF_CHECK_MATCH_MSG ,
594.Fn ATF_REQUIRE_MATCH
595and
596.Fn ATF_REQUIRE_MATCH_MSG
597take a regular expression and a string and fail if the regular expression does
598not match the given string.
599Note that the regular expression is not anchored, so it will match anywhere in
600the string.
601.Pp
602.Fn ATF_CHECK_STREQ ,
603.Fn ATF_CHECK_STREQ_MSG ,
604.Fn ATF_REQUIRE_STREQ
605and
606.Fn ATF_REQUIRE_STREQ_MSG
607take two strings and fail if the two are not equal character by character.
608The common style is to put the expected string in the first parameter and the
609observed string in the second parameter.
610.Pp
611.Fn ATF_CHECK_INTEQ ,
612.Fn ATF_CHECK_INTEQ_MSG ,
613.Fn ATF_REQUIRE_INTEQ
614and
615.Fn ATF_REQUIRE_INTQ_MSG
616take two integers and fail if the two are not equal.
617The common style is to put the expected integer in the first parameter and the
618observed integer in the second parameter.
619.Pp
620.Fn ATF_CHECK_ERRNO
621and
622.Fn ATF_REQUIRE_ERRNO
623take, first, the error code that the check is expecting to find in the
624.Va errno
625variable and, second, a boolean expression that, if evaluates to true,
626means that a call failed and
627.Va errno
628has to be checked against the first value.
629.Ss Utility functions
630The following functions are provided as part of the
631.Nm
632API to simplify the creation of a variety of tests.
633In particular, these are useful to write tests for command-line interfaces.
634.Pp
635.Ft void
636.Fo atf_utils_cat_file
637.Fa "const char *file"
638.Fa "const char *prefix"
639.Fc
640.Bd -ragged -offset indent
641Prints the contents of
642.Fa file
643to the standard output, prefixing every line with the string in
644.Fa prefix .
645.Ed
646.Pp
647.Ft bool
648.Fo atf_utils_compare_file
649.Fa "const char *file"
650.Fa "const char *contents"
651.Fc
652.Bd -ragged -offset indent
653Returns true if the given
654.Fa file
655matches exactly the expected inlined
656.Fa contents .
657.Ed
658.Pp
659.Ft void
660.Fo atf_utils_copy_file
661.Fa "const char *source"
662.Fa "const char *destination"
663.Fc
664.Bd -ragged -offset indent
665Copies the file
666.Fa source
667to
668.Fa destination .
669The permissions of the file are preserved during the code.
670.Ed
671.Pp
672.Ft void
673.Fo atf_utils_create_file
674.Fa "const char *file"
675.Fa "const char *contents"
676.Fa "..."
677.Fc
678.Bd -ragged -offset indent
679Creates
680.Fa file
681with the text given in
682.Fa contents ,
683which is a formatting string that uses the rest of the variable arguments.
684.Ed
685.Pp
686.Ft void
687.Fo atf_utils_file_exists
688.Fa "const char *file"
689.Fc
690.Bd -ragged -offset indent
691Checks if
692.Fa file
693exists.
694.Ed
695.Pp
696.Ft pid_t
697.Fo atf_utils_fork
698.Fa "void"
699.Fc
700.Bd -ragged -offset indent
701Forks a process and redirects the standard output and standard error of the
702child to files for later validation with
703.Fn atf_utils_wait .
704Fails the test case if the fork fails, so this does not return an error.
705.Ed
706.Pp
707.Ft void
708.Fo atf_utils_free_charpp
709.Fa "char **argv"
710.Fc
711.Bd -ragged -offset indent
712Frees a dynamically-allocated array of dynamically-allocated strings.
713.Ed
714.Pp
715.Ft bool
716.Fo atf_utils_grep_file
717.Fa "const char *regexp"
718.Fa "const char *file"
719.Fa "..."
720.Fc
721.Bd -ragged -offset indent
722Searches for the
723.Fa regexp ,
724which is a formatting string representing the regular expression,
725in the
726.Fa file .
727The variable arguments are used to construct the regular expression.
728.Ed
729.Pp
730.Ft bool
731.Fo atf_utils_grep_string
732.Fa "const char *regexp"
733.Fa "const char *str"
734.Fa "..."
735.Fc
736.Bd -ragged -offset indent
737Searches for the
738.Fa regexp ,
739which is a formatting string representing the regular expression,
740in the literal string
741.Fa str .
742The variable arguments are used to construct the regular expression.
743.Ed
744.Pp
745.Ft char *
746.Fo atf_utils_readline
747.Fa "int fd"
748.Fc
749.Bd -ragged -offset indent
750Reads a line from the file descriptor
751.Fa fd .
752The line, if any, is returned as a dynamically-allocated buffer that must be
753released with
754.Xr free 3 .
755If there was nothing to read, returns
756.Sq NULL .
757.Ed
758.Pp
759.Ft void
760.Fo atf_utils_redirect
761.Fa "const int fd"
762.Fa "const char *file"
763.Fc
764.Bd -ragged -offset indent
765Redirects the given file descriptor
766.Fa fd
767to
768.Fa file .
769This function exits the process in case of an error and does not properly mark
770the test case as failed.
771As a result, it should only be used in subprocesses of the test case; specially
772those spawned by
773.Fn atf_utils_fork .
774.Ed
775.Pp
776.Ft void
777.Fo atf_utils_wait
778.Fa "const pid_t pid"
779.Fa "const int expected_exit_status"
780.Fa "const char *expected_stdout"
781.Fa "const char *expected_stderr"
782.Fc
783.Bd -ragged -offset indent
784Waits and validates the result of a subprocess spawned with
785.Fn atf_utils_fork .
786The validation involves checking that the subprocess exited cleanly and returned
787the code specified in
788.Fa expected_exit_status
789and that its standard output and standard error match the strings given in
790.Fa expected_stdout
791and
792.Fa expected_stderr .
793.Pp
794If any of the
795.Fa expected_stdout
796or
797.Fa expected_stderr
798strings are prefixed with
799.Sq save: ,
800then they specify the name of the file into which to store the stdout or stderr
801of the subprocess, and no comparison is performed.
802.Ed
803.Sh ENVIRONMENT
804The following variables are recognized by
805.Nm
806but should not be overridden other than for testing purposes:
807.Pp
808.Bl -tag -width ATFXBUILDXCXXFLAGSXX -compact
809.It Va ATF_BUILD_CC
810Path to the C compiler.
811.It Va ATF_BUILD_CFLAGS
812C compiler flags.
813.It Va ATF_BUILD_CPP
814Path to the C/C++ preprocessor.
815.It Va ATF_BUILD_CPPFLAGS
816C/C++ preprocessor flags.
817.It Va ATF_BUILD_CXX
818Path to the C++ compiler.
819.It Va ATF_BUILD_CXXFLAGS
820C++ compiler flags.
821.El
822.Sh EXAMPLES
823The following shows a complete test program with a single test case that
824validates the addition operator:
825.Bd -literal -offset indent
826#include <atf-c.h>
827
828ATF_TC(addition);
829ATF_TC_HEAD(addition, tc)
830{
831    atf_tc_set_md_var(tc, "descr",
832                      "Sample tests for the addition operator");
833}
834ATF_TC_BODY(addition, tc)
835{
836    ATF_CHECK_EQ(0, 0 + 0);
837    ATF_CHECK_EQ(1, 0 + 1);
838    ATF_CHECK_EQ(1, 1 + 0);
839
840    ATF_CHECK_EQ(2, 1 + 1);
841
842    ATF_CHECK_EQ(300, 100 + 200);
843}
844
845ATF_TC(string_formatting);
846ATF_TC_HEAD(string_formatting, tc)
847{
848    atf_tc_set_md_var(tc, "descr",
849                      "Sample tests for the snprintf");
850}
851ATF_TC_BODY(string_formatting, tc)
852{
853    char buf[1024];
854    snprintf(buf, sizeof(buf), "a %s", "string");
855    ATF_CHECK_STREQ_MSG("a string", buf, "%s is not working");
856}
857
858ATF_TC(open_failure);
859ATF_TC_HEAD(open_failure, tc)
860{
861    atf_tc_set_md_var(tc, "descr",
862                      "Sample tests for the open function");
863}
864ATF_TC_BODY(open_failure, tc)
865{
866    ATF_CHECK_ERRNO(ENOENT, open("non-existent", O_RDONLY) == -1);
867}
868
869ATF_TC(known_bug);
870ATF_TC_HEAD(known_bug, tc)
871{
872    atf_tc_set_md_var(tc, "descr",
873                      "Reproduces a known bug");
874}
875ATF_TC_BODY(known_bug, tc)
876{
877    atf_tc_expect_fail("See bug number foo/bar");
878    ATF_CHECK_EQ(3, 1 + 1);
879    atf_tc_expect_pass();
880    ATF_CHECK_EQ(3, 1 + 2);
881}
882
883ATF_TP_ADD_TCS(tp)
884{
885    ATF_TP_ADD_TC(tp, addition);
886    ATF_TP_ADD_TC(tp, string_formatting);
887    ATF_TP_ADD_TC(tp, open_failure);
888    ATF_TP_ADD_TC(tp, known_bug);
889
890    return atf_no_error();
891}
892.Ed
893.Sh SEE ALSO
894.Xr atf-test-program 1 ,
895.Xr atf-test-case 4
896