1 /**
2 * (C) 2016 - 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
3 * (C) 2016 - 2019 Stanislav Angelovic <angelovic.s@gmail.com>
4 *
5 * @file Connection_test.cpp
6 * @author Ardazishvili Roman (ardazishvili.roman@yandex.ru)
7 *
8 * Created on: Feb 4, 2019
9 * Project: sdbus-c++
10 * Description: High-level D-Bus IPC C++ library based on sd-bus
11 *
12 * This file is part of sdbus-c++.
13 *
14 * sdbus-c++ is free software; you can redistribute it and/or modify it
15 * under the terms of the GNU Lesser General Public License as published by
16 * the Free Software Foundation, either version 2.1 of the License, or
17 * (at your option) any later version.
18 *
19 * sdbus-c++ is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU Lesser General Public License for more details.
23 *
24 * You should have received a copy of the GNU Lesser General Public License
25 * along with sdbus-c++. If not, see <http://www.gnu.org/licenses/>.
26 */
27
28 #include "Connection.h"
29 #include "unittests/mocks/SdBusMock.h"
30
31 #include <gtest/gtest.h>
32
33 using ::testing::_;
34 using ::testing::DoAll;
35 using ::testing::SetArgPointee;
36 using ::testing::Return;
37 using ::testing::NiceMock;
38 using sdbus::internal::Connection;
39 constexpr sdbus::internal::Connection::default_bus_t default_bus;
40 constexpr sdbus::internal::Connection::system_bus_t system_bus;
41 constexpr sdbus::internal::Connection::session_bus_t session_bus;
42 constexpr sdbus::internal::Connection::remote_system_bus_t remote_system_bus;
43
44 class ConnectionCreationTest : public ::testing::Test
45 {
46 protected:
47 ConnectionCreationTest() = default;
48
49 std::unique_ptr<NiceMock<SdBusMock>> sdBusIntfMock_ = std::make_unique<NiceMock<SdBusMock>>();
50 sd_bus* fakeBusPtr_ = reinterpret_cast<sd_bus*>(1);
51 };
52
53 using ADefaultBusConnection = ConnectionCreationTest;
54 using ASystemBusConnection = ConnectionCreationTest;
55 using ASessionBusConnection = ConnectionCreationTest;
56
TEST_F(ADefaultBusConnection,OpensAndFlushesBusWhenCreated)57 TEST_F(ADefaultBusConnection, OpensAndFlushesBusWhenCreated)
58 {
59 EXPECT_CALL(*sdBusIntfMock_, sd_bus_open(_)).WillOnce(DoAll(SetArgPointee<0>(fakeBusPtr_), Return(1)));
60 EXPECT_CALL(*sdBusIntfMock_, sd_bus_flush(_)).Times(1);
61 Connection(std::move(sdBusIntfMock_), default_bus);
62 }
63
TEST_F(ASystemBusConnection,OpensAndFlushesBusWhenCreated)64 TEST_F(ASystemBusConnection, OpensAndFlushesBusWhenCreated)
65 {
66 EXPECT_CALL(*sdBusIntfMock_, sd_bus_open_system(_)).WillOnce(DoAll(SetArgPointee<0>(fakeBusPtr_), Return(1)));
67 EXPECT_CALL(*sdBusIntfMock_, sd_bus_flush(_)).Times(1);
68 Connection(std::move(sdBusIntfMock_), system_bus);
69 }
70
TEST_F(ASessionBusConnection,OpensAndFlushesBusWhenCreated)71 TEST_F(ASessionBusConnection, OpensAndFlushesBusWhenCreated)
72 {
73 EXPECT_CALL(*sdBusIntfMock_, sd_bus_open_user(_)).WillOnce(DoAll(SetArgPointee<0>(fakeBusPtr_), Return(1)));
74 EXPECT_CALL(*sdBusIntfMock_, sd_bus_flush(_)).Times(1);
75 Connection(std::move(sdBusIntfMock_), session_bus);
76 }
77
TEST_F(ADefaultBusConnection,ClosesAndUnrefsBusWhenDestructed)78 TEST_F(ADefaultBusConnection, ClosesAndUnrefsBusWhenDestructed)
79 {
80 ON_CALL(*sdBusIntfMock_, sd_bus_open(_)).WillByDefault(DoAll(SetArgPointee<0>(fakeBusPtr_), Return(1)));
81 EXPECT_CALL(*sdBusIntfMock_, sd_bus_flush_close_unref(_)).Times(1);
82 Connection(std::move(sdBusIntfMock_), default_bus);
83 }
84
TEST_F(ASystemBusConnection,ClosesAndUnrefsBusWhenDestructed)85 TEST_F(ASystemBusConnection, ClosesAndUnrefsBusWhenDestructed)
86 {
87 ON_CALL(*sdBusIntfMock_, sd_bus_open_system(_)).WillByDefault(DoAll(SetArgPointee<0>(fakeBusPtr_), Return(1)));
88 EXPECT_CALL(*sdBusIntfMock_, sd_bus_flush_close_unref(_)).Times(1);
89 Connection(std::move(sdBusIntfMock_), system_bus);
90 }
91
TEST_F(ASessionBusConnection,ClosesAndUnrefsBusWhenDestructed)92 TEST_F(ASessionBusConnection, ClosesAndUnrefsBusWhenDestructed)
93 {
94 ON_CALL(*sdBusIntfMock_, sd_bus_open_user(_)).WillByDefault(DoAll(SetArgPointee<0>(fakeBusPtr_), Return(1)));
95 EXPECT_CALL(*sdBusIntfMock_, sd_bus_flush_close_unref(_)).Times(1);
96 Connection(std::move(sdBusIntfMock_), session_bus);
97 }
98
TEST_F(ADefaultBusConnection,ThrowsErrorWhenOpeningTheBusFailsDuringConstruction)99 TEST_F(ADefaultBusConnection, ThrowsErrorWhenOpeningTheBusFailsDuringConstruction)
100 {
101 ON_CALL(*sdBusIntfMock_, sd_bus_open(_)).WillByDefault(DoAll(SetArgPointee<0>(fakeBusPtr_), Return(-1)));
102 ASSERT_THROW(Connection(std::move(sdBusIntfMock_), default_bus), sdbus::Error);
103 }
104
TEST_F(ASystemBusConnection,ThrowsErrorWhenOpeningTheBusFailsDuringConstruction)105 TEST_F(ASystemBusConnection, ThrowsErrorWhenOpeningTheBusFailsDuringConstruction)
106 {
107 ON_CALL(*sdBusIntfMock_, sd_bus_open_system(_)).WillByDefault(DoAll(SetArgPointee<0>(fakeBusPtr_), Return(-1)));
108 ASSERT_THROW(Connection(std::move(sdBusIntfMock_), system_bus), sdbus::Error);
109 }
110
TEST_F(ASessionBusConnection,ThrowsErrorWhenOpeningTheBusFailsDuringConstruction)111 TEST_F(ASessionBusConnection, ThrowsErrorWhenOpeningTheBusFailsDuringConstruction)
112 {
113 ON_CALL(*sdBusIntfMock_, sd_bus_open_user(_)).WillByDefault(DoAll(SetArgPointee<0>(fakeBusPtr_), Return(-1)));
114 ASSERT_THROW(Connection(std::move(sdBusIntfMock_), session_bus), sdbus::Error);
115 }
116
TEST_F(ADefaultBusConnection,ThrowsErrorWhenFlushingTheBusFailsDuringConstruction)117 TEST_F(ADefaultBusConnection, ThrowsErrorWhenFlushingTheBusFailsDuringConstruction)
118 {
119 ON_CALL(*sdBusIntfMock_, sd_bus_open(_)).WillByDefault(DoAll(SetArgPointee<0>(fakeBusPtr_), Return(1)));
120 ON_CALL(*sdBusIntfMock_, sd_bus_flush(_)).WillByDefault(Return(-1));
121 ASSERT_THROW(Connection(std::move(sdBusIntfMock_), default_bus), sdbus::Error);
122 }
123
TEST_F(ASystemBusConnection,ThrowsErrorWhenFlushingTheBusFailsDuringConstruction)124 TEST_F(ASystemBusConnection, ThrowsErrorWhenFlushingTheBusFailsDuringConstruction)
125 {
126 ON_CALL(*sdBusIntfMock_, sd_bus_open_system(_)).WillByDefault(DoAll(SetArgPointee<0>(fakeBusPtr_), Return(1)));
127 ON_CALL(*sdBusIntfMock_, sd_bus_flush(_)).WillByDefault(Return(-1));
128 ASSERT_THROW(Connection(std::move(sdBusIntfMock_), system_bus), sdbus::Error);
129 }
130
TEST_F(ASessionBusConnection,ThrowsErrorWhenFlushingTheBusFailsDuringConstruction)131 TEST_F(ASessionBusConnection, ThrowsErrorWhenFlushingTheBusFailsDuringConstruction)
132 {
133 ON_CALL(*sdBusIntfMock_, sd_bus_open_user(_)).WillByDefault(DoAll(SetArgPointee<0>(fakeBusPtr_), Return(1)));
134 ON_CALL(*sdBusIntfMock_, sd_bus_flush(_)).WillByDefault(Return(-1));
135 ASSERT_THROW(Connection(std::move(sdBusIntfMock_), session_bus), sdbus::Error);
136 }
137
138 namespace
139 {
140 template <typename _BusTypeTag>
141 class AConnectionNameRequest : public ::testing::Test
142 {
143 protected:
144 void setUpBusOpenExpectation();
145 std::unique_ptr<Connection> makeConnection();
146
SetUp()147 void SetUp() override
148 {
149 setUpBusOpenExpectation();
150 ON_CALL(*sdBusIntfMock_, sd_bus_flush(_)).WillByDefault(Return(1));
151 ON_CALL(*sdBusIntfMock_, sd_bus_flush_close_unref(_)).WillByDefault(Return(fakeBusPtr_));
152 con_ = makeConnection();
153 }
154
155 NiceMock<SdBusMock>* sdBusIntfMock_ = new NiceMock<SdBusMock>(); // con_ below will assume ownership
156 sd_bus* fakeBusPtr_ = reinterpret_cast<sd_bus*>(1);
157 std::unique_ptr<Connection> con_;
158 };
159
setUpBusOpenExpectation()160 template<> void AConnectionNameRequest<Connection::default_bus_t>::setUpBusOpenExpectation()
161 {
162 EXPECT_CALL(*sdBusIntfMock_, sd_bus_open(_)).WillOnce(DoAll(SetArgPointee<0>(fakeBusPtr_), Return(1)));
163 }
setUpBusOpenExpectation()164 template<> void AConnectionNameRequest<Connection::system_bus_t>::setUpBusOpenExpectation()
165 {
166 EXPECT_CALL(*sdBusIntfMock_, sd_bus_open_system(_)).WillOnce(DoAll(SetArgPointee<0>(fakeBusPtr_), Return(1)));
167 }
setUpBusOpenExpectation()168 template<> void AConnectionNameRequest<Connection::session_bus_t>::setUpBusOpenExpectation()
169 {
170 EXPECT_CALL(*sdBusIntfMock_, sd_bus_open_user(_)).WillOnce(DoAll(SetArgPointee<0>(fakeBusPtr_), Return(1)));
171 }
setUpBusOpenExpectation()172 template<> void AConnectionNameRequest<Connection::remote_system_bus_t>::setUpBusOpenExpectation()
173 {
174 EXPECT_CALL(*sdBusIntfMock_, sd_bus_open_system_remote(_, _)).WillOnce(DoAll(SetArgPointee<0>(fakeBusPtr_), Return(1)));
175 }
176 template <typename _BusTypeTag>
makeConnection()177 std::unique_ptr<Connection> AConnectionNameRequest<_BusTypeTag>::makeConnection()
178 {
179 return std::make_unique<Connection>(std::unique_ptr<NiceMock<SdBusMock>>(sdBusIntfMock_), _BusTypeTag{});
180 }
makeConnection()181 template<> std::unique_ptr<Connection> AConnectionNameRequest<Connection::remote_system_bus_t>::makeConnection()
182 {
183 return std::make_unique<Connection>(std::unique_ptr<NiceMock<SdBusMock>>(sdBusIntfMock_), remote_system_bus, "some host");
184 }
185
186 typedef ::testing::Types< Connection::default_bus_t
187 , Connection::system_bus_t
188 , Connection::session_bus_t
189 , Connection::remote_system_bus_t
190 > BusTypeTags;
191
192 TYPED_TEST_SUITE(AConnectionNameRequest, BusTypeTags);
193 }
194
TYPED_TEST(AConnectionNameRequest,DoesNotThrowOnSuccess)195 TYPED_TEST(AConnectionNameRequest, DoesNotThrowOnSuccess)
196 {
197 EXPECT_CALL(*this->sdBusIntfMock_, sd_bus_request_name(_, _, _)).WillOnce(Return(1));
198 this->con_->requestName("org.sdbuscpp.somename");
199 }
200
TYPED_TEST(AConnectionNameRequest,ThrowsOnFail)201 TYPED_TEST(AConnectionNameRequest, ThrowsOnFail)
202 {
203 EXPECT_CALL(*this->sdBusIntfMock_, sd_bus_request_name(_, _, _)).WillOnce(Return(-1));
204
205 ASSERT_THROW(this->con_->requestName("org.sdbuscpp.somename"), sdbus::Error);
206 }
207