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