1240116Smarcel/* 2240116Smarcel * Automated Testing Framework (atf) 3240116Smarcel * 4240116Smarcel * Copyright (c) 2008 The NetBSD Foundation, Inc. 5240116Smarcel * All rights reserved. 6240116Smarcel * 7240116Smarcel * Redistribution and use in source and binary forms, with or without 8240116Smarcel * modification, are permitted provided that the following conditions 9240116Smarcel * are met: 10240116Smarcel * 1. Redistributions of source code must retain the above copyright 11240116Smarcel * notice, this list of conditions and the following disclaimer. 12240116Smarcel * 2. Redistributions in binary form must reproduce the above copyright 13240116Smarcel * notice, this list of conditions and the following disclaimer in the 14240116Smarcel * documentation and/or other materials provided with the distribution. 15240116Smarcel * 16240116Smarcel * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND 17240116Smarcel * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 18240116Smarcel * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19240116Smarcel * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20240116Smarcel * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY 21240116Smarcel * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22240116Smarcel * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 23240116Smarcel * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24240116Smarcel * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 25240116Smarcel * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 26240116Smarcel * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 27240116Smarcel * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28240116Smarcel */ 29240116Smarcel 30240116Smarcel#if defined(HAVE_CONFIG_H) 31240116Smarcel#include "bconfig.h" 32240116Smarcel#endif 33240116Smarcel 34240116Smarcel#include <sys/types.h> 35240116Smarcel#include <sys/wait.h> 36240116Smarcel 37240116Smarcel#include <signal.h> 38240116Smarcel#include <stdbool.h> 39240116Smarcel#include <stdlib.h> 40240116Smarcel#include <string.h> 41240116Smarcel#include <unistd.h> 42240116Smarcel 43240116Smarcel#include <atf-c.h> 44240116Smarcel 45240116Smarcel#include "dynstr.h" 46240116Smarcel#include "process.h" 47240116Smarcel#include "sanity.h" 48240116Smarcel#include "test_helpers.h" 49240116Smarcel 50240116Smarcel/* --------------------------------------------------------------------- 51240116Smarcel * Auxiliary functions. 52240116Smarcel * --------------------------------------------------------------------- */ 53240116Smarcel 54240116Smarcelenum type { inv, pre, post, unreachable }; 55240116Smarcel 56240116Smarcelstruct test_data { 57240116Smarcel enum type m_type; 58240116Smarcel bool m_cond; 59240116Smarcel}; 60240116Smarcel 61240116Smarcelstatic void do_test_child(void *) ATF_DEFS_ATTRIBUTE_NORETURN; 62240116Smarcel 63240116Smarcelstatic 64240116Smarcelvoid 65240116Smarceldo_test_child(void *v) 66240116Smarcel{ 67240116Smarcel struct test_data *td = v; 68240116Smarcel 69240116Smarcel switch (td->m_type) { 70240116Smarcel case inv: 71240116Smarcel INV(td->m_cond); 72240116Smarcel break; 73240116Smarcel 74240116Smarcel case pre: 75240116Smarcel PRE(td->m_cond); 76240116Smarcel break; 77240116Smarcel 78240116Smarcel case post: 79240116Smarcel POST(td->m_cond); 80240116Smarcel break; 81240116Smarcel 82240116Smarcel case unreachable: 83240116Smarcel if (!td->m_cond) 84240116Smarcel UNREACHABLE; 85240116Smarcel break; 86240116Smarcel } 87240116Smarcel 88240116Smarcel exit(EXIT_SUCCESS); 89240116Smarcel} 90240116Smarcel 91240116Smarcelstatic 92240116Smarcelvoid 93240116Smarceldo_test(enum type t, bool cond) 94240116Smarcel{ 95240116Smarcel atf_process_child_t child; 96240116Smarcel atf_process_status_t status; 97240116Smarcel int nlines; 98260029Sjmmv char *lines[3]; 99240116Smarcel 100240116Smarcel { 101240116Smarcel atf_process_stream_t outsb, errsb; 102240116Smarcel struct test_data td = { t, cond }; 103240116Smarcel 104240116Smarcel RE(atf_process_stream_init_inherit(&outsb)); 105240116Smarcel RE(atf_process_stream_init_capture(&errsb)); 106240116Smarcel RE(atf_process_fork(&child, do_test_child, &outsb, &errsb, &td)); 107240116Smarcel atf_process_stream_fini(&errsb); 108240116Smarcel atf_process_stream_fini(&outsb); 109240116Smarcel } 110240116Smarcel 111240116Smarcel nlines = 0; 112260029Sjmmv while (nlines < 3 && (lines[nlines] = 113260029Sjmmv atf_utils_readline(atf_process_child_stderr(&child))) != NULL) 114240116Smarcel nlines++; 115240116Smarcel ATF_REQUIRE(nlines == 0 || nlines == 3); 116240116Smarcel 117240116Smarcel RE(atf_process_child_wait(&child, &status)); 118240116Smarcel if (!cond) { 119240116Smarcel ATF_REQUIRE(atf_process_status_signaled(&status)); 120240116Smarcel ATF_REQUIRE(atf_process_status_termsig(&status) == SIGABRT); 121240116Smarcel } else { 122240116Smarcel ATF_REQUIRE(atf_process_status_exited(&status)); 123240116Smarcel ATF_REQUIRE(atf_process_status_exitstatus(&status) == EXIT_SUCCESS); 124240116Smarcel } 125240116Smarcel atf_process_status_fini(&status); 126240116Smarcel 127240116Smarcel if (!cond) { 128240116Smarcel switch (t) { 129240116Smarcel case inv: 130260029Sjmmv ATF_REQUIRE(atf_utils_grep_string("Invariant", lines[0])); 131240116Smarcel break; 132240116Smarcel 133240116Smarcel case pre: 134260029Sjmmv ATF_REQUIRE(atf_utils_grep_string("Precondition", lines[0])); 135240116Smarcel break; 136240116Smarcel 137240116Smarcel case post: 138260029Sjmmv ATF_REQUIRE(atf_utils_grep_string("Postcondition", lines[0])); 139240116Smarcel break; 140240116Smarcel 141240116Smarcel case unreachable: 142260029Sjmmv ATF_REQUIRE(atf_utils_grep_string("Invariant", lines[0])); 143240116Smarcel break; 144240116Smarcel } 145240116Smarcel 146260029Sjmmv ATF_REQUIRE(atf_utils_grep_string(__FILE__, lines[0])); 147260029Sjmmv ATF_REQUIRE(atf_utils_grep_string(PACKAGE_BUGREPORT, lines[2])); 148240116Smarcel } 149240116Smarcel 150240116Smarcel while (nlines > 0) { 151240116Smarcel nlines--; 152260029Sjmmv free(lines[nlines]); 153240116Smarcel } 154240116Smarcel} 155240116Smarcel 156240116Smarcelstatic 157240116Smarcelvoid 158240116Smarcelrequire_ndebug(void) 159240116Smarcel{ 160240116Smarcel#if defined(NDEBUG) 161240116Smarcel atf_tc_skip("Sanity checks not available; code built with -DNDEBUG"); 162240116Smarcel#endif 163240116Smarcel} 164240116Smarcel 165240116Smarcel/* --------------------------------------------------------------------- 166240116Smarcel * Test cases for the free functions. 167240116Smarcel * --------------------------------------------------------------------- */ 168240116Smarcel 169240116SmarcelATF_TC(inv); 170240116SmarcelATF_TC_HEAD(inv, tc) 171240116Smarcel{ 172240116Smarcel atf_tc_set_md_var(tc, "descr", "Tests the INV macro"); 173240116Smarcel} 174240116SmarcelATF_TC_BODY(inv, tc) 175240116Smarcel{ 176240116Smarcel require_ndebug(); 177240116Smarcel 178240116Smarcel do_test(inv, false); 179240116Smarcel do_test(inv, true); 180240116Smarcel} 181240116Smarcel 182240116SmarcelATF_TC(pre); 183240116SmarcelATF_TC_HEAD(pre, tc) 184240116Smarcel{ 185240116Smarcel atf_tc_set_md_var(tc, "descr", "Tests the PRE macro"); 186240116Smarcel} 187240116SmarcelATF_TC_BODY(pre, tc) 188240116Smarcel{ 189240116Smarcel require_ndebug(); 190240116Smarcel 191240116Smarcel do_test(pre, false); 192240116Smarcel do_test(pre, true); 193240116Smarcel} 194240116Smarcel 195240116SmarcelATF_TC(post); 196240116SmarcelATF_TC_HEAD(post, tc) 197240116Smarcel{ 198240116Smarcel atf_tc_set_md_var(tc, "descr", "Tests the POST macro"); 199240116Smarcel} 200240116SmarcelATF_TC_BODY(post, tc) 201240116Smarcel{ 202240116Smarcel require_ndebug(); 203240116Smarcel 204240116Smarcel do_test(post, false); 205240116Smarcel do_test(post, true); 206240116Smarcel} 207240116Smarcel 208240116SmarcelATF_TC(unreachable); 209240116SmarcelATF_TC_HEAD(unreachable, tc) 210240116Smarcel{ 211240116Smarcel atf_tc_set_md_var(tc, "descr", "Tests the UNREACHABLE macro"); 212240116Smarcel} 213240116SmarcelATF_TC_BODY(unreachable, tc) 214240116Smarcel{ 215240116Smarcel require_ndebug(); 216240116Smarcel 217240116Smarcel do_test(unreachable, false); 218240116Smarcel do_test(unreachable, true); 219240116Smarcel} 220240116Smarcel 221240116Smarcel/* --------------------------------------------------------------------- 222240116Smarcel * Main. 223240116Smarcel * --------------------------------------------------------------------- */ 224240116Smarcel 225240116SmarcelATF_TP_ADD_TCS(tp) 226240116Smarcel{ 227240116Smarcel ATF_TP_ADD_TC(tp, inv); 228240116Smarcel ATF_TP_ADD_TC(tp, pre); 229240116Smarcel ATF_TP_ADD_TC(tp, post); 230240116Smarcel ATF_TP_ADD_TC(tp, unreachable); 231240116Smarcel 232240116Smarcel return atf_no_error(); 233240116Smarcel} 234