2 * Automated Testing Framework (atf)
4 * Copyright (c) 2008 The NetBSD Foundation, Inc.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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.
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.
30 #include <sys/types.h>
43 #include "atf-c/defs.h"
44 #include "atf-c/error.h"
47 #include "detail/env.h"
48 #include "detail/fs.h"
49 #include "detail/map.h"
50 #include "detail/sanity.h"
51 #include "detail/text.h"
53 /* ---------------------------------------------------------------------
54 * Auxiliary functions.
55 * --------------------------------------------------------------------- */
71 enum expect_type expect
;
72 atf_dynstr_t expect_reason
;
73 size_t expect_previous_fail_count
;
74 size_t expect_fail_count
;
79 static void context_init(struct context
*, const atf_tc_t
*, const char *);
80 static void check_fatal_error(atf_error_t
);
81 static void report_fatal_error(const char *, ...)
82 ATF_DEFS_ATTRIBUTE_FORMAT_PRINTF(1, 2)
83 ATF_DEFS_ATTRIBUTE_NORETURN
;
84 static atf_error_t
write_resfile(const int, const char *, const int,
85 const atf_dynstr_t
*);
86 static void create_resfile(const char *, const char *, const int,
88 static void error_in_expect(struct context
*, const char *, ...)
89 ATF_DEFS_ATTRIBUTE_FORMAT_PRINTF(2, 3)
90 ATF_DEFS_ATTRIBUTE_NORETURN
;
91 static void validate_expect(struct context
*);
92 static void expected_failure(struct context
*, atf_dynstr_t
*)
93 ATF_DEFS_ATTRIBUTE_NORETURN
;
94 static void fail_requirement(struct context
*, atf_dynstr_t
*)
95 ATF_DEFS_ATTRIBUTE_NORETURN
;
96 static void fail_check(struct context
*, atf_dynstr_t
*);
97 static void pass(struct context
*)
98 ATF_DEFS_ATTRIBUTE_NORETURN
;
99 static void skip(struct context
*, atf_dynstr_t
*)
100 ATF_DEFS_ATTRIBUTE_NORETURN
;
101 static void format_reason_ap(atf_dynstr_t
*, const char *, const size_t,
102 const char *, va_list)
103 ATF_DEFS_ATTRIBUTE_FORMAT_PRINTF(4, 0);
104 static void format_reason_fmt(atf_dynstr_t
*, const char *, const size_t,
106 ATF_DEFS_ATTRIBUTE_FORMAT_PRINTF(4, 5);
107 static void errno_test(struct context
*, const char *, const size_t,
108 const int, const char *, const bool,
109 void (*)(struct context
*, atf_dynstr_t
*));
110 static atf_error_t
check_prog_in_dir(const char *, void *);
111 static atf_error_t
check_prog(struct context
*, const char *);
114 context_init(struct context
*ctx
, const atf_tc_t
*tc
, const char *resfile
)
117 ctx
->resfile
= resfile
;
119 ctx
->expect
= EXPECT_PASS
;
120 check_fatal_error(atf_dynstr_init(&ctx
->expect_reason
));
121 ctx
->expect_previous_fail_count
= 0;
122 ctx
->expect_fail_count
= 0;
123 ctx
->expect_exitcode
= 0;
124 ctx
->expect_signo
= 0;
128 check_fatal_error(atf_error_t err
)
130 if (atf_is_error(err
)) {
132 atf_error_format(err
, buf
, sizeof(buf
));
133 fprintf(stderr
, "FATAL ERROR: %s\n", buf
);
140 report_fatal_error(const char *msg
, ...)
143 fprintf(stderr
, "FATAL ERROR: ");
146 vfprintf(stderr
, msg
, ap
);
149 fprintf(stderr
, "\n");
153 /** Writes to a results file.
155 * The results file is supposed to be already open.
157 * This function returns an error code instead of exiting in case of error
158 * because the caller needs to clean up the reason object before terminating.
161 write_resfile(const int fd
, const char *result
, const int arg
,
162 const atf_dynstr_t
*reason
)
164 static char NL
[] = "\n", CS
[] = ": ";
171 INV(arg
== -1 || reason
!= NULL
);
173 #define UNCONST(a) ((void *)(unsigned long)(const void *)(a))
174 iov
[count
].iov_base
= UNCONST(result
);
175 iov
[count
++].iov_len
= strlen(result
);
177 if (reason
!= NULL
) {
179 iov
[count
].iov_base
= buf
;
180 iov
[count
++].iov_len
= snprintf(buf
, sizeof(buf
), "(%d)", arg
);
183 iov
[count
].iov_base
= CS
;
184 iov
[count
++].iov_len
= sizeof(CS
) - 1;
186 r
= atf_dynstr_cstring(reason
);
187 iov
[count
].iov_base
= UNCONST(r
);
188 iov
[count
++].iov_len
= strlen(r
);
192 iov
[count
].iov_base
= NL
;
193 iov
[count
++].iov_len
= sizeof(NL
) - 1;
195 while ((ret
= writev(fd
, iov
, count
)) == -1 && errno
== EINTR
)
196 continue; /* Retry. */
198 return atf_no_error();
200 return atf_libc_error(
201 errno
, "Failed to write results file; result %s, reason %s", result
,
202 reason
== NULL
? "null" : atf_dynstr_cstring(reason
));
205 /** Creates a results file.
207 * The input reason is released in all cases.
209 * An error in this function is considered to be fatal, hence why it does
210 * not return any error code.
213 create_resfile(const char *resfile
, const char *result
, const int arg
,
214 atf_dynstr_t
*reason
)
218 if (strcmp("/dev/stdout", resfile
) == 0) {
219 err
= write_resfile(STDOUT_FILENO
, result
, arg
, reason
);
220 } else if (strcmp("/dev/stderr", resfile
) == 0) {
221 err
= write_resfile(STDERR_FILENO
, result
, arg
, reason
);
223 const int fd
= open(resfile
, O_WRONLY
| O_CREAT
| O_TRUNC
,
224 S_IRUSR
| S_IWUSR
| S_IRGRP
| S_IROTH
);
226 err
= atf_libc_error(errno
, "Cannot create results file '%s'",
229 err
= write_resfile(fd
, result
, arg
, reason
);
235 atf_dynstr_fini(reason
);
237 check_fatal_error(err
);
240 /** Fails a test case if validate_expect fails. */
242 error_in_expect(struct context
*ctx
, const char *fmt
, ...)
248 format_reason_ap(&reason
, NULL
, 0, fmt
, ap
);
251 ctx
->expect
= EXPECT_PASS
; /* Ensure fail_requirement really fails. */
252 fail_requirement(ctx
, &reason
);
255 /** Ensures that the "expect" state is correct.
257 * Call this function before modifying the current value of expect.
260 validate_expect(struct context
*ctx
)
262 if (ctx
->expect
== EXPECT_DEATH
) {
263 error_in_expect(ctx
, "Test case was expected to terminate abruptly "
264 "but it continued execution");
265 } else if (ctx
->expect
== EXPECT_EXIT
) {
266 error_in_expect(ctx
, "Test case was expected to exit cleanly but it "
267 "continued execution");
268 } else if (ctx
->expect
== EXPECT_FAIL
) {
269 if (ctx
->expect_fail_count
== ctx
->expect_previous_fail_count
)
270 error_in_expect(ctx
, "Test case was expecting a failure but none "
273 INV(ctx
->expect_fail_count
> ctx
->expect_previous_fail_count
);
274 } else if (ctx
->expect
== EXPECT_PASS
) {
275 /* Nothing to validate. */
276 } else if (ctx
->expect
== EXPECT_SIGNAL
) {
277 error_in_expect(ctx
, "Test case was expected to receive a termination "
278 "signal but it continued execution");
279 } else if (ctx
->expect
== EXPECT_TIMEOUT
) {
280 error_in_expect(ctx
, "Test case was expected to hang but it continued "
287 expected_failure(struct context
*ctx
, atf_dynstr_t
*reason
)
289 check_fatal_error(atf_dynstr_prepend_fmt(reason
, "%s: ",
290 atf_dynstr_cstring(&ctx
->expect_reason
)));
291 create_resfile(ctx
->resfile
, "expected_failure", -1, reason
);
296 fail_requirement(struct context
*ctx
, atf_dynstr_t
*reason
)
298 if (ctx
->expect
== EXPECT_FAIL
) {
299 expected_failure(ctx
, reason
);
300 } else if (ctx
->expect
== EXPECT_PASS
) {
301 create_resfile(ctx
->resfile
, "failed", -1, reason
);
304 error_in_expect(ctx
, "Test case raised a failure but was not "
305 "expecting one; reason was %s", atf_dynstr_cstring(reason
));
311 fail_check(struct context
*ctx
, atf_dynstr_t
*reason
)
313 if (ctx
->expect
== EXPECT_FAIL
) {
314 fprintf(stderr
, "*** Expected check failure: %s: %s\n",
315 atf_dynstr_cstring(&ctx
->expect_reason
),
316 atf_dynstr_cstring(reason
));
317 ctx
->expect_fail_count
++;
318 } else if (ctx
->expect
== EXPECT_PASS
) {
319 fprintf(stderr
, "*** Check failed: %s\n", atf_dynstr_cstring(reason
));
322 error_in_expect(ctx
, "Test case raised a failure but was not "
323 "expecting one; reason was %s", atf_dynstr_cstring(reason
));
326 atf_dynstr_fini(reason
);
330 pass(struct context
*ctx
)
332 if (ctx
->expect
== EXPECT_FAIL
) {
333 error_in_expect(ctx
, "Test case was expecting a failure but got "
335 } else if (ctx
->expect
== EXPECT_PASS
) {
336 create_resfile(ctx
->resfile
, "passed", -1, NULL
);
339 error_in_expect(ctx
, "Test case asked to explicitly pass but was "
340 "not expecting such condition");
346 skip(struct context
*ctx
, atf_dynstr_t
*reason
)
348 if (ctx
->expect
== EXPECT_PASS
) {
349 create_resfile(ctx
->resfile
, "skipped", -1, reason
);
352 error_in_expect(ctx
, "Can only skip a test case when running in "
358 /** Formats a failure/skip reason message.
360 * The formatted reason is stored in out_reason. out_reason is initialized
361 * in this function and is supposed to be released by the caller. In general,
362 * the reason will eventually be fed to create_resfile, which will release
365 * Errors in this function are fatal. Rationale being: reasons are used to
366 * create results files; if we can't format the reason correctly, the result
367 * of the test program will be bogus. So it's better to just exit with a
371 format_reason_ap(atf_dynstr_t
*out_reason
,
372 const char *source_file
, const size_t source_line
,
373 const char *reason
, va_list ap
)
377 if (source_file
!= NULL
) {
378 err
= atf_dynstr_init_fmt(out_reason
, "%s:%zd: ", source_file
,
381 PRE(source_line
== 0);
382 err
= atf_dynstr_init(out_reason
);
385 if (!atf_is_error(err
)) {
388 err
= atf_dynstr_append_ap(out_reason
, reason
, ap2
);
392 check_fatal_error(err
);
396 format_reason_fmt(atf_dynstr_t
*out_reason
,
397 const char *source_file
, const size_t source_line
,
398 const char *reason
, ...)
402 va_start(ap
, reason
);
403 format_reason_ap(out_reason
, source_file
, source_line
, reason
, ap
);
408 errno_test(struct context
*ctx
, const char *file
, const size_t line
,
409 const int exp_errno
, const char *expr_str
,
410 const bool expr_result
,
411 void (*fail_func
)(struct context
*, atf_dynstr_t
*))
413 const int actual_errno
= errno
;
416 if (exp_errno
!= actual_errno
) {
419 format_reason_fmt(&reason
, file
, line
, "Expected errno %d, got %d, "
420 "in %s", exp_errno
, actual_errno
, expr_str
);
421 fail_func(ctx
, &reason
);
426 format_reason_fmt(&reason
, file
, line
, "Expected true value in %s",
428 fail_func(ctx
, &reason
);
432 struct prog_found_pair
{
438 check_prog_in_dir(const char *dir
, void *data
)
440 struct prog_found_pair
*pf
= data
;
444 err
= atf_no_error();
448 err
= atf_fs_path_init_fmt(&p
, "%s/%s", dir
, pf
->prog
);
449 if (atf_is_error(err
))
452 err
= atf_fs_eaccess(&p
, atf_fs_access_x
);
453 if (!atf_is_error(err
))
458 err
= atf_no_error();
462 atf_fs_path_fini(&p
);
469 check_prog(struct context
*ctx
, const char *prog
)
474 err
= atf_fs_path_init_fmt(&p
, "%s", prog
);
475 if (atf_is_error(err
))
478 if (atf_fs_path_is_absolute(&p
)) {
479 err
= atf_fs_eaccess(&p
, atf_fs_access_x
);
480 if (atf_is_error(err
)) {
484 atf_fs_path_fini(&p
);
485 format_reason_fmt(&reason
, NULL
, 0, "The required program %s could "
486 "not be found", prog
);
490 const char *path
= atf_env_get("PATH");
491 struct prog_found_pair pf
;
494 err
= atf_fs_path_branch_path(&p
, &bp
);
495 if (atf_is_error(err
))
498 if (strcmp(atf_fs_path_cstring(&bp
), ".") != 0) {
499 atf_fs_path_fini(&bp
);
500 atf_fs_path_fini(&p
);
502 report_fatal_error("Relative paths are not allowed when searching "
503 "for a program (%s)", prog
);
509 err
= atf_text_for_each_word(path
, ":", check_prog_in_dir
, &pf
);
510 if (atf_is_error(err
))
516 atf_fs_path_fini(&bp
);
517 atf_fs_path_fini(&p
);
518 format_reason_fmt(&reason
, NULL
, 0, "The required program %s could "
519 "not be found in the PATH", prog
);
520 fail_requirement(ctx
, &reason
);
524 atf_fs_path_fini(&bp
);
528 atf_fs_path_fini(&p
);
533 /* ---------------------------------------------------------------------
535 * --------------------------------------------------------------------- */
543 atf_tc_head_t m_head
;
544 atf_tc_body_t m_body
;
545 atf_tc_cleanup_t m_cleanup
;
549 * Constructors/destructors.
553 atf_tc_init(atf_tc_t
*tc
, const char *ident
, atf_tc_head_t head
,
554 atf_tc_body_t body
, atf_tc_cleanup_t cleanup
,
555 const char *const *config
)
559 tc
->pimpl
= malloc(sizeof(struct atf_tc_impl
));
560 if (tc
->pimpl
== NULL
) {
561 err
= atf_no_memory_error();
565 tc
->pimpl
->m_ident
= ident
;
566 tc
->pimpl
->m_head
= head
;
567 tc
->pimpl
->m_body
= body
;
568 tc
->pimpl
->m_cleanup
= cleanup
;
570 err
= atf_map_init_charpp(&tc
->pimpl
->m_config
, config
);
571 if (atf_is_error(err
))
574 err
= atf_map_init(&tc
->pimpl
->m_vars
);
575 if (atf_is_error(err
))
578 err
= atf_tc_set_md_var(tc
, "ident", "%s", ident
);
579 if (atf_is_error(err
))
582 if (cleanup
!= NULL
) {
583 err
= atf_tc_set_md_var(tc
, "has.cleanup", "true");
584 if (atf_is_error(err
))
588 /* XXX Should the head be able to return error codes? */
589 if (tc
->pimpl
->m_head
!= NULL
)
590 tc
->pimpl
->m_head(tc
);
592 if (strcmp(atf_tc_get_md_var(tc
, "ident"), ident
) != 0) {
593 report_fatal_error("Test case head modified the read-only 'ident' "
598 INV(!atf_is_error(err
));
602 atf_map_fini(&tc
->pimpl
->m_vars
);
604 atf_map_fini(&tc
->pimpl
->m_config
);
610 atf_tc_init_pack(atf_tc_t
*tc
, const atf_tc_pack_t
*pack
,
611 const char *const *config
)
613 return atf_tc_init(tc
, pack
->m_ident
, pack
->m_head
, pack
->m_body
,
614 pack
->m_cleanup
, config
);
618 atf_tc_fini(atf_tc_t
*tc
)
620 atf_map_fini(&tc
->pimpl
->m_vars
);
629 atf_tc_get_ident(const atf_tc_t
*tc
)
631 return tc
->pimpl
->m_ident
;
635 atf_tc_get_config_var(const atf_tc_t
*tc
, const char *name
)
638 atf_map_citer_t iter
;
640 PRE(atf_tc_has_config_var(tc
, name
));
641 iter
= atf_map_find_c(&tc
->pimpl
->m_config
, name
);
642 val
= atf_map_citer_data(iter
);
649 atf_tc_get_config_var_wd(const atf_tc_t
*tc
, const char *name
,
654 if (!atf_tc_has_config_var(tc
, name
))
657 val
= atf_tc_get_config_var(tc
, name
);
663 atf_tc_get_config_var_as_bool(const atf_tc_t
*tc
, const char *name
)
669 strval
= atf_tc_get_config_var(tc
, name
);
670 err
= atf_text_to_bool(strval
, &val
);
671 if (atf_is_error(err
)) {
673 atf_tc_fail("Configuration variable %s does not have a valid "
674 "boolean value; found %s", name
, strval
);
681 atf_tc_get_config_var_as_bool_wd(const atf_tc_t
*tc
, const char *name
,
686 if (!atf_tc_has_config_var(tc
, name
))
689 val
= atf_tc_get_config_var_as_bool(tc
, name
);
695 atf_tc_get_config_var_as_long(const atf_tc_t
*tc
, const char *name
)
701 strval
= atf_tc_get_config_var(tc
, name
);
702 err
= atf_text_to_long(strval
, &val
);
703 if (atf_is_error(err
)) {
705 atf_tc_fail("Configuration variable %s does not have a valid "
706 "long value; found %s", name
, strval
);
713 atf_tc_get_config_var_as_long_wd(const atf_tc_t
*tc
, const char *name
,
718 if (!atf_tc_has_config_var(tc
, name
))
721 val
= atf_tc_get_config_var_as_long(tc
, name
);
727 atf_tc_get_md_var(const atf_tc_t
*tc
, const char *name
)
730 atf_map_citer_t iter
;
732 PRE(atf_tc_has_md_var(tc
, name
));
733 iter
= atf_map_find_c(&tc
->pimpl
->m_vars
, name
);
734 val
= atf_map_citer_data(iter
);
741 atf_tc_get_md_vars(const atf_tc_t
*tc
)
743 return atf_map_to_charpp(&tc
->pimpl
->m_vars
);
747 atf_tc_has_config_var(const atf_tc_t
*tc
, const char *name
)
749 atf_map_citer_t end
, iter
;
751 iter
= atf_map_find_c(&tc
->pimpl
->m_config
, name
);
752 end
= atf_map_end_c(&tc
->pimpl
->m_config
);
753 return !atf_equal_map_citer_map_citer(iter
, end
);
757 atf_tc_has_md_var(const atf_tc_t
*tc
, const char *name
)
759 atf_map_citer_t end
, iter
;
761 iter
= atf_map_find_c(&tc
->pimpl
->m_vars
, name
);
762 end
= atf_map_end_c(&tc
->pimpl
->m_vars
);
763 return !atf_equal_map_citer_map_citer(iter
, end
);
771 atf_tc_set_md_var(atf_tc_t
*tc
, const char *name
, const char *fmt
, ...)
778 err
= atf_text_format_ap(&value
, fmt
, ap
);
781 if (!atf_is_error(err
))
782 err
= atf_map_insert(&tc
->pimpl
->m_vars
, name
, value
, true);
789 /* ---------------------------------------------------------------------
790 * Free functions, as they should be publicly but they can't.
791 * --------------------------------------------------------------------- */
793 static void _atf_tc_fail(struct context
*, const char *, va_list)
794 ATF_DEFS_ATTRIBUTE_FORMAT_PRINTF(2, 0)
795 ATF_DEFS_ATTRIBUTE_NORETURN
;
796 static void _atf_tc_fail_nonfatal(struct context
*, const char *, va_list)
797 ATF_DEFS_ATTRIBUTE_FORMAT_PRINTF(2, 0);
798 static void _atf_tc_fail_check(struct context
*, const char *, const size_t,
799 const char *, va_list)
800 ATF_DEFS_ATTRIBUTE_FORMAT_PRINTF(4, 0);
801 static void _atf_tc_fail_requirement(struct context
*, const char *,
802 const size_t, const char *, va_list)
803 ATF_DEFS_ATTRIBUTE_NORETURN
804 ATF_DEFS_ATTRIBUTE_FORMAT_PRINTF(4, 0);
805 static void _atf_tc_pass(struct context
*) ATF_DEFS_ATTRIBUTE_NORETURN
;
806 static void _atf_tc_require_prog(struct context
*, const char *);
807 static void _atf_tc_skip(struct context
*, const char *, va_list)
808 ATF_DEFS_ATTRIBUTE_FORMAT_PRINTF(2, 0)
809 ATF_DEFS_ATTRIBUTE_NORETURN
;
810 static void _atf_tc_check_errno(struct context
*, const char *, const size_t,
811 const int, const char *, const bool);
812 static void _atf_tc_require_errno(struct context
*, const char *, const size_t,
813 const int, const char *, const bool);
814 static void _atf_tc_expect_pass(struct context
*);
815 static void _atf_tc_expect_fail(struct context
*, const char *, va_list)
816 ATF_DEFS_ATTRIBUTE_FORMAT_PRINTF(2, 0);
817 static void _atf_tc_expect_exit(struct context
*, const int, const char *,
818 va_list) ATF_DEFS_ATTRIBUTE_FORMAT_PRINTF(3, 0);
819 static void _atf_tc_expect_signal(struct context
*, const int, const char *,
820 va_list) ATF_DEFS_ATTRIBUTE_FORMAT_PRINTF(3, 0);
821 static void _atf_tc_expect_death(struct context
*, const char *,
822 va_list) ATF_DEFS_ATTRIBUTE_FORMAT_PRINTF(2, 0);
825 _atf_tc_fail(struct context
*ctx
, const char *fmt
, va_list ap
)
831 format_reason_ap(&reason
, NULL
, 0, fmt
, ap2
);
834 fail_requirement(ctx
, &reason
);
839 _atf_tc_fail_nonfatal(struct context
*ctx
, const char *fmt
, va_list ap
)
845 format_reason_ap(&reason
, NULL
, 0, fmt
, ap2
);
848 fail_check(ctx
, &reason
);
852 _atf_tc_fail_check(struct context
*ctx
, const char *file
, const size_t line
,
853 const char *fmt
, va_list ap
)
859 format_reason_ap(&reason
, file
, line
, fmt
, ap2
);
862 fail_check(ctx
, &reason
);
866 _atf_tc_fail_requirement(struct context
*ctx
, const char *file
,
867 const size_t line
, const char *fmt
, va_list ap
)
873 format_reason_ap(&reason
, file
, line
, fmt
, ap2
);
876 fail_requirement(ctx
, &reason
);
881 _atf_tc_pass(struct context
*ctx
)
888 _atf_tc_require_prog(struct context
*ctx
, const char *prog
)
890 check_fatal_error(check_prog(ctx
, prog
));
894 _atf_tc_skip(struct context
*ctx
, const char *fmt
, va_list ap
)
900 format_reason_ap(&reason
, NULL
, 0, fmt
, ap2
);
907 _atf_tc_check_errno(struct context
*ctx
, const char *file
, const size_t line
,
908 const int exp_errno
, const char *expr_str
,
909 const bool expr_result
)
911 errno_test(ctx
, file
, line
, exp_errno
, expr_str
, expr_result
, fail_check
);
915 _atf_tc_require_errno(struct context
*ctx
, const char *file
, const size_t line
,
916 const int exp_errno
, const char *expr_str
,
917 const bool expr_result
)
919 errno_test(ctx
, file
, line
, exp_errno
, expr_str
, expr_result
,
924 _atf_tc_expect_pass(struct context
*ctx
)
926 validate_expect(ctx
);
928 ctx
->expect
= EXPECT_PASS
;
932 _atf_tc_expect_fail(struct context
*ctx
, const char *reason
, va_list ap
)
936 validate_expect(ctx
);
938 ctx
->expect
= EXPECT_FAIL
;
939 atf_dynstr_fini(&ctx
->expect_reason
);
941 check_fatal_error(atf_dynstr_init_ap(&ctx
->expect_reason
, reason
, ap2
));
943 ctx
->expect_previous_fail_count
= ctx
->expect_fail_count
;
947 _atf_tc_expect_exit(struct context
*ctx
, const int exitcode
, const char *reason
,
951 atf_dynstr_t formatted
;
953 validate_expect(ctx
);
955 ctx
->expect
= EXPECT_EXIT
;
957 check_fatal_error(atf_dynstr_init_ap(&formatted
, reason
, ap2
));
960 create_resfile(ctx
->resfile
, "expected_exit", exitcode
, &formatted
);
964 _atf_tc_expect_signal(struct context
*ctx
, const int signo
, const char *reason
,
968 atf_dynstr_t formatted
;
970 validate_expect(ctx
);
972 ctx
->expect
= EXPECT_SIGNAL
;
974 check_fatal_error(atf_dynstr_init_ap(&formatted
, reason
, ap2
));
977 create_resfile(ctx
->resfile
, "expected_signal", signo
, &formatted
);
981 _atf_tc_expect_death(struct context
*ctx
, const char *reason
, va_list ap
)
984 atf_dynstr_t formatted
;
986 validate_expect(ctx
);
988 ctx
->expect
= EXPECT_DEATH
;
990 check_fatal_error(atf_dynstr_init_ap(&formatted
, reason
, ap2
));
993 create_resfile(ctx
->resfile
, "expected_death", -1, &formatted
);
996 ATF_DEFS_ATTRIBUTE_FORMAT_PRINTF(2, 0)
998 _atf_tc_expect_timeout(struct context
*ctx
, const char *reason
, va_list ap
)
1001 atf_dynstr_t formatted
;
1003 validate_expect(ctx
);
1005 ctx
->expect
= EXPECT_TIMEOUT
;
1007 check_fatal_error(atf_dynstr_init_ap(&formatted
, reason
, ap2
));
1010 create_resfile(ctx
->resfile
, "expected_timeout", -1, &formatted
);
1013 /* ---------------------------------------------------------------------
1015 * --------------------------------------------------------------------- */
1017 static struct context Current
;
1020 atf_tc_run(const atf_tc_t
*tc
, const char *resfile
)
1022 context_init(&Current
, tc
, resfile
);
1024 tc
->pimpl
->m_body(tc
);
1026 validate_expect(&Current
);
1028 if (Current
.fail_count
> 0) {
1029 atf_dynstr_t reason
;
1031 format_reason_fmt(&reason
, NULL
, 0, "%zu checks failed; see output for "
1032 "more details", Current
.fail_count
);
1033 fail_requirement(&Current
, &reason
);
1034 } else if (Current
.expect_fail_count
> 0) {
1035 atf_dynstr_t reason
;
1037 format_reason_fmt(&reason
, NULL
, 0, "%zu checks failed as expected; "
1038 "see output for more details", Current
.expect_fail_count
);
1039 expected_failure(&Current
, &reason
);
1044 return atf_no_error();
1048 atf_tc_cleanup(const atf_tc_t
*tc
)
1050 if (tc
->pimpl
->m_cleanup
!= NULL
)
1051 tc
->pimpl
->m_cleanup(tc
);
1052 return atf_no_error(); /* XXX */
1055 /* ---------------------------------------------------------------------
1056 * Free functions that depend on Current.
1057 * --------------------------------------------------------------------- */
1060 * All the functions below provide delegates to other internal functions
1061 * (prefixed by _) that take the current test case as an argument to
1062 * prevent them from accessing global state. This is to keep the side-
1063 * effects of the internal functions clearer and easier to understand.
1065 * The public API should never have hid the fact that it needs access to
1066 * the current test case (other than maybe in the macros), but changing it
1067 * is hard. TODO: Revisit in the future.
1071 atf_tc_fail(const char *fmt
, ...)
1075 PRE(Current
.tc
!= NULL
);
1078 _atf_tc_fail(&Current
, fmt
, ap
);
1083 atf_tc_fail_nonfatal(const char *fmt
, ...)
1087 PRE(Current
.tc
!= NULL
);
1090 _atf_tc_fail_nonfatal(&Current
, fmt
, ap
);
1095 atf_tc_fail_check(const char *file
, const size_t line
, const char *fmt
, ...)
1099 PRE(Current
.tc
!= NULL
);
1102 _atf_tc_fail_check(&Current
, file
, line
, fmt
, ap
);
1107 atf_tc_fail_requirement(const char *file
, const size_t line
,
1108 const char *fmt
, ...)
1112 PRE(Current
.tc
!= NULL
);
1115 _atf_tc_fail_requirement(&Current
, file
, line
, fmt
, ap
);
1122 PRE(Current
.tc
!= NULL
);
1124 _atf_tc_pass(&Current
);
1128 atf_tc_require_prog(const char *prog
)
1130 PRE(Current
.tc
!= NULL
);
1132 _atf_tc_require_prog(&Current
, prog
);
1136 atf_tc_skip(const char *fmt
, ...)
1140 PRE(Current
.tc
!= NULL
);
1143 _atf_tc_skip(&Current
, fmt
, ap
);
1148 atf_tc_check_errno(const char *file
, const size_t line
, const int exp_errno
,
1149 const char *expr_str
, const bool expr_result
)
1151 PRE(Current
.tc
!= NULL
);
1153 _atf_tc_check_errno(&Current
, file
, line
, exp_errno
, expr_str
,
1158 atf_tc_require_errno(const char *file
, const size_t line
, const int exp_errno
,
1159 const char *expr_str
, const bool expr_result
)
1161 PRE(Current
.tc
!= NULL
);
1163 _atf_tc_require_errno(&Current
, file
, line
, exp_errno
, expr_str
,
1168 atf_tc_expect_pass(void)
1170 PRE(Current
.tc
!= NULL
);
1172 _atf_tc_expect_pass(&Current
);
1176 atf_tc_expect_fail(const char *reason
, ...)
1180 PRE(Current
.tc
!= NULL
);
1182 va_start(ap
, reason
);
1183 _atf_tc_expect_fail(&Current
, reason
, ap
);
1188 atf_tc_expect_exit(const int exitcode
, const char *reason
, ...)
1192 PRE(Current
.tc
!= NULL
);
1194 va_start(ap
, reason
);
1195 _atf_tc_expect_exit(&Current
, exitcode
, reason
, ap
);
1200 atf_tc_expect_signal(const int signo
, const char *reason
, ...)
1204 PRE(Current
.tc
!= NULL
);
1206 va_start(ap
, reason
);
1207 _atf_tc_expect_signal(&Current
, signo
, reason
, ap
);
1212 atf_tc_expect_death(const char *reason
, ...)
1216 PRE(Current
.tc
!= NULL
);
1218 va_start(ap
, reason
);
1219 _atf_tc_expect_death(&Current
, reason
, ap
);
1224 atf_tc_expect_timeout(const char *reason
, ...)
1228 PRE(Current
.tc
!= NULL
);
1230 va_start(ap
, reason
);
1231 _atf_tc_expect_timeout(&Current
, reason
, ap
);