Extended validation for CommonAPI Addresses
[profile/ivi/common-api-dbus-runtime.git] / src / test / DBusMainLoopIntegrationTest.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
8 #include <gtest/gtest.h>
9
10 #include <cassert>
11 #include <cstdint>
12 #include <iostream>
13 #include <functional>
14 #include <memory>
15 #include <stdint.h>
16 #include <string>
17 #include <utility>
18 #include <tuple>
19 #include <type_traits>
20 #include <glib.h>
21
22 #include <CommonAPI/CommonAPI.h>
23
24 #include <CommonAPI/DBus/DBusConnection.h>
25 #include <CommonAPI/DBus/DBusProxy.h>
26 #include <CommonAPI/DBus/DBusRuntime.h>
27
28 #include "DBusTestUtils.h"
29 #include "DemoMainLoop.h"
30
31 #include "commonapi/tests/PredefinedTypeCollection.h"
32 #include "commonapi/tests/DerivedTypeCollection.h"
33 #include "commonapi/tests/TestInterfaceProxy.h"
34 #include "commonapi/tests/TestInterfaceStubDefault.h"
35 #include "commonapi/tests/TestInterfaceDBusStubAdapter.h"
36
37 #include "commonapi/tests/TestInterfaceDBusProxy.h"
38
39
40 const std::string testAddress1 = "local:my.first.test:commonapi.address.one";
41 const std::string testAddress2 = "local:my.second.test:commonapi.address.two";
42 const std::string testAddress3 = "local:my.third.test:commonapi.address.three";
43 const std::string testAddress4 = "local:my.fourth.test:commonapi.address.four";
44 const std::string testAddress5 = "local:my.fifth.test:commonapi.address.five";
45 const std::string testAddress6 = "local:my.sixth.test:commonapi.address.six";
46 const std::string testAddress7 = "local:my.seventh.test:commonapi.address.seven";
47 const std::string testAddress8 = "local:my.eigth.test:commonapi.address.eight";
48
49 //####################################################################################################################
50
51 class DBusBasicMainLoopTest: public ::testing::Test {
52 protected:
53     virtual void SetUp() {
54     }
55
56     virtual void TearDown() {
57     }
58 };
59
60
61 TEST_F(DBusBasicMainLoopTest, MainloopContextCanBeCreated) {
62     std::shared_ptr<CommonAPI::Runtime> runtime = CommonAPI::Runtime::load();
63     ASSERT_TRUE((bool) runtime);
64
65     std::shared_ptr<CommonAPI::MainLoopContext> context = runtime->getNewMainLoopContext();
66     ASSERT_TRUE((bool) context);
67 }
68
69
70 TEST_F(DBusBasicMainLoopTest, SeveralMainloopContextsCanBeCreated) {
71     std::shared_ptr<CommonAPI::Runtime> runtime = CommonAPI::Runtime::load();
72     ASSERT_TRUE((bool)runtime);
73
74     std::shared_ptr<CommonAPI::MainLoopContext> context1 = runtime->getNewMainLoopContext();
75     ASSERT_TRUE((bool) context1);
76     std::shared_ptr<CommonAPI::MainLoopContext> context2 = runtime->getNewMainLoopContext();
77     ASSERT_TRUE((bool) context2);
78     std::shared_ptr<CommonAPI::MainLoopContext> context3 = runtime->getNewMainLoopContext();
79     ASSERT_TRUE((bool) context3);
80
81     ASSERT_NE(context1, context2);
82     ASSERT_NE(context1, context3);
83     ASSERT_NE(context2, context3);
84 }
85
86 struct TestSource: public CommonAPI::DispatchSource {
87     TestSource(const std::string value, std::string& result): value_(value), result_(result) {}
88
89     bool prepare(int64_t& timeout) {
90         return true;
91     }
92     bool check() {
93         return true;
94     }
95     bool dispatch() {
96         result_.append(value_);
97         return false;
98     }
99
100  private:
101     std::string value_;
102     std::string& result_;
103 };
104
105 TEST_F(DBusBasicMainLoopTest, PrioritiesAreHandledCorrectlyInDemoMainloop) {
106     std::shared_ptr<CommonAPI::Runtime> runtime = CommonAPI::Runtime::load();
107     ASSERT_TRUE((bool) runtime);
108
109     std::shared_ptr<CommonAPI::MainLoopContext> context = runtime->getNewMainLoopContext();
110     ASSERT_TRUE((bool) context);
111
112     auto mainLoop = new CommonAPI::MainLoop(context);
113
114     std::string result = "";
115
116     TestSource* testSource1Default = new TestSource("A", result);
117     TestSource* testSource2Default = new TestSource("B", result);
118     TestSource* testSource1High = new TestSource("C", result);
119     TestSource* testSource1Low = new TestSource("D", result);
120     TestSource* testSource1VeryHigh = new TestSource("E", result);
121     context->registerDispatchSource(testSource1Default);
122     context->registerDispatchSource(testSource2Default, CommonAPI::DispatchPriority::DEFAULT);
123     context->registerDispatchSource(testSource1High, CommonAPI::DispatchPriority::HIGH);
124     context->registerDispatchSource(testSource1Low, CommonAPI::DispatchPriority::LOW);
125     context->registerDispatchSource(testSource1VeryHigh, CommonAPI::DispatchPriority::VERY_HIGH);
126
127     mainLoop->doSingleIteration(CommonAPI::TIMEOUT_INFINITE);
128
129     std::string reference("ECABD");
130     ASSERT_EQ(reference, result);
131 }
132
133
134 //####################################################################################################################
135
136 class DBusMainLoopTest: public ::testing::Test {
137 protected:
138     virtual void SetUp() {
139         runtime_ = CommonAPI::Runtime::load();
140         ASSERT_TRUE((bool) runtime_);
141
142         context_ = runtime_->getNewMainLoopContext();
143         ASSERT_TRUE((bool) context_);
144         mainLoop_ = new CommonAPI::MainLoop(context_);
145
146         mainloopFactory_ = runtime_->createFactory(context_);
147         ASSERT_TRUE((bool) mainloopFactory_);
148         standardFactory_ = runtime_->createFactory();
149         ASSERT_TRUE((bool) standardFactory_);
150
151         servicePublisher_ = runtime_->getServicePublisher();
152         ASSERT_TRUE((bool) servicePublisher_);
153     }
154
155     virtual void TearDown() {
156         delete mainLoop_;
157     }
158
159     std::shared_ptr<CommonAPI::Runtime> runtime_;
160     std::shared_ptr<CommonAPI::MainLoopContext> context_;
161     std::shared_ptr<CommonAPI::Factory> mainloopFactory_;
162     std::shared_ptr<CommonAPI::Factory> standardFactory_;
163     std::shared_ptr<CommonAPI::ServicePublisher> servicePublisher_;
164     CommonAPI::MainLoop* mainLoop_;
165 };
166
167
168 TEST_F(DBusMainLoopTest, ServiceInDemoMainloopCanBeAddressed) {
169     std::shared_ptr<commonapi::tests::TestInterfaceStubDefault> stub = std::make_shared<
170                     commonapi::tests::TestInterfaceStubDefault>();
171     ASSERT_TRUE(servicePublisher_->registerService(stub, testAddress1, mainloopFactory_));
172
173     auto proxy = standardFactory_->buildProxy<commonapi::tests::TestInterfaceProxy>(testAddress1);
174     ASSERT_TRUE((bool) proxy);
175
176     while (!proxy->isAvailable()) {
177         mainLoop_->doSingleIteration(50000);
178     }
179
180     uint32_t uint32Value = 42;
181     std::string stringValue = "Hai :)";
182
183     std::future<CommonAPI::CallStatus> futureStatus = proxy->testVoidPredefinedTypeMethodAsync(
184                     uint32Value,
185                     stringValue,
186                     [&] (const CommonAPI::CallStatus& status) {
187                         EXPECT_EQ(toString(CommonAPI::CallStatus::SUCCESS), toString(status));
188                         mainLoop_->stop();
189                     }
190     );
191
192     mainLoop_->run();
193
194     ASSERT_EQ(toString(CommonAPI::CallStatus::SUCCESS), toString(futureStatus.get()));
195
196     servicePublisher_->unregisterService(testAddress1);
197 }
198
199
200 TEST_F(DBusMainLoopTest, ProxyInDemoMainloopCanCallMethods) {
201     std::shared_ptr<commonapi::tests::TestInterfaceStubDefault> stub = std::make_shared<
202                     commonapi::tests::TestInterfaceStubDefault>();
203     ASSERT_TRUE(servicePublisher_->registerService(stub, testAddress2, standardFactory_));
204
205     usleep(500000);
206
207     auto proxy = mainloopFactory_->buildProxy<commonapi::tests::TestInterfaceProxy>(testAddress2);
208     ASSERT_TRUE((bool) proxy);
209
210     while (!proxy->isAvailable()) {
211         mainLoop_->doSingleIteration();
212         usleep(50000);
213     }
214
215     uint32_t uint32Value = 42;
216     std::string stringValue = "Hai :)";
217
218     std::future<CommonAPI::CallStatus> futureStatus = proxy->testVoidPredefinedTypeMethodAsync(
219                     uint32Value,
220                     stringValue,
221                     [&] (const CommonAPI::CallStatus& status) {
222                         EXPECT_EQ(toString(CommonAPI::CallStatus::SUCCESS), toString(status));
223                         mainLoop_->stop();
224                     }
225     );
226
227     mainLoop_->run();
228
229     ASSERT_EQ(toString(CommonAPI::CallStatus::SUCCESS), toString(futureStatus.get()));
230
231     servicePublisher_->unregisterService(testAddress2);
232 }
233
234 TEST_F(DBusMainLoopTest, ProxyAndServiceInSameDemoMainloopCanCommunicate) {
235     std::shared_ptr<commonapi::tests::TestInterfaceStubDefault> stub = std::make_shared<
236                     commonapi::tests::TestInterfaceStubDefault>();
237     ASSERT_TRUE(servicePublisher_->registerService(stub, testAddress4, mainloopFactory_));
238
239     auto proxy = mainloopFactory_->buildProxy<commonapi::tests::TestInterfaceProxy>(testAddress4);
240     ASSERT_TRUE((bool) proxy);
241
242     while (!proxy->isAvailable()) {
243         mainLoop_->doSingleIteration();
244         usleep(50000);
245     }
246
247     uint32_t uint32Value = 42;
248     std::string stringValue = "Hai :)";
249     bool running = true;
250
251     std::future<CommonAPI::CallStatus> futureStatus = proxy->testVoidPredefinedTypeMethodAsync(
252                     uint32Value,
253                     stringValue,
254                     [&] (const CommonAPI::CallStatus& status) {
255                         EXPECT_EQ(toString(CommonAPI::CallStatus::SUCCESS), toString(status));
256                         mainLoop_->stop();
257                     }
258     );
259
260     mainLoop_->run();
261
262     ASSERT_EQ(toString(CommonAPI::CallStatus::SUCCESS), toString(futureStatus.get()));
263
264     servicePublisher_->unregisterService(testAddress4);
265 }
266
267
268 class BigDataTestStub: public commonapi::tests::TestInterfaceStubDefault {
269     void testDerivedTypeMethod(
270             commonapi::tests::DerivedTypeCollection::TestEnumExtended2 testEnumExtended2InValue,
271             commonapi::tests::DerivedTypeCollection::TestMap testMapInValue,
272             commonapi::tests::DerivedTypeCollection::TestEnumExtended2& testEnumExtended2OutValue,
273             commonapi::tests::DerivedTypeCollection::TestMap& testMapOutValue) {
274         testEnumExtended2OutValue = testEnumExtended2InValue;
275         testMapOutValue = testMapInValue;
276     }
277 };
278
279
280 TEST_F(DBusMainLoopTest, ProxyAndServiceInSameDemoMainloopCanHandleBigData) {
281     std::shared_ptr<BigDataTestStub> stub = std::make_shared<
282                     BigDataTestStub>();
283     ASSERT_TRUE(servicePublisher_->registerService(stub, testAddress8, mainloopFactory_));
284
285     auto proxy = mainloopFactory_->buildProxy<commonapi::tests::TestInterfaceProxy>(testAddress8);
286     ASSERT_TRUE((bool) proxy);
287
288     while (!proxy->isAvailable()) {
289         mainLoop_->doSingleIteration();
290         usleep(50000);
291     }
292
293     uint32_t uint32Value = 42;
294     std::string stringValue = "Hai :)";
295     bool running = true;
296
297     commonapi::tests::DerivedTypeCollection::TestEnumExtended2 testEnumExtended2InValue =
298             commonapi::tests::DerivedTypeCollection::TestEnumExtended2::E_OK;
299     commonapi::tests::DerivedTypeCollection::TestMap testMapInValue;
300
301     // Estimated amount of data (differring padding at beginning/end of Map/Array etc. not taken into account):
302     // 4 + 4 + 500 * (4 + (4 + 4 + 100 * (11 + 1 + 4)) + 4 ) = 811008
303     for(uint32_t i = 0; i < 500; ++i) {
304         commonapi::tests::DerivedTypeCollection::TestArrayTestStruct testArrayTestStruct;
305         for(uint32_t j = 0; j < 100; ++j) {
306             commonapi::tests::DerivedTypeCollection::TestStruct testStruct("Hai all (:", j);
307             testArrayTestStruct.push_back(testStruct);
308         }
309         testMapInValue.insert( {i, testArrayTestStruct} );
310     }
311
312     std::future<CommonAPI::CallStatus> futureStatus = proxy->testDerivedTypeMethodAsync(
313             testEnumExtended2InValue,
314             testMapInValue,
315             [&] (const CommonAPI::CallStatus& status,
316                     commonapi::tests::DerivedTypeCollection::TestEnumExtended2 testEnumExtended2OutValue,
317                     commonapi::tests::DerivedTypeCollection::TestMap testMapOutValue) {
318                 EXPECT_EQ(toString(CommonAPI::CallStatus::SUCCESS), toString(status));
319                 EXPECT_EQ(testEnumExtended2InValue, testEnumExtended2OutValue);
320                 EXPECT_EQ(testMapInValue.size(), testMapOutValue.size());
321                 mainLoop_->stop();
322             }
323     );
324
325     mainLoop_->run();
326
327     ASSERT_EQ(toString(CommonAPI::CallStatus::SUCCESS), toString(futureStatus.get()));
328
329     servicePublisher_->unregisterService(testAddress8);
330 }
331
332 TEST_F(DBusMainLoopTest, DemoMainloopClientsHandleNonavailableServices) {
333     auto proxy = mainloopFactory_->buildProxy<commonapi::tests::TestInterfaceProxy>(testAddress3);
334     ASSERT_TRUE((bool) proxy);
335
336     uint32_t uint32Value = 42;
337     std::string stringValue = "Hai :)";
338
339     std::future<CommonAPI::CallStatus> futureStatus = proxy->testVoidPredefinedTypeMethodAsync(
340                     uint32Value,
341                     stringValue,
342                     [&] (const CommonAPI::CallStatus& status) {
343                         //Will never be called, @see DBusProxyAsyncCallbackHandler
344                         EXPECT_EQ(toString(CommonAPI::CallStatus::NOT_AVAILABLE), toString(status));
345                     }
346     );
347
348     ASSERT_EQ(toString(CommonAPI::CallStatus::NOT_AVAILABLE), toString(futureStatus.get()));
349 }
350
351 //##################################################################################################
352
353 class GDispatchWrapper: public GSource {
354  public:
355     GDispatchWrapper(CommonAPI::DispatchSource* dispatchSource): dispatchSource_(dispatchSource) {}
356     CommonAPI::DispatchSource* dispatchSource_;
357 };
358
359 gboolean dispatchPrepare(GSource* source, gint* timeout) {
360     int64_t eventTimeout;
361     return static_cast<GDispatchWrapper*>(source)->dispatchSource_->prepare(eventTimeout);
362 }
363
364 gboolean dispatchCheck(GSource* source) {
365     return static_cast<GDispatchWrapper*>(source)->dispatchSource_->check();
366 }
367
368 gboolean dispatchExecute(GSource* source, GSourceFunc callback, gpointer userData) {
369     static_cast<GDispatchWrapper*>(source)->dispatchSource_->dispatch();
370     return true;
371 }
372
373 gboolean gWatchDispatcher(GIOChannel *source, GIOCondition condition, gpointer userData) {
374     CommonAPI::Watch* watch = static_cast<CommonAPI::Watch*>(userData);
375     watch->dispatch(condition);
376     return true;
377 }
378
379 gboolean gTimeoutDispatcher(void* userData) {
380     return static_cast<CommonAPI::DispatchSource*>(userData)->dispatch();
381 }
382
383
384 static GSourceFuncs standardGLibSourceCallbackFuncs = {
385         dispatchPrepare,
386         dispatchCheck,
387         dispatchExecute,
388         NULL
389 };
390
391
392 class DBusInGLibMainLoopTest: public ::testing::Test {
393  protected:
394     virtual void SetUp() {
395         running_ = true;
396
397         std::shared_ptr<CommonAPI::Runtime> runtime_ = CommonAPI::Runtime::load();
398         ASSERT_TRUE((bool) runtime_);
399
400         context_ = runtime_->getNewMainLoopContext();
401         ASSERT_TRUE((bool) context_);
402
403         doSubscriptions();
404
405         mainloopFactory_ = runtime_->createFactory(context_);
406         ASSERT_TRUE((bool) mainloopFactory_);
407         standardFactory_ = runtime_->createFactory();
408         ASSERT_TRUE((bool) standardFactory_);
409
410         servicePublisher_ = runtime_->getServicePublisher();
411         ASSERT_TRUE((bool) servicePublisher_);
412     }
413
414     virtual void TearDown() {
415     }
416
417     void doSubscriptions() {
418         context_->subscribeForTimeouts(
419                 std::bind(&DBusInGLibMainLoopTest::timeoutAddedCallback, this, std::placeholders::_1, std::placeholders::_2),
420                 std::bind(&DBusInGLibMainLoopTest::timeoutRemovedCallback, this, std::placeholders::_1)
421         );
422
423         context_->subscribeForWatches(
424                 std::bind(&DBusInGLibMainLoopTest::watchAddedCallback, this, std::placeholders::_1, std::placeholders::_2),
425                 std::bind(&DBusInGLibMainLoopTest::watchRemovedCallback, this, std::placeholders::_1)
426         );
427
428         context_->subscribeForWakeupEvents(
429                 std::bind(&DBusInGLibMainLoopTest::wakeupMain, this)
430         );
431     }
432
433
434  public:
435     std::shared_ptr<CommonAPI::MainLoopContext> context_;
436     std::shared_ptr<CommonAPI::Factory> mainloopFactory_;
437     std::shared_ptr<CommonAPI::Factory> standardFactory_;
438     std::shared_ptr<CommonAPI::ServicePublisher> servicePublisher_;
439     bool running_;
440     static constexpr bool mayBlock_ = true;
441
442     std::map<CommonAPI::DispatchSource*, GSource*> gSourceMappings;
443
444     GIOChannel* dbusChannel_;
445
446     void watchAddedCallback(CommonAPI::Watch* watch, const CommonAPI::DispatchPriority dispatchPriority) {
447         const pollfd& fileDesc = watch->getAssociatedFileDescriptor();
448         dbusChannel_ = g_io_channel_unix_new(fileDesc.fd);
449
450         GSource* gWatch = g_io_create_watch(dbusChannel_, static_cast<GIOCondition>(fileDesc.events));
451         g_source_set_callback(gWatch, reinterpret_cast<GSourceFunc>(&gWatchDispatcher), watch, NULL);
452
453         const auto& dependentSources = watch->getDependentDispatchSources();
454         for (auto dependentSourceIterator = dependentSources.begin();
455                 dependentSourceIterator != dependentSources.end();
456                 dependentSourceIterator++) {
457             GSource* gDispatchSource = g_source_new(&standardGLibSourceCallbackFuncs, sizeof(GDispatchWrapper));
458             static_cast<GDispatchWrapper*>(gDispatchSource)->dispatchSource_ = *dependentSourceIterator;
459
460             g_source_add_child_source(gWatch, gDispatchSource);
461
462             gSourceMappings.insert( {*dependentSourceIterator, gDispatchSource} );
463         }
464         g_source_attach(gWatch, NULL);
465     }
466
467     void watchRemovedCallback(CommonAPI::Watch* watch) {
468         g_source_remove_by_user_data(watch);
469
470         if(dbusChannel_) {
471             g_io_channel_unref(dbusChannel_);
472             dbusChannel_ = NULL;
473         }
474
475         const auto& dependentSources = watch->getDependentDispatchSources();
476         for (auto dependentSourceIterator = dependentSources.begin();
477                 dependentSourceIterator != dependentSources.end();
478                 dependentSourceIterator++) {
479             GSource* gDispatchSource = g_source_new(&standardGLibSourceCallbackFuncs, sizeof(GDispatchWrapper));
480             GSource* gSource = gSourceMappings.find(*dependentSourceIterator)->second;
481             g_source_destroy(gSource);
482             g_source_unref(gSource);
483         }
484     }
485
486     void timeoutAddedCallback(CommonAPI::Timeout* commonApiTimeoutSource, const CommonAPI::DispatchPriority dispatchPriority) {
487         GSource* gTimeoutSource = g_timeout_source_new(commonApiTimeoutSource->getTimeoutInterval());
488         g_source_set_callback(gTimeoutSource, &gTimeoutDispatcher, commonApiTimeoutSource, NULL);
489         g_source_attach(gTimeoutSource, NULL);
490     }
491
492     void timeoutRemovedCallback(CommonAPI::Timeout* timeout) {
493         g_source_remove_by_user_data(timeout);
494     }
495
496     void wakeupMain() {
497         g_main_context_wakeup(NULL);
498     }
499 };
500
501
502 TEST_F(DBusInGLibMainLoopTest, ProxyInGLibMainloopCanCallMethods) {
503     auto proxy = mainloopFactory_->buildProxy<commonapi::tests::TestInterfaceProxy>(testAddress5);
504     ASSERT_TRUE((bool) proxy);
505
506     std::shared_ptr<commonapi::tests::TestInterfaceStubDefault> stub = std::make_shared<
507                     commonapi::tests::TestInterfaceStubDefault>();
508     ASSERT_TRUE(servicePublisher_->registerService(stub, testAddress5, standardFactory_));
509
510     while(!proxy->isAvailable()) {
511         g_main_context_iteration(NULL, mayBlock_);
512         usleep(50000);
513     }
514
515     uint32_t uint32Value = 24;
516     std::string stringValue = "Hai :)";
517
518     std::future<CommonAPI::CallStatus> futureStatus = proxy->testVoidPredefinedTypeMethodAsync(
519                     uint32Value,
520                     stringValue,
521                     [&] (const CommonAPI::CallStatus& status) {
522                         EXPECT_EQ(toString(CommonAPI::CallStatus::SUCCESS), toString(status));
523                         running_ = false;
524                     }
525     );
526
527     while(running_) {
528         g_main_context_iteration(NULL, mayBlock_);
529         usleep(50000);
530     }
531
532     ASSERT_EQ(toString(CommonAPI::CallStatus::SUCCESS), toString(futureStatus.get()));
533
534     servicePublisher_->unregisterService(testAddress5);
535 }
536
537
538 TEST_F(DBusInGLibMainLoopTest, ServiceInGLibMainloopCanBeAddressed) {
539     auto proxy = standardFactory_->buildProxy<commonapi::tests::TestInterfaceProxy>(testAddress6);
540     ASSERT_TRUE((bool) proxy);
541
542     std::shared_ptr<commonapi::tests::TestInterfaceStubDefault> stub = std::make_shared<
543                     commonapi::tests::TestInterfaceStubDefault>();
544     ASSERT_TRUE(servicePublisher_->registerService(stub, testAddress6, mainloopFactory_));
545
546     uint32_t uint32Value = 42;
547     std::string stringValue = "Ciao (:";
548
549     while(!proxy->isAvailable()) {
550         g_main_context_iteration(NULL, mayBlock_);
551         usleep(50000);
552     }
553
554     std::future<CommonAPI::CallStatus> futureStatus = proxy->testVoidPredefinedTypeMethodAsync(
555                     uint32Value,
556                     stringValue,
557                     [&] (const CommonAPI::CallStatus& status) {
558                         EXPECT_EQ(toString(CommonAPI::CallStatus::SUCCESS), toString(status));
559                         running_ = false;
560                         //Wakeup needed as the service will be in a poll-block when the client
561                         //call returns, and no other timeout is present to get him out of there.
562                         g_main_context_wakeup(NULL);
563                     }
564     );
565
566     while(running_) {
567         g_main_context_iteration(NULL, mayBlock_);
568         usleep(50000);
569     }
570
571     ASSERT_EQ(toString(CommonAPI::CallStatus::SUCCESS), toString(futureStatus.get()));
572
573     servicePublisher_->unregisterService(testAddress6);
574 }
575
576
577 TEST_F(DBusInGLibMainLoopTest, ProxyAndServiceInSameGlibMainloopCanCommunicate) {
578     auto proxy = mainloopFactory_->buildProxy<commonapi::tests::TestInterfaceProxy>(testAddress7);
579     ASSERT_TRUE((bool) proxy);
580
581     std::shared_ptr<commonapi::tests::TestInterfaceStubDefault> stub = std::make_shared<
582                     commonapi::tests::TestInterfaceStubDefault>();
583     ASSERT_TRUE(servicePublisher_->registerService(stub, testAddress7, mainloopFactory_));
584
585     uint32_t uint32Value = 42;
586     std::string stringValue = "Ciao (:";
587
588     while(!proxy->isAvailable()) {
589         g_main_context_iteration(NULL, mayBlock_);
590         usleep(50000);
591     }
592
593     std::future<CommonAPI::CallStatus> futureStatus = proxy->testVoidPredefinedTypeMethodAsync(
594                     uint32Value,
595                     stringValue,
596                     [&] (const CommonAPI::CallStatus& status) {
597                         EXPECT_EQ(toString(CommonAPI::CallStatus::SUCCESS), toString(status));
598                         running_ = false;
599                         //Wakeup needed as the service will be in a poll-block when the client
600                         //call returns, and no other timeout is present to get him out of there.
601                         g_main_context_wakeup(NULL);
602                     }
603     );
604
605     while(running_) {
606         g_main_context_iteration(NULL, mayBlock_);
607         usleep(50000);
608     }
609
610     ASSERT_EQ(toString(CommonAPI::CallStatus::SUCCESS), toString(futureStatus.get()));
611
612     servicePublisher_->unregisterService(testAddress7);
613 }
614
615
616 int main(int argc, char** argv) {
617     ::testing::InitGoogleTest(&argc, argv);
618     return RUN_ALL_TESTS();
619 }