2 Copyright (c) 2018-2019 Nokia.
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
8 http://www.apache.org/licenses/LICENSE-2.0
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
18 #include <sys/epoll.h>
19 #include <gmock/gmock.h>
20 #include "private/filedescriptor.hpp"
21 #include "private/engineimpl.hpp"
22 #include "private/tst/systemmock.hpp"
24 using namespace shareddatalayer;
25 using namespace shareddatalayer::tst;
26 using namespace testing;
30 class EventHandlerMock
33 MOCK_METHOD1(handleEvents, void(unsigned int events));
36 class EngineImplTest: public testing::Test
42 NiceMock<SystemMock> systemMock;
43 std::shared_ptr<EngineImpl> services;
44 EventHandlerMock eventHandlerMock1;
45 EventHandlerMock eventHandlerMock2;
47 EngineImplTest(): fd1(100), fd2(200), epfd(300)
49 EXPECT_CALL(systemMock, epoll_create1(EPOLL_CLOEXEC))
51 .WillOnce(Return(epfd));
52 services.reset(new EngineImpl(systemMock));
53 Mock::VerifyAndClear(&systemMock);
61 void addMonitoredFD(int fd, unsigned int events)
63 services->addMonitoredFD(fd, events, [] (unsigned int) { });
66 void addMonitoredFD(int fd, unsigned int events, EventHandlerMock& eventHandlerMock)
68 services->addMonitoredFD(fd, events, std::bind(&EventHandlerMock::handleEvents, &eventHandlerMock, std::placeholders::_1));
71 void modifyMonitoredFD(int fd, unsigned int events)
73 services->modifyMonitoredFD(fd, events);
76 void deleteMonitoredFD(int fd)
78 services->deleteMonitoredFD(fd);
81 void expectEpollCtl(int epfd, int op, int fd, unsigned int events)
83 EXPECT_CALL(systemMock, epoll_ctl(epfd, op, fd, NotNull()))
85 .WillOnce(Invoke([fd, events] (int, int, int, epoll_event* event)
87 epoll_data data = { };
89 EXPECT_EQ(data.fd, event->data.fd);
90 EXPECT_EQ(data.u64, event->data.u64);
91 EXPECT_EQ(data.ptr, event->data.ptr);
92 EXPECT_EQ(events, event->events);
96 void expectAtLeastOneEpollCtl(int epfd, int op, int fd, unsigned int events)
98 EXPECT_CALL(systemMock, epoll_ctl(epfd, op, fd, NotNull()))
100 .WillOnce(Invoke([fd, events] (int, int, int, epoll_event* event)
102 EXPECT_EQ(fd, event->data.fd);
103 EXPECT_EQ(events, event->events);
107 void stopEngineImpl()
112 EXPECT_CALL(systemMock, close(epfd)).Times(1);
114 Mock::VerifyAndClear(&systemMock);
118 using EngineImplDeathTest = EngineImplTest;
121 TEST_F(EngineImplTest, HandleEventsWithoutAnyAddedFDsDoesNothing)
123 EXPECT_CALL(systemMock, epoll_wait(_, _, _, _))
125 services->handleEvents();
128 TEST_F(EngineImplTest, FDReturnsTheEpollFD)
130 EXPECT_EQ(epfd, services->fd());
133 TEST_F(EngineImplTest, AddingFDAddsTheFDToEpoll)
135 expectEpollCtl(epfd, EPOLL_CTL_ADD, fd1, Engine::EVENT_IN);
136 addMonitoredFD(fd1, Engine::EVENT_IN);
139 TEST_F(EngineImplTest, AddingFileDescriptorSetsAtCloseCallback)
141 FileDescriptor fd(systemMock, fd1);
142 expectEpollCtl(epfd, EPOLL_CTL_ADD, fd1, Engine::EVENT_IN);
143 services->addMonitoredFD(fd, Engine::EVENT_IN, Engine::EventHandler());
146 EXPECT_CALL(systemMock, epoll_ctl(epfd, EPOLL_CTL_DEL, fd1, nullptr))
148 EXPECT_CALL(systemMock, close(fd1)).Times(1);
151 TEST_F(EngineImplDeathTest, AddingAlreadyAddedFDCallsSHAREDDATALAYER_ABORT)
153 expectAtLeastOneEpollCtl(epfd, EPOLL_CTL_ADD, fd1, Engine::EVENT_IN);
154 addMonitoredFD(fd1, Engine::EVENT_IN);
155 EXPECT_EXIT(addMonitoredFD(fd1, Engine::EVENT_IN),
156 KilledBySignal(SIGABRT), "ABORT.*engineimpl\\.cpp");
159 TEST_F(EngineImplTest, ModifyingFDModifiesTheFDInEpoll)
161 addMonitoredFD(fd1, Engine::EVENT_IN);
162 expectEpollCtl(epfd, EPOLL_CTL_MOD, fd1, Engine::EVENT_OUT);
163 modifyMonitoredFD(fd1, Engine::EVENT_OUT);
166 TEST_F(EngineImplDeathTest, ModifyingNonExistingFDCallsSHAREDDATALAYER_ABORT)
168 EXPECT_EXIT(modifyMonitoredFD(fd1, 0U),
169 KilledBySignal(SIGABRT), "ABORT.*engineimpl\\.cpp");
172 TEST_F(EngineImplDeathTest, DellingFDDelsTheFDFromEpollAndFromTheMap)
174 addMonitoredFD(fd1, Engine::EVENT_IN);
175 EXPECT_CALL(systemMock, epoll_ctl(epfd, EPOLL_CTL_DEL, fd1, nullptr))
177 deleteMonitoredFD(fd1);
178 EXPECT_EXIT(modifyMonitoredFD(fd1, 0U),
179 KilledBySignal(SIGABRT), "ABORT.*engineimpl\\.cpp");
182 TEST_F(EngineImplDeathTest, DellingNonExistingFDCallsSHAREDDATALAYER_ABORT)
184 EXPECT_EXIT(deleteMonitoredFD(fd1),
185 KilledBySignal(SIGABRT), "ABORT.*engineimpl\\.cpp");
188 TEST_F(EngineImplTest, HandleEventsCallsAddedEventHandlersAccordingToEpollReturnValue)
190 addMonitoredFD(fd1, Engine::EVENT_IN, eventHandlerMock1);
191 addMonitoredFD(fd2, Engine::EVENT_IN, eventHandlerMock2);
193 EXPECT_CALL(systemMock, epoll_wait(epfd, NotNull(), 2, 0))
195 .WillOnce(Invoke([this] (int, epoll_event* events, int, int) -> int
197 events[0].events = EPOLLIN;
198 events[0].data.fd = fd1;
199 events[1].events = EPOLLOUT;
200 events[1].data.fd = fd2;
203 EXPECT_CALL(eventHandlerMock1, handleEvents(Engine::EVENT_IN))
205 EXPECT_CALL(eventHandlerMock2, handleEvents(Engine::EVENT_OUT))
207 services->handleEvents();
210 TEST_F(EngineImplTest, PendingEventsOfDeletedFileDescriptorAreForgotten)
212 addMonitoredFD(fd1, Engine::EVENT_IN, eventHandlerMock1);
213 addMonitoredFD(fd2, Engine::EVENT_IN, eventHandlerMock2);
215 EXPECT_CALL(eventHandlerMock2, handleEvents(_))
217 EXPECT_CALL(systemMock, epoll_wait(epfd, NotNull(), 2, 0))
219 .WillOnce(Invoke([this] (int, epoll_event* events, int, int) -> int
221 events[0].events = EPOLLIN;
222 events[0].data.fd = fd1;
223 events[1].events = EPOLLIN;
224 events[1].data.fd = fd2;
227 EXPECT_CALL(eventHandlerMock1, handleEvents(_))
229 .WillOnce(Invoke([this](unsigned int)
231 deleteMonitoredFD(fd2);
232 addMonitoredFD(fd2, Engine::EVENT_IN, eventHandlerMock2);
234 services->handleEvents();