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 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 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 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 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 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 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 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 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 121 void SetUp() 122 { 123 event = 124 std::make_unique<Event>(expected_event, std::false_type(), &mock); 125 } 126 127 void TearDown() 128 { 129 EXPECT_CALL(mock, sd_event_unref(expected_event)) 130 .WillOnce(Return(nullptr)); 131 } 132 }; 133 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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