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