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