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