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