tests: fix blocking semantic in DBusProxyTest
[profile/ivi/common-api-dbus-runtime.git] / src / test / DBusStubAdapterTest.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/DBusFunctionalHash.h>
8 #include <CommonAPI/DBus/DBusStubAdapterHelper.h>
9
10 #include <cassert>
11 #include <iostream>
12 #include <tuple>
13
14 static uint32_t dispatchedMessageCount;
15
16 class TestStubRemoteEventHandler {
17  public:
18     virtual ~TestStubRemoteEventHandler() { }
19
20     virtual bool onRemoteSetTestAttribute(int32_t testValue) = 0;
21
22     virtual void onRemoteTestAttributeChanged() = 0;
23 };
24
25 class TestStubAdapter: virtual public CommonAPI::StubAdapter {
26  public:
27     virtual void fireTestAttributeChanged(const int32_t& testValue)  = 0;
28 };
29
30 class TestStub: public CommonAPI::Stub<TestStubAdapter, TestStubRemoteEventHandler> {
31  public:
32     TestStub(): remoteEventHandler_(this) {
33     }
34
35     virtual TestStubRemoteEventHandler* initStubAdapter(const std::shared_ptr<TestStubAdapter>& stubAdapter) {
36         return &remoteEventHandler_;
37     }
38
39     void getEmptyResponse() {
40         std::cout << "onGetEmptyResponse()\n";
41         dispatchedMessageCount++;
42     }
43
44     void getDeepCopy(int32_t inValue, int32_t& outValue) {
45         outValue = inValue;
46         std::cout << "getDeepCopy(inValue=" << inValue << ", outValue=" << outValue << ")\n";
47         dispatchedMessageCount++;
48     }
49
50     void getDeepCopies(std::vector<int32_t> inValues, std::vector<int32_t>& outValues) {
51         outValues = inValues;
52         std::cout << "getDeepCopies(inValues=" << inValues.size() << ", outValues=" << outValues.size() << ")\n";
53         dispatchedMessageCount++;
54     }
55
56     void getShallowCopy(int32_t inValue, int32_t& outValue) {
57         outValue = inValue;
58         std::cout << "getShallowCopy(inValue=" << inValue << ", outValue=" << outValue << ")\n";
59         dispatchedMessageCount++;
60     }
61
62     void getShallowCopies(std::vector<int32_t> inValues, std::vector<int32_t>& outValues) {
63         outValues = inValues;
64         std::cout << "getShallowCopies(inValues=" << inValues.size() << ", outValues=" << outValues.size() << ")\n";
65         dispatchedMessageCount++;
66     }
67
68     const int32_t& getTestAttribute() {
69         return testAttributeValue_;
70     }
71
72  private:
73     class RemoteEventHandler: public TestStubRemoteEventHandler {
74      public:
75         RemoteEventHandler(TestStub* stub): stub_(stub) {
76         }
77
78         virtual bool onRemoteSetTestAttribute(int32_t testValue) {
79             std::cout << "RemoteEventHandler::onRemoteSetTestAttribute(" << testValue << "): oldValue = " << stub_->testAttributeValue_ << "\n";
80             const bool valueChanged = (stub_->testAttributeValue_ != testValue);
81             stub_->testAttributeValue_ = testValue;
82             return valueChanged;
83         }
84
85         virtual void onRemoteTestAttributeChanged() {
86             std::cout << "RemoteEventHandler::onRemoteTestAttributeChanged()\n";
87         }
88
89      private:
90         TestStub* stub_;
91     };
92
93     RemoteEventHandler remoteEventHandler_;
94     int32_t testAttributeValue_;
95 };
96
97 typedef CommonAPI::DBus::DBusStubAdapterHelper<TestStub> TestStubAdapterHelper;
98
99 class TestDBusStubAdapter: public TestStubAdapter,  public TestStubAdapterHelper {
100  public:
101     TestDBusStubAdapter(const std::string& commonApiAddress,
102                         const std::string& dbusBusName,
103                         const std::string& dbusObjectPath,
104                         const std::shared_ptr<CommonAPI::DBus::DBusConnection>& dbusConnection,
105                         const std::shared_ptr<TestStub>& testStub) :
106                     TestStubAdapterHelper(
107                                     commonApiAddress,
108                                     dbusBusName,
109                                     dbusObjectPath,
110                                     "org.genivi.CommonAPI.DBus.TestInterface",
111                                     dbusConnection,
112                                     testStub) {
113     }
114
115     virtual void fireTestAttributeChanged(const int32_t& testValue) {
116         std::cout << "TestDBusStubAdapter::fireTestAttributeChanged(" << testValue << ")\n";
117     }
118
119  protected:
120     virtual const char* getMethodsDBusIntrospectionXmlData() const;
121 };
122
123 const char* TestDBusStubAdapter::getMethodsDBusIntrospectionXmlData() const {
124     return "<method name=\"GetEmptyResponse\">\n"
125            "</method>\n"
126            "<method name=\"GetDeepCopy\">\n"
127                     "<arg type=\"i\" name=\"int32InValue\" direction=\"in\"/>\n"
128                     "<arg type=\"i\" name=\"int32OutValue\" direction=\"out\"/>\n"
129            "</method>\n"
130            "<method name=\"GetDeepCopies\">\n"
131                     "<arg type=\"ai\" name=\"int32InValues\" direction=\"in\"/>\n"
132                     "<arg type=\"ai\" name=\"int32OutValues\" direction=\"out\"/>\n"
133            "</method>\n"
134            "<method name=\"GetShallowCopy\">\n"
135                     "<arg type=\"i\" name=\"int32InValue\" direction=\"in\"/>\n"
136                     "<arg type=\"i\" name=\"int32OutValue\" direction=\"out\"/>\n"
137            "</method>\n"
138            "<method name=\"GetShallowCopies\">\n"
139                     "<arg type=\"ai\" name=\"int32InValues\" direction=\"in\"/>\n"
140                     "<arg type=\"ai\" name=\"int32OutValues\" direction=\"out\"/>\n"
141            "</method>"
142            "<method name=\"SetTestAttribute\">\n"
143                     "<arg type=\"i\" name=\"value\" direction=\"in\"/>\n"
144                     "<arg type=\"i\" name=\"value\" direction=\"out\"/>\n"
145            "</method>"
146            ;
147 }
148
149 namespace {
150 static CommonAPI::DBus::DBusMethodWithReplyStubDispatcher<
151                     TestStub,
152                     std::tuple<>,
153                     std::tuple<> > getEmptyResponseStubDispatcher(&TestStub::getEmptyResponse, "");
154 static CommonAPI::DBus::DBusMethodWithReplyStubDispatcher<
155                     TestStub,
156                     std::tuple<int32_t>,
157                     std::tuple<int32_t> > getDeepCopyStubDispatcher(&TestStub::getDeepCopy, "i");
158 static CommonAPI::DBus::DBusMethodWithReplyStubDispatcher<
159                     TestStub,
160                     std::tuple<std::vector<int32_t>>,
161                     std::tuple<std::vector<int32_t>> > getDeepCopiesStubDispatcher(&TestStub::getDeepCopies, "ai");
162 static CommonAPI::DBus::DBusMethodWithReplyStubDispatcher<
163                     TestStub,
164                     std::tuple<int32_t>,
165                     std::tuple<int32_t> > getShallowCopyStubDispatcher(&TestStub::getShallowCopy, "i");
166 static CommonAPI::DBus::DBusMethodWithReplyStubDispatcher<
167                     TestStub,
168                     std::tuple<std::vector<int32_t>>,
169                     std::tuple<std::vector<int32_t>> > getShallowCopiesStubDispatcher(&TestStub::getShallowCopies, "ai");
170 static CommonAPI::DBus::DBusSetObservableAttributeStubDispatcher<TestStub, int32_t> setTestAttributeStubDispatcher(
171                                     &TestStub::getTestAttribute,
172                                     &TestStubRemoteEventHandler::onRemoteSetTestAttribute,
173                                     &TestStubRemoteEventHandler::onRemoteTestAttributeChanged,
174                                     &TestStubAdapter::fireTestAttributeChanged,
175                                     "i");
176 }
177
178 template<>
179 const TestStubAdapterHelper::StubDispatcherTable TestStubAdapterHelper::stubDispatcherTable_ = {
180      { {"GetEmptyResponse", ""}, &getEmptyResponseStubDispatcher },
181      { {"GetDeepCopy", "i"}, &getDeepCopyStubDispatcher },
182      { {"GetDeepCopies", "ai"}, &getDeepCopiesStubDispatcher },
183      { {"GetShallowCopy", "i"}, &getShallowCopyStubDispatcher },
184      { {"GetShallowCopies", "ai"}, &getShallowCopiesStubDispatcher },
185      { {"SetTestAttribute", "i"}, &setTestAttributeStubDispatcher }
186 };
187
188 int main(void) {
189     auto dbusConnection = CommonAPI::DBus::DBusConnection::getSessionBus();
190
191     if (!dbusConnection->isConnected())
192         dbusConnection->connect();
193
194     assert(dbusConnection->isConnected());
195
196     const bool serviceNameAcquired = dbusConnection->requestServiceNameAndBlock(
197                     "org.genivi.CommonAPI.DBus.TestDBusInterfaceAdapter");
198     assert(serviceNameAcquired);
199
200     auto testStub = std::make_shared<TestStub>();
201     auto testStubAdapter = std::make_shared<TestDBusStubAdapter>(
202                     "my:common.api:address.for.dbus",
203                     "org.genivi.CommonAPI.DBus.TestDBusInterfaceAdapter",
204                     "/common/api/dbus/TestDBusInterfaceAdapter",
205                     dbusConnection,
206                     testStub);
207     testStubAdapter->init();
208
209     auto dbusMessageCall = CommonAPI::DBus::DBusMessage::createMethodCall(
210                     "org.genivi.CommonAPI.DBus.TestDBusInterfaceAdapter",
211                     testStubAdapter->getObjectPath().c_str(),
212                     testStubAdapter->getServiceId().c_str(),
213                     "GetEmptyResponse");
214
215     const bool messageSent = dbusConnection->sendDBusMessage(dbusMessageCall);
216     assert(messageSent);
217
218     for (int i = 0; i < 10; i++) {
219         dbusConnection->readWriteDispatch(100);
220     }
221
222     assert(dispatchedMessageCount > 0);
223
224     return 0;
225 }