blob: 48948407be1ebf4006be726467a37305be1ae505 [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 III0a816c52018-07-17 14:40:14 -070070
William A. Kennington III65db8632018-07-17 14:40:14 -070071 {
72 testing::InSequence seq;
73 EXPECT_CALL(mock,
74 sd_event_source_set_enabled(expected_source, SD_EVENT_OFF))
75 .WillOnce(Return(0));
76 EXPECT_CALL(mock, sd_event_source_unref(expected_source))
77 .WillOnce(Return(nullptr));
78 }
William A. Kennington III715c72f2018-07-17 14:40:14 -070079 EXPECT_CALL(mock, sd_event_unref(expected_event)).WillOnce(Return(nullptr));
William A. Kennington III0a816c52018-07-17 14:40:14 -070080}
81
82TEST_F(BaseTest, NewBaseNoRef)
83{
William A. Kennington III715c72f2018-07-17 14:40:14 -070084 EXPECT_CALL(mock, sd_event_ref(expected_event))
85 .WillOnce(Return(expected_event));
86 BaseImpl source(*event, expected_source, std::false_type());
William A. Kennington III4863b962018-07-17 14:40:14 -070087 EXPECT_EQ(expected_source, source.get());
88 EXPECT_NE(event.get(), &source.get_event());
89 EXPECT_EQ(expected_event, source.get_event().get());
William A. Kennington III0a816c52018-07-17 14:40:14 -070090
William A. Kennington III65db8632018-07-17 14:40:14 -070091 {
92 testing::InSequence seq;
93 EXPECT_CALL(mock,
94 sd_event_source_set_enabled(expected_source, SD_EVENT_OFF))
95 .WillOnce(Return(0));
96 EXPECT_CALL(mock, sd_event_source_unref(expected_source))
97 .WillOnce(Return(nullptr));
98 }
William A. Kennington III715c72f2018-07-17 14:40:14 -070099 EXPECT_CALL(mock, sd_event_unref(expected_event)).WillOnce(Return(nullptr));
William A. Kennington III65db8632018-07-17 14:40:14 -0700100}
101
William A. Kennington III7c24e052018-07-17 14:40:14 -0700102TEST_F(BaseTest, NoSource)
103{
104 EXPECT_CALL(mock, sd_event_ref(expected_event))
105 .WillOnce(Return(expected_event));
106 BaseImpl source(*event, nullptr, std::false_type());
William A. Kennington III4863b962018-07-17 14:40:14 -0700107 EXPECT_EQ(nullptr, source.get());
108 EXPECT_NE(event.get(), &source.get_event());
109 EXPECT_EQ(expected_event, source.get_event().get());
William A. Kennington III7c24e052018-07-17 14:40:14 -0700110
111 EXPECT_CALL(mock, sd_event_source_unref(nullptr)).WillOnce(Return(nullptr));
112 EXPECT_CALL(mock, sd_event_unref(expected_event)).WillOnce(Return(nullptr));
113}
114
William A. Kennington III65db8632018-07-17 14:40:14 -0700115class BaseMethodTest : public BaseTest
116{
117 protected:
118 std::unique_ptr<BaseImpl> base;
119
William A. Kennington III715c72f2018-07-17 14:40:14 -0700120 void SetUp() override
William A. Kennington III65db8632018-07-17 14:40:14 -0700121 {
William A. Kennington III715c72f2018-07-17 14:40:14 -0700122 BaseTest::SetUp();
123 EXPECT_CALL(mock, sd_event_ref(expected_event))
124 .WillOnce(Return(expected_event));
125 base = std::make_unique<BaseImpl>(*event, expected_source,
126 std::false_type());
William A. Kennington III65db8632018-07-17 14:40:14 -0700127 }
128
William A. Kennington III715c72f2018-07-17 14:40:14 -0700129 void TearDown() override
William A. Kennington III65db8632018-07-17 14:40:14 -0700130 {
131 {
132 testing::InSequence seq;
133 EXPECT_CALL(mock, sd_event_source_set_enabled(expected_source,
134 SD_EVENT_OFF))
135 .WillOnce(Return(0));
136 EXPECT_CALL(mock, sd_event_source_unref(expected_source))
137 .WillOnce(Return(nullptr));
138 }
William A. Kennington III715c72f2018-07-17 14:40:14 -0700139 EXPECT_CALL(mock, sd_event_unref(expected_event))
140 .WillOnce(Return(nullptr));
141 base.reset();
142 BaseTest::TearDown();
William A. Kennington III65db8632018-07-17 14:40:14 -0700143 }
144};
145
146TEST_F(BaseMethodTest, GetDescriptionSuccess)
147{
148 const char* expected = "test_desc";
149 EXPECT_CALL(mock,
150 sd_event_source_get_description(expected_source, testing::_))
151 .WillOnce(DoAll(SetArgPointee<1>(expected), Return(0)));
152 // Intentionally comparing pointers to make sure no copying is happening
153 EXPECT_EQ(expected, base->get_description());
154}
155
156TEST_F(BaseMethodTest, GetDescriptionError)
157{
158 EXPECT_CALL(mock,
159 sd_event_source_get_description(expected_source, testing::_))
160 .WillOnce(Return(-EINVAL));
161 EXPECT_THROW(base->get_description(), SdEventError);
162}
163
164TEST_F(BaseMethodTest, SetDescriptionSuccess)
165{
166 const char* expected = "test desc";
167 // Intentionally comparing pointers to make sure no copying is happening
168 EXPECT_CALL(mock,
169 sd_event_source_set_description(expected_source, expected))
170 .WillOnce(Return(0));
171 base->set_description(expected);
172}
173
174TEST_F(BaseMethodTest, SetDescriptionError)
175{
176 const char* expected = "test desc";
177 // Intentionally comparing pointers to make sure no copying is happening
178 EXPECT_CALL(mock,
179 sd_event_source_set_description(expected_source, expected))
180 .WillOnce(Return(-EINVAL));
181 EXPECT_THROW(base->set_description(expected), SdEventError);
182}
183
William A. Kennington III48c42752018-07-17 14:40:14 -0700184TEST_F(BaseMethodTest, SetPrepareCallback)
185{
186 bool completed = false;
187 Base::Callback callback = [&completed](Base&) { completed = true; };
188 sd_event_handler_t event_handler;
189 EXPECT_CALL(mock, sd_event_source_set_prepare(expected_source, testing::_))
190 .WillOnce(DoAll(SaveArg<1>(&event_handler), Return(0)));
191 base->set_prepare(std::move(callback));
192 EXPECT_FALSE(callback);
193 EXPECT_FALSE(completed);
194
195 EXPECT_EQ(0, event_handler(nullptr, base.get()));
196 EXPECT_TRUE(completed);
197}
198
199TEST_F(BaseMethodTest, SetPrepareCallbackNoUserdata)
200{
201 Base::Callback callback = [](Base&) {};
202 sd_event_handler_t event_handler;
203 EXPECT_CALL(mock, sd_event_source_set_prepare(expected_source, testing::_))
204 .WillOnce(DoAll(SaveArg<1>(&event_handler), Return(0)));
205 base->set_prepare(std::move(callback));
206 EXPECT_FALSE(callback);
207
208 EXPECT_EQ(-EINVAL, event_handler(nullptr, nullptr));
209}
210
211TEST_F(BaseMethodTest, SetPrepareNull)
212{
213 EXPECT_CALL(mock, sd_event_source_set_prepare(expected_source, nullptr))
214 .WillOnce(Return(0));
215 base->set_prepare(nullptr);
216 EXPECT_EQ(-ENOSYS, base->prepareCallback());
217}
218
219TEST_F(BaseMethodTest, SetPrepareSystemError)
220{
221 Base::Callback callback = [](Base&) {
222 throw std::system_error(EBUSY, std::generic_category());
223 };
224 EXPECT_CALL(mock, sd_event_source_set_prepare(expected_source, testing::_))
225 .WillOnce(Return(0));
226 base->set_prepare(std::move(callback));
227 EXPECT_FALSE(callback);
228 EXPECT_EQ(-EBUSY, base->prepareCallback());
229}
230
231TEST_F(BaseMethodTest, SetPrepareUnknownException)
232{
233 Base::Callback callback = [](Base&) { throw static_cast<int>(1); };
234 EXPECT_CALL(mock, sd_event_source_set_prepare(expected_source, testing::_))
235 .WillOnce(Return(0));
236 base->set_prepare(std::move(callback));
237 EXPECT_FALSE(callback);
238 EXPECT_EQ(-ENOSYS, base->prepareCallback());
239}
240
241TEST_F(BaseMethodTest, SetPrepareError)
242{
243 Base::Callback callback = [](Base&) {};
244 EXPECT_CALL(mock, sd_event_source_set_prepare(expected_source, testing::_))
245 .WillOnce(Return(-EINVAL));
246 EXPECT_THROW(base->set_prepare(std::move(callback)), SdEventError);
247 EXPECT_TRUE(callback);
248 EXPECT_EQ(-ENOSYS, base->prepareCallback());
249}
250
William A. Kennington III65db8632018-07-17 14:40:14 -0700251TEST_F(BaseMethodTest, GetPendingSuccess)
252{
253 EXPECT_CALL(mock, sd_event_source_get_pending(expected_source))
254 .WillOnce(Return(0));
255 EXPECT_EQ(0, base->get_pending());
256 EXPECT_CALL(mock, sd_event_source_get_pending(expected_source))
257 .WillOnce(Return(4));
258 EXPECT_EQ(4, base->get_pending());
259}
260
261TEST_F(BaseMethodTest, GetPendingError)
262{
263 EXPECT_CALL(mock, sd_event_source_get_pending(expected_source))
264 .WillOnce(Return(-EINVAL));
265 EXPECT_THROW(base->get_pending(), SdEventError);
266}
267
268TEST_F(BaseMethodTest, GetPrioritySuccess)
269{
270 EXPECT_CALL(mock, sd_event_source_get_priority(expected_source, testing::_))
271 .WillOnce(DoAll(SetArgPointee<1>(1024), Return(0)));
272 EXPECT_EQ(1024, base->get_priority());
273}
274
275TEST_F(BaseMethodTest, GetPriorityError)
276{
277 EXPECT_CALL(mock, sd_event_source_get_priority(expected_source, testing::_))
278 .WillOnce(Return(-EINVAL));
279 EXPECT_THROW(base->get_priority(), SdEventError);
280}
281
282TEST_F(BaseMethodTest, SetPrioritySuccess)
283{
284 EXPECT_CALL(mock, sd_event_source_set_priority(expected_source, 1024))
285 .WillOnce(Return(0));
286 base->set_priority(1024);
287}
288
289TEST_F(BaseMethodTest, SetPriorityError)
290{
291 EXPECT_CALL(mock, sd_event_source_set_priority(expected_source, 1024))
292 .WillOnce(Return(-EINVAL));
293 EXPECT_THROW(base->set_priority(1024), SdEventError);
294}
295
296TEST_F(BaseMethodTest, GetEnabledSuccess)
297{
298 EXPECT_CALL(mock, sd_event_source_get_enabled(expected_source, testing::_))
299 .WillOnce(DoAll(SetArgPointee<1>(SD_EVENT_ON), Return(0)));
300 EXPECT_EQ(SD_EVENT_ON, base->get_enabled());
301}
302
303TEST_F(BaseMethodTest, GetEnabledError)
304{
305 EXPECT_CALL(mock, sd_event_source_get_enabled(expected_source, testing::_))
306 .WillOnce(Return(-EINVAL));
307 EXPECT_THROW(base->get_enabled(), SdEventError);
308}
309
310TEST_F(BaseMethodTest, SetEnabledSuccess)
311{
312 EXPECT_CALL(mock, sd_event_source_set_enabled(expected_source, SD_EVENT_ON))
313 .WillOnce(Return(0));
314 base->set_enabled(SD_EVENT_ON);
315}
316
317TEST_F(BaseMethodTest, SetEnabledError)
318{
319 EXPECT_CALL(mock, sd_event_source_set_enabled(expected_source, SD_EVENT_ON))
320 .WillOnce(Return(-EINVAL));
321 EXPECT_THROW(base->set_enabled(SD_EVENT_ON), SdEventError);
William A. Kennington III0a816c52018-07-17 14:40:14 -0700322}
323
324} // namespace
325} // namespace source
326} // namespace sdeventplus