xref: /freebsd/contrib/atf/atf-c/build_test.c (revision 8d20be1e22095c27faf8fe8b2f0d089739cc742e)
1 /*
2  * Automated Testing Framework (atf)
3  *
4  * Copyright (c) 2009 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 
34 #include <atf-c.h>
35 
36 #include "atf-c/build.h"
37 #include "atf-c/config.h"
38 #include "atf-c/utils.h"
39 
40 #include "detail/env.h"
41 #include "detail/test_helpers.h"
42 #include "h_build.h"
43 
44 /* ---------------------------------------------------------------------
45  * Auxiliary functions.
46  * --------------------------------------------------------------------- */
47 
48 void __atf_config_reinit(void);
49 
50 static
51 bool
52 equal_arrays(const char *const *exp_array, char **actual_array)
53 {
54     bool equal;
55 
56     if (*exp_array == NULL && *actual_array == NULL)
57         equal = true;
58     else if (*exp_array == NULL || *actual_array == NULL)
59         equal = false;
60     else {
61         equal = true;
62         while (*actual_array != NULL) {
63             if (*exp_array == NULL || strcmp(*exp_array, *actual_array) != 0) {
64                 equal = false;
65                 break;
66             }
67             exp_array++;
68             actual_array++;
69         }
70     }
71 
72     return equal;
73 }
74 
75 static
76 void
77 check_equal_array(const char *const *exp_array, char **actual_array)
78 {
79     {
80         const char *const *exp_ptr;
81         printf("Expected arguments:");
82         for (exp_ptr = exp_array; *exp_ptr != NULL; exp_ptr++)
83             printf(" '%s'", *exp_ptr);
84         printf("\n");
85     }
86 
87     {
88         char **actual_ptr;
89         printf("Returned arguments:");
90         for (actual_ptr = actual_array; *actual_ptr != NULL; actual_ptr++)
91             printf(" '%s'", *actual_ptr);
92         printf("\n");
93     }
94 
95     if (!equal_arrays(exp_array, actual_array))
96         atf_tc_fail_nonfatal("The constructed argv differs from the "
97                              "expected values");
98 }
99 
100 static
101 void
102 verbose_set_env(const char *var, const char *val)
103 {
104     printf("Setting %s to '%s'\n", var, val);
105     RE(atf_env_set(var, val));
106 }
107 
108 /* ---------------------------------------------------------------------
109  * Internal test cases.
110  * --------------------------------------------------------------------- */
111 
112 ATF_TC(equal_arrays);
113 ATF_TC_HEAD(equal_arrays, tc)
114 {
115     atf_tc_set_md_var(tc, "descr", "Tests the test case internal "
116                       "equal_arrays function");
117 }
118 ATF_TC_BODY(equal_arrays, tc)
119 {
120     {
121         const char *const exp[] = { NULL };
122         char *actual[] = { NULL };
123 
124         ATF_CHECK(equal_arrays(exp, actual));
125     }
126 
127     {
128         const char *const exp[] = { NULL };
129         char *actual[2] = { strdup("foo"), NULL };
130 
131         ATF_CHECK(!equal_arrays(exp, actual));
132         free(actual[0]);
133     }
134 
135     {
136         const char *const exp[] = { "foo", NULL };
137         char *actual[] = { NULL };
138 
139         ATF_CHECK(!equal_arrays(exp, actual));
140     }
141 
142     {
143         const char *const exp[] = { "foo", NULL };
144         char *actual[2] = { strdup("foo"), NULL };
145 
146         ATF_CHECK(equal_arrays(exp, actual));
147         free(actual[0]);
148     }
149 }
150 
151 /* ---------------------------------------------------------------------
152  * Test cases for the free functions.
153  * --------------------------------------------------------------------- */
154 
155 ATF_TC(c_o);
156 ATF_TC_HEAD(c_o, tc)
157 {
158     atf_tc_set_md_var(tc, "descr", "Tests the atf_build_c_o function");
159 }
160 ATF_TC_BODY(c_o, tc)
161 {
162     struct c_o_test *test;
163 
164     for (test = c_o_tests; test->expargv[0] != NULL; test++) {
165         printf("> Test: %s\n", test->msg);
166 
167         verbose_set_env("ATF_BUILD_CC", test->cc);
168         verbose_set_env("ATF_BUILD_CFLAGS", test->cflags);
169         verbose_set_env("ATF_BUILD_CPPFLAGS", test->cppflags);
170         __atf_config_reinit();
171 
172         {
173             char **argv;
174             if (test->hasoptargs)
175                 RE(atf_build_c_o(test->sfile, test->ofile, test->optargs,
176                                  &argv));
177             else
178                 RE(atf_build_c_o(test->sfile, test->ofile, NULL, &argv));
179             check_equal_array(test->expargv, argv);
180             atf_utils_free_charpp(argv);
181         }
182     }
183 }
184 
185 ATF_TC(cpp);
186 ATF_TC_HEAD(cpp, tc)
187 {
188     atf_tc_set_md_var(tc, "descr", "Tests the atf_build_cpp function");
189 }
190 ATF_TC_BODY(cpp, tc)
191 {
192     struct cpp_test *test;
193 
194     for (test = cpp_tests; test->expargv[0] != NULL; test++) {
195         printf("> Test: %s\n", test->msg);
196 
197         verbose_set_env("ATF_BUILD_CPP", test->cpp);
198         verbose_set_env("ATF_BUILD_CPPFLAGS", test->cppflags);
199         __atf_config_reinit();
200 
201         {
202             char **argv;
203             if (test->hasoptargs)
204                 RE(atf_build_cpp(test->sfile, test->ofile, test->optargs,
205                                  &argv));
206             else
207                 RE(atf_build_cpp(test->sfile, test->ofile, NULL, &argv));
208             check_equal_array(test->expargv, argv);
209             atf_utils_free_charpp(argv);
210         }
211     }
212 }
213 
214 ATF_TC(cxx_o);
215 ATF_TC_HEAD(cxx_o, tc)
216 {
217     atf_tc_set_md_var(tc, "descr", "Tests the atf_build_cxx_o function");
218 }
219 ATF_TC_BODY(cxx_o, tc)
220 {
221     struct cxx_o_test *test;
222 
223     for (test = cxx_o_tests; test->expargv[0] != NULL; test++) {
224         printf("> Test: %s\n", test->msg);
225 
226         verbose_set_env("ATF_BUILD_CXX", test->cxx);
227         verbose_set_env("ATF_BUILD_CXXFLAGS", test->cxxflags);
228         verbose_set_env("ATF_BUILD_CPPFLAGS", test->cppflags);
229         __atf_config_reinit();
230 
231         {
232             char **argv;
233             if (test->hasoptargs)
234                 RE(atf_build_cxx_o(test->sfile, test->ofile, test->optargs,
235                                    &argv));
236             else
237                 RE(atf_build_cxx_o(test->sfile, test->ofile, NULL, &argv));
238             check_equal_array(test->expargv, argv);
239             atf_utils_free_charpp(argv);
240         }
241     }
242 }
243 
244 /* ---------------------------------------------------------------------
245  * Tests cases for the header file.
246  * --------------------------------------------------------------------- */
247 
248 HEADER_TC(include, "atf-c/build.h");
249 
250 /* ---------------------------------------------------------------------
251  * Main.
252  * --------------------------------------------------------------------- */
253 
254 ATF_TP_ADD_TCS(tp)
255 {
256     /* Add the internal test cases. */
257     ATF_TP_ADD_TC(tp, equal_arrays);
258 
259     /* Add the test cases for the free functions. */
260     ATF_TP_ADD_TC(tp, c_o);
261     ATF_TP_ADD_TC(tp, cpp);
262     ATF_TP_ADD_TC(tp, cxx_o);
263 
264     /* Add the test cases for the header file. */
265     ATF_TP_ADD_TC(tp, include);
266 
267     return atf_no_error();
268 }
269