Expand PMF_FN_* macros.
[netbsd-mini2440.git] / external / bsd / atf / dist / atf-c / tp.c
blobbfc87a9964f88da75d696b87463d0a7ae5c9d9e9
1 /*
2 * Automated Testing Framework (atf)
4 * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
5 * All rights reserved.
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.
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 <stdio.h>
31 #include <string.h>
32 #include <unistd.h>
34 #include "atf-c/error.h"
35 #include "atf-c/fs.h"
36 #include "atf-c/io.h"
37 #include "atf-c/sanity.h"
38 #include "atf-c/tc.h"
39 #include "atf-c/tcr.h"
40 #include "atf-c/tp.h"
42 /* ---------------------------------------------------------------------
43 * Auxiliary functions.
44 * --------------------------------------------------------------------- */
46 static
47 const atf_tc_t *
48 find_tc(const atf_tp_t *tp, const char *ident)
50 const atf_tc_t *tc;
51 atf_list_citer_t iter;
53 tc = NULL;
54 atf_list_for_each_c(iter, &tp->m_tcs) {
55 const atf_tc_t *tc2;
56 tc2 = atf_list_citer_data(iter);
57 if (strcmp(tc2->m_ident, ident) == 0) {
58 tc = tc2;
59 break;
62 return tc;
65 /* ---------------------------------------------------------------------
66 * The "atf_tp" type.
67 * --------------------------------------------------------------------- */
70 * Constructors/destructors.
73 atf_error_t
74 atf_tp_init(atf_tp_t *tp, struct atf_map *config)
76 atf_error_t err;
78 PRE(config != NULL);
80 atf_object_init(&tp->m_object);
82 err = atf_list_init(&tp->m_tcs);
83 if (atf_is_error(err))
84 goto err_object;
86 tp->m_config = config;
88 INV(!atf_is_error(err));
89 return err;
91 err_object:
92 atf_object_fini(&tp->m_object);
93 return err;
96 void
97 atf_tp_fini(atf_tp_t *tp)
99 atf_list_iter_t iter;
101 atf_list_for_each(iter, &tp->m_tcs) {
102 atf_tc_t *tc = atf_list_iter_data(iter);
103 atf_tc_fini(tc);
105 atf_list_fini(&tp->m_tcs);
107 atf_object_fini(&tp->m_object);
111 * Getters.
114 const struct atf_map *
115 atf_tp_get_config(const atf_tp_t *tp)
117 return tp->m_config;
120 const atf_tc_t *
121 atf_tp_get_tc(const atf_tp_t *tp, const char *id)
123 const atf_tc_t *tc = find_tc(tp, id);
124 PRE(tc != NULL);
125 return tc;
128 const atf_list_t *
129 atf_tp_get_tcs(const atf_tp_t *tp)
131 return &tp->m_tcs;
135 * Modifiers.
138 atf_error_t
139 atf_tp_add_tc(atf_tp_t *tp, atf_tc_t *tc)
141 atf_error_t err;
143 PRE(find_tc(tp, tc->m_ident) == NULL);
145 err = atf_list_append(&tp->m_tcs, tc, false);
147 POST(find_tc(tp, tc->m_ident) != NULL);
149 return err;
152 /* ---------------------------------------------------------------------
153 * Free functions.
154 * --------------------------------------------------------------------- */
156 atf_error_t
157 atf_tp_run(const atf_tp_t *tp, const atf_list_t *ids, int fd,
158 const atf_fs_path_t *workdir, size_t *failcount)
160 atf_error_t err;
161 atf_list_citer_t iter;
162 size_t count;
164 err = atf_io_write_fmt(fd, "Content-Type: application/X-atf-tcs; "
165 "version=\"1\"\n\n");
166 if (atf_is_error(err))
167 goto out;
168 err = atf_io_write_fmt(fd, "tcs-count: %d\n", atf_list_size(ids));
169 if (atf_is_error(err))
170 goto out;
172 *failcount = count = 0;
173 atf_list_for_each_c(iter, ids) {
174 const char *ident = atf_list_citer_data(iter);
175 const atf_tc_t *tc;
176 atf_tcr_t tcr;
177 int state;
179 err = atf_io_write_fmt(fd, "tc-start: %s\n", ident);
180 if (atf_is_error(err))
181 goto out;
183 tc = find_tc(tp, ident);
184 PRE(tc != NULL);
186 err = atf_tc_run(tc, &tcr, STDOUT_FILENO, STDERR_FILENO, workdir);
187 if (atf_is_error(err))
188 goto out;
190 count++;
191 if (count < atf_list_size(ids)) {
192 fprintf(stdout, "__atf_tc_separator__\n");
193 fprintf(stderr, "__atf_tc_separator__\n");
195 fflush(stdout);
196 fflush(stderr);
198 state = atf_tcr_get_state(&tcr);
199 if (state == atf_tcr_passed_state) {
200 err = atf_io_write_fmt(fd, "tc-end: %s, passed\n", ident);
201 } else if (state == atf_tcr_failed_state) {
202 const atf_dynstr_t *reason = atf_tcr_get_reason(&tcr);
203 err = atf_io_write_fmt(fd, "tc-end: %s, failed, %s\n", ident,
204 atf_dynstr_cstring(reason));
205 (*failcount)++;
206 } else if (state == atf_tcr_skipped_state) {
207 const atf_dynstr_t *reason = atf_tcr_get_reason(&tcr);
208 err = atf_io_write_fmt(fd, "tc-end: %s, skipped, %s\n", ident,
209 atf_dynstr_cstring(reason));
210 } else
211 UNREACHABLE;
212 atf_tcr_fini(&tcr);
213 if (atf_is_error(err))
214 goto out;
217 out:
218 return err;