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