test_helpers.hpp revision 251108
1240116Smarcel// 2240116Smarcel// Automated Testing Framework (atf) 3240116Smarcel// 4240116Smarcel// Copyright (c) 2009 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(TESTS_ATF_ATF_CXX_TEST_HELPERS_H) 31240116Smarcel# error "Cannot include test_helpers.hpp more than once." 32240116Smarcel#else 33240116Smarcel# define TESTS_ATF_ATF_CXX_TEST_HELPERS_H 34240116Smarcel#endif 35240116Smarcel 36240116Smarcel#include <cstdlib> 37240116Smarcel#include <iostream> 38240116Smarcel#include <sstream> 39240116Smarcel#include <utility> 40240116Smarcel 41240116Smarcel#include "../macros.hpp" 42240116Smarcel#include "../tests.hpp" 43240116Smarcel#include "parser.hpp" 44240116Smarcel#include "process.hpp" 45240116Smarcel#include "text.hpp" 46240116Smarcel 47240116Smarcel#define HEADER_TC(name, hdrname) \ 48240116Smarcel ATF_TEST_CASE(name); \ 49240116Smarcel ATF_TEST_CASE_HEAD(name) \ 50240116Smarcel { \ 51240116Smarcel set_md_var("descr", "Tests that the " hdrname " file can be " \ 52240116Smarcel "included on its own, without any prerequisites"); \ 53240116Smarcel } \ 54240116Smarcel ATF_TEST_CASE_BODY(name) \ 55240116Smarcel { \ 56240116Smarcel header_check(hdrname); \ 57240116Smarcel } 58240116Smarcel 59240116Smarcel#define BUILD_TC(name, sfile, descr, failmsg) \ 60240116Smarcel ATF_TEST_CASE(name); \ 61240116Smarcel ATF_TEST_CASE_HEAD(name) \ 62240116Smarcel { \ 63240116Smarcel set_md_var("descr", descr); \ 64240116Smarcel } \ 65240116Smarcel ATF_TEST_CASE_BODY(name) \ 66240116Smarcel { \ 67240116Smarcel build_check_cxx_o(*this, sfile, failmsg, true); \ 68240116Smarcel } 69240116Smarcel 70240116Smarcel#define BUILD_TC_FAIL(name, sfile, descr, failmsg) \ 71240116Smarcel ATF_TEST_CASE(name); \ 72240116Smarcel ATF_TEST_CASE_HEAD(name) \ 73240116Smarcel { \ 74240116Smarcel set_md_var("descr", descr); \ 75240116Smarcel } \ 76240116Smarcel ATF_TEST_CASE_BODY(name) \ 77240116Smarcel { \ 78240116Smarcel build_check_cxx_o(*this, sfile, failmsg, false); \ 79240116Smarcel } 80240116Smarcel 81240116Smarcelnamespace atf { 82240116Smarcelnamespace tests { 83240116Smarcelclass tc; 84240116Smarcel} 85240116Smarcel} 86240116Smarcel 87240116Smarcelvoid header_check(const char*); 88240116Smarcelvoid build_check_cxx_o(const atf::tests::tc&, const char*, const char*, bool); 89251108Smarcelatf::fs::path get_process_helpers_path(const atf::tests::tc&, bool); 90240116Smarcelbool grep_file(const char*, const char*); 91240116Smarcelbool grep_string(const std::string&, const char*); 92240116Smarcel 93240116Smarcelstruct run_h_tc_data { 94240116Smarcel const atf::tests::vars_map& m_config; 95240116Smarcel 96240116Smarcel run_h_tc_data(const atf::tests::vars_map& config) : 97240116Smarcel m_config(config) {} 98240116Smarcel}; 99240116Smarcel 100240116Smarceltemplate< class TestCase > 101240116Smarcelvoid 102240116Smarcelrun_h_tc_child(void* v) 103240116Smarcel{ 104240116Smarcel run_h_tc_data* data = static_cast< run_h_tc_data* >(v); 105240116Smarcel 106240116Smarcel TestCase tc; 107240116Smarcel tc.init(data->m_config); 108240116Smarcel tc.run("result"); 109240116Smarcel std::exit(EXIT_SUCCESS); 110240116Smarcel} 111240116Smarcel 112240116Smarceltemplate< class TestCase > 113240116Smarcelvoid 114240116Smarcelrun_h_tc(atf::tests::vars_map config = atf::tests::vars_map()) 115240116Smarcel{ 116240116Smarcel run_h_tc_data data(config); 117240116Smarcel atf::process::child c = atf::process::fork( 118240116Smarcel run_h_tc_child< TestCase >, 119240116Smarcel atf::process::stream_redirect_path(atf::fs::path("stdout")), 120240116Smarcel atf::process::stream_redirect_path(atf::fs::path("stderr")), 121240116Smarcel &data); 122240116Smarcel const atf::process::status s = c.wait(); 123240116Smarcel ATF_REQUIRE(s.exited()); 124240116Smarcel} 125240116Smarcel 126240116Smarcelnamespace test_helpers_detail { 127240116Smarcel 128240116Smarceltypedef std::vector< std::string > string_vector; 129240116Smarcel 130240116Smarceltemplate< class Reader > 131240116Smarcelstd::pair< string_vector, string_vector > 132240116Smarceldo_read(const char* input) 133240116Smarcel{ 134240116Smarcel string_vector errors; 135240116Smarcel 136240116Smarcel std::istringstream is(input); 137240116Smarcel Reader reader(is); 138240116Smarcel try { 139240116Smarcel reader.read(); 140240116Smarcel } catch (const atf::parser::parse_errors& pes) { 141240116Smarcel for (std::vector< atf::parser::parse_error >::const_iterator iter = 142240116Smarcel pes.begin(); iter != pes.end(); iter++) 143240116Smarcel errors.push_back(*iter); 144240116Smarcel } catch (const atf::parser::parse_error& pe) { 145240116Smarcel ATF_FAIL("Raised a lonely parse error: " + 146240116Smarcel atf::text::to_string(pe.first) + ": " + pe.second); 147240116Smarcel } 148240116Smarcel 149240116Smarcel return std::make_pair(reader.m_calls, errors); 150240116Smarcel} 151240116Smarcel 152240116Smarcelvoid check_equal(const char*[], const string_vector&); 153240116Smarcel 154240116Smarcel} // namespace test_helpers_detail 155240116Smarcel 156240116Smarceltemplate< class Reader > 157240116Smarcelvoid 158240116Smarceldo_parser_test(const char* input, const char* exp_calls[], 159240116Smarcel const char* exp_errors[]) 160240116Smarcel{ 161240116Smarcel const std::pair< test_helpers_detail::string_vector, 162240116Smarcel test_helpers_detail::string_vector > 163240116Smarcel actual = test_helpers_detail::do_read< Reader >(input); 164240116Smarcel test_helpers_detail::check_equal(exp_calls, actual.first); 165240116Smarcel test_helpers_detail::check_equal(exp_errors, actual.second); 166240116Smarcel} 167