xref: /netbsd/external/bsd/atf/dist/atf-c/macros_test.c (revision 032c8705)
1edebbb8eSjmmv /*
2edebbb8eSjmmv  * Automated Testing Framework (atf)
3edebbb8eSjmmv  *
46debfaafSjmmv  * Copyright (c) 2008 The NetBSD Foundation, Inc.
5edebbb8eSjmmv  * All rights reserved.
6edebbb8eSjmmv  *
7edebbb8eSjmmv  * Redistribution and use in source and binary forms, with or without
8edebbb8eSjmmv  * modification, are permitted provided that the following conditions
9edebbb8eSjmmv  * are met:
10edebbb8eSjmmv  * 1. Redistributions of source code must retain the above copyright
11edebbb8eSjmmv  *    notice, this list of conditions and the following disclaimer.
12edebbb8eSjmmv  * 2. Redistributions in binary form must reproduce the above copyright
13edebbb8eSjmmv  *    notice, this list of conditions and the following disclaimer in the
14edebbb8eSjmmv  *    documentation and/or other materials provided with the distribution.
15edebbb8eSjmmv  *
16edebbb8eSjmmv  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
17edebbb8eSjmmv  * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
18edebbb8eSjmmv  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19edebbb8eSjmmv  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20edebbb8eSjmmv  * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
21edebbb8eSjmmv  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22edebbb8eSjmmv  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
23edebbb8eSjmmv  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24edebbb8eSjmmv  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25edebbb8eSjmmv  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26edebbb8eSjmmv  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27edebbb8eSjmmv  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28edebbb8eSjmmv  */
29edebbb8eSjmmv 
30edebbb8eSjmmv #include <sys/types.h>
31edebbb8eSjmmv #include <sys/wait.h>
32edebbb8eSjmmv 
33edebbb8eSjmmv #include <errno.h>
34edebbb8eSjmmv #include <fcntl.h>
35edebbb8eSjmmv #include <stdarg.h>
36edebbb8eSjmmv #include <stdbool.h>
37edebbb8eSjmmv #include <stdio.h>
38edebbb8eSjmmv #include <stdlib.h>
39edebbb8eSjmmv #include <string.h>
40edebbb8eSjmmv #include <unistd.h>
41edebbb8eSjmmv 
42edebbb8eSjmmv #include <atf-c.h>
43edebbb8eSjmmv 
44895f502bSjmmv #include "detail/fs.h"
45895f502bSjmmv #include "detail/process.h"
46895f502bSjmmv #include "detail/test_helpers.h"
47895f502bSjmmv #include "detail/text.h"
48edebbb8eSjmmv 
49edebbb8eSjmmv /* ---------------------------------------------------------------------
50edebbb8eSjmmv  * Auxiliary functions.
51edebbb8eSjmmv  * --------------------------------------------------------------------- */
52edebbb8eSjmmv 
53edebbb8eSjmmv static
54edebbb8eSjmmv void
create_ctl_file(const char * name)556debfaafSjmmv create_ctl_file(const char *name)
56edebbb8eSjmmv {
57edebbb8eSjmmv     atf_fs_path_t p;
58edebbb8eSjmmv 
59edebbb8eSjmmv     RE(atf_fs_path_init_fmt(&p, "%s", name));
60edebbb8eSjmmv     ATF_REQUIRE(open(atf_fs_path_cstring(&p),
61edebbb8eSjmmv                    O_CREAT | O_WRONLY | O_TRUNC, 0644) != -1);
62edebbb8eSjmmv     atf_fs_path_fini(&p);
63edebbb8eSjmmv }
64edebbb8eSjmmv 
65edebbb8eSjmmv static
66edebbb8eSjmmv bool
exists(const char * p)67edebbb8eSjmmv exists(const char *p)
68edebbb8eSjmmv {
69edebbb8eSjmmv     bool b;
70edebbb8eSjmmv     atf_fs_path_t pp;
71edebbb8eSjmmv 
72edebbb8eSjmmv     RE(atf_fs_path_init_fmt(&pp, "%s", p));
73edebbb8eSjmmv     RE(atf_fs_exists(&pp, &b));
74edebbb8eSjmmv     atf_fs_path_fini(&pp);
75edebbb8eSjmmv 
76edebbb8eSjmmv     return b;
77edebbb8eSjmmv }
78edebbb8eSjmmv 
79edebbb8eSjmmv static
80edebbb8eSjmmv void
init_and_run_h_tc(const char * name,void (* head)(atf_tc_t *),void (* body)(const atf_tc_t *))81edebbb8eSjmmv init_and_run_h_tc(const char *name, void (*head)(atf_tc_t *),
82edebbb8eSjmmv                   void (*body)(const atf_tc_t *))
83edebbb8eSjmmv {
84edebbb8eSjmmv     atf_tc_t tc;
85895f502bSjmmv     const char *const config[] = { NULL };
86edebbb8eSjmmv 
87895f502bSjmmv     RE(atf_tc_init(&tc, name, head, body, NULL, config));
88edebbb8eSjmmv     run_h_tc(&tc, "output", "error", "result");
89edebbb8eSjmmv     atf_tc_fini(&tc);
90edebbb8eSjmmv }
91edebbb8eSjmmv 
92edebbb8eSjmmv /* ---------------------------------------------------------------------
93edebbb8eSjmmv  * Helper test cases.
94edebbb8eSjmmv  * --------------------------------------------------------------------- */
95edebbb8eSjmmv 
96edebbb8eSjmmv #define H_DEF(id, macro) \
97edebbb8eSjmmv     ATF_TC_HEAD(h_ ## id, tc) \
98edebbb8eSjmmv     { \
99edebbb8eSjmmv         atf_tc_set_md_var(tc, "descr", "Helper test case"); \
100edebbb8eSjmmv     } \
101edebbb8eSjmmv     ATF_TC_BODY(h_ ## id, tc) \
102edebbb8eSjmmv     { \
1036debfaafSjmmv         create_ctl_file("before"); \
104edebbb8eSjmmv         macro; \
1056debfaafSjmmv         create_ctl_file("after"); \
106edebbb8eSjmmv     }
107edebbb8eSjmmv 
108edebbb8eSjmmv #define H_CHECK_HEAD_NAME(id) ATF_TC_HEAD_NAME(h_check_ ## id)
109edebbb8eSjmmv #define H_CHECK_BODY_NAME(id) ATF_TC_BODY_NAME(h_check_ ## id)
110edebbb8eSjmmv #define H_CHECK(id, condition) \
111edebbb8eSjmmv     H_DEF(check_ ## id, ATF_CHECK(condition))
112edebbb8eSjmmv 
113edebbb8eSjmmv #define H_CHECK_MSG_HEAD_NAME(id) ATF_TC_HEAD_NAME(h_check_msg_ ## id)
114edebbb8eSjmmv #define H_CHECK_MSG_BODY_NAME(id) ATF_TC_BODY_NAME(h_check_msg_ ## id)
115edebbb8eSjmmv #define H_CHECK_MSG(id, condition, msg) \
116edebbb8eSjmmv     H_DEF(check_msg_ ## id, ATF_CHECK_MSG(condition, msg))
117edebbb8eSjmmv 
118edebbb8eSjmmv #define H_CHECK_EQ_HEAD_NAME(id) ATF_TC_HEAD_NAME(h_check_eq_ ## id)
119edebbb8eSjmmv #define H_CHECK_EQ_BODY_NAME(id) ATF_TC_BODY_NAME(h_check_eq_ ## id)
120edebbb8eSjmmv #define H_CHECK_EQ(id, v1, v2) \
121edebbb8eSjmmv     H_DEF(check_eq_ ## id, ATF_CHECK_EQ(v1, v2))
122edebbb8eSjmmv 
123edebbb8eSjmmv #define H_CHECK_STREQ_HEAD_NAME(id) ATF_TC_HEAD_NAME(h_check_streq_ ## id)
124edebbb8eSjmmv #define H_CHECK_STREQ_BODY_NAME(id) ATF_TC_BODY_NAME(h_check_streq_ ## id)
125edebbb8eSjmmv #define H_CHECK_STREQ(id, v1, v2) \
126edebbb8eSjmmv     H_DEF(check_streq_ ## id, ATF_CHECK_STREQ(v1, v2))
127edebbb8eSjmmv 
128f153ecaeSjmmv #define H_CHECK_MATCH_HEAD_NAME(id) ATF_TC_HEAD_NAME(h_check_match_ ## id)
129f153ecaeSjmmv #define H_CHECK_MATCH_BODY_NAME(id) ATF_TC_BODY_NAME(h_check_match_ ## id)
130f153ecaeSjmmv #define H_CHECK_MATCH(id, v1, v2) \
131f153ecaeSjmmv     H_DEF(check_match_ ## id, ATF_CHECK_MATCH(v1, v2))
132f153ecaeSjmmv 
133edebbb8eSjmmv #define H_CHECK_EQ_MSG_HEAD_NAME(id) \
134edebbb8eSjmmv     ATF_TC_HEAD_NAME(h_check_eq_msg_ ## id)
135edebbb8eSjmmv #define H_CHECK_EQ_MSG_BODY_NAME(id) \
136edebbb8eSjmmv     ATF_TC_BODY_NAME(h_check_eq_msg_ ## id)
137edebbb8eSjmmv #define H_CHECK_EQ_MSG(id, v1, v2, msg) \
138edebbb8eSjmmv     H_DEF(check_eq_msg_ ## id, ATF_CHECK_EQ_MSG(v1, v2, msg))
139edebbb8eSjmmv 
140edebbb8eSjmmv #define H_CHECK_STREQ_MSG_HEAD_NAME(id) \
141edebbb8eSjmmv     ATF_TC_HEAD_NAME(h_check_streq_msg_ ## id)
142edebbb8eSjmmv #define H_CHECK_STREQ_MSG_BODY_NAME(id) \
143edebbb8eSjmmv     ATF_TC_BODY_NAME(h_check_streq_msg_ ## id)
144edebbb8eSjmmv #define H_CHECK_STREQ_MSG(id, v1, v2, msg) \
145edebbb8eSjmmv     H_DEF(check_streq_msg_ ## id, ATF_CHECK_STREQ_MSG(v1, v2, msg))
146edebbb8eSjmmv 
147f153ecaeSjmmv #define H_CHECK_MATCH_MSG_HEAD_NAME(id) \
148f153ecaeSjmmv     ATF_TC_HEAD_NAME(h_check_match_msg_ ## id)
149f153ecaeSjmmv #define H_CHECK_MATCH_MSG_BODY_NAME(id) \
150f153ecaeSjmmv     ATF_TC_BODY_NAME(h_check_match_msg_ ## id)
151f153ecaeSjmmv #define H_CHECK_MATCH_MSG(id, v1, v2, msg) \
152f153ecaeSjmmv     H_DEF(check_match_msg_ ## id, ATF_CHECK_MATCH_MSG(v1, v2, msg))
153f153ecaeSjmmv 
154edebbb8eSjmmv #define H_CHECK_ERRNO_HEAD_NAME(id) ATF_TC_HEAD_NAME(h_check_errno_ ## id)
155edebbb8eSjmmv #define H_CHECK_ERRNO_BODY_NAME(id) ATF_TC_BODY_NAME(h_check_errno_ ## id)
156edebbb8eSjmmv #define H_CHECK_ERRNO(id, exp_errno, bool_expr) \
157edebbb8eSjmmv     H_DEF(check_errno_ ## id, ATF_CHECK_ERRNO(exp_errno, bool_expr))
158edebbb8eSjmmv 
159edebbb8eSjmmv #define H_REQUIRE_HEAD_NAME(id) ATF_TC_HEAD_NAME(h_require_ ## id)
160edebbb8eSjmmv #define H_REQUIRE_BODY_NAME(id) ATF_TC_BODY_NAME(h_require_ ## id)
161edebbb8eSjmmv #define H_REQUIRE(id, condition) \
162edebbb8eSjmmv     H_DEF(require_ ## id, ATF_REQUIRE(condition))
163edebbb8eSjmmv 
164edebbb8eSjmmv #define H_REQUIRE_MSG_HEAD_NAME(id) ATF_TC_HEAD_NAME(h_require_msg_ ## id)
165edebbb8eSjmmv #define H_REQUIRE_MSG_BODY_NAME(id) ATF_TC_BODY_NAME(h_require_msg_ ## id)
166edebbb8eSjmmv #define H_REQUIRE_MSG(id, condition, msg) \
167edebbb8eSjmmv     H_DEF(require_msg_ ## id, ATF_REQUIRE_MSG(condition, msg))
168edebbb8eSjmmv 
169edebbb8eSjmmv #define H_REQUIRE_EQ_HEAD_NAME(id) ATF_TC_HEAD_NAME(h_require_eq_ ## id)
170edebbb8eSjmmv #define H_REQUIRE_EQ_BODY_NAME(id) ATF_TC_BODY_NAME(h_require_eq_ ## id)
171edebbb8eSjmmv #define H_REQUIRE_EQ(id, v1, v2) \
172edebbb8eSjmmv     H_DEF(require_eq_ ## id, ATF_REQUIRE_EQ(v1, v2))
173edebbb8eSjmmv 
174edebbb8eSjmmv #define H_REQUIRE_STREQ_HEAD_NAME(id) ATF_TC_HEAD_NAME(h_require_streq_ ## id)
175edebbb8eSjmmv #define H_REQUIRE_STREQ_BODY_NAME(id) ATF_TC_BODY_NAME(h_require_streq_ ## id)
176edebbb8eSjmmv #define H_REQUIRE_STREQ(id, v1, v2) \
177edebbb8eSjmmv     H_DEF(require_streq_ ## id, ATF_REQUIRE_STREQ(v1, v2))
178edebbb8eSjmmv 
179f153ecaeSjmmv #define H_REQUIRE_MATCH_HEAD_NAME(id) ATF_TC_HEAD_NAME(h_require_match_ ## id)
180f153ecaeSjmmv #define H_REQUIRE_MATCH_BODY_NAME(id) ATF_TC_BODY_NAME(h_require_match_ ## id)
181f153ecaeSjmmv #define H_REQUIRE_MATCH(id, v1, v2) \
182f153ecaeSjmmv     H_DEF(require_match_ ## id, ATF_REQUIRE_MATCH(v1, v2))
183f153ecaeSjmmv 
184edebbb8eSjmmv #define H_REQUIRE_EQ_MSG_HEAD_NAME(id) \
185edebbb8eSjmmv     ATF_TC_HEAD_NAME(h_require_eq_msg_ ## id)
186edebbb8eSjmmv #define H_REQUIRE_EQ_MSG_BODY_NAME(id) \
187edebbb8eSjmmv     ATF_TC_BODY_NAME(h_require_eq_msg_ ## id)
188edebbb8eSjmmv #define H_REQUIRE_EQ_MSG(id, v1, v2, msg) \
189edebbb8eSjmmv     H_DEF(require_eq_msg_ ## id, ATF_REQUIRE_EQ_MSG(v1, v2, msg))
190edebbb8eSjmmv 
191edebbb8eSjmmv #define H_REQUIRE_STREQ_MSG_HEAD_NAME(id) \
192edebbb8eSjmmv     ATF_TC_HEAD_NAME(h_require_streq_msg_ ## id)
193edebbb8eSjmmv #define H_REQUIRE_STREQ_MSG_BODY_NAME(id) \
194edebbb8eSjmmv     ATF_TC_BODY_NAME(h_require_streq_msg_ ## id)
195edebbb8eSjmmv #define H_REQUIRE_STREQ_MSG(id, v1, v2, msg) \
196edebbb8eSjmmv     H_DEF(require_streq_msg_ ## id, ATF_REQUIRE_STREQ_MSG(v1, v2, msg))
197edebbb8eSjmmv 
198f153ecaeSjmmv #define H_REQUIRE_MATCH_MSG_HEAD_NAME(id) \
199f153ecaeSjmmv     ATF_TC_HEAD_NAME(h_require_match_msg_ ## id)
200f153ecaeSjmmv #define H_REQUIRE_MATCH_MSG_BODY_NAME(id) \
201f153ecaeSjmmv     ATF_TC_BODY_NAME(h_require_match_msg_ ## id)
202f153ecaeSjmmv #define H_REQUIRE_MATCH_MSG(id, v1, v2, msg) \
203f153ecaeSjmmv     H_DEF(require_match_msg_ ## id, ATF_REQUIRE_MATCH_MSG(v1, v2, msg))
204f153ecaeSjmmv 
205edebbb8eSjmmv #define H_REQUIRE_ERRNO_HEAD_NAME(id) ATF_TC_HEAD_NAME(h_require_errno_ ## id)
206edebbb8eSjmmv #define H_REQUIRE_ERRNO_BODY_NAME(id) ATF_TC_BODY_NAME(h_require_errno_ ## id)
207edebbb8eSjmmv #define H_REQUIRE_ERRNO(id, exp_errno, bool_expr) \
208edebbb8eSjmmv     H_DEF(require_errno_ ## id, ATF_REQUIRE_ERRNO(exp_errno, bool_expr))
209edebbb8eSjmmv 
210edebbb8eSjmmv /* ---------------------------------------------------------------------
211edebbb8eSjmmv  * Test cases for the ATF_{CHECK,REQUIRE}_ERRNO macros.
212edebbb8eSjmmv  * --------------------------------------------------------------------- */
213edebbb8eSjmmv 
214edebbb8eSjmmv static int
errno_fail_stub(const int raised_errno)215edebbb8eSjmmv errno_fail_stub(const int raised_errno)
216edebbb8eSjmmv {
217edebbb8eSjmmv     errno = raised_errno;
218edebbb8eSjmmv     return -1;
219edebbb8eSjmmv }
220edebbb8eSjmmv 
221edebbb8eSjmmv static int
errno_ok_stub(void)222edebbb8eSjmmv errno_ok_stub(void)
223edebbb8eSjmmv {
224edebbb8eSjmmv     return 0;
225edebbb8eSjmmv }
226edebbb8eSjmmv 
227edebbb8eSjmmv H_CHECK_ERRNO(no_error, -1, errno_ok_stub() == -1);
228edebbb8eSjmmv H_CHECK_ERRNO(errno_ok, 2, errno_fail_stub(2) == -1);
229edebbb8eSjmmv H_CHECK_ERRNO(errno_fail, 3, errno_fail_stub(4) == -1);
230edebbb8eSjmmv 
231edebbb8eSjmmv H_REQUIRE_ERRNO(no_error, -1, errno_ok_stub() == -1);
232edebbb8eSjmmv H_REQUIRE_ERRNO(errno_ok, 2, errno_fail_stub(2) == -1);
233edebbb8eSjmmv H_REQUIRE_ERRNO(errno_fail, 3, errno_fail_stub(4) == -1);
234edebbb8eSjmmv 
235edebbb8eSjmmv ATF_TC(check_errno);
ATF_TC_HEAD(check_errno,tc)236edebbb8eSjmmv ATF_TC_HEAD(check_errno, tc)
237edebbb8eSjmmv {
238edebbb8eSjmmv     atf_tc_set_md_var(tc, "descr", "Tests the ATF_CHECK_ERRNO macro");
239edebbb8eSjmmv }
ATF_TC_BODY(check_errno,tc)240edebbb8eSjmmv ATF_TC_BODY(check_errno, tc)
241edebbb8eSjmmv {
242edebbb8eSjmmv     struct test {
243edebbb8eSjmmv         void (*head)(atf_tc_t *);
244edebbb8eSjmmv         void (*body)(const atf_tc_t *);
245edebbb8eSjmmv         bool ok;
246edebbb8eSjmmv         const char *exp_regex;
247edebbb8eSjmmv     } *t, tests[] = {
248edebbb8eSjmmv         { H_CHECK_ERRNO_HEAD_NAME(no_error),
249edebbb8eSjmmv           H_CHECK_ERRNO_BODY_NAME(no_error),
250edebbb8eSjmmv           false, "Expected true value in errno_ok_stub\\(\\) == -1" },
251edebbb8eSjmmv         { H_CHECK_ERRNO_HEAD_NAME(errno_ok),
252edebbb8eSjmmv           H_CHECK_ERRNO_BODY_NAME(errno_ok),
253edebbb8eSjmmv           true, NULL },
254edebbb8eSjmmv         { H_CHECK_ERRNO_HEAD_NAME(errno_fail),
255edebbb8eSjmmv           H_CHECK_ERRNO_BODY_NAME(errno_fail),
256edebbb8eSjmmv           false, "Expected errno 3, got 4, in errno_fail_stub\\(4\\) == -1" },
257edebbb8eSjmmv         { NULL, NULL, false, NULL }
258edebbb8eSjmmv     };
259edebbb8eSjmmv 
260edebbb8eSjmmv     for (t = &tests[0]; t->head != NULL; t++) {
261edebbb8eSjmmv         init_and_run_h_tc("h_check_errno", t->head, t->body);
262edebbb8eSjmmv 
263edebbb8eSjmmv         ATF_REQUIRE(exists("before"));
264edebbb8eSjmmv         ATF_REQUIRE(exists("after"));
265edebbb8eSjmmv 
266edebbb8eSjmmv         if (t->ok) {
267f153ecaeSjmmv             ATF_REQUIRE(atf_utils_grep_file("^passed", "result"));
268edebbb8eSjmmv         } else {
269f153ecaeSjmmv             ATF_REQUIRE(atf_utils_grep_file("^failed", "result"));
270f153ecaeSjmmv             ATF_REQUIRE(atf_utils_grep_file(
271f153ecaeSjmmv                 "macros_test.c:[0-9]+: %s$", "error", t->exp_regex));
272edebbb8eSjmmv         }
273edebbb8eSjmmv 
274edebbb8eSjmmv         ATF_REQUIRE(unlink("before") != -1);
275edebbb8eSjmmv         ATF_REQUIRE(unlink("after") != -1);
276edebbb8eSjmmv     }
277edebbb8eSjmmv }
278edebbb8eSjmmv 
279edebbb8eSjmmv ATF_TC(require_errno);
ATF_TC_HEAD(require_errno,tc)280edebbb8eSjmmv ATF_TC_HEAD(require_errno, tc)
281edebbb8eSjmmv {
282edebbb8eSjmmv     atf_tc_set_md_var(tc, "descr", "Tests the ATF_REQUIRE_ERRNO macro");
283edebbb8eSjmmv }
ATF_TC_BODY(require_errno,tc)284edebbb8eSjmmv ATF_TC_BODY(require_errno, tc)
285edebbb8eSjmmv {
286edebbb8eSjmmv     struct test {
287edebbb8eSjmmv         void (*head)(atf_tc_t *);
288edebbb8eSjmmv         void (*body)(const atf_tc_t *);
289edebbb8eSjmmv         bool ok;
290edebbb8eSjmmv         const char *exp_regex;
291edebbb8eSjmmv     } *t, tests[] = {
292edebbb8eSjmmv         { H_REQUIRE_ERRNO_HEAD_NAME(no_error),
293edebbb8eSjmmv           H_REQUIRE_ERRNO_BODY_NAME(no_error),
294edebbb8eSjmmv           false, "Expected true value in errno_ok_stub\\(\\) == -1" },
295edebbb8eSjmmv         { H_REQUIRE_ERRNO_HEAD_NAME(errno_ok),
296edebbb8eSjmmv           H_REQUIRE_ERRNO_BODY_NAME(errno_ok),
297edebbb8eSjmmv           true, NULL },
298edebbb8eSjmmv         { H_REQUIRE_ERRNO_HEAD_NAME(errno_fail),
299edebbb8eSjmmv           H_REQUIRE_ERRNO_BODY_NAME(errno_fail),
300edebbb8eSjmmv           false, "Expected errno 3, got 4, in errno_fail_stub\\(4\\) == -1" },
301edebbb8eSjmmv         { NULL, NULL, false, NULL }
302edebbb8eSjmmv     };
303edebbb8eSjmmv 
304edebbb8eSjmmv     for (t = &tests[0]; t->head != NULL; t++) {
305edebbb8eSjmmv         init_and_run_h_tc("h_require_errno", t->head, t->body);
306edebbb8eSjmmv 
307edebbb8eSjmmv         ATF_REQUIRE(exists("before"));
308edebbb8eSjmmv         if (t->ok) {
309f153ecaeSjmmv             ATF_REQUIRE(atf_utils_grep_file("^passed", "result"));
310edebbb8eSjmmv             ATF_REQUIRE(exists("after"));
311edebbb8eSjmmv         } else {
312f153ecaeSjmmv             ATF_REQUIRE(atf_utils_grep_file(
313f153ecaeSjmmv                 "^failed: .*macros_test.c:[0-9]+: %s$", "result",
314f153ecaeSjmmv                 t->exp_regex));
315edebbb8eSjmmv             ATF_REQUIRE(!exists("after"));
316edebbb8eSjmmv         }
317edebbb8eSjmmv 
318edebbb8eSjmmv         ATF_REQUIRE(unlink("before") != -1);
319edebbb8eSjmmv         if (t->ok)
320edebbb8eSjmmv             ATF_REQUIRE(unlink("after") != -1);
321edebbb8eSjmmv     }
322edebbb8eSjmmv }
323edebbb8eSjmmv 
324edebbb8eSjmmv /* ---------------------------------------------------------------------
325edebbb8eSjmmv  * Test cases for the ATF_CHECK and ATF_CHECK_MSG macros.
326edebbb8eSjmmv  * --------------------------------------------------------------------- */
327edebbb8eSjmmv 
328edebbb8eSjmmv H_CHECK(0, 0);
329edebbb8eSjmmv H_CHECK(1, 1);
330edebbb8eSjmmv H_CHECK_MSG(0, 0, "expected a false value");
331edebbb8eSjmmv H_CHECK_MSG(1, 1, "expected a true value");
332edebbb8eSjmmv 
333edebbb8eSjmmv ATF_TC(check);
ATF_TC_HEAD(check,tc)334edebbb8eSjmmv ATF_TC_HEAD(check, tc)
335edebbb8eSjmmv {
336edebbb8eSjmmv     atf_tc_set_md_var(tc, "descr", "Tests the ATF_CHECK and "
337edebbb8eSjmmv                       "ATF_CHECK_MSG macros");
338edebbb8eSjmmv }
ATF_TC_BODY(check,tc)339edebbb8eSjmmv ATF_TC_BODY(check, tc)
340edebbb8eSjmmv {
341edebbb8eSjmmv     struct test {
342edebbb8eSjmmv         void (*head)(atf_tc_t *);
343edebbb8eSjmmv         void (*body)(const atf_tc_t *);
344edebbb8eSjmmv         bool value;
345edebbb8eSjmmv         const char *msg;
346edebbb8eSjmmv         bool ok;
347edebbb8eSjmmv     } *t, tests[] = {
348edebbb8eSjmmv         { H_CHECK_HEAD_NAME(0), H_CHECK_BODY_NAME(0), 0,
349edebbb8eSjmmv           "0 not met", false },
350edebbb8eSjmmv         { H_CHECK_HEAD_NAME(1), H_CHECK_BODY_NAME(1), 1,
351edebbb8eSjmmv           "1 not met", true },
352edebbb8eSjmmv         { H_CHECK_MSG_HEAD_NAME(0), H_CHECK_MSG_BODY_NAME(0), 0,
353edebbb8eSjmmv           "expected a false value", false },
354edebbb8eSjmmv         { H_CHECK_MSG_HEAD_NAME(1), H_CHECK_MSG_BODY_NAME(1), 1,
355edebbb8eSjmmv           "expected a true value", true },
356edebbb8eSjmmv         { NULL, NULL, false, NULL, false }
357edebbb8eSjmmv     };
358edebbb8eSjmmv 
359edebbb8eSjmmv     for (t = &tests[0]; t->head != NULL; t++) {
360edebbb8eSjmmv         printf("Checking with a %d value\n", t->value);
361edebbb8eSjmmv 
362edebbb8eSjmmv         init_and_run_h_tc("h_check", t->head, t->body);
363edebbb8eSjmmv 
364edebbb8eSjmmv         ATF_REQUIRE(exists("before"));
365edebbb8eSjmmv         ATF_REQUIRE(exists("after"));
366edebbb8eSjmmv 
367edebbb8eSjmmv         if (t->ok) {
368f153ecaeSjmmv             ATF_REQUIRE(atf_utils_grep_file("^passed", "result"));
369edebbb8eSjmmv         } else {
370f153ecaeSjmmv             ATF_REQUIRE(atf_utils_grep_file("^failed", "result"));
371f153ecaeSjmmv             ATF_REQUIRE(atf_utils_grep_file("Check failed: .*"
372f153ecaeSjmmv                 "macros_test.c:[0-9]+: %s$", "error", t->msg));
373edebbb8eSjmmv         }
374edebbb8eSjmmv 
375edebbb8eSjmmv         ATF_REQUIRE(unlink("before") != -1);
376edebbb8eSjmmv         ATF_REQUIRE(unlink("after") != -1);
377edebbb8eSjmmv     }
378edebbb8eSjmmv }
379edebbb8eSjmmv 
380edebbb8eSjmmv /* ---------------------------------------------------------------------
381edebbb8eSjmmv  * Test cases for the ATF_CHECK_*EQ_ macros.
382edebbb8eSjmmv  * --------------------------------------------------------------------- */
383edebbb8eSjmmv 
384edebbb8eSjmmv struct check_eq_test {
385edebbb8eSjmmv     void (*head)(atf_tc_t *);
386edebbb8eSjmmv     void (*body)(const atf_tc_t *);
387edebbb8eSjmmv     const char *v1;
388edebbb8eSjmmv     const char *v2;
389edebbb8eSjmmv     const char *msg;
390edebbb8eSjmmv     bool ok;
391edebbb8eSjmmv };
392edebbb8eSjmmv 
393edebbb8eSjmmv static
394edebbb8eSjmmv void
do_check_eq_tests(const struct check_eq_test * tests)395edebbb8eSjmmv do_check_eq_tests(const struct check_eq_test *tests)
396edebbb8eSjmmv {
397edebbb8eSjmmv     const struct check_eq_test *t;
398edebbb8eSjmmv 
399edebbb8eSjmmv     for (t = &tests[0]; t->head != NULL; t++) {
400edebbb8eSjmmv         printf("Checking with %s, %s and expecting %s\n", t->v1, t->v2,
401edebbb8eSjmmv                t->ok ? "true" : "false");
402edebbb8eSjmmv 
403edebbb8eSjmmv         init_and_run_h_tc("h_check", t->head, t->body);
404edebbb8eSjmmv 
405edebbb8eSjmmv         ATF_CHECK(exists("before"));
406edebbb8eSjmmv         ATF_CHECK(exists("after"));
407edebbb8eSjmmv 
408edebbb8eSjmmv         if (t->ok) {
409f153ecaeSjmmv             ATF_REQUIRE(atf_utils_grep_file("^passed", "result"));
410edebbb8eSjmmv         } else {
411f153ecaeSjmmv             ATF_REQUIRE(atf_utils_grep_file("^failed", "result"));
412f153ecaeSjmmv             ATF_CHECK(atf_utils_grep_file("Check failed: .*"
413f153ecaeSjmmv                 "macros_test.c:[0-9]+: %s$", "error", t->msg));
414edebbb8eSjmmv         }
415edebbb8eSjmmv 
416edebbb8eSjmmv         ATF_CHECK(unlink("before") != -1);
417edebbb8eSjmmv         ATF_CHECK(unlink("after") != -1);
418edebbb8eSjmmv     }
419edebbb8eSjmmv }
420edebbb8eSjmmv 
421edebbb8eSjmmv H_CHECK_EQ(1_1, 1, 1);
422edebbb8eSjmmv H_CHECK_EQ(1_2, 1, 2);
423edebbb8eSjmmv H_CHECK_EQ(2_1, 2, 1);
424edebbb8eSjmmv H_CHECK_EQ(2_2, 2, 2);
425edebbb8eSjmmv H_CHECK_EQ_MSG(1_1, 1, 1, "1 does not match 1");
426edebbb8eSjmmv H_CHECK_EQ_MSG(1_2, 1, 2, "1 does not match 2");
427edebbb8eSjmmv H_CHECK_EQ_MSG(2_1, 2, 1, "2 does not match 1");
428edebbb8eSjmmv H_CHECK_EQ_MSG(2_2, 2, 2, "2 does not match 2");
429edebbb8eSjmmv 
430edebbb8eSjmmv ATF_TC(check_eq);
ATF_TC_HEAD(check_eq,tc)431edebbb8eSjmmv ATF_TC_HEAD(check_eq, tc)
432edebbb8eSjmmv {
433edebbb8eSjmmv     atf_tc_set_md_var(tc, "descr", "Tests the ATF_CHECK_EQ and "
434edebbb8eSjmmv                       "ATF_CHECK_EQ_MSG macros");
435edebbb8eSjmmv }
ATF_TC_BODY(check_eq,tc)436edebbb8eSjmmv ATF_TC_BODY(check_eq, tc)
437edebbb8eSjmmv {
438edebbb8eSjmmv     struct check_eq_test tests[] = {
439edebbb8eSjmmv         { H_CHECK_EQ_HEAD_NAME(1_1), H_CHECK_EQ_BODY_NAME(1_1),
440edebbb8eSjmmv           "1", "1", "1 != 1", true },
441edebbb8eSjmmv         { H_CHECK_EQ_HEAD_NAME(1_2), H_CHECK_EQ_BODY_NAME(1_2),
442edebbb8eSjmmv           "1", "2", "1 != 2", false },
443edebbb8eSjmmv         { H_CHECK_EQ_HEAD_NAME(2_1), H_CHECK_EQ_BODY_NAME(2_1),
444edebbb8eSjmmv           "2", "1", "2 != 1", false },
445edebbb8eSjmmv         { H_CHECK_EQ_HEAD_NAME(2_2), H_CHECK_EQ_BODY_NAME(2_2),
446edebbb8eSjmmv           "2", "2", "2 != 2", true },
447edebbb8eSjmmv         { H_CHECK_EQ_MSG_HEAD_NAME(1_1), H_CHECK_EQ_MSG_BODY_NAME(1_1),
448edebbb8eSjmmv           "1", "1", "1 != 1: 1 does not match 1", true },
449edebbb8eSjmmv         { H_CHECK_EQ_MSG_HEAD_NAME(1_2), H_CHECK_EQ_MSG_BODY_NAME(1_2),
450edebbb8eSjmmv           "1", "2", "1 != 2: 1 does not match 2", false },
451edebbb8eSjmmv         { H_CHECK_EQ_MSG_HEAD_NAME(2_1), H_CHECK_EQ_MSG_BODY_NAME(2_1),
452edebbb8eSjmmv           "2", "1", "2 != 1: 2 does not match 1", false },
453edebbb8eSjmmv         { H_CHECK_EQ_MSG_HEAD_NAME(2_2), H_CHECK_EQ_MSG_BODY_NAME(2_2),
454edebbb8eSjmmv           "2", "2", "2 != 2: 2 does not match 2", true },
455edebbb8eSjmmv         { NULL, NULL, 0, 0, "", false }
456edebbb8eSjmmv     };
457edebbb8eSjmmv     do_check_eq_tests(tests);
458edebbb8eSjmmv }
459edebbb8eSjmmv 
460edebbb8eSjmmv H_CHECK_STREQ(1_1, "1", "1");
461edebbb8eSjmmv H_CHECK_STREQ(1_2, "1", "2");
462edebbb8eSjmmv H_CHECK_STREQ(2_1, "2", "1");
463edebbb8eSjmmv H_CHECK_STREQ(2_2, "2", "2");
464edebbb8eSjmmv H_CHECK_STREQ_MSG(1_1, "1", "1", "1 does not match 1");
465edebbb8eSjmmv H_CHECK_STREQ_MSG(1_2, "1", "2", "1 does not match 2");
466edebbb8eSjmmv H_CHECK_STREQ_MSG(2_1, "2", "1", "2 does not match 1");
467edebbb8eSjmmv H_CHECK_STREQ_MSG(2_2, "2", "2", "2 does not match 2");
468edebbb8eSjmmv #define CHECK_STREQ_VAR1 "5"
469edebbb8eSjmmv #define CHECK_STREQ_VAR2 "9"
470f153ecaeSjmmv const char *check_streq_var1 = CHECK_STREQ_VAR1;
471f153ecaeSjmmv const char *check_streq_var2 = CHECK_STREQ_VAR2;
472edebbb8eSjmmv H_CHECK_STREQ(vars, check_streq_var1, check_streq_var2);
473edebbb8eSjmmv 
474edebbb8eSjmmv ATF_TC(check_streq);
ATF_TC_HEAD(check_streq,tc)475edebbb8eSjmmv ATF_TC_HEAD(check_streq, tc)
476edebbb8eSjmmv {
477edebbb8eSjmmv     atf_tc_set_md_var(tc, "descr", "Tests the ATF_CHECK_STREQ and "
478edebbb8eSjmmv                       "ATF_CHECK_STREQ_MSG macros");
479edebbb8eSjmmv }
ATF_TC_BODY(check_streq,tc)480edebbb8eSjmmv ATF_TC_BODY(check_streq, tc)
481edebbb8eSjmmv {
482edebbb8eSjmmv     struct check_eq_test tests[] = {
483edebbb8eSjmmv         { H_CHECK_STREQ_HEAD_NAME(1_1), H_CHECK_STREQ_BODY_NAME(1_1),
484edebbb8eSjmmv           "1", "1", "\"1\" != \"1\" \\(1 != 1\\)", true },
485edebbb8eSjmmv         { H_CHECK_STREQ_HEAD_NAME(1_2), H_CHECK_STREQ_BODY_NAME(1_2),
486edebbb8eSjmmv           "1", "2", "\"1\" != \"2\" \\(1 != 2\\)", false },
487edebbb8eSjmmv         { H_CHECK_STREQ_HEAD_NAME(2_1), H_CHECK_STREQ_BODY_NAME(2_1),
488edebbb8eSjmmv           "2", "1", "\"2\" != \"1\" \\(2 != 1\\)", false },
489edebbb8eSjmmv         { H_CHECK_STREQ_HEAD_NAME(2_2), H_CHECK_STREQ_BODY_NAME(2_2),
490edebbb8eSjmmv           "2", "2", "\"2\" != \"2\" \\(2 != 2\\)", true },
491edebbb8eSjmmv         { H_CHECK_STREQ_MSG_HEAD_NAME(1_1),
492edebbb8eSjmmv           H_CHECK_STREQ_MSG_BODY_NAME(1_1),
493edebbb8eSjmmv           "1", "1", "\"1\" != \"1\" \\(1 != 1\\): 1 does not match 1", true },
494edebbb8eSjmmv         { H_CHECK_STREQ_MSG_HEAD_NAME(1_2),
495edebbb8eSjmmv           H_CHECK_STREQ_MSG_BODY_NAME(1_2),
496edebbb8eSjmmv           "1", "2", "\"1\" != \"2\" \\(1 != 2\\): 1 does not match 2", false },
497edebbb8eSjmmv         { H_CHECK_STREQ_MSG_HEAD_NAME(2_1),
498edebbb8eSjmmv           H_CHECK_STREQ_MSG_BODY_NAME(2_1),
499edebbb8eSjmmv           "2", "1", "\"2\" != \"1\" \\(2 != 1\\): 2 does not match 1", false },
500edebbb8eSjmmv         { H_CHECK_STREQ_MSG_HEAD_NAME(2_2),
501edebbb8eSjmmv           H_CHECK_STREQ_MSG_BODY_NAME(2_2),
502edebbb8eSjmmv           "2", "2", "\"2\" != \"2\" \\(2 != 2\\): 2 does not match 2", true },
503edebbb8eSjmmv         { H_CHECK_STREQ_HEAD_NAME(vars), H_CHECK_STREQ_BODY_NAME(vars),
504edebbb8eSjmmv           check_streq_var1, check_streq_var2,
505edebbb8eSjmmv           "check_streq_var1 != check_streq_var2 \\("
506edebbb8eSjmmv           CHECK_STREQ_VAR1 " != " CHECK_STREQ_VAR2 "\\)", false },
507edebbb8eSjmmv         { NULL, NULL, 0, 0, "", false }
508edebbb8eSjmmv     };
509edebbb8eSjmmv     do_check_eq_tests(tests);
510edebbb8eSjmmv }
511edebbb8eSjmmv 
512edebbb8eSjmmv /* ---------------------------------------------------------------------
513f153ecaeSjmmv  * Test cases for the ATF_CHECK_MATCH and ATF_CHECK_MATCH_MSG macros.
514f153ecaeSjmmv  * --------------------------------------------------------------------- */
515f153ecaeSjmmv 
516f153ecaeSjmmv H_CHECK_MATCH(yes, "hello [a-z]+", "abc hello world");
517f153ecaeSjmmv H_CHECK_MATCH(no, "hello [a-z]+", "abc hello WORLD");
518f153ecaeSjmmv H_CHECK_MATCH_MSG(yes, "hello [a-z]+", "abc hello world", "lowercase");
519f153ecaeSjmmv H_CHECK_MATCH_MSG(no, "hello [a-z]+", "abc hello WORLD", "uppercase");
520f153ecaeSjmmv 
521f153ecaeSjmmv ATF_TC(check_match);
ATF_TC_HEAD(check_match,tc)522f153ecaeSjmmv ATF_TC_HEAD(check_match, tc)
523f153ecaeSjmmv {
524f153ecaeSjmmv     atf_tc_set_md_var(tc, "descr", "Tests the ATF_CHECK_MATCH and "
525f153ecaeSjmmv                       "ATF_CHECK_MATCH_MSG macros");
526f153ecaeSjmmv }
ATF_TC_BODY(check_match,tc)527f153ecaeSjmmv ATF_TC_BODY(check_match, tc)
528f153ecaeSjmmv {
529f153ecaeSjmmv     struct check_eq_test tests[] = {
530f153ecaeSjmmv         { H_CHECK_MATCH_HEAD_NAME(yes), H_CHECK_MATCH_BODY_NAME(yes),
531f153ecaeSjmmv           "hello [a-z]+", "abc hello world", "", true },
532f153ecaeSjmmv         { H_CHECK_MATCH_HEAD_NAME(no), H_CHECK_MATCH_BODY_NAME(no),
533f153ecaeSjmmv           "hello [a-z]+", "abc hello WORLD",
534f153ecaeSjmmv           "'hello \\[a-z\\]\\+' not matched in 'abc hello WORLD'", false },
535f153ecaeSjmmv         { H_CHECK_MATCH_MSG_HEAD_NAME(yes), H_CHECK_MATCH_MSG_BODY_NAME(yes),
536f153ecaeSjmmv           "hello [a-z]+", "abc hello world", "", true },
537f153ecaeSjmmv         { H_CHECK_MATCH_MSG_HEAD_NAME(no), H_CHECK_MATCH_MSG_BODY_NAME(no),
538f153ecaeSjmmv           "hello [a-z]+", "abc hello WORLD",
539f153ecaeSjmmv           "'hello \\[a-z\\]\\+' not matched in 'abc hello WORLD': uppercase",
540f153ecaeSjmmv           false },
541f153ecaeSjmmv         { NULL, NULL, 0, 0, "", false }
542f153ecaeSjmmv     };
543f153ecaeSjmmv     do_check_eq_tests(tests);
544f153ecaeSjmmv }
545f153ecaeSjmmv 
546f153ecaeSjmmv /* ---------------------------------------------------------------------
547edebbb8eSjmmv  * Test cases for the ATF_REQUIRE and ATF_REQUIRE_MSG macros.
548edebbb8eSjmmv  * --------------------------------------------------------------------- */
549edebbb8eSjmmv 
550edebbb8eSjmmv H_REQUIRE(0, 0);
551edebbb8eSjmmv H_REQUIRE(1, 1);
552edebbb8eSjmmv H_REQUIRE_MSG(0, 0, "expected a false value");
553edebbb8eSjmmv H_REQUIRE_MSG(1, 1, "expected a true value");
554edebbb8eSjmmv 
555edebbb8eSjmmv ATF_TC(require);
ATF_TC_HEAD(require,tc)556edebbb8eSjmmv ATF_TC_HEAD(require, tc)
557edebbb8eSjmmv {
558edebbb8eSjmmv     atf_tc_set_md_var(tc, "descr", "Tests the ATF_REQUIRE and "
559edebbb8eSjmmv                       "ATF_REQUIRE_MSG macros");
560edebbb8eSjmmv }
ATF_TC_BODY(require,tc)561edebbb8eSjmmv ATF_TC_BODY(require, tc)
562edebbb8eSjmmv {
563edebbb8eSjmmv     struct test {
564edebbb8eSjmmv         void (*head)(atf_tc_t *);
565edebbb8eSjmmv         void (*body)(const atf_tc_t *);
566edebbb8eSjmmv         bool value;
567edebbb8eSjmmv         const char *msg;
568edebbb8eSjmmv         bool ok;
569edebbb8eSjmmv     } *t, tests[] = {
570edebbb8eSjmmv         { H_REQUIRE_HEAD_NAME(0), H_REQUIRE_BODY_NAME(0), 0,
571edebbb8eSjmmv           "0 not met", false },
572edebbb8eSjmmv         { H_REQUIRE_HEAD_NAME(1), H_REQUIRE_BODY_NAME(1), 1,
573edebbb8eSjmmv           "1 not met", true },
574edebbb8eSjmmv         { H_REQUIRE_MSG_HEAD_NAME(0), H_REQUIRE_MSG_BODY_NAME(0), 0,
575edebbb8eSjmmv           "expected a false value", false },
576edebbb8eSjmmv         { H_REQUIRE_MSG_HEAD_NAME(1), H_REQUIRE_MSG_BODY_NAME(1), 1,
577edebbb8eSjmmv           "expected a true value", true },
578edebbb8eSjmmv         { NULL, NULL, false, NULL, false }
579edebbb8eSjmmv     };
580edebbb8eSjmmv 
581edebbb8eSjmmv     for (t = &tests[0]; t->head != NULL; t++) {
582edebbb8eSjmmv         printf("Checking with a %d value\n", t->value);
583edebbb8eSjmmv 
584edebbb8eSjmmv         init_and_run_h_tc("h_require", t->head, t->body);
585edebbb8eSjmmv 
586edebbb8eSjmmv         ATF_REQUIRE(exists("before"));
587edebbb8eSjmmv         if (t->ok) {
588f153ecaeSjmmv             ATF_REQUIRE(atf_utils_grep_file("^passed", "result"));
589edebbb8eSjmmv             ATF_REQUIRE(exists("after"));
590edebbb8eSjmmv         } else {
591f153ecaeSjmmv             ATF_REQUIRE(atf_utils_grep_file(
592f153ecaeSjmmv                 "^failed: .*macros_test.c:[0-9]+: %s$", "result", t->msg));
593edebbb8eSjmmv             ATF_REQUIRE(!exists("after"));
594edebbb8eSjmmv         }
595edebbb8eSjmmv 
596edebbb8eSjmmv         ATF_REQUIRE(unlink("before") != -1);
597edebbb8eSjmmv         if (t->ok)
598edebbb8eSjmmv             ATF_REQUIRE(unlink("after") != -1);
599edebbb8eSjmmv     }
600edebbb8eSjmmv }
601edebbb8eSjmmv 
602edebbb8eSjmmv /* ---------------------------------------------------------------------
603edebbb8eSjmmv  * Test cases for the ATF_REQUIRE_*EQ_ macros.
604edebbb8eSjmmv  * --------------------------------------------------------------------- */
605edebbb8eSjmmv 
606edebbb8eSjmmv struct require_eq_test {
607edebbb8eSjmmv     void (*head)(atf_tc_t *);
608edebbb8eSjmmv     void (*body)(const atf_tc_t *);
609edebbb8eSjmmv     const char *v1;
610edebbb8eSjmmv     const char *v2;
611edebbb8eSjmmv     const char *msg;
612edebbb8eSjmmv     bool ok;
613edebbb8eSjmmv };
614edebbb8eSjmmv 
615edebbb8eSjmmv static
616edebbb8eSjmmv void
do_require_eq_tests(const struct require_eq_test * tests)617edebbb8eSjmmv do_require_eq_tests(const struct require_eq_test *tests)
618edebbb8eSjmmv {
619edebbb8eSjmmv     const struct require_eq_test *t;
620edebbb8eSjmmv 
621edebbb8eSjmmv     for (t = &tests[0]; t->head != NULL; t++) {
622edebbb8eSjmmv         printf("Checking with %s, %s and expecting %s\n", t->v1, t->v2,
623edebbb8eSjmmv                t->ok ? "true" : "false");
624edebbb8eSjmmv 
625edebbb8eSjmmv         init_and_run_h_tc("h_require", t->head, t->body);
626edebbb8eSjmmv 
627edebbb8eSjmmv         ATF_REQUIRE(exists("before"));
628edebbb8eSjmmv         if (t->ok) {
629f153ecaeSjmmv             ATF_REQUIRE(atf_utils_grep_file("^passed", "result"));
630edebbb8eSjmmv             ATF_REQUIRE(exists("after"));
631edebbb8eSjmmv         } else {
632f153ecaeSjmmv             ATF_REQUIRE(atf_utils_grep_file("^failed: .*macros_test.c"
633f153ecaeSjmmv                 ":[0-9]+: %s$", "result", t->msg));
634edebbb8eSjmmv             ATF_REQUIRE(!exists("after"));
635edebbb8eSjmmv         }
636edebbb8eSjmmv 
637edebbb8eSjmmv         ATF_REQUIRE(unlink("before") != -1);
638edebbb8eSjmmv         if (t->ok)
639edebbb8eSjmmv             ATF_REQUIRE(unlink("after") != -1);
640edebbb8eSjmmv     }
641edebbb8eSjmmv }
642edebbb8eSjmmv 
643edebbb8eSjmmv H_REQUIRE_EQ(1_1, 1, 1);
644edebbb8eSjmmv H_REQUIRE_EQ(1_2, 1, 2);
645edebbb8eSjmmv H_REQUIRE_EQ(2_1, 2, 1);
646edebbb8eSjmmv H_REQUIRE_EQ(2_2, 2, 2);
647edebbb8eSjmmv H_REQUIRE_EQ_MSG(1_1, 1, 1, "1 does not match 1");
648edebbb8eSjmmv H_REQUIRE_EQ_MSG(1_2, 1, 2, "1 does not match 2");
649edebbb8eSjmmv H_REQUIRE_EQ_MSG(2_1, 2, 1, "2 does not match 1");
650edebbb8eSjmmv H_REQUIRE_EQ_MSG(2_2, 2, 2, "2 does not match 2");
651edebbb8eSjmmv 
652edebbb8eSjmmv ATF_TC(require_eq);
ATF_TC_HEAD(require_eq,tc)653edebbb8eSjmmv ATF_TC_HEAD(require_eq, tc)
654edebbb8eSjmmv {
655edebbb8eSjmmv     atf_tc_set_md_var(tc, "descr", "Tests the ATF_REQUIRE_EQ and "
656edebbb8eSjmmv                       "ATF_REQUIRE_EQ_MSG macros");
657edebbb8eSjmmv }
ATF_TC_BODY(require_eq,tc)658edebbb8eSjmmv ATF_TC_BODY(require_eq, tc)
659edebbb8eSjmmv {
660edebbb8eSjmmv     struct require_eq_test tests[] = {
661edebbb8eSjmmv         { H_REQUIRE_EQ_HEAD_NAME(1_1), H_REQUIRE_EQ_BODY_NAME(1_1),
662edebbb8eSjmmv           "1", "1", "1 != 1", true },
663edebbb8eSjmmv         { H_REQUIRE_EQ_HEAD_NAME(1_2), H_REQUIRE_EQ_BODY_NAME(1_2),
664edebbb8eSjmmv           "1", "2", "1 != 2", false },
665edebbb8eSjmmv         { H_REQUIRE_EQ_HEAD_NAME(2_1), H_REQUIRE_EQ_BODY_NAME(2_1),
666edebbb8eSjmmv           "2", "1", "2 != 1", false },
667edebbb8eSjmmv         { H_REQUIRE_EQ_HEAD_NAME(2_2), H_REQUIRE_EQ_BODY_NAME(2_2),
668edebbb8eSjmmv           "2", "2", "2 != 2", true },
669edebbb8eSjmmv         { H_REQUIRE_EQ_MSG_HEAD_NAME(1_1), H_REQUIRE_EQ_MSG_BODY_NAME(1_1),
670edebbb8eSjmmv           "1", "1", "1 != 1: 1 does not match 1", true },
671edebbb8eSjmmv         { H_REQUIRE_EQ_MSG_HEAD_NAME(1_2), H_REQUIRE_EQ_MSG_BODY_NAME(1_2),
672edebbb8eSjmmv           "1", "2", "1 != 2: 1 does not match 2", false },
673edebbb8eSjmmv         { H_REQUIRE_EQ_MSG_HEAD_NAME(2_1), H_REQUIRE_EQ_MSG_BODY_NAME(2_1),
674edebbb8eSjmmv           "2", "1", "2 != 1: 2 does not match 1", false },
675edebbb8eSjmmv         { H_REQUIRE_EQ_MSG_HEAD_NAME(2_2), H_REQUIRE_EQ_MSG_BODY_NAME(2_2),
676edebbb8eSjmmv           "2", "2", "2 != 2: 2 does not match 2", true },
677edebbb8eSjmmv         { NULL, NULL, 0, 0, "", false }
678edebbb8eSjmmv     };
679edebbb8eSjmmv     do_require_eq_tests(tests);
680edebbb8eSjmmv }
681edebbb8eSjmmv 
682edebbb8eSjmmv H_REQUIRE_STREQ(1_1, "1", "1");
683edebbb8eSjmmv H_REQUIRE_STREQ(1_2, "1", "2");
684edebbb8eSjmmv H_REQUIRE_STREQ(2_1, "2", "1");
685edebbb8eSjmmv H_REQUIRE_STREQ(2_2, "2", "2");
686edebbb8eSjmmv H_REQUIRE_STREQ_MSG(1_1, "1", "1", "1 does not match 1");
687edebbb8eSjmmv H_REQUIRE_STREQ_MSG(1_2, "1", "2", "1 does not match 2");
688edebbb8eSjmmv H_REQUIRE_STREQ_MSG(2_1, "2", "1", "2 does not match 1");
689edebbb8eSjmmv H_REQUIRE_STREQ_MSG(2_2, "2", "2", "2 does not match 2");
690edebbb8eSjmmv #define REQUIRE_STREQ_VAR1 "5"
691edebbb8eSjmmv #define REQUIRE_STREQ_VAR2 "9"
692f153ecaeSjmmv const char *require_streq_var1 = REQUIRE_STREQ_VAR1;
693f153ecaeSjmmv const char *require_streq_var2 = REQUIRE_STREQ_VAR2;
694edebbb8eSjmmv H_REQUIRE_STREQ(vars, require_streq_var1, require_streq_var2);
695edebbb8eSjmmv 
696edebbb8eSjmmv ATF_TC(require_streq);
ATF_TC_HEAD(require_streq,tc)697edebbb8eSjmmv ATF_TC_HEAD(require_streq, tc)
698edebbb8eSjmmv {
699edebbb8eSjmmv     atf_tc_set_md_var(tc, "descr", "Tests the ATF_REQUIRE_STREQ and "
700edebbb8eSjmmv                       "ATF_REQUIRE_STREQ_MSG macros");
701edebbb8eSjmmv }
ATF_TC_BODY(require_streq,tc)702edebbb8eSjmmv ATF_TC_BODY(require_streq, tc)
703edebbb8eSjmmv {
704edebbb8eSjmmv     struct require_eq_test tests[] = {
705edebbb8eSjmmv         { H_REQUIRE_STREQ_HEAD_NAME(1_1), H_REQUIRE_STREQ_BODY_NAME(1_1),
706edebbb8eSjmmv           "1", "1", "\"1\" != \"1\" \\(1 != 1\\)", true },
707edebbb8eSjmmv         { H_REQUIRE_STREQ_HEAD_NAME(1_2), H_REQUIRE_STREQ_BODY_NAME(1_2),
708edebbb8eSjmmv           "1", "2", "\"1\" != \"2\" \\(1 != 2\\)", false },
709edebbb8eSjmmv         { H_REQUIRE_STREQ_HEAD_NAME(2_1), H_REQUIRE_STREQ_BODY_NAME(2_1),
710edebbb8eSjmmv           "2", "1", "\"2\" != \"1\" \\(2 != 1\\)", false },
711edebbb8eSjmmv         { H_REQUIRE_STREQ_HEAD_NAME(2_2), H_REQUIRE_STREQ_BODY_NAME(2_2),
712edebbb8eSjmmv           "2", "2", "\"2\" != \"2\" \\(2 != 2\\)", true },
713edebbb8eSjmmv         { H_REQUIRE_STREQ_MSG_HEAD_NAME(1_1),
714edebbb8eSjmmv           H_REQUIRE_STREQ_MSG_BODY_NAME(1_1),
715edebbb8eSjmmv           "1", "1", "\"1\" != \"1\" \\(1 != 1\\): 1 does not match 1", true },
716edebbb8eSjmmv         { H_REQUIRE_STREQ_MSG_HEAD_NAME(1_2),
717edebbb8eSjmmv           H_REQUIRE_STREQ_MSG_BODY_NAME(1_2),
718edebbb8eSjmmv           "1", "2", "\"1\" != \"2\" \\(1 != 2\\): 1 does not match 2", false },
719edebbb8eSjmmv         { H_REQUIRE_STREQ_MSG_HEAD_NAME(2_1),
720edebbb8eSjmmv           H_REQUIRE_STREQ_MSG_BODY_NAME(2_1),
721edebbb8eSjmmv           "2", "1", "\"2\" != \"1\" \\(2 != 1\\): 2 does not match 1", false },
722edebbb8eSjmmv         { H_REQUIRE_STREQ_MSG_HEAD_NAME(2_2),
723edebbb8eSjmmv           H_REQUIRE_STREQ_MSG_BODY_NAME(2_2),
724edebbb8eSjmmv           "2", "2", "\"2\" != \"2\" \\(2 != 2\\): 2 does not match 2", true },
725edebbb8eSjmmv         { H_REQUIRE_STREQ_HEAD_NAME(vars), H_REQUIRE_STREQ_BODY_NAME(vars),
726edebbb8eSjmmv           require_streq_var1, require_streq_var2,
727edebbb8eSjmmv           "require_streq_var1 != require_streq_var2 \\("
728edebbb8eSjmmv           REQUIRE_STREQ_VAR1 " != " REQUIRE_STREQ_VAR2 "\\)", false },
729edebbb8eSjmmv         { NULL, NULL, 0, 0, "", false }
730edebbb8eSjmmv     };
731edebbb8eSjmmv     do_require_eq_tests(tests);
732edebbb8eSjmmv }
733edebbb8eSjmmv 
734edebbb8eSjmmv /* ---------------------------------------------------------------------
735f153ecaeSjmmv  * Test cases for the ATF_REQUIRE_MATCH and ATF_REQUIRE_MATCH_MSG macros.
736f153ecaeSjmmv  * --------------------------------------------------------------------- */
737f153ecaeSjmmv 
738f153ecaeSjmmv H_REQUIRE_MATCH(yes, "hello [a-z]+", "abc hello world");
739f153ecaeSjmmv H_REQUIRE_MATCH(no, "hello [a-z]+", "abc hello WORLD");
740f153ecaeSjmmv H_REQUIRE_MATCH_MSG(yes, "hello [a-z]+", "abc hello world", "lowercase");
741f153ecaeSjmmv H_REQUIRE_MATCH_MSG(no, "hello [a-z]+", "abc hello WORLD", "uppercase");
742f153ecaeSjmmv 
743f153ecaeSjmmv ATF_TC(require_match);
ATF_TC_HEAD(require_match,tc)744f153ecaeSjmmv ATF_TC_HEAD(require_match, tc)
745f153ecaeSjmmv {
746f153ecaeSjmmv     atf_tc_set_md_var(tc, "descr", "Tests the ATF_REQUIRE_MATCH and "
747f153ecaeSjmmv                       "ATF_REQUIRE_MATCH_MSG macros");
748f153ecaeSjmmv }
ATF_TC_BODY(require_match,tc)749f153ecaeSjmmv ATF_TC_BODY(require_match, tc)
750f153ecaeSjmmv {
751f153ecaeSjmmv     struct require_eq_test tests[] = {
752f153ecaeSjmmv         { H_REQUIRE_MATCH_HEAD_NAME(yes), H_REQUIRE_MATCH_BODY_NAME(yes),
753f153ecaeSjmmv           "hello [a-z]+", "abc hello world", "", true },
754f153ecaeSjmmv         { H_REQUIRE_MATCH_HEAD_NAME(no), H_REQUIRE_MATCH_BODY_NAME(no),
755f153ecaeSjmmv           "hello [a-z]+", "abc hello WORLD",
756f153ecaeSjmmv           "'hello \\[a-z\\]\\+' not matched in 'abc hello WORLD'", false },
757f153ecaeSjmmv         { H_REQUIRE_MATCH_MSG_HEAD_NAME(yes),
758f153ecaeSjmmv           H_REQUIRE_MATCH_MSG_BODY_NAME(yes),
759f153ecaeSjmmv           "hello [a-z]+", "abc hello world", "", true },
760f153ecaeSjmmv         { H_REQUIRE_MATCH_MSG_HEAD_NAME(no), H_REQUIRE_MATCH_MSG_BODY_NAME(no),
761f153ecaeSjmmv           "hello [a-z]+", "abc hello WORLD",
762f153ecaeSjmmv           "'hello \\[a-z\\]\\+' not matched in 'abc hello WORLD': uppercase",
763f153ecaeSjmmv           false },
764f153ecaeSjmmv         { NULL, NULL, 0, 0, "", false }
765f153ecaeSjmmv     };
766f153ecaeSjmmv     do_require_eq_tests(tests);
767f153ecaeSjmmv }
768f153ecaeSjmmv 
769f153ecaeSjmmv /* ---------------------------------------------------------------------
770edebbb8eSjmmv  * Miscellaneous test cases covering several macros.
771edebbb8eSjmmv  * --------------------------------------------------------------------- */
772edebbb8eSjmmv 
773edebbb8eSjmmv static
774edebbb8eSjmmv bool
aux_bool(const char * fmt ATF_DEFS_ATTRIBUTE_UNUSED)7756debfaafSjmmv aux_bool(const char *fmt ATF_DEFS_ATTRIBUTE_UNUSED)
776edebbb8eSjmmv {
777edebbb8eSjmmv     return false;
778edebbb8eSjmmv }
779edebbb8eSjmmv 
780edebbb8eSjmmv static
781edebbb8eSjmmv const char *
aux_str(const char * fmt ATF_DEFS_ATTRIBUTE_UNUSED)7826debfaafSjmmv aux_str(const char *fmt ATF_DEFS_ATTRIBUTE_UNUSED)
783edebbb8eSjmmv {
784edebbb8eSjmmv     return "foo";
785edebbb8eSjmmv }
786edebbb8eSjmmv 
787edebbb8eSjmmv H_CHECK(msg, aux_bool("%d"));
788edebbb8eSjmmv H_REQUIRE(msg, aux_bool("%d"));
789edebbb8eSjmmv H_CHECK_STREQ(msg, aux_str("%d"), "");
790edebbb8eSjmmv H_REQUIRE_STREQ(msg, aux_str("%d"), "");
791edebbb8eSjmmv 
792edebbb8eSjmmv ATF_TC(msg_embedded_fmt);
ATF_TC_HEAD(msg_embedded_fmt,tc)793edebbb8eSjmmv ATF_TC_HEAD(msg_embedded_fmt, tc)
794edebbb8eSjmmv {
795edebbb8eSjmmv     atf_tc_set_md_var(tc, "descr", "Tests that format strings passed "
796edebbb8eSjmmv                       "as part of the automatically-generated messages "
797edebbb8eSjmmv                       "do not get expanded");
798edebbb8eSjmmv }
ATF_TC_BODY(msg_embedded_fmt,tc)799edebbb8eSjmmv ATF_TC_BODY(msg_embedded_fmt, tc)
800edebbb8eSjmmv {
801edebbb8eSjmmv     struct test {
802edebbb8eSjmmv         void (*head)(atf_tc_t *);
803edebbb8eSjmmv         void (*body)(const atf_tc_t *);
804edebbb8eSjmmv         bool fatal;
805edebbb8eSjmmv         const char *msg;
806edebbb8eSjmmv     } *t, tests[] = {
807edebbb8eSjmmv        {  H_CHECK_HEAD_NAME(msg), H_CHECK_BODY_NAME(msg), false,
808edebbb8eSjmmv           "aux_bool\\(\"%d\"\\) not met" },
809edebbb8eSjmmv        {  H_REQUIRE_HEAD_NAME(msg), H_REQUIRE_BODY_NAME(msg), true,
810edebbb8eSjmmv           "aux_bool\\(\"%d\"\\) not met" },
811edebbb8eSjmmv        {  H_CHECK_STREQ_HEAD_NAME(msg), H_CHECK_STREQ_BODY_NAME(msg), false,
812edebbb8eSjmmv           "aux_str\\(\"%d\"\\) != \"\" \\(foo != \\)" },
813edebbb8eSjmmv        {  H_REQUIRE_STREQ_HEAD_NAME(msg), H_REQUIRE_STREQ_BODY_NAME(msg), true,
814edebbb8eSjmmv           "aux_str\\(\"%d\"\\) != \"\" \\(foo != \\)" },
815edebbb8eSjmmv        { NULL, NULL, false, NULL }
816edebbb8eSjmmv     };
817edebbb8eSjmmv 
818edebbb8eSjmmv     for (t = &tests[0]; t->head != NULL; t++) {
819edebbb8eSjmmv         printf("Checking with an expected '%s' message\n", t->msg);
820edebbb8eSjmmv 
821edebbb8eSjmmv         init_and_run_h_tc("h_check", t->head, t->body);
822edebbb8eSjmmv 
823edebbb8eSjmmv         if (t->fatal) {
824edebbb8eSjmmv             bool matched =
825f153ecaeSjmmv                 atf_utils_grep_file(
826f153ecaeSjmmv                     "^failed: .*macros_test.c:[0-9]+: %s$", "result", t->msg);
827edebbb8eSjmmv             ATF_CHECK_MSG(matched, "couldn't find error string in result");
828edebbb8eSjmmv         } else {
829f153ecaeSjmmv             bool matched = atf_utils_grep_file("Check failed: .*"
830f153ecaeSjmmv                 "macros_test.c:[0-9]+: %s$", "error", t->msg);
831edebbb8eSjmmv             ATF_CHECK_MSG(matched, "couldn't find error string in output");
832edebbb8eSjmmv         }
833edebbb8eSjmmv     }
834edebbb8eSjmmv }
835edebbb8eSjmmv 
836edebbb8eSjmmv /* ---------------------------------------------------------------------
837edebbb8eSjmmv  * Tests cases for the header file.
838edebbb8eSjmmv  * --------------------------------------------------------------------- */
839edebbb8eSjmmv 
840edebbb8eSjmmv HEADER_TC(include, "atf-c/macros.h");
841edebbb8eSjmmv BUILD_TC(use, "macros_h_test.c",
842edebbb8eSjmmv          "Tests that the macros provided by the atf-c/macros.h file "
843edebbb8eSjmmv          "do not cause syntax errors when used",
844edebbb8eSjmmv          "Build of macros_h_test.c failed; some macros in atf-c/macros.h "
845edebbb8eSjmmv          "are broken");
84614fc6011Sjmmv 
84714fc6011Sjmmv ATF_TC(detect_unused_tests);
ATF_TC_HEAD(detect_unused_tests,tc)84814fc6011Sjmmv ATF_TC_HEAD(detect_unused_tests, tc)
84914fc6011Sjmmv {
85014fc6011Sjmmv     atf_tc_set_md_var(tc, "descr",
85114fc6011Sjmmv                       "Tests that defining an unused test case raises a "
85214fc6011Sjmmv                       "warning (and thus an error)");
85314fc6011Sjmmv }
ATF_TC_BODY(detect_unused_tests,tc)85414fc6011Sjmmv ATF_TC_BODY(detect_unused_tests, tc)
85514fc6011Sjmmv {
85614fc6011Sjmmv     const char* validate_compiler =
85714fc6011Sjmmv         "struct test_struct { int dummy; };\n"
85814fc6011Sjmmv         "#define define_unused static struct test_struct unused\n"
85914fc6011Sjmmv         "define_unused;\n";
86014fc6011Sjmmv 
86114fc6011Sjmmv     atf_utils_create_file("compiler_test.c", "%s", validate_compiler);
86214fc6011Sjmmv     if (build_check_c_o("compiler_test.c"))
86314fc6011Sjmmv         atf_tc_expect_fail("Compiler does not raise a warning on an unused "
86414fc6011Sjmmv                            "static global variable declared by a macro");
86514fc6011Sjmmv 
866*032c8705Sgson #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
867*032c8705Sgson         atf_tc_expect_fail("PR 49187");
868*032c8705Sgson #endif
869*032c8705Sgson 
87014fc6011Sjmmv     if (build_check_c_o_srcdir(tc, "unused_test.c"))
87114fc6011Sjmmv         atf_tc_fail("Build of unused_test.c passed; unused test cases are "
87214fc6011Sjmmv                     "not properly detected");
87314fc6011Sjmmv }
874edebbb8eSjmmv 
875edebbb8eSjmmv /* ---------------------------------------------------------------------
876edebbb8eSjmmv  * Main.
877edebbb8eSjmmv  * --------------------------------------------------------------------- */
878edebbb8eSjmmv 
ATF_TP_ADD_TCS(tp)879edebbb8eSjmmv ATF_TP_ADD_TCS(tp)
880edebbb8eSjmmv {
881edebbb8eSjmmv     ATF_TP_ADD_TC(tp, check);
882edebbb8eSjmmv     ATF_TP_ADD_TC(tp, check_eq);
883edebbb8eSjmmv     ATF_TP_ADD_TC(tp, check_streq);
884edebbb8eSjmmv     ATF_TP_ADD_TC(tp, check_errno);
885f153ecaeSjmmv     ATF_TP_ADD_TC(tp, check_match);
886edebbb8eSjmmv 
887edebbb8eSjmmv     ATF_TP_ADD_TC(tp, require);
888edebbb8eSjmmv     ATF_TP_ADD_TC(tp, require_eq);
889edebbb8eSjmmv     ATF_TP_ADD_TC(tp, require_streq);
890edebbb8eSjmmv     ATF_TP_ADD_TC(tp, require_errno);
891f153ecaeSjmmv     ATF_TP_ADD_TC(tp, require_match);
892edebbb8eSjmmv 
893edebbb8eSjmmv     ATF_TP_ADD_TC(tp, msg_embedded_fmt);
894edebbb8eSjmmv 
895edebbb8eSjmmv     /* Add the test cases for the header file. */
896edebbb8eSjmmv     ATF_TP_ADD_TC(tp, include);
897edebbb8eSjmmv     ATF_TP_ADD_TC(tp, use);
898ac0943f1Sjmmv     ATF_TP_ADD_TC(tp, detect_unused_tests);
899edebbb8eSjmmv 
900edebbb8eSjmmv     return atf_no_error();
901edebbb8eSjmmv }
902