1571fdf9eSWilliam A. Kennington III #include <cerrno> 2571fdf9eSWilliam A. Kennington III #include <functional> 3571fdf9eSWilliam A. Kennington III #include <gmock/gmock.h> 4571fdf9eSWilliam A. Kennington III #include <gtest/gtest.h> 5571fdf9eSWilliam A. Kennington III #include <memory> 6571fdf9eSWilliam A. Kennington III #include <sdeventplus/event.hpp> 7571fdf9eSWilliam A. Kennington III #include <sdeventplus/exception.hpp> 8571fdf9eSWilliam A. Kennington III #include <sdeventplus/source/child.hpp> 9571fdf9eSWilliam A. Kennington III #include <sdeventplus/test/sdevent.hpp> 10571fdf9eSWilliam A. Kennington III #include <sys/wait.h> 11571fdf9eSWilliam A. Kennington III #include <systemd/sd-event.h> 12571fdf9eSWilliam A. Kennington III #include <type_traits> 13571fdf9eSWilliam A. Kennington III #include <utility> 14571fdf9eSWilliam A. Kennington III 15571fdf9eSWilliam A. Kennington III namespace sdeventplus 16571fdf9eSWilliam A. Kennington III { 17571fdf9eSWilliam A. Kennington III namespace source 18571fdf9eSWilliam A. Kennington III { 19571fdf9eSWilliam A. Kennington III namespace 20571fdf9eSWilliam A. Kennington III { 21571fdf9eSWilliam A. Kennington III 22571fdf9eSWilliam A. Kennington III using testing::DoAll; 23571fdf9eSWilliam A. Kennington III using testing::Return; 24571fdf9eSWilliam A. Kennington III using testing::SaveArg; 25571fdf9eSWilliam A. Kennington III using testing::SetArgPointee; 26571fdf9eSWilliam A. Kennington III 27571fdf9eSWilliam A. Kennington III using UniqueEvent = std::unique_ptr<Event, std::function<void(Event*)>>; 28571fdf9eSWilliam A. Kennington III 29571fdf9eSWilliam A. Kennington III class ChildTest : public testing::Test 30571fdf9eSWilliam A. Kennington III { 31571fdf9eSWilliam A. Kennington III protected: 32571fdf9eSWilliam A. Kennington III testing::StrictMock<test::SdEventMock> mock; 33571fdf9eSWilliam A. Kennington III sd_event_source* const expected_source = 34571fdf9eSWilliam A. Kennington III reinterpret_cast<sd_event_source*>(1234); 35571fdf9eSWilliam A. Kennington III sd_event* const expected_event = reinterpret_cast<sd_event*>(2345); 36571fdf9eSWilliam A. Kennington III UniqueEvent event = make_event(expected_event); 37571fdf9eSWilliam A. Kennington III 38571fdf9eSWilliam A. Kennington III UniqueEvent make_event(sd_event* event) 39571fdf9eSWilliam A. Kennington III { 40571fdf9eSWilliam A. Kennington III auto deleter = [this, event](Event* e) { 41571fdf9eSWilliam A. Kennington III EXPECT_CALL(this->mock, sd_event_unref(event)) 42571fdf9eSWilliam A. Kennington III .WillOnce(Return(nullptr)); 43571fdf9eSWilliam A. Kennington III delete e; 44571fdf9eSWilliam A. Kennington III }; 45571fdf9eSWilliam A. Kennington III return UniqueEvent(new Event(event, std::false_type(), &mock), deleter); 46571fdf9eSWilliam A. Kennington III } 47571fdf9eSWilliam A. Kennington III 48571fdf9eSWilliam A. Kennington III void expect_destruct() 49571fdf9eSWilliam A. Kennington III { 50571fdf9eSWilliam A. Kennington III { 51571fdf9eSWilliam A. Kennington III testing::InSequence sequence; 52571fdf9eSWilliam A. Kennington III EXPECT_CALL(mock, sd_event_source_set_enabled(expected_source, 53571fdf9eSWilliam A. Kennington III SD_EVENT_OFF)) 54571fdf9eSWilliam A. Kennington III .WillOnce(Return(0)); 55571fdf9eSWilliam A. Kennington III EXPECT_CALL(mock, sd_event_source_unref(expected_source)) 56571fdf9eSWilliam A. Kennington III .WillOnce(Return(nullptr)); 57571fdf9eSWilliam A. Kennington III } 58571fdf9eSWilliam A. Kennington III EXPECT_CALL(mock, sd_event_unref(expected_event)) 59571fdf9eSWilliam A. Kennington III .WillOnce(Return(nullptr)); 60571fdf9eSWilliam A. Kennington III } 61571fdf9eSWilliam A. Kennington III }; 62571fdf9eSWilliam A. Kennington III 63571fdf9eSWilliam A. Kennington III TEST_F(ChildTest, ConstructSuccess) 64571fdf9eSWilliam A. Kennington III { 65571fdf9eSWilliam A. Kennington III const pid_t pid = 50; 66571fdf9eSWilliam A. Kennington III const int options = WEXITED; 67571fdf9eSWilliam A. Kennington III 68571fdf9eSWilliam A. Kennington III EXPECT_CALL(mock, sd_event_ref(expected_event)) 69571fdf9eSWilliam A. Kennington III .WillOnce(Return(expected_event)); 70571fdf9eSWilliam A. Kennington III sd_event_child_handler_t handler; 71571fdf9eSWilliam A. Kennington III EXPECT_CALL(mock, sd_event_add_child(expected_event, testing::_, pid, 72571fdf9eSWilliam A. Kennington III options, testing::_, nullptr)) 73571fdf9eSWilliam A. Kennington III .WillOnce(DoAll(SetArgPointee<1>(expected_source), SaveArg<4>(&handler), 74571fdf9eSWilliam A. Kennington III Return(0))); 75571fdf9eSWilliam A. Kennington III void* userdata; 76571fdf9eSWilliam A. Kennington III EXPECT_CALL(mock, sd_event_source_set_userdata(expected_source, testing::_)) 77571fdf9eSWilliam A. Kennington III .WillOnce(DoAll(SaveArg<1>(&userdata), Return(nullptr))); 78571fdf9eSWilliam A. Kennington III int completions = 0; 79571fdf9eSWilliam A. Kennington III const siginfo_t* return_si; 80571fdf9eSWilliam A. Kennington III Child::Callback callback = [&](Child&, const siginfo_t* si) { 81571fdf9eSWilliam A. Kennington III return_si = si; 82571fdf9eSWilliam A. Kennington III completions++; 83571fdf9eSWilliam A. Kennington III }; 84571fdf9eSWilliam A. Kennington III Child child(*event, pid, options, std::move(callback)); 85571fdf9eSWilliam A. Kennington III EXPECT_FALSE(callback); 86571fdf9eSWilliam A. Kennington III EXPECT_EQ(&child, userdata); 87571fdf9eSWilliam A. Kennington III EXPECT_EQ(0, completions); 88571fdf9eSWilliam A. Kennington III 89571fdf9eSWilliam A. Kennington III const siginfo_t* expected_si = reinterpret_cast<siginfo_t*>(865); 90571fdf9eSWilliam A. Kennington III EXPECT_EQ(0, handler(nullptr, expected_si, &child)); 91571fdf9eSWilliam A. Kennington III EXPECT_EQ(1, completions); 92571fdf9eSWilliam A. Kennington III EXPECT_EQ(expected_si, return_si); 93571fdf9eSWilliam A. Kennington III 94*b53ef902SWilliam A. Kennington III child.set_callback(std::bind([]() {})); 95*b53ef902SWilliam A. Kennington III EXPECT_EQ(0, handler(nullptr, expected_si, &child)); 96*b53ef902SWilliam A. Kennington III EXPECT_EQ(1, completions); 97*b53ef902SWilliam A. Kennington III 98571fdf9eSWilliam A. Kennington III expect_destruct(); 99571fdf9eSWilliam A. Kennington III } 100571fdf9eSWilliam A. Kennington III 101571fdf9eSWilliam A. Kennington III TEST_F(ChildTest, ConstructError) 102571fdf9eSWilliam A. Kennington III { 103571fdf9eSWilliam A. Kennington III const pid_t pid = 50; 104571fdf9eSWilliam A. Kennington III const int options = WEXITED; 105571fdf9eSWilliam A. Kennington III 106571fdf9eSWilliam A. Kennington III EXPECT_CALL(mock, sd_event_add_child(expected_event, testing::_, pid, 107571fdf9eSWilliam A. Kennington III options, testing::_, nullptr)) 108571fdf9eSWilliam A. Kennington III .WillOnce(Return(-EINVAL)); 109571fdf9eSWilliam A. Kennington III int completions = 0; 110571fdf9eSWilliam A. Kennington III Child::Callback callback = [&completions](Child&, const siginfo_t*) { 111571fdf9eSWilliam A. Kennington III completions++; 112571fdf9eSWilliam A. Kennington III }; 113571fdf9eSWilliam A. Kennington III EXPECT_THROW(Child(*event, pid, options, std::move(callback)), 114571fdf9eSWilliam A. Kennington III SdEventError); 115571fdf9eSWilliam A. Kennington III EXPECT_TRUE(callback); 116571fdf9eSWilliam A. Kennington III EXPECT_EQ(0, completions); 117571fdf9eSWilliam A. Kennington III } 118571fdf9eSWilliam A. Kennington III 119571fdf9eSWilliam A. Kennington III class ChildMethodTest : public ChildTest 120571fdf9eSWilliam A. Kennington III { 121571fdf9eSWilliam A. Kennington III protected: 122571fdf9eSWilliam A. Kennington III std::unique_ptr<Child> child; 123571fdf9eSWilliam A. Kennington III 124571fdf9eSWilliam A. Kennington III void SetUp() 125571fdf9eSWilliam A. Kennington III { 126571fdf9eSWilliam A. Kennington III const pid_t pid = 50; 127571fdf9eSWilliam A. Kennington III const int options = WEXITED; 128571fdf9eSWilliam A. Kennington III 129571fdf9eSWilliam A. Kennington III EXPECT_CALL(mock, sd_event_ref(expected_event)) 130571fdf9eSWilliam A. Kennington III .WillOnce(Return(expected_event)); 131571fdf9eSWilliam A. Kennington III EXPECT_CALL(mock, sd_event_add_child(expected_event, testing::_, pid, 132571fdf9eSWilliam A. Kennington III options, testing::_, nullptr)) 133571fdf9eSWilliam A. Kennington III .WillOnce(DoAll(SetArgPointee<1>(expected_source), Return(0))); 134571fdf9eSWilliam A. Kennington III EXPECT_CALL(mock, 135571fdf9eSWilliam A. Kennington III sd_event_source_set_userdata(expected_source, testing::_)) 136571fdf9eSWilliam A. Kennington III .WillOnce(Return(nullptr)); 137571fdf9eSWilliam A. Kennington III child = std::make_unique<Child>(*event, pid, options, 138571fdf9eSWilliam A. Kennington III [](Child&, const siginfo_t*) {}); 139571fdf9eSWilliam A. Kennington III } 140571fdf9eSWilliam A. Kennington III 141571fdf9eSWilliam A. Kennington III void TearDown() 142571fdf9eSWilliam A. Kennington III { 143571fdf9eSWilliam A. Kennington III expect_destruct(); 144571fdf9eSWilliam A. Kennington III child.reset(); 145571fdf9eSWilliam A. Kennington III } 146571fdf9eSWilliam A. Kennington III }; 147571fdf9eSWilliam A. Kennington III 148571fdf9eSWilliam A. Kennington III TEST_F(ChildMethodTest, GetPidSuccess) 149571fdf9eSWilliam A. Kennington III { 150571fdf9eSWilliam A. Kennington III const pid_t pid = 32; 151571fdf9eSWilliam A. Kennington III EXPECT_CALL(mock, 152571fdf9eSWilliam A. Kennington III sd_event_source_get_child_pid(expected_source, testing::_)) 153571fdf9eSWilliam A. Kennington III .WillOnce(DoAll(SetArgPointee<1>(pid), Return(0))); 154571fdf9eSWilliam A. Kennington III EXPECT_EQ(pid, child->get_pid()); 155571fdf9eSWilliam A. Kennington III } 156571fdf9eSWilliam A. Kennington III 157571fdf9eSWilliam A. Kennington III TEST_F(ChildMethodTest, GetPidError) 158571fdf9eSWilliam A. Kennington III { 159571fdf9eSWilliam A. Kennington III EXPECT_CALL(mock, 160571fdf9eSWilliam A. Kennington III sd_event_source_get_child_pid(expected_source, testing::_)) 161571fdf9eSWilliam A. Kennington III .WillOnce(Return(-EINVAL)); 162571fdf9eSWilliam A. Kennington III EXPECT_THROW(child->get_pid(), SdEventError); 163571fdf9eSWilliam A. Kennington III } 164571fdf9eSWilliam A. Kennington III 165571fdf9eSWilliam A. Kennington III } // namespace 166571fdf9eSWilliam A. Kennington III } // namespace source 167571fdf9eSWilliam A. Kennington III } // namespace sdeventplus 168