Use tag dispatching to construct various types of Connection, refactor Connection unit tests

This commit is contained in:
sangelovic
2019-11-03 20:30:52 +01:00
parent 099bc857ad
commit 304b69dd8b
5 changed files with 153 additions and 148 deletions

View File

@ -35,54 +35,33 @@
#include <poll.h> #include <poll.h>
#include <sys/eventfd.h> #include <sys/eventfd.h>
namespace {
std::vector</*const */char*> to_strv(const std::vector<std::string>& strings)
{
std::vector</*const */char*> strv;
for (auto& str : strings)
strv.push_back(const_cast<char*>(str.c_str()));
strv.push_back(nullptr);
return strv;
}
}
namespace sdbus { namespace internal { namespace sdbus { namespace internal {
Connection::Connection(Connection::BusType type, std::unique_ptr<ISdBus>&& interface) Connection::Connection(std::unique_ptr<ISdBus>&& interface, const BusFactory& busFactory)
: iface_(std::move(interface)) : iface_(std::move(interface))
, busType_(type) , bus_(openBus(busFactory))
{ {
assert(iface_ != nullptr); assert(iface_ != nullptr);
auto bus = openBus(busType_);
bus_.reset(bus);
finishHandshake(bus);
loopExitFd_ = createProcessingLoopExitDescriptor();
} }
Connection::Connection(const std::string& host, std::unique_ptr<ISdBus> &&interface) Connection::Connection(std::unique_ptr<ISdBus>&& interface, system_bus_t)
: iface_(std::move(interface)) : Connection(std::move(interface), [this](sd_bus** bus){ return iface_->sd_bus_open_system(bus); })
, busType_(BusType::eRemoteSystem)
, host_(host)
{ {
assert(iface_ != nullptr); }
auto bus = openBus(busType_); Connection::Connection(std::unique_ptr<ISdBus>&& interface, session_bus_t)
bus_.reset(bus); : Connection(std::move(interface), [this](sd_bus** bus){ return iface_->sd_bus_open_user(bus); })
{
}
finishHandshake(bus); Connection::Connection(std::unique_ptr<ISdBus>&& interface, remote_system_bus_t, const std::string& host)
: Connection(std::move(interface), [this, &host](sd_bus** bus){ return iface_->sd_bus_open_system_remote(bus, host.c_str()); })
loopExitFd_ = createProcessingLoopExitDescriptor(); {
} }
Connection::~Connection() Connection::~Connection()
{ {
leaveProcessingLoop(); leaveProcessingLoop();
closeProcessingLoopExitDescriptor(loopExitFd_);
} }
void Connection::requestName(const std::string& name) void Connection::requestName(const std::string& name)
@ -301,23 +280,15 @@ SlotPtr Connection::registerSignalHandler( const std::string& objectPath
return {slot, [this](void *slot){ iface_->sd_bus_slot_unref((sd_bus_slot*)slot); }}; return {slot, [this](void *slot){ iface_->sd_bus_slot_unref((sd_bus_slot*)slot); }};
} }
sd_bus* Connection::openBus(Connection::BusType type) Connection::BusPtr Connection::openBus(const BusFactory& busFactory)
{ {
sd_bus* bus{}; sd_bus* bus{};
int r = 0; int r = busFactory(&bus);
if (type == BusType::eSystem)
r = iface_->sd_bus_open_system(&bus);
else if (type == BusType::eSession)
r = iface_->sd_bus_open_user(&bus);
else if (type == BusType::eRemoteSystem)
r = iface_->sd_bus_open_system_remote(&bus, host_.c_str());
else
assert(false);
SDBUS_THROW_ERROR_IF(r < 0, "Failed to open bus", -r); SDBUS_THROW_ERROR_IF(r < 0, "Failed to open bus", -r);
assert(bus != nullptr);
return bus; BusPtr busPtr{bus, [this](sd_bus* bus){ return iface_->sd_bus_flush_close_unref(bus); }};
finishHandshake(busPtr.get());
return busPtr;
} }
void Connection::finishHandshake(sd_bus* bus) void Connection::finishHandshake(sd_bus* bus)
@ -333,33 +304,19 @@ void Connection::finishHandshake(sd_bus* bus)
SDBUS_THROW_ERROR_IF(r < 0, "Failed to flush bus on opening", -r); SDBUS_THROW_ERROR_IF(r < 0, "Failed to flush bus on opening", -r);
} }
int Connection::createProcessingLoopExitDescriptor()
{
auto r = eventfd(0, EFD_SEMAPHORE | EFD_CLOEXEC | EFD_NONBLOCK);
SDBUS_THROW_ERROR_IF(r < 0, "Failed to create event object", -errno);
return r;
}
void Connection::closeProcessingLoopExitDescriptor(int fd)
{
close(fd);
}
void Connection::notifyProcessingLoopToExit() void Connection::notifyProcessingLoopToExit()
{ {
assert(loopExitFd_ >= 0); assert(loopExitFd_.fd >= 0);
uint64_t value = 1; uint64_t value = 1;
auto r = write(loopExitFd_, &value, sizeof(value)); auto r = write(loopExitFd_.fd, &value, sizeof(value));
SDBUS_THROW_ERROR_IF(r < 0, "Failed to notify processing loop", -errno); SDBUS_THROW_ERROR_IF(r < 0, "Failed to notify processing loop", -errno);
} }
void Connection::clearExitNotification() void Connection::clearExitNotification()
{ {
uint64_t value{}; uint64_t value{};
auto r = read(loopExitFd_, &value, sizeof(value)); auto r = read(loopExitFd_.fd, &value, sizeof(value));
SDBUS_THROW_ERROR_IF(r < 0, "Failed to read from the event descriptor", -errno); SDBUS_THROW_ERROR_IF(r < 0, "Failed to read from the event descriptor", -errno);
} }
@ -385,10 +342,10 @@ bool Connection::waitForNextRequest()
auto bus = bus_.get(); auto bus = bus_.get();
assert(bus != nullptr); assert(bus != nullptr);
assert(loopExitFd_ != 0); assert(loopExitFd_.fd != 0);
auto sdbusPollData = getProcessLoopPollData(); auto sdbusPollData = getProcessLoopPollData();
struct pollfd fds[] = {{sdbusPollData.fd, sdbusPollData.events, 0}, {loopExitFd_, POLLIN, 0}}; struct pollfd fds[] = {{sdbusPollData.fd, sdbusPollData.events, 0}, {loopExitFd_.fd, POLLIN, 0}};
auto fdsCount = sizeof(fds)/sizeof(fds[0]); auto fdsCount = sizeof(fds)/sizeof(fds[0]);
auto timeout = sdbusPollData.timeout_usec == (uint64_t) -1 ? (uint64_t)-1 : (sdbusPollData.timeout_usec+999)/1000; auto timeout = sdbusPollData.timeout_usec == (uint64_t) -1 ? (uint64_t)-1 : (sdbusPollData.timeout_usec+999)/1000;
@ -422,6 +379,27 @@ std::string Connection::composeSignalMatchFilter( const std::string& objectPath
return filter; return filter;
} }
std::vector</*const */char*> Connection::to_strv(const std::vector<std::string>& strings)
{
std::vector</*const */char*> strv;
for (auto& str : strings)
strv.push_back(const_cast<char*>(str.c_str()));
strv.push_back(nullptr);
return strv;
}
Connection::LoopExitEventFd::LoopExitEventFd()
{
fd = eventfd(0, EFD_SEMAPHORE | EFD_CLOEXEC | EFD_NONBLOCK);
SDBUS_THROW_ERROR_IF(fd < 0, "Failed to create event object", -errno);
}
Connection::LoopExitEventFd::~LoopExitEventFd()
{
assert(fd >= 0);
close(fd);
}
}} }}
namespace sdbus { namespace sdbus {
@ -440,8 +418,8 @@ std::unique_ptr<sdbus::IConnection> createSystemBusConnection()
{ {
auto interface = std::make_unique<sdbus::internal::SdBus>(); auto interface = std::make_unique<sdbus::internal::SdBus>();
assert(interface != nullptr); assert(interface != nullptr);
return std::make_unique<sdbus::internal::Connection>( sdbus::internal::Connection::BusType::eSystem constexpr sdbus::internal::Connection::system_bus_t system_bus;
, std::move(interface)); return std::make_unique<sdbus::internal::Connection>(std::move(interface), system_bus);
} }
std::unique_ptr<sdbus::IConnection> createSystemBusConnection(const std::string& name) std::unique_ptr<sdbus::IConnection> createSystemBusConnection(const std::string& name)
@ -455,8 +433,8 @@ std::unique_ptr<sdbus::IConnection> createSessionBusConnection()
{ {
auto interface = std::make_unique<sdbus::internal::SdBus>(); auto interface = std::make_unique<sdbus::internal::SdBus>();
assert(interface != nullptr); assert(interface != nullptr);
return std::make_unique<sdbus::internal::Connection>( sdbus::internal::Connection::BusType::eSession constexpr sdbus::internal::Connection::session_bus_t session_bus;
, std::move(interface)); return std::make_unique<sdbus::internal::Connection>(std::move(interface), session_bus);
} }
std::unique_ptr<sdbus::IConnection> createSessionBusConnection(const std::string& name) std::unique_ptr<sdbus::IConnection> createSessionBusConnection(const std::string& name)
@ -470,8 +448,8 @@ std::unique_ptr<sdbus::IConnection> createRemoteSystemBusConnection(const std::s
{ {
auto interface = std::make_unique<sdbus::internal::SdBus>(); auto interface = std::make_unique<sdbus::internal::SdBus>();
assert(interface != nullptr); assert(interface != nullptr);
return std::make_unique<sdbus::internal::Connection>( host constexpr sdbus::internal::Connection::remote_system_bus_t remote_system_bus;
, std::move(interface)); return std::make_unique<sdbus::internal::Connection>(std::move(interface), remote_system_bus, host);
} }
} }

View File

@ -35,6 +35,8 @@
#include <systemd/sd-bus.h> #include <systemd/sd-bus.h>
#include <memory> #include <memory>
#include <thread> #include <thread>
#include <string>
#include <vector>
namespace sdbus { namespace internal { namespace sdbus { namespace internal {
@ -43,15 +45,14 @@ namespace sdbus { namespace internal {
, public sdbus::internal::IConnection // Internal, private interface , public sdbus::internal::IConnection // Internal, private interface
{ {
public: public:
enum class BusType // Bus type tags
{ struct system_bus_t{};
eSystem, struct session_bus_t{};
eSession, struct remote_system_bus_t{};
eRemoteSystem,
};
Connection(BusType type, std::unique_ptr<ISdBus>&& interface); Connection(std::unique_ptr<ISdBus>&& interface, system_bus_t);
Connection(const std::string& host, std::unique_ptr<ISdBus>&& interface); Connection(std::unique_ptr<ISdBus>&& interface, session_bus_t);
Connection(std::unique_ptr<ISdBus>&& interface, remote_system_bus_t, const std::string& host);
~Connection() override; ~Connection() override;
void requestName(const std::string& name) override; void requestName(const std::string& name) override;
@ -102,10 +103,12 @@ namespace sdbus { namespace internal {
, void* userData ) override; , void* userData ) override;
private: private:
sd_bus* openBus(Connection::BusType type); using BusFactory = std::function<int(sd_bus**)>;
using BusPtr = std::unique_ptr<sd_bus, std::function<sd_bus*(sd_bus*)>>;
Connection(std::unique_ptr<ISdBus>&& interface, const BusFactory& busFactory);
BusPtr openBus(const std::function<int(sd_bus**)>& busFactory);
void finishHandshake(sd_bus* bus); void finishHandshake(sd_bus* bus);
static int createProcessingLoopExitDescriptor();
static void closeProcessingLoopExitDescriptor(int fd);
bool waitForNextRequest(); bool waitForNextRequest();
static std::string composeSignalMatchFilter( const std::string& objectPath static std::string composeSignalMatchFilter( const std::string& objectPath
, const std::string& interfaceName , const std::string& interfaceName
@ -113,18 +116,20 @@ namespace sdbus { namespace internal {
void notifyProcessingLoopToExit(); void notifyProcessingLoopToExit();
void clearExitNotification(); void clearExitNotification();
void joinWithProcessingLoop(); void joinWithProcessingLoop();
static std::vector</*const */char*> to_strv(const std::vector<std::string>& strings);
struct LoopExitEventFd
{
LoopExitEventFd();
~LoopExitEventFd();
int fd;
};
private: private:
std::unique_ptr<ISdBus> iface_; std::unique_ptr<ISdBus> iface_;
std::unique_ptr<sd_bus, std::function<sd_bus*(sd_bus*)>> bus_ {nullptr, [this](sd_bus* bus) BusPtr bus_;
{
return iface_->sd_bus_flush_close_unref(bus);
}};
BusType busType_;
std::thread asyncLoopThread_; std::thread asyncLoopThread_;
int loopExitFd_{-1}; LoopExitEventFd loopExitFd_;
std::string host_;
}; };
}} }}

View File

@ -35,17 +35,18 @@ using ::testing::DoAll;
using ::testing::SetArgPointee; using ::testing::SetArgPointee;
using ::testing::Return; using ::testing::Return;
using ::testing::NiceMock; using ::testing::NiceMock;
using sdbus::internal::Connection;
using BusType = sdbus::internal::Connection::BusType; constexpr sdbus::internal::Connection::system_bus_t system_bus;
constexpr sdbus::internal::Connection::session_bus_t session_bus;
constexpr sdbus::internal::Connection::remote_system_bus_t remote_system_bus;
class ConnectionCreationTest : public ::testing::Test class ConnectionCreationTest : public ::testing::Test
{ {
protected: protected:
ConnectionCreationTest() = default; ConnectionCreationTest() = default;
std::unique_ptr<NiceMock<SdBusMock>> mock_ { std::make_unique<NiceMock<SdBusMock>>() }; std::unique_ptr<NiceMock<SdBusMock>> sdBusIntfMock_ = std::make_unique<NiceMock<SdBusMock>>();
sd_bus* STUB_ { reinterpret_cast<sd_bus*>(1) }; sd_bus* fakeBusPtr_ = reinterpret_cast<sd_bus*>(1);
}; };
using ASystemBusConnection = ConnectionCreationTest; using ASystemBusConnection = ConnectionCreationTest;
@ -53,99 +54,119 @@ using ASessionBusConnection = ConnectionCreationTest;
TEST_F(ASystemBusConnection, OpensAndFlushesBusWhenCreated) TEST_F(ASystemBusConnection, OpensAndFlushesBusWhenCreated)
{ {
EXPECT_CALL(*mock_, sd_bus_open_system(_)).WillOnce(DoAll(SetArgPointee<0>(STUB_), Return(1))); EXPECT_CALL(*sdBusIntfMock_, sd_bus_open_system(_)).WillOnce(DoAll(SetArgPointee<0>(fakeBusPtr_), Return(1)));
EXPECT_CALL(*mock_, sd_bus_flush(_)).Times(1); EXPECT_CALL(*sdBusIntfMock_, sd_bus_flush(_)).Times(1);
sdbus::internal::Connection(BusType::eSystem, std::move(mock_)); Connection(std::move(sdBusIntfMock_), system_bus);
} }
TEST_F(ASessionBusConnection, OpensAndFlushesBusWhenCreated) TEST_F(ASessionBusConnection, OpensAndFlushesBusWhenCreated)
{ {
EXPECT_CALL(*mock_, sd_bus_open_user(_)).WillOnce(DoAll(SetArgPointee<0>(STUB_), Return(1))); EXPECT_CALL(*sdBusIntfMock_, sd_bus_open_user(_)).WillOnce(DoAll(SetArgPointee<0>(fakeBusPtr_), Return(1)));
EXPECT_CALL(*mock_, sd_bus_flush(_)).Times(1); EXPECT_CALL(*sdBusIntfMock_, sd_bus_flush(_)).Times(1);
sdbus::internal::Connection(BusType::eSession, std::move(mock_)); Connection(std::move(sdBusIntfMock_), session_bus);
} }
TEST_F(ASystemBusConnection, ClosesAndUnrefsBusWhenDestructed) TEST_F(ASystemBusConnection, ClosesAndUnrefsBusWhenDestructed)
{ {
ON_CALL(*mock_, sd_bus_open_user(_)).WillByDefault(DoAll(SetArgPointee<0>(STUB_), Return(1))); ON_CALL(*sdBusIntfMock_, sd_bus_open_user(_)).WillByDefault(DoAll(SetArgPointee<0>(fakeBusPtr_), Return(1)));
EXPECT_CALL(*mock_, sd_bus_flush_close_unref(_)).Times(1); EXPECT_CALL(*sdBusIntfMock_, sd_bus_flush_close_unref(_)).Times(1);
sdbus::internal::Connection(BusType::eSession, std::move(mock_)); Connection(std::move(sdBusIntfMock_), session_bus);
} }
TEST_F(ASessionBusConnection, ClosesAndUnrefsBusWhenDestructed) TEST_F(ASessionBusConnection, ClosesAndUnrefsBusWhenDestructed)
{ {
ON_CALL(*mock_, sd_bus_open_user(_)).WillByDefault(DoAll(SetArgPointee<0>(STUB_), Return(1))); ON_CALL(*sdBusIntfMock_, sd_bus_open_user(_)).WillByDefault(DoAll(SetArgPointee<0>(fakeBusPtr_), Return(1)));
EXPECT_CALL(*mock_, sd_bus_flush_close_unref(_)).Times(1); EXPECT_CALL(*sdBusIntfMock_, sd_bus_flush_close_unref(_)).Times(1);
sdbus::internal::Connection(BusType::eSession, std::move(mock_)); Connection(std::move(sdBusIntfMock_), session_bus);
} }
TEST_F(ASystemBusConnection, ThrowsErrorWhenOpeningTheBusFailsDuringConstruction) TEST_F(ASystemBusConnection, ThrowsErrorWhenOpeningTheBusFailsDuringConstruction)
{ {
ON_CALL(*mock_, sd_bus_open_system(_)).WillByDefault(DoAll(SetArgPointee<0>(STUB_), Return(-1))); ON_CALL(*sdBusIntfMock_, sd_bus_open_system(_)).WillByDefault(DoAll(SetArgPointee<0>(fakeBusPtr_), Return(-1)));
ASSERT_THROW(sdbus::internal::Connection(BusType::eSystem, std::move(mock_)), sdbus::Error); ASSERT_THROW(Connection(std::move(sdBusIntfMock_), system_bus), sdbus::Error);
} }
TEST_F(ASessionBusConnection, ThrowsErrorWhenOpeningTheBusFailsDuringConstruction) TEST_F(ASessionBusConnection, ThrowsErrorWhenOpeningTheBusFailsDuringConstruction)
{ {
ON_CALL(*mock_, sd_bus_open_user(_)).WillByDefault(DoAll(SetArgPointee<0>(STUB_), Return(-1))); ON_CALL(*sdBusIntfMock_, sd_bus_open_user(_)).WillByDefault(DoAll(SetArgPointee<0>(fakeBusPtr_), Return(-1)));
ASSERT_THROW(sdbus::internal::Connection(BusType::eSession, std::move(mock_)), sdbus::Error); ASSERT_THROW(Connection(std::move(sdBusIntfMock_), session_bus), sdbus::Error);
} }
TEST_F(ASystemBusConnection, ThrowsErrorWhenFlushingTheBusFailsDuringConstruction) TEST_F(ASystemBusConnection, ThrowsErrorWhenFlushingTheBusFailsDuringConstruction)
{ {
ON_CALL(*mock_, sd_bus_open_system(_)).WillByDefault(DoAll(SetArgPointee<0>(STUB_), Return(1))); ON_CALL(*sdBusIntfMock_, sd_bus_open_system(_)).WillByDefault(DoAll(SetArgPointee<0>(fakeBusPtr_), Return(1)));
ON_CALL(*mock_, sd_bus_flush(_)).WillByDefault(Return(-1)); ON_CALL(*sdBusIntfMock_, sd_bus_flush(_)).WillByDefault(Return(-1));
ASSERT_THROW(sdbus::internal::Connection(BusType::eSystem, std::move(mock_)), sdbus::Error); ASSERT_THROW(Connection(std::move(sdBusIntfMock_), system_bus), sdbus::Error);
} }
TEST_F(ASessionBusConnection, ThrowsErrorWhenFlushingTheBusFailsDuringConstruction) TEST_F(ASessionBusConnection, ThrowsErrorWhenFlushingTheBusFailsDuringConstruction)
{ {
ON_CALL(*mock_, sd_bus_open_user(_)).WillByDefault(DoAll(SetArgPointee<0>(STUB_), Return(1))); ON_CALL(*sdBusIntfMock_, sd_bus_open_user(_)).WillByDefault(DoAll(SetArgPointee<0>(fakeBusPtr_), Return(1)));
ON_CALL(*mock_, sd_bus_flush(_)).WillByDefault(Return(-1)); ON_CALL(*sdBusIntfMock_, sd_bus_flush(_)).WillByDefault(Return(-1));
ASSERT_THROW(sdbus::internal::Connection(BusType::eSession, std::move(mock_)), sdbus::Error); ASSERT_THROW(Connection(std::move(sdBusIntfMock_), session_bus), sdbus::Error);
} }
class ConnectionRequestTest : public ::testing::TestWithParam<BusType> namespace
{
template <typename _BusTypeTag>
class AConnectionNameRequest : public ::testing::Test
{ {
protected: protected:
ConnectionRequestTest() = default; void setUpBusOpenExpectation();
std::unique_ptr<Connection> makeConnection();
void SetUp() override void SetUp() override
{ {
switch (GetParam()) setUpBusOpenExpectation();
{ ON_CALL(*sdBusIntfMock_, sd_bus_flush(_)).WillByDefault(Return(1));
case BusType::eSystem: ON_CALL(*sdBusIntfMock_, sd_bus_flush_close_unref(_)).WillByDefault(Return(fakeBusPtr_));
EXPECT_CALL(*mock_, sd_bus_open_system(_)).WillOnce(DoAll(SetArgPointee<0>(STUB_), Return(1))); con_ = makeConnection();
break;
case BusType::eSession:
EXPECT_CALL(*mock_, sd_bus_open_user(_)).WillOnce(DoAll(SetArgPointee<0>(STUB_), Return(1)));
break;
default:
break;
}
ON_CALL(*mock_, sd_bus_flush(_)).WillByDefault(Return(1));
ON_CALL(*mock_, sd_bus_flush_close_unref(_)).WillByDefault(Return(STUB_));
} }
std::unique_ptr<NiceMock<SdBusMock>> mock_ { std::make_unique<NiceMock<SdBusMock>>() }; NiceMock<SdBusMock>* sdBusIntfMock_ = new NiceMock<SdBusMock>(); // con_ below will assume ownership
sd_bus* STUB_ { reinterpret_cast<sd_bus*>(1) }; sd_bus* fakeBusPtr_ = reinterpret_cast<sd_bus*>(1);
std::unique_ptr<Connection> con_;
}; };
using AConnectionNameRequest = ConnectionRequestTest; template<> void AConnectionNameRequest<Connection::system_bus_t>::setUpBusOpenExpectation()
TEST_P(AConnectionNameRequest, DoesNotThrowOnSuccess)
{ {
EXPECT_CALL(*mock_, sd_bus_request_name(_, _, _)).WillOnce(Return(1)); EXPECT_CALL(*sdBusIntfMock_, sd_bus_open_system(_)).WillOnce(DoAll(SetArgPointee<0>(fakeBusPtr_), Return(1)));
sdbus::internal::Connection(GetParam(), std::move(mock_)).requestName(""); }
template<> void AConnectionNameRequest<Connection::session_bus_t>::setUpBusOpenExpectation()
{
EXPECT_CALL(*sdBusIntfMock_, sd_bus_open_user(_)).WillOnce(DoAll(SetArgPointee<0>(fakeBusPtr_), Return(1)));
}
template<> void AConnectionNameRequest<Connection::remote_system_bus_t>::setUpBusOpenExpectation()
{
EXPECT_CALL(*sdBusIntfMock_, sd_bus_open_system_remote(_, _)).WillOnce(DoAll(SetArgPointee<0>(fakeBusPtr_), Return(1)));
}
template <typename _BusTypeTag>
std::unique_ptr<Connection> AConnectionNameRequest<_BusTypeTag>::makeConnection()
{
return std::make_unique<Connection>(std::unique_ptr<NiceMock<SdBusMock>>(sdBusIntfMock_), _BusTypeTag{});
}
template<> std::unique_ptr<Connection> AConnectionNameRequest<Connection::remote_system_bus_t>::makeConnection()
{
return std::make_unique<Connection>(std::unique_ptr<NiceMock<SdBusMock>>(sdBusIntfMock_), remote_system_bus, "some host");
} }
TEST_P(AConnectionNameRequest, ThrowsOnFail) typedef ::testing::Types< Connection::system_bus_t
{ , Connection::session_bus_t
EXPECT_CALL(*mock_, sd_bus_request_name(_, _, _)).WillOnce(Return(-1)); , Connection::remote_system_bus_t
> BusTypeTags;
sdbus::internal::Connection conn_(GetParam(), std::move(mock_)); TYPED_TEST_SUITE(AConnectionNameRequest, BusTypeTags);
ASSERT_THROW(conn_.requestName(""), sdbus::Error);
} }
// INSTANTIATE_TEST_SUITE_P is defined in googletest master, but not in googletest v1.8.1 that we are using now TYPED_TEST(AConnectionNameRequest, DoesNotThrowOnSuccess)
INSTANTIATE_TEST_CASE_P(Request, AConnectionNameRequest, ::testing::Values(BusType::eSystem, BusType::eSession)); {
//INSTANTIATE_TEST_SUITE_P(Request, AConnectionNameRequest, ::testing::Values(BusType::eSystem, BusType::eSession)) EXPECT_CALL(*this->sdBusIntfMock_, sd_bus_request_name(_, _, _)).WillOnce(Return(1));
this->con_->requestName("org.sdbuscpp.somename");
}
TYPED_TEST(AConnectionNameRequest, ThrowsOnFail)
{
EXPECT_CALL(*this->sdBusIntfMock_, sd_bus_request_name(_, _, _)).WillOnce(Return(-1));
ASSERT_THROW(this->con_->requestName("org.sdbuscpp.somename"), sdbus::Error);
}

View File

@ -121,7 +121,7 @@ namespace
, ComplexType , ComplexType
> DBusSupportedTypes; > DBusSupportedTypes;
TYPED_TEST_CASE(Type2DBusTypeSignatureConversion, DBusSupportedTypes); TYPED_TEST_SUITE(Type2DBusTypeSignatureConversion, DBusSupportedTypes);
} }
/*-------------------------------------*/ /*-------------------------------------*/

View File

@ -58,6 +58,7 @@ public:
MOCK_METHOD1(sd_bus_open_user, int(sd_bus **ret)); MOCK_METHOD1(sd_bus_open_user, int(sd_bus **ret));
MOCK_METHOD1(sd_bus_open_system, int(sd_bus **ret)); MOCK_METHOD1(sd_bus_open_system, int(sd_bus **ret));
MOCK_METHOD2(sd_bus_open_system_remote, int(sd_bus **ret, const char *host));
MOCK_METHOD3(sd_bus_request_name, int(sd_bus *bus, const char *name, uint64_t flags)); MOCK_METHOD3(sd_bus_request_name, int(sd_bus *bus, const char *name, uint64_t flags));
MOCK_METHOD2(sd_bus_release_name, int(sd_bus *bus, const char *name)); MOCK_METHOD2(sd_bus_release_name, int(sd_bus *bus, const char *name));
MOCK_METHOD6(sd_bus_add_object_vtable, int(sd_bus *bus, sd_bus_slot **slot, const char *path, const char *interface, const sd_bus_vtable *vtable, void *userdata)); MOCK_METHOD6(sd_bus_add_object_vtable, int(sd_bus *bus, sd_bus_slot **slot, const char *path, const char *interface, const sd_bus_vtable *vtable, void *userdata));