source/base: Expose trivial built in methods
diff --git a/src/sdeventplus/internal/sdevent.hpp b/src/sdeventplus/internal/sdevent.hpp
index 7603a3d..e6c420c 100644
--- a/src/sdeventplus/internal/sdevent.hpp
+++ b/src/sdeventplus/internal/sdevent.hpp
@@ -25,6 +25,22 @@
sd_event_source_ref(sd_event_source* source) const = 0;
virtual sd_event_source*
sd_event_source_unref(sd_event_source* source) const = 0;
+
+ virtual int
+ sd_event_source_get_description(sd_event_source* source,
+ const char** description) const = 0;
+ virtual int
+ sd_event_source_set_description(sd_event_source* source,
+ const char* description) const = 0;
+ virtual int sd_event_source_get_pending(sd_event_source* source) const = 0;
+ virtual int sd_event_source_get_priority(sd_event_source* source,
+ int64_t* priority) const = 0;
+ virtual int sd_event_source_set_priority(sd_event_source* source,
+ int64_t priority) const = 0;
+ virtual int sd_event_source_get_enabled(sd_event_source* source,
+ int* enabled) const = 0;
+ virtual int sd_event_source_set_enabled(sd_event_source* source,
+ int enabled) const = 0;
};
class SdEventImpl : public SdEvent
@@ -74,6 +90,41 @@
{
return ::sd_event_source_unref(source);
}
+
+ int sd_event_source_get_description(sd_event_source* source,
+ const char** description) const override
+ {
+ return ::sd_event_source_get_description(source, description);
+ }
+ int sd_event_source_set_description(sd_event_source* source,
+ const char* description) const override
+ {
+ return ::sd_event_source_set_description(source, description);
+ }
+ int sd_event_source_get_pending(sd_event_source* source) const override
+ {
+ return ::sd_event_source_get_pending(source);
+ }
+ int sd_event_source_get_priority(sd_event_source* source,
+ int64_t* priority) const override
+ {
+ return ::sd_event_source_get_priority(source, priority);
+ }
+ int sd_event_source_set_priority(sd_event_source* source,
+ int64_t priority) const override
+ {
+ return ::sd_event_source_set_priority(source, priority);
+ }
+ int sd_event_source_get_enabled(sd_event_source* source,
+ int* enabled) const override
+ {
+ return ::sd_event_source_get_enabled(source, enabled);
+ }
+ int sd_event_source_set_enabled(sd_event_source* source,
+ int enabled) const override
+ {
+ return ::sd_event_source_set_enabled(source, enabled);
+ }
};
extern SdEventImpl sdevent_impl;
diff --git a/src/sdeventplus/source/base.cpp b/src/sdeventplus/source/base.cpp
index fd9b45f..d99d562 100644
--- a/src/sdeventplus/source/base.cpp
+++ b/src/sdeventplus/source/base.cpp
@@ -1,12 +1,93 @@
+#include <cerrno>
+#include <exception>
+#include <sdeventplus/exception.hpp>
#include <sdeventplus/internal/sdevent.hpp>
#include <sdeventplus/source/base.hpp>
+#include <stdexcept>
#include <type_traits>
+#include <utility>
namespace sdeventplus
{
namespace source
{
+Base::~Base()
+{
+ set_enabled(SD_EVENT_OFF);
+}
+
+const char* Base::get_description()
+{
+ const char* description;
+ int r =
+ sdevent->sd_event_source_get_description(source.get(), &description);
+ if (r < 0)
+ {
+ throw SdEventError(-r, "sd_event_source_get_description");
+ }
+ return description;
+}
+
+void Base::set_description(const char* description)
+{
+ int r = sdevent->sd_event_source_set_description(source.get(), description);
+ if (r < 0)
+ {
+ throw SdEventError(-r, "sd_event_source_set_description");
+ }
+}
+
+int Base::get_pending()
+{
+ int r = sdevent->sd_event_source_get_pending(source.get());
+ if (r < 0)
+ {
+ throw SdEventError(-r, "sd_event_source_get_pending");
+ }
+ return r;
+}
+
+int64_t Base::get_priority()
+{
+ int64_t priority;
+ int r = sdevent->sd_event_source_get_priority(source.get(), &priority);
+ if (r < 0)
+ {
+ throw SdEventError(-r, "sd_event_source_get_priority");
+ }
+ return priority;
+}
+
+void Base::set_priority(int64_t priority)
+{
+ int r = sdevent->sd_event_source_set_priority(source.get(), priority);
+ if (r < 0)
+ {
+ throw SdEventError(-r, "sd_event_source_set_priority");
+ }
+}
+
+int Base::get_enabled()
+{
+ int enabled;
+ int r = sdevent->sd_event_source_get_enabled(source.get(), &enabled);
+ if (r < 0)
+ {
+ throw SdEventError(-r, "sd_event_source_get_enabled");
+ }
+ return enabled;
+}
+
+void Base::set_enabled(int enabled)
+{
+ int r = sdevent->sd_event_source_set_enabled(source.get(), enabled);
+ if (r < 0)
+ {
+ throw SdEventError(-r, "sd_event_source_set_enabled");
+ }
+}
+
Base::Base(sd_event_source* source, internal::SdEvent* sdevent) :
sdevent(sdevent), source(source, &internal::SdEvent::sd_event_source_ref,
&internal::SdEvent::sd_event_source_unref, sdevent)
diff --git a/src/sdeventplus/source/base.hpp b/src/sdeventplus/source/base.hpp
index 88a17f0..20ab820 100644
--- a/src/sdeventplus/source/base.hpp
+++ b/src/sdeventplus/source/base.hpp
@@ -1,5 +1,6 @@
#pragma once
+#include <cstdint>
#include <sdeventplus/internal/sdevent.hpp>
#include <sdeventplus/internal/sdref.hpp>
#include <systemd/sd-bus.h>
@@ -13,15 +14,25 @@
class Base
{
public:
+ virtual ~Base();
+
// We don't want to allow any kind of slicing.
Base(const Base& source) = delete;
Base& operator=(const Base& source) = delete;
Base(Base&& source) = delete;
Base& operator=(Base&& source) = delete;
+ const char* get_description();
+ void set_description(const char* description);
+ int get_pending();
+ int64_t get_priority();
+ void set_priority(int64_t priority);
+ int get_enabled();
+ void set_enabled(int enabled);
+
protected:
- internal::SdEvent* sdevent;
- internal::SdRef<sd_event_source> source;
+ const internal::SdEvent* const sdevent;
+ const internal::SdRef<sd_event_source> source;
// Base sources cannot be directly constructed.
Base(sd_event_source* source,
diff --git a/src/sdeventplus/test/sdevent.hpp b/src/sdeventplus/test/sdevent.hpp
index 982e4e7..1cb723f 100644
--- a/src/sdeventplus/test/sdevent.hpp
+++ b/src/sdeventplus/test/sdevent.hpp
@@ -24,6 +24,21 @@
MOCK_CONST_METHOD1(sd_event_source_ref, sd_event_source*(sd_event_source*));
MOCK_CONST_METHOD1(sd_event_source_unref,
sd_event_source*(sd_event_source*));
+
+ MOCK_CONST_METHOD2(sd_event_source_get_description,
+ int(sd_event_source*, const char**));
+ MOCK_CONST_METHOD2(sd_event_source_set_description,
+ int(sd_event_source*, const char*));
+ MOCK_CONST_METHOD2(sd_event_source_set_prepare,
+ int(sd_event_source*, sd_event_handler_t));
+ MOCK_CONST_METHOD1(sd_event_source_get_pending, int(sd_event_source*));
+ MOCK_CONST_METHOD2(sd_event_source_get_priority,
+ int(sd_event_source*, int64_t*));
+ MOCK_CONST_METHOD2(sd_event_source_set_priority,
+ int(sd_event_source*, int64_t));
+ MOCK_CONST_METHOD2(sd_event_source_get_enabled,
+ int(sd_event_source*, int*));
+ MOCK_CONST_METHOD2(sd_event_source_set_enabled, int(sd_event_source*, int));
};
} // namespace test
diff --git a/test/source/base.cpp b/test/source/base.cpp
index 3bf76c0..ce95f12 100644
--- a/test/source/base.cpp
+++ b/test/source/base.cpp
@@ -1,8 +1,10 @@
#include <gmock/gmock.h>
#include <gtest/gtest.h>
+#include <sdeventplus/exception.hpp>
#include <sdeventplus/internal/sdevent.hpp>
#include <sdeventplus/source/base.hpp>
#include <sdeventplus/test/sdevent.hpp>
+#include <string>
#include <type_traits>
namespace sdeventplus
@@ -12,7 +14,9 @@
namespace
{
+using testing::DoAll;
using testing::Return;
+using testing::SetArgPointee;
class BaseImpl : public Base
{
@@ -42,16 +46,163 @@
.WillOnce(Return(expected_source));
BaseImpl source(expected_source, &mock);
- EXPECT_CALL(mock, sd_event_source_unref(expected_source))
- .WillOnce(Return(nullptr));
+ {
+ testing::InSequence seq;
+ 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));
+ }
}
TEST_F(BaseTest, NewBaseNoRef)
{
BaseImpl source(expected_source, std::false_type(), &mock);
- EXPECT_CALL(mock, sd_event_source_unref(expected_source))
- .WillOnce(Return(nullptr));
+ {
+ testing::InSequence seq;
+ 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));
+ }
+}
+
+class BaseMethodTest : public BaseTest
+{
+ protected:
+ std::unique_ptr<BaseImpl> base;
+
+ void SetUp()
+ {
+ base = std::make_unique<BaseImpl>(expected_source, std::false_type(),
+ &mock);
+ }
+
+ void TearDown()
+ {
+ {
+ testing::InSequence seq;
+ 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));
+ }
+ }
+};
+
+TEST_F(BaseMethodTest, GetDescriptionSuccess)
+{
+ const char* expected = "test_desc";
+ EXPECT_CALL(mock,
+ sd_event_source_get_description(expected_source, testing::_))
+ .WillOnce(DoAll(SetArgPointee<1>(expected), Return(0)));
+ // Intentionally comparing pointers to make sure no copying is happening
+ EXPECT_EQ(expected, base->get_description());
+}
+
+TEST_F(BaseMethodTest, GetDescriptionError)
+{
+ EXPECT_CALL(mock,
+ sd_event_source_get_description(expected_source, testing::_))
+ .WillOnce(Return(-EINVAL));
+ EXPECT_THROW(base->get_description(), SdEventError);
+}
+
+TEST_F(BaseMethodTest, SetDescriptionSuccess)
+{
+ const char* expected = "test desc";
+ // Intentionally comparing pointers to make sure no copying is happening
+ EXPECT_CALL(mock,
+ sd_event_source_set_description(expected_source, expected))
+ .WillOnce(Return(0));
+ base->set_description(expected);
+}
+
+TEST_F(BaseMethodTest, SetDescriptionError)
+{
+ const char* expected = "test desc";
+ // Intentionally comparing pointers to make sure no copying is happening
+ EXPECT_CALL(mock,
+ sd_event_source_set_description(expected_source, expected))
+ .WillOnce(Return(-EINVAL));
+ EXPECT_THROW(base->set_description(expected), SdEventError);
+}
+
+TEST_F(BaseMethodTest, GetPendingSuccess)
+{
+ EXPECT_CALL(mock, sd_event_source_get_pending(expected_source))
+ .WillOnce(Return(0));
+ EXPECT_EQ(0, base->get_pending());
+ EXPECT_CALL(mock, sd_event_source_get_pending(expected_source))
+ .WillOnce(Return(4));
+ EXPECT_EQ(4, base->get_pending());
+}
+
+TEST_F(BaseMethodTest, GetPendingError)
+{
+ EXPECT_CALL(mock, sd_event_source_get_pending(expected_source))
+ .WillOnce(Return(-EINVAL));
+ EXPECT_THROW(base->get_pending(), SdEventError);
+}
+
+TEST_F(BaseMethodTest, GetPrioritySuccess)
+{
+ EXPECT_CALL(mock, sd_event_source_get_priority(expected_source, testing::_))
+ .WillOnce(DoAll(SetArgPointee<1>(1024), Return(0)));
+ EXPECT_EQ(1024, base->get_priority());
+}
+
+TEST_F(BaseMethodTest, GetPriorityError)
+{
+ EXPECT_CALL(mock, sd_event_source_get_priority(expected_source, testing::_))
+ .WillOnce(Return(-EINVAL));
+ EXPECT_THROW(base->get_priority(), SdEventError);
+}
+
+TEST_F(BaseMethodTest, SetPrioritySuccess)
+{
+ EXPECT_CALL(mock, sd_event_source_set_priority(expected_source, 1024))
+ .WillOnce(Return(0));
+ base->set_priority(1024);
+}
+
+TEST_F(BaseMethodTest, SetPriorityError)
+{
+ EXPECT_CALL(mock, sd_event_source_set_priority(expected_source, 1024))
+ .WillOnce(Return(-EINVAL));
+ EXPECT_THROW(base->set_priority(1024), SdEventError);
+}
+
+TEST_F(BaseMethodTest, GetEnabledSuccess)
+{
+ EXPECT_CALL(mock, sd_event_source_get_enabled(expected_source, testing::_))
+ .WillOnce(DoAll(SetArgPointee<1>(SD_EVENT_ON), Return(0)));
+ EXPECT_EQ(SD_EVENT_ON, base->get_enabled());
+}
+
+TEST_F(BaseMethodTest, GetEnabledError)
+{
+ EXPECT_CALL(mock, sd_event_source_get_enabled(expected_source, testing::_))
+ .WillOnce(Return(-EINVAL));
+ EXPECT_THROW(base->get_enabled(), SdEventError);
+}
+
+TEST_F(BaseMethodTest, SetEnabledSuccess)
+{
+ EXPECT_CALL(mock, sd_event_source_set_enabled(expected_source, SD_EVENT_ON))
+ .WillOnce(Return(0));
+ base->set_enabled(SD_EVENT_ON);
+}
+
+TEST_F(BaseMethodTest, SetEnabledError)
+{
+ EXPECT_CALL(mock, sd_event_source_set_enabled(expected_source, SD_EVENT_ON))
+ .WillOnce(Return(-EINVAL));
+ EXPECT_THROW(base->set_enabled(SD_EVENT_ON), SdEventError);
}
} // namespace