RIC:1060: Change in PTL
[ric-plt/sdl.git] / tst / eventfd_test.cpp
1 /*
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 /*
18  * This source code is part of the near-RT RIC (RAN Intelligent Controller)
19  * platform project (RICP).
20 */
21
22 #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
32 using namespace shareddatalayer;
33 using namespace shareddatalayer::tst;
34 using namespace testing;
35
36 namespace
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
97 TEST_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
105 TEST_F(EventFDTest, PostWritesToEventFD)
106 {
107     expectWrite();
108     post(1);
109 }
110
111 TEST_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
124 TEST_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
134 TEST_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
144 TEST_F(EventFDTest, PostingNullCallbackCallsSHAREDDATALAYER_ABORT)
145 {
146     EXPECT_EXIT(post(EventFD::Callback()),
147          KilledBySignal(SIGABRT), "ABORT.*eventfd\\.cpp");
148 }