tests: fix blocking semantic in DBusProxyTest
[profile/ivi/common-api-dbus-runtime.git] / src / test / DBusDaemonProxyTest.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/DBusDaemonProxy.h>
9 #include <CommonAPI/DBus/DBusUtils.h>
10
11 #include <gtest/gtest.h>
12
13 #include <future>
14 #include <tuple>
15
16 namespace {
17
18 void dispatch(std::shared_ptr<CommonAPI::DBus::DBusConnection> dbusConnection) {
19     while (dbusConnection->readWriteDispatch(10)) {}
20 }
21
22 class DBusDaemonProxyTest: public ::testing::Test {
23  protected:
24
25         std::thread* thread;
26
27         virtual void SetUp() {
28                 dbusConnection_ = CommonAPI::DBus::DBusConnection::getSessionBus();
29                 ASSERT_TRUE(dbusConnection_->connect());
30                 thread = new std::thread(dispatch, dbusConnection_);
31                 thread->detach();
32                 //readWriteDispatchCount_ = 0;
33         }
34
35         virtual void TearDown() {
36                 delete thread;
37                 if (dbusConnection_ && dbusConnection_->isConnected()) {
38                         //dbusConnection_->disconnect();
39                 }
40         }
41
42         /*bool doReadWriteDispatch(int timeoutMilliseconds = 100) {
43                 readWriteDispatchCount_++;
44                 return dbusConnection_->readWriteDispatch(timeoutMilliseconds);
45         }*/
46
47         std::shared_ptr<CommonAPI::DBus::DBusConnection> dbusConnection_;
48         //size_t readWriteDispatchCount_;
49 };
50
51 TEST_F(DBusDaemonProxyTest, ListNames) {
52         std::vector<std::string> busNames;
53         CommonAPI::CallStatus callStatus;
54
55         dbusConnection_->getDBusDaemonProxy()->listNames(callStatus, busNames);
56         ASSERT_EQ(callStatus, CommonAPI::CallStatus::SUCCESS);
57
58         ASSERT_GT(busNames.size(), 0);
59         for (const std::string& busName : busNames) {
60                 ASSERT_FALSE(busName.empty());
61                 ASSERT_GT(busName.length(), 1);
62         }
63 }
64
65 TEST_F(DBusDaemonProxyTest, ListNamesAsync) {
66         std::promise<std::tuple<CommonAPI::CallStatus, std::vector<std::string>>> promise;
67         auto future = promise.get_future();
68
69         auto callStatusFuture = dbusConnection_->getDBusDaemonProxy()->listNamesAsync(
70                         [&](const CommonAPI::CallStatus& callStatus, std::vector<std::string> busNames) {
71                 promise.set_value(std::tuple<CommonAPI::CallStatus, std::vector<std::string>>(callStatus, std::move(busNames)));
72         });
73
74         auto status = future.wait_for(std::chrono::milliseconds(200));
75         bool waitResult = CommonAPI::DBus::checkReady(status);
76     ASSERT_EQ(waitResult, true);
77
78         ASSERT_EQ(callStatusFuture.get(), CommonAPI::CallStatus::SUCCESS);
79
80         auto futureResult = future.get();
81         const CommonAPI::CallStatus& callStatus = std::get<0>(futureResult);
82         const std::vector<std::string>& busNames = std::get<1>(futureResult);
83
84         ASSERT_EQ(callStatus, CommonAPI::CallStatus::SUCCESS);
85
86         ASSERT_GT(busNames.size(), 0);
87         for (const std::string& busName : busNames) {
88                 ASSERT_FALSE(busName.empty());
89                 ASSERT_GT(busName.length(), 1);
90         }
91 }
92
93 TEST_F(DBusDaemonProxyTest, NameHasOwner) {
94         bool nameHasOwner;
95         CommonAPI::CallStatus callStatus;
96
97         dbusConnection_->getDBusDaemonProxy()->nameHasOwner("org.freedesktop.DBus", callStatus, nameHasOwner);
98         ASSERT_EQ(callStatus, CommonAPI::CallStatus::SUCCESS);
99         ASSERT_TRUE(nameHasOwner);
100
101         dbusConnection_->getDBusDaemonProxy()->nameHasOwner("org.freedesktop.DBus.InvalidName.XXYYZZ", callStatus, nameHasOwner);
102         ASSERT_EQ(callStatus, CommonAPI::CallStatus::SUCCESS);
103         ASSERT_FALSE(nameHasOwner);
104 }
105
106 TEST_F(DBusDaemonProxyTest, NameHasOwnerAsync) {
107         std::promise<std::tuple<CommonAPI::CallStatus, bool>> promise;
108         auto future = promise.get_future();
109
110         auto callStatusFuture = dbusConnection_->getDBusDaemonProxy()->nameHasOwnerAsync(
111                         "org.freedesktop.DBus",
112                         [&](const CommonAPI::CallStatus& callStatus, bool nameHasOwner) {
113                 promise.set_value(std::tuple<CommonAPI::CallStatus, bool>(callStatus, std::move(nameHasOwner)));
114         });
115
116         //while (readWriteDispatchCount_ < 5) {
117         //      ASSERT_TRUE(doReadWriteDispatch());
118                 //if (callStatusFuture.wait_for(std::chrono::milliseconds(100)) == std::future_status::ready)
119                 //      break;
120         //}
121         //ASSERT_NE(readWriteDispatchCount_, 5);
122         auto status = future.wait_for(std::chrono::milliseconds(100));
123         const bool waitResult = CommonAPI::DBus::checkReady(status);
124     ASSERT_EQ(waitResult, true);
125
126         ASSERT_EQ(callStatusFuture.get(), CommonAPI::CallStatus::SUCCESS);
127
128         auto futureResult = future.get();
129         const CommonAPI::CallStatus& callStatus = std::get<0>(futureResult);
130         const bool& nameHasOwner = std::get<1>(futureResult);
131
132         ASSERT_EQ(callStatus, CommonAPI::CallStatus::SUCCESS);
133         ASSERT_TRUE(nameHasOwner);
134 }
135
136 TEST_F(DBusDaemonProxyTest, NameOwnerChangedEvent) {
137         std::promise<bool> promise;
138         auto future = promise.get_future();
139
140         dbusConnection_->getDBusDaemonProxy()->getNameOwnerChangedEvent().subscribe(
141                         [&](const std::string& name, const std::string& oldOwner, const std::string& newOwner) {
142             static bool promiseIsSet = false;
143             if(!promiseIsSet) {
144                 promiseIsSet = true;
145                 promise.set_value(!name.empty() && (!oldOwner.empty() || !newOwner.empty()));
146             }
147         });
148
149         // Trigger NameOwnerChanged using a new DBusConnection
150         ASSERT_TRUE(CommonAPI::DBus::DBusConnection::getSessionBus()->connect());
151
152         //while (readWriteDispatchCount_ < 5) {
153         //      ASSERT_TRUE(doReadWriteDispatch());
154                 //if (future.wait_for(std::chrono::milliseconds(100)) == std::future_status::ready)
155                 //      break;
156         //}
157
158         //ASSERT_NE(readWriteDispatchCount_, 5);
159         ASSERT_TRUE(future.get());
160 }
161
162 } // namespace
163
164 int main(int argc, char** argv) {
165         ::testing::InitGoogleTest(&argc, argv);
166         return RUN_ALL_TESTS();
167 }