Dev for variant
[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 <common-api-dbus/dbus-connection.h>
8 #include <common-api-dbus/dbus-output-message-stream.h>
9
10 #include <gtest/gtest.h>
11
12 #include <cstring>
13
14
15 #define ASSERT_DBUSMESSAGE_EQ(_dbusMessage1, _dbusMessage2) \
16                         ASSERT_FALSE(_dbusMessage1.getSignatureString() == NULL); \
17                         ASSERT_FALSE(_dbusMessage2.getSignatureString() == NULL); \
18                         ASSERT_STREQ(_dbusMessage1.getSignatureString(), _dbusMessage2.getSignatureString()); \
19                         ASSERT_EQ(_dbusMessage1.getBodyLength(), _dbusMessage2.getBodyLength()); \
20                         ASSERT_FALSE(_dbusMessage1.getBodyData() == NULL); \
21                         ASSERT_FALSE(_dbusMessage2.getBodyData() == NULL); \
22                         ASSERT_EQ(memcmp(_dbusMessage1.getBodyData(), _dbusMessage2.getBodyData(), _dbusMessage1.getBodyLength()), 0)
23
24
25 namespace {
26
27 class DBusConnectionTest: public ::testing::Test {
28  public:
29         void onConnectionStatusEvent(const common::api::AvailabilityStatus& newConnectionStatus) {
30                 connectionStatusEventCount_++;
31                 connectionStatus_ = newConnectionStatus;
32         }
33
34         bool onInterfaceHandlerDBusMessageReply(const common::api::dbus::DBusMessage& dbusMessage,
35                                                                                         const std::shared_ptr<common::api::dbus::DBusConnection>& dbusConnection) {
36                 interfaceHandlerDBusMessageCount_++;
37                 interfaceHandlerDBusMessage_ = dbusMessage;
38                 interfaceHandlerDBusMessageReply_ = dbusMessage.createMethodReturn("si");
39
40                 common::api::dbus::DBusOutputMessageStream dbusOutputMessageStream(interfaceHandlerDBusMessageReply_);
41                 dbusOutputMessageStream << "This is a default message reply!" << interfaceHandlerDBusMessageCount_;
42                 dbusOutputMessageStream.flush();
43
44                 dbusConnection->sendDBusMessage(interfaceHandlerDBusMessageReply_);
45
46                 return true;
47         }
48
49         void onDBusMessageHandler(const common::api::dbus::DBusMessage& dbusMessage) {
50                 dbusMessageHandlerCount_++;
51                 dbusMessageHandlerDBusMessage_ = dbusMessage;
52         }
53
54  protected:
55         virtual void SetUp() {
56                 dbusConnection_ = common::api::dbus::DBusConnection::getSessionBus();
57                 connectionStatusEventCount_ = 0;
58                 interfaceHandlerDBusMessageCount_ = 0;
59                 dbusMessageHandlerCount_ = 0;
60         }
61
62         virtual void TearDown() {
63                 if (dbusConnection_ && dbusConnection_->isConnected())
64                         dbusConnection_->disconnect();
65
66                 // reset DBusMessage
67                 interfaceHandlerDBusMessage_ = common::api::dbus::DBusMessage();
68                 interfaceHandlerDBusMessageReply_ = common::api::dbus::DBusMessage();
69
70                 dbusMessageHandlerDBusMessage_ = common::api::dbus::DBusMessage();
71         }
72
73
74         std::shared_ptr<common::api::dbus::DBusConnection> dbusConnection_;
75
76         uint32_t connectionStatusEventCount_;
77         common::api::AvailabilityStatus connectionStatus_;
78
79         uint32_t interfaceHandlerDBusMessageCount_;
80         common::api::dbus::DBusMessage interfaceHandlerDBusMessage_;
81         common::api::dbus::DBusMessage interfaceHandlerDBusMessageReply_;
82
83         uint32_t dbusMessageHandlerCount_;
84         common::api::dbus::DBusMessage dbusMessageHandlerDBusMessage_;
85 };
86
87
88 TEST_F(DBusConnectionTest, IsInitiallyDisconnected) {
89         ASSERT_FALSE(dbusConnection_->isConnected());
90 }
91
92 TEST_F(DBusConnectionTest, ConnectAndDisconnectWork) {
93         ASSERT_TRUE(dbusConnection_->connect());
94         ASSERT_TRUE(dbusConnection_->isConnected());
95
96         dbusConnection_->disconnect();
97         ASSERT_FALSE(dbusConnection_->isConnected());
98 }
99
100 TEST_F(DBusConnectionTest, ConnectionStatusEventWorks) {
101         ASSERT_EQ(connectionStatusEventCount_, 0);
102
103         auto connectionStatusSubscription = dbusConnection_->getConnectionStatusEvent().subscribe(std::bind(
104                         &DBusConnectionTest::onConnectionStatusEvent,
105                         this,
106                         std::placeholders::_1));
107
108         ASSERT_FALSE(dbusConnection_->isConnected());
109         ASSERT_EQ(connectionStatusEventCount_, 0);
110
111         uint32_t expectedEventCount = 0;
112         while (expectedEventCount < 10) {
113                 ASSERT_TRUE(dbusConnection_->connect());
114                 ASSERT_TRUE(dbusConnection_->isConnected());
115                 ASSERT_EQ(connectionStatusEventCount_, ++expectedEventCount);
116                 ASSERT_EQ(connectionStatus_, common::api::AvailabilityStatus::AVAILABLE);
117
118                 dbusConnection_->disconnect();
119                 ASSERT_FALSE(dbusConnection_->isConnected());
120                 ASSERT_EQ(connectionStatusEventCount_, ++expectedEventCount);
121                 ASSERT_EQ(connectionStatus_, common::api::AvailabilityStatus::NOT_AVAILABLE);
122         }
123
124         dbusConnection_->getConnectionStatusEvent().unsubscribe(connectionStatusSubscription);
125         ASSERT_EQ(connectionStatusEventCount_, expectedEventCount);
126
127         ASSERT_TRUE(dbusConnection_->connect());
128         ASSERT_TRUE(dbusConnection_->isConnected());
129         ASSERT_EQ(connectionStatusEventCount_, expectedEventCount);
130
131         dbusConnection_->disconnect();
132         ASSERT_FALSE(dbusConnection_->isConnected());
133         ASSERT_EQ(connectionStatusEventCount_, expectedEventCount);
134 }
135
136 TEST_F(DBusConnectionTest, SendingAsyncDBusMessagesWorks) {
137         const char* busName = "common.api.dbus.test.TestInterfaceHandler";
138         const char* objectPath = "/common/api/dbus/test/TestObject";
139         const char* interfaceName = "common.api.dbus.test.TestInterface";
140         const char* methodName = "TestMethod";
141
142         auto interfaceHandlerDBusConnection = common::api::dbus::DBusConnection::getSessionBus();
143
144         ASSERT_TRUE(interfaceHandlerDBusConnection->connect());
145         ASSERT_TRUE(interfaceHandlerDBusConnection->requestServiceNameAndBlock(busName));
146
147         auto interfaceHandlerToken = interfaceHandlerDBusConnection->registerInterfaceHandler(
148                         objectPath,
149                         interfaceName,
150                         std::bind(&DBusConnectionTest::onInterfaceHandlerDBusMessageReply,
151                                           this,
152                                           std::placeholders::_1,
153                                           interfaceHandlerDBusConnection));
154
155
156         ASSERT_TRUE(dbusConnection_->connect());
157
158         for (uint32_t expectedDBusMessageCount = 1; expectedDBusMessageCount <= 10; expectedDBusMessageCount++) {
159                 auto dbusMessageCall = common::api::dbus::DBusMessage::createMethodCall(
160                                 busName,
161                                 objectPath,
162                                 interfaceName,
163                                 methodName,
164                                 "si");
165                 ASSERT_TRUE(dbusMessageCall);
166
167                 common::api::dbus::DBusOutputMessageStream dbusOutputMessageStream(dbusMessageCall);
168                 dbusOutputMessageStream << "This is a test async call"
169                                                                 << expectedDBusMessageCount;
170                 dbusOutputMessageStream.flush();
171
172                 dbusConnection_->sendDBusMessageWithReplyAsync(
173                                 dbusMessageCall,
174                                 std::bind(&DBusConnectionTest::onDBusMessageHandler, this, std::placeholders::_1));
175
176                 for (int i = 0; i < 10 && interfaceHandlerDBusMessageCount_ < expectedDBusMessageCount; i++)
177                         interfaceHandlerDBusConnection->readWriteDispatch(100);
178
179                 ASSERT_EQ(interfaceHandlerDBusMessageCount_, expectedDBusMessageCount);
180                 ASSERT_DBUSMESSAGE_EQ(dbusMessageCall, interfaceHandlerDBusMessage_);
181
182                 for (int i = 0; i < 10 && dbusMessageHandlerCount_ < expectedDBusMessageCount; i++)
183                         dbusConnection_->readWriteDispatch(100);
184
185                 ASSERT_EQ(dbusMessageHandlerCount_, expectedDBusMessageCount);
186                 ASSERT_DBUSMESSAGE_EQ(dbusMessageHandlerDBusMessage_, interfaceHandlerDBusMessageReply_);
187         }
188
189         dbusConnection_->disconnect();
190
191
192         interfaceHandlerDBusConnection->unregisterInterfaceHandler(interfaceHandlerToken);
193
194         ASSERT_TRUE(interfaceHandlerDBusConnection->releaseServiceName(busName));
195         interfaceHandlerDBusConnection->disconnect();
196 }
197
198 } // namespace