xref: /openbmc/sdeventplus/test/event.cpp (revision 18db9a3e)
1 #include <sdeventplus/event.hpp>
2 #include <sdeventplus/exception.hpp>
3 #include <sdeventplus/test/sdevent.hpp>
4 
5 #include <memory>
6 #include <optional>
7 #include <type_traits>
8 
9 #include <gmock/gmock.h>
10 #include <gtest/gtest.h>
11 
12 namespace sdeventplus
13 {
14 namespace
15 {
16 
17 using testing::DoAll;
18 using testing::Return;
19 using testing::SetArgPointee;
20 
21 class EventTest : public testing::Test
22 {
23   protected:
24     testing::StrictMock<test::SdEventMock> mock;
25     sd_event* const expected_event = reinterpret_cast<sd_event*>(1234);
26 };
27 
TEST_F(EventTest,NewEventRef)28 TEST_F(EventTest, NewEventRef)
29 {
30     EXPECT_CALL(mock, sd_event_ref(expected_event))
31         .WillOnce(Return(expected_event));
32     Event event(expected_event, &mock);
33     EXPECT_EQ(&mock, event.getSdEvent());
34     EXPECT_EQ(expected_event, event.get());
35 
36     EXPECT_CALL(mock, sd_event_unref(expected_event)).WillOnce(Return(nullptr));
37 }
38 
TEST_F(EventTest,NewEventNoRef)39 TEST_F(EventTest, NewEventNoRef)
40 {
41     Event event(expected_event, std::false_type(), &mock);
42     EXPECT_EQ(&mock, event.getSdEvent());
43     EXPECT_EQ(expected_event, event.get());
44 
45     EXPECT_CALL(mock, sd_event_unref(expected_event)).WillOnce(Return(nullptr));
46 }
47 
TEST_F(EventTest,CopyEventNoOwn)48 TEST_F(EventTest, CopyEventNoOwn)
49 {
50     Event event(expected_event, std::false_type(), &mock);
51     EXPECT_EQ(&mock, event.getSdEvent());
52     EXPECT_EQ(expected_event, event.get());
53 
54     Event event_noown(event, sdeventplus::internal::NoOwn());
55     EXPECT_EQ(&mock, event_noown.getSdEvent());
56     EXPECT_EQ(expected_event, event_noown.get());
57 
58     EXPECT_CALL(mock, sd_event_unref(expected_event)).WillOnce(Return(nullptr));
59 }
60 
TEST_F(EventTest,CopyEventNoOwnCopy)61 TEST_F(EventTest, CopyEventNoOwnCopy)
62 {
63     Event event(expected_event, std::false_type(), &mock);
64     EXPECT_EQ(&mock, event.getSdEvent());
65     EXPECT_EQ(expected_event, event.get());
66 
67     Event event_noown(event, sdeventplus::internal::NoOwn());
68     EXPECT_EQ(&mock, event_noown.getSdEvent());
69     EXPECT_EQ(expected_event, event_noown.get());
70 
71     EXPECT_CALL(mock, sd_event_ref(expected_event))
72         .WillOnce(Return(expected_event));
73     Event event2(event_noown);
74     EXPECT_EQ(&mock, event2.getSdEvent());
75     EXPECT_EQ(expected_event, event2.get());
76 
77     EXPECT_CALL(mock, sd_event_unref(expected_event))
78         .WillOnce(Return(nullptr))
79         .WillOnce(Return(nullptr));
80 }
81 
TEST_F(EventTest,GetNewEvent)82 TEST_F(EventTest, GetNewEvent)
83 {
84     EXPECT_CALL(mock, sd_event_new(testing::_))
85         .WillOnce(DoAll(SetArgPointee<0>(expected_event), Return(0)));
86     Event event = Event::get_new(&mock);
87     EXPECT_EQ(&mock, event.getSdEvent());
88     EXPECT_EQ(expected_event, event.get());
89 
90     EXPECT_CALL(mock, sd_event_unref(expected_event)).WillOnce(Return(nullptr));
91 }
92 
TEST_F(EventTest,GetNewEventFail)93 TEST_F(EventTest, GetNewEventFail)
94 {
95     EXPECT_CALL(mock, sd_event_new(testing::_)).WillOnce(Return(-EINVAL));
96     EXPECT_THROW(Event::get_new(&mock), SdEventError);
97 }
98 
TEST_F(EventTest,GetDefaultEvent)99 TEST_F(EventTest, GetDefaultEvent)
100 {
101     EXPECT_CALL(mock, sd_event_default(testing::_))
102         .WillOnce(DoAll(SetArgPointee<0>(expected_event), Return(0)));
103     Event event = Event::get_default(&mock);
104     EXPECT_EQ(&mock, event.getSdEvent());
105     EXPECT_EQ(expected_event, event.get());
106 
107     EXPECT_CALL(mock, sd_event_unref(expected_event)).WillOnce(Return(nullptr));
108 }
109 
TEST_F(EventTest,GetDefaultEventFail)110 TEST_F(EventTest, GetDefaultEventFail)
111 {
112     EXPECT_CALL(mock, sd_event_default(testing::_)).WillOnce(Return(-EINVAL));
113     EXPECT_THROW(Event::get_default(&mock), SdEventError);
114 }
115 
116 class EventMethodTest : public EventTest
117 {
118   protected:
119     std::unique_ptr<Event> event;
120 
SetUp()121     void SetUp()
122     {
123         event =
124             std::make_unique<Event>(expected_event, std::false_type(), &mock);
125     }
126 
TearDown()127     void TearDown()
128     {
129         EXPECT_CALL(mock, sd_event_unref(expected_event))
130             .WillOnce(Return(nullptr));
131     }
132 };
133 
TEST_F(EventMethodTest,PrepareSuccessNone)134 TEST_F(EventMethodTest, PrepareSuccessNone)
135 {
136     EXPECT_CALL(mock, sd_event_prepare(expected_event)).WillOnce(Return(0));
137     EXPECT_EQ(0, event->prepare());
138 }
139 
TEST_F(EventMethodTest,PrepareSuccessReady)140 TEST_F(EventMethodTest, PrepareSuccessReady)
141 {
142     const int events_ready = 10;
143     EXPECT_CALL(mock, sd_event_prepare(expected_event))
144         .WillOnce(Return(events_ready));
145     EXPECT_EQ(events_ready, event->prepare());
146 }
147 
TEST_F(EventMethodTest,PrepareInternalError)148 TEST_F(EventMethodTest, PrepareInternalError)
149 {
150     EXPECT_CALL(mock, sd_event_prepare(expected_event))
151         .WillOnce(Return(-EINVAL));
152     EXPECT_THROW(event->prepare(), SdEventError);
153 }
154 
TEST_F(EventMethodTest,WaitSuccessNone)155 TEST_F(EventMethodTest, WaitSuccessNone)
156 {
157     const std::chrono::microseconds timeout{20};
158     EXPECT_CALL(mock, sd_event_wait(expected_event, timeout.count()))
159         .WillOnce(Return(0));
160     EXPECT_EQ(0, event->wait(timeout));
161 }
162 
TEST_F(EventMethodTest,WaitSuccessReady)163 TEST_F(EventMethodTest, WaitSuccessReady)
164 {
165     const int events_ready = 10;
166     EXPECT_CALL(mock, sd_event_wait(expected_event, static_cast<uint64_t>(-1)))
167         .WillOnce(Return(events_ready));
168     EXPECT_EQ(events_ready, event->wait(std::nullopt));
169 }
170 
TEST_F(EventMethodTest,WaitInternalError)171 TEST_F(EventMethodTest, WaitInternalError)
172 {
173     EXPECT_CALL(mock, sd_event_wait(expected_event, static_cast<uint64_t>(-1)))
174         .WillOnce(Return(-EINVAL));
175     EXPECT_THROW(event->wait(std::nullopt), SdEventError);
176 }
177 
TEST_F(EventMethodTest,DispatchInitial)178 TEST_F(EventMethodTest, DispatchInitial)
179 {
180     EXPECT_CALL(mock, sd_event_dispatch(expected_event)).WillOnce(Return(0));
181     EXPECT_EQ(0, event->dispatch());
182 }
183 
TEST_F(EventMethodTest,DispatchDone)184 TEST_F(EventMethodTest, DispatchDone)
185 {
186     const int done_code = 10;
187     EXPECT_CALL(mock, sd_event_dispatch(expected_event))
188         .WillOnce(Return(done_code));
189     EXPECT_EQ(done_code, event->dispatch());
190 }
191 
TEST_F(EventMethodTest,DispatchInternalError)192 TEST_F(EventMethodTest, DispatchInternalError)
193 {
194     EXPECT_CALL(mock, sd_event_dispatch(expected_event))
195         .WillOnce(Return(-EINVAL));
196     EXPECT_THROW(event->dispatch(), SdEventError);
197 }
198 
TEST_F(EventMethodTest,RunSuccessNone)199 TEST_F(EventMethodTest, RunSuccessNone)
200 {
201     const std::chrono::microseconds timeout{20};
202     EXPECT_CALL(mock, sd_event_run(expected_event, timeout.count()))
203         .WillOnce(Return(0));
204     EXPECT_EQ(0, event->run(timeout));
205 }
206 
TEST_F(EventMethodTest,RunSuccessReady)207 TEST_F(EventMethodTest, RunSuccessReady)
208 {
209     const int events_ready = 10;
210     EXPECT_CALL(mock, sd_event_run(expected_event, static_cast<uint64_t>(-1)))
211         .WillOnce(Return(events_ready));
212     EXPECT_EQ(events_ready, event->run(std::nullopt));
213 }
214 
TEST_F(EventMethodTest,RunInternalError)215 TEST_F(EventMethodTest, RunInternalError)
216 {
217     EXPECT_CALL(mock, sd_event_run(expected_event, static_cast<uint64_t>(-1)))
218         .WillOnce(Return(-EINVAL));
219     EXPECT_THROW(event->run(std::nullopt), SdEventError);
220 }
221 
TEST_F(EventMethodTest,LoopSuccess)222 TEST_F(EventMethodTest, LoopSuccess)
223 {
224     EXPECT_CALL(mock, sd_event_loop(expected_event)).WillOnce(Return(0));
225     EXPECT_EQ(0, event->loop());
226 }
227 
TEST_F(EventMethodTest,LoopUserError)228 TEST_F(EventMethodTest, LoopUserError)
229 {
230     const int user_error = 10;
231     EXPECT_CALL(mock, sd_event_loop(expected_event))
232         .WillOnce(Return(user_error));
233     EXPECT_EQ(user_error, event->loop());
234 }
235 
TEST_F(EventMethodTest,LoopInternalError)236 TEST_F(EventMethodTest, LoopInternalError)
237 {
238     EXPECT_CALL(mock, sd_event_loop(expected_event)).WillOnce(Return(-EINVAL));
239     EXPECT_THROW(event->loop(), SdEventError);
240 }
241 
TEST_F(EventMethodTest,ExitSuccess)242 TEST_F(EventMethodTest, ExitSuccess)
243 {
244     EXPECT_CALL(mock, sd_event_exit(expected_event, 0)).WillOnce(Return(2));
245     event->exit(0);
246     EXPECT_CALL(mock, sd_event_exit(expected_event, 0)).WillOnce(Return(0));
247     event->exit(0);
248     EXPECT_CALL(mock, sd_event_exit(expected_event, 10)).WillOnce(Return(0));
249     event->exit(10);
250 }
251 
TEST_F(EventMethodTest,ExitInternalError)252 TEST_F(EventMethodTest, ExitInternalError)
253 {
254     EXPECT_CALL(mock, sd_event_exit(expected_event, 5))
255         .WillOnce(Return(-EINVAL));
256     EXPECT_THROW(event->exit(5), SdEventError);
257 }
258 
TEST_F(EventMethodTest,GetExitCodeSuccess)259 TEST_F(EventMethodTest, GetExitCodeSuccess)
260 {
261     EXPECT_CALL(mock, sd_event_get_exit_code(expected_event, testing::_))
262         .WillOnce(DoAll(SetArgPointee<1>(1), Return(0)));
263     EXPECT_EQ(1, event->get_exit_code());
264 
265     EXPECT_CALL(mock, sd_event_get_exit_code(expected_event, testing::_))
266         .WillOnce(DoAll(SetArgPointee<1>(0), Return(2)));
267     EXPECT_EQ(0, event->get_exit_code());
268 }
269 
TEST_F(EventMethodTest,GetExitCodeError)270 TEST_F(EventMethodTest, GetExitCodeError)
271 {
272     EXPECT_CALL(mock, sd_event_get_exit_code(expected_event, testing::_))
273         .WillOnce(Return(-EINVAL));
274     EXPECT_THROW(event->get_exit_code(), SdEventError);
275 }
276 
TEST_F(EventMethodTest,GetWatchdogSuccess)277 TEST_F(EventMethodTest, GetWatchdogSuccess)
278 {
279     EXPECT_CALL(mock, sd_event_get_watchdog(expected_event))
280         .WillOnce(Return(0));
281     EXPECT_FALSE(event->get_watchdog());
282 
283     EXPECT_CALL(mock, sd_event_get_watchdog(expected_event))
284         .WillOnce(Return(2));
285     EXPECT_TRUE(event->get_watchdog());
286 }
287 
TEST_F(EventMethodTest,GetWatchdogError)288 TEST_F(EventMethodTest, GetWatchdogError)
289 {
290     EXPECT_CALL(mock, sd_event_get_watchdog(expected_event))
291         .WillOnce(Return(-EINVAL));
292     EXPECT_THROW(event->get_watchdog(), SdEventError);
293 }
294 
TEST_F(EventMethodTest,SetWatchdogSuccess)295 TEST_F(EventMethodTest, SetWatchdogSuccess)
296 {
297     // Disable
298     EXPECT_CALL(mock, sd_event_set_watchdog(expected_event, false))
299         .WillOnce(Return(0));
300     EXPECT_FALSE(event->set_watchdog(false));
301 
302     // Enable but not supported
303     EXPECT_CALL(mock, sd_event_set_watchdog(expected_event, true))
304         .WillOnce(Return(0));
305     EXPECT_FALSE(event->set_watchdog(true));
306 
307     // Enabled and supported
308     EXPECT_CALL(mock, sd_event_set_watchdog(expected_event, true))
309         .WillOnce(Return(2));
310     EXPECT_TRUE(event->set_watchdog(true));
311 }
312 
TEST_F(EventMethodTest,SetWatchdogError)313 TEST_F(EventMethodTest, SetWatchdogError)
314 {
315     EXPECT_CALL(mock, sd_event_set_watchdog(expected_event, 1))
316         .WillOnce(Return(-EINVAL));
317     EXPECT_THROW(event->set_watchdog(1), SdEventError);
318 }
319 
320 } // namespace
321 } // namespace sdeventplus
322