IPC: Fixed DisconnectedPeerError test
[platform/core/security/vasum.git] / tests / unit_tests / ipc / ut-ipc.cpp
1 /*
2  *  Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *  Contact: Jan Olszak <j.olszak@samsung.com>
5  *
6  *  Licensed under the Apache License, Version 2.0 (the "License");
7  *  you may not use this file except in compliance with the License.
8  *  You may obtain a copy of the License at
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
12  *  Unless required by applicable law or agreed to in writing, software
13  *  distributed under the License is distributed on an "AS IS" BASIS,
14  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  *  See the License for the specific language governing permissions and
16  *  limitations under the License
17  */
18
19
20 /**
21  * @file
22  * @author  Jan Olszak (j.olszak@samsung.com)
23  * @brief   Tests of the IPC
24  */
25
26 // TODO: Test connection limit
27 // TODO: Refactor tests - function for setting up env
28 // TODO: Callback wrapper that waits till the callback is called
29
30
31 #include "config.hpp"
32 #include "ut.hpp"
33
34 #include "ipc/service.hpp"
35 #include "ipc/client.hpp"
36 #include "ipc/ipc-gsource.hpp"
37 #include "ipc/types.hpp"
38 #include "utils/glib-loop.hpp"
39
40 #include "config/fields.hpp"
41 #include "logger/logger.hpp"
42
43 #include <atomic>
44 #include <random>
45 #include <string>
46 #include <thread>
47 #include <chrono>
48 #include <utility>
49 #include <boost/filesystem.hpp>
50
51 using namespace vasum;
52 using namespace vasum::ipc;
53 using namespace vasum::utils;
54 using namespace std::placeholders;
55 namespace fs = boost::filesystem;
56
57 namespace {
58 struct Fixture {
59     std::string socketPath;
60
61     Fixture()
62         : socketPath(fs::unique_path("/tmp/ipc-%%%%.socket").string())
63     {
64     }
65     ~Fixture()
66     {
67         fs::remove(socketPath);
68     }
69 };
70
71 struct SendData {
72     int intVal;
73     SendData(int i = 0): intVal(i) {}
74
75     CONFIG_REGISTER
76     (
77         intVal
78     )
79 };
80
81 struct LongSendData {
82     LongSendData(int i = 0, int waitTime = 1000): mSendData(i), mWaitTime(waitTime), intVal(i) {}
83
84     template<typename Visitor>
85     void accept(Visitor visitor)
86     {
87         std::this_thread::sleep_for(std::chrono::milliseconds(mWaitTime));
88         mSendData.accept(visitor);
89     }
90     template<typename Visitor>
91     void accept(Visitor visitor) const
92     {
93         std::this_thread::sleep_for(std::chrono::milliseconds(mWaitTime));
94         mSendData.accept(visitor);
95     }
96
97     SendData mSendData;
98     int mWaitTime;
99     int intVal;
100 };
101
102 struct EmptyData {
103     CONFIG_REGISTER_EMPTY
104 };
105
106 struct ThrowOnAcceptData {
107     template<typename Visitor>
108     void accept(Visitor)
109     {
110         throw std::runtime_error("intentional failure in accept");
111     }
112     template<typename Visitor>
113     void accept(Visitor) const
114     {
115         throw std::runtime_error("intentional failure in accept const");
116     }
117 };
118
119 std::shared_ptr<EmptyData> returnEmptyCallback(const FileDescriptor, std::shared_ptr<EmptyData>&)
120 {
121     return std::shared_ptr<EmptyData>(new EmptyData());
122 }
123
124 std::shared_ptr<SendData> returnDataCallback(const FileDescriptor, std::shared_ptr<SendData>&)
125 {
126     return std::shared_ptr<SendData>(new SendData(1));
127 }
128
129 std::shared_ptr<SendData> echoCallback(const FileDescriptor, std::shared_ptr<SendData>& data)
130 {
131     return data;
132 }
133
134 std::shared_ptr<SendData> longEchoCallback(const FileDescriptor, std::shared_ptr<SendData>& data)
135 {
136     std::this_thread::sleep_for(std::chrono::seconds(1));
137     return data;
138 }
139
140 FileDescriptor connect(Service& s, Client& c)
141 {
142     // Connects the Client to the Service and returns Clients FileDescriptor
143     std::mutex mutex;
144     std::condition_variable cv;
145
146     FileDescriptor peerFD = 0;
147     auto newPeerCallback = [&cv, &peerFD, &mutex](const FileDescriptor newFD) {
148         std::unique_lock<std::mutex> lock(mutex);
149         peerFD = newFD;
150         cv.notify_all();
151     };
152
153     // TODO: On timeout remove the callback
154     s.setNewPeerCallback(newPeerCallback);
155
156     if (!s.isStarted()) {
157         s.start();
158     }
159
160     c.start();
161
162
163     std::unique_lock<std::mutex> lock(mutex);
164     BOOST_REQUIRE(cv.wait_for(lock, std::chrono::milliseconds(2000), [&peerFD]() {
165         return peerFD != 0;
166     }));
167
168     return peerFD;
169 }
170
171
172
173 #if GLIB_CHECK_VERSION(2,36,0)
174
175 std::pair<FileDescriptor, IPCGSource::Pointer> connectServiceGSource(Service& s, Client& c)
176 {
177     std::mutex mutex;
178     std::condition_variable cv;
179
180     FileDescriptor peerFD = 0;
181     IPCGSource::Pointer ipcGSourcePtr = IPCGSource::create(s.getFDs(), std::bind(&Service::handle, &s, _1, _2));
182
183     auto newPeerCallback = [&cv, &peerFD, &mutex, ipcGSourcePtr](const FileDescriptor newFD) {
184         if (ipcGSourcePtr) {
185             //TODO: Remove this if
186             ipcGSourcePtr->addFD(newFD);
187         }
188         std::unique_lock<std::mutex> lock(mutex);
189         peerFD = newFD;
190         cv.notify_all();
191     };
192
193
194     // TODO: On timeout remove the callback
195     s.setNewPeerCallback(newPeerCallback);
196     s.setRemovedPeerCallback(std::bind(&IPCGSource::removeFD, ipcGSourcePtr, _1));
197
198     // Service starts to process
199     ipcGSourcePtr->attach();
200
201     c.start();
202
203     std::unique_lock<std::mutex> lock(mutex);
204     BOOST_REQUIRE(cv.wait_for(lock, std::chrono::milliseconds(2000), [&peerFD]() {
205         return peerFD != 0;
206     }));
207
208     return std::make_pair(peerFD, ipcGSourcePtr);
209 }
210
211 std::pair<FileDescriptor, IPCGSource::Pointer> connectClientGSource(Service& s, Client& c)
212 {
213     // Connects the Client to the Service and returns Clients FileDescriptor
214     std::mutex mutex;
215     std::condition_variable cv;
216
217     FileDescriptor peerFD = 0;
218     auto newPeerCallback = [&cv, &peerFD, &mutex](const FileDescriptor newFD) {
219         std::unique_lock<std::mutex> lock(mutex);
220         peerFD = newFD;
221         cv.notify_all();
222     };
223     // TODO: On timeout remove the callback
224     s.setNewPeerCallback(newPeerCallback);
225
226     if (!s.isStarted()) {
227         // Service starts to process
228         s.start();
229     }
230
231
232     c.connect();
233     IPCGSource::Pointer ipcGSourcePtr = IPCGSource::create(c.getFDs(),
234                                                            std::bind(&Client::handle, &c, _1, _2));
235
236     ipcGSourcePtr->attach();
237
238     std::unique_lock<std::mutex> lock(mutex);
239     BOOST_REQUIRE(cv.wait_for(lock, std::chrono::milliseconds(2000), [&peerFD]() {
240         return peerFD != 0;
241     }));
242
243     return std::make_pair(peerFD, ipcGSourcePtr);
244 }
245
246 #endif // GLIB_CHECK_VERSION
247
248
249 void testEcho(Client& c, const MethodID methodID)
250 {
251     std::shared_ptr<SendData> sentData(new SendData(34));
252     std::shared_ptr<SendData> recvData = c.callSync<SendData, SendData>(methodID, sentData, 1000);
253     BOOST_CHECK_EQUAL(recvData->intVal, sentData->intVal);
254 }
255
256 void testEcho(Service& s, const MethodID methodID, const FileDescriptor peerFD)
257 {
258     std::shared_ptr<SendData> sentData(new SendData(56));
259     std::shared_ptr<SendData> recvData = s.callSync<SendData, SendData>(methodID, peerFD, sentData, 1000);
260     BOOST_CHECK_EQUAL(recvData->intVal, sentData->intVal);
261 }
262
263 } // namespace
264
265
266 BOOST_FIXTURE_TEST_SUITE(IPCSuite, Fixture)
267
268 BOOST_AUTO_TEST_CASE(ConstructorDestructor)
269 {
270     Service s(socketPath);
271     Client c(socketPath);
272 }
273
274 BOOST_AUTO_TEST_CASE(ServiceAddRemoveMethod)
275 {
276     Service s(socketPath);
277
278     s.addMethodHandler<EmptyData, EmptyData>(1, returnEmptyCallback);
279     s.addMethodHandler<SendData, SendData>(1, returnDataCallback);
280
281     s.start();
282
283     s.addMethodHandler<SendData, SendData>(1, echoCallback);
284     s.addMethodHandler<SendData, SendData>(2, returnDataCallback);
285
286     Client c(socketPath);
287     c.start();
288     testEcho(c, 1);
289
290     s.removeMethod(1);
291     s.removeMethod(2);
292
293     BOOST_CHECK_THROW(testEcho(c, 2), IPCException);
294 }
295
296 BOOST_AUTO_TEST_CASE(ClientAddRemoveMethod)
297 {
298     Service s(socketPath);
299     Client c(socketPath);
300     c.addMethodHandler<EmptyData, EmptyData>(1, returnEmptyCallback);
301     c.addMethodHandler<SendData, SendData>(1, returnDataCallback);
302
303     FileDescriptor peerFD = connect(s, c);
304
305     c.addMethodHandler<SendData, SendData>(1, echoCallback);
306     c.addMethodHandler<SendData, SendData>(2, returnDataCallback);
307
308     testEcho(s, 1, peerFD);
309
310     c.removeMethod(1);
311     c.removeMethod(2);
312
313     BOOST_CHECK_THROW(testEcho(s, 1, peerFD), IPCException);
314 }
315
316 BOOST_AUTO_TEST_CASE(ServiceStartStop)
317 {
318     Service s(socketPath);
319
320     s.addMethodHandler<SendData, SendData>(1, returnDataCallback);
321
322     s.start();
323     s.stop();
324     s.start();
325     s.stop();
326
327     s.start();
328     s.start();
329 }
330
331 BOOST_AUTO_TEST_CASE(ClientStartStop)
332 {
333     Service s(socketPath);
334     Client c(socketPath);
335     c.addMethodHandler<SendData, SendData>(1, returnDataCallback);
336
337     c.start();
338     c.stop();
339     c.start();
340     c.stop();
341
342     c.start();
343     c.start();
344
345     c.stop();
346     c.stop();
347 }
348
349 BOOST_AUTO_TEST_CASE(SyncClientToServiceEcho)
350 {
351     Service s(socketPath);
352     s.addMethodHandler<SendData, SendData>(1, echoCallback);
353     s.addMethodHandler<SendData, SendData>(2, echoCallback);
354
355     s.start();
356     Client c(socketPath);
357     c.start();
358     testEcho(c, 1);
359     testEcho(c, 2);
360 }
361
362 BOOST_AUTO_TEST_CASE(Restart)
363 {
364     Service s(socketPath);
365     s.addMethodHandler<SendData, SendData>(1, echoCallback);
366     s.start();
367     s.addMethodHandler<SendData, SendData>(2, echoCallback);
368
369     Client c(socketPath);
370     c.start();
371     testEcho(c, 1);
372     testEcho(c, 2);
373
374     c.stop();
375     c.start();
376
377     testEcho(c, 1);
378     testEcho(c, 2);
379
380     s.stop();
381     s.start();
382
383     testEcho(c, 1);
384     testEcho(c, 2);
385 }
386
387 BOOST_AUTO_TEST_CASE(SyncServiceToClientEcho)
388 {
389     Service s(socketPath);
390     Client c(socketPath);
391     c.addMethodHandler<SendData, SendData>(1, echoCallback);
392     FileDescriptor peerFD = connect(s, c);
393
394     std::shared_ptr<SendData> sentData(new SendData(56));
395     std::shared_ptr<SendData> recvData = s.callSync<SendData, SendData>(1, peerFD, sentData);
396     BOOST_CHECK_EQUAL(recvData->intVal, sentData->intVal);
397 }
398
399 BOOST_AUTO_TEST_CASE(AsyncClientToServiceEcho)
400 {
401     // Setup Service and Client
402     Service s(socketPath);
403     s.addMethodHandler<SendData, SendData>(1, echoCallback);
404     s.start();
405     Client c(socketPath);
406     c.start();
407
408     std::mutex mutex;
409     std::condition_variable cv;
410
411     //Async call
412     std::shared_ptr<SendData> sentData(new SendData(34));
413     std::shared_ptr<SendData> recvData;
414     auto dataBack = [&cv, &recvData, &mutex](ipc::Status status, std::shared_ptr<SendData>& data) {
415         BOOST_CHECK(status == ipc::Status::OK);
416         std::unique_lock<std::mutex> lock(mutex);
417         recvData = data;
418         cv.notify_one();
419     };
420     c.callAsync<SendData, SendData>(1, sentData, dataBack);
421
422     // Wait for the response
423     std::unique_lock<std::mutex> lock(mutex);
424     BOOST_CHECK(cv.wait_for(lock, std::chrono::milliseconds(100), [&recvData]() {
425         return static_cast<bool>(recvData);
426     }));
427
428     BOOST_CHECK_EQUAL(recvData->intVal, sentData->intVal);
429 }
430
431 BOOST_AUTO_TEST_CASE(AsyncServiceToClientEcho)
432 {
433     Service s(socketPath);
434     Client c(socketPath);
435     c.addMethodHandler<SendData, SendData>(1, echoCallback);
436     FileDescriptor peerFD = connect(s, c);
437
438     // Async call
439     std::shared_ptr<SendData> sentData(new SendData(56));
440     std::shared_ptr<SendData> recvData;
441
442     std::mutex mutex;
443     std::condition_variable cv;
444     auto dataBack = [&cv, &recvData, &mutex](ipc::Status status, std::shared_ptr<SendData>& data) {
445         BOOST_CHECK(status == ipc::Status::OK);
446         std::unique_lock<std::mutex> lock(mutex);
447         recvData = data;
448         cv.notify_one();
449     };
450
451     s.callAsync<SendData, SendData>(1, peerFD, sentData, dataBack);
452
453     // Wait for the response
454     std::unique_lock<std::mutex> lock(mutex);
455     BOOST_CHECK(cv.wait_for(lock, std::chrono::milliseconds(1000), [&recvData]() {
456         return recvData.get() != nullptr;
457     }));
458
459     BOOST_CHECK_EQUAL(recvData->intVal, sentData->intVal);
460 }
461
462
463 BOOST_AUTO_TEST_CASE(SyncTimeout)
464 {
465     Service s(socketPath);
466     s.addMethodHandler<SendData, SendData>(1, longEchoCallback);
467
468     s.start();
469     Client c(socketPath);
470     c.start();
471
472     std::shared_ptr<SendData> sentData(new SendData(78));
473
474     BOOST_CHECK_THROW((c.callSync<SendData, SendData>(1, sentData, 10)), IPCException); //TODO it fails from time to time
475 }
476
477 BOOST_AUTO_TEST_CASE(SerializationError)
478 {
479     Service s(socketPath);
480     s.addMethodHandler<SendData, SendData>(1, echoCallback);
481     s.start();
482
483     Client c(socketPath);
484     c.start();
485
486     std::shared_ptr<ThrowOnAcceptData> throwingData(new ThrowOnAcceptData());
487
488     BOOST_CHECK_THROW((c.callSync<ThrowOnAcceptData, SendData>(1, throwingData)), IPCSerializationException);
489
490 }
491
492 BOOST_AUTO_TEST_CASE(ParseError)
493 {
494     Service s(socketPath);
495     s.addMethodHandler<SendData, SendData>(1, echoCallback);
496     s.start();
497
498     Client c(socketPath);
499     c.start();
500
501     std::shared_ptr<SendData> sentData(new SendData(78));
502     BOOST_CHECK_THROW((c.callSync<SendData, ThrowOnAcceptData>(1, sentData, 10000)), IPCParsingException);
503 }
504
505 BOOST_AUTO_TEST_CASE(DisconnectedPeerError)
506 {
507     Service s(socketPath);
508
509     auto method = [](const FileDescriptor, std::shared_ptr<ThrowOnAcceptData>&) {
510         return std::shared_ptr<SendData>(new SendData(1));
511     };
512
513     // Method will throw during serialization and disconnect automatically
514     s.addMethodHandler<SendData, ThrowOnAcceptData>(1, method);
515     s.start();
516
517     Client c(socketPath);
518     c.start();
519
520     std::mutex mutex;
521     std::condition_variable cv;
522     ipc::Status retStatus = ipc::Status::UNDEFINED;
523
524     auto dataBack = [&cv, &retStatus, &mutex](ipc::Status status, std::shared_ptr<SendData>&) {
525         std::unique_lock<std::mutex> lock(mutex);
526         retStatus = status;
527         cv.notify_one();
528     };
529
530     std::shared_ptr<SendData> sentData(new SendData(78));
531     c.callAsync<SendData, SendData>(1, sentData, dataBack);
532
533     // Wait for the response
534     std::unique_lock<std::mutex> lock(mutex);
535     BOOST_CHECK(cv.wait_for(lock, std::chrono::seconds(100), [&retStatus]() {
536         return retStatus != ipc::Status::UNDEFINED;
537     }));
538
539     // The disconnection might have happened:
540     // - after sending the message (PEER_DISCONNECTED)
541     // - during external serialization (SERIALIZATION_ERROR)
542     BOOST_CHECK(retStatus == ipc::Status::PEER_DISCONNECTED || retStatus == ipc::Status::SERIALIZATION_ERROR);
543 }
544
545
546 BOOST_AUTO_TEST_CASE(ReadTimeout)
547 {
548     Service s(socketPath);
549     auto longEchoCallback = [](const FileDescriptor, std::shared_ptr<SendData>& data) {
550         return std::shared_ptr<LongSendData>(new LongSendData(data->intVal, 4000 /*ms*/));
551     };
552     s.addMethodHandler<LongSendData, SendData>(1, longEchoCallback);
553
554     Client c(socketPath);
555     connect(s, c);
556
557     // Test timeout on read
558     std::shared_ptr<SendData> sentData(new SendData(334));
559     BOOST_CHECK_THROW((c.callSync<SendData, SendData>(1, sentData, 10)), IPCException);
560 }
561
562
563 BOOST_AUTO_TEST_CASE(WriteTimeout)
564 {
565     Service s(socketPath);
566     s.addMethodHandler<SendData, SendData>(1, echoCallback);
567     s.start();
568
569     Client c(socketPath);
570     c.start();
571
572     // Test echo with a minimal timeout
573     std::shared_ptr<LongSendData> sentDataA(new LongSendData(34, 10 /*ms*/));
574     std::shared_ptr<SendData> recvData = c.callSync<LongSendData, SendData>(1, sentDataA, 100);
575     BOOST_CHECK_EQUAL(recvData->intVal, sentDataA->intVal);
576
577     // Test timeout on write
578     std::shared_ptr<LongSendData> sentDataB(new LongSendData(34, 1000 /*ms*/));
579     BOOST_CHECK_THROW((c.callSync<LongSendData, SendData>(1, sentDataB, 100)), IPCTimeoutException);
580 }
581
582
583 BOOST_AUTO_TEST_CASE(AddSignalInRuntime)
584 {
585     Service s(socketPath);
586     Client c(socketPath);
587     connect(s, c);
588
589     std::atomic_bool isHandlerACalled(false);
590     auto handlerA = [&isHandlerACalled](const FileDescriptor, std::shared_ptr<SendData>&) {
591         isHandlerACalled = true;
592     };
593
594     std::atomic_bool isHandlerBCalled(false);
595     auto handlerB = [&isHandlerBCalled](const FileDescriptor, std::shared_ptr<SendData>&) {
596         isHandlerBCalled = true;
597     };
598
599     c.addSignalHandler<SendData>(1, handlerA);
600     c.addSignalHandler<SendData>(2, handlerB);
601
602     auto data = std::make_shared<SendData>(1);
603     s.signal<SendData>(2, data);
604     s.signal<SendData>(1, data);
605
606     // Wait for the signals to arrive
607     std::this_thread::sleep_for(std::chrono::milliseconds(100)); //TODO wait_for
608     BOOST_CHECK(isHandlerACalled && isHandlerBCalled);
609 }
610
611
612 BOOST_AUTO_TEST_CASE(AddSignalOffline)
613 {
614     Service s(socketPath);
615     Client c(socketPath);
616
617     std::atomic_bool isHandlerACalled(false);
618     auto handlerA = [&isHandlerACalled](const FileDescriptor, std::shared_ptr<SendData>&) {
619         isHandlerACalled = true;
620     };
621
622     std::atomic_bool isHandlerBCalled(false);
623     auto handlerB = [&isHandlerBCalled](const FileDescriptor, std::shared_ptr<SendData>&) {
624         isHandlerBCalled = true;
625     };
626
627     c.addSignalHandler<SendData>(1, handlerA);
628     c.addSignalHandler<SendData>(2, handlerB);
629
630     connect(s, c);
631
632     // Wait for the information about the signals to propagate
633     std::this_thread::sleep_for(std::chrono::milliseconds(100));
634     auto data = std::make_shared<SendData>(1);
635     s.signal<SendData>(2, data);
636     s.signal<SendData>(1, data);
637
638     // Wait for the signals to arrive
639     std::this_thread::sleep_for(std::chrono::milliseconds(100)); //TODO wait_for
640     BOOST_CHECK(isHandlerACalled && isHandlerBCalled);
641 }
642
643
644 #if GLIB_CHECK_VERSION(2,36,0)
645
646 BOOST_AUTO_TEST_CASE(ServiceGSource)
647 {
648     ScopedGlibLoop loop;
649
650     std::atomic_bool isSignalCalled(false);
651     auto signalHandler = [&isSignalCalled](const FileDescriptor, std::shared_ptr<SendData>&) {
652         isSignalCalled = true;
653     };
654
655     IPCGSource::Pointer serviceGSource;
656     Service s(socketPath);
657     s.addMethodHandler<SendData, SendData>(1, echoCallback);
658
659     Client c(socketPath);
660     s.addSignalHandler<SendData>(2, signalHandler);
661
662     auto ret = connectServiceGSource(s, c);
663     serviceGSource = ret.second;
664
665     testEcho(c, 1);
666
667     auto data = std::make_shared<SendData>(1);
668     c.signal<SendData>(2, data);
669
670     std::this_thread::sleep_for(std::chrono::milliseconds(100)); //TODO wait_for
671     BOOST_CHECK(isSignalCalled);
672 }
673
674 BOOST_AUTO_TEST_CASE(ClientGSource)
675 {
676     ScopedGlibLoop loop;
677
678     std::atomic_bool isSignalCalled(false);
679     auto signalHandler = [&isSignalCalled](const FileDescriptor, std::shared_ptr<SendData>&) {
680         isSignalCalled = true;
681     };
682
683     Service s(socketPath);
684     s.start();
685
686     IPCGSource::Pointer clientGSource;
687     Client c(socketPath);
688     c.addMethodHandler<SendData, SendData>(1, echoCallback);
689     c.addSignalHandler<SendData>(2, signalHandler);
690
691     auto ret = connectClientGSource(s, c);
692     FileDescriptor peerFD = ret.first;
693     clientGSource = ret.second;
694
695     testEcho(s, 1, peerFD);
696
697     auto data = std::make_shared<SendData>(1);
698     s.signal<SendData>(2, data);
699
700     std::this_thread::sleep_for(std::chrono::milliseconds(100)); //TODO wait_for
701     BOOST_CHECK(isSignalCalled);
702 }
703
704 #endif // GLIB_CHECK_VERSION
705
706 // BOOST_AUTO_TEST_CASE(ConnectionLimitTest)
707 // {
708 //     unsigned oldLimit = ipc::getMaxFDNumber();
709 //     ipc::setMaxFDNumber(50);
710
711 //     // Setup Service and many Clients
712 //     Service s(socketPath);
713 //     s.addMethodHandler<SendData, SendData>(1, echoCallback);
714 //     s.start();
715
716 //     std::list<Client> clients;
717 //     for (int i = 0; i < 100; ++i) {
718 //         try {
719 //             clients.push_back(Client(socketPath));
720 //             clients.back().start();
721 //         } catch (...) {}
722 //     }
723
724 //     unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
725 //     std::mt19937 generator(seed);
726 //     for (auto it = clients.begin(); it != clients.end(); ++it) {
727 //         try {
728 //             std::shared_ptr<SendData> sentData(new SendData(generator()));
729 //             std::shared_ptr<SendData> recvData = it->callSync<SendData, SendData>(1, sentData);
730 //             BOOST_CHECK_EQUAL(recvData->intVal, sentData->intVal);
731 //         } catch (...) {}
732 //     }
733
734 //     ipc::setMaxFDNumber(oldLimit);
735 // }
736
737
738
739 BOOST_AUTO_TEST_SUITE_END()