xref: /freebsd/contrib/atf/atf-c++/detail/test_helpers.hpp (revision c203bd70b5957f85616424b6fa374479372d06e3)
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  
70  namespace atf {
71  namespace tests {
72  class tc;
73  }
74  }
75  
76  void header_check(const char*);
77  bool build_check_cxx_o(const char*);
78  bool build_check_cxx_o_srcdir(const atf::tests::tc&, const char*);
79  atf::fs::path get_process_helpers_path(const atf::tests::tc&, bool);
80  
81  struct run_h_tc_data {
82      const atf::tests::vars_map& m_config;
83  
run_h_tc_datarun_h_tc_data84      run_h_tc_data(const atf::tests::vars_map& config) :
85          m_config(config) {}
86  };
87  
88  template< class TestCase >
89  void
run_h_tc_child(void * v)90  run_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  
100  template< class TestCase >
101  void
run_h_tc(atf::tests::vars_map config=atf::tests::vars_map ())102  run_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