/** * (C) 2016 - 2021 KISTLER INSTRUMENTE AG, Winterthur, Switzerland * (C) 2016 - 2022 Stanislav Angelovic * * @file Connection_test.cpp * @author Ardazishvili Roman (ardazishvili.roman@yandex.ru) * * Created on: Feb 4, 2019 * Project: sdbus-c++ * Description: High-level D-Bus IPC C++ library based on sd-bus * * This file is part of sdbus-c++. * * sdbus-c++ is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. * * sdbus-c++ is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with sdbus-c++. If not, see . */ #include "Connection.h" #include "unittests/mocks/SdBusMock.h" #include using ::testing::_; using ::testing::DoAll; using ::testing::SetArgPointee; using ::testing::Return; using ::testing::NiceMock; using ::sdbus::internal::Connection; class ConnectionCreationTest : public ::testing::Test { protected: ConnectionCreationTest() = default; std::unique_ptr> sdBusIntfMock_ = std::make_unique>(); sd_bus* fakeBusPtr_ = reinterpret_cast(1); }; using ADefaultBusConnection = ConnectionCreationTest; using ASystemBusConnection = ConnectionCreationTest; using ASessionBusConnection = ConnectionCreationTest; TEST_F(ADefaultBusConnection, OpensAndFlushesBusWhenCreated) { EXPECT_CALL(*sdBusIntfMock_, sd_bus_open(_)).WillOnce(DoAll(SetArgPointee<0>(fakeBusPtr_), Return(1))); EXPECT_CALL(*sdBusIntfMock_, sd_bus_flush(_)).Times(1); Connection(std::move(sdBusIntfMock_), Connection::default_bus); } TEST_F(ASystemBusConnection, OpensAndFlushesBusWhenCreated) { EXPECT_CALL(*sdBusIntfMock_, sd_bus_open_system(_)).WillOnce(DoAll(SetArgPointee<0>(fakeBusPtr_), Return(1))); EXPECT_CALL(*sdBusIntfMock_, sd_bus_flush(_)).Times(1); Connection(std::move(sdBusIntfMock_), Connection::system_bus); } TEST_F(ASessionBusConnection, OpensAndFlushesBusWhenCreated) { EXPECT_CALL(*sdBusIntfMock_, sd_bus_open_user(_)).WillOnce(DoAll(SetArgPointee<0>(fakeBusPtr_), Return(1))); EXPECT_CALL(*sdBusIntfMock_, sd_bus_flush(_)).Times(1); Connection(std::move(sdBusIntfMock_), Connection::session_bus); } TEST_F(ADefaultBusConnection, ClosesAndUnrefsBusWhenDestructed) { ON_CALL(*sdBusIntfMock_, sd_bus_open(_)).WillByDefault(DoAll(SetArgPointee<0>(fakeBusPtr_), Return(1))); EXPECT_CALL(*sdBusIntfMock_, sd_bus_flush_close_unref(_)).Times(1); Connection(std::move(sdBusIntfMock_), Connection::default_bus); } TEST_F(ASystemBusConnection, ClosesAndUnrefsBusWhenDestructed) { ON_CALL(*sdBusIntfMock_, sd_bus_open_system(_)).WillByDefault(DoAll(SetArgPointee<0>(fakeBusPtr_), Return(1))); EXPECT_CALL(*sdBusIntfMock_, sd_bus_flush_close_unref(_)).Times(1); Connection(std::move(sdBusIntfMock_), Connection::system_bus); } TEST_F(ASessionBusConnection, ClosesAndUnrefsBusWhenDestructed) { ON_CALL(*sdBusIntfMock_, sd_bus_open_user(_)).WillByDefault(DoAll(SetArgPointee<0>(fakeBusPtr_), Return(1))); EXPECT_CALL(*sdBusIntfMock_, sd_bus_flush_close_unref(_)).Times(1); Connection(std::move(sdBusIntfMock_), Connection::session_bus); } TEST_F(ADefaultBusConnection, ThrowsErrorWhenOpeningTheBusFailsDuringConstruction) { ON_CALL(*sdBusIntfMock_, sd_bus_open(_)).WillByDefault(DoAll(SetArgPointee<0>(fakeBusPtr_), Return(-1))); ASSERT_THROW(Connection(std::move(sdBusIntfMock_), Connection::default_bus), sdbus::Error); } TEST_F(ASystemBusConnection, ThrowsErrorWhenOpeningTheBusFailsDuringConstruction) { ON_CALL(*sdBusIntfMock_, sd_bus_open_system(_)).WillByDefault(DoAll(SetArgPointee<0>(fakeBusPtr_), Return(-1))); ASSERT_THROW(Connection(std::move(sdBusIntfMock_), Connection::system_bus), sdbus::Error); } TEST_F(ASessionBusConnection, ThrowsErrorWhenOpeningTheBusFailsDuringConstruction) { ON_CALL(*sdBusIntfMock_, sd_bus_open_user(_)).WillByDefault(DoAll(SetArgPointee<0>(fakeBusPtr_), Return(-1))); ASSERT_THROW(Connection(std::move(sdBusIntfMock_), Connection::session_bus), sdbus::Error); } TEST_F(ADefaultBusConnection, ThrowsErrorWhenFlushingTheBusFailsDuringConstruction) { ON_CALL(*sdBusIntfMock_, sd_bus_open(_)).WillByDefault(DoAll(SetArgPointee<0>(fakeBusPtr_), Return(1))); ON_CALL(*sdBusIntfMock_, sd_bus_flush(_)).WillByDefault(Return(-1)); ASSERT_THROW(Connection(std::move(sdBusIntfMock_), Connection::default_bus), sdbus::Error); } TEST_F(ASystemBusConnection, ThrowsErrorWhenFlushingTheBusFailsDuringConstruction) { ON_CALL(*sdBusIntfMock_, sd_bus_open_system(_)).WillByDefault(DoAll(SetArgPointee<0>(fakeBusPtr_), Return(1))); ON_CALL(*sdBusIntfMock_, sd_bus_flush(_)).WillByDefault(Return(-1)); ASSERT_THROW(Connection(std::move(sdBusIntfMock_), Connection::system_bus), sdbus::Error); } TEST_F(ASessionBusConnection, ThrowsErrorWhenFlushingTheBusFailsDuringConstruction) { ON_CALL(*sdBusIntfMock_, sd_bus_open_user(_)).WillByDefault(DoAll(SetArgPointee<0>(fakeBusPtr_), Return(1))); ON_CALL(*sdBusIntfMock_, sd_bus_flush(_)).WillByDefault(Return(-1)); ASSERT_THROW(Connection(std::move(sdBusIntfMock_), Connection::session_bus), sdbus::Error); } namespace { template class AConnectionNameRequest : public ::testing::Test { protected: void setUpBusOpenExpectation(); std::unique_ptr makeConnection(); void SetUp() override { setUpBusOpenExpectation(); ON_CALL(*sdBusIntfMock_, sd_bus_flush(_)).WillByDefault(Return(1)); ON_CALL(*sdBusIntfMock_, sd_bus_flush_close_unref(_)).WillByDefault(Return(fakeBusPtr_)); con_ = makeConnection(); } NiceMock* sdBusIntfMock_ = new NiceMock(); // con_ below will assume ownership sd_bus* fakeBusPtr_ = reinterpret_cast(1); std::unique_ptr con_; }; template<> void AConnectionNameRequest::setUpBusOpenExpectation() { EXPECT_CALL(*sdBusIntfMock_, sd_bus_open(_)).WillOnce(DoAll(SetArgPointee<0>(fakeBusPtr_), Return(1))); } template<> void AConnectionNameRequest::setUpBusOpenExpectation() { EXPECT_CALL(*sdBusIntfMock_, sd_bus_open_system(_)).WillOnce(DoAll(SetArgPointee<0>(fakeBusPtr_), Return(1))); } template<> void AConnectionNameRequest::setUpBusOpenExpectation() { EXPECT_CALL(*sdBusIntfMock_, sd_bus_open_user(_)).WillOnce(DoAll(SetArgPointee<0>(fakeBusPtr_), Return(1))); } template<> void AConnectionNameRequest::setUpBusOpenExpectation() { EXPECT_CALL(*sdBusIntfMock_, sd_bus_open_user_with_address(_, _)).WillOnce(DoAll(SetArgPointee<0>(fakeBusPtr_), Return(1))); } template<> void AConnectionNameRequest::setUpBusOpenExpectation() { EXPECT_CALL(*sdBusIntfMock_, sd_bus_open_system_remote(_, _)).WillOnce(DoAll(SetArgPointee<0>(fakeBusPtr_), Return(1))); } template<> void AConnectionNameRequest::setUpBusOpenExpectation() { EXPECT_CALL(*sdBusIntfMock_, sd_bus_new(_)).WillOnce(DoAll(SetArgPointee<0>(fakeBusPtr_), Return(1))); // `sd_bus_start` for pseudo connection shall return an error value, remember this is a fake connection... EXPECT_CALL(*sdBusIntfMock_, sd_bus_start(fakeBusPtr_)).WillOnce(Return(-EINVAL)); } template std::unique_ptr AConnectionNameRequest<_BusTypeTag>::makeConnection() { return std::make_unique(std::unique_ptr>(sdBusIntfMock_), _BusTypeTag{}); } template<> std::unique_ptr AConnectionNameRequest::makeConnection() { return std::make_unique(std::unique_ptr>(sdBusIntfMock_), Connection::custom_session_bus, "custom session bus"); } template<> std::unique_ptr AConnectionNameRequest::makeConnection() { return std::make_unique(std::unique_ptr>(sdBusIntfMock_), Connection::remote_system_bus, "some host"); } typedef ::testing::Types< Connection::default_bus_t , Connection::system_bus_t , Connection::session_bus_t , Connection::custom_session_bus_t , Connection::remote_system_bus_t , Connection::pseudo_bus_t > BusTypeTags; TYPED_TEST_SUITE(AConnectionNameRequest, BusTypeTags); } TYPED_TEST(AConnectionNameRequest, DoesNotThrowOnSuccess) { 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); }