116190Sdfuchs/* Copyright (c) 2008 The NetBSD Foundation, Inc. 216190Sdfuchs * All rights reserved. 316190Sdfuchs * 416190Sdfuchs * Redistribution and use in source and binary forms, with or without 516190Sdfuchs * modification, are permitted provided that the following conditions 616190Sdfuchs * are met: 716190Sdfuchs * 1. Redistributions of source code must retain the above copyright 816190Sdfuchs * notice, this list of conditions and the following disclaimer. 916190Sdfuchs * 2. Redistributions in binary form must reproduce the above copyright 1016190Sdfuchs * notice, this list of conditions and the following disclaimer in the 1116190Sdfuchs * documentation and/or other materials provided with the distribution. 1216190Sdfuchs * 1316190Sdfuchs * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND 1416190Sdfuchs * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 1516190Sdfuchs * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 1616190Sdfuchs * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 1716190Sdfuchs * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY 1816190Sdfuchs * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1916190Sdfuchs * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 2016190Sdfuchs * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2116190Sdfuchs * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 2216190Sdfuchs * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 2316190Sdfuchs * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 2416190Sdfuchs * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 2516190Sdfuchs 2616190Sdfuchs#include "atf-c/detail/sanity.h" 2716190Sdfuchs 2816190Sdfuchs#if defined(HAVE_CONFIG_H) 2916190Sdfuchs#include "config.h" 3016190Sdfuchs#endif 3116190Sdfuchs 3216190Sdfuchs#include <sys/types.h> 3316190Sdfuchs#include <sys/wait.h> 3416190Sdfuchs 3516190Sdfuchs#include <signal.h> 3616190Sdfuchs#include <stdbool.h> 3716190Sdfuchs#include <stdlib.h> 3816190Sdfuchs#include <string.h> 3916190Sdfuchs#include <unistd.h> 4016190Sdfuchs 4116190Sdfuchs#include <atf-c.h> 4216190Sdfuchs 4316190Sdfuchs#include "atf-c/detail/dynstr.h" 4416190Sdfuchs#include "atf-c/detail/process.h" 4516190Sdfuchs#include "atf-c/detail/test_helpers.h" 4616190Sdfuchs 4716190Sdfuchs/* --------------------------------------------------------------------- 4816190Sdfuchs * Auxiliary functions. 4916190Sdfuchs * --------------------------------------------------------------------- */ 5016190Sdfuchs 5116190Sdfuchsenum type { inv, pre, post, unreachable }; 5216190Sdfuchs 5316608Sdfuchsstruct test_data { 5416190Sdfuchs enum type m_type; 5516190Sdfuchs bool m_cond; 5616190Sdfuchs}; 5716190Sdfuchs 5816190Sdfuchsstatic void do_test_child(void *) ATF_DEFS_ATTRIBUTE_NORETURN; 5916608Sdfuchs 6016190Sdfuchsstatic 6116190Sdfuchsvoid 6216190Sdfuchsdo_test_child(void *v) 6316190Sdfuchs{ 6416190Sdfuchs struct test_data *td = v; 6516190Sdfuchs 6616190Sdfuchs switch (td->m_type) { 6716190Sdfuchs case inv: 6816190Sdfuchs INV(td->m_cond); 6916190Sdfuchs break; 7016190Sdfuchs 7116190Sdfuchs case pre: 7216190Sdfuchs PRE(td->m_cond); 7316190Sdfuchs break; 7416190Sdfuchs 7516190Sdfuchs case post: 7616190Sdfuchs POST(td->m_cond); 7716190Sdfuchs break; 7816190Sdfuchs 7916190Sdfuchs case unreachable: 8016190Sdfuchs if (!td->m_cond) 8116190Sdfuchs UNREACHABLE; 8216190Sdfuchs break; 8316190Sdfuchs } 8416190Sdfuchs 8516190Sdfuchs exit(EXIT_SUCCESS); 8616190Sdfuchs} 8716190Sdfuchs 8816190Sdfuchsstatic 8916190Sdfuchsvoid 9016190Sdfuchsdo_test(enum type t, bool cond) 9116190Sdfuchs{ 9216190Sdfuchs atf_process_child_t child; 9316190Sdfuchs atf_process_status_t status; 9416190Sdfuchs int nlines; 9516190Sdfuchs char *lines[3]; 9616190Sdfuchs 9716190Sdfuchs { 9816190Sdfuchs atf_process_stream_t outsb, errsb; 9916190Sdfuchs struct test_data td = { t, cond }; 10016190Sdfuchs 10116190Sdfuchs RE(atf_process_stream_init_inherit(&outsb)); 10216190Sdfuchs RE(atf_process_stream_init_capture(&errsb)); 10316190Sdfuchs RE(atf_process_fork(&child, do_test_child, &outsb, &errsb, &td)); 10416190Sdfuchs atf_process_stream_fini(&errsb); 10516190Sdfuchs atf_process_stream_fini(&outsb); 10616190Sdfuchs } 10716190Sdfuchs 10816190Sdfuchs nlines = 0; 10916190Sdfuchs while (nlines < 3 && (lines[nlines] = 11016190Sdfuchs atf_utils_readline(atf_process_child_stderr(&child))) != NULL) 11116190Sdfuchs nlines++; 11216190Sdfuchs ATF_REQUIRE(nlines == 0 || nlines == 3); 11316190Sdfuchs 11416190Sdfuchs RE(atf_process_child_wait(&child, &status)); 11516190Sdfuchs if (!cond) { 11616190Sdfuchs ATF_REQUIRE(atf_process_status_signaled(&status)); 11716190Sdfuchs ATF_REQUIRE(atf_process_status_termsig(&status) == SIGABRT); 11816190Sdfuchs } else { 11916190Sdfuchs ATF_REQUIRE(atf_process_status_exited(&status)); 12016190Sdfuchs ATF_REQUIRE(atf_process_status_exitstatus(&status) == EXIT_SUCCESS); 12116190Sdfuchs } 12216190Sdfuchs atf_process_status_fini(&status); 12316190Sdfuchs 12416190Sdfuchs if (!cond) { 12516190Sdfuchs switch (t) { 12616190Sdfuchs case inv: 12716190Sdfuchs ATF_REQUIRE(atf_utils_grep_string("Invariant", lines[0])); 12816190Sdfuchs break; 12916190Sdfuchs 13016190Sdfuchs case pre: 13116190Sdfuchs ATF_REQUIRE(atf_utils_grep_string("Precondition", lines[0])); 13216190Sdfuchs break; 13316190Sdfuchs 13416190Sdfuchs case post: 13516190Sdfuchs ATF_REQUIRE(atf_utils_grep_string("Postcondition", lines[0])); 13616190Sdfuchs break; 13716190Sdfuchs 13816190Sdfuchs case unreachable: 13916190Sdfuchs ATF_REQUIRE(atf_utils_grep_string("Invariant", lines[0])); 14016190Sdfuchs break; 14116190Sdfuchs } 14216190Sdfuchs 14316190Sdfuchs ATF_REQUIRE(atf_utils_grep_string(__FILE__, lines[0])); 14416190Sdfuchs ATF_REQUIRE(atf_utils_grep_string(PACKAGE_BUGREPORT, lines[2])); 14516190Sdfuchs } 14616190Sdfuchs 14716190Sdfuchs while (nlines > 0) { 14816190Sdfuchs nlines--; 14916190Sdfuchs free(lines[nlines]); 15016608Sdfuchs } 15116608Sdfuchs} 15216608Sdfuchs 15316608Sdfuchsstatic 15416608Sdfuchsvoid 15516608Sdfuchsrequire_ndebug(void) 15616608Sdfuchs{ 15716608Sdfuchs#if defined(NDEBUG) 15816608Sdfuchs atf_tc_skip("Sanity checks not available; code built with -DNDEBUG"); 15916608Sdfuchs#endif 16016608Sdfuchs} 16116608Sdfuchs 16216608Sdfuchs/* --------------------------------------------------------------------- 16316608Sdfuchs * Test cases for the free functions. 16416608Sdfuchs * --------------------------------------------------------------------- */ 16516608Sdfuchs 16616608SdfuchsATF_TC(inv); 16716608SdfuchsATF_TC_HEAD(inv, tc) 16816608Sdfuchs{ 16916608Sdfuchs atf_tc_set_md_var(tc, "descr", "Tests the INV macro"); 17016608Sdfuchs} 17116608SdfuchsATF_TC_BODY(inv, tc) 17216608Sdfuchs{ 17316608Sdfuchs require_ndebug(); 17416608Sdfuchs 17516608Sdfuchs do_test(inv, false); 17616608Sdfuchs do_test(inv, true); 17716608Sdfuchs} 17816608Sdfuchs 17916608SdfuchsATF_TC(pre); 18016608SdfuchsATF_TC_HEAD(pre, tc) 18116608Sdfuchs{ 18216608Sdfuchs atf_tc_set_md_var(tc, "descr", "Tests the PRE macro"); 18316608Sdfuchs} 18416608SdfuchsATF_TC_BODY(pre, tc) 18516608Sdfuchs{ 18616608Sdfuchs require_ndebug(); 18716608Sdfuchs 18816608Sdfuchs do_test(pre, false); 18916608Sdfuchs do_test(pre, true); 19016608Sdfuchs} 19116608Sdfuchs 19216608SdfuchsATF_TC(post); 19316608SdfuchsATF_TC_HEAD(post, tc) 19416608Sdfuchs{ 19516608Sdfuchs atf_tc_set_md_var(tc, "descr", "Tests the POST macro"); 19616608Sdfuchs} 19716608SdfuchsATF_TC_BODY(post, tc) 19816608Sdfuchs{ 19916608Sdfuchs require_ndebug(); 20016608Sdfuchs 20116608Sdfuchs do_test(post, false); 20216608Sdfuchs do_test(post, true); 20316190Sdfuchs} 20416190Sdfuchs 20516608SdfuchsATF_TC(unreachable); 20616608SdfuchsATF_TC_HEAD(unreachable, tc) 20716190Sdfuchs{ 20816190Sdfuchs atf_tc_set_md_var(tc, "descr", "Tests the UNREACHABLE macro"); 20916190Sdfuchs} 21016190SdfuchsATF_TC_BODY(unreachable, tc) 21116190Sdfuchs{ 21216190Sdfuchs require_ndebug(); 21316190Sdfuchs 21416190Sdfuchs do_test(unreachable, false); 21516190Sdfuchs do_test(unreachable, true); 21616190Sdfuchs} 21716190Sdfuchs 21816190Sdfuchs/* --------------------------------------------------------------------- 21916190Sdfuchs * Main. 22016190Sdfuchs * --------------------------------------------------------------------- */ 22116190Sdfuchs 22216190SdfuchsATF_TP_ADD_TCS(tp) 22316190Sdfuchs{ 22416190Sdfuchs ATF_TP_ADD_TC(tp, inv); 22516190Sdfuchs ATF_TP_ADD_TC(tp, pre); 22616190Sdfuchs ATF_TP_ADD_TC(tp, post); 22716190Sdfuchs ATF_TP_ADD_TC(tp, unreachable); 22816190Sdfuchs 22916190Sdfuchs return atf_no_error(); 23016190Sdfuchs} 23116190Sdfuchs