diff options
| author | William A. Kennington III <wak@google.com> | 2018-07-22 18:16:22 -0700 |
|---|---|---|
| committer | William A. Kennington III <wak@google.com> | 2018-07-22 19:05:26 -0700 |
| commit | 571fdf9e9c35001d6aca73052020143833e1794b (patch) | |
| tree | e5b00b538c1dd855e93bab51fccc15b3a7b0f2be /test/source/child.cpp | |
| parent | 210ce580b1fcdad7e067cba671a613108a48e426 (diff) | |
| download | sdeventplus-571fdf9e9c35001d6aca73052020143833e1794b.tar.gz sdeventplus-571fdf9e9c35001d6aca73052020143833e1794b.zip | |
source/child: Implement
Diffstat (limited to 'test/source/child.cpp')
| -rw-r--r-- | test/source/child.cpp | 163 |
1 files changed, 163 insertions, 0 deletions
diff --git a/test/source/child.cpp b/test/source/child.cpp new file mode 100644 index 0000000..e1e1322 --- /dev/null +++ b/test/source/child.cpp @@ -0,0 +1,163 @@ +#include <cerrno> +#include <functional> +#include <gmock/gmock.h> +#include <gtest/gtest.h> +#include <memory> +#include <sdeventplus/event.hpp> +#include <sdeventplus/exception.hpp> +#include <sdeventplus/source/child.hpp> +#include <sdeventplus/test/sdevent.hpp> +#include <sys/wait.h> +#include <systemd/sd-event.h> +#include <type_traits> +#include <utility> + +namespace sdeventplus +{ +namespace source +{ +namespace +{ + +using testing::DoAll; +using testing::Return; +using testing::SaveArg; +using testing::SetArgPointee; + +using UniqueEvent = std::unique_ptr<Event, std::function<void(Event*)>>; + +class ChildTest : public testing::Test +{ + protected: + testing::StrictMock<test::SdEventMock> mock; + sd_event_source* const expected_source = + reinterpret_cast<sd_event_source*>(1234); + sd_event* const expected_event = reinterpret_cast<sd_event*>(2345); + UniqueEvent event = make_event(expected_event); + + UniqueEvent make_event(sd_event* event) + { + auto deleter = [this, event](Event* e) { + EXPECT_CALL(this->mock, sd_event_unref(event)) + .WillOnce(Return(nullptr)); + delete e; + }; + return UniqueEvent(new Event(event, std::false_type(), &mock), deleter); + } + + void expect_destruct() + { + { + testing::InSequence sequence; + EXPECT_CALL(mock, sd_event_source_set_enabled(expected_source, + SD_EVENT_OFF)) + .WillOnce(Return(0)); + EXPECT_CALL(mock, sd_event_source_unref(expected_source)) + .WillOnce(Return(nullptr)); + } + EXPECT_CALL(mock, sd_event_unref(expected_event)) + .WillOnce(Return(nullptr)); + } +}; + +TEST_F(ChildTest, ConstructSuccess) +{ + const pid_t pid = 50; + const int options = WEXITED; + + EXPECT_CALL(mock, sd_event_ref(expected_event)) + .WillOnce(Return(expected_event)); + sd_event_child_handler_t handler; + EXPECT_CALL(mock, sd_event_add_child(expected_event, testing::_, pid, + options, testing::_, nullptr)) + .WillOnce(DoAll(SetArgPointee<1>(expected_source), SaveArg<4>(&handler), + Return(0))); + void* userdata; + EXPECT_CALL(mock, sd_event_source_set_userdata(expected_source, testing::_)) + .WillOnce(DoAll(SaveArg<1>(&userdata), Return(nullptr))); + int completions = 0; + const siginfo_t* return_si; + Child::Callback callback = [&](Child&, const siginfo_t* si) { + return_si = si; + completions++; + }; + Child child(*event, pid, options, std::move(callback)); + EXPECT_FALSE(callback); + EXPECT_EQ(&child, userdata); + EXPECT_EQ(0, completions); + + const siginfo_t* expected_si = reinterpret_cast<siginfo_t*>(865); + EXPECT_EQ(0, handler(nullptr, expected_si, &child)); + EXPECT_EQ(1, completions); + EXPECT_EQ(expected_si, return_si); + + expect_destruct(); +} + +TEST_F(ChildTest, ConstructError) +{ + const pid_t pid = 50; + const int options = WEXITED; + + EXPECT_CALL(mock, sd_event_add_child(expected_event, testing::_, pid, + options, testing::_, nullptr)) + .WillOnce(Return(-EINVAL)); + int completions = 0; + Child::Callback callback = [&completions](Child&, const siginfo_t*) { + completions++; + }; + EXPECT_THROW(Child(*event, pid, options, std::move(callback)), + SdEventError); + EXPECT_TRUE(callback); + EXPECT_EQ(0, completions); +} + +class ChildMethodTest : public ChildTest +{ + protected: + std::unique_ptr<Child> child; + + void SetUp() + { + const pid_t pid = 50; + const int options = WEXITED; + + EXPECT_CALL(mock, sd_event_ref(expected_event)) + .WillOnce(Return(expected_event)); + EXPECT_CALL(mock, sd_event_add_child(expected_event, testing::_, pid, + options, testing::_, nullptr)) + .WillOnce(DoAll(SetArgPointee<1>(expected_source), Return(0))); + EXPECT_CALL(mock, + sd_event_source_set_userdata(expected_source, testing::_)) + .WillOnce(Return(nullptr)); + child = std::make_unique<Child>(*event, pid, options, + [](Child&, const siginfo_t*) {}); + } + + void TearDown() + { + expect_destruct(); + child.reset(); + } +}; + +TEST_F(ChildMethodTest, GetPidSuccess) +{ + const pid_t pid = 32; + EXPECT_CALL(mock, + sd_event_source_get_child_pid(expected_source, testing::_)) + .WillOnce(DoAll(SetArgPointee<1>(pid), Return(0))); + EXPECT_EQ(pid, child->get_pid()); +} + +TEST_F(ChildMethodTest, GetPidError) +{ + EXPECT_CALL(mock, + sd_event_source_get_child_pid(expected_source, testing::_)) + .WillOnce(Return(-EINVAL)); + EXPECT_THROW(child->get_pid(), SdEventError); +} + +} // namespace +} // namespace source +} // namespace sdeventplus |

