process-cpp: /build/process-cpp/src/process-cpp-3.0.1/tests/fork_and_run_test.cpp Source File

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
19 #include <core/testing/fork_and_run.h>
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
35 (result & core::testing::ForkAndRunResult::client_failed) == core::testing::ForkAndRunResult::empty ?
36 ::testing::AssertionFailure() :
37 ::testing::AssertionSuccess();
38 }
39
40 ::testing::AssertionResult ServiceFailed(core::testing::ForkAndRunResult result)
41 {
42 return
43 (result & core::testing::ForkAndRunResult::service_failed) == core::testing::ForkAndRunResult::empty ?
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
127 TESTP(TestingMacros, test_fp_macro_reports_success_for_passing_test,
128 {
129 return core::posix::exit::Status::success;
130 })
131
132 TESTP_F(TestingMacrosFixture, test_fp_macro_reports_success_for_passing_test,
133 {
134 return core::posix::exit::Status::success;
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.
139 TESTP(TestingMacros, DISABLED_test_fp_macro_reports_success_for_failing_test,
140 {
141 return core::posix::exit::Status::failure;
142 })
143
144 TESTP_F(TestingMacrosFixture, DISABLED_test_fp_macro_reports_success_for_failing_test,
145 {
146 return core::posix::exit::Status::failure;
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*)";
155 auto symbol = core::posix::backtrace::Frame::Symbol::for_testing_from_raw_symbol(ref);
156
157 EXPECT_TRUE(symbol->is_cxx());
158 EXPECT_EQ(ref, symbol->raw());
159 EXPECT_EQ(ref_demangled, symbol->demangled());
160 }
fork_and_run.h
core::testing::ForkAndRunResult
ForkAndRunResult
The ForkAndRunResult enum models the different failure modes of fork_and_run.
Definition: fork_and_run.h:35
TESTP_F
#define TESTP_F(test_fixture, test_name, CODE)
Definition: fork_and_run.h:100
TESTP
TESTP(TestingMacros, test_fp_macro_reports_success_for_passing_test, { return core::posix::exit::Status::success;}) TESTP_F(TestingMacrosFixture
signal.h
core::posix::this_process::cout
CORE_POSIX_DLL_PUBLIC std::ostream & cout() noexcept(true)
Access this process's stdout.
Definition: this_process.cpp:166
test_fp_macro_reports_success_for_passing_test
test_fp_macro_reports_success_for_passing_test
Definition: fork_and_run_test.cpp:132
TEST
TEST(ForkAndRun, succeeding_client_and_service_result_in_correct_return_value)
Definition: fork_and_run_test.cpp:61
core::posix::exit::Status::success
@ success
DISABLED_test_fp_macro_reports_success_for_failing_test
DISABLED_test_fp_macro_reports_success_for_failing_test
Definition: fork_and_run_test.cpp:144
core::posix::backtrace::Frame::Symbol::for_testing_from_raw_symbol
static std::shared_ptr< Symbol > for_testing_from_raw_symbol(const char *symbol)
Definition: backtrace.cpp:120
core::testing::ForkAndRunResult::empty
@ empty
Special value indicating no bit being set.
core::testing::fork_and_run
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.
Definition: fork_and_run.cpp:41