1 /* Copyright (C) 2013 BMW Group
2 * Author: Manfred Bathelt (manfred.bathelt@bmw.de)
3 * Author: Juergen Gehring (juergen.gehring@bmw.de)
4 * This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include <CommonAPI/DBus/DBusConnection.h>
8 #include <CommonAPI/DBus/DBusProxyAsyncCallbackHandler.h>
10 #include <gtest/gtest.h>
11 #include <dbus/dbus.h>
16 class DBusConnectionTest: public ::testing::Test {
18 virtual void SetUp() {
21 virtual void TearDown() {
26 //TEST_F(DBusConnectionTest, IsInitiallyDisconnected) {
27 // ASSERT_FALSE(dbusConnection_->isConnected());
30 //TEST_F(DBusConnectionTest, ConnectAndDisconnectWork) {
31 // ASSERT_TRUE(dbusConnection_->connect());
32 // ASSERT_TRUE(dbusConnection_->isConnected());
34 // dbusConnection_->disconnect();
35 // ASSERT_FALSE(dbusConnection_->isConnected());
38 //TEST_F(DBusConnectionTest, ConnectionStatusEventWorks) {
39 // ASSERT_EQ(connectionStatusEventCount_, 0);
41 // auto connectionStatusSubscription = dbusConnection_->getConnectionStatusEvent().subscribe(std::bind(
42 // &DBusConnectionTest::onConnectionStatusEvent,
44 // std::placeholders::_1));
46 // ASSERT_FALSE(dbusConnection_->isConnected());
47 // ASSERT_EQ(connectionStatusEventCount_, 0);
49 // uint32_t expectedEventCount = 0;
50 // while (expectedEventCount < 10) {
51 // ASSERT_TRUE(dbusConnection_->connect());
52 // ASSERT_TRUE(dbusConnection_->isConnected());
53 // ASSERT_EQ(connectionStatusEventCount_, ++expectedEventCount);
54 // ASSERT_EQ(connectionStatus_, common::api::AvailabilityStatus::AVAILABLE);
56 // dbusConnection_->disconnect();
57 // ASSERT_FALSE(dbusConnection_->isConnected());
58 // ASSERT_EQ(connectionStatusEventCount_, ++expectedEventCount);
59 // ASSERT_EQ(connectionStatus_, common::api::AvailabilityStatus::NOT_AVAILABLE);
62 // dbusConnection_->getConnectionStatusEvent().unsubscribe(connectionStatusSubscription);
63 // ASSERT_EQ(connectionStatusEventCount_, expectedEventCount);
65 // ASSERT_TRUE(dbusConnection_->connect());
66 // ASSERT_TRUE(dbusConnection_->isConnected());
67 // ASSERT_EQ(connectionStatusEventCount_, expectedEventCount);
69 // dbusConnection_->disconnect();
70 // ASSERT_FALSE(dbusConnection_->isConnected());
71 // ASSERT_EQ(connectionStatusEventCount_, expectedEventCount);
74 //TEST_F(DBusConnectionTest, SendingAsyncDBusMessagesWorks) {
75 // const char* busName = "common.api.dbus.test.TestInterfaceHandler";
76 // const char* objectPath = "/common/api/dbus/test/TestObject";
77 // const char* interfaceName = "common.api.dbus.test.TestInterface";
78 // const char* methodName = "TestMethod";
80 // auto interfaceHandlerDBusConnection = common::api::dbus::DBusConnection::getSessionBus();
82 // ASSERT_TRUE(interfaceHandlerDBusConnection->connect());
83 // ASSERT_TRUE(interfaceHandlerDBusConnection->requestServiceNameAndBlock(busName));
85 // auto interfaceHandlerToken = interfaceHandlerDBusConnection->registerInterfaceHandler(
88 // std::bind(&DBusConnectionTest::onInterfaceHandlerDBusMessageReply,
90 // std::placeholders::_1,
91 // interfaceHandlerDBusConnection));
94 // ASSERT_TRUE(dbusConnection_->connect());
96 // for (uint32_t expectedDBusMessageCount = 1; expectedDBusMessageCount <= 10; expectedDBusMessageCount++) {
97 // auto dbusMessageCall = common::api::dbus::DBusMessage::createMethodCall(
103 // ASSERT_TRUE(dbusMessageCall);
105 // common::api::dbus::DBusOutputMessageStream dbusOutputMessageStream(dbusMessageCall);
106 // dbusOutputMessageStream << "This is a test async call"
107 // << expectedDBusMessageCount;
108 // dbusOutputMessageStream.flush();
110 // dbusConnection_->sendDBusMessageWithReplyAsync(
112 // std::bind(&DBusConnectionTest::onDBusMessageHandler, this, std::placeholders::_1));
114 // for (int i = 0; i < 10 && interfaceHandlerDBusMessageCount_ < expectedDBusMessageCount; i++)
115 // interfaceHandlerDBusConnection->readWriteDispatch(100);
117 // ASSERT_EQ(interfaceHandlerDBusMessageCount_, expectedDBusMessageCount);
118 // ASSERT_DBUSMESSAGE_EQ(dbusMessageCall, interfaceHandlerDBusMessage_);
120 // for (int i = 0; i < 10 && dbusMessageHandlerCount_ < expectedDBusMessageCount; i++)
121 // dbusConnection_->readWriteDispatch(100);
123 // ASSERT_EQ(dbusMessageHandlerCount_, expectedDBusMessageCount);
124 // ASSERT_DBUSMESSAGE_EQ(dbusMessageHandlerDBusMessage_, interfaceHandlerDBusMessageReply_);
127 // dbusConnection_->disconnect();
130 // interfaceHandlerDBusConnection->unregisterInterfaceHandler(interfaceHandlerToken);
132 // ASSERT_TRUE(interfaceHandlerDBusConnection->releaseServiceName(busName));
133 // interfaceHandlerDBusConnection->disconnect();
137 void dispatch(::DBusConnection* libdbusConnection) {
138 dbus_bool_t success = TRUE;
140 success = dbus_connection_read_write_dispatch(libdbusConnection, 1);
144 std::promise<bool> promise;
145 std::future<bool> future = promise.get_future();
147 void notifyThunk(DBusPendingCall*, void* data) {
148 ::DBusConnection* libdbusConnection = reinterpret_cast<DBusConnection*>(data);
149 dbus_connection_close(libdbusConnection);
150 dbus_connection_unref(libdbusConnection);
151 promise.set_value(true);
154 TEST_F(DBusConnectionTest, LibdbusConnectionsMayCommitSuicide) {
155 const ::DBusBusType libdbusType = ::DBusBusType::DBUS_BUS_SESSION;
156 ::DBusError libdbusError;
157 dbus_error_init(&libdbusError);
158 ::DBusConnection* libdbusConnection = dbus_bus_get_private(libdbusType, &libdbusError);
160 assert(libdbusConnection);
161 dbus_connection_set_exit_on_disconnect(libdbusConnection, false);
163 auto dispatchThread = std::thread(&dispatch, libdbusConnection);
165 ::DBusMessage* libdbusMessageCall = dbus_message_new_method_call(
166 "org.freedesktop.DBus",
167 "/org/freedesktop/DBus",
168 "org.freedesktop.DBus",
171 dbus_message_set_signature(libdbusMessageCall, "");
173 bool hasHappened = false;
175 DBusPendingCall* libdbusPendingCall;
176 dbus_bool_t libdbusSuccess;
178 dbus_connection_send_with_reply(
184 dbus_pending_call_set_notify(
190 ASSERT_EQ(true, future.get());
191 dispatchThread.join();
195 std::promise<bool> promise2;
196 std::future<bool> future2 = promise2.get_future();
197 std::promise<bool> promise3;
198 std::future<bool> future3 = promise3.get_future();
200 void noPartnerCallback(DBusPendingCall*, void* data) {
201 ::DBusConnection* libdbusConnection = reinterpret_cast<DBusConnection*>(data);
202 dbus_connection_close(libdbusConnection);
203 dbus_connection_unref(libdbusConnection);
204 promise2.set_value(true);
207 void noPartnerCleanup(void* data) {
208 std::cout << "Cleanup" << std::endl;
209 promise3.set_value(true);
212 TEST_F(DBusConnectionTest, TimeoutForNonexistingServices) {
213 const ::DBusBusType libdbusType = ::DBusBusType::DBUS_BUS_SESSION;
214 ::DBusError libdbusError;
215 dbus_error_init(&libdbusError);
216 ::DBusConnection* libdbusConnection = dbus_bus_get_private(libdbusType, &libdbusError);
218 assert(libdbusConnection);
219 dbus_connection_set_exit_on_disconnect(libdbusConnection, false);
221 auto dispatchThread = std::thread(&dispatch, libdbusConnection);
223 ::DBusMessage* libdbusMessageCall = dbus_message_new_method_call(
224 "some.connection.somewhere",
225 "/some/non/existing/object",
226 "some.interface.somewhere.but.same.place",
227 "NoReasonableMethod");
229 dbus_message_set_signature(libdbusMessageCall, "");
231 bool hasHappened = false;
233 DBusPendingCall* libdbusPendingCall;
234 dbus_bool_t libdbusSuccess;
236 dbus_connection_send_with_reply(
242 dbus_pending_call_set_notify(
248 ASSERT_EQ(true, future2.get());
249 dispatchThread.join();
252 //TEST_F(DBusConnectionTest, ConnectionsMayCommitAsynchronousSuicide) {
253 // CommonAPI::DBus::DBusConnection* dbusConnection_ = new CommonAPI::DBus::DBusConnection(CommonAPI::DBus::DBusConnection::BusType::SESSION);
254 // dbusConnection_->connect();
256 // auto dbusMessageCall = CommonAPI::DBus::DBusMessage::createMethodCall(
257 // "org.freedesktop.DBus",
258 // "/org/freedesktop/DBus",
259 // "org.freedesktop.DBus",
263 // bool hasHappened = false;
265 // auto future = dbusConnection_->sendDBusMessageWithReplyAsync(dbusMessageCall, CommonAPI::DBus::DBusProxyAsyncCallbackHandler<std::vector<std::string>>::create(
266 // [&] (const CommonAPI::CallStatus&, std::vector<std::string>) {
267 // hasHappened = true;
268 // delete dbusConnection_;
272 // ASSERT_EQ(CommonAPI::CallStatus::SUCCESS, future.get());
276 int main(int argc, char** argv) {
277 ::testing::InitGoogleTest(&argc, argv);
278 return RUN_ALL_TESTS();