1/*
2 * Automated Testing Framework (atf)
3 *
4 * Copyright (c) 2008, 2009, 2010 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
17 * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
18 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
23 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30#include <sys/types.h>
31#include <sys/wait.h>
32
33#include <errno.h>
34#include <fcntl.h>
35#include <stdarg.h>
36#include <stdbool.h>
37#include <stdio.h>
38#include <stdlib.h>
39#include <string.h>
40#include <unistd.h>
41
42#include <atf-c.h>
43
44#include "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
53static
54void
55create_ctl_file(const atf_tc_t *tc, 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
65static
66bool
67exists(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
79static
80void
81init_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(tc, "before"); \
104        macro; \
105        create_ctl_file(tc, "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
190static int
191errno_fail_stub(const int raised_errno)
192{
193    errno = raised_errno;
194    return -1;
195}
196
197static int
198errno_ok_stub(void)
199{
200    return 0;
201}
202
203H_CHECK_ERRNO(no_error, -1, errno_ok_stub() == -1);
204H_CHECK_ERRNO(errno_ok, 2, errno_fail_stub(2) == -1);
205H_CHECK_ERRNO(errno_fail, 3, errno_fail_stub(4) == -1);
206
207H_REQUIRE_ERRNO(no_error, -1, errno_ok_stub() == -1);
208H_REQUIRE_ERRNO(errno_ok, 2, errno_fail_stub(2) == -1);
209H_REQUIRE_ERRNO(errno_fail, 3, errno_fail_stub(4) == -1);
210
211ATF_TC(check_errno);
212ATF_TC_HEAD(check_errno, tc)
213{
214    atf_tc_set_md_var(tc, "descr", "Tests the ATF_CHECK_ERRNO macro");
215}
216ATF_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
255ATF_TC(require_errno);
256ATF_TC_HEAD(require_errno, tc)
257{
258    atf_tc_set_md_var(tc, "descr", "Tests the ATF_REQUIRE_ERRNO macro");
259}
260ATF_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
303H_CHECK(0, 0);
304H_CHECK(1, 1);
305H_CHECK_MSG(0, 0, "expected a false value");
306H_CHECK_MSG(1, 1, "expected a true value");
307
308ATF_TC(check);
309ATF_TC_HEAD(check, tc)
310{
311    atf_tc_set_md_var(tc, "descr", "Tests the ATF_CHECK and "
312                      "ATF_CHECK_MSG macros");
313}
314ATF_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
359struct 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
368static
369void
370do_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
396H_CHECK_EQ(1_1, 1, 1);
397H_CHECK_EQ(1_2, 1, 2);
398H_CHECK_EQ(2_1, 2, 1);
399H_CHECK_EQ(2_2, 2, 2);
400H_CHECK_EQ_MSG(1_1, 1, 1, "1 does not match 1");
401H_CHECK_EQ_MSG(1_2, 1, 2, "1 does not match 2");
402H_CHECK_EQ_MSG(2_1, 2, 1, "2 does not match 1");
403H_CHECK_EQ_MSG(2_2, 2, 2, "2 does not match 2");
404
405ATF_TC(check_eq);
406ATF_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}
411ATF_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
435H_CHECK_STREQ(1_1, "1", "1");
436H_CHECK_STREQ(1_2, "1", "2");
437H_CHECK_STREQ(2_1, "2", "1");
438H_CHECK_STREQ(2_2, "2", "2");
439H_CHECK_STREQ_MSG(1_1, "1", "1", "1 does not match 1");
440H_CHECK_STREQ_MSG(1_2, "1", "2", "1 does not match 2");
441H_CHECK_STREQ_MSG(2_1, "2", "1", "2 does not match 1");
442H_CHECK_STREQ_MSG(2_2, "2", "2", "2 does not match 2");
443#define CHECK_STREQ_VAR1 "5"
444#define CHECK_STREQ_VAR2 "9"
445const const char *check_streq_var1 = CHECK_STREQ_VAR1;
446const const char *check_streq_var2 = CHECK_STREQ_VAR2;
447H_CHECK_STREQ(vars, check_streq_var1, check_streq_var2);
448
449ATF_TC(check_streq);
450ATF_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}
455ATF_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
491H_REQUIRE(0, 0);
492H_REQUIRE(1, 1);
493H_REQUIRE_MSG(0, 0, "expected a false value");
494H_REQUIRE_MSG(1, 1, "expected a true value");
495
496ATF_TC(require);
497ATF_TC_HEAD(require, tc)
498{
499    atf_tc_set_md_var(tc, "descr", "Tests the ATF_REQUIRE and "
500                      "ATF_REQUIRE_MSG macros");
501}
502ATF_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
547struct 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
556static
557void
558do_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
584H_REQUIRE_EQ(1_1, 1, 1);
585H_REQUIRE_EQ(1_2, 1, 2);
586H_REQUIRE_EQ(2_1, 2, 1);
587H_REQUIRE_EQ(2_2, 2, 2);
588H_REQUIRE_EQ_MSG(1_1, 1, 1, "1 does not match 1");
589H_REQUIRE_EQ_MSG(1_2, 1, 2, "1 does not match 2");
590H_REQUIRE_EQ_MSG(2_1, 2, 1, "2 does not match 1");
591H_REQUIRE_EQ_MSG(2_2, 2, 2, "2 does not match 2");
592
593ATF_TC(require_eq);
594ATF_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}
599ATF_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
623H_REQUIRE_STREQ(1_1, "1", "1");
624H_REQUIRE_STREQ(1_2, "1", "2");
625H_REQUIRE_STREQ(2_1, "2", "1");
626H_REQUIRE_STREQ(2_2, "2", "2");
627H_REQUIRE_STREQ_MSG(1_1, "1", "1", "1 does not match 1");
628H_REQUIRE_STREQ_MSG(1_2, "1", "2", "1 does not match 2");
629H_REQUIRE_STREQ_MSG(2_1, "2", "1", "2 does not match 1");
630H_REQUIRE_STREQ_MSG(2_2, "2", "2", "2 does not match 2");
631#define REQUIRE_STREQ_VAR1 "5"
632#define REQUIRE_STREQ_VAR2 "9"
633const const char *require_streq_var1 = REQUIRE_STREQ_VAR1;
634const const char *require_streq_var2 = REQUIRE_STREQ_VAR2;
635H_REQUIRE_STREQ(vars, require_streq_var1, require_streq_var2);
636
637ATF_TC(require_streq);
638ATF_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}
643ATF_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
679static
680bool
681aux_bool(const char *fmt)
682{
683    return false;
684}
685
686static
687const char *
688aux_str(const char *fmt)
689{
690    return "foo";
691}
692
693H_CHECK(msg, aux_bool("%d"));
694H_REQUIRE(msg, aux_bool("%d"));
695H_CHECK_STREQ(msg, aux_str("%d"), "");
696H_REQUIRE_STREQ(msg, aux_str("%d"), "");
697
698ATF_TC(msg_embedded_fmt);
699ATF_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}
705ATF_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
746HEADER_TC(include, "atf-c/macros.h");
747BUILD_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
753/* ---------------------------------------------------------------------
754 * Main.
755 * --------------------------------------------------------------------- */
756
757ATF_TP_ADD_TCS(tp)
758{
759    ATF_TP_ADD_TC(tp, check);
760    ATF_TP_ADD_TC(tp, check_eq);
761    ATF_TP_ADD_TC(tp, check_streq);
762    ATF_TP_ADD_TC(tp, check_errno);
763
764    ATF_TP_ADD_TC(tp, require);
765    ATF_TP_ADD_TC(tp, require_eq);
766    ATF_TP_ADD_TC(tp, require_streq);
767    ATF_TP_ADD_TC(tp, require_errno);
768
769    ATF_TP_ADD_TC(tp, msg_embedded_fmt);
770
771    /* Add the test cases for the header file. */
772    ATF_TP_ADD_TC(tp, include);
773    ATF_TP_ADD_TC(tp, use);
774
775    return atf_no_error();
776}
777