xref: /netbsd-src/external/bsd/atf/dist/atf-c/macros_test.c (revision b1c86f5f087524e68db12794ee9c3e3da1ab17a0)
1 /*
2  * Automated Testing Framework (atf)
3  *
4  * Copyright (c) 2008, 2009, 2010 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 <sys/types.h>
31 #include <sys/wait.h>
32 
33 #include <errno.h>
34 #include <fcntl.h>
35 #include <stdarg.h>
36 #include <stdbool.h>
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <string.h>
40 #include <unistd.h>
41 
42 #include <atf-c.h>
43 
44 #include "atf-c/fs.h"
45 #include "atf-c/process.h"
46 #include "atf-c/text.h"
47 
48 #include "test_helpers.h"
49 
50 /* ---------------------------------------------------------------------
51  * Auxiliary functions.
52  * --------------------------------------------------------------------- */
53 
54 static
55 void
56 create_ctl_file(const atf_tc_t *tc, const char *name)
57 {
58     atf_fs_path_t p;
59 
60     RE(atf_fs_path_init_fmt(&p, "%s", name));
61     ATF_REQUIRE(open(atf_fs_path_cstring(&p),
62                    O_CREAT | O_WRONLY | O_TRUNC, 0644) != -1);
63     atf_fs_path_fini(&p);
64 }
65 
66 static
67 bool
68 exists(const char *p)
69 {
70     bool b;
71     atf_fs_path_t pp;
72 
73     RE(atf_fs_path_init_fmt(&pp, "%s", p));
74     RE(atf_fs_exists(&pp, &b));
75     atf_fs_path_fini(&pp);
76 
77     return b;
78 }
79 
80 static
81 void
82 init_and_run_h_tc(const char *name, void (*head)(atf_tc_t *),
83                   void (*body)(const atf_tc_t *))
84 {
85     atf_tc_t tc;
86     atf_map_t config;
87 
88     RE(atf_map_init(&config));
89     RE(atf_tc_init(&tc, name, head, body, NULL, &config));
90     run_h_tc(&tc, "output", "error", "result");
91     atf_tc_fini(&tc);
92     atf_map_fini(&config);
93 }
94 
95 /* ---------------------------------------------------------------------
96  * Helper test cases.
97  * --------------------------------------------------------------------- */
98 
99 #define H_DEF(id, macro) \
100     ATF_TC_HEAD(h_ ## id, tc) \
101     { \
102         atf_tc_set_md_var(tc, "descr", "Helper test case"); \
103     } \
104     ATF_TC_BODY(h_ ## id, tc) \
105     { \
106         create_ctl_file(tc, "before"); \
107         macro; \
108         create_ctl_file(tc, "after"); \
109     }
110 
111 #define H_CHECK_HEAD_NAME(id) ATF_TC_HEAD_NAME(h_check_ ## id)
112 #define H_CHECK_BODY_NAME(id) ATF_TC_BODY_NAME(h_check_ ## id)
113 #define H_CHECK(id, condition) \
114     H_DEF(check_ ## id, ATF_CHECK(condition))
115 
116 #define H_CHECK_MSG_HEAD_NAME(id) ATF_TC_HEAD_NAME(h_check_msg_ ## id)
117 #define H_CHECK_MSG_BODY_NAME(id) ATF_TC_BODY_NAME(h_check_msg_ ## id)
118 #define H_CHECK_MSG(id, condition, msg) \
119     H_DEF(check_msg_ ## id, ATF_CHECK_MSG(condition, msg))
120 
121 #define H_CHECK_EQ_HEAD_NAME(id) ATF_TC_HEAD_NAME(h_check_eq_ ## id)
122 #define H_CHECK_EQ_BODY_NAME(id) ATF_TC_BODY_NAME(h_check_eq_ ## id)
123 #define H_CHECK_EQ(id, v1, v2) \
124     H_DEF(check_eq_ ## id, ATF_CHECK_EQ(v1, v2))
125 
126 #define H_CHECK_STREQ_HEAD_NAME(id) ATF_TC_HEAD_NAME(h_check_streq_ ## id)
127 #define H_CHECK_STREQ_BODY_NAME(id) ATF_TC_BODY_NAME(h_check_streq_ ## id)
128 #define H_CHECK_STREQ(id, v1, v2) \
129     H_DEF(check_streq_ ## id, ATF_CHECK_STREQ(v1, v2))
130 
131 #define H_CHECK_EQ_MSG_HEAD_NAME(id) \
132     ATF_TC_HEAD_NAME(h_check_eq_msg_ ## id)
133 #define H_CHECK_EQ_MSG_BODY_NAME(id) \
134     ATF_TC_BODY_NAME(h_check_eq_msg_ ## id)
135 #define H_CHECK_EQ_MSG(id, v1, v2, msg) \
136     H_DEF(check_eq_msg_ ## id, ATF_CHECK_EQ_MSG(v1, v2, msg))
137 
138 #define H_CHECK_STREQ_MSG_HEAD_NAME(id) \
139     ATF_TC_HEAD_NAME(h_check_streq_msg_ ## id)
140 #define H_CHECK_STREQ_MSG_BODY_NAME(id) \
141     ATF_TC_BODY_NAME(h_check_streq_msg_ ## id)
142 #define H_CHECK_STREQ_MSG(id, v1, v2, msg) \
143     H_DEF(check_streq_msg_ ## id, ATF_CHECK_STREQ_MSG(v1, v2, msg))
144 
145 #define H_CHECK_ERRNO_HEAD_NAME(id) ATF_TC_HEAD_NAME(h_check_errno_ ## id)
146 #define H_CHECK_ERRNO_BODY_NAME(id) ATF_TC_BODY_NAME(h_check_errno_ ## id)
147 #define H_CHECK_ERRNO(id, exp_errno, bool_expr) \
148     H_DEF(check_errno_ ## id, ATF_CHECK_ERRNO(exp_errno, bool_expr))
149 
150 #define H_REQUIRE_HEAD_NAME(id) ATF_TC_HEAD_NAME(h_require_ ## id)
151 #define H_REQUIRE_BODY_NAME(id) ATF_TC_BODY_NAME(h_require_ ## id)
152 #define H_REQUIRE(id, condition) \
153     H_DEF(require_ ## id, ATF_REQUIRE(condition))
154 
155 #define H_REQUIRE_MSG_HEAD_NAME(id) ATF_TC_HEAD_NAME(h_require_msg_ ## id)
156 #define H_REQUIRE_MSG_BODY_NAME(id) ATF_TC_BODY_NAME(h_require_msg_ ## id)
157 #define H_REQUIRE_MSG(id, condition, msg) \
158     H_DEF(require_msg_ ## id, ATF_REQUIRE_MSG(condition, msg))
159 
160 #define H_REQUIRE_EQ_HEAD_NAME(id) ATF_TC_HEAD_NAME(h_require_eq_ ## id)
161 #define H_REQUIRE_EQ_BODY_NAME(id) ATF_TC_BODY_NAME(h_require_eq_ ## id)
162 #define H_REQUIRE_EQ(id, v1, v2) \
163     H_DEF(require_eq_ ## id, ATF_REQUIRE_EQ(v1, v2))
164 
165 #define H_REQUIRE_STREQ_HEAD_NAME(id) ATF_TC_HEAD_NAME(h_require_streq_ ## id)
166 #define H_REQUIRE_STREQ_BODY_NAME(id) ATF_TC_BODY_NAME(h_require_streq_ ## id)
167 #define H_REQUIRE_STREQ(id, v1, v2) \
168     H_DEF(require_streq_ ## id, ATF_REQUIRE_STREQ(v1, v2))
169 
170 #define H_REQUIRE_EQ_MSG_HEAD_NAME(id) \
171     ATF_TC_HEAD_NAME(h_require_eq_msg_ ## id)
172 #define H_REQUIRE_EQ_MSG_BODY_NAME(id) \
173     ATF_TC_BODY_NAME(h_require_eq_msg_ ## id)
174 #define H_REQUIRE_EQ_MSG(id, v1, v2, msg) \
175     H_DEF(require_eq_msg_ ## id, ATF_REQUIRE_EQ_MSG(v1, v2, msg))
176 
177 #define H_REQUIRE_STREQ_MSG_HEAD_NAME(id) \
178     ATF_TC_HEAD_NAME(h_require_streq_msg_ ## id)
179 #define H_REQUIRE_STREQ_MSG_BODY_NAME(id) \
180     ATF_TC_BODY_NAME(h_require_streq_msg_ ## id)
181 #define H_REQUIRE_STREQ_MSG(id, v1, v2, msg) \
182     H_DEF(require_streq_msg_ ## id, ATF_REQUIRE_STREQ_MSG(v1, v2, msg))
183 
184 #define H_REQUIRE_ERRNO_HEAD_NAME(id) ATF_TC_HEAD_NAME(h_require_errno_ ## id)
185 #define H_REQUIRE_ERRNO_BODY_NAME(id) ATF_TC_BODY_NAME(h_require_errno_ ## id)
186 #define H_REQUIRE_ERRNO(id, exp_errno, bool_expr) \
187     H_DEF(require_errno_ ## id, ATF_REQUIRE_ERRNO(exp_errno, bool_expr))
188 
189 /* ---------------------------------------------------------------------
190  * Test cases for the ATF_{CHECK,REQUIRE}_ERRNO macros.
191  * --------------------------------------------------------------------- */
192 
193 static int
194 errno_fail_stub(const int raised_errno)
195 {
196     errno = raised_errno;
197     return -1;
198 }
199 
200 static int
201 errno_ok_stub(void)
202 {
203     return 0;
204 }
205 
206 H_CHECK_ERRNO(no_error, -1, errno_ok_stub() == -1);
207 H_CHECK_ERRNO(errno_ok, 2, errno_fail_stub(2) == -1);
208 H_CHECK_ERRNO(errno_fail, 3, errno_fail_stub(4) == -1);
209 
210 H_REQUIRE_ERRNO(no_error, -1, errno_ok_stub() == -1);
211 H_REQUIRE_ERRNO(errno_ok, 2, errno_fail_stub(2) == -1);
212 H_REQUIRE_ERRNO(errno_fail, 3, errno_fail_stub(4) == -1);
213 
214 ATF_TC(check_errno);
215 ATF_TC_HEAD(check_errno, tc)
216 {
217     atf_tc_set_md_var(tc, "descr", "Tests the ATF_CHECK_ERRNO macro");
218     atf_tc_set_md_var(tc, "use.fs", "true");
219 }
220 ATF_TC_BODY(check_errno, tc)
221 {
222     struct test {
223         void (*head)(atf_tc_t *);
224         void (*body)(const atf_tc_t *);
225         bool ok;
226         const char *exp_regex;
227     } *t, tests[] = {
228         { H_CHECK_ERRNO_HEAD_NAME(no_error),
229           H_CHECK_ERRNO_BODY_NAME(no_error),
230           false, "Expected true value in errno_ok_stub\\(\\) == -1" },
231         { H_CHECK_ERRNO_HEAD_NAME(errno_ok),
232           H_CHECK_ERRNO_BODY_NAME(errno_ok),
233           true, NULL },
234         { H_CHECK_ERRNO_HEAD_NAME(errno_fail),
235           H_CHECK_ERRNO_BODY_NAME(errno_fail),
236           false, "Expected errno 3, got 4, in errno_fail_stub\\(4\\) == -1" },
237         { NULL, NULL, false, NULL }
238     };
239 
240     for (t = &tests[0]; t->head != NULL; t++) {
241         init_and_run_h_tc("h_check_errno", t->head, t->body);
242 
243         ATF_REQUIRE(exists("before"));
244         ATF_REQUIRE(exists("after"));
245 
246         if (t->ok) {
247             ATF_REQUIRE(grep_file("result", "^passed"));
248         } else {
249             ATF_REQUIRE(grep_file("result", "^failed"));
250             ATF_REQUIRE(grep_file("error", "macros_test.c:[0-9]+: %s$",
251                 t->exp_regex));
252         }
253 
254         ATF_REQUIRE(unlink("before") != -1);
255         ATF_REQUIRE(unlink("after") != -1);
256     }
257 }
258 
259 ATF_TC(require_errno);
260 ATF_TC_HEAD(require_errno, tc)
261 {
262     atf_tc_set_md_var(tc, "descr", "Tests the ATF_REQUIRE_ERRNO macro");
263     atf_tc_set_md_var(tc, "use.fs", "true");
264 }
265 ATF_TC_BODY(require_errno, tc)
266 {
267     struct test {
268         void (*head)(atf_tc_t *);
269         void (*body)(const atf_tc_t *);
270         bool ok;
271         const char *exp_regex;
272     } *t, tests[] = {
273         { H_REQUIRE_ERRNO_HEAD_NAME(no_error),
274           H_REQUIRE_ERRNO_BODY_NAME(no_error),
275           false, "Expected true value in errno_ok_stub\\(\\) == -1" },
276         { H_REQUIRE_ERRNO_HEAD_NAME(errno_ok),
277           H_REQUIRE_ERRNO_BODY_NAME(errno_ok),
278           true, NULL },
279         { H_REQUIRE_ERRNO_HEAD_NAME(errno_fail),
280           H_REQUIRE_ERRNO_BODY_NAME(errno_fail),
281           false, "Expected errno 3, got 4, in errno_fail_stub\\(4\\) == -1" },
282         { NULL, NULL, false, NULL }
283     };
284 
285     for (t = &tests[0]; t->head != NULL; t++) {
286         init_and_run_h_tc("h_require_errno", t->head, t->body);
287 
288         ATF_REQUIRE(exists("before"));
289         if (t->ok) {
290             ATF_REQUIRE(grep_file("result", "^passed"));
291             ATF_REQUIRE(exists("after"));
292         } else {
293             ATF_REQUIRE(grep_file("result", "^failed: .*macros_test.c:[0-9]+: "
294                 "%s$", t->exp_regex));
295             ATF_REQUIRE(!exists("after"));
296         }
297 
298         ATF_REQUIRE(unlink("before") != -1);
299         if (t->ok)
300             ATF_REQUIRE(unlink("after") != -1);
301     }
302 }
303 
304 /* ---------------------------------------------------------------------
305  * Test cases for the ATF_CHECK and ATF_CHECK_MSG macros.
306  * --------------------------------------------------------------------- */
307 
308 H_CHECK(0, 0);
309 H_CHECK(1, 1);
310 H_CHECK_MSG(0, 0, "expected a false value");
311 H_CHECK_MSG(1, 1, "expected a true value");
312 
313 ATF_TC(check);
314 ATF_TC_HEAD(check, tc)
315 {
316     atf_tc_set_md_var(tc, "descr", "Tests the ATF_CHECK and "
317                       "ATF_CHECK_MSG macros");
318     atf_tc_set_md_var(tc, "use.fs", "true");
319 }
320 ATF_TC_BODY(check, tc)
321 {
322     struct test {
323         void (*head)(atf_tc_t *);
324         void (*body)(const atf_tc_t *);
325         bool value;
326         const char *msg;
327         bool ok;
328     } *t, tests[] = {
329         { H_CHECK_HEAD_NAME(0), H_CHECK_BODY_NAME(0), 0,
330           "0 not met", false },
331         { H_CHECK_HEAD_NAME(1), H_CHECK_BODY_NAME(1), 1,
332           "1 not met", true },
333         { H_CHECK_MSG_HEAD_NAME(0), H_CHECK_MSG_BODY_NAME(0), 0,
334           "expected a false value", false },
335         { H_CHECK_MSG_HEAD_NAME(1), H_CHECK_MSG_BODY_NAME(1), 1,
336           "expected a true value", true },
337         { NULL, NULL, false, NULL, false }
338     };
339 
340     for (t = &tests[0]; t->head != NULL; t++) {
341         printf("Checking with a %d value\n", t->value);
342 
343         init_and_run_h_tc("h_check", t->head, t->body);
344 
345         ATF_REQUIRE(exists("before"));
346         ATF_REQUIRE(exists("after"));
347 
348         if (t->ok) {
349             ATF_REQUIRE(grep_file("result", "^passed"));
350         } else {
351             ATF_REQUIRE(grep_file("result", "^failed"));
352             ATF_REQUIRE(grep_file("error", "Check failed: .*"
353                 "macros_test.c:[0-9]+: %s$", t->msg));
354         }
355 
356         ATF_REQUIRE(unlink("before") != -1);
357         ATF_REQUIRE(unlink("after") != -1);
358     }
359 }
360 
361 /* ---------------------------------------------------------------------
362  * Test cases for the ATF_CHECK_*EQ_ macros.
363  * --------------------------------------------------------------------- */
364 
365 struct check_eq_test {
366     void (*head)(atf_tc_t *);
367     void (*body)(const atf_tc_t *);
368     const char *v1;
369     const char *v2;
370     const char *msg;
371     bool ok;
372 };
373 
374 static
375 void
376 do_check_eq_tests(const struct check_eq_test *tests)
377 {
378     const struct check_eq_test *t;
379 
380     for (t = &tests[0]; t->head != NULL; t++) {
381         printf("Checking with %s, %s and expecting %s\n", t->v1, t->v2,
382                t->ok ? "true" : "false");
383 
384         init_and_run_h_tc("h_check", t->head, t->body);
385 
386         ATF_CHECK(exists("before"));
387         ATF_CHECK(exists("after"));
388 
389         if (t->ok) {
390             ATF_REQUIRE(grep_file("result", "^passed"));
391         } else {
392             ATF_REQUIRE(grep_file("result", "^failed"));
393             ATF_CHECK(grep_file("error", "Check failed: .*"
394                 "macros_test.c:[0-9]+: %s$", t->msg));
395         }
396 
397         ATF_CHECK(unlink("before") != -1);
398         ATF_CHECK(unlink("after") != -1);
399     }
400 }
401 
402 H_CHECK_EQ(1_1, 1, 1);
403 H_CHECK_EQ(1_2, 1, 2);
404 H_CHECK_EQ(2_1, 2, 1);
405 H_CHECK_EQ(2_2, 2, 2);
406 H_CHECK_EQ_MSG(1_1, 1, 1, "1 does not match 1");
407 H_CHECK_EQ_MSG(1_2, 1, 2, "1 does not match 2");
408 H_CHECK_EQ_MSG(2_1, 2, 1, "2 does not match 1");
409 H_CHECK_EQ_MSG(2_2, 2, 2, "2 does not match 2");
410 
411 ATF_TC(check_eq);
412 ATF_TC_HEAD(check_eq, tc)
413 {
414     atf_tc_set_md_var(tc, "descr", "Tests the ATF_CHECK_EQ and "
415                       "ATF_CHECK_EQ_MSG macros");
416     atf_tc_set_md_var(tc, "use.fs", "true");
417 }
418 ATF_TC_BODY(check_eq, tc)
419 {
420     struct check_eq_test tests[] = {
421         { H_CHECK_EQ_HEAD_NAME(1_1), H_CHECK_EQ_BODY_NAME(1_1),
422           "1", "1", "1 != 1", true },
423         { H_CHECK_EQ_HEAD_NAME(1_2), H_CHECK_EQ_BODY_NAME(1_2),
424           "1", "2", "1 != 2", false },
425         { H_CHECK_EQ_HEAD_NAME(2_1), H_CHECK_EQ_BODY_NAME(2_1),
426           "2", "1", "2 != 1", false },
427         { H_CHECK_EQ_HEAD_NAME(2_2), H_CHECK_EQ_BODY_NAME(2_2),
428           "2", "2", "2 != 2", true },
429         { H_CHECK_EQ_MSG_HEAD_NAME(1_1), H_CHECK_EQ_MSG_BODY_NAME(1_1),
430           "1", "1", "1 != 1: 1 does not match 1", true },
431         { H_CHECK_EQ_MSG_HEAD_NAME(1_2), H_CHECK_EQ_MSG_BODY_NAME(1_2),
432           "1", "2", "1 != 2: 1 does not match 2", false },
433         { H_CHECK_EQ_MSG_HEAD_NAME(2_1), H_CHECK_EQ_MSG_BODY_NAME(2_1),
434           "2", "1", "2 != 1: 2 does not match 1", false },
435         { H_CHECK_EQ_MSG_HEAD_NAME(2_2), H_CHECK_EQ_MSG_BODY_NAME(2_2),
436           "2", "2", "2 != 2: 2 does not match 2", true },
437         { NULL, NULL, 0, 0, "", false }
438     };
439     do_check_eq_tests(tests);
440 }
441 
442 H_CHECK_STREQ(1_1, "1", "1");
443 H_CHECK_STREQ(1_2, "1", "2");
444 H_CHECK_STREQ(2_1, "2", "1");
445 H_CHECK_STREQ(2_2, "2", "2");
446 H_CHECK_STREQ_MSG(1_1, "1", "1", "1 does not match 1");
447 H_CHECK_STREQ_MSG(1_2, "1", "2", "1 does not match 2");
448 H_CHECK_STREQ_MSG(2_1, "2", "1", "2 does not match 1");
449 H_CHECK_STREQ_MSG(2_2, "2", "2", "2 does not match 2");
450 #define CHECK_STREQ_VAR1 "5"
451 #define CHECK_STREQ_VAR2 "9"
452 const const char *check_streq_var1 = CHECK_STREQ_VAR1;
453 const const char *check_streq_var2 = CHECK_STREQ_VAR2;
454 H_CHECK_STREQ(vars, check_streq_var1, check_streq_var2);
455 
456 ATF_TC(check_streq);
457 ATF_TC_HEAD(check_streq, tc)
458 {
459     atf_tc_set_md_var(tc, "descr", "Tests the ATF_CHECK_STREQ and "
460                       "ATF_CHECK_STREQ_MSG macros");
461     atf_tc_set_md_var(tc, "use.fs", "true");
462 }
463 ATF_TC_BODY(check_streq, tc)
464 {
465     struct check_eq_test tests[] = {
466         { H_CHECK_STREQ_HEAD_NAME(1_1), H_CHECK_STREQ_BODY_NAME(1_1),
467           "1", "1", "\"1\" != \"1\" \\(1 != 1\\)", true },
468         { H_CHECK_STREQ_HEAD_NAME(1_2), H_CHECK_STREQ_BODY_NAME(1_2),
469           "1", "2", "\"1\" != \"2\" \\(1 != 2\\)", false },
470         { H_CHECK_STREQ_HEAD_NAME(2_1), H_CHECK_STREQ_BODY_NAME(2_1),
471           "2", "1", "\"2\" != \"1\" \\(2 != 1\\)", false },
472         { H_CHECK_STREQ_HEAD_NAME(2_2), H_CHECK_STREQ_BODY_NAME(2_2),
473           "2", "2", "\"2\" != \"2\" \\(2 != 2\\)", true },
474         { H_CHECK_STREQ_MSG_HEAD_NAME(1_1),
475           H_CHECK_STREQ_MSG_BODY_NAME(1_1),
476           "1", "1", "\"1\" != \"1\" \\(1 != 1\\): 1 does not match 1", true },
477         { H_CHECK_STREQ_MSG_HEAD_NAME(1_2),
478           H_CHECK_STREQ_MSG_BODY_NAME(1_2),
479           "1", "2", "\"1\" != \"2\" \\(1 != 2\\): 1 does not match 2", false },
480         { H_CHECK_STREQ_MSG_HEAD_NAME(2_1),
481           H_CHECK_STREQ_MSG_BODY_NAME(2_1),
482           "2", "1", "\"2\" != \"1\" \\(2 != 1\\): 2 does not match 1", false },
483         { H_CHECK_STREQ_MSG_HEAD_NAME(2_2),
484           H_CHECK_STREQ_MSG_BODY_NAME(2_2),
485           "2", "2", "\"2\" != \"2\" \\(2 != 2\\): 2 does not match 2", true },
486         { H_CHECK_STREQ_HEAD_NAME(vars), H_CHECK_STREQ_BODY_NAME(vars),
487           check_streq_var1, check_streq_var2,
488           "check_streq_var1 != check_streq_var2 \\("
489           CHECK_STREQ_VAR1 " != " CHECK_STREQ_VAR2 "\\)", false },
490         { NULL, NULL, 0, 0, "", false }
491     };
492     do_check_eq_tests(tests);
493 }
494 
495 /* ---------------------------------------------------------------------
496  * Test cases for the ATF_REQUIRE and ATF_REQUIRE_MSG macros.
497  * --------------------------------------------------------------------- */
498 
499 H_REQUIRE(0, 0);
500 H_REQUIRE(1, 1);
501 H_REQUIRE_MSG(0, 0, "expected a false value");
502 H_REQUIRE_MSG(1, 1, "expected a true value");
503 
504 ATF_TC(require);
505 ATF_TC_HEAD(require, tc)
506 {
507     atf_tc_set_md_var(tc, "descr", "Tests the ATF_REQUIRE and "
508                       "ATF_REQUIRE_MSG macros");
509     atf_tc_set_md_var(tc, "use.fs", "true");
510 }
511 ATF_TC_BODY(require, tc)
512 {
513     struct test {
514         void (*head)(atf_tc_t *);
515         void (*body)(const atf_tc_t *);
516         bool value;
517         const char *msg;
518         bool ok;
519     } *t, tests[] = {
520         { H_REQUIRE_HEAD_NAME(0), H_REQUIRE_BODY_NAME(0), 0,
521           "0 not met", false },
522         { H_REQUIRE_HEAD_NAME(1), H_REQUIRE_BODY_NAME(1), 1,
523           "1 not met", true },
524         { H_REQUIRE_MSG_HEAD_NAME(0), H_REQUIRE_MSG_BODY_NAME(0), 0,
525           "expected a false value", false },
526         { H_REQUIRE_MSG_HEAD_NAME(1), H_REQUIRE_MSG_BODY_NAME(1), 1,
527           "expected a true value", true },
528         { NULL, NULL, false, NULL, false }
529     };
530 
531     for (t = &tests[0]; t->head != NULL; t++) {
532         printf("Checking with a %d value\n", t->value);
533 
534         init_and_run_h_tc("h_require", t->head, t->body);
535 
536         ATF_REQUIRE(exists("before"));
537         if (t->ok) {
538             ATF_REQUIRE(grep_file("result", "^passed"));
539             ATF_REQUIRE(exists("after"));
540         } else {
541             ATF_REQUIRE(grep_file("result", "^failed: .*macros_test.c:[0-9]+: "
542                                   "%s$", t->msg));
543             ATF_REQUIRE(!exists("after"));
544         }
545 
546         ATF_REQUIRE(unlink("before") != -1);
547         if (t->ok)
548             ATF_REQUIRE(unlink("after") != -1);
549     }
550 }
551 
552 /* ---------------------------------------------------------------------
553  * Test cases for the ATF_REQUIRE_*EQ_ macros.
554  * --------------------------------------------------------------------- */
555 
556 struct require_eq_test {
557     void (*head)(atf_tc_t *);
558     void (*body)(const atf_tc_t *);
559     const char *v1;
560     const char *v2;
561     const char *msg;
562     bool ok;
563 };
564 
565 static
566 void
567 do_require_eq_tests(const struct require_eq_test *tests)
568 {
569     const struct require_eq_test *t;
570 
571     for (t = &tests[0]; t->head != NULL; t++) {
572         printf("Checking with %s, %s and expecting %s\n", t->v1, t->v2,
573                t->ok ? "true" : "false");
574 
575         init_and_run_h_tc("h_require", t->head, t->body);
576 
577         ATF_REQUIRE(exists("before"));
578         if (t->ok) {
579             ATF_REQUIRE(grep_file("result", "^passed"));
580             ATF_REQUIRE(exists("after"));
581         } else {
582             ATF_REQUIRE(grep_file("result", "^failed: .*macros_test.c"
583                 ":[0-9]+: %s$", t->msg));
584             ATF_REQUIRE(!exists("after"));
585         }
586 
587         ATF_REQUIRE(unlink("before") != -1);
588         if (t->ok)
589             ATF_REQUIRE(unlink("after") != -1);
590     }
591 }
592 
593 H_REQUIRE_EQ(1_1, 1, 1);
594 H_REQUIRE_EQ(1_2, 1, 2);
595 H_REQUIRE_EQ(2_1, 2, 1);
596 H_REQUIRE_EQ(2_2, 2, 2);
597 H_REQUIRE_EQ_MSG(1_1, 1, 1, "1 does not match 1");
598 H_REQUIRE_EQ_MSG(1_2, 1, 2, "1 does not match 2");
599 H_REQUIRE_EQ_MSG(2_1, 2, 1, "2 does not match 1");
600 H_REQUIRE_EQ_MSG(2_2, 2, 2, "2 does not match 2");
601 
602 ATF_TC(require_eq);
603 ATF_TC_HEAD(require_eq, tc)
604 {
605     atf_tc_set_md_var(tc, "descr", "Tests the ATF_REQUIRE_EQ and "
606                       "ATF_REQUIRE_EQ_MSG macros");
607     atf_tc_set_md_var(tc, "use.fs", "true");
608 }
609 ATF_TC_BODY(require_eq, tc)
610 {
611     struct require_eq_test tests[] = {
612         { H_REQUIRE_EQ_HEAD_NAME(1_1), H_REQUIRE_EQ_BODY_NAME(1_1),
613           "1", "1", "1 != 1", true },
614         { H_REQUIRE_EQ_HEAD_NAME(1_2), H_REQUIRE_EQ_BODY_NAME(1_2),
615           "1", "2", "1 != 2", false },
616         { H_REQUIRE_EQ_HEAD_NAME(2_1), H_REQUIRE_EQ_BODY_NAME(2_1),
617           "2", "1", "2 != 1", false },
618         { H_REQUIRE_EQ_HEAD_NAME(2_2), H_REQUIRE_EQ_BODY_NAME(2_2),
619           "2", "2", "2 != 2", true },
620         { H_REQUIRE_EQ_MSG_HEAD_NAME(1_1), H_REQUIRE_EQ_MSG_BODY_NAME(1_1),
621           "1", "1", "1 != 1: 1 does not match 1", true },
622         { H_REQUIRE_EQ_MSG_HEAD_NAME(1_2), H_REQUIRE_EQ_MSG_BODY_NAME(1_2),
623           "1", "2", "1 != 2: 1 does not match 2", false },
624         { H_REQUIRE_EQ_MSG_HEAD_NAME(2_1), H_REQUIRE_EQ_MSG_BODY_NAME(2_1),
625           "2", "1", "2 != 1: 2 does not match 1", false },
626         { H_REQUIRE_EQ_MSG_HEAD_NAME(2_2), H_REQUIRE_EQ_MSG_BODY_NAME(2_2),
627           "2", "2", "2 != 2: 2 does not match 2", true },
628         { NULL, NULL, 0, 0, "", false }
629     };
630     do_require_eq_tests(tests);
631 }
632 
633 H_REQUIRE_STREQ(1_1, "1", "1");
634 H_REQUIRE_STREQ(1_2, "1", "2");
635 H_REQUIRE_STREQ(2_1, "2", "1");
636 H_REQUIRE_STREQ(2_2, "2", "2");
637 H_REQUIRE_STREQ_MSG(1_1, "1", "1", "1 does not match 1");
638 H_REQUIRE_STREQ_MSG(1_2, "1", "2", "1 does not match 2");
639 H_REQUIRE_STREQ_MSG(2_1, "2", "1", "2 does not match 1");
640 H_REQUIRE_STREQ_MSG(2_2, "2", "2", "2 does not match 2");
641 #define REQUIRE_STREQ_VAR1 "5"
642 #define REQUIRE_STREQ_VAR2 "9"
643 const const char *require_streq_var1 = REQUIRE_STREQ_VAR1;
644 const const char *require_streq_var2 = REQUIRE_STREQ_VAR2;
645 H_REQUIRE_STREQ(vars, require_streq_var1, require_streq_var2);
646 
647 ATF_TC(require_streq);
648 ATF_TC_HEAD(require_streq, tc)
649 {
650     atf_tc_set_md_var(tc, "descr", "Tests the ATF_REQUIRE_STREQ and "
651                       "ATF_REQUIRE_STREQ_MSG macros");
652     atf_tc_set_md_var(tc, "use.fs", "true");
653 }
654 ATF_TC_BODY(require_streq, tc)
655 {
656     struct require_eq_test tests[] = {
657         { H_REQUIRE_STREQ_HEAD_NAME(1_1), H_REQUIRE_STREQ_BODY_NAME(1_1),
658           "1", "1", "\"1\" != \"1\" \\(1 != 1\\)", true },
659         { H_REQUIRE_STREQ_HEAD_NAME(1_2), H_REQUIRE_STREQ_BODY_NAME(1_2),
660           "1", "2", "\"1\" != \"2\" \\(1 != 2\\)", false },
661         { H_REQUIRE_STREQ_HEAD_NAME(2_1), H_REQUIRE_STREQ_BODY_NAME(2_1),
662           "2", "1", "\"2\" != \"1\" \\(2 != 1\\)", false },
663         { H_REQUIRE_STREQ_HEAD_NAME(2_2), H_REQUIRE_STREQ_BODY_NAME(2_2),
664           "2", "2", "\"2\" != \"2\" \\(2 != 2\\)", true },
665         { H_REQUIRE_STREQ_MSG_HEAD_NAME(1_1),
666           H_REQUIRE_STREQ_MSG_BODY_NAME(1_1),
667           "1", "1", "\"1\" != \"1\" \\(1 != 1\\): 1 does not match 1", true },
668         { H_REQUIRE_STREQ_MSG_HEAD_NAME(1_2),
669           H_REQUIRE_STREQ_MSG_BODY_NAME(1_2),
670           "1", "2", "\"1\" != \"2\" \\(1 != 2\\): 1 does not match 2", false },
671         { H_REQUIRE_STREQ_MSG_HEAD_NAME(2_1),
672           H_REQUIRE_STREQ_MSG_BODY_NAME(2_1),
673           "2", "1", "\"2\" != \"1\" \\(2 != 1\\): 2 does not match 1", false },
674         { H_REQUIRE_STREQ_MSG_HEAD_NAME(2_2),
675           H_REQUIRE_STREQ_MSG_BODY_NAME(2_2),
676           "2", "2", "\"2\" != \"2\" \\(2 != 2\\): 2 does not match 2", true },
677         { H_REQUIRE_STREQ_HEAD_NAME(vars), H_REQUIRE_STREQ_BODY_NAME(vars),
678           require_streq_var1, require_streq_var2,
679           "require_streq_var1 != require_streq_var2 \\("
680           REQUIRE_STREQ_VAR1 " != " REQUIRE_STREQ_VAR2 "\\)", false },
681         { NULL, NULL, 0, 0, "", false }
682     };
683     do_require_eq_tests(tests);
684 }
685 
686 /* ---------------------------------------------------------------------
687  * Miscellaneous test cases covering several macros.
688  * --------------------------------------------------------------------- */
689 
690 static
691 bool
692 aux_bool(const char *fmt)
693 {
694     return false;
695 }
696 
697 static
698 const char *
699 aux_str(const char *fmt)
700 {
701     return "foo";
702 }
703 
704 H_CHECK(msg, aux_bool("%d"));
705 H_REQUIRE(msg, aux_bool("%d"));
706 H_CHECK_STREQ(msg, aux_str("%d"), "");
707 H_REQUIRE_STREQ(msg, aux_str("%d"), "");
708 
709 ATF_TC(msg_embedded_fmt);
710 ATF_TC_HEAD(msg_embedded_fmt, tc)
711 {
712     atf_tc_set_md_var(tc, "descr", "Tests that format strings passed "
713                       "as part of the automatically-generated messages "
714                       "do not get expanded");
715     atf_tc_set_md_var(tc, "use.fs", "true");
716 }
717 ATF_TC_BODY(msg_embedded_fmt, tc)
718 {
719     struct test {
720         void (*head)(atf_tc_t *);
721         void (*body)(const atf_tc_t *);
722         bool fatal;
723         const char *msg;
724     } *t, tests[] = {
725        {  H_CHECK_HEAD_NAME(msg), H_CHECK_BODY_NAME(msg), false,
726           "aux_bool\\(\"%d\"\\) not met" },
727        {  H_REQUIRE_HEAD_NAME(msg), H_REQUIRE_BODY_NAME(msg), true,
728           "aux_bool\\(\"%d\"\\) not met" },
729        {  H_CHECK_STREQ_HEAD_NAME(msg), H_CHECK_STREQ_BODY_NAME(msg), false,
730           "aux_str\\(\"%d\"\\) != \"\" \\(foo != \\)" },
731        {  H_REQUIRE_STREQ_HEAD_NAME(msg), H_REQUIRE_STREQ_BODY_NAME(msg), true,
732           "aux_str\\(\"%d\"\\) != \"\" \\(foo != \\)" },
733        { NULL, NULL, false, NULL }
734     };
735 
736     for (t = &tests[0]; t->head != NULL; t++) {
737         printf("Checking with an expected '%s' message\n", t->msg);
738 
739         init_and_run_h_tc("h_check", t->head, t->body);
740 
741         if (t->fatal) {
742             bool matched =
743                 grep_file("result", "^failed: .*macros_test.c:[0-9]+: "
744                           "%s$", t->msg);
745             ATF_CHECK_MSG(matched, "couldn't find error string in result");
746         } else {
747             bool matched = grep_file("error", "Check failed: .*"
748                 "macros_test.c:[0-9]+: %s$", t->msg);
749             ATF_CHECK_MSG(matched, "couldn't find error string in output");
750         }
751     }
752 }
753 
754 /* ---------------------------------------------------------------------
755  * Tests cases for the header file.
756  * --------------------------------------------------------------------- */
757 
758 HEADER_TC(include, "atf-c/macros.h");
759 BUILD_TC(use, "macros_h_test.c",
760          "Tests that the macros provided by the atf-c/macros.h file "
761          "do not cause syntax errors when used",
762          "Build of macros_h_test.c failed; some macros in atf-c/macros.h "
763          "are broken");
764 
765 /* ---------------------------------------------------------------------
766  * Main.
767  * --------------------------------------------------------------------- */
768 
769 ATF_TP_ADD_TCS(tp)
770 {
771     ATF_TP_ADD_TC(tp, check);
772     ATF_TP_ADD_TC(tp, check_eq);
773     ATF_TP_ADD_TC(tp, check_streq);
774     ATF_TP_ADD_TC(tp, check_errno);
775 
776     ATF_TP_ADD_TC(tp, require);
777     ATF_TP_ADD_TC(tp, require_eq);
778     ATF_TP_ADD_TC(tp, require_streq);
779     ATF_TP_ADD_TC(tp, require_errno);
780 
781     ATF_TP_ADD_TC(tp, msg_embedded_fmt);
782 
783     /* Add the test cases for the header file. */
784     ATF_TP_ADD_TC(tp, include);
785     ATF_TP_ADD_TC(tp, use);
786 
787     return atf_no_error();
788 }
789