2 * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
4 * Contact: Piotr Bartosiewicz <p.bartosiewi@partner.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 Piotr Bartosiewicz (p.bartosiewi@partner.samsung.com)
23 * @brief Unit tests of event poll
29 #include "utils/event-poll.hpp"
30 #include "logger/logger.hpp"
31 #include "ipc/internals/socket.hpp"
32 #include "utils/latch.hpp"
33 #include "utils/glib-loop.hpp"
34 #include "utils/glib-poll-dispatcher.hpp"
35 #include "utils/thread-poll-dispatcher.hpp"
38 #include <sys/epoll.h>
40 using namespace vasum::utils;
41 using namespace vasum::ipc;
45 const int unsigned TIMEOUT = 1000;
46 #define ADD_EVENT(e) {EPOLL##e, #e}
47 const std::map<EventPoll::Events, std::string> EVENT_NAMES = {
56 std::string strEvents(EventPoll::Events events)
61 std::ostringstream ss;
62 for (const auto& p : EVENT_NAMES) {
63 if (events & p.first) {
64 ss << p.second << ", ";
69 ss << std::hex << events;
72 std::string ret = ss.str();
73 ret.resize(ret.size() - 2);
80 BOOST_AUTO_TEST_SUITE(EventPollSuite)
82 BOOST_AUTO_TEST_CASE(EmptyPoll)
85 BOOST_CHECK(!poll.dispatchIteration(0));
88 BOOST_AUTO_TEST_CASE(ThreadedPoll)
91 ThreadPollDispatcher dispatcher(poll);
94 BOOST_AUTO_TEST_CASE(GlibPoll)
99 GlibPollDispatcher dispatcher(poll);
102 void doSocketTest(EventPoll& poll, Latch& goodMessage, Latch& remoteClosed)
104 const std::string PATH = "/tmp/ut-poll.sock";
105 const std::string MESSAGE = "This is a test message";
107 Socket listen = Socket::createSocket(PATH);
108 std::shared_ptr<Socket> server;
110 auto serverCallback = [&](int, EventPoll::Events events) -> bool {
111 LOGD("Server events: " << strEvents(events));
113 if (events & EPOLLOUT) {
114 server->write(MESSAGE.data(), MESSAGE.size());
115 poll.removeFD(server->getFD());
121 auto listenCallback = [&](int, EventPoll::Events events) -> bool {
122 LOGD("Listen events: " << strEvents(events));
123 if (events & EPOLLIN) {
124 server = listen.accept();
125 poll.addFD(server->getFD(), EPOLLHUP | EPOLLRDHUP | EPOLLOUT, serverCallback);
130 poll.addFD(listen.getFD(), EPOLLIN, listenCallback);
132 Socket client = Socket::connectSocket(PATH);
134 auto clientCallback = [&](int, EventPoll::Events events) -> bool {
135 LOGD("Client events: " << strEvents(events));
137 if (events & EPOLLIN) {
138 std::string ret(MESSAGE.size(), 'x');
139 client.read(&ret.front(), ret.size());
140 if (ret == MESSAGE) {
144 if (events & EPOLLRDHUP) {
145 poll.removeFD(client.getFD());
151 poll.addFD(client.getFD(), EPOLLHUP | EPOLLRDHUP | EPOLLIN, clientCallback);
153 BOOST_CHECK(goodMessage.wait(TIMEOUT));
154 BOOST_CHECK(remoteClosed.wait(TIMEOUT));
156 poll.removeFD(listen.getFD());
159 BOOST_AUTO_TEST_CASE(ThreadedPollSocket)
165 ThreadPollDispatcher dispatcher(poll);
167 doSocketTest(poll, goodMessage, remoteClosed);
170 BOOST_AUTO_TEST_CASE(GlibPollSocket)
178 GlibPollDispatcher dispatcher(poll);
180 doSocketTest(poll, goodMessage, remoteClosed);
183 BOOST_AUTO_TEST_CASE(PollStacking)
191 auto dispatchInner = [&](int, EventPoll::Events) -> bool {
192 inner.dispatchIteration(0);
196 outer.addFD(inner.getPollFD(), EPOLLIN, dispatchInner);
198 ThreadPollDispatcher dispatcher(outer);
199 doSocketTest(inner, goodMessage, remoteClosed);
201 outer.removeFD(inner.getPollFD());
204 BOOST_AUTO_TEST_SUITE_END()