blob: 13c534a1809e3831f118ef1e958505598c67a347 [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 III65db8632018-07-17 14:40:14 -07004#include <sdeventplus/exception.hpp>
William A. Kennington III0a816c52018-07-17 14:40:14 -07005#include <sdeventplus/internal/sdevent.hpp>
6#include <sdeventplus/source/base.hpp>
7#include <sdeventplus/test/sdevent.hpp>
William A. Kennington III65db8632018-07-17 14:40:14 -07008#include <string>
William A. Kennington III48c42752018-07-17 14:40:14 -07009#include <system_error>
William A. Kennington III0a816c52018-07-17 14:40:14 -070010#include <type_traits>
11
12namespace sdeventplus
13{
14namespace source
15{
16namespace
17{
18
William A. Kennington III65db8632018-07-17 14:40:14 -070019using testing::DoAll;
William A. Kennington III0a816c52018-07-17 14:40:14 -070020using testing::Return;
William A. Kennington III48c42752018-07-17 14:40:14 -070021using testing::SaveArg;
William A. Kennington III65db8632018-07-17 14:40:14 -070022using testing::SetArgPointee;
William A. Kennington III0a816c52018-07-17 14:40:14 -070023
24class BaseImpl : public Base
25{
26 public:
27 BaseImpl(sd_event_source* source, internal::SdEvent* sdevent) :
28 Base(source, sdevent)
29 {
30 }
31 BaseImpl(sd_event_source* source, std::false_type,
32 internal::SdEvent* sdevent) :
33 Base(source, std::false_type(), sdevent)
34 {
35 }
36};
37
38class BaseTest : public testing::Test
39{
40 protected:
41 testing::StrictMock<test::SdEventMock> mock;
42 sd_event_source* const expected_source =
43 reinterpret_cast<sd_event_source*>(1234);
44};
45
46TEST_F(BaseTest, NewBaseRef)
47{
48 EXPECT_CALL(mock, sd_event_source_ref(expected_source))
49 .WillOnce(Return(expected_source));
50 BaseImpl source(expected_source, &mock);
51
William A. Kennington III65db8632018-07-17 14:40:14 -070052 {
53 testing::InSequence seq;
54 EXPECT_CALL(mock,
55 sd_event_source_set_enabled(expected_source, SD_EVENT_OFF))
56 .WillOnce(Return(0));
57 EXPECT_CALL(mock, sd_event_source_unref(expected_source))
58 .WillOnce(Return(nullptr));
59 }
William A. Kennington III0a816c52018-07-17 14:40:14 -070060}
61
62TEST_F(BaseTest, NewBaseNoRef)
63{
64 BaseImpl source(expected_source, std::false_type(), &mock);
65
William A. Kennington III65db8632018-07-17 14:40:14 -070066 {
67 testing::InSequence seq;
68 EXPECT_CALL(mock,
69 sd_event_source_set_enabled(expected_source, SD_EVENT_OFF))
70 .WillOnce(Return(0));
71 EXPECT_CALL(mock, sd_event_source_unref(expected_source))
72 .WillOnce(Return(nullptr));
73 }
74}
75
76class BaseMethodTest : public BaseTest
77{
78 protected:
79 std::unique_ptr<BaseImpl> base;
80
81 void SetUp()
82 {
83 base = std::make_unique<BaseImpl>(expected_source, std::false_type(),
84 &mock);
85 }
86
87 void TearDown()
88 {
89 {
90 testing::InSequence seq;
91 EXPECT_CALL(mock, sd_event_source_set_enabled(expected_source,
92 SD_EVENT_OFF))
93 .WillOnce(Return(0));
94 EXPECT_CALL(mock, sd_event_source_unref(expected_source))
95 .WillOnce(Return(nullptr));
96 }
97 }
98};
99
100TEST_F(BaseMethodTest, GetDescriptionSuccess)
101{
102 const char* expected = "test_desc";
103 EXPECT_CALL(mock,
104 sd_event_source_get_description(expected_source, testing::_))
105 .WillOnce(DoAll(SetArgPointee<1>(expected), Return(0)));
106 // Intentionally comparing pointers to make sure no copying is happening
107 EXPECT_EQ(expected, base->get_description());
108}
109
110TEST_F(BaseMethodTest, GetDescriptionError)
111{
112 EXPECT_CALL(mock,
113 sd_event_source_get_description(expected_source, testing::_))
114 .WillOnce(Return(-EINVAL));
115 EXPECT_THROW(base->get_description(), SdEventError);
116}
117
118TEST_F(BaseMethodTest, SetDescriptionSuccess)
119{
120 const char* expected = "test desc";
121 // Intentionally comparing pointers to make sure no copying is happening
122 EXPECT_CALL(mock,
123 sd_event_source_set_description(expected_source, expected))
124 .WillOnce(Return(0));
125 base->set_description(expected);
126}
127
128TEST_F(BaseMethodTest, SetDescriptionError)
129{
130 const char* expected = "test desc";
131 // Intentionally comparing pointers to make sure no copying is happening
132 EXPECT_CALL(mock,
133 sd_event_source_set_description(expected_source, expected))
134 .WillOnce(Return(-EINVAL));
135 EXPECT_THROW(base->set_description(expected), SdEventError);
136}
137
William A. Kennington III48c42752018-07-17 14:40:14 -0700138TEST_F(BaseMethodTest, SetPrepareCallback)
139{
140 bool completed = false;
141 Base::Callback callback = [&completed](Base&) { completed = true; };
142 sd_event_handler_t event_handler;
143 EXPECT_CALL(mock, sd_event_source_set_prepare(expected_source, testing::_))
144 .WillOnce(DoAll(SaveArg<1>(&event_handler), Return(0)));
145 base->set_prepare(std::move(callback));
146 EXPECT_FALSE(callback);
147 EXPECT_FALSE(completed);
148
149 EXPECT_EQ(0, event_handler(nullptr, base.get()));
150 EXPECT_TRUE(completed);
151}
152
153TEST_F(BaseMethodTest, SetPrepareCallbackNoUserdata)
154{
155 Base::Callback callback = [](Base&) {};
156 sd_event_handler_t event_handler;
157 EXPECT_CALL(mock, sd_event_source_set_prepare(expected_source, testing::_))
158 .WillOnce(DoAll(SaveArg<1>(&event_handler), Return(0)));
159 base->set_prepare(std::move(callback));
160 EXPECT_FALSE(callback);
161
162 EXPECT_EQ(-EINVAL, event_handler(nullptr, nullptr));
163}
164
165TEST_F(BaseMethodTest, SetPrepareNull)
166{
167 EXPECT_CALL(mock, sd_event_source_set_prepare(expected_source, nullptr))
168 .WillOnce(Return(0));
169 base->set_prepare(nullptr);
170 EXPECT_EQ(-ENOSYS, base->prepareCallback());
171}
172
173TEST_F(BaseMethodTest, SetPrepareSystemError)
174{
175 Base::Callback callback = [](Base&) {
176 throw std::system_error(EBUSY, std::generic_category());
177 };
178 EXPECT_CALL(mock, sd_event_source_set_prepare(expected_source, testing::_))
179 .WillOnce(Return(0));
180 base->set_prepare(std::move(callback));
181 EXPECT_FALSE(callback);
182 EXPECT_EQ(-EBUSY, base->prepareCallback());
183}
184
185TEST_F(BaseMethodTest, SetPrepareUnknownException)
186{
187 Base::Callback callback = [](Base&) { throw static_cast<int>(1); };
188 EXPECT_CALL(mock, sd_event_source_set_prepare(expected_source, testing::_))
189 .WillOnce(Return(0));
190 base->set_prepare(std::move(callback));
191 EXPECT_FALSE(callback);
192 EXPECT_EQ(-ENOSYS, base->prepareCallback());
193}
194
195TEST_F(BaseMethodTest, SetPrepareError)
196{
197 Base::Callback callback = [](Base&) {};
198 EXPECT_CALL(mock, sd_event_source_set_prepare(expected_source, testing::_))
199 .WillOnce(Return(-EINVAL));
200 EXPECT_THROW(base->set_prepare(std::move(callback)), SdEventError);
201 EXPECT_TRUE(callback);
202 EXPECT_EQ(-ENOSYS, base->prepareCallback());
203}
204
William A. Kennington III65db8632018-07-17 14:40:14 -0700205TEST_F(BaseMethodTest, GetPendingSuccess)
206{
207 EXPECT_CALL(mock, sd_event_source_get_pending(expected_source))
208 .WillOnce(Return(0));
209 EXPECT_EQ(0, base->get_pending());
210 EXPECT_CALL(mock, sd_event_source_get_pending(expected_source))
211 .WillOnce(Return(4));
212 EXPECT_EQ(4, base->get_pending());
213}
214
215TEST_F(BaseMethodTest, GetPendingError)
216{
217 EXPECT_CALL(mock, sd_event_source_get_pending(expected_source))
218 .WillOnce(Return(-EINVAL));
219 EXPECT_THROW(base->get_pending(), SdEventError);
220}
221
222TEST_F(BaseMethodTest, GetPrioritySuccess)
223{
224 EXPECT_CALL(mock, sd_event_source_get_priority(expected_source, testing::_))
225 .WillOnce(DoAll(SetArgPointee<1>(1024), Return(0)));
226 EXPECT_EQ(1024, base->get_priority());
227}
228
229TEST_F(BaseMethodTest, GetPriorityError)
230{
231 EXPECT_CALL(mock, sd_event_source_get_priority(expected_source, testing::_))
232 .WillOnce(Return(-EINVAL));
233 EXPECT_THROW(base->get_priority(), SdEventError);
234}
235
236TEST_F(BaseMethodTest, SetPrioritySuccess)
237{
238 EXPECT_CALL(mock, sd_event_source_set_priority(expected_source, 1024))
239 .WillOnce(Return(0));
240 base->set_priority(1024);
241}
242
243TEST_F(BaseMethodTest, SetPriorityError)
244{
245 EXPECT_CALL(mock, sd_event_source_set_priority(expected_source, 1024))
246 .WillOnce(Return(-EINVAL));
247 EXPECT_THROW(base->set_priority(1024), SdEventError);
248}
249
250TEST_F(BaseMethodTest, GetEnabledSuccess)
251{
252 EXPECT_CALL(mock, sd_event_source_get_enabled(expected_source, testing::_))
253 .WillOnce(DoAll(SetArgPointee<1>(SD_EVENT_ON), Return(0)));
254 EXPECT_EQ(SD_EVENT_ON, base->get_enabled());
255}
256
257TEST_F(BaseMethodTest, GetEnabledError)
258{
259 EXPECT_CALL(mock, sd_event_source_get_enabled(expected_source, testing::_))
260 .WillOnce(Return(-EINVAL));
261 EXPECT_THROW(base->get_enabled(), SdEventError);
262}
263
264TEST_F(BaseMethodTest, SetEnabledSuccess)
265{
266 EXPECT_CALL(mock, sd_event_source_set_enabled(expected_source, SD_EVENT_ON))
267 .WillOnce(Return(0));
268 base->set_enabled(SD_EVENT_ON);
269}
270
271TEST_F(BaseMethodTest, SetEnabledError)
272{
273 EXPECT_CALL(mock, sd_event_source_set_enabled(expected_source, SD_EVENT_ON))
274 .WillOnce(Return(-EINVAL));
275 EXPECT_THROW(base->set_enabled(SD_EVENT_ON), SdEventError);
William A. Kennington III0a816c52018-07-17 14:40:14 -0700276}
277
278} // namespace
279} // namespace source
280} // namespace sdeventplus