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