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