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
25namespace
26{
27struct 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}
47struct 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
61TEST(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
72TEST(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
83TEST(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
94TEST(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
105TEST(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
116TEST(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
151TEST(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}
static std::shared_ptr< Symbol > for_testing_from_raw_symbol(const char *symbol)
#define TESTP_F(test_fixture, test_name, CODE)
#define TESTP(test_suite, test_name, CODE)
DISABLED_test_fp_macro_reports_success_for_failing_test
test_fp_macro_reports_success_for_passing_test
TEST(ForkAndRun, succeeding_client_and_service_result_in_correct_return_value)
ForkAndRunResult
The ForkAndRunResult enum models the different failure modes of fork_and_run.
@ client_failed
The client failed.
@ empty
Special value indicating no bit being set.
@ service_failed
The service failed.
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.