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