2 * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
4 * Contact: Jan Olszak <j.olszak@samsung.com>
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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
22 * @author Jan Olszak (j.olszak@samsung.com)
23 * @brief Tests of the IPC
26 // TODO: Test connection limit
27 // TODO: Refactor tests - function for setting up env
33 #include "ipc/service.hpp"
34 #include "ipc/client.hpp"
35 #include "ipc/types.hpp"
36 #include "ipc/unique-id.hpp"
37 #include "ipc/result.hpp"
38 #include "ipc/epoll/thread-dispatcher.hpp"
39 #include "ipc/epoll/glib-dispatcher.hpp"
40 #include "utils/glib-loop.hpp"
41 #include "utils/latch.hpp"
42 #include "utils/value-latch.hpp"
43 #include "utils/scoped-dir.hpp"
45 #include "config/fields.hpp"
46 #include "logger/logger.hpp"
48 #include <boost/filesystem.hpp>
56 #include <sys/types.h>
62 using namespace epoll;
63 using namespace utils;
64 using namespace std::placeholders;
65 namespace fs = boost::filesystem;
67 // Timeout for sending one message
68 const int TIMEOUT = 1000 /*ms*/;
70 // Time that won't cause "TIMEOUT" methods to throw
71 const int SHORT_OPERATION_TIME = TIMEOUT / 100;
73 // Time that will cause "TIMEOUT" methods to throw
74 const int LONG_OPERATION_TIME = 1000 + TIMEOUT;
76 const std::string TEST_DIR = "/tmp/ut-ipc";
77 const std::string SOCKET_PATH = TEST_DIR + "/test.socket";
78 const std::string TEST_FILE = TEST_DIR + "/file.txt";
81 ScopedDir mTestPathGuard;
84 : mTestPathGuard(TEST_DIR)
89 struct ThreadedFixture : FixtureBase {
90 ThreadDispatcher dispatcher;
92 EventPoll& getPoll() {
93 return dispatcher.getPoll();
97 struct GlibFixture : FixtureBase {
98 ScopedGlibLoop glibLoop;
99 GlibDispatcher dispatcher;
101 EventPoll& getPoll() {
102 return dispatcher.getPoll();
108 SendData(int i): intVal(i) {}
118 RecvData(): intVal(-1) {}
127 config::FileDescriptor fd;
128 FDData(int fd = -1): fd(fd) {}
136 struct LongSendData {
137 LongSendData(int i, int waitTime): mSendData(i), mWaitTime(waitTime), intVal(i) {}
139 template<typename Visitor>
140 void accept(Visitor visitor)
142 std::this_thread::sleep_for(std::chrono::milliseconds(mWaitTime));
143 mSendData.accept(visitor);
145 template<typename Visitor>
146 void accept(Visitor visitor) const
148 std::this_thread::sleep_for(std::chrono::milliseconds(mWaitTime));
149 mSendData.accept(visitor);
158 CONFIG_REGISTER_EMPTY
161 struct ThrowOnAcceptData {
162 template<typename Visitor>
163 static void accept(Visitor)
165 throw std::runtime_error("intentional failure in accept");
169 void returnEmptyCallback(const PeerID,
170 std::shared_ptr<EmptyData>&,
171 MethodResult::Pointer methodResult)
173 methodResult->setVoid();
176 void returnDataCallback(const PeerID,
177 std::shared_ptr<RecvData>&,
178 MethodResult::Pointer methodResult)
180 auto returnData = std::make_shared<SendData>(1);
181 methodResult->set(returnData);
184 void echoCallback(const PeerID,
185 std::shared_ptr<RecvData>& data,
186 MethodResult::Pointer methodResult)
188 auto returnData = std::make_shared<SendData>(data->intVal);
189 methodResult->set(returnData);
192 void longEchoCallback(const PeerID,
193 std::shared_ptr<RecvData>& data,
194 MethodResult::Pointer methodResult)
196 std::this_thread::sleep_for(std::chrono::milliseconds(LONG_OPERATION_TIME));
197 auto returnData = std::make_shared<SendData>(data->intVal);
198 methodResult->set(returnData);
201 void shortEchoCallback(const PeerID,
202 std::shared_ptr<RecvData>& data,
203 MethodResult::Pointer methodResult)
205 std::this_thread::sleep_for(std::chrono::milliseconds(SHORT_OPERATION_TIME));
206 auto returnData = std::make_shared<SendData>(data->intVal);
207 methodResult->set(returnData);
210 PeerID connect(Service& s, Client& c)
212 // Connects the Client to the Service and returns Clients PeerID
213 ValueLatch<PeerID> peerIDLatch;
214 auto newPeerCallback = [&peerIDLatch](const PeerID newID, const FileDescriptor) {
215 peerIDLatch.set(newID);
218 s.setNewPeerCallback(newPeerCallback);
220 if (!s.isStarted()) {
226 PeerID peerID = peerIDLatch.get(TIMEOUT);
227 s.setNewPeerCallback(nullptr);
228 BOOST_REQUIRE_NE(peerID, static_cast<std::string>(ipc::UniqueID()));
232 void testEcho(Client& c, const MethodID methodID)
234 std::shared_ptr<SendData> sentData(new SendData(34));
235 std::shared_ptr<RecvData> recvData = c.callSync<SendData, RecvData>(methodID, sentData, TIMEOUT);
236 BOOST_REQUIRE(recvData);
237 BOOST_CHECK_EQUAL(recvData->intVal, sentData->intVal);
240 void testEcho(Service& s, const MethodID methodID, const PeerID& peerID)
242 std::shared_ptr<SendData> sentData(new SendData(56));
243 std::shared_ptr<RecvData> recvData = s.callSync<SendData, RecvData>(methodID, peerID, sentData, TIMEOUT);
244 BOOST_REQUIRE(recvData);
245 BOOST_CHECK_EQUAL(recvData->intVal, sentData->intVal);
248 BOOST_AUTO_TEST_SUITE(IPCSuite)
250 MULTI_FIXTURE_TEST_CASE(ConstructorDestructor, F, ThreadedFixture, GlibFixture)
252 Service s(F::getPoll(), SOCKET_PATH);
253 Client c(F::getPoll(), SOCKET_PATH);
256 MULTI_FIXTURE_TEST_CASE(ServiceAddRemoveMethod, F, ThreadedFixture, GlibFixture)
258 Service s(F::getPoll(), SOCKET_PATH);
259 s.setMethodHandler<EmptyData, EmptyData>(1, returnEmptyCallback);
260 s.setMethodHandler<SendData, RecvData>(1, returnDataCallback);
264 s.setMethodHandler<SendData, RecvData>(1, echoCallback);
265 s.setMethodHandler<SendData, RecvData>(2, returnDataCallback);
267 Client c(F::getPoll(), SOCKET_PATH);
274 BOOST_CHECK_THROW(testEcho(c, 2), IPCException);
277 MULTI_FIXTURE_TEST_CASE(ClientAddRemoveMethod, F, ThreadedFixture, GlibFixture)
279 Service s(F::getPoll(), SOCKET_PATH);
280 Client c(F::getPoll(), SOCKET_PATH);
281 c.setMethodHandler<EmptyData, EmptyData>(1, returnEmptyCallback);
282 c.setMethodHandler<SendData, RecvData>(1, returnDataCallback);
284 PeerID peerID = connect(s, c);
286 c.setMethodHandler<SendData, RecvData>(1, echoCallback);
287 c.setMethodHandler<SendData, RecvData>(2, returnDataCallback);
289 testEcho(s, 1, peerID);
294 BOOST_CHECK_THROW(testEcho(s, 1, peerID), IPCException);
297 MULTI_FIXTURE_TEST_CASE(ServiceStartStop, F, ThreadedFixture, GlibFixture)
299 Service s(F::getPoll(), SOCKET_PATH);
301 s.setMethodHandler<SendData, RecvData>(1, returnDataCallback);
312 MULTI_FIXTURE_TEST_CASE(ClientStartStop, F, ThreadedFixture, GlibFixture)
314 Service s(F::getPoll(), SOCKET_PATH);
315 Client c(F::getPoll(), SOCKET_PATH);
316 c.setMethodHandler<SendData, RecvData>(1, returnDataCallback);
330 MULTI_FIXTURE_TEST_CASE(SyncClientToServiceEcho, F, ThreadedFixture, GlibFixture)
332 Service s(F::getPoll(), SOCKET_PATH);
333 s.setMethodHandler<SendData, RecvData>(1, echoCallback);
334 s.setMethodHandler<SendData, RecvData>(2, echoCallback);
336 Client c(F::getPoll(), SOCKET_PATH);
343 MULTI_FIXTURE_TEST_CASE(Restart, F, ThreadedFixture, GlibFixture)
345 Service s(F::getPoll(), SOCKET_PATH);
346 s.setMethodHandler<SendData, RecvData>(1, echoCallback);
348 s.setMethodHandler<SendData, RecvData>(2, echoCallback);
350 Client c(F::getPoll(), SOCKET_PATH);
364 BOOST_CHECK_THROW(testEcho(c, 2), IPCException);
373 MULTI_FIXTURE_TEST_CASE(SyncServiceToClientEcho, F, ThreadedFixture, GlibFixture)
375 Service s(F::getPoll(), SOCKET_PATH);
376 Client c(F::getPoll(), SOCKET_PATH);
377 c.setMethodHandler<SendData, RecvData>(1, echoCallback);
378 PeerID peerID = connect(s, c);
380 std::shared_ptr<SendData> sentData(new SendData(56));
381 std::shared_ptr<RecvData> recvData = s.callSync<SendData, RecvData>(1, peerID, sentData);
382 BOOST_REQUIRE(recvData);
383 BOOST_CHECK_EQUAL(recvData->intVal, sentData->intVal);
386 MULTI_FIXTURE_TEST_CASE(AsyncClientToServiceEcho, F, ThreadedFixture, GlibFixture)
388 std::shared_ptr<SendData> sentData(new SendData(34));
389 ValueLatch<std::shared_ptr<RecvData>> recvDataLatch;
391 // Setup Service and Client
392 Service s(F::getPoll(), SOCKET_PATH);
393 s.setMethodHandler<SendData, RecvData>(1, echoCallback);
395 Client c(F::getPoll(), SOCKET_PATH);
399 auto dataBack = [&recvDataLatch](Result<RecvData> && r) {
400 recvDataLatch.set(r.get());
402 c.callAsync<SendData, RecvData>(1, sentData, dataBack);
404 // Wait for the response
405 std::shared_ptr<RecvData> recvData(recvDataLatch.get(TIMEOUT));
406 BOOST_CHECK_EQUAL(recvData->intVal, sentData->intVal);
409 MULTI_FIXTURE_TEST_CASE(AsyncServiceToClientEcho, F, ThreadedFixture, GlibFixture)
411 std::shared_ptr<SendData> sentData(new SendData(56));
412 ValueLatch<std::shared_ptr<RecvData>> recvDataLatch;
414 Service s(F::getPoll(), SOCKET_PATH);
415 Client c(F::getPoll(), SOCKET_PATH);
416 c.setMethodHandler<SendData, RecvData>(1, echoCallback);
417 PeerID peerID = connect(s, c);
420 auto dataBack = [&recvDataLatch](Result<RecvData> && r) {
421 recvDataLatch.set(r.get());
424 s.callAsync<SendData, RecvData>(1, peerID, sentData, dataBack);
426 // Wait for the response
427 std::shared_ptr<RecvData> recvData(recvDataLatch.get(TIMEOUT));
428 BOOST_CHECK_EQUAL(recvData->intVal, sentData->intVal);
432 MULTI_FIXTURE_TEST_CASE(SyncTimeout, F, ThreadedFixture, GlibFixture)
434 Service s(F::getPoll(), SOCKET_PATH);
435 s.setMethodHandler<SendData, RecvData>(1, longEchoCallback);
437 Client c(F::getPoll(), SOCKET_PATH);
440 std::shared_ptr<SendData> sentData(new SendData(78));
441 BOOST_REQUIRE_THROW((c.callSync<SendData, RecvData>(1, sentData, TIMEOUT)), IPCException);
444 MULTI_FIXTURE_TEST_CASE(SerializationError, F, ThreadedFixture, GlibFixture)
446 Service s(F::getPoll(), SOCKET_PATH);
447 s.setMethodHandler<SendData, RecvData>(1, echoCallback);
449 Client c(F::getPoll(), SOCKET_PATH);
452 std::shared_ptr<ThrowOnAcceptData> throwingData(new ThrowOnAcceptData());
454 BOOST_CHECK_THROW((c.callSync<ThrowOnAcceptData, RecvData>(1, throwingData)), IPCSerializationException);
458 MULTI_FIXTURE_TEST_CASE(ParseError, F, ThreadedFixture, GlibFixture)
460 Service s(F::getPoll(), SOCKET_PATH);
461 s.setMethodHandler<SendData, RecvData>(1, echoCallback);
464 Client c(F::getPoll(), SOCKET_PATH);
467 std::shared_ptr<SendData> sentData(new SendData(78));
468 BOOST_CHECK_THROW((c.callSync<SendData, ThrowOnAcceptData>(1, sentData, 10000)), IPCParsingException);
471 MULTI_FIXTURE_TEST_CASE(DisconnectedPeerError, F, ThreadedFixture, GlibFixture)
473 ValueLatch<Result<RecvData>> retStatusLatch;
475 Service s(F::getPoll(), SOCKET_PATH);
477 auto method = [](const PeerID, std::shared_ptr<ThrowOnAcceptData>&, MethodResult::Pointer methodResult) {
478 auto resultData = std::make_shared<SendData>(1);
479 methodResult->set<SendData>(resultData);
482 // Method will throw during serialization and disconnect automatically
483 s.setMethodHandler<SendData, ThrowOnAcceptData>(1, method);
486 Client c(F::getPoll(), SOCKET_PATH);
489 auto dataBack = [&retStatusLatch](Result<RecvData> && r) {
490 retStatusLatch.set(std::move(r));
493 std::shared_ptr<SendData> sentData(new SendData(78));
494 c.callAsync<SendData, RecvData>(1, sentData, dataBack);
496 // Wait for the response
497 Result<RecvData> result = retStatusLatch.get(TIMEOUT);
499 // The disconnection might have happened:
500 // - after sending the message (PEER_DISCONNECTED)
501 // - during external serialization (SERIALIZATION_ERROR)
502 BOOST_CHECK_THROW(result.get(), IPCException);
506 MULTI_FIXTURE_TEST_CASE(ReadTimeout, F, ThreadedFixture, GlibFixture)
508 Service s(F::getPoll(), SOCKET_PATH);
509 auto longEchoCallback = [](const PeerID, std::shared_ptr<RecvData>& data, MethodResult::Pointer methodResult) {
510 auto resultData = std::make_shared<LongSendData>(data->intVal, LONG_OPERATION_TIME);
511 methodResult->set<LongSendData>(resultData);
513 s.setMethodHandler<LongSendData, RecvData>(1, longEchoCallback);
515 Client c(F::getPoll(), SOCKET_PATH);
518 // Test timeout on read
519 std::shared_ptr<SendData> sentData(new SendData(334));
520 BOOST_CHECK_THROW((c.callSync<SendData, RecvData>(1, sentData, TIMEOUT)), IPCException);
524 MULTI_FIXTURE_TEST_CASE(WriteTimeout, F, ThreadedFixture, GlibFixture)
526 Service s(F::getPoll(), SOCKET_PATH);
527 s.setMethodHandler<SendData, RecvData>(1, shortEchoCallback);
530 Client c(F::getPoll(), SOCKET_PATH);
533 // Test echo with a minimal timeout
534 std::shared_ptr<LongSendData> sentDataA(new LongSendData(34, SHORT_OPERATION_TIME));
535 std::shared_ptr<RecvData> recvData = c.callSync<LongSendData, RecvData>(1, sentDataA, TIMEOUT);
536 BOOST_REQUIRE(recvData);
537 BOOST_CHECK_EQUAL(recvData->intVal, sentDataA->intVal);
539 // Test timeout on write
540 std::shared_ptr<LongSendData> sentDataB(new LongSendData(34, LONG_OPERATION_TIME));
541 BOOST_CHECK_THROW((c.callSync<LongSendData, RecvData>(1, sentDataB, TIMEOUT)), IPCTimeoutException);
545 MULTI_FIXTURE_TEST_CASE(AddSignalInRuntime, F, ThreadedFixture, GlibFixture)
547 ValueLatch<std::shared_ptr<RecvData>> recvDataLatchA;
548 ValueLatch<std::shared_ptr<RecvData>> recvDataLatchB;
550 Service s(F::getPoll(), SOCKET_PATH);
551 Client c(F::getPoll(), SOCKET_PATH);
554 auto handlerA = [&recvDataLatchA](const PeerID, std::shared_ptr<RecvData>& data) {
555 recvDataLatchA.set(data);
558 auto handlerB = [&recvDataLatchB](const PeerID, std::shared_ptr<RecvData>& data) {
559 recvDataLatchB.set(data);
562 c.setSignalHandler<RecvData>(1, handlerA);
563 c.setSignalHandler<RecvData>(2, handlerB);
565 // Wait for the signals to propagate to the Service
566 std::this_thread::sleep_for(std::chrono::milliseconds(2 * TIMEOUT));
568 auto sendDataA = std::make_shared<SendData>(1);
569 auto sendDataB = std::make_shared<SendData>(2);
570 s.signal<SendData>(2, sendDataB);
571 s.signal<SendData>(1, sendDataA);
573 // Wait for the signals to arrive
574 std::shared_ptr<RecvData> recvDataA(recvDataLatchA.get(TIMEOUT));
575 std::shared_ptr<RecvData> recvDataB(recvDataLatchB.get(TIMEOUT));
576 BOOST_CHECK_EQUAL(recvDataA->intVal, sendDataA->intVal);
577 BOOST_CHECK_EQUAL(recvDataB->intVal, sendDataB->intVal);
581 MULTI_FIXTURE_TEST_CASE(AddSignalOffline, F, ThreadedFixture, GlibFixture)
583 ValueLatch<std::shared_ptr<RecvData>> recvDataLatchA;
584 ValueLatch<std::shared_ptr<RecvData>> recvDataLatchB;
586 Service s(F::getPoll(), SOCKET_PATH);
587 Client c(F::getPoll(), SOCKET_PATH);
589 auto handlerA = [&recvDataLatchA](const PeerID, std::shared_ptr<RecvData>& data) {
590 recvDataLatchA.set(data);
593 auto handlerB = [&recvDataLatchB](const PeerID, std::shared_ptr<RecvData>& data) {
594 recvDataLatchB.set(data);
597 c.setSignalHandler<RecvData>(1, handlerA);
598 c.setSignalHandler<RecvData>(2, handlerB);
602 // Wait for the information about the signals to propagate
603 std::this_thread::sleep_for(std::chrono::milliseconds(TIMEOUT));
605 auto sendDataA = std::make_shared<SendData>(1);
606 auto sendDataB = std::make_shared<SendData>(2);
607 s.signal<SendData>(2, sendDataB);
608 s.signal<SendData>(1, sendDataA);
610 // Wait for the signals to arrive
611 std::shared_ptr<RecvData> recvDataA(recvDataLatchA.get(TIMEOUT));
612 std::shared_ptr<RecvData> recvDataB(recvDataLatchB.get(TIMEOUT));
613 BOOST_CHECK_EQUAL(recvDataA->intVal, sendDataA->intVal);
614 BOOST_CHECK_EQUAL(recvDataB->intVal, sendDataB->intVal);
617 MULTI_FIXTURE_TEST_CASE(UsersError, F, ThreadedFixture, GlibFixture)
619 const int TEST_ERROR_CODE = -234;
620 const std::string TEST_ERROR_MESSAGE = "Ay, caramba!";
622 Service s(F::getPoll(), SOCKET_PATH);
623 Client c(F::getPoll(), SOCKET_PATH);
624 auto clientID = connect(s, c);
626 auto throwingMethodHandler = [&](const PeerID, std::shared_ptr<RecvData>&, MethodResult::Pointer) {
627 throw IPCUserException(TEST_ERROR_CODE, TEST_ERROR_MESSAGE);
630 auto sendErrorMethodHandler = [&](const PeerID, std::shared_ptr<RecvData>&, MethodResult::Pointer methodResult) {
631 methodResult->setError(TEST_ERROR_CODE, TEST_ERROR_MESSAGE);
634 s.setMethodHandler<SendData, RecvData>(1, throwingMethodHandler);
635 s.setMethodHandler<SendData, RecvData>(2, sendErrorMethodHandler);
636 c.setMethodHandler<SendData, RecvData>(1, throwingMethodHandler);
637 c.setMethodHandler<SendData, RecvData>(2, sendErrorMethodHandler);
639 std::shared_ptr<SendData> sentData(new SendData(78));
641 auto hasProperData = [&](const IPCUserException & e) {
642 return e.getCode() == TEST_ERROR_CODE && e.what() == TEST_ERROR_MESSAGE;
645 BOOST_CHECK_EXCEPTION((c.callSync<SendData, RecvData>(1, sentData, TIMEOUT)), IPCUserException, hasProperData);
646 BOOST_CHECK_EXCEPTION((s.callSync<SendData, RecvData>(1, clientID, sentData, TIMEOUT)), IPCUserException, hasProperData);
647 BOOST_CHECK_EXCEPTION((c.callSync<SendData, RecvData>(2, sentData, TIMEOUT)), IPCUserException, hasProperData);
648 BOOST_CHECK_EXCEPTION((s.callSync<SendData, RecvData>(2, clientID, sentData, TIMEOUT)), IPCUserException, hasProperData);
651 MULTI_FIXTURE_TEST_CASE(AsyncResult, F, ThreadedFixture, GlibFixture)
653 const int TEST_ERROR_CODE = -567;
654 const std::string TEST_ERROR_MESSAGE = "Ooo jooo!";
656 Service s(F::getPoll(), SOCKET_PATH);
657 Client c(F::getPoll(), SOCKET_PATH);
658 auto clientID = connect(s, c);
660 auto errorMethodHandler = [&](const PeerID, std::shared_ptr<RecvData>&, MethodResult::Pointer methodResult) {
661 std::async(std::launch::async, [&, methodResult] {
662 std::this_thread::sleep_for(std::chrono::milliseconds(SHORT_OPERATION_TIME));
663 methodResult->setError(TEST_ERROR_CODE, TEST_ERROR_MESSAGE);
667 auto voidMethodHandler = [&](const PeerID, std::shared_ptr<RecvData>&, MethodResult::Pointer methodResult) {
668 std::async(std::launch::async, [methodResult] {
669 std::this_thread::sleep_for(std::chrono::milliseconds(SHORT_OPERATION_TIME));
670 methodResult->setVoid();
674 auto dataMethodHandler = [&](const PeerID, std::shared_ptr<RecvData>& data, MethodResult::Pointer methodResult) {
675 std::async(std::launch::async, [data, methodResult] {
676 std::this_thread::sleep_for(std::chrono::milliseconds(SHORT_OPERATION_TIME));
677 methodResult->set(data);
681 s.setMethodHandler<SendData, RecvData>(1, errorMethodHandler);
682 s.setMethodHandler<EmptyData, RecvData>(2, voidMethodHandler);
683 s.setMethodHandler<SendData, RecvData>(3, dataMethodHandler);
684 c.setMethodHandler<SendData, RecvData>(1, errorMethodHandler);
685 c.setMethodHandler<EmptyData, RecvData>(2, voidMethodHandler);
686 c.setMethodHandler<SendData, RecvData>(3, dataMethodHandler);
688 std::shared_ptr<SendData> sentData(new SendData(90));
690 auto hasProperData = [&](const IPCUserException & e) {
691 return e.getCode() == TEST_ERROR_CODE && e.what() == TEST_ERROR_MESSAGE;
694 BOOST_CHECK_EXCEPTION((s.callSync<SendData, RecvData>(1, clientID, sentData, TIMEOUT)), IPCUserException, hasProperData);
695 BOOST_CHECK_EXCEPTION((c.callSync<SendData, RecvData>(1, sentData, TIMEOUT)), IPCUserException, hasProperData);
697 BOOST_CHECK_NO_THROW((s.callSync<SendData, EmptyData>(2, clientID, sentData, TIMEOUT)));
698 BOOST_CHECK_NO_THROW((c.callSync<SendData, EmptyData>(2, sentData, TIMEOUT)));
700 std::shared_ptr<RecvData> recvData;
701 recvData = s.callSync<SendData, RecvData>(3, clientID, sentData, TIMEOUT);
702 BOOST_CHECK_EQUAL(recvData->intVal, sentData->intVal);
703 recvData = c.callSync<SendData, RecvData>(3, sentData, TIMEOUT);
704 BOOST_CHECK_EQUAL(recvData->intVal, sentData->intVal);
707 MULTI_FIXTURE_TEST_CASE(MixOperations, F, ThreadedFixture, GlibFixture)
711 auto signalHandler = [&l](const PeerID, std::shared_ptr<RecvData>&) {
715 Service s(F::getPoll(), SOCKET_PATH);
716 s.setMethodHandler<SendData, RecvData>(1, echoCallback);
718 Client c(F::getPoll(), SOCKET_PATH);
719 s.setSignalHandler<RecvData>(2, signalHandler);
725 auto data = std::make_shared<SendData>(1);
726 c.signal<SendData>(2, data);
728 BOOST_CHECK(l.wait(TIMEOUT));
731 MULTI_FIXTURE_TEST_CASE(FDSendReceive, F, ThreadedFixture, GlibFixture)
733 const char DATA[] = "Content of the file";
736 fs::remove(TEST_FILE);
737 std::ofstream file(TEST_FILE);
742 auto methodHandler = [&](const PeerID, std::shared_ptr<EmptyData>&, MethodResult::Pointer methodResult) {
743 int fd = ::open(TEST_FILE.c_str(), O_RDONLY);
744 auto returnData = std::make_shared<FDData>(fd);
745 methodResult->set(returnData);
748 Service s(F::getPoll(), SOCKET_PATH);
749 s.setMethodHandler<FDData, EmptyData>(1, methodHandler);
751 Client c(F::getPoll(), SOCKET_PATH);
754 std::shared_ptr<FDData> fdData;
755 std::shared_ptr<EmptyData> sentData(new EmptyData());
756 fdData = c.callSync<EmptyData, FDData>(1, sentData, TIMEOUT);
758 // Use the file descriptor
759 char buffer[sizeof(DATA)];
760 BOOST_REQUIRE(::read(fdData->fd.value, buffer, sizeof(buffer))>0);
761 BOOST_REQUIRE(strncmp(DATA, buffer, strlen(DATA))==0);
762 ::close(fdData->fd.value);
765 // MULTI_FIXTURE_TEST_CASE(ConnectionLimit, F, ThreadedFixture, GlibFixture)
767 // unsigned oldLimit = ipc::getMaxFDNumber();
768 // ipc::setMaxFDNumber(50);
770 // // Setup Service and many Clients
771 // Service s(F::getPoll(), SOCKET_PATH);
772 // s.setMethodHandler<SendData, RecvData>(1, echoCallback);
775 // std::list<Client> clients;
776 // for (int i = 0; i < 100; ++i) {
778 // clients.push_back(Client(F::getPoll(), SOCKET_PATH));
779 // clients.back().start();
783 // unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
784 // std::mt19937 generator(seed);
785 // for (auto it = clients.begin(); it != clients.end(); ++it) {
787 // std::shared_ptr<SendData> sentData(new SendData(generator()));
788 // std::shared_ptr<RecvData> recvData = it->callSync<SendData, RecvData>(1, sentData);
789 // BOOST_CHECK_EQUAL(recvData->intVal, sentData->intVal);
793 // ipc::setMaxFDNumber(oldLimit);
798 BOOST_AUTO_TEST_SUITE_END()