]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/blob - contrib/atf/atf-c++/atf-c++.3
MFC r273929:
[FreeBSD/stable/10.git] / contrib / atf / atf-c++ / atf-c++.3
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 October 13, 2014
26 .Dt ATF-C++ 3
27 .Os
28 .Sh NAME
29 .Nm atf-c++ ,
30 .Nm ATF_ADD_TEST_CASE ,
31 .Nm ATF_CHECK_ERRNO ,
32 .Nm ATF_FAIL ,
33 .Nm ATF_INIT_TEST_CASES ,
34 .Nm ATF_PASS ,
35 .Nm ATF_REQUIRE ,
36 .Nm ATF_REQUIRE_EQ ,
37 .Nm ATF_REQUIRE_ERRNO ,
38 .Nm ATF_REQUIRE_IN ,
39 .Nm ATF_REQUIRE_MATCH ,
40 .Nm ATF_REQUIRE_NOT_IN ,
41 .Nm ATF_REQUIRE_THROW ,
42 .Nm ATF_REQUIRE_THROW_RE ,
43 .Nm ATF_SKIP ,
44 .Nm ATF_TEST_CASE ,
45 .Nm ATF_TEST_CASE_BODY ,
46 .Nm ATF_TEST_CASE_CLEANUP ,
47 .Nm ATF_TEST_CASE_HEAD ,
48 .Nm ATF_TEST_CASE_NAME ,
49 .Nm ATF_TEST_CASE_USE ,
50 .Nm ATF_TEST_CASE_WITH_CLEANUP ,
51 .Nm ATF_TEST_CASE_WITHOUT_HEAD ,
52 .Nm atf::utils::cat_file ,
53 .Nm atf::utils::compare_file ,
54 .Nm atf::utils::copy_file ,
55 .Nm atf::utils::create_file ,
56 .Nm atf::utils::file_exists ,
57 .Nm atf::utils::fork ,
58 .Nm atf::utils::grep_collection ,
59 .Nm atf::utils::grep_file ,
60 .Nm atf::utils::grep_string ,
61 .Nm atf::utils::redirect ,
62 .Nm atf::utils::wait
63 .Nd C++ API to write ATF-based test programs
64 .Sh SYNOPSIS
65 .In atf-c++.hpp
66 .Fn ATF_ADD_TEST_CASE "tcs" "name"
67 .Fn ATF_CHECK_ERRNO "expected_errno" "bool_expression"
68 .Fn ATF_FAIL "reason"
69 .Fn ATF_INIT_TEST_CASES "tcs"
70 .Fn ATF_PASS
71 .Fn ATF_REQUIRE "expression"
72 .Fn ATF_REQUIRE_EQ "expected_expression" "actual_expression"
73 .Fn ATF_REQUIRE_ERRNO "expected_errno" "bool_expression"
74 .Fn ATF_REQUIRE_IN "element" "collection"
75 .Fn ATF_REQUIRE_MATCH "regexp" "string_expression"
76 .Fn ATF_REQUIRE_NOT_IN "element" "collection"
77 .Fn ATF_REQUIRE_THROW "expected_exception" "statement"
78 .Fn ATF_REQUIRE_THROW_RE "expected_exception" "regexp" "statement"
79 .Fn ATF_SKIP "reason"
80 .Fn ATF_TEST_CASE "name"
81 .Fn ATF_TEST_CASE_BODY "name"
82 .Fn ATF_TEST_CASE_CLEANUP "name"
83 .Fn ATF_TEST_CASE_HEAD "name"
84 .Fn ATF_TEST_CASE_NAME "name"
85 .Fn ATF_TEST_CASE_USE "name"
86 .Fn ATF_TEST_CASE_WITH_CLEANUP "name"
87 .Fn ATF_TEST_CASE_WITHOUT_HEAD "name"
88 .Ft void
89 .Fo atf::utils::cat_file
90 .Fa "const std::string& path"
91 .Fa "const std::string& prefix"
92 .Fc
93 .Ft bool
94 .Fo atf::utils::compare_file
95 .Fa "const std::string& path"
96 .Fa "const std::string& contents"
97 .Fc
98 .Ft void
99 .Fo atf::utils::copy_file
100 .Fa "const std::string& source"
101 .Fa "const std::string& destination"
102 .Fc
103 .Ft void
104 .Fo atf::utils::create_file
105 .Fa "const std::string& path"
106 .Fa "const std::string& contents"
107 .Fc
108 .Ft void
109 .Fo atf::utils::file_exists
110 .Fa "const std::string& path"
111 .Fc
112 .Ft pid_t
113 .Fo atf::utils::fork
114 .Fa "void"
115 .Fc
116 .Ft bool
117 .Fo atf::utils::grep_collection
118 .Fa "const std::string& regexp"
119 .Fa "const Collection& collection"
120 .Fc
121 .Ft bool
122 .Fo atf::utils::grep_file
123 .Fa "const std::string& regexp"
124 .Fa "const std::string& path"
125 .Fc
126 .Ft bool
127 .Fo atf::utils::grep_string
128 .Fa "const std::string& regexp"
129 .Fa "const std::string& path"
130 .Fc
131 .Ft void
132 .Fo atf::utils::redirect
133 .Fa "const int fd"
134 .Fa "const std::string& path"
135 .Fc
136 .Ft void
137 .Fo atf::utils::wait
138 .Fa "const pid_t pid"
139 .Fa "const int expected_exit_status"
140 .Fa "const std::string& expected_stdout"
141 .Fa "const std::string& expected_stderr"
142 .Fc
143 .Sh DESCRIPTION
144 ATF provides a C++ programming interface to implement test programs.
145 C++-based test programs follow this template:
146 .Bd -literal -offset indent
147 extern "C" {
148 .Ns ... C-specific includes go here ...
149 }
150
151 .Ns ... C++-specific includes go here ...
152
153 #include <atf-c++.hpp>
154
155 ATF_TEST_CASE(tc1);
156 ATF_TEST_CASE_HEAD(tc1)
157 {
158     ... first test case's header ...
159 }
160 ATF_TEST_CASE_BODY(tc1)
161 {
162     ... first test case's body ...
163 }
164
165 ATF_TEST_CASE_WITH_CLEANUP(tc2);
166 ATF_TEST_CASE_HEAD(tc2)
167 {
168     ... second test case's header ...
169 }
170 ATF_TEST_CASE_BODY(tc2)
171 {
172     ... second test case's body ...
173 }
174 ATF_TEST_CASE_CLEANUP(tc2)
175 {
176     ... second test case's cleanup ...
177 }
178
179 ATF_TEST_CASE(tc3);
180 ATF_TEST_CASE_BODY(tc3)
181 {
182     ... third test case's body ...
183 }
184
185 .Ns ... additional test cases ...
186
187 ATF_INIT_TEST_CASES(tcs)
188 {
189     ATF_ADD_TEST_CASE(tcs, tc1);
190     ATF_ADD_TEST_CASE(tcs, tc2);
191     ATF_ADD_TEST_CASE(tcs, tc3);
192     ... add additional test cases ...
193 }
194 .Ed
195 .Ss Definition of test cases
196 Test cases have an identifier and are composed of three different parts:
197 the header, the body and an optional cleanup routine, all of which are
198 described in
199 .Xr atf-test-case 4 .
200 To define test cases, one can use the
201 .Fn ATF_TEST_CASE ,
202 .Fn ATF_TEST_CASE_WITH_CLEANUP
203 or the
204 .Fn ATF_TEST_CASE_WITHOUT_HEAD
205 macros, which take a single parameter specifiying the test case's
206 name.
207 .Fn ATF_TEST_CASE ,
208 requires to define a head and a body for the test case,
209 .Fn ATF_TEST_CASE_WITH_CLEANUP
210 requires to define a head, a body and a cleanup for the test case and
211 .Fn ATF_TEST_CASE_WITHOUT_HEAD
212 requires only a body for the test case.
213 It is important to note that these
214 .Em do not
215 set the test case up for execution when the program is run.
216 In order to do so, a later registration is needed through the
217 .Fn ATF_ADD_TEST_CASE
218 macro detailed in
219 .Sx Program initialization .
220 .Pp
221 Later on, one must define the three parts of the body by means of three
222 functions.
223 Their headers are given by the
224 .Fn ATF_TEST_CASE_HEAD ,
225 .Fn ATF_TEST_CASE_BODY
226 and
227 .Fn ATF_TEST_CASE_CLEANUP
228 macros, all of which take the test case's name.
229 Following each of these, a block of code is expected, surrounded by the
230 opening and closing brackets.
231 .Pp
232 Additionally, the
233 .Fn ATF_TEST_CASE_NAME
234 macro can be used to obtain the name of the class corresponding to a
235 particular test case, as the name is internally manged by the library to
236 prevent clashes with other user identifiers.
237 Similarly, the
238 .Fn ATF_TEST_CASE_USE
239 macro can be executed on a particular test case to mark it as "used" and
240 thus prevent compiler warnings regarding unused symbols.
241 Note that
242 .Em you should never have to use these macros during regular operation.
243 .Ss Program initialization
244 The library provides a way to easily define the test program's
245 .Fn main
246 function.
247 You should never define one on your own, but rely on the
248 library to do it for you.
249 This is done by using the
250 .Fn ATF_INIT_TEST_CASES
251 macro, which is passed the name of the list that will hold the test cases.
252 This name can be whatever you want as long as it is a valid variable value.
253 .Pp
254 After the macro, you are supposed to provide the body of a function, which
255 should only use the
256 .Fn ATF_ADD_TEST_CASE
257 macro to register the test cases the test program will execute.
258 The first parameter of this macro matches the name you provided in the
259 former call.
260 .Ss Header definitions
261 The test case's header can define the meta-data by using the
262 .Fn set_md_var
263 method, which takes two parameters: the first one specifies the
264 meta-data variable to be set and the second one specifies its value.
265 Both of them are strings.
266 .Ss Configuration variables
267 The test case has read-only access to the current configuration variables
268 by means of the
269 .Ft bool
270 .Fn has_config_var
271 and the
272 .Ft std::string
273 .Fn get_config_var
274 methods, which can be called in any of the three parts of a test case.
275 .Ss Access to the source directory
276 It is possible to get the path to the test case's source directory from any
277 of its three components by querying the
278 .Sq srcdir
279 configuration variable.
280 .Ss Requiring programs
281 Aside from the
282 .Va require.progs
283 meta-data variable available in the header only, one can also check for
284 additional programs in the test case's body by using the
285 .Fn require_prog
286 function, which takes the base name or full path of a single binary.
287 Relative paths are forbidden.
288 If it is not found, the test case will be automatically skipped.
289 .Ss Test case finalization
290 The test case finalizes either when the body reaches its end, at which
291 point the test is assumed to have
292 .Em passed ,
293 or at any explicit call to
294 .Fn ATF_PASS ,
295 .Fn ATF_FAIL
296 or
297 .Fn ATF_SKIP .
298 These three macros terminate the execution of the test case immediately.
299 The cleanup routine will be processed afterwards in a completely automated
300 way, regardless of the test case's termination reason.
301 .Pp
302 .Fn ATF_PASS
303 does not take any parameters.
304 .Fn ATF_FAIL
305 and
306 .Fn ATF_SKIP
307 take a single string that describes why the test case failed or
308 was skipped, respectively.
309 It is very important to provide a clear error message in both cases so that
310 the user can quickly know why the test did not pass.
311 .Ss Expectations
312 Everything explained in the previous section changes when the test case
313 expectations are redefined by the programmer.
314 .Pp
315 Each test case has an internal state called
316 .Sq expect
317 that describes what the test case expectations are at any point in time.
318 The value of this property can change during execution by any of:
319 .Bl -tag -width indent
320 .It Fn expect_death "reason"
321 Expects the test case to exit prematurely regardless of the nature of the
322 exit.
323 .It Fn expect_exit "exitcode" "reason"
324 Expects the test case to exit cleanly.
325 If
326 .Va exitcode
327 is not
328 .Sq -1 ,
329 the runtime engine will validate that the exit code of the test case
330 matches the one provided in this call.
331 Otherwise, the exact value will be ignored.
332 .It Fn expect_fail "reason"
333 Any failure (be it fatal or non-fatal) raised in this mode is recorded.
334 However, such failures do not report the test case as failed; instead, the
335 test case finalizes cleanly and is reported as
336 .Sq expected failure ;
337 this report includes the provided
338 .Fa reason
339 as part of it.
340 If no error is raised while running in this mode, then the test case is
341 reported as
342 .Sq failed .
343 .Pp
344 This mode is useful to reproduce actual known bugs in tests.
345 Whenever the developer fixes the bug later on, the test case will start
346 reporting a failure, signaling the developer that the test case must be
347 adjusted to the new conditions.
348 In this situation, it is useful, for example, to set
349 .Fa reason
350 as the bug number for tracking purposes.
351 .It Fn expect_pass
352 This is the normal mode of execution.
353 In this mode, any failure is reported as such to the user and the test case
354 is marked as
355 .Sq failed .
356 .It Fn expect_race "reason"
357 Any failure or timeout during the execution of the test case will be
358 considered as if a race condition has been triggered and reported as such.
359 If no problems arise, the test will continue execution as usual.
360 .It Fn expect_signal "signo" "reason"
361 Expects the test case to terminate due to the reception of a signal.
362 If
363 .Va signo
364 is not
365 .Sq -1 ,
366 the runtime engine will validate that the signal that terminated the test
367 case matches the one provided in this call.
368 Otherwise, the exact value will be ignored.
369 .It Fn expect_timeout "reason"
370 Expects the test case to execute for longer than its timeout.
371 .El
372 .Ss Helper macros for common checks
373 The library provides several macros that are very handy in multiple
374 situations.
375 These basically check some condition after executing a given statement or
376 processing a given expression and, if the condition is not met, they
377 automatically call
378 .Fn ATF_FAIL
379 with an appropriate error message.
380 .Pp
381 .Fn ATF_REQUIRE
382 takes an expression and raises a failure if it evaluates to false.
383 .Pp
384 .Fn ATF_REQUIRE_EQ
385 takes two expressions and raises a failure if the two do not evaluate to
386 the same exact value.
387 The common style is to put the expected value in the first parameter and the
388 actual value in the second parameter.
389 .Pp
390 .Fn ATF_REQUIRE_IN
391 takes an element and a collection and validates that the element is present in
392 the collection.
393 .Pp
394 .Fn ATF_REQUIRE_MATCH
395 takes a regular expression and a string and raises a failure if the regular
396 expression does not match the string.
397 .Pp
398 .Fn ATF_REQUIRE_NOT_IN
399 takes an element and a collection and validates that the element is not present
400 in the collection.
401 .Pp
402 .Fn ATF_REQUIRE_THROW
403 takes the name of an exception and a statement and raises a failure if
404 the statement does not throw the specified exception.
405 .Fn ATF_REQUIRE_THROW_RE
406 takes the name of an exception, a regular expresion and a statement and raises a
407 failure if the statement does not throw the specified exception and if the
408 message of the exception does not match the regular expression.
409 .Pp
410 .Fn ATF_CHECK_ERRNO
411 and
412 .Fn ATF_REQUIRE_ERRNO
413 take, first, the error code that the check is expecting to find in the
414 .Va errno
415 variable and, second, a boolean expression that, if evaluates to true,
416 means that a call failed and
417 .Va errno
418 has to be checked against the first value.
419 .Ss Utility functions
420 The following functions are provided as part of the
421 .Nm
422 API to simplify the creation of a variety of tests.
423 In particular, these are useful to write tests for command-line interfaces.
424 .Pp
425 .Ft void
426 .Fo atf::utils::cat_file
427 .Fa "const std::string& path"
428 .Fa "const std::string& prefix"
429 .Fc
430 .Bd -ragged -offset indent
431 Prints the contents of
432 .Fa path
433 to the standard output, prefixing every line with the string in
434 .Fa prefix .
435 .Ed
436 .Pp
437 .Ft bool
438 .Fo atf::utils::compare_file
439 .Fa "const std::string& path"
440 .Fa "const std::string& contents"
441 .Fc
442 .Bd -ragged -offset indent
443 Returns true if the given
444 .Fa path
445 matches exactly the expected inlined
446 .Fa contents .
447 .Ed
448 .Pp
449 .Ft void
450 .Fo atf::utils::copy_file
451 .Fa "const std::string& source"
452 .Fa "const std::string& destination"
453 .Fc
454 .Bd -ragged -offset indent
455 Copies the file
456 .Fa source
457 to
458 .Fa destination .
459 The permissions of the file are preserved during the code.
460 .Ed
461 .Pp
462 .Ft void
463 .Fo atf::utils::create_file
464 .Fa "const std::string& path"
465 .Fa "const std::string& contents"
466 .Fc
467 .Bd -ragged -offset indent
468 Creates
469 .Fa file
470 with the text given in
471 .Fa contents .
472 .Ed
473 .Pp
474 .Ft void
475 .Fo atf::utils::file_exists
476 .Fa "const std::string& path"
477 .Fc
478 .Bd -ragged -offset indent
479 Checks if
480 .Fa path
481 exists.
482 .Ed
483 .Pp
484 .Ft pid_t
485 .Fo atf::utils::fork
486 .Fa "void"
487 .Fc
488 .Bd -ragged -offset indent
489 Forks a process and redirects the standard output and standard error of the
490 child to files for later validation with
491 .Fn atf::utils::wait .
492 Fails the test case if the fork fails, so this does not return an error.
493 .Ed
494 .Pp
495 .Ft bool
496 .Fo atf::utils::grep_collection
497 .Fa "const std::string& regexp"
498 .Fa "const Collection& collection"
499 .Fc
500 .Bd -ragged -offset indent
501 Searches for the regular expression
502 .Fa regexp
503 in any of the strings contained in the
504 .Fa collection .
505 This is a template that accepts any one-dimensional container of strings.
506 .Ed
507 .Pp
508 .Ft bool
509 .Fo atf::utils::grep_file
510 .Fa "const std::string& regexp"
511 .Fa "const std::string& path"
512 .Fc
513 .Bd -ragged -offset indent
514 Searches for the regular expression
515 .Fa regexp
516 in the file
517 .Fa path .
518 The variable arguments are used to construct the regular expression.
519 .Ed
520 .Pp
521 .Ft bool
522 .Fo atf::utils::grep_string
523 .Fa "const std::string& regexp"
524 .Fa "const std::string& str"
525 .Fc
526 .Bd -ragged -offset indent
527 Searches for the regular expression
528 .Fa regexp
529 in the string
530 .Fa str .
531 .Ed
532 .Ft void
533 .Fo atf::utils::redirect
534 .Fa "const int fd"
535 .Fa "const std::string& path"
536 .Fc
537 .Bd -ragged -offset indent
538 Redirects the given file descriptor
539 .Fa fd
540 to the file
541 .Fa path .
542 This function exits the process in case of an error and does not properly mark
543 the test case as failed.
544 As a result, it should only be used in subprocesses of the test case; specially
545 those spawned by
546 .Fn atf::utils::fork .
547 .Ed
548 .Pp
549 .Ft void
550 .Fo atf::utils::wait
551 .Fa "const pid_t pid"
552 .Fa "const int expected_exit_status"
553 .Fa "const std::string& expected_stdout"
554 .Fa "const std::string& expected_stderr"
555 .Fc
556 .Bd -ragged -offset indent
557 Waits and validates the result of a subprocess spawned with
558 .Fn atf::utils::wait .
559 The validation involves checking that the subprocess exited cleanly and returned
560 the code specified in
561 .Fa expected_exit_status
562 and that its standard output and standard error match the strings given in
563 .Fa expected_stdout
564 and
565 .Fa expected_stderr .
566 .Pp
567 If any of the
568 .Fa expected_stdout
569 or
570 .Fa expected_stderr
571 strings are prefixed with
572 .Sq save: ,
573 then they specify the name of the file into which to store the stdout or stderr
574 of the subprocess, and no comparison is performed.
575 .Ed
576 .Sh ENVIRONMENT
577 The following variables are recognized by
578 .Nm
579 but should not be overridden other than for testing purposes:
580 .Pp
581 .Bl -tag -width ATFXBUILDXCXXFLAGSXX -compact
582 .It Va ATF_BUILD_CC
583 Path to the C compiler.
584 .It Va ATF_BUILD_CFLAGS
585 C compiler flags.
586 .It Va ATF_BUILD_CPP
587 Path to the C/C++ preprocessor.
588 .It Va ATF_BUILD_CPPFLAGS
589 C/C++ preprocessor flags.
590 .It Va ATF_BUILD_CXX
591 Path to the C++ compiler.
592 .It Va ATF_BUILD_CXXFLAGS
593 C++ compiler flags.
594 .El
595 .Sh EXAMPLES
596 The following shows a complete test program with a single test case that
597 validates the addition operator:
598 .Bd -literal -offset indent
599 #include <atf-c++.hpp>
600
601 ATF_TEST_CASE(addition);
602 ATF_TEST_CASE_HEAD(addition)
603 {
604     set_md_var("descr", "Sample tests for the addition operator");
605 }
606 ATF_TEST_CASE_BODY(addition)
607 {
608     ATF_REQUIRE_EQ(0, 0 + 0);
609     ATF_REQUIRE_EQ(1, 0 + 1);
610     ATF_REQUIRE_EQ(1, 1 + 0);
611
612     ATF_REQUIRE_EQ(2, 1 + 1);
613
614     ATF_REQUIRE_EQ(300, 100 + 200);
615 }
616
617 ATF_TEST_CASE(open_failure);
618 ATF_TEST_CASE_HEAD(open_failure)
619 {
620     set_md_var("descr", "Sample tests for the open function");
621 }
622 ATF_TEST_CASE_BODY(open_failure)
623 {
624     ATF_REQUIRE_ERRNO(ENOENT, open("non-existent", O_RDONLY) == -1);
625 }
626
627 ATF_TEST_CASE(known_bug);
628 ATF_TEST_CASE_HEAD(known_bug)
629 {
630     set_md_var("descr", "Reproduces a known bug");
631 }
632 ATF_TEST_CASE_BODY(known_bug)
633 {
634     expect_fail("See bug number foo/bar");
635     ATF_REQUIRE_EQ(3, 1 + 1);
636     expect_pass();
637     ATF_REQUIRE_EQ(3, 1 + 2);
638 }
639
640 ATF_INIT_TEST_CASES(tcs)
641 {
642     ATF_ADD_TEST_CASE(tcs, addition);
643     ATF_ADD_TEST_CASE(tcs, open_failure);
644     ATF_ADD_TEST_CASE(tcs, known_bug);
645 }
646 .Ed
647 .Sh SEE ALSO
648 .Xr atf-test-program 1 ,
649 .Xr atf-test-case 4