atf-c-api man page

atf-c-api, ATF_CHECK, ATF_CHECK_MSG, ATF_CHECK_EQ, ATF_CHECK_EQ_MSG, ATF_CHECK_MATCH, ATF_CHECK_MATCH_MSG, ATF_CHECK_STREQ, ATF_CHECK_STREQ_MSG, ATF_CHECK_ERRNO, ATF_REQUIRE, ATF_REQUIRE_MSG, ATF_REQUIRE_EQ, ATF_REQUIRE_EQ_MSG, ATF_REQUIRE_MATCH, ATF_REQUIRE_MATCH_MSG, ATF_REQUIRE_STREQ, ATF_REQUIRE_STREQ_MSG, ATF_REQUIRE_ERRNO, ATF_TC, ATF_TC_BODY, ATF_TC_BODY_NAME, ATF_TC_CLEANUP, ATF_TC_CLEANUP_NAME, ATF_TC_HEAD, ATF_TC_HEAD_NAME, ATF_TC_NAME, ATF_TC_WITH_CLEANUP, ATF_TC_WITHOUT_HEAD, ATF_TP_ADD_TC, ATF_TP_ADD_TCS, atf_tc_get_config_var, atf_tc_get_config_var_wd, atf_tc_get_config_var_as_bool, atf_tc_get_config_var_as_bool_wd, atf_tc_get_config_var_as_long, atf_tc_get_config_var_as_long_wd, atf_no_error, atf_tc_expect_death, atf_tc_expect_exit, atf_tc_expect_fail, atf_tc_expect_pass, atf_tc_expect_signal, atf_tc_expect_timeout, atf_tc_fail, atf_tc_fail_nonfatal, atf_tc_pass, atf_tc_skip, atf_utils_cat_file, atf_utils_compare_file, atf_utils_copy_file, atf_utils_create_file, atf_utils_file_exists, atf_utils_fork, atf_utils_free_charpp, atf_utils_grep_file, atf_utils_grep_string, atf_utils_readline, atf_utils_redirect, atf_utils_wait — C API to write ATF-based test programs

Synopsis

#include <atf-c.h>

ATF_CHECK(expression);

ATF_CHECK_MSG(expression, fail_msg_fmt, ...);

ATF_CHECK_EQ(expression_1, expression_2);

ATF_CHECK_EQ_MSG(expression_1, expression_2, fail_msg_fmt, ...);

ATF_CHECK_MATCH(regexp, string);

ATF_CHECK_MATCH_MSG(regexp, string, fail_msg_fmt, ...);

ATF_CHECK_STREQ(string_1, string_2);

ATF_CHECK_STREQ_MSG(string_1, string_2, fail_msg_fmt, ...);

ATF_CHECK_ERRNO(exp_errno, bool_expression);

ATF_REQUIRE(expression);

ATF_REQUIRE_MSG(expression, fail_msg_fmt, ...);

ATF_REQUIRE_EQ(expression_1, expression_2);

ATF_REQUIRE_EQ_MSG(expression_1, expression_2, fail_msg_fmt, ...);

ATF_REQUIRE_MATCH(regexp, string);

ATF_REQUIRE_MATCH_MSG(regexp, string, fail_msg_fmt, ...);

ATF_REQUIRE_STREQ(string_1, string_2);

ATF_REQUIRE_STREQ_MSG(string_1, string_2, fail_msg_fmt, ...);

ATF_REQUIRE_ERRNO(exp_errno, bool_expression);

ATF_TC(name);

ATF_TC_BODY(name, tc);

ATF_TC_BODY_NAME(name);

ATF_TC_CLEANUP(name, tc);

ATF_TC_CLEANUP_NAME(name);

ATF_TC_HEAD(name, tc);

ATF_TC_HEAD_NAME(name);

ATF_TC_NAME(name);

ATF_TC_WITH_CLEANUP(name);

ATF_TC_WITHOUT_HEAD(name);

ATF_TP_ADD_TC(tp_name, tc_name);

ATF_TP_ADD_TCS(tp_name);

atf_tc_get_config_var(tc, varname);

atf_tc_get_config_var_wd(tc, variable_name, default_value);

atf_tc_get_config_var_as_bool(tc, variable_name);

atf_tc_get_config_var_as_bool_wd(tc, variable_name, default_value);

atf_tc_get_config_var_as_long(tc, variable_name);

atf_tc_get_config_var_as_long_wd(tc, variable_name, default_value);

atf_no_error();

atf_tc_expect_death(reason, ...);

atf_tc_expect_exit(exitcode, reason, ...);

atf_tc_expect_fail(reason, ...);

atf_tc_expect_pass();

atf_tc_expect_signal(signo, reason, ...);

atf_tc_expect_timeout(reason, ...);

atf_tc_fail(reason);

atf_tc_fail_nonfatal(reason);

atf_tc_pass();

atf_tc_skip(reason);

void
atf_utils_cat_file(const char *file, const char *prefix);

bool
atf_utils_compare_file(const char *file, const char *contents);

void
atf_utils_copy_file(const char *source, const char *destination);

void
atf_utils_create_file(const char *file, const char *contents, ...);

void
atf_utils_file_exists(const char *file);

pid_t
atf_utils_fork(void);

void
atf_utils_free_charpp(char **argv);

bool
atf_utils_grep_file(const char *regexp, const char *file, ...);

bool
atf_utils_grep_string(const char *regexp, const char *str, ...);

char *
atf_utils_readline(int fd);

void
atf_utils_redirect(const int fd, const char *file);

void
atf_utils_wait(const pid_t pid, const int expected_exit_status, const char *expected_stdout, const char *expected_stderr);

Description

ATF provides a C programming interface to implement test programs. C-based test programs follow this template:

... C-specific includes go here ... 
 
#include <atf-c.h> 
 
ATF_TC(tc1); 
ATF_TC_HEAD(tc1, tc) 
{ 
    ... first test case's header ... 
} 
ATF_TC_BODY(tc1, tc) 
{ 
    ... first test case's body ... 
} 
 
ATF_TC_WITH_CLEANUP(tc2); 
ATF_TC_HEAD(tc2, tc) 
{ 
    ... second test case's header ... 
} 
ATF_TC_BODY(tc2, tc) 
{ 
    ... second test case's body ... 
} 
ATF_TC_CLEANUP(tc2, tc) 
{ 
    ... second test case's cleanup ... 
} 
 
ATF_TC_WITHOUT_HEAD(tc3); 
ATF_TC_BODY(tc3, tc) 
{ 
    ... third test case's body ... 
} 
 
... additional test cases ... 
 
ATF_TP_ADD_TCS(tp) 
{ 
    ATF_TP_ADD_TC(tcs, tc1); 
    ATF_TP_ADD_TC(tcs, tc2); 
    ATF_TP_ADD_TC(tcs, tc3); 
    ... add additional test cases ... 
 
    return atf_no_error(); 
}

Definition of test cases

Test cases have an identifier and are composed of three different parts: the header, the body and an optional cleanup routine, all of which are described in atf-test-case(4). To define test cases, one can use the ATF_TC(), ATF_TC_WITH_CLEANUP() or the ATF_TC_WITHOUT_HEAD() macros, which take a single parameter specifiying the test case's name. ATF_TC(), requires to define a head and a body for the test case, ATF_TC_WITH_CLEANUP() requires to define a head, a body and a cleanup for the test case and ATF_TC_WITHOUT_HEAD() requires only a body for the test case. It is important to note that these do not set the test case up for execution when the program is run. In order to do so, a later registration is needed with the ATF_TP_ADD_TC() macro detailed in Program initialization.

Later on, one must define the three parts of the body by means of three functions. Their headers are given by the ATF_TC_HEAD(), ATF_TC_BODY() and ATF_TC_CLEANUP() macros, all of which take the test case name provided to the ATF_TC() ATF_TC_WITH_CLEANUP(), or ATF_TC_WITHOUT_HEAD() macros and the name of the variable that will hold a pointer to the test case data. Following each of these, a block of code is expected, surrounded by the opening and closing brackets.

Program initialization

The library provides a way to easily define the test program's main() function. You should never define one on your own, but rely on the library to do it for you. This is done by using the ATF_TP_ADD_TCS() macro, which is passed the name of the object that will hold the test cases; i.e. the test program instance. This name can be whatever you want as long as it is a valid variable identifier.

After the macro, you are supposed to provide the body of a function, which should only use the ATF_TP_ADD_TC() macro to register the test cases the test program will execute and return a success error code. The first parameter of this macro matches the name you provided in the former call. The success status can be returned using the atf_no_error() function.

Header definitions

The test case's header can define the meta-data by using the atf_tc_set_md_var() method, which takes three parameters: the first one points to the test case data, the second one specifies the meta-data variable to be set and the third one specifies its value. Both of them are strings.

Configuration variables

The test case has read-only access to the current configuration variables by means of the bool atf_tc_has_config_var(), const char * atf_tc_get_config_var(), const char * atf_tc_get_config_var_wd(), bool atf_tc_get_config_var_as_bool(), bool atf_tc_get_config_var_as_bool_wd(), long atf_tc_get_config_var_as_long(), and the long atf_tc_get_config_var_as_long_wd() functions, which can be called in any of the three parts of a test case.

The ‘_wd’ variants take a default value for the variable which is returned if the variable is not defined. The other functions without the ‘_wd’ suffix require the variable to be defined.

Access to the source directory

It is possible to get the path to the test case's source directory from any of its three components by querying the ‘srcdir’ configuration variable.

Requiring programs

Aside from the require.progs meta-data variable available in the header only, one can also check for additional programs in the test case's body by using the atf_tc_re