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