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