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