blob: 1d5a877c91a46cc923f6558ce50ae522e9a357fa [file] [log] [blame]
William A. Kennington III5a7365c2018-07-22 00:22:08 -07001#include <cerrno>
2#include <functional>
3#include <gmock/gmock.h>
4#include <gtest/gtest.h>
5#include <memory>
6#include <sdeventplus/event.hpp>
7#include <sdeventplus/exception.hpp>
8#include <sdeventplus/source/event.hpp>
9#include <sdeventplus/test/sdevent.hpp>
10#include <systemd/sd-event.h>
William A. Kennington IIIebcb4f12018-07-22 16:51:36 -070011#include <type_traits>
William A. Kennington III5a7365c2018-07-22 00:22:08 -070012#include <utility>
13
14namespace sdeventplus
15{
16namespace source
17{
18namespace
19{
20
21using testing::DoAll;
22using testing::Return;
William A. Kennington III5320b1f2019-03-29 20:00:37 -070023using testing::ReturnPointee;
William A. Kennington III5a7365c2018-07-22 00:22:08 -070024using testing::SaveArg;
25using testing::SetArgPointee;
26
William A. Kennington III86be5dd2018-07-23 09:46:18 -070027using UniqueEvent = std::unique_ptr<Event, std::function<void(Event*)>>;
William A. Kennington III5a7365c2018-07-22 00:22:08 -070028
29class EventTest : public testing::Test
30{
31 protected:
32 testing::StrictMock<test::SdEventMock> mock;
33 sd_event_source* const expected_source =
34 reinterpret_cast<sd_event_source*>(1234);
35 sd_event* const expected_event = reinterpret_cast<sd_event*>(2345);
36 UniqueEvent event = make_event(expected_event);
37
38 UniqueEvent make_event(sd_event* event)
39 {
William A. Kennington III86be5dd2018-07-23 09:46:18 -070040 auto deleter = [this, event](Event* e) {
William A. Kennington III5a7365c2018-07-22 00:22:08 -070041 EXPECT_CALL(this->mock, sd_event_unref(event))
42 .WillOnce(Return(nullptr));
43 delete e;
44 };
William A. Kennington III86be5dd2018-07-23 09:46:18 -070045 return UniqueEvent(new Event(event, std::false_type(), &mock), deleter);
William A. Kennington III5a7365c2018-07-22 00:22:08 -070046 }
47
48 void expect_destruct()
49 {
William A. Kennington III5320b1f2019-03-29 20:00:37 -070050 EXPECT_CALL(mock, sd_event_source_unref(expected_source))
51 .WillOnce(Return(nullptr));
William A. Kennington III5a7365c2018-07-22 00:22:08 -070052 EXPECT_CALL(mock, sd_event_unref(expected_event))
53 .WillOnce(Return(nullptr));
54 }
55};
56
57TEST_F(EventTest, DeferConstruct)
58{
59 EXPECT_CALL(mock, sd_event_ref(expected_event))
60 .WillOnce(Return(expected_event));
William A. Kennington III5320b1f2019-03-29 20:00:37 -070061 sd_event_destroy_t destroy;
William A. Kennington III5a7365c2018-07-22 00:22:08 -070062 void* userdata;
William A. Kennington III5320b1f2019-03-29 20:00:37 -070063 {
64 testing::InSequence seq;
65 EXPECT_CALL(mock, sd_event_source_set_destroy_callback(expected_source,
66 testing::_))
67 .WillOnce(DoAll(SaveArg<1>(&destroy), Return(0)));
68 EXPECT_CALL(mock,
69 sd_event_source_set_userdata(expected_source, testing::_))
70 .WillOnce(DoAll(SaveArg<1>(&userdata), Return(nullptr)));
71 EXPECT_CALL(mock, sd_event_source_get_userdata(expected_source))
72 .WillRepeatedly(ReturnPointee(&userdata));
73 }
William A. Kennington III5a7365c2018-07-22 00:22:08 -070074 sd_event_handler_t handler;
75 EXPECT_CALL(mock, sd_event_add_defer(expected_event, testing::_, testing::_,
76 nullptr))
77 .WillOnce(DoAll(SetArgPointee<1>(expected_source), SaveArg<2>(&handler),
78 Return(0)));
79 int completions = 0;
William A. Kennington III86be5dd2018-07-23 09:46:18 -070080 EventBase::Callback callback = [&completions](EventBase&) {
81 completions++;
82 };
William A. Kennington III5a7365c2018-07-22 00:22:08 -070083 Defer defer(*event, std::move(callback));
William A. Kennington III5320b1f2019-03-29 20:00:37 -070084 EXPECT_NE(&defer, userdata);
William A. Kennington III5a7365c2018-07-22 00:22:08 -070085 EXPECT_FALSE(callback);
86 EXPECT_EQ(0, completions);
87
William A. Kennington III5320b1f2019-03-29 20:00:37 -070088 EXPECT_EQ(0, handler(nullptr, userdata));
William A. Kennington III5a7365c2018-07-22 00:22:08 -070089 EXPECT_EQ(1, completions);
90
William A. Kennington IIIb53ef902018-10-29 20:06:45 -070091 defer.set_callback(std::bind([]() {}));
William A. Kennington III5320b1f2019-03-29 20:00:37 -070092 EXPECT_EQ(0, handler(nullptr, userdata));
William A. Kennington IIIb53ef902018-10-29 20:06:45 -070093 EXPECT_EQ(1, completions);
94
William A. Kennington III5a7365c2018-07-22 00:22:08 -070095 expect_destruct();
William A. Kennington III5320b1f2019-03-29 20:00:37 -070096 destroy(userdata);
William A. Kennington III5a7365c2018-07-22 00:22:08 -070097}
98
99TEST_F(EventTest, PostConstruct)
100{
101 EXPECT_CALL(mock, sd_event_ref(expected_event))
102 .WillOnce(Return(expected_event));
William A. Kennington III5320b1f2019-03-29 20:00:37 -0700103 sd_event_destroy_t destroy;
William A. Kennington III5a7365c2018-07-22 00:22:08 -0700104 void* userdata;
William A. Kennington III5320b1f2019-03-29 20:00:37 -0700105 {
106 testing::InSequence seq;
107 EXPECT_CALL(mock, sd_event_source_set_destroy_callback(expected_source,
108 testing::_))
109 .WillOnce(DoAll(SaveArg<1>(&destroy), Return(0)));
110 EXPECT_CALL(mock,
111 sd_event_source_set_userdata(expected_source, testing::_))
112 .WillOnce(DoAll(SaveArg<1>(&userdata), Return(nullptr)));
113 EXPECT_CALL(mock, sd_event_source_get_userdata(expected_source))
114 .WillRepeatedly(ReturnPointee(&userdata));
115 }
William A. Kennington III5a7365c2018-07-22 00:22:08 -0700116 sd_event_handler_t handler;
117 EXPECT_CALL(mock, sd_event_add_post(expected_event, testing::_, testing::_,
118 nullptr))
119 .WillOnce(DoAll(SetArgPointee<1>(expected_source), SaveArg<2>(&handler),
120 Return(0)));
121 int completions = 0;
William A. Kennington III86be5dd2018-07-23 09:46:18 -0700122 EventBase::Callback callback = [&completions](EventBase&) {
123 completions++;
124 };
William A. Kennington III5a7365c2018-07-22 00:22:08 -0700125 Post post(*event, std::move(callback));
William A. Kennington III5320b1f2019-03-29 20:00:37 -0700126 EXPECT_NE(&post, userdata);
William A. Kennington III5a7365c2018-07-22 00:22:08 -0700127 EXPECT_FALSE(callback);
128 EXPECT_EQ(0, completions);
129
William A. Kennington III5320b1f2019-03-29 20:00:37 -0700130 EXPECT_EQ(0, handler(nullptr, userdata));
William A. Kennington III5a7365c2018-07-22 00:22:08 -0700131 EXPECT_EQ(1, completions);
132
133 expect_destruct();
William A. Kennington III5320b1f2019-03-29 20:00:37 -0700134 destroy(userdata);
William A. Kennington III5a7365c2018-07-22 00:22:08 -0700135}
136
137TEST_F(EventTest, ExitConstruct)
138{
139 EXPECT_CALL(mock, sd_event_ref(expected_event))
140 .WillOnce(Return(expected_event));
William A. Kennington III5320b1f2019-03-29 20:00:37 -0700141 sd_event_destroy_t destroy;
William A. Kennington III5a7365c2018-07-22 00:22:08 -0700142 void* userdata;
William A. Kennington III5320b1f2019-03-29 20:00:37 -0700143 {
144 testing::InSequence seq;
145 EXPECT_CALL(mock, sd_event_source_set_destroy_callback(expected_source,
146 testing::_))
147 .WillOnce(DoAll(SaveArg<1>(&destroy), Return(0)));
148 EXPECT_CALL(mock,
149 sd_event_source_set_userdata(expected_source, testing::_))
150 .WillOnce(DoAll(SaveArg<1>(&userdata), Return(nullptr)));
151 EXPECT_CALL(mock, sd_event_source_get_userdata(expected_source))
152 .WillRepeatedly(ReturnPointee(&userdata));
153 }
William A. Kennington III5a7365c2018-07-22 00:22:08 -0700154 sd_event_handler_t handler;
155 EXPECT_CALL(mock, sd_event_add_exit(expected_event, testing::_, testing::_,
156 nullptr))
157 .WillOnce(DoAll(SetArgPointee<1>(expected_source), SaveArg<2>(&handler),
158 Return(0)));
159 int completions = 0;
William A. Kennington III86be5dd2018-07-23 09:46:18 -0700160 EventBase::Callback callback = [&completions](EventBase&) {
161 completions++;
162 };
William A. Kennington III5a7365c2018-07-22 00:22:08 -0700163 Exit exit(*event, std::move(callback));
William A. Kennington III5320b1f2019-03-29 20:00:37 -0700164 EXPECT_NE(&exit, userdata);
William A. Kennington III5a7365c2018-07-22 00:22:08 -0700165 EXPECT_FALSE(callback);
166 EXPECT_EQ(0, completions);
167
William A. Kennington III5320b1f2019-03-29 20:00:37 -0700168 EXPECT_EQ(0, handler(nullptr, userdata));
William A. Kennington III5a7365c2018-07-22 00:22:08 -0700169 EXPECT_EQ(1, completions);
170
171 expect_destruct();
William A. Kennington III5320b1f2019-03-29 20:00:37 -0700172 destroy(userdata);
William A. Kennington III5a7365c2018-07-22 00:22:08 -0700173}
174
175TEST_F(EventTest, ConstructFailure)
176{
177 EXPECT_CALL(mock, sd_event_add_defer(expected_event, testing::_, testing::_,
178 nullptr))
179 .WillOnce(Return(-EINVAL));
180 int completions = 0;
William A. Kennington III86be5dd2018-07-23 09:46:18 -0700181 EventBase::Callback callback = [&completions](EventBase&) {
182 completions++;
183 };
William A. Kennington III5a7365c2018-07-22 00:22:08 -0700184 EXPECT_THROW(Defer(*event, std::move(callback)), SdEventError);
185 EXPECT_TRUE(callback);
186 EXPECT_EQ(0, completions);
187}
188
189} // namespace
190} // namespace source
191} // namespace sdeventplus