Updated DBusConnectionTest to current version of CommonAPI, integrated
[profile/ivi/common-api-dbus-runtime.git] / src / test / DBusConnectionTest.cpp
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>
9
10 #include <gtest/gtest.h>
11 #include <dbus/dbus.h>
12
13 #include <cstring>
14
15
16 class DBusConnectionTest: public ::testing::Test {
17  protected:
18         virtual void SetUp() {
19         }
20
21         virtual void TearDown() {
22         }
23 };
24
25
26 //TEST_F(DBusConnectionTest, IsInitiallyDisconnected) {
27 //      ASSERT_FALSE(dbusConnection_->isConnected());
28 //}
29 //
30 //TEST_F(DBusConnectionTest, ConnectAndDisconnectWork) {
31 //      ASSERT_TRUE(dbusConnection_->connect());
32 //      ASSERT_TRUE(dbusConnection_->isConnected());
33 //
34 //      dbusConnection_->disconnect();
35 //      ASSERT_FALSE(dbusConnection_->isConnected());
36 //}
37 //
38 //TEST_F(DBusConnectionTest, ConnectionStatusEventWorks) {
39 //      ASSERT_EQ(connectionStatusEventCount_, 0);
40 //
41 //      auto connectionStatusSubscription = dbusConnection_->getConnectionStatusEvent().subscribe(std::bind(
42 //                      &DBusConnectionTest::onConnectionStatusEvent,
43 //                      this,
44 //                      std::placeholders::_1));
45 //
46 //      ASSERT_FALSE(dbusConnection_->isConnected());
47 //      ASSERT_EQ(connectionStatusEventCount_, 0);
48 //
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);
55 //
56 //              dbusConnection_->disconnect();
57 //              ASSERT_FALSE(dbusConnection_->isConnected());
58 //              ASSERT_EQ(connectionStatusEventCount_, ++expectedEventCount);
59 //              ASSERT_EQ(connectionStatus_, common::api::AvailabilityStatus::NOT_AVAILABLE);
60 //      }
61 //
62 //      dbusConnection_->getConnectionStatusEvent().unsubscribe(connectionStatusSubscription);
63 //      ASSERT_EQ(connectionStatusEventCount_, expectedEventCount);
64 //
65 //      ASSERT_TRUE(dbusConnection_->connect());
66 //      ASSERT_TRUE(dbusConnection_->isConnected());
67 //      ASSERT_EQ(connectionStatusEventCount_, expectedEventCount);
68 //
69 //      dbusConnection_->disconnect();
70 //      ASSERT_FALSE(dbusConnection_->isConnected());
71 //      ASSERT_EQ(connectionStatusEventCount_, expectedEventCount);
72 //}
73 //
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";
79 //
80 //      auto interfaceHandlerDBusConnection = common::api::dbus::DBusConnection::getSessionBus();
81 //
82 //      ASSERT_TRUE(interfaceHandlerDBusConnection->connect());
83 //      ASSERT_TRUE(interfaceHandlerDBusConnection->requestServiceNameAndBlock(busName));
84 //
85 //      auto interfaceHandlerToken = interfaceHandlerDBusConnection->registerInterfaceHandler(
86 //                      objectPath,
87 //                      interfaceName,
88 //                      std::bind(&DBusConnectionTest::onInterfaceHandlerDBusMessageReply,
89 //                                        this,
90 //                                        std::placeholders::_1,
91 //                                        interfaceHandlerDBusConnection));
92 //
93 //
94 //      ASSERT_TRUE(dbusConnection_->connect());
95 //
96 //      for (uint32_t expectedDBusMessageCount = 1; expectedDBusMessageCount <= 10; expectedDBusMessageCount++) {
97 //              auto dbusMessageCall = common::api::dbus::DBusMessage::createMethodCall(
98 //                              busName,
99 //                              objectPath,
100 //                              interfaceName,
101 //                              methodName,
102 //                              "si");
103 //              ASSERT_TRUE(dbusMessageCall);
104 //
105 //              common::api::dbus::DBusOutputMessageStream dbusOutputMessageStream(dbusMessageCall);
106 //              dbusOutputMessageStream << "This is a test async call"
107 //                                                              << expectedDBusMessageCount;
108 //              dbusOutputMessageStream.flush();
109 //
110 //              dbusConnection_->sendDBusMessageWithReplyAsync(
111 //                              dbusMessageCall,
112 //                              std::bind(&DBusConnectionTest::onDBusMessageHandler, this, std::placeholders::_1));
113 //
114 //              for (int i = 0; i < 10 && interfaceHandlerDBusMessageCount_ < expectedDBusMessageCount; i++)
115 //                      interfaceHandlerDBusConnection->readWriteDispatch(100);
116 //
117 //              ASSERT_EQ(interfaceHandlerDBusMessageCount_, expectedDBusMessageCount);
118 //              ASSERT_DBUSMESSAGE_EQ(dbusMessageCall, interfaceHandlerDBusMessage_);
119 //
120 //              for (int i = 0; i < 10 && dbusMessageHandlerCount_ < expectedDBusMessageCount; i++)
121 //                      dbusConnection_->readWriteDispatch(100);
122 //
123 //              ASSERT_EQ(dbusMessageHandlerCount_, expectedDBusMessageCount);
124 //              ASSERT_DBUSMESSAGE_EQ(dbusMessageHandlerDBusMessage_, interfaceHandlerDBusMessageReply_);
125 //      }
126 //
127 //      dbusConnection_->disconnect();
128 //
129 //
130 //      interfaceHandlerDBusConnection->unregisterInterfaceHandler(interfaceHandlerToken);
131 //
132 //      ASSERT_TRUE(interfaceHandlerDBusConnection->releaseServiceName(busName));
133 //      interfaceHandlerDBusConnection->disconnect();
134 //}
135
136
137 void dispatch(::DBusConnection* libdbusConnection) {
138         dbus_bool_t success = TRUE;
139         while(success) {
140         success = dbus_connection_read_write_dispatch(libdbusConnection, 1);
141     }
142 }
143
144 std::promise<bool> promise;
145 std::future<bool> future = promise.get_future();
146
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);
152 }
153
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);
159
160         assert(libdbusConnection);
161         dbus_connection_set_exit_on_disconnect(libdbusConnection, false);
162
163         auto dispatchThread = std::thread(&dispatch, libdbusConnection);
164
165         ::DBusMessage* libdbusMessageCall = dbus_message_new_method_call(
166                         "org.freedesktop.DBus",
167                         "/org/freedesktop/DBus",
168                         "org.freedesktop.DBus",
169             "ListNames");
170
171         dbus_message_set_signature(libdbusMessageCall, "");
172
173     bool hasHappened = false;
174
175     DBusPendingCall* libdbusPendingCall;
176     dbus_bool_t libdbusSuccess;
177
178     dbus_connection_send_with_reply(
179                     libdbusConnection,
180                     libdbusMessageCall,
181                     &libdbusPendingCall,
182                     500);
183
184     dbus_pending_call_set_notify(
185                     libdbusPendingCall,
186                     notifyThunk,
187                     libdbusConnection,
188                     NULL);
189
190     ASSERT_EQ(true, future.get());
191     dispatchThread.join();
192 }
193
194
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();
199
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);
205 }
206
207 void noPartnerCleanup(void* data) {
208         std::cout << "Cleanup" << std::endl;
209         promise3.set_value(true);
210 }
211
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);
217
218         assert(libdbusConnection);
219         dbus_connection_set_exit_on_disconnect(libdbusConnection, false);
220
221         auto dispatchThread = std::thread(&dispatch, libdbusConnection);
222
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");
228
229         dbus_message_set_signature(libdbusMessageCall, "");
230
231     bool hasHappened = false;
232
233     DBusPendingCall* libdbusPendingCall;
234     dbus_bool_t libdbusSuccess;
235
236     dbus_connection_send_with_reply(
237                     libdbusConnection,
238                     libdbusMessageCall,
239                     &libdbusPendingCall,
240                     5000);
241
242     dbus_pending_call_set_notify(
243                     libdbusPendingCall,
244                     noPartnerCallback,
245                     libdbusConnection,
246                     noPartnerCleanup);
247
248     ASSERT_EQ(true, future2.get());
249     dispatchThread.join();
250 }
251
252 //TEST_F(DBusConnectionTest, ConnectionsMayCommitAsynchronousSuicide) {
253 //      CommonAPI::DBus::DBusConnection* dbusConnection_ = new CommonAPI::DBus::DBusConnection(CommonAPI::DBus::DBusConnection::BusType::SESSION);
254 //      dbusConnection_->connect();
255 //
256 //    auto dbusMessageCall = CommonAPI::DBus::DBusMessage::createMethodCall(
257 //                      "org.freedesktop.DBus",
258 //                      "/org/freedesktop/DBus",
259 //                      "org.freedesktop.DBus",
260 //            "ListNames",
261 //            "");
262 //
263 //    bool hasHappened = false;
264 //
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_;
269 //              }
270 //    ));
271 //
272 //      ASSERT_EQ(CommonAPI::CallStatus::SUCCESS, future.get());
273 //}
274
275
276 int main(int argc, char** argv) {
277     ::testing::InitGoogleTest(&argc, argv);
278     return RUN_ALL_TESTS();
279 }
280