1// Copyright (c) 2009 The NetBSD Foundation, Inc.
2// All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without
5// modification, are permitted provided that the following conditions
6// are met:
7// 1. Redistributions of source code must retain the above copyright
8//    notice, this list of conditions and the following disclaimer.
9// 2. Redistributions in binary form must reproduce the above copyright
10//    notice, this list of conditions and the following disclaimer in the
11//    documentation and/or other materials provided with the distribution.
12//
13// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
14// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
15// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
18// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
20// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
22// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
24// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
26#if defined(ATF_CXX_DETAIL_TEST_HELPERS_H)
27#   error "Cannot include test_helpers.hpp more than once."
28#else
29#   define ATF_CXX_DETAIL_TEST_HELPERS_H
30#endif
31
32#include <cstdlib>
33#include <iostream>
34#include <sstream>
35#include <utility>
36
37#include <atf-c++.hpp>
38
39#include <atf-c++/detail/env.hpp>
40#include <atf-c++/detail/process.hpp>
41
42#define HEADER_TC(name, hdrname) \
43    ATF_TEST_CASE(name); \
44    ATF_TEST_CASE_HEAD(name) \
45    { \
46        set_md_var("descr", "Tests that the " hdrname " file can be " \
47            "included on its own, without any prerequisites"); \
48        const std::string cxx = atf::env::get("ATF_BUILD_CXX", ATF_BUILD_CXX); \
49        set_md_var("require.progs", cxx); \
50    } \
51    ATF_TEST_CASE_BODY(name) \
52    { \
53        header_check(hdrname); \
54    }
55
56#define BUILD_TC(name, sfile, descr, failmsg) \
57    ATF_TEST_CASE(name); \
58    ATF_TEST_CASE_HEAD(name) \
59    { \
60        set_md_var("descr", descr); \
61        const std::string cxx = atf::env::get("ATF_BUILD_CXX", ATF_BUILD_CXX); \
62        set_md_var("require.progs", cxx); \
63    } \
64    ATF_TEST_CASE_BODY(name) \
65    { \
66        if (!build_check_cxx_o_srcdir(*this, sfile)) \
67            ATF_FAIL(failmsg); \
68    }
69
70namespace atf {
71namespace tests {
72class tc;
73}
74}
75
76void header_check(const char*);
77bool build_check_cxx_o(const char*);
78bool build_check_cxx_o_srcdir(const atf::tests::tc&, const char*);
79atf::fs::path get_process_helpers_path(const atf::tests::tc&, bool);
80
81struct run_h_tc_data {
82    const atf::tests::vars_map& m_config;
83
84    run_h_tc_data(const atf::tests::vars_map& config) :
85        m_config(config) {}
86};
87
88template< class TestCase >
89void
90run_h_tc_child(void* v)
91{
92    run_h_tc_data* data = static_cast< run_h_tc_data* >(v);
93
94    TestCase tc;
95    tc.init(data->m_config);
96    tc.run("result");
97    std::exit(EXIT_SUCCESS);
98}
99
100template< class TestCase >
101void
102run_h_tc(atf::tests::vars_map config = atf::tests::vars_map())
103{
104    run_h_tc_data data(config);
105    atf::process::child c = atf::process::fork(
106        run_h_tc_child< TestCase >,
107        atf::process::stream_redirect_path(atf::fs::path("stdout")),
108        atf::process::stream_redirect_path(atf::fs::path("stderr")),
109        &data);
110    const atf::process::status s = c.wait();
111    ATF_REQUIRE(s.exited());
112}
113