blob: c383bc627c00a5aa2ad96f18285f2c4eb26687b5 [file] [log] [blame]
Rolf Badorekef2bf512019-08-20 11:17:15 +03001/*
2 Copyright (c) 2018-2019 Nokia.
3
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
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
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.
15*/
16
17#include <type_traits>
18#include <memory>
19#include <cstdint>
20#include <sys/eventfd.h>
21#include <gmock/gmock.h>
22#include "private/eventfd.hpp"
23#include "private/timerfd.hpp"
24#include "private/tst/systemmock.hpp"
25#include "private/tst/enginemock.hpp"
26
27using namespace shareddatalayer;
28using namespace shareddatalayer::tst;
29using namespace testing;
30
31namespace
32{
33 class EventFDTest: public testing::Test
34 {
35 public:
36 const int efd;
37 NiceMock<SystemMock> systemMock;
38 EngineMock engineMock;
39 std::unique_ptr<EventFD> eventFD;
40 Engine::EventHandler savedEventHandler;
41
42 EventFDTest(): efd(123)
43 {
44 InSequence dummy;
45 EXPECT_CALL(systemMock, eventfd(0U, EFD_CLOEXEC | EFD_NONBLOCK))
46 .Times(1)
47 .WillOnce(Return(efd));
48 EXPECT_CALL(engineMock, addMonitoredFD(Matcher<FileDescriptor&>(_), Engine::EVENT_IN, _))
49 .Times(1)
50 .WillOnce(Invoke([this] (FileDescriptor& fd, unsigned int, const Engine::EventHandler& eh)
51 {
52 EXPECT_EQ(efd, static_cast<int>(fd));
53 savedEventHandler = eh;
54 }));
55 eventFD.reset(new EventFD(systemMock, engineMock));
56 Mock::VerifyAndClear(&systemMock);
57 Mock::VerifyAndClear(&engineMock);
58 }
59
60 void expectWrite()
61 {
62 EXPECT_CALL(systemMock, write(efd, NotNull(), sizeof(uint64_t)))
63 .Times(1)
64 .WillOnce(Invoke([] (int, const void* buf, size_t) -> ssize_t
65 {
66 EXPECT_EQ(1U, *static_cast<const uint64_t*>(buf));
67 return sizeof(uint64_t);
68 }));
69 }
70
71 void expectRead()
72 {
73 EXPECT_CALL(systemMock, read(efd, NotNull(), sizeof(uint64_t)))
74 .Times(1)
75 .WillOnce(Return(sizeof(uint64_t)));
76 }
77
78 void post(const EventFD::Callback& callback)
79 {
80 eventFD->post(callback);
81 }
82
83 void post(int i)
84 {
85 post(std::bind(&EventFDTest::callback, this, i));
86 }
87
88 MOCK_METHOD1(callback, void(int i));
89 };
90}
91
92TEST_F(EventFDTest, IsNotCopyableAndIsNotMovable)
93{
94 EXPECT_FALSE(std::is_copy_assignable<EventFD>::value);
95 EXPECT_FALSE(std::is_move_assignable<EventFD>::value);
96 EXPECT_FALSE(std::is_copy_constructible<EventFD>::value);
97 EXPECT_FALSE(std::is_move_constructible<EventFD>::value);
98}
99
100TEST_F(EventFDTest, PostWritesToEventFD)
101{
102 expectWrite();
103 post(1);
104}
105
106TEST_F(EventFDTest, HandleEventsExecutesAllCallbacksInFIFOOrder)
107{
108 post(1);
109 post(2);
110 InSequence dummy;
111 expectRead();
112 EXPECT_CALL(*this, callback(1))
113 .Times(1);
114 EXPECT_CALL(*this, callback(2))
115 .Times(1);
116 savedEventHandler(Engine::EVENT_IN);
117}
118
119TEST_F(EventFDTest, CallbacksAddedInPostAreNotExecutedDuringTheSameHandleEvents)
120{
121 post([this] () { post(1); });
122 InSequence dummy;
123 expectRead();
124 EXPECT_CALL(*this, callback(_))
125 .Times(0);
126 savedEventHandler(Engine::EVENT_IN);
127}
128
129TEST_F(EventFDTest, ExecutedCallbackIsDestroyedBeforeExecutingTheNextCallback)
130{
131 std::shared_ptr<int> data(std::make_shared<int>(1));
132 std::weak_ptr<int> weak(data);
133 post([data] () { static_cast<void>(data); });
134 data.reset();
135 post([weak] () { EXPECT_EQ(nullptr, weak.lock()); });
136 savedEventHandler(Engine::EVENT_IN);
137}
138
139TEST_F(EventFDTest, PostingNullCallbackCallsSHAREDDATALAYER_ABORT)
140{
141 EXPECT_EXIT(post(EventFD::Callback()),
142 KilledBySignal(SIGABRT), "ABORT.*eventfd\\.cpp");
143}