process-cpp  3.0.0
A simple convenience library for handling processes in C++11.
fork_and_run_test.cpp
Go to the documentation of this file.
1 /*
2  * Copyright © 2013 Canonical Ltd.
3  *
4  * This program is free software: you can redistribute it and/or modify it
5  * under the terms of the GNU Lesser General Public License version 3,
6  * as published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU Lesser General Public License for more details.
12  *
13  * You should have received a copy of the GNU Lesser General Public License
14  * along with this program. If not, see <http://www.gnu.org/licenses/>.
15  *
16  * Authored by: Thomas Voß <thomas.voss@canonical.com>
17  */
18 
20 
21 #include <core/posix/signal.h>
22 
23 #include <gtest/gtest.h>
24 
25 namespace
26 {
27 struct TestingMacrosFixture : public ::testing::Test
28 {
29  TestingMacrosFixture() = default;
30 };
31 
32 ::testing::AssertionResult ClientFailed(core::testing::ForkAndRunResult result)
33 {
34  return
36  ::testing::AssertionFailure() :
37  ::testing::AssertionSuccess();
38 }
39 
40 ::testing::AssertionResult ServiceFailed(core::testing::ForkAndRunResult result)
41 {
42  return
44  ::testing::AssertionFailure() :
45  ::testing::AssertionSuccess();
46 }
47 struct SigTermCatcher
48 {
49  static void sig_term_handler(int)
50  {
51  std::cout << "Received sigterm." << std::endl;
52  }
53 
54  SigTermCatcher()
55  {
56  signal(static_cast<int>(core::posix::Signal::sig_term), sig_term_handler);
57  }
58 } sig_term_catcher;
59 }
60 
61 TEST(ForkAndRun, succeeding_client_and_service_result_in_correct_return_value)
62 {
63  auto service = [](){ return core::posix::exit::Status::success; };
64  auto client = [](){ return core::posix::exit::Status::success; };
65 
66  auto result = core::testing::fork_and_run(service, client);
67 
68  ASSERT_FALSE(ClientFailed(result));
69  ASSERT_FALSE(ServiceFailed(result));
70 }
71 
72 TEST(ForkAndRun, succeeding_client_and_failing_service_result_in_correct_return_value)
73 {
74  auto service = [](){ return core::posix::exit::Status::failure; };
75  auto client = [](){ return core::posix::exit::Status::success; };
76 
77  auto result = core::testing::fork_and_run(service, client);
78 
79  EXPECT_FALSE(ClientFailed(result));
80  EXPECT_TRUE(ServiceFailed(result));
81 }
82 
83 TEST(ForkAndRun, failing_client_and_failing_service_result_in_correct_return_value)
84 {
85  auto service = [](){ return core::posix::exit::Status::failure; };
86  auto client = [](){ return core::posix::exit::Status::failure; };
87 
88  auto result = core::testing::fork_and_run(service, client);
89 
90  EXPECT_TRUE(ClientFailed(result));
91  EXPECT_TRUE(ServiceFailed(result));
92 }
93 
94 TEST(ForkAndRun, throwing_client_is_reported_as_failing)
95 {
96  auto service = [](){ return core::posix::exit::Status::success; };
97  auto client = [](){ throw std::runtime_error("failing client"); return core::posix::exit::Status::success; };
98 
99  auto result = core::testing::fork_and_run(service, client);
100 
101  EXPECT_TRUE(ClientFailed(result));
102  EXPECT_FALSE(ServiceFailed(result));
103 }
104 
105 TEST(ForkAndRun, exiting_with_failure_client_is_reported_as_failing)
106 {
107  auto service = [](){ return core::posix::exit::Status::success; };
108  auto client = [](){ exit(EXIT_FAILURE); return core::posix::exit::Status::success; };
109 
110  auto result = core::testing::fork_and_run(service, client);
111 
112  EXPECT_TRUE(ClientFailed(result));
113  EXPECT_FALSE(ServiceFailed(result));
114 }
115 
116 TEST(ForkAndRun, aborting_client_is_reported_as_failing)
117 {
118  auto service = [](){ return core::posix::exit::Status::success; };
119  auto client = [](){ abort(); return core::posix::exit::Status::success; };
120 
121  auto result = core::testing::fork_and_run(service, client);
122 
123  EXPECT_TRUE(ClientFailed(result));
124  EXPECT_FALSE(ServiceFailed(result));
125 }
126 
128  {
130  })
131 
133  {
135  })
136 
137 // The following two tests fail, and rightly so. However, translating this
138 // failing behavior to success is really difficult and we omit it for now.
140  {
142  })
143 
145  {
147  })
148 
149 #include <core/posix/backtrace.h>
150 
151 TEST(BacktraceSymbolDemangling, demangling_a_cpp_symbol_works)
152 {
153  const char* ref = "tests/fork_and_run_test(_ZN7testing8internal35HandleExceptionsInMethodIfSupportedINS0_12UnitTestImplEbEET0_PT_MS4_FS3_vEPKc+0x4b) [0x4591f8]";
154  const char* ref_demangled = "bool testing::internal::HandleExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*)";
156 
157  EXPECT_TRUE(symbol->is_cxx());
158  EXPECT_EQ(ref, symbol->raw());
159  EXPECT_EQ(ref_demangled, symbol->demangled());
160 }
ForkAndRunResult
The ForkAndRunResult enum models the different failure modes of fork_and_run.
Definition: fork_and_run.h:34
TESTP(TestingMacros, test_fp_macro_reports_success_for_passing_test,{return core::posix::exit::Status::success;}) TESTP_F(TestingMacrosFixture
CORE_POSIX_DLL_PUBLIC ForkAndRunResult fork_and_run(const std::function< core::posix::exit::Status()> &service, const std::function< core::posix::exit::Status()> &client)
Forks two processes for both the service and the client.
static std::shared_ptr< Symbol > for_testing_from_raw_symbol(const char *symbol)
Definition: backtrace.cpp:120
test_fp_macro_reports_success_for_passing_test
Special value indicating no bit being set.
#define TESTP_F(test_fixture, test_name, CODE)
Definition: fork_and_run.h:100
TEST(ForkAndRun, succeeding_client_and_service_result_in_correct_return_value)
CORE_POSIX_DLL_PUBLIC std::ostream & cout() noexcept(true)
Access this process&#39;s stdout.
DISABLED_test_fp_macro_reports_success_for_failing_test