blob: 4b89d52f3f4622d86511cd64806ee40dd880fcf6 [file] [log] [blame]
William A. Kennington III48c42752018-07-17 14:40:14 -07001#include <cerrno>
William A. Kennington III0a816c52018-07-17 14:40:14 -07002#include <gmock/gmock.h>
3#include <gtest/gtest.h>
William A. Kennington III715c72f2018-07-17 14:40:14 -07004#include <memory>
5#include <sdeventplus/event.hpp>
William A. Kennington III65db8632018-07-17 14:40:14 -07006#include <sdeventplus/exception.hpp>
William A. Kennington III0a816c52018-07-17 14:40:14 -07007#include <sdeventplus/internal/sdevent.hpp>
8#include <sdeventplus/source/base.hpp>
9#include <sdeventplus/test/sdevent.hpp>
William A. Kennington III65db8632018-07-17 14:40:14 -070010#include <string>
William A. Kennington III48c42752018-07-17 14:40:14 -070011#include <system_error>
William A. Kennington III715c72f2018-07-17 14:40:14 -070012#include <systemd/sd-event.h>
William A. Kennington III0a816c52018-07-17 14:40:14 -070013#include <type_traits>
14
15namespace sdeventplus
16{
17namespace source
18{
19namespace
20{
21
William A. Kennington III65db8632018-07-17 14:40:14 -070022using testing::DoAll;
William A. Kennington III0a816c52018-07-17 14:40:14 -070023using testing::Return;
William A. Kennington III48c42752018-07-17 14:40:14 -070024using testing::SaveArg;
William A. Kennington III65db8632018-07-17 14:40:14 -070025using testing::SetArgPointee;
William A. Kennington III0a816c52018-07-17 14:40:14 -070026
27class BaseImpl : public Base
28{
29 public:
William A. Kennington III715c72f2018-07-17 14:40:14 -070030 BaseImpl(const Event& event, sd_event_source* source) : Base(event, source)
William A. Kennington III0a816c52018-07-17 14:40:14 -070031 {
32 }
William A. Kennington III715c72f2018-07-17 14:40:14 -070033 BaseImpl(const Event& event, sd_event_source* source, std::false_type) :
34 Base(event, source, std::false_type())
William A. Kennington III0a816c52018-07-17 14:40:14 -070035 {
36 }
37};
38
39class BaseTest : public testing::Test
40{
41 protected:
42 testing::StrictMock<test::SdEventMock> mock;
William A. Kennington III715c72f2018-07-17 14:40:14 -070043 sd_event_source* expected_source = reinterpret_cast<sd_event_source*>(1234);
44 sd_event* expected_event = reinterpret_cast<sd_event*>(2345);
45 std::unique_ptr<Event> event;
46
47 virtual void SetUp()
48 {
49 event =
50 std::make_unique<Event>(expected_event, std::false_type(), &mock);
51 }
52 virtual void TearDown()
53 {
54 EXPECT_CALL(mock, sd_event_unref(expected_event))
55 .WillOnce(Return(nullptr));
56 event.reset();
57 }
William A. Kennington III0a816c52018-07-17 14:40:14 -070058};
59
60TEST_F(BaseTest, NewBaseRef)
61{
William A. Kennington III715c72f2018-07-17 14:40:14 -070062 EXPECT_CALL(mock, sd_event_ref(expected_event))
63 .WillOnce(Return(expected_event));
William A. Kennington III0a816c52018-07-17 14:40:14 -070064 EXPECT_CALL(mock, sd_event_source_ref(expected_source))
65 .WillOnce(Return(expected_source));
William A. Kennington III715c72f2018-07-17 14:40:14 -070066 BaseImpl source(*event, expected_source);
William A. Kennington III4863b962018-07-17 14:40:14 -070067 EXPECT_EQ(expected_source, source.get());
68 EXPECT_NE(event.get(), &source.get_event());
69 EXPECT_EQ(expected_event, source.get_event().get());
William A. Kennington IIIf5285c72018-07-17 14:40:14 -070070 EXPECT_FALSE(source.get_prepare());
William A. Kennington III0a816c52018-07-17 14:40:14 -070071
William A. Kennington III65db8632018-07-17 14:40:14 -070072 {
73 testing::InSequence seq;
74 EXPECT_CALL(mock,
75 sd_event_source_set_enabled(expected_source, SD_EVENT_OFF))
76 .WillOnce(Return(0));
77 EXPECT_CALL(mock, sd_event_source_unref(expected_source))
78 .WillOnce(Return(nullptr));
79 }
William A. Kennington III715c72f2018-07-17 14:40:14 -070080 EXPECT_CALL(mock, sd_event_unref(expected_event)).WillOnce(Return(nullptr));
William A. Kennington III0a816c52018-07-17 14:40:14 -070081}
82
83TEST_F(BaseTest, NewBaseNoRef)
84{
William A. Kennington III715c72f2018-07-17 14:40:14 -070085 EXPECT_CALL(mock, sd_event_ref(expected_event))
86 .WillOnce(Return(expected_event));
87 BaseImpl source(*event, expected_source, std::false_type());
William A. Kennington III4863b962018-07-17 14:40:14 -070088 EXPECT_EQ(expected_source, source.get());
89 EXPECT_NE(event.get(), &source.get_event());
90 EXPECT_EQ(expected_event, source.get_event().get());
William A. Kennington IIIf5285c72018-07-17 14:40:14 -070091 EXPECT_FALSE(source.get_prepare());
William A. Kennington III0a816c52018-07-17 14:40:14 -070092
William A. Kennington III65db8632018-07-17 14:40:14 -070093 {
94 testing::InSequence seq;
95 EXPECT_CALL(mock,
96 sd_event_source_set_enabled(expected_source, SD_EVENT_OFF))
97 .WillOnce(Return(0));
98 EXPECT_CALL(mock, sd_event_source_unref(expected_source))
99 .WillOnce(Return(nullptr));
100 }
William A. Kennington III715c72f2018-07-17 14:40:14 -0700101 EXPECT_CALL(mock, sd_event_unref(expected_event)).WillOnce(Return(nullptr));
William A. Kennington III65db8632018-07-17 14:40:14 -0700102}
103
William A. Kennington III7c24e052018-07-17 14:40:14 -0700104TEST_F(BaseTest, NoSource)
105{
106 EXPECT_CALL(mock, sd_event_ref(expected_event))
107 .WillOnce(Return(expected_event));
108 BaseImpl source(*event, nullptr, std::false_type());
William A. Kennington III4863b962018-07-17 14:40:14 -0700109 EXPECT_EQ(nullptr, source.get());
110 EXPECT_NE(event.get(), &source.get_event());
111 EXPECT_EQ(expected_event, source.get_event().get());
William A. Kennington IIIf5285c72018-07-17 14:40:14 -0700112 EXPECT_FALSE(source.get_prepare());
William A. Kennington III7c24e052018-07-17 14:40:14 -0700113
114 EXPECT_CALL(mock, sd_event_source_unref(nullptr)).WillOnce(Return(nullptr));
115 EXPECT_CALL(mock, sd_event_unref(expected_event)).WillOnce(Return(nullptr));
116}
117
William A. Kennington III65db8632018-07-17 14:40:14 -0700118class BaseMethodTest : public BaseTest
119{
120 protected:
121 std::unique_ptr<BaseImpl> base;
122
William A. Kennington III715c72f2018-07-17 14:40:14 -0700123 void SetUp() override
William A. Kennington III65db8632018-07-17 14:40:14 -0700124 {
William A. Kennington III715c72f2018-07-17 14:40:14 -0700125 BaseTest::SetUp();
126 EXPECT_CALL(mock, sd_event_ref(expected_event))
127 .WillOnce(Return(expected_event));
128 base = std::make_unique<BaseImpl>(*event, expected_source,
129 std::false_type());
William A. Kennington III65db8632018-07-17 14:40:14 -0700130 }
131
William A. Kennington III715c72f2018-07-17 14:40:14 -0700132 void TearDown() override
William A. Kennington III65db8632018-07-17 14:40:14 -0700133 {
134 {
135 testing::InSequence seq;
136 EXPECT_CALL(mock, sd_event_source_set_enabled(expected_source,
137 SD_EVENT_OFF))
138 .WillOnce(Return(0));
139 EXPECT_CALL(mock, sd_event_source_unref(expected_source))
140 .WillOnce(Return(nullptr));
141 }
William A. Kennington III715c72f2018-07-17 14:40:14 -0700142 EXPECT_CALL(mock, sd_event_unref(expected_event))
143 .WillOnce(Return(nullptr));
144 base.reset();
145 BaseTest::TearDown();
William A. Kennington III65db8632018-07-17 14:40:14 -0700146 }
147};
148
149TEST_F(BaseMethodTest, GetDescriptionSuccess)
150{
151 const char* expected = "test_desc";
152 EXPECT_CALL(mock,
153 sd_event_source_get_description(expected_source, testing::_))
154 .WillOnce(DoAll(SetArgPointee<1>(expected), Return(0)));
155 // Intentionally comparing pointers to make sure no copying is happening
156 EXPECT_EQ(expected, base->get_description());
157}
158
159TEST_F(BaseMethodTest, GetDescriptionError)
160{
161 EXPECT_CALL(mock,
162 sd_event_source_get_description(expected_source, testing::_))
163 .WillOnce(Return(-EINVAL));
164 EXPECT_THROW(base->get_description(), SdEventError);
165}
166
167TEST_F(BaseMethodTest, SetDescriptionSuccess)
168{
169 const char* expected = "test desc";
170 // Intentionally comparing pointers to make sure no copying is happening
171 EXPECT_CALL(mock,
172 sd_event_source_set_description(expected_source, expected))
173 .WillOnce(Return(0));
174 base->set_description(expected);
175}
176
177TEST_F(BaseMethodTest, SetDescriptionError)
178{
179 const char* expected = "test desc";
180 // Intentionally comparing pointers to make sure no copying is happening
181 EXPECT_CALL(mock,
182 sd_event_source_set_description(expected_source, expected))
183 .WillOnce(Return(-EINVAL));
184 EXPECT_THROW(base->set_description(expected), SdEventError);
185}
186
William A. Kennington III48c42752018-07-17 14:40:14 -0700187TEST_F(BaseMethodTest, SetPrepareCallback)
188{
189 bool completed = false;
190 Base::Callback callback = [&completed](Base&) { completed = true; };
191 sd_event_handler_t event_handler;
192 EXPECT_CALL(mock, sd_event_source_set_prepare(expected_source, testing::_))
193 .WillOnce(DoAll(SaveArg<1>(&event_handler), Return(0)));
194 base->set_prepare(std::move(callback));
William A. Kennington IIIf5285c72018-07-17 14:40:14 -0700195 EXPECT_TRUE(base->get_prepare());
William A. Kennington III48c42752018-07-17 14:40:14 -0700196 EXPECT_FALSE(callback);
197 EXPECT_FALSE(completed);
198
199 EXPECT_EQ(0, event_handler(nullptr, base.get()));
200 EXPECT_TRUE(completed);
201}
202
203TEST_F(BaseMethodTest, SetPrepareCallbackNoUserdata)
204{
205 Base::Callback callback = [](Base&) {};
206 sd_event_handler_t event_handler;
207 EXPECT_CALL(mock, sd_event_source_set_prepare(expected_source, testing::_))
208 .WillOnce(DoAll(SaveArg<1>(&event_handler), Return(0)));
209 base->set_prepare(std::move(callback));
William A. Kennington IIIf5285c72018-07-17 14:40:14 -0700210 EXPECT_TRUE(base->get_prepare());
William A. Kennington III48c42752018-07-17 14:40:14 -0700211 EXPECT_FALSE(callback);
212
213 EXPECT_EQ(-EINVAL, event_handler(nullptr, nullptr));
214}
215
216TEST_F(BaseMethodTest, SetPrepareNull)
217{
218 EXPECT_CALL(mock, sd_event_source_set_prepare(expected_source, nullptr))
219 .WillOnce(Return(0));
220 base->set_prepare(nullptr);
221 EXPECT_EQ(-ENOSYS, base->prepareCallback());
222}
223
224TEST_F(BaseMethodTest, SetPrepareSystemError)
225{
226 Base::Callback callback = [](Base&) {
227 throw std::system_error(EBUSY, std::generic_category());
228 };
229 EXPECT_CALL(mock, sd_event_source_set_prepare(expected_source, testing::_))
230 .WillOnce(Return(0));
231 base->set_prepare(std::move(callback));
William A. Kennington IIIf5285c72018-07-17 14:40:14 -0700232 EXPECT_TRUE(base->get_prepare());
William A. Kennington III48c42752018-07-17 14:40:14 -0700233 EXPECT_FALSE(callback);
234 EXPECT_EQ(-EBUSY, base->prepareCallback());
235}
236
237TEST_F(BaseMethodTest, SetPrepareUnknownException)
238{
239 Base::Callback callback = [](Base&) { throw static_cast<int>(1); };
240 EXPECT_CALL(mock, sd_event_source_set_prepare(expected_source, testing::_))
241 .WillOnce(Return(0));
242 base->set_prepare(std::move(callback));
William A. Kennington IIIf5285c72018-07-17 14:40:14 -0700243 EXPECT_TRUE(base->get_prepare());
William A. Kennington III48c42752018-07-17 14:40:14 -0700244 EXPECT_FALSE(callback);
245 EXPECT_EQ(-ENOSYS, base->prepareCallback());
246}
247
248TEST_F(BaseMethodTest, SetPrepareError)
249{
250 Base::Callback callback = [](Base&) {};
251 EXPECT_CALL(mock, sd_event_source_set_prepare(expected_source, testing::_))
252 .WillOnce(Return(-EINVAL));
253 EXPECT_THROW(base->set_prepare(std::move(callback)), SdEventError);
William A. Kennington IIIf5285c72018-07-17 14:40:14 -0700254 EXPECT_FALSE(base->get_prepare());
William A. Kennington III48c42752018-07-17 14:40:14 -0700255 EXPECT_TRUE(callback);
256 EXPECT_EQ(-ENOSYS, base->prepareCallback());
257}
258
William A. Kennington III65db8632018-07-17 14:40:14 -0700259TEST_F(BaseMethodTest, GetPendingSuccess)
260{
261 EXPECT_CALL(mock, sd_event_source_get_pending(expected_source))
262 .WillOnce(Return(0));
263 EXPECT_EQ(0, base->get_pending());
264 EXPECT_CALL(mock, sd_event_source_get_pending(expected_source))
265 .WillOnce(Return(4));
266 EXPECT_EQ(4, base->get_pending());
267}
268
269TEST_F(BaseMethodTest, GetPendingError)
270{
271 EXPECT_CALL(mock, sd_event_source_get_pending(expected_source))
272 .WillOnce(Return(-EINVAL));
273 EXPECT_THROW(base->get_pending(), SdEventError);
274}
275
276TEST_F(BaseMethodTest, GetPrioritySuccess)
277{
278 EXPECT_CALL(mock, sd_event_source_get_priority(expected_source, testing::_))
279 .WillOnce(DoAll(SetArgPointee<1>(1024), Return(0)));
280 EXPECT_EQ(1024, base->get_priority());
281}
282
283TEST_F(BaseMethodTest, GetPriorityError)
284{
285 EXPECT_CALL(mock, sd_event_source_get_priority(expected_source, testing::_))
286 .WillOnce(Return(-EINVAL));
287 EXPECT_THROW(base->get_priority(), SdEventError);
288}
289
290TEST_F(BaseMethodTest, SetPrioritySuccess)
291{
292 EXPECT_CALL(mock, sd_event_source_set_priority(expected_source, 1024))
293 .WillOnce(Return(0));
294 base->set_priority(1024);
295}
296
297TEST_F(BaseMethodTest, SetPriorityError)
298{
299 EXPECT_CALL(mock, sd_event_source_set_priority(expected_source, 1024))
300 .WillOnce(Return(-EINVAL));
301 EXPECT_THROW(base->set_priority(1024), SdEventError);
302}
303
304TEST_F(BaseMethodTest, GetEnabledSuccess)
305{
306 EXPECT_CALL(mock, sd_event_source_get_enabled(expected_source, testing::_))
307 .WillOnce(DoAll(SetArgPointee<1>(SD_EVENT_ON), Return(0)));
308 EXPECT_EQ(SD_EVENT_ON, base->get_enabled());
309}
310
311TEST_F(BaseMethodTest, GetEnabledError)
312{
313 EXPECT_CALL(mock, sd_event_source_get_enabled(expected_source, testing::_))
314 .WillOnce(Return(-EINVAL));
315 EXPECT_THROW(base->get_enabled(), SdEventError);
316}
317
318TEST_F(BaseMethodTest, SetEnabledSuccess)
319{
320 EXPECT_CALL(mock, sd_event_source_set_enabled(expected_source, SD_EVENT_ON))
321 .WillOnce(Return(0));
322 base->set_enabled(SD_EVENT_ON);
323}
324
325TEST_F(BaseMethodTest, SetEnabledError)
326{
327 EXPECT_CALL(mock, sd_event_source_set_enabled(expected_source, SD_EVENT_ON))
328 .WillOnce(Return(-EINVAL));
329 EXPECT_THROW(base->set_enabled(SD_EVENT_ON), SdEventError);
William A. Kennington III0a816c52018-07-17 14:40:14 -0700330}
331
332} // namespace
333} // namespace source
334} // namespace sdeventplus