xref: /freebsd/contrib/atf/atf-c/tp.c (revision 7661de35d15f582ab33e3bd6b8d909601557e436)
1 /*
2  * Automated Testing Framework (atf)
3  *
4  * Copyright (c) 2008 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 
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <unistd.h>
34 
35 #include "atf-c/error.h"
36 #include "atf-c/tc.h"
37 #include "atf-c/tp.h"
38 
39 #include "detail/fs.h"
40 #include "detail/map.h"
41 #include "detail/sanity.h"
42 
43 struct atf_tp_impl {
44     atf_list_t m_tcs;
45     atf_map_t m_config;
46 };
47 
48 /* ---------------------------------------------------------------------
49  * Auxiliary functions.
50  * --------------------------------------------------------------------- */
51 
52 static
53 const atf_tc_t *
54 find_tc(const atf_tp_t *tp, const char *ident)
55 {
56     const atf_tc_t *tc;
57     atf_list_citer_t iter;
58 
59     tc = NULL;
60     atf_list_for_each_c(iter, &tp->pimpl->m_tcs) {
61         const atf_tc_t *tc2;
62         tc2 = atf_list_citer_data(iter);
63         if (strcmp(atf_tc_get_ident(tc2), ident) == 0) {
64             tc = tc2;
65             break;
66         }
67     }
68     return tc;
69 }
70 
71 /* ---------------------------------------------------------------------
72  * The "atf_tp" type.
73  * --------------------------------------------------------------------- */
74 
75 /*
76  * Constructors/destructors.
77  */
78 
79 atf_error_t
80 atf_tp_init(atf_tp_t *tp, const char *const *config)
81 {
82     atf_error_t err;
83 
84     PRE(config != NULL);
85 
86     tp->pimpl = malloc(sizeof(struct atf_tp_impl));
87     if (tp->pimpl == NULL)
88         return atf_no_memory_error();
89 
90     err = atf_list_init(&tp->pimpl->m_tcs);
91     if (atf_is_error(err))
92         goto out;
93 
94     err = atf_map_init_charpp(&tp->pimpl->m_config, config);
95     if (atf_is_error(err)) {
96         atf_list_fini(&tp->pimpl->m_tcs);
97         goto out;
98     }
99 
100     INV(!atf_is_error(err));
101 out:
102     return err;
103 }
104 
105 void
106 atf_tp_fini(atf_tp_t *tp)
107 {
108     atf_list_iter_t iter;
109 
110     atf_map_fini(&tp->pimpl->m_config);
111 
112     atf_list_for_each(iter, &tp->pimpl->m_tcs) {
113         atf_tc_t *tc = atf_list_iter_data(iter);
114         atf_tc_fini(tc);
115     }
116     atf_list_fini(&tp->pimpl->m_tcs);
117 
118     free(tp->pimpl);
119 }
120 
121 /*
122  * Getters.
123  */
124 
125 char **
126 atf_tp_get_config(const atf_tp_t *tp)
127 {
128     return atf_map_to_charpp(&tp->pimpl->m_config);
129 }
130 
131 bool
132 atf_tp_has_tc(const atf_tp_t *tp, const char *id)
133 {
134     const atf_tc_t *tc = find_tc(tp, id);
135     return tc != NULL;
136 }
137 
138 const atf_tc_t *
139 atf_tp_get_tc(const atf_tp_t *tp, const char *id)
140 {
141     const atf_tc_t *tc = find_tc(tp, id);
142     PRE(tc != NULL);
143     return tc;
144 }
145 
146 const atf_tc_t *const *
147 atf_tp_get_tcs(const atf_tp_t *tp)
148 {
149     const atf_tc_t **array;
150     atf_list_citer_t iter;
151     size_t i;
152 
153     array = malloc(sizeof(atf_tc_t *) *
154                    (atf_list_size(&tp->pimpl->m_tcs) + 1));
155     if (array == NULL)
156         goto out;
157 
158     i = 0;
159     atf_list_for_each_c(iter, &tp->pimpl->m_tcs) {
160         array[i] = atf_list_citer_data(iter);
161         if (array[i] == NULL) {
162             free(array);
163             array = NULL;
164             goto out;
165         }
166 
167         i++;
168     }
169     array[i] = NULL;
170 
171 out:
172     return array;
173 }
174 
175 /*
176  * Modifiers.
177  */
178 
179 atf_error_t
180 atf_tp_add_tc(atf_tp_t *tp, atf_tc_t *tc)
181 {
182     atf_error_t err;
183 
184     PRE(find_tc(tp, atf_tc_get_ident(tc)) == NULL);
185 
186     err = atf_list_append(&tp->pimpl->m_tcs, tc, false);
187 
188     POST(find_tc(tp, atf_tc_get_ident(tc)) != NULL);
189 
190     return err;
191 }
192 
193 /* ---------------------------------------------------------------------
194  * Free functions.
195  * --------------------------------------------------------------------- */
196 
197 atf_error_t
198 atf_tp_run(const atf_tp_t *tp, const char *tcname, const char *resfile)
199 {
200     const atf_tc_t *tc;
201 
202     tc = find_tc(tp, tcname);
203     PRE(tc != NULL);
204 
205     return atf_tc_run(tc, resfile);
206 }
207 
208 atf_error_t
209 atf_tp_cleanup(const atf_tp_t *tp, const char *tcname)
210 {
211     const atf_tc_t *tc;
212 
213     tc = find_tc(tp, tcname);
214     PRE(tc != NULL);
215 
216     return atf_tc_cleanup(tc);
217 }
218