1*00b67f09SDavid van Moolenbroek /* $NetBSD: sanity_test.c,v 1.3 2014/12/10 04:38:03 christos Exp $ */
2*00b67f09SDavid van Moolenbroek
3*00b67f09SDavid van Moolenbroek /*
4*00b67f09SDavid van Moolenbroek * Automated Testing Framework (atf)
5*00b67f09SDavid van Moolenbroek *
6*00b67f09SDavid van Moolenbroek * Copyright (c) 2008 The NetBSD Foundation, Inc.
7*00b67f09SDavid van Moolenbroek * All rights reserved.
8*00b67f09SDavid van Moolenbroek *
9*00b67f09SDavid van Moolenbroek * Redistribution and use in source and binary forms, with or without
10*00b67f09SDavid van Moolenbroek * modification, are permitted provided that the following conditions
11*00b67f09SDavid van Moolenbroek * are met:
12*00b67f09SDavid van Moolenbroek * 1. Redistributions of source code must retain the above copyright
13*00b67f09SDavid van Moolenbroek * notice, this list of conditions and the following disclaimer.
14*00b67f09SDavid van Moolenbroek * 2. Redistributions in binary form must reproduce the above copyright
15*00b67f09SDavid van Moolenbroek * notice, this list of conditions and the following disclaimer in the
16*00b67f09SDavid van Moolenbroek * documentation and/or other materials provided with the distribution.
17*00b67f09SDavid van Moolenbroek *
18*00b67f09SDavid van Moolenbroek * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
19*00b67f09SDavid van Moolenbroek * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
20*00b67f09SDavid van Moolenbroek * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21*00b67f09SDavid van Moolenbroek * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22*00b67f09SDavid van Moolenbroek * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
23*00b67f09SDavid van Moolenbroek * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24*00b67f09SDavid van Moolenbroek * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
25*00b67f09SDavid van Moolenbroek * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26*00b67f09SDavid van Moolenbroek * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
27*00b67f09SDavid van Moolenbroek * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28*00b67f09SDavid van Moolenbroek * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
29*00b67f09SDavid van Moolenbroek * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30*00b67f09SDavid van Moolenbroek */
31*00b67f09SDavid van Moolenbroek
32*00b67f09SDavid van Moolenbroek #if defined(HAVE_CONFIG_H)
33*00b67f09SDavid van Moolenbroek #include "bconfig.h"
34*00b67f09SDavid van Moolenbroek #endif
35*00b67f09SDavid van Moolenbroek
36*00b67f09SDavid van Moolenbroek #include <sys/types.h>
37*00b67f09SDavid van Moolenbroek #include <sys/wait.h>
38*00b67f09SDavid van Moolenbroek
39*00b67f09SDavid van Moolenbroek #include <signal.h>
40*00b67f09SDavid van Moolenbroek #include <stdbool.h>
41*00b67f09SDavid van Moolenbroek #include <stdlib.h>
42*00b67f09SDavid van Moolenbroek #include <string.h>
43*00b67f09SDavid van Moolenbroek #include <unistd.h>
44*00b67f09SDavid van Moolenbroek
45*00b67f09SDavid van Moolenbroek #include <atf-c.h>
46*00b67f09SDavid van Moolenbroek
47*00b67f09SDavid van Moolenbroek #include "dynstr.h"
48*00b67f09SDavid van Moolenbroek #include "process.h"
49*00b67f09SDavid van Moolenbroek #include "sanity.h"
50*00b67f09SDavid van Moolenbroek #include "test_helpers.h"
51*00b67f09SDavid van Moolenbroek
52*00b67f09SDavid van Moolenbroek /* ---------------------------------------------------------------------
53*00b67f09SDavid van Moolenbroek * Auxiliary functions.
54*00b67f09SDavid van Moolenbroek * --------------------------------------------------------------------- */
55*00b67f09SDavid van Moolenbroek
56*00b67f09SDavid van Moolenbroek enum type { inv, pre, post, unreachable };
57*00b67f09SDavid van Moolenbroek
58*00b67f09SDavid van Moolenbroek struct test_data {
59*00b67f09SDavid van Moolenbroek enum type m_type;
60*00b67f09SDavid van Moolenbroek bool m_cond;
61*00b67f09SDavid van Moolenbroek };
62*00b67f09SDavid van Moolenbroek
63*00b67f09SDavid van Moolenbroek static void do_test_child(void *) ATF_DEFS_ATTRIBUTE_NORETURN;
64*00b67f09SDavid van Moolenbroek
65*00b67f09SDavid van Moolenbroek static
66*00b67f09SDavid van Moolenbroek void
do_test_child(void * v)67*00b67f09SDavid van Moolenbroek do_test_child(void *v)
68*00b67f09SDavid van Moolenbroek {
69*00b67f09SDavid van Moolenbroek struct test_data *td = v;
70*00b67f09SDavid van Moolenbroek
71*00b67f09SDavid van Moolenbroek switch (td->m_type) {
72*00b67f09SDavid van Moolenbroek case inv:
73*00b67f09SDavid van Moolenbroek INV(td->m_cond);
74*00b67f09SDavid van Moolenbroek break;
75*00b67f09SDavid van Moolenbroek
76*00b67f09SDavid van Moolenbroek case pre:
77*00b67f09SDavid van Moolenbroek PRE(td->m_cond);
78*00b67f09SDavid van Moolenbroek break;
79*00b67f09SDavid van Moolenbroek
80*00b67f09SDavid van Moolenbroek case post:
81*00b67f09SDavid van Moolenbroek POST(td->m_cond);
82*00b67f09SDavid van Moolenbroek break;
83*00b67f09SDavid van Moolenbroek
84*00b67f09SDavid van Moolenbroek case unreachable:
85*00b67f09SDavid van Moolenbroek if (!td->m_cond)
86*00b67f09SDavid van Moolenbroek UNREACHABLE;
87*00b67f09SDavid van Moolenbroek break;
88*00b67f09SDavid van Moolenbroek }
89*00b67f09SDavid van Moolenbroek
90*00b67f09SDavid van Moolenbroek exit(EXIT_SUCCESS);
91*00b67f09SDavid van Moolenbroek }
92*00b67f09SDavid van Moolenbroek
93*00b67f09SDavid van Moolenbroek static
94*00b67f09SDavid van Moolenbroek void
do_test(enum type t,bool cond)95*00b67f09SDavid van Moolenbroek do_test(enum type t, bool cond)
96*00b67f09SDavid van Moolenbroek {
97*00b67f09SDavid van Moolenbroek atf_process_child_t child;
98*00b67f09SDavid van Moolenbroek atf_process_status_t status;
99*00b67f09SDavid van Moolenbroek int nlines;
100*00b67f09SDavid van Moolenbroek char *lines[3];
101*00b67f09SDavid van Moolenbroek
102*00b67f09SDavid van Moolenbroek {
103*00b67f09SDavid van Moolenbroek atf_process_stream_t outsb, errsb;
104*00b67f09SDavid van Moolenbroek struct test_data td = { t, cond };
105*00b67f09SDavid van Moolenbroek
106*00b67f09SDavid van Moolenbroek RE(atf_process_stream_init_inherit(&outsb));
107*00b67f09SDavid van Moolenbroek RE(atf_process_stream_init_capture(&errsb));
108*00b67f09SDavid van Moolenbroek RE(atf_process_fork(&child, do_test_child, &outsb, &errsb, &td));
109*00b67f09SDavid van Moolenbroek atf_process_stream_fini(&errsb);
110*00b67f09SDavid van Moolenbroek atf_process_stream_fini(&outsb);
111*00b67f09SDavid van Moolenbroek }
112*00b67f09SDavid van Moolenbroek
113*00b67f09SDavid van Moolenbroek nlines = 0;
114*00b67f09SDavid van Moolenbroek while (nlines < 3 && (lines[nlines] =
115*00b67f09SDavid van Moolenbroek atf_utils_readline(atf_process_child_stderr(&child))) != NULL)
116*00b67f09SDavid van Moolenbroek nlines++;
117*00b67f09SDavid van Moolenbroek ATF_REQUIRE(nlines == 0 || nlines == 3);
118*00b67f09SDavid van Moolenbroek
119*00b67f09SDavid van Moolenbroek RE(atf_process_child_wait(&child, &status));
120*00b67f09SDavid van Moolenbroek if (!cond) {
121*00b67f09SDavid van Moolenbroek ATF_REQUIRE(atf_process_status_signaled(&status));
122*00b67f09SDavid van Moolenbroek ATF_REQUIRE(atf_process_status_termsig(&status) == SIGABRT);
123*00b67f09SDavid van Moolenbroek } else {
124*00b67f09SDavid van Moolenbroek ATF_REQUIRE(atf_process_status_exited(&status));
125*00b67f09SDavid van Moolenbroek ATF_REQUIRE(atf_process_status_exitstatus(&status) == EXIT_SUCCESS);
126*00b67f09SDavid van Moolenbroek }
127*00b67f09SDavid van Moolenbroek atf_process_status_fini(&status);
128*00b67f09SDavid van Moolenbroek
129*00b67f09SDavid van Moolenbroek if (!cond) {
130*00b67f09SDavid van Moolenbroek switch (t) {
131*00b67f09SDavid van Moolenbroek case inv:
132*00b67f09SDavid van Moolenbroek ATF_REQUIRE(atf_utils_grep_string("Invariant", lines[0]));
133*00b67f09SDavid van Moolenbroek break;
134*00b67f09SDavid van Moolenbroek
135*00b67f09SDavid van Moolenbroek case pre:
136*00b67f09SDavid van Moolenbroek ATF_REQUIRE(atf_utils_grep_string("Precondition", lines[0]));
137*00b67f09SDavid van Moolenbroek break;
138*00b67f09SDavid van Moolenbroek
139*00b67f09SDavid van Moolenbroek case post:
140*00b67f09SDavid van Moolenbroek ATF_REQUIRE(atf_utils_grep_string("Postcondition", lines[0]));
141*00b67f09SDavid van Moolenbroek break;
142*00b67f09SDavid van Moolenbroek
143*00b67f09SDavid van Moolenbroek case unreachable:
144*00b67f09SDavid van Moolenbroek ATF_REQUIRE(atf_utils_grep_string("Invariant", lines[0]));
145*00b67f09SDavid van Moolenbroek break;
146*00b67f09SDavid van Moolenbroek }
147*00b67f09SDavid van Moolenbroek
148*00b67f09SDavid van Moolenbroek ATF_REQUIRE(atf_utils_grep_string(__FILE__, lines[0]));
149*00b67f09SDavid van Moolenbroek ATF_REQUIRE(atf_utils_grep_string(PACKAGE_BUGREPORT, lines[2]));
150*00b67f09SDavid van Moolenbroek }
151*00b67f09SDavid van Moolenbroek
152*00b67f09SDavid van Moolenbroek while (nlines > 0) {
153*00b67f09SDavid van Moolenbroek nlines--;
154*00b67f09SDavid van Moolenbroek free(lines[nlines]);
155*00b67f09SDavid van Moolenbroek }
156*00b67f09SDavid van Moolenbroek }
157*00b67f09SDavid van Moolenbroek
158*00b67f09SDavid van Moolenbroek static
159*00b67f09SDavid van Moolenbroek void
require_ndebug(void)160*00b67f09SDavid van Moolenbroek require_ndebug(void)
161*00b67f09SDavid van Moolenbroek {
162*00b67f09SDavid van Moolenbroek #if defined(NDEBUG)
163*00b67f09SDavid van Moolenbroek atf_tc_skip("Sanity checks not available; code built with -DNDEBUG");
164*00b67f09SDavid van Moolenbroek #endif
165*00b67f09SDavid van Moolenbroek }
166*00b67f09SDavid van Moolenbroek
167*00b67f09SDavid van Moolenbroek /* ---------------------------------------------------------------------
168*00b67f09SDavid van Moolenbroek * Test cases for the free functions.
169*00b67f09SDavid van Moolenbroek * --------------------------------------------------------------------- */
170*00b67f09SDavid van Moolenbroek
171*00b67f09SDavid van Moolenbroek ATF_TC(inv);
ATF_TC_HEAD(inv,tc)172*00b67f09SDavid van Moolenbroek ATF_TC_HEAD(inv, tc)
173*00b67f09SDavid van Moolenbroek {
174*00b67f09SDavid van Moolenbroek atf_tc_set_md_var(tc, "descr", "Tests the INV macro");
175*00b67f09SDavid van Moolenbroek }
ATF_TC_BODY(inv,tc)176*00b67f09SDavid van Moolenbroek ATF_TC_BODY(inv, tc)
177*00b67f09SDavid van Moolenbroek {
178*00b67f09SDavid van Moolenbroek require_ndebug();
179*00b67f09SDavid van Moolenbroek
180*00b67f09SDavid van Moolenbroek do_test(inv, false);
181*00b67f09SDavid van Moolenbroek do_test(inv, true);
182*00b67f09SDavid van Moolenbroek }
183*00b67f09SDavid van Moolenbroek
184*00b67f09SDavid van Moolenbroek ATF_TC(pre);
ATF_TC_HEAD(pre,tc)185*00b67f09SDavid van Moolenbroek ATF_TC_HEAD(pre, tc)
186*00b67f09SDavid van Moolenbroek {
187*00b67f09SDavid van Moolenbroek atf_tc_set_md_var(tc, "descr", "Tests the PRE macro");
188*00b67f09SDavid van Moolenbroek }
ATF_TC_BODY(pre,tc)189*00b67f09SDavid van Moolenbroek ATF_TC_BODY(pre, tc)
190*00b67f09SDavid van Moolenbroek {
191*00b67f09SDavid van Moolenbroek require_ndebug();
192*00b67f09SDavid van Moolenbroek
193*00b67f09SDavid van Moolenbroek do_test(pre, false);
194*00b67f09SDavid van Moolenbroek do_test(pre, true);
195*00b67f09SDavid van Moolenbroek }
196*00b67f09SDavid van Moolenbroek
197*00b67f09SDavid van Moolenbroek ATF_TC(post);
ATF_TC_HEAD(post,tc)198*00b67f09SDavid van Moolenbroek ATF_TC_HEAD(post, tc)
199*00b67f09SDavid van Moolenbroek {
200*00b67f09SDavid van Moolenbroek atf_tc_set_md_var(tc, "descr", "Tests the POST macro");
201*00b67f09SDavid van Moolenbroek }
ATF_TC_BODY(post,tc)202*00b67f09SDavid van Moolenbroek ATF_TC_BODY(post, tc)
203*00b67f09SDavid van Moolenbroek {
204*00b67f09SDavid van Moolenbroek require_ndebug();
205*00b67f09SDavid van Moolenbroek
206*00b67f09SDavid van Moolenbroek do_test(post, false);
207*00b67f09SDavid van Moolenbroek do_test(post, true);
208*00b67f09SDavid van Moolenbroek }
209*00b67f09SDavid van Moolenbroek
210*00b67f09SDavid van Moolenbroek ATF_TC(unreachable);
ATF_TC_HEAD(unreachable,tc)211*00b67f09SDavid van Moolenbroek ATF_TC_HEAD(unreachable, tc)
212*00b67f09SDavid van Moolenbroek {
213*00b67f09SDavid van Moolenbroek atf_tc_set_md_var(tc, "descr", "Tests the UNREACHABLE macro");
214*00b67f09SDavid van Moolenbroek }
ATF_TC_BODY(unreachable,tc)215*00b67f09SDavid van Moolenbroek ATF_TC_BODY(unreachable, tc)
216*00b67f09SDavid van Moolenbroek {
217*00b67f09SDavid van Moolenbroek require_ndebug();
218*00b67f09SDavid van Moolenbroek
219*00b67f09SDavid van Moolenbroek do_test(unreachable, false);
220*00b67f09SDavid van Moolenbroek do_test(unreachable, true);
221*00b67f09SDavid van Moolenbroek }
222*00b67f09SDavid van Moolenbroek
223*00b67f09SDavid van Moolenbroek /* ---------------------------------------------------------------------
224*00b67f09SDavid van Moolenbroek * Main.
225*00b67f09SDavid van Moolenbroek * --------------------------------------------------------------------- */
226*00b67f09SDavid van Moolenbroek
ATF_TP_ADD_TCS(tp)227*00b67f09SDavid van Moolenbroek ATF_TP_ADD_TCS(tp)
228*00b67f09SDavid van Moolenbroek {
229*00b67f09SDavid van Moolenbroek ATF_TP_ADD_TC(tp, inv);
230*00b67f09SDavid van Moolenbroek ATF_TP_ADD_TC(tp, pre);
231*00b67f09SDavid van Moolenbroek ATF_TP_ADD_TC(tp, post);
232*00b67f09SDavid van Moolenbroek ATF_TP_ADD_TC(tp, unreachable);
233*00b67f09SDavid van Moolenbroek
234*00b67f09SDavid van Moolenbroek return atf_no_error();
235*00b67f09SDavid van Moolenbroek }
236