diff --git a/include/sdbus-c++/IConnection.h b/include/sdbus-c++/IConnection.h index 264e6f7..02fe253 100644 --- a/include/sdbus-c++/IConnection.h +++ b/include/sdbus-c++/IConnection.h @@ -34,6 +34,8 @@ #include #include +struct sd_event; + namespace sdbus { /********************************************//** @@ -127,7 +129,7 @@ namespace sdbus { virtual void releaseName(const std::string& name) = 0; /*! - * @brief Retrieve the unique name of a connection. E.g. ":1.xx" + * @brief Retrieves the unique name of a connection. E.g. ":1.xx" * * @throws sdbus::Error in case of failure */ @@ -305,6 +307,32 @@ namespace sdbus { */ virtual void addMatch(const std::string& match, message_handler callback, floating_slot_t) = 0; + /*! + * @brief Attaches the bus connection to an sd-event event loop + * + * @param[in] event sd-event event loop object + * @param[in] priority Specified priority + * + * @throws sdbus::Error in case of failure + * + * See `man sd_bus_attach_event'. + */ + virtual void attachSdEventLoop(sd_event *event, int priority = 0) = 0; + + /*! + * @brief Detaches the bus connection from an sd-event event loop + * + * @throws sdbus::Error in case of failure + */ + virtual void detachSdEventLoop() = 0; + + /*! + * @brief Gets current sd-event event loop for the bus connection + * + * @return Pointer to event loop object if attached, nullptr otherwise + */ + virtual sd_event *getSdEventLoop() = 0; + /*! * @copydoc IConnection::enterEventLoop() * diff --git a/src/Connection.cpp b/src/Connection.cpp index d235ed1..0ebc4ac 100644 --- a/src/Connection.cpp +++ b/src/Connection.cpp @@ -32,6 +32,7 @@ #include #include "ScopeGuard.h" #include +#include #include #include #include @@ -223,6 +224,102 @@ void Connection::addMatch(const std::string& match, message_handler callback, fl floatingMatchRules_.push_back(addMatch(match, std::move(callback))); } +void Connection::attachSdEventLoop(sd_event *event, int priority) +{ + // Get default event if no event is provided by the caller + if (event != nullptr) + event = sd_event_ref(event); + else + (void)sd_event_default(&event); + SDBUS_THROW_ERROR_IF(!event, "Invalid sd_event handle", EINVAL); + Slot sdEvent{event, [](void* event){ sd_event_unref((sd_event*)event); }}; + // TODO: auto sdEvent = createSdEventSlot(...); + + sd_event_source *timeEventSource{}; + auto r = sd_event_add_time(event, &timeEventSource, CLOCK_MONOTONIC, 0, 0, onSdTimerEvent, this); + SDBUS_THROW_ERROR_IF(r < 0, "Failed to add timer event", -r); + Slot sdTimeEventSource{timeEventSource, [](void* source){ sd_event_source_disable_unref((sd_event_source*)source); }}; + + r = sd_event_source_set_priority(timeEventSource, priority); // TODO maybe use custom EventSourceSlot with custom type? Then we can use slot.get() here + SDBUS_THROW_ERROR_IF(r < 0, "Failed to set time event priority", -r); + + r = sd_event_source_set_description(timeEventSource, "bus-time"); + SDBUS_THROW_ERROR_IF(r < 0, "Failed to set time event description", -r); + // TODO: auto sdTimeEventSource = createSdTimeEventSourceSlot(...); + + sd_event_source *ioEventSource{}; + auto pollData = getEventLoopPollData(); + r = sd_event_add_io(event, &ioEventSource, pollData.fd, 0, onSdIoEvent, this); + SDBUS_THROW_ERROR_IF(r < 0, "Failed to add io event", -r); + Slot sdIoEventSource{ioEventSource, [](void* source){ sd_event_source_disable_unref((sd_event_source*)source); }}; + + r = sd_event_source_set_prepare(ioEventSource, onSdEventPrepare); + SDBUS_THROW_ERROR_IF(r < 0, "Failed to set prepare callback for IO event", -r); + + r = sd_event_source_set_priority(ioEventSource, priority); + SDBUS_THROW_ERROR_IF(r < 0, "Failed to set priority for IO event", -r); + + r = sd_event_source_set_description(ioEventSource, "bus-input"); + SDBUS_THROW_ERROR_IF(r < 0, "Failed to set priority for IO event", -r); + // TODO: auto sdIoEventSource = createSdIoEventSourceSlot(...); + + sdEvent_ = std::make_unique(SdEvent{std::move(sdEvent), std::move(sdTimeEventSource), std::move(sdIoEventSource)}); +} + +void Connection::detachSdEventLoop() +{ + sdEvent_.reset(); +} + +sd_event *Connection::getSdEventLoop() +{ + return iface_->sd_bus_get_event(bus_.get()); +} + +int Connection::onSdTimerEvent(sd_event_source */*s*/, uint64_t /*usec*/, void *userdata) +{ + auto connection = static_cast(userdata); + assert(connection != nullptr); + + connection->processPendingRequest(); + + return 1; +} + +int Connection::onSdIoEvent(sd_event_source */*s*/, int /*fd*/, uint32_t /*revents*/, void *userdata) +{ + auto connection = static_cast(userdata); + assert(connection != nullptr); + + connection->processPendingRequest(); + + return 1; +} + +int Connection::onSdEventPrepare(sd_event_source */*s*/, void *userdata) +{ + auto connection = static_cast(userdata); + assert(connection != nullptr); + + auto sdbusPollData = connection->getEventLoopPollData(); + + // Set poll events to watch out for + auto* sdIoEventSource = static_cast(connection->sdEvent_->sdIoEventSource_.get()); + auto r = sd_event_source_set_io_events(sdIoEventSource, sdbusPollData.events); + SDBUS_THROW_ERROR_IF(r < 0, "Failed to set poll events for IO event source", -r); + + // Set current timeout to the time event source (may be zero if there are messages in the sd-bus queues to be processed) + auto* sdTimeEventSource = static_cast(connection->sdEvent_->sdTimeEventSource_.get()); + r = sd_event_source_set_time(sdTimeEventSource, sdbusPollData.timeout_usec); + SDBUS_THROW_ERROR_IF(r < 0, "Failed to set timeout for time event source", -r); + r = sd_event_source_set_enabled(sdTimeEventSource, SD_EVENT_ON); + SDBUS_THROW_ERROR_IF(r < 0, "Failed to enable time event source", -r); + + // TODO: Continue with integration tests + + return 1; +} + Slot Connection::addObjectVTable( const std::string& objectPath , const std::string& interfaceName , const sd_bus_vtable* vtable diff --git a/src/Connection.h b/src/Connection.h index 445c915..cc2833d 100644 --- a/src/Connection.h +++ b/src/Connection.h @@ -87,6 +87,10 @@ namespace sdbus::internal { [[nodiscard]] Slot addMatch(const std::string& match, message_handler callback) override; void addMatch(const std::string& match, message_handler callback, floating_slot_t) override; + void attachSdEventLoop(sd_event *event, int priority) override; + void detachSdEventLoop() override; + sd_event *getSdEventLoop() override; + const ISdBus& getSdBusInterface() const override; ISdBus& getSdBusInterface() override; @@ -141,10 +145,13 @@ namespace sdbus::internal { void clearEventLoopNotification(int fd) const; void notifyEventLoopNewTimeout() const override; - private: void joinWithEventLoop(); static std::vector to_strv(const std::vector& strings); + static int onSdTimerEvent(sd_event_source *s, uint64_t usec, void *userdata); + static int onSdIoEvent(sd_event_source *s, int fd, uint32_t revents, void *userdata); + static int onSdEventPrepare(sd_event_source *s, void *userdata); + struct EventFd { EventFd(); @@ -169,6 +176,15 @@ namespace sdbus::internal { EventFd eventFd_; std::atomic activeTimeout_{}; std::vector floatingMatchRules_; + + // sd-event integration + struct SdEvent + { + Slot sdEvent_; + Slot sdTimeEventSource_; + Slot sdIoEventSource_{}; + }; + std::unique_ptr sdEvent_; }; } diff --git a/src/ISdBus.h b/src/ISdBus.h index 5fdd352..4bdd099 100644 --- a/src/ISdBus.h +++ b/src/ISdBus.h @@ -101,6 +101,8 @@ namespace sdbus::internal { virtual int sd_bus_creds_get_egid(sd_bus_creds *c, gid_t *egid) = 0; virtual int sd_bus_creds_get_supplementary_gids(sd_bus_creds *c, const gid_t **gids) = 0; virtual int sd_bus_creds_get_selinux_context(sd_bus_creds *c, const char **label) = 0; + + virtual sd_event *sd_bus_get_event(sd_bus *bus) = 0; }; } diff --git a/src/SdBus.cpp b/src/SdBus.cpp index b523b79..8395bd1 100644 --- a/src/SdBus.cpp +++ b/src/SdBus.cpp @@ -401,4 +401,11 @@ int SdBus::sd_bus_creds_get_selinux_context(sd_bus_creds *c, const char **label) return ::sd_bus_creds_get_selinux_context(c, label); } +sd_event *SdBus::sd_bus_get_event(sd_bus *bus) +{ + std::lock_guard lock(sdbusMutex_); + + return ::sd_bus_get_event(bus); +} + } diff --git a/src/SdBus.h b/src/SdBus.h index 364d127..e6e79dc 100644 --- a/src/SdBus.h +++ b/src/SdBus.h @@ -94,6 +94,8 @@ public: virtual int sd_bus_creds_get_supplementary_gids(sd_bus_creds *c, const gid_t **gids) override; virtual int sd_bus_creds_get_selinux_context(sd_bus_creds *c, const char **label) override; + virtual sd_event *sd_bus_get_event(sd_bus *bus) override; + private: std::recursive_mutex sdbusMutex_; }; diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index ec42e55..955c0ae 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -109,7 +109,8 @@ target_link_libraries(sdbus-c++-unit-tests sdbus-c++-objlib GTest::gmock) add_executable(sdbus-c++-integration-tests ${INTEGRATIONTESTS_SRCS}) target_compile_definitions(sdbus-c++-integration-tests PRIVATE LIBSYSTEMD_VERSION=${LIBSYSTEMD_VERSION}) -target_link_libraries(sdbus-c++-integration-tests sdbus-c++ GTest::gmock) +# Systemd::Libsystemd is included because integration tests use sd-event. Otherwise sdbus-c++ encapsulates and hides libsystemd. +target_link_libraries(sdbus-c++-integration-tests sdbus-c++ Systemd::Libsystemd GTest::gmock) # Manual performance and stress tests option(ENABLE_PERF_TESTS "Build and install manual performance tests (default OFF)" OFF) diff --git a/tests/integrationtests/DBusAsyncMethodsTests.cpp b/tests/integrationtests/DBusAsyncMethodsTests.cpp index 29cb220..7553b69 100644 --- a/tests/integrationtests/DBusAsyncMethodsTests.cpp +++ b/tests/integrationtests/DBusAsyncMethodsTests.cpp @@ -49,20 +49,18 @@ using ::testing::SizeIs; using namespace std::chrono_literals; using namespace sdbus::test; -using SdbusTestObject = TestFixture; - /*-------------------------------------*/ /* -- TEST CASES -- */ /*-------------------------------------*/ -TEST_F(SdbusTestObject, ThrowsTimeoutErrorWhenClientSideAsyncMethodTimesOut) +TYPED_TEST(AsyncSdbusTestObject, ThrowsTimeoutErrorWhenClientSideAsyncMethodTimesOut) { std::chrono::time_point start; try { std::promise promise; auto future = promise.get_future(); - m_proxy->installDoOperationClientSideAsyncReplyHandler([&](uint32_t res, const sdbus::Error* err) + this->m_proxy->installDoOperationClientSideAsyncReplyHandler([&](uint32_t res, const sdbus::Error* err) { if (err == nullptr) promise.set_value(res); @@ -71,7 +69,7 @@ TEST_F(SdbusTestObject, ThrowsTimeoutErrorWhenClientSideAsyncMethodTimesOut) }); start = std::chrono::steady_clock::now(); - m_proxy->doOperationClientSideAsyncWithTimeout(1us, 1000); // The operation will take 1s, but the timeout is 500ms, so we should time out + this->m_proxy->doOperationClientSideAsyncWithTimeout(1us, 1000); // The operation will take 1s, but the timeout is 1us, so we should time out future.get(); FAIL() << "Expected sdbus::Error exception"; @@ -89,7 +87,7 @@ TEST_F(SdbusTestObject, ThrowsTimeoutErrorWhenClientSideAsyncMethodTimesOut) } } -TEST_F(SdbusTestObject, RunsServerSideAsynchoronousMethodAsynchronously) +TYPED_TEST(AsyncSdbusTestObject, RunsServerSideAsynchoronousMethodAsynchronously) { // Yeah, this is kinda timing-dependent test, but times should be safe... std::mutex mtx; @@ -114,7 +112,7 @@ TEST_F(SdbusTestObject, RunsServerSideAsynchoronousMethodAsynchronously) ASSERT_THAT(results, ElementsAre(500, 1000, 1500)); } -TEST_F(SdbusTestObject, HandlesCorrectlyABulkOfParallelServerSideAsyncMethods) +TYPED_TEST(AsyncSdbusTestObject, HandlesCorrectlyABulkOfParallelServerSideAsyncMethods) { std::atomic resultCount{}; std::atomic invoke{}; @@ -144,11 +142,11 @@ TEST_F(SdbusTestObject, HandlesCorrectlyABulkOfParallelServerSideAsyncMethods) ASSERT_THAT(resultCount, Eq(1500)); } -TEST_F(SdbusTestObject, InvokesMethodAsynchronouslyOnClientSide) +TYPED_TEST(AsyncSdbusTestObject, InvokesMethodAsynchronouslyOnClientSide) { std::promise promise; auto future = promise.get_future(); - m_proxy->installDoOperationClientSideAsyncReplyHandler([&](uint32_t res, const sdbus::Error* err) + this->m_proxy->installDoOperationClientSideAsyncReplyHandler([&](uint32_t res, const sdbus::Error* err) { if (err == nullptr) promise.set_value(res); @@ -156,77 +154,77 @@ TEST_F(SdbusTestObject, InvokesMethodAsynchronouslyOnClientSide) promise.set_exception(std::make_exception_ptr(*err)); }); - m_proxy->doOperationClientSideAsync(100); + this->m_proxy->doOperationClientSideAsync(100); ASSERT_THAT(future.get(), Eq(100)); } -TEST_F(SdbusTestObject, AnswersThatAsyncCallIsPendingIfItIsInProgress) +TYPED_TEST(AsyncSdbusTestObject, AnswersThatAsyncCallIsPendingIfItIsInProgress) { - m_proxy->installDoOperationClientSideAsyncReplyHandler([&](uint32_t /*res*/, const sdbus::Error* /*err*/){}); + this->m_proxy->installDoOperationClientSideAsyncReplyHandler([&](uint32_t /*res*/, const sdbus::Error* /*err*/){}); - auto call = m_proxy->doOperationClientSideAsync(100); + auto call = this->m_proxy->doOperationClientSideAsync(100); ASSERT_TRUE(call.isPending()); } -TEST_F(SdbusTestObject, CancelsPendingAsyncCallOnClientSide) +TYPED_TEST(AsyncSdbusTestObject, CancelsPendingAsyncCallOnClientSide) { std::promise promise; auto future = promise.get_future(); - m_proxy->installDoOperationClientSideAsyncReplyHandler([&](uint32_t /*res*/, const sdbus::Error* /*err*/){ promise.set_value(1); }); - auto call = m_proxy->doOperationClientSideAsync(100); + this->m_proxy->installDoOperationClientSideAsyncReplyHandler([&](uint32_t /*res*/, const sdbus::Error* /*err*/){ promise.set_value(1); }); + auto call = this->m_proxy->doOperationClientSideAsync(100); call.cancel(); ASSERT_THAT(future.wait_for(300ms), Eq(std::future_status::timeout)); } -TEST_F(SdbusTestObject, AnswersThatAsyncCallIsNotPendingAfterItHasBeenCancelled) +TYPED_TEST(AsyncSdbusTestObject, AnswersThatAsyncCallIsNotPendingAfterItHasBeenCancelled) { std::promise promise; auto future = promise.get_future(); - m_proxy->installDoOperationClientSideAsyncReplyHandler([&](uint32_t /*res*/, const sdbus::Error* /*err*/){ promise.set_value(1); }); - auto call = m_proxy->doOperationClientSideAsync(100); + this->m_proxy->installDoOperationClientSideAsyncReplyHandler([&](uint32_t /*res*/, const sdbus::Error* /*err*/){ promise.set_value(1); }); + auto call = this->m_proxy->doOperationClientSideAsync(100); call.cancel(); ASSERT_FALSE(call.isPending()); } -TEST_F(SdbusTestObject, AnswersThatAsyncCallIsNotPendingAfterItHasBeenCompleted) +TYPED_TEST(AsyncSdbusTestObject, AnswersThatAsyncCallIsNotPendingAfterItHasBeenCompleted) { std::promise promise; auto future = promise.get_future(); - m_proxy->installDoOperationClientSideAsyncReplyHandler([&](uint32_t /*res*/, const sdbus::Error* /*err*/){ promise.set_value(1); }); + this->m_proxy->installDoOperationClientSideAsyncReplyHandler([&](uint32_t /*res*/, const sdbus::Error* /*err*/){ promise.set_value(1); }); - auto call = m_proxy->doOperationClientSideAsync(0); + auto call = this->m_proxy->doOperationClientSideAsync(0); (void) future.get(); // Wait for the call to finish - ASSERT_TRUE(waitUntil([&call](){ return !call.isPending(); })); + ASSERT_TRUE(this->waitUntil([&call](){ return !call.isPending(); })); } -TEST_F(SdbusTestObject, AnswersThatDefaultConstructedAsyncCallIsNotPending) +TYPED_TEST(AsyncSdbusTestObject, AnswersThatDefaultConstructedAsyncCallIsNotPending) { sdbus::PendingAsyncCall call; ASSERT_FALSE(call.isPending()); } -TEST_F(SdbusTestObject, SupportsAsyncCallCopyAssignment) +TYPED_TEST(AsyncSdbusTestObject, SupportsAsyncCallCopyAssignment) { sdbus::PendingAsyncCall call; - call = m_proxy->doOperationClientSideAsync(100); + call = this->m_proxy->doOperationClientSideAsync(100); ASSERT_TRUE(call.isPending()); } -TEST_F(SdbusTestObject, InvokesErroneousMethodAsynchronouslyOnClientSide) +TYPED_TEST(AsyncSdbusTestObject, InvokesErroneousMethodAsynchronouslyOnClientSide) { std::promise promise; auto future = promise.get_future(); - m_proxy->installDoOperationClientSideAsyncReplyHandler([&](uint32_t res, const sdbus::Error* err) + this->m_proxy->installDoOperationClientSideAsyncReplyHandler([&](uint32_t res, const sdbus::Error* err) { if (err == nullptr) promise.set_value(res); @@ -234,7 +232,7 @@ TEST_F(SdbusTestObject, InvokesErroneousMethodAsynchronouslyOnClientSide) promise.set_exception(std::make_exception_ptr(*err)); }); - m_proxy->doErroneousOperationClientSideAsync(); + this->m_proxy->doErroneousOperationClientSideAsync(); ASSERT_THROW(future.get(), sdbus::Error); } diff --git a/tests/integrationtests/DBusGeneralTests.cpp b/tests/integrationtests/DBusGeneralTests.cpp index 1e09811..1f463ca 100644 --- a/tests/integrationtests/DBusGeneralTests.cpp +++ b/tests/integrationtests/DBusGeneralTests.cpp @@ -45,8 +45,6 @@ using ::testing::Eq; using namespace std::chrono_literals; using namespace sdbus::test; -using AConnection = TestFixture; - /*-------------------------------------*/ /* -- TEST CASES -- */ /*-------------------------------------*/ @@ -72,38 +70,38 @@ TEST(AnAdaptor, SupportsMoveSemantics) static_assert(std::is_move_assignable_v); } -TEST_F(AConnection, WillCallCallbackHandlerForIncomingMessageMatchingMatchRule) +TYPED_TEST(AConnection, WillCallCallbackHandlerForIncomingMessageMatchingMatchRule) { auto matchRule = "sender='" + BUS_NAME + "',path='" + OBJECT_PATH + "'"; std::atomic matchingMessageReceived{false}; - auto slot = s_proxyConnection->addMatch(matchRule, [&](sdbus::Message& msg) + auto slot = this->s_proxyConnection->addMatch(matchRule, [&](sdbus::Message& msg) { if(msg.getPath() == OBJECT_PATH) matchingMessageReceived = true; }); - m_adaptor->emitSimpleSignal(); + this->m_adaptor->emitSimpleSignal(); - ASSERT_TRUE(waitUntil(matchingMessageReceived)); + ASSERT_TRUE(this->waitUntil(matchingMessageReceived)); } -TEST_F(AConnection, WillUnsubscribeMatchRuleWhenClientDestroysTheAssociatedSlot) +TYPED_TEST(AConnection, WillUnsubscribeMatchRuleWhenClientDestroysTheAssociatedSlot) { auto matchRule = "sender='" + BUS_NAME + "',path='" + OBJECT_PATH + "'"; std::atomic matchingMessageReceived{false}; - auto slot = s_proxyConnection->addMatch(matchRule, [&](sdbus::Message& msg) + auto slot = this->s_proxyConnection->addMatch(matchRule, [&](sdbus::Message& msg) { if(msg.getPath() == OBJECT_PATH) matchingMessageReceived = true; }); slot.reset(); - m_adaptor->emitSimpleSignal(); + this->m_adaptor->emitSimpleSignal(); - ASSERT_FALSE(waitUntil(matchingMessageReceived, 2s)); + ASSERT_FALSE(this->waitUntil(matchingMessageReceived, 2s)); } -TEST_F(AConnection, CanAddFloatingMatchRule) +TYPED_TEST(AConnection, CanAddFloatingMatchRule) { auto matchRule = "sender='" + BUS_NAME + "',path='" + OBJECT_PATH + "'"; std::atomic matchingMessageReceived{false}; @@ -115,32 +113,32 @@ TEST_F(AConnection, CanAddFloatingMatchRule) matchingMessageReceived = true; }; con->addMatch(matchRule, std::move(callback), sdbus::floating_slot); - m_adaptor->emitSimpleSignal(); - [[maybe_unused]] auto gotMessage = waitUntil(matchingMessageReceived, 2s); + this->m_adaptor->emitSimpleSignal(); + [[maybe_unused]] auto gotMessage = this->waitUntil(matchingMessageReceived, 2s); assert(gotMessage); matchingMessageReceived = false; con.reset(); - m_adaptor->emitSimpleSignal(); + this->m_adaptor->emitSimpleSignal(); - ASSERT_FALSE(waitUntil(matchingMessageReceived, 2s)); + ASSERT_FALSE(this->waitUntil(matchingMessageReceived, 2s)); } -TEST_F(AConnection, WillNotPassToMatchCallbackMessagesThatDoNotMatchTheRule) +TYPED_TEST(AConnection, WillNotPassToMatchCallbackMessagesThatDoNotMatchTheRule) { auto matchRule = "type='signal',interface='" + INTERFACE_NAME + "',member='simpleSignal'"; std::atomic numberOfMatchingMessages{}; - auto slot = s_proxyConnection->addMatch(matchRule, [&](sdbus::Message& msg) + auto slot = this->s_proxyConnection->addMatch(matchRule, [&](sdbus::Message& msg) { if(msg.getMemberName() == "simpleSignal") numberOfMatchingMessages++; }); - auto adaptor2 = std::make_unique(*s_adaptorConnection, OBJECT_PATH_2); + auto adaptor2 = std::make_unique(*this->s_adaptorConnection, OBJECT_PATH_2); - m_adaptor->emitSignalWithMap({}); + this->m_adaptor->emitSignalWithMap({}); adaptor2->emitSimpleSignal(); - m_adaptor->emitSimpleSignal(); + this->m_adaptor->emitSimpleSignal(); - ASSERT_TRUE(waitUntil([&](){ return numberOfMatchingMessages == 2; })); - ASSERT_FALSE(waitUntil([&](){ return numberOfMatchingMessages > 2; }, 1s)); + ASSERT_TRUE(this->waitUntil([&](){ return numberOfMatchingMessages == 2; })); + ASSERT_FALSE(this->waitUntil([&](){ return numberOfMatchingMessages > 2; }, 1s)); } diff --git a/tests/integrationtests/DBusMethodsTests.cpp b/tests/integrationtests/DBusMethodsTests.cpp index 77bb317..0a40ba4 100644 --- a/tests/integrationtests/DBusMethodsTests.cpp +++ b/tests/integrationtests/DBusMethodsTests.cpp @@ -50,59 +50,57 @@ using ::testing::NotNull; using namespace std::chrono_literals; using namespace sdbus::test; -using SdbusTestObject = TestFixture; - /*-------------------------------------*/ /* -- TEST CASES -- */ /*-------------------------------------*/ -TEST_F(SdbusTestObject, CallsEmptyMethodSuccesfully) +TYPED_TEST(SdbusTestObject, CallsEmptyMethodSuccesfully) { - ASSERT_NO_THROW(m_proxy->noArgNoReturn()); + ASSERT_NO_THROW(this->m_proxy->noArgNoReturn()); } -TEST_F(SdbusTestObject, CallsMethodsWithBaseTypesSuccesfully) +TYPED_TEST(SdbusTestObject, CallsMethodsWithBaseTypesSuccesfully) { - auto resInt = m_proxy->getInt(); + auto resInt = this->m_proxy->getInt(); ASSERT_THAT(resInt, Eq(INT32_VALUE)); - auto multiplyRes = m_proxy->multiply(INT64_VALUE, DOUBLE_VALUE); + auto multiplyRes = this->m_proxy->multiply(INT64_VALUE, DOUBLE_VALUE); ASSERT_THAT(multiplyRes, Eq(INT64_VALUE * DOUBLE_VALUE)); } -TEST_F(SdbusTestObject, CallsMethodsWithTuplesSuccesfully) +TYPED_TEST(SdbusTestObject, CallsMethodsWithTuplesSuccesfully) { - auto resTuple = m_proxy->getTuple(); + auto resTuple = this->m_proxy->getTuple(); ASSERT_THAT(std::get<0>(resTuple), Eq(UINT32_VALUE)); ASSERT_THAT(std::get<1>(resTuple), Eq(STRING_VALUE)); } -TEST_F(SdbusTestObject, CallsMethodsWithStructSuccesfully) +TYPED_TEST(SdbusTestObject, CallsMethodsWithStructSuccesfully) { sdbus::Struct> a{}; - auto vectorRes = m_proxy->getInts16FromStruct(a); + auto vectorRes = this->m_proxy->getInts16FromStruct(a); ASSERT_THAT(vectorRes, Eq(std::vector{0})); // because second item is by default initialized to 0 sdbus::Struct> b{ UINT8_VALUE, INT16_VALUE, DOUBLE_VALUE, STRING_VALUE, {INT16_VALUE, -INT16_VALUE} }; - vectorRes = m_proxy->getInts16FromStruct(b); + vectorRes = this->m_proxy->getInts16FromStruct(b); ASSERT_THAT(vectorRes, Eq(std::vector{INT16_VALUE, INT16_VALUE, -INT16_VALUE})); } -TEST_F(SdbusTestObject, CallsMethodWithVariantSuccesfully) +TYPED_TEST(SdbusTestObject, CallsMethodWithVariantSuccesfully) { sdbus::Variant v{DOUBLE_VALUE}; - auto variantRes = m_proxy->processVariant(v); + sdbus::Variant variantRes = this->m_proxy->processVariant(v); ASSERT_THAT(variantRes.get(), Eq(static_cast(DOUBLE_VALUE))); } -TEST_F(SdbusTestObject, CallsMethodWithStructVariantsAndGetMapSuccesfully) +TYPED_TEST(SdbusTestObject, CallsMethodWithStructVariantsAndGetMapSuccesfully) { std::vector x{-2, 0, 2}; sdbus::Struct y{false, true}; - auto mapOfVariants = m_proxy->getMapOfVariants(x, y); + std::map mapOfVariants = this->m_proxy->getMapOfVariants(x, y); decltype(mapOfVariants) res{{-2, false}, {0, false}, {2, true}}; ASSERT_THAT(mapOfVariants[-2].get(), Eq(res[-2].get())); @@ -110,69 +108,69 @@ TEST_F(SdbusTestObject, CallsMethodWithStructVariantsAndGetMapSuccesfully) ASSERT_THAT(mapOfVariants[2].get(), Eq(res[2].get())); } -TEST_F(SdbusTestObject, CallsMethodWithStructInStructSuccesfully) +TYPED_TEST(SdbusTestObject, CallsMethodWithStructInStructSuccesfully) { - auto val = m_proxy->getStructInStruct(); - ASSERT_THAT(val.get<0>(), Eq(STRING_VALUE)); + auto val = this->m_proxy->getStructInStruct(); + ASSERT_THAT(val.template get<0>(), Eq(STRING_VALUE)); ASSERT_THAT(std::get<0>(std::get<1>(val))[INT32_VALUE], Eq(INT32_VALUE)); } -TEST_F(SdbusTestObject, CallsMethodWithTwoStructsSuccesfully) +TYPED_TEST(SdbusTestObject, CallsMethodWithTwoStructsSuccesfully) { - auto val = m_proxy->sumStructItems({1, 2}, {3, 4}); + auto val = this->m_proxy->sumStructItems({1, 2}, {3, 4}); ASSERT_THAT(val, Eq(1 + 2 + 3 + 4)); } -TEST_F(SdbusTestObject, CallsMethodWithTwoVectorsSuccesfully) +TYPED_TEST(SdbusTestObject, CallsMethodWithTwoVectorsSuccesfully) { - auto val = m_proxy->sumVectorItems({1, 7}, {2, 3}); + auto val = this->m_proxy->sumVectorItems({1, 7}, {2, 3}); ASSERT_THAT(val, Eq(1 + 7 + 2 + 3)); } -TEST_F(SdbusTestObject, CallsMethodWithSignatureSuccesfully) +TYPED_TEST(SdbusTestObject, CallsMethodWithSignatureSuccesfully) { - auto resSignature = m_proxy->getSignature(); + auto resSignature = this->m_proxy->getSignature(); ASSERT_THAT(resSignature, Eq(SIGNATURE_VALUE)); } -TEST_F(SdbusTestObject, CallsMethodWithObjectPathSuccesfully) +TYPED_TEST(SdbusTestObject, CallsMethodWithObjectPathSuccesfully) { - auto resObjectPath = m_proxy->getObjPath(); + auto resObjectPath = this->m_proxy->getObjPath(); ASSERT_THAT(resObjectPath, Eq(OBJECT_PATH_VALUE)); } -TEST_F(SdbusTestObject, CallsMethodWithUnixFdSuccesfully) +TYPED_TEST(SdbusTestObject, CallsMethodWithUnixFdSuccesfully) { - auto resUnixFd = m_proxy->getUnixFd(); + auto resUnixFd = this->m_proxy->getUnixFd(); ASSERT_THAT(resUnixFd.get(), Gt(UNIX_FD_VALUE)); } -TEST_F(SdbusTestObject, CallsMethodWithComplexTypeSuccesfully) +TYPED_TEST(SdbusTestObject, CallsMethodWithComplexTypeSuccesfully) { - auto resComplex = m_proxy->getComplex(); + auto resComplex = this->m_proxy->getComplex(); ASSERT_THAT(resComplex.count(0), Eq(1)); } -TEST_F(SdbusTestObject, CallsMultiplyMethodWithNoReplyFlag) +TYPED_TEST(SdbusTestObject, CallsMultiplyMethodWithNoReplyFlag) { - m_proxy->multiplyWithNoReply(INT64_VALUE, DOUBLE_VALUE); + this->m_proxy->multiplyWithNoReply(INT64_VALUE, DOUBLE_VALUE); - ASSERT_TRUE(waitUntil(m_adaptor->m_wasMultiplyCalled)); - ASSERT_THAT(m_adaptor->m_multiplyResult, Eq(INT64_VALUE * DOUBLE_VALUE)); + ASSERT_TRUE(this->waitUntil(this->m_adaptor->m_wasMultiplyCalled)); + ASSERT_THAT(this->m_adaptor->m_multiplyResult, Eq(INT64_VALUE * DOUBLE_VALUE)); } -TEST_F(SdbusTestObject, CallsMethodWithCustomTimeoutSuccessfully) +TYPED_TEST(SdbusTestObject, CallsMethodWithCustomTimeoutSuccessfully) { - auto res = m_proxy->doOperationWithTimeout(500ms, 20); // The operation will take 20ms, but the timeout is 500ms, so we are fine + auto res = this->m_proxy->doOperationWithTimeout(500ms, 20); // The operation will take 20ms, but the timeout is 500ms, so we are fine ASSERT_THAT(res, Eq(20)); } -TEST_F(SdbusTestObject, ThrowsTimeoutErrorWhenMethodTimesOut) +TYPED_TEST(SdbusTestObject, ThrowsTimeoutErrorWhenMethodTimesOut) { auto start = std::chrono::steady_clock::now(); try { - m_proxy->doOperationWithTimeout(1us, 1000); // The operation will take 1s, but the timeout is 1us, so we should time out + this->m_proxy->doOperationWithTimeout(1us, 1000); // The operation will take 1s, but the timeout is 1us, so we should time out FAIL() << "Expected sdbus::Error exception"; } catch (const sdbus::Error& e) @@ -188,11 +186,11 @@ TEST_F(SdbusTestObject, ThrowsTimeoutErrorWhenMethodTimesOut) } } -TEST_F(SdbusTestObject, CallsMethodThatThrowsError) +TYPED_TEST(SdbusTestObject, CallsMethodThatThrowsError) { try { - m_proxy->throwError(); + this->m_proxy->throwError(); FAIL() << "Expected sdbus::Error exception"; } catch (const sdbus::Error& e) @@ -206,74 +204,74 @@ TEST_F(SdbusTestObject, CallsMethodThatThrowsError) } } -TEST_F(SdbusTestObject, CallsErrorThrowingMethodWithDontExpectReplySet) +TYPED_TEST(SdbusTestObject, CallsErrorThrowingMethodWithDontExpectReplySet) { - ASSERT_NO_THROW(m_proxy->throwErrorWithNoReply()); + ASSERT_NO_THROW(this->m_proxy->throwErrorWithNoReply()); - ASSERT_TRUE(waitUntil(m_adaptor->m_wasThrowErrorCalled)); + ASSERT_TRUE(this->waitUntil(this->m_adaptor->m_wasThrowErrorCalled)); } -TEST_F(SdbusTestObject, FailsCallingNonexistentMethod) +TYPED_TEST(SdbusTestObject, FailsCallingNonexistentMethod) { - ASSERT_THROW(m_proxy->callNonexistentMethod(), sdbus::Error); + ASSERT_THROW(this->m_proxy->callNonexistentMethod(), sdbus::Error); } -TEST_F(SdbusTestObject, FailsCallingMethodOnNonexistentInterface) +TYPED_TEST(SdbusTestObject, FailsCallingMethodOnNonexistentInterface) { - ASSERT_THROW(m_proxy->callMethodOnNonexistentInterface(), sdbus::Error); + ASSERT_THROW(this->m_proxy->callMethodOnNonexistentInterface(), sdbus::Error); } -TEST_F(SdbusTestObject, FailsCallingMethodOnNonexistentDestination) +TYPED_TEST(SdbusTestObject, FailsCallingMethodOnNonexistentDestination) { TestProxy proxy("sdbuscpp.destination.that.does.not.exist", OBJECT_PATH); ASSERT_THROW(proxy.getInt(), sdbus::Error); } -TEST_F(SdbusTestObject, FailsCallingMethodOnNonexistentObject) +TYPED_TEST(SdbusTestObject, FailsCallingMethodOnNonexistentObject) { TestProxy proxy(BUS_NAME, "/sdbuscpp/path/that/does/not/exist"); ASSERT_THROW(proxy.getInt(), sdbus::Error); } -TEST_F(SdbusTestObject, CanReceiveSignalWhileMakingMethodCall) +TYPED_TEST(SdbusTestObject, CanReceiveSignalWhileMakingMethodCall) { - m_proxy->emitTwoSimpleSignals(); + this->m_proxy->emitTwoSimpleSignals(); - ASSERT_TRUE(waitUntil(m_proxy->m_gotSimpleSignal)); - ASSERT_TRUE(waitUntil(m_proxy->m_gotSignalWithMap)); + ASSERT_TRUE(this->waitUntil(this->m_proxy->m_gotSimpleSignal)); + ASSERT_TRUE(this->waitUntil(this->m_proxy->m_gotSignalWithMap)); } -TEST_F(SdbusTestObject, CanAccessAssociatedMethodCallMessageInMethodCallHandler) +TYPED_TEST(SdbusTestObject, CanAccessAssociatedMethodCallMessageInMethodCallHandler) { - m_proxy->doOperation(10); // This will save pointer to method call message on server side + this->m_proxy->doOperation(10); // This will save pointer to method call message on server side - ASSERT_THAT(m_adaptor->m_methodCallMsg, NotNull()); - ASSERT_THAT(m_adaptor->m_methodCallMemberName, Eq("doOperation")); + ASSERT_THAT(this->m_adaptor->m_methodCallMsg, NotNull()); + ASSERT_THAT(this->m_adaptor->m_methodCallMemberName, Eq("doOperation")); } -TEST_F(SdbusTestObject, CanAccessAssociatedMethodCallMessageInAsyncMethodCallHandler) +TYPED_TEST(SdbusTestObject, CanAccessAssociatedMethodCallMessageInAsyncMethodCallHandler) { - m_proxy->doOperationAsync(10); // This will save pointer to method call message on server side + this->m_proxy->doOperationAsync(10); // This will save pointer to method call message on server side - ASSERT_THAT(m_adaptor->m_methodCallMsg, NotNull()); - ASSERT_THAT(m_adaptor->m_methodCallMemberName, Eq("doOperationAsync")); + ASSERT_THAT(this->m_adaptor->m_methodCallMsg, NotNull()); + ASSERT_THAT(this->m_adaptor->m_methodCallMemberName, Eq("doOperationAsync")); } #if LIBSYSTEMD_VERSION>=240 -TEST_F(SdbusTestObject, CanSetGeneralMethodTimeoutWithLibsystemdVersionGreaterThan239) +TYPED_TEST(SdbusTestObject, CanSetGeneralMethodTimeoutWithLibsystemdVersionGreaterThan239) { - s_adaptorConnection->setMethodCallTimeout(5000000); - ASSERT_THAT(s_adaptorConnection->getMethodCallTimeout(), Eq(5000000)); + this->s_adaptorConnection->setMethodCallTimeout(5000000); + ASSERT_THAT(this->s_adaptorConnection->getMethodCallTimeout(), Eq(5000000)); } #else -TEST_F(SdbusTestObject, CannotSetGeneralMethodTimeoutWithLibsystemdVersionLessThan240) +TYPED_TEST(SdbusTestObject, CannotSetGeneralMethodTimeoutWithLibsystemdVersionLessThan240) { - ASSERT_THROW(s_adaptorConnection->setMethodCallTimeout(5000000), sdbus::Error); - ASSERT_THROW(s_adaptorConnection->getMethodCallTimeout(), sdbus::Error); + ASSERT_THROW(this->s_adaptorConnection->setMethodCallTimeout(5000000), sdbus::Error); + ASSERT_THROW(this->s_adaptorConnection->getMethodCallTimeout(), sdbus::Error); } #endif -TEST_F(SdbusTestObject, CanCallMethodSynchronouslyWithoutAnEventLoopThread) +TYPED_TEST(SdbusTestObject, CanCallMethodSynchronouslyWithoutAnEventLoopThread) { auto proxy = std::make_unique(BUS_NAME, OBJECT_PATH, sdbus::dont_run_event_loop_thread); diff --git a/tests/integrationtests/DBusPropertiesTests.cpp b/tests/integrationtests/DBusPropertiesTests.cpp index 12fe326..fa90215 100644 --- a/tests/integrationtests/DBusPropertiesTests.cpp +++ b/tests/integrationtests/DBusPropertiesTests.cpp @@ -51,35 +51,33 @@ using ::testing::IsEmpty; using namespace std::chrono_literals; using namespace sdbus::test; -using SdbusTestObject = TestFixture; - /*-------------------------------------*/ /* -- TEST CASES -- */ /*-------------------------------------*/ -TEST_F(SdbusTestObject, ReadsReadOnlyPropertySuccesfully) +TYPED_TEST(SdbusTestObject, ReadsReadOnlyPropertySuccesfully) { - ASSERT_THAT(m_proxy->state(), Eq(DEFAULT_STATE_VALUE)); + ASSERT_THAT(this->m_proxy->state(), Eq(DEFAULT_STATE_VALUE)); } -TEST_F(SdbusTestObject, FailsWritingToReadOnlyProperty) +TYPED_TEST(SdbusTestObject, FailsWritingToReadOnlyProperty) { - ASSERT_THROW(m_proxy->setStateProperty("new_value"), sdbus::Error); + ASSERT_THROW(this->m_proxy->setStateProperty("new_value"), sdbus::Error); } -TEST_F(SdbusTestObject, WritesAndReadsReadWritePropertySuccesfully) +TYPED_TEST(SdbusTestObject, WritesAndReadsReadWritePropertySuccesfully) { uint32_t newActionValue = 5678; - m_proxy->action(newActionValue); + this->m_proxy->action(newActionValue); - ASSERT_THAT(m_proxy->action(), Eq(newActionValue)); + ASSERT_THAT(this->m_proxy->action(), Eq(newActionValue)); } -TEST_F(SdbusTestObject, CanAccessAssociatedPropertySetMessageInPropertySetHandler) +TYPED_TEST(SdbusTestObject, CanAccessAssociatedPropertySetMessageInPropertySetHandler) { - m_proxy->blocking(true); // This will save pointer to property get message on server side + this->m_proxy->blocking(true); // This will save pointer to property get message on server side - ASSERT_THAT(m_adaptor->m_propertySetMsg, NotNull()); - ASSERT_THAT(m_adaptor->m_propertySetSender, Not(IsEmpty())); + ASSERT_THAT(this->m_adaptor->m_propertySetMsg, NotNull()); + ASSERT_THAT(this->m_adaptor->m_propertySetSender, Not(IsEmpty())); } diff --git a/tests/integrationtests/DBusSignalsTests.cpp b/tests/integrationtests/DBusSignalsTests.cpp index 5ac40d8..385bd1c 100644 --- a/tests/integrationtests/DBusSignalsTests.cpp +++ b/tests/integrationtests/DBusSignalsTests.cpp @@ -44,32 +44,30 @@ using ::testing::NotNull; using namespace std::chrono_literals; using namespace sdbus::test; -using SdbusTestObject = TestFixture; - /*-------------------------------------*/ /* -- TEST CASES -- */ /*-------------------------------------*/ -TEST_F(SdbusTestObject, EmitsSimpleSignalSuccesfully) +TYPED_TEST(SdbusTestObject, EmitsSimpleSignalSuccesfully) { - m_adaptor->emitSimpleSignal(); + this->m_adaptor->emitSimpleSignal(); - ASSERT_TRUE(waitUntil(m_proxy->m_gotSimpleSignal)); + ASSERT_TRUE(this->waitUntil(this->m_proxy->m_gotSimpleSignal)); } -TEST_F(SdbusTestObject, EmitsSimpleSignalToMultipleProxiesSuccesfully) +TYPED_TEST(SdbusTestObject, EmitsSimpleSignalToMultipleProxiesSuccesfully) { - auto proxy1 = std::make_unique(*s_adaptorConnection, BUS_NAME, OBJECT_PATH); - auto proxy2 = std::make_unique(*s_adaptorConnection, BUS_NAME, OBJECT_PATH); + auto proxy1 = std::make_unique(*this->s_adaptorConnection, BUS_NAME, OBJECT_PATH); + auto proxy2 = std::make_unique(*this->s_adaptorConnection, BUS_NAME, OBJECT_PATH); - m_adaptor->emitSimpleSignal(); + this->m_adaptor->emitSimpleSignal(); - ASSERT_TRUE(waitUntil(m_proxy->m_gotSimpleSignal)); - ASSERT_TRUE(waitUntil(proxy1->m_gotSimpleSignal)); - ASSERT_TRUE(waitUntil(proxy2->m_gotSimpleSignal)); + ASSERT_TRUE(this->waitUntil(this->m_proxy->m_gotSimpleSignal)); + ASSERT_TRUE(this->waitUntil(proxy1->m_gotSimpleSignal)); + ASSERT_TRUE(this->waitUntil(proxy2->m_gotSimpleSignal)); } -TEST_F(SdbusTestObject, ProxyDoesNotReceiveSignalFromOtherBusName) +TYPED_TEST(SdbusTestObject, ProxyDoesNotReceiveSignalFromOtherBusName) { auto otherBusName = BUS_NAME + "2"; auto connection2 = sdbus::createConnection(otherBusName); @@ -77,93 +75,93 @@ TEST_F(SdbusTestObject, ProxyDoesNotReceiveSignalFromOtherBusName) adaptor2->emitSimpleSignal(); - ASSERT_FALSE(waitUntil(m_proxy->m_gotSimpleSignal, 2s)); + ASSERT_FALSE(this->waitUntil(this->m_proxy->m_gotSimpleSignal, 2s)); } -TEST_F(SdbusTestObject, EmitsSignalWithMapSuccesfully) +TYPED_TEST(SdbusTestObject, EmitsSignalWithMapSuccesfully) { - m_adaptor->emitSignalWithMap({{0, "zero"}, {1, "one"}}); + this->m_adaptor->emitSignalWithMap({{0, "zero"}, {1, "one"}}); - ASSERT_TRUE(waitUntil(m_proxy->m_gotSignalWithMap)); - ASSERT_THAT(m_proxy->m_mapFromSignal[0], Eq("zero")); - ASSERT_THAT(m_proxy->m_mapFromSignal[1], Eq("one")); + ASSERT_TRUE(this->waitUntil(this->m_proxy->m_gotSignalWithMap)); + ASSERT_THAT(this->m_proxy->m_mapFromSignal[0], Eq("zero")); + ASSERT_THAT(this->m_proxy->m_mapFromSignal[1], Eq("one")); } -TEST_F(SdbusTestObject, EmitsSignalWithLargeMapSuccesfully) +TYPED_TEST(SdbusTestObject, EmitsSignalWithLargeMapSuccesfully) { std::map largeMap; for (int32_t i = 0; i < 20'000; ++i) largeMap.emplace(i, "This is string nr. " + std::to_string(i+1)); - m_adaptor->emitSignalWithMap(largeMap); + this->m_adaptor->emitSignalWithMap(largeMap); - ASSERT_TRUE(waitUntil(m_proxy->m_gotSignalWithMap)); - ASSERT_THAT(m_proxy->m_mapFromSignal[0], Eq("This is string nr. 1")); - ASSERT_THAT(m_proxy->m_mapFromSignal[1], Eq("This is string nr. 2")); + ASSERT_TRUE(this->waitUntil(this->m_proxy->m_gotSignalWithMap)); + ASSERT_THAT(this->m_proxy->m_mapFromSignal[0], Eq("This is string nr. 1")); + ASSERT_THAT(this->m_proxy->m_mapFromSignal[1], Eq("This is string nr. 2")); } -TEST_F(SdbusTestObject, EmitsSignalWithVariantSuccesfully) +TYPED_TEST(SdbusTestObject, EmitsSignalWithVariantSuccesfully) { double d = 3.14; - m_adaptor->emitSignalWithVariant(d); + this->m_adaptor->emitSignalWithVariant(d); - ASSERT_TRUE(waitUntil(m_proxy->m_gotSignalWithVariant)); - ASSERT_THAT(m_proxy->m_variantFromSignal, DoubleEq(d)); + ASSERT_TRUE(this->waitUntil(this->m_proxy->m_gotSignalWithVariant)); + ASSERT_THAT(this->m_proxy->m_variantFromSignal, DoubleEq(d)); } -TEST_F(SdbusTestObject, EmitsSignalWithoutRegistrationSuccesfully) +TYPED_TEST(SdbusTestObject, EmitsSignalWithoutRegistrationSuccesfully) { - m_adaptor->emitSignalWithoutRegistration({"platform", {"av"}}); + this->m_adaptor->emitSignalWithoutRegistration({"platform", {"av"}}); - ASSERT_TRUE(waitUntil(m_proxy->m_gotSignalWithSignature)); - ASSERT_THAT(m_proxy->m_signatureFromSignal["platform"], Eq("av")); + ASSERT_TRUE(this->waitUntil(this->m_proxy->m_gotSignalWithSignature)); + ASSERT_THAT(this->m_proxy->m_signatureFromSignal["platform"], Eq("av")); } -TEST_F(SdbusTestObject, CanAccessAssociatedSignalMessageInSignalHandler) +TYPED_TEST(SdbusTestObject, CanAccessAssociatedSignalMessageInSignalHandler) { - m_adaptor->emitSimpleSignal(); + this->m_adaptor->emitSimpleSignal(); - waitUntil(m_proxy->m_gotSimpleSignal); + this->waitUntil(this->m_proxy->m_gotSimpleSignal); - ASSERT_THAT(m_proxy->m_signalMsg, NotNull()); - ASSERT_THAT(m_proxy->m_signalMemberName, Eq("simpleSignal")); + ASSERT_THAT(this->m_proxy->m_signalMsg, NotNull()); + ASSERT_THAT(this->m_proxy->m_signalMemberName, Eq("simpleSignal")); } -TEST_F(SdbusTestObject, UnregistersSignalHandler) +TYPED_TEST(SdbusTestObject, UnregistersSignalHandler) { - ASSERT_NO_THROW(m_proxy->unregisterSimpleSignalHandler()); + ASSERT_NO_THROW(this->m_proxy->unregisterSimpleSignalHandler()); - m_adaptor->emitSimpleSignal(); + this->m_adaptor->emitSimpleSignal(); - ASSERT_FALSE(waitUntil(m_proxy->m_gotSimpleSignal, 2s)); + ASSERT_FALSE(this->waitUntil(this->m_proxy->m_gotSimpleSignal, 2s)); } -TEST_F(SdbusTestObject, UnregistersSignalHandlerForSomeProxies) +TYPED_TEST(SdbusTestObject, UnregistersSignalHandlerForSomeProxies) { - auto proxy1 = std::make_unique(*s_adaptorConnection, BUS_NAME, OBJECT_PATH); - auto proxy2 = std::make_unique(*s_adaptorConnection, BUS_NAME, OBJECT_PATH); + auto proxy1 = std::make_unique(*this->s_adaptorConnection, BUS_NAME, OBJECT_PATH); + auto proxy2 = std::make_unique(*this->s_adaptorConnection, BUS_NAME, OBJECT_PATH); - ASSERT_NO_THROW(m_proxy->unregisterSimpleSignalHandler()); + ASSERT_NO_THROW(this->m_proxy->unregisterSimpleSignalHandler()); - m_adaptor->emitSimpleSignal(); + this->m_adaptor->emitSimpleSignal(); - ASSERT_TRUE(waitUntil(proxy1->m_gotSimpleSignal)); - ASSERT_TRUE(waitUntil(proxy2->m_gotSimpleSignal)); - ASSERT_FALSE(waitUntil(m_proxy->m_gotSimpleSignal, 2s)); + ASSERT_TRUE(this->waitUntil(proxy1->m_gotSimpleSignal)); + ASSERT_TRUE(this->waitUntil(proxy2->m_gotSimpleSignal)); + ASSERT_FALSE(this->waitUntil(this->m_proxy->m_gotSimpleSignal, 2s)); } -TEST_F(SdbusTestObject, ReRegistersSignalHandler) +TYPED_TEST(SdbusTestObject, ReRegistersSignalHandler) { // unregister simple-signal handler - ASSERT_NO_THROW(m_proxy->unregisterSimpleSignalHandler()); + ASSERT_NO_THROW(this->m_proxy->unregisterSimpleSignalHandler()); - m_adaptor->emitSimpleSignal(); + this->m_adaptor->emitSimpleSignal(); - ASSERT_FALSE(waitUntil(m_proxy->m_gotSimpleSignal, 2s)); + ASSERT_FALSE(this->waitUntil(this->m_proxy->m_gotSimpleSignal, 2s)); // re-register simple-signal handler - ASSERT_NO_THROW(m_proxy->reRegisterSimpleSignalHandler()); + ASSERT_NO_THROW(this->m_proxy->reRegisterSimpleSignalHandler()); - m_adaptor->emitSimpleSignal(); + this->m_adaptor->emitSimpleSignal(); - ASSERT_TRUE(waitUntil(m_proxy->m_gotSimpleSignal)); + ASSERT_TRUE(this->waitUntil(this->m_proxy->m_gotSimpleSignal)); } diff --git a/tests/integrationtests/DBusStandardInterfacesTests.cpp b/tests/integrationtests/DBusStandardInterfacesTests.cpp index 6381587..138c818 100644 --- a/tests/integrationtests/DBusStandardInterfacesTests.cpp +++ b/tests/integrationtests/DBusStandardInterfacesTests.cpp @@ -48,18 +48,16 @@ using ::testing::SizeIs; using namespace std::chrono_literals; using namespace sdbus::test; -using SdbusTestObject = TestFixture; - /*-------------------------------------*/ /* -- TEST CASES -- */ /*-------------------------------------*/ -TEST_F(SdbusTestObject, PingsViaPeerInterface) +TYPED_TEST(SdbusTestObject, PingsViaPeerInterface) { - ASSERT_NO_THROW(m_proxy->Ping()); + ASSERT_NO_THROW(this->m_proxy->Ping()); } -TEST_F(SdbusTestObject, AnswersMachineUuidViaPeerInterface) +TYPED_TEST(SdbusTestObject, AnswersMachineUuidViaPeerInterface) { // If /etc/machine-id does not exist in your system (which is very likely because you have // a non-systemd Linux), org.freedesktop.DBus.Peer.GetMachineId() will not work. To solve @@ -68,45 +66,45 @@ TEST_F(SdbusTestObject, AnswersMachineUuidViaPeerInterface) if (::access("/etc/machine-id", F_OK) == -1) GTEST_SKIP() << "/etc/machine-id file does not exist, GetMachineId() will not work"; - ASSERT_NO_THROW(m_proxy->GetMachineId()); + ASSERT_NO_THROW(this->m_proxy->GetMachineId()); } // TODO: Adjust expected xml and uncomment this test -//TEST_F(SdbusTestObject, AnswersXmlApiDescriptionViaIntrospectableInterface) +//TYPED_TEST(SdbusTestObject, AnswersXmlApiDescriptionViaIntrospectableInterface) //{ -// ASSERT_THAT(m_proxy->Introspect(), Eq(m_adaptor->getExpectedXmlApiDescription())); +// ASSERT_THAT(this->m_proxy->Introspect(), Eq(this->m_adaptor->getExpectedXmlApiDescription())); //} -TEST_F(SdbusTestObject, GetsPropertyViaPropertiesInterface) +TYPED_TEST(SdbusTestObject, GetsPropertyViaPropertiesInterface) { - ASSERT_THAT(m_proxy->Get(INTERFACE_NAME, "state").get(), Eq(DEFAULT_STATE_VALUE)); + ASSERT_THAT(this->m_proxy->Get(INTERFACE_NAME, "state").template get(), Eq(DEFAULT_STATE_VALUE)); } -TEST_F(SdbusTestObject, SetsPropertyViaPropertiesInterface) +TYPED_TEST(SdbusTestObject, SetsPropertyViaPropertiesInterface) { uint32_t newActionValue = 2345; - m_proxy->Set(INTERFACE_NAME, "action", newActionValue); + this->m_proxy->Set(INTERFACE_NAME, "action", newActionValue); - ASSERT_THAT(m_proxy->action(), Eq(newActionValue)); + ASSERT_THAT(this->m_proxy->action(), Eq(newActionValue)); } -TEST_F(SdbusTestObject, GetsAllPropertiesViaPropertiesInterface) +TYPED_TEST(SdbusTestObject, GetsAllPropertiesViaPropertiesInterface) { - const auto properties = m_proxy->GetAll(INTERFACE_NAME); + const auto properties = this->m_proxy->GetAll(INTERFACE_NAME); ASSERT_THAT(properties, SizeIs(3)); - EXPECT_THAT(properties.at("state").get(), Eq(DEFAULT_STATE_VALUE)); - EXPECT_THAT(properties.at("action").get(), Eq(DEFAULT_ACTION_VALUE)); - EXPECT_THAT(properties.at("blocking").get(), Eq(DEFAULT_BLOCKING_VALUE)); + EXPECT_THAT(properties.at("state").template get(), Eq(DEFAULT_STATE_VALUE)); + EXPECT_THAT(properties.at("action").template get(), Eq(DEFAULT_ACTION_VALUE)); + EXPECT_THAT(properties.at("blocking").template get(), Eq(DEFAULT_BLOCKING_VALUE)); } -TEST_F(SdbusTestObject, EmitsPropertyChangedSignalForSelectedProperties) +TYPED_TEST(SdbusTestObject, EmitsPropertyChangedSignalForSelectedProperties) { std::atomic signalReceived{false}; - m_proxy->m_onPropertiesChangedHandler = [&signalReceived]( const std::string& interfaceName - , const std::map& changedProperties - , const std::vector& /*invalidatedProperties*/ ) + this->m_proxy->m_onPropertiesChangedHandler = [&signalReceived]( const std::string& interfaceName + , const std::map& changedProperties + , const std::vector& /*invalidatedProperties*/ ) { EXPECT_THAT(interfaceName, Eq(INTERFACE_NAME)); EXPECT_THAT(changedProperties, SizeIs(1)); @@ -114,19 +112,19 @@ TEST_F(SdbusTestObject, EmitsPropertyChangedSignalForSelectedProperties) signalReceived = true; }; - m_proxy->blocking(!DEFAULT_BLOCKING_VALUE); - m_proxy->action(DEFAULT_ACTION_VALUE*2); - m_adaptor->emitPropertiesChangedSignal(INTERFACE_NAME, {"blocking"}); + this->m_proxy->blocking(!DEFAULT_BLOCKING_VALUE); + this->m_proxy->action(DEFAULT_ACTION_VALUE*2); + this->m_adaptor->emitPropertiesChangedSignal(INTERFACE_NAME, {"blocking"}); - ASSERT_TRUE(waitUntil(signalReceived)); + ASSERT_TRUE(this->waitUntil(signalReceived)); } -TEST_F(SdbusTestObject, EmitsPropertyChangedSignalForAllProperties) +TYPED_TEST(SdbusTestObject, EmitsPropertyChangedSignalForAllProperties) { std::atomic signalReceived{false}; - m_proxy->m_onPropertiesChangedHandler = [&signalReceived]( const std::string& interfaceName - , const std::map& changedProperties - , const std::vector& invalidatedProperties ) + this->m_proxy->m_onPropertiesChangedHandler = [&signalReceived]( const std::string& interfaceName + , const std::map& changedProperties + , const std::vector& invalidatedProperties ) { EXPECT_THAT(interfaceName, Eq(INTERFACE_NAME)); EXPECT_THAT(changedProperties, SizeIs(1)); @@ -136,38 +134,38 @@ TEST_F(SdbusTestObject, EmitsPropertyChangedSignalForAllProperties) signalReceived = true; }; - m_adaptor->emitPropertiesChangedSignal(INTERFACE_NAME); + this->m_adaptor->emitPropertiesChangedSignal(INTERFACE_NAME); - ASSERT_TRUE(waitUntil(signalReceived)); + ASSERT_TRUE(this->waitUntil(signalReceived)); } -TEST_F(SdbusTestObject, GetsZeroManagedObjectsIfHasNoSubPathObjects) +TYPED_TEST(SdbusTestObject, GetsZeroManagedObjectsIfHasNoSubPathObjects) { - m_adaptor.reset(); - const auto objectsInterfacesAndProperties = m_objectManagerProxy->GetManagedObjects(); + this->m_adaptor.reset(); + const auto objectsInterfacesAndProperties = this->m_objectManagerProxy->GetManagedObjects(); ASSERT_THAT(objectsInterfacesAndProperties, SizeIs(0)); } -TEST_F(SdbusTestObject, GetsManagedObjectsSuccessfully) +TYPED_TEST(SdbusTestObject, GetsManagedObjectsSuccessfully) { - auto adaptor2 = std::make_unique(*s_adaptorConnection, OBJECT_PATH_2); - const auto objectsInterfacesAndProperties = m_objectManagerProxy->GetManagedObjects(); + auto adaptor2 = std::make_unique(*this->s_adaptorConnection, OBJECT_PATH_2); + const auto objectsInterfacesAndProperties = this->m_objectManagerProxy->GetManagedObjects(); ASSERT_THAT(objectsInterfacesAndProperties, SizeIs(2)); EXPECT_THAT(objectsInterfacesAndProperties.at(OBJECT_PATH) .at(org::sdbuscpp::integrationtests_adaptor::INTERFACE_NAME) - .at("action").get(), Eq(DEFAULT_ACTION_VALUE)); + .at("action").template get(), Eq(DEFAULT_ACTION_VALUE)); EXPECT_THAT(objectsInterfacesAndProperties.at(OBJECT_PATH_2) .at(org::sdbuscpp::integrationtests_adaptor::INTERFACE_NAME) - .at("action").get(), Eq(DEFAULT_ACTION_VALUE)); + .at("action").template get(), Eq(DEFAULT_ACTION_VALUE)); } -TEST_F(SdbusTestObject, EmitsInterfacesAddedSignalForSelectedObjectInterfaces) +TYPED_TEST(SdbusTestObject, EmitsInterfacesAddedSignalForSelectedObjectInterfaces) { std::atomic signalReceived{false}; - m_objectManagerProxy->m_onInterfacesAddedHandler = [&signalReceived]( const sdbus::ObjectPath& objectPath - , const std::map>& interfacesAndProperties ) + this->m_objectManagerProxy->m_onInterfacesAddedHandler = [&signalReceived]( const sdbus::ObjectPath& objectPath + , const std::map>& interfacesAndProperties ) { EXPECT_THAT(objectPath, Eq(OBJECT_PATH)); EXPECT_THAT(interfacesAndProperties, SizeIs(1)); @@ -189,16 +187,16 @@ TEST_F(SdbusTestObject, EmitsInterfacesAddedSignalForSelectedObjectInterfaces) signalReceived = true; }; - m_adaptor->emitInterfacesAddedSignal({INTERFACE_NAME}); + this->m_adaptor->emitInterfacesAddedSignal({INTERFACE_NAME}); - ASSERT_TRUE(waitUntil(signalReceived)); + ASSERT_TRUE(this->waitUntil(signalReceived)); } -TEST_F(SdbusTestObject, EmitsInterfacesAddedSignalForAllObjectInterfaces) +TYPED_TEST(SdbusTestObject, EmitsInterfacesAddedSignalForAllObjectInterfaces) { std::atomic signalReceived{false}; - m_objectManagerProxy->m_onInterfacesAddedHandler = [&signalReceived]( const sdbus::ObjectPath& objectPath - , const std::map>& interfacesAndProperties ) + this->m_objectManagerProxy->m_onInterfacesAddedHandler = [&signalReceived]( const sdbus::ObjectPath& objectPath + , const std::map>& interfacesAndProperties ) { EXPECT_THAT(objectPath, Eq(OBJECT_PATH)); #if LIBSYSTEMD_VERSION<=250 @@ -225,16 +223,16 @@ TEST_F(SdbusTestObject, EmitsInterfacesAddedSignalForAllObjectInterfaces) signalReceived = true; }; - m_adaptor->emitInterfacesAddedSignal(); + this->m_adaptor->emitInterfacesAddedSignal(); - ASSERT_TRUE(waitUntil(signalReceived)); + ASSERT_TRUE(this->waitUntil(signalReceived)); } -TEST_F(SdbusTestObject, EmitsInterfacesRemovedSignalForSelectedObjectInterfaces) +TYPED_TEST(SdbusTestObject, EmitsInterfacesRemovedSignalForSelectedObjectInterfaces) { std::atomic signalReceived{false}; - m_objectManagerProxy->m_onInterfacesRemovedHandler = [&signalReceived]( const sdbus::ObjectPath& objectPath - , const std::vector& interfaces ) + this->m_objectManagerProxy->m_onInterfacesRemovedHandler = [&signalReceived]( const sdbus::ObjectPath& objectPath + , const std::vector& interfaces ) { EXPECT_THAT(objectPath, Eq(OBJECT_PATH)); ASSERT_THAT(interfaces, SizeIs(1)); @@ -242,16 +240,16 @@ TEST_F(SdbusTestObject, EmitsInterfacesRemovedSignalForSelectedObjectInterfaces) signalReceived = true; }; - m_adaptor->emitInterfacesRemovedSignal({INTERFACE_NAME}); + this->m_adaptor->emitInterfacesRemovedSignal({INTERFACE_NAME}); - ASSERT_TRUE(waitUntil(signalReceived)); + ASSERT_TRUE(this->waitUntil(signalReceived)); } -TEST_F(SdbusTestObject, EmitsInterfacesRemovedSignalForAllObjectInterfaces) +TYPED_TEST(SdbusTestObject, EmitsInterfacesRemovedSignalForAllObjectInterfaces) { std::atomic signalReceived{false}; - m_objectManagerProxy->m_onInterfacesRemovedHandler = [&signalReceived]( const sdbus::ObjectPath& objectPath - , const std::vector& interfaces ) + this->m_objectManagerProxy->m_onInterfacesRemovedHandler = [&signalReceived]( const sdbus::ObjectPath& objectPath + , const std::vector& interfaces ) { EXPECT_THAT(objectPath, Eq(OBJECT_PATH)); #if LIBSYSTEMD_VERSION<=250 @@ -264,7 +262,7 @@ TEST_F(SdbusTestObject, EmitsInterfacesRemovedSignalForAllObjectInterfaces) signalReceived = true; }; - m_adaptor->emitInterfacesRemovedSignal(); + this->m_adaptor->emitInterfacesRemovedSignal(); - ASSERT_TRUE(waitUntil(signalReceived)); + ASSERT_TRUE(this->waitUntil(signalReceived)); } diff --git a/tests/integrationtests/TestFixture.cpp b/tests/integrationtests/TestFixture.cpp index 3436a27..e9f85ea 100644 --- a/tests/integrationtests/TestFixture.cpp +++ b/tests/integrationtests/TestFixture.cpp @@ -2,7 +2,7 @@ * (C) 2016 - 2021 KISTLER INSTRUMENTE AG, Winterthur, Switzerland * (C) 2016 - 2022 Stanislav Angelovic * - * @file TestAdaptor.cpp + * @file TestFixture.cpp * * Created on: May 23, 2020 * Project: sdbus-c++ @@ -27,8 +27,12 @@ #include "TestFixture.h" namespace sdbus { namespace test { - -std::unique_ptr TestFixture::s_adaptorConnection = sdbus::createSystemBusConnection(); -std::unique_ptr TestFixture::s_proxyConnection = sdbus::createSystemBusConnection(); + +std::unique_ptr BaseTestFixture::s_adaptorConnection = sdbus::createSystemBusConnection(); +std::unique_ptr BaseTestFixture::s_proxyConnection = sdbus::createSystemBusConnection(); + +std::thread TestFixture::s_eventLoopThread{}; +sd_event *TestFixture::s_sdEvent{}; +int TestFixture::s_eventExitFd{-1}; }} diff --git a/tests/integrationtests/TestFixture.h b/tests/integrationtests/TestFixture.h index 1d2d688..8dd25e7 100644 --- a/tests/integrationtests/TestFixture.h +++ b/tests/integrationtests/TestFixture.h @@ -2,7 +2,7 @@ * (C) 2016 - 2021 KISTLER INSTRUMENTE AG, Winterthur, Switzerland * (C) 2016 - 2022 Stanislav Angelovic * - * @file TestAdaptor.h + * @file TestFixture.h * * Created on: Jan 2, 2017 * Project: sdbus-c++ @@ -33,6 +33,8 @@ #include #include +#include +#include #include #include @@ -41,22 +43,17 @@ namespace sdbus { namespace test { -class TestFixture : public ::testing::Test +class BaseTestFixture : public ::testing::Test { public: static void SetUpTestCase() { - s_proxyConnection->enterEventLoopAsync(); s_adaptorConnection->requestName(BUS_NAME); - s_adaptorConnection->enterEventLoopAsync(); - std::this_thread::sleep_for(std::chrono::milliseconds(50)); // Give time for the proxy connection to start listening to signals } static void TearDownTestCase() { s_adaptorConnection->releaseName(BUS_NAME); - s_adaptorConnection->leaveEventLoop(); - s_proxyConnection->leaveEventLoop(); } template @@ -84,17 +81,17 @@ public: private: void SetUp() override { - m_objectManagerProxy = std::make_unique(*s_proxyConnection, BUS_NAME, MANAGER_PATH); - m_proxy = std::make_unique(*s_proxyConnection, BUS_NAME, OBJECT_PATH); + m_objectManagerProxy = std::make_unique(*s_proxyConnection, BUS_NAME, MANAGER_PATH); + m_proxy = std::make_unique(*s_proxyConnection, BUS_NAME, OBJECT_PATH); - m_objectManagerAdaptor = std::make_unique(*s_adaptorConnection, MANAGER_PATH); - m_adaptor = std::make_unique(*s_adaptorConnection, OBJECT_PATH); + m_objectManagerAdaptor = std::make_unique(*s_adaptorConnection, MANAGER_PATH); + m_adaptor = std::make_unique(*s_adaptorConnection, OBJECT_PATH); } void TearDown() override { - m_proxy.reset(); - m_adaptor.reset(); + m_proxy.reset(); + m_adaptor.reset(); } public: @@ -106,6 +103,93 @@ public: std::unique_ptr m_proxy; }; +struct SdBusCppLoop{}; +struct SdEventLoop{}; + +template +class TestFixture : public BaseTestFixture{}; + +// Fixture working upon internal sdbus-c++ event loop +template <> +class TestFixture : public BaseTestFixture +{ +public: + static void SetUpTestCase() + { + BaseTestFixture::SetUpTestCase(); + s_proxyConnection->enterEventLoopAsync(); + s_adaptorConnection->enterEventLoopAsync(); + std::this_thread::sleep_for(std::chrono::milliseconds(50)); // Give time for the proxy connection to start listening to signals + } + + static void TearDownTestCase() + { + BaseTestFixture::TearDownTestCase(); + s_adaptorConnection->leaveEventLoop(); + s_proxyConnection->leaveEventLoop(); + } +}; + +// Fixture working upon attached external sd-event loop +template <> +class TestFixture : public BaseTestFixture +{ +public: + static void SetUpTestCase() + { + sd_event_new(&s_sdEvent); + + s_proxyConnection->attachSdEventLoop(s_sdEvent); + s_adaptorConnection->attachSdEventLoop(s_sdEvent); + + s_eventExitFd = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK); + // No callback means that the event loop will exit when this event source triggers + sd_event_add_io(s_sdEvent, nullptr, s_eventExitFd, EPOLLIN, nullptr, NULL); + + s_eventLoopThread = std::thread([]() + { + sd_event_loop(s_sdEvent); + }); + + BaseTestFixture::SetUpTestCase(); + std::this_thread::sleep_for(std::chrono::milliseconds(50)); // Give time for the proxy connection to start listening to signals + } + + static void TearDownTestCase() + { + uint64_t value = 1; + write(s_eventExitFd, &value, sizeof(value)); + + s_eventLoopThread.join(); + + sd_event_unref(s_sdEvent); + close(s_eventExitFd); + + BaseTestFixture::TearDownTestCase(); + } + +private: + static std::thread s_eventLoopThread; + static sd_event *s_sdEvent; + static int s_eventExitFd; +}; + +typedef ::testing::Types EventLoopTags; + +TYPED_TEST_SUITE(TestFixture, EventLoopTags); + +template +using SdbusTestObject = TestFixture<_EventLoop>; +TYPED_TEST_SUITE(SdbusTestObject, EventLoopTags); + +template +using AsyncSdbusTestObject = TestFixture<_EventLoop>; +TYPED_TEST_SUITE(AsyncSdbusTestObject, EventLoopTags); + +template +using AConnection = TestFixture<_EventLoop>; +TYPED_TEST_SUITE(AConnection, EventLoopTags); + }} #endif /* SDBUS_CPP_INTEGRATIONTESTS_TESTFIXTURE_H_ */ diff --git a/tests/integrationtests/TestProxy.cpp b/tests/integrationtests/TestProxy.cpp index 3b8a27b..a94001e 100644 --- a/tests/integrationtests/TestProxy.cpp +++ b/tests/integrationtests/TestProxy.cpp @@ -2,7 +2,7 @@ * (C) 2016 - 2021 KISTLER INSTRUMENTE AG, Winterthur, Switzerland * (C) 2016 - 2022 Stanislav Angelovic * - * @file TestAdaptor.cpp + * @file TestProxy.cpp * * Created on: May 23, 2020 * Project: sdbus-c++ diff --git a/tests/integrationtests/TestProxy.h b/tests/integrationtests/TestProxy.h index 37fff82..998c035 100644 --- a/tests/integrationtests/TestProxy.h +++ b/tests/integrationtests/TestProxy.h @@ -2,7 +2,7 @@ * (C) 2016 - 2021 KISTLER INSTRUMENTE AG, Winterthur, Switzerland * (C) 2016 - 2022 Stanislav Angelovic * - * @file TestAdaptor.h + * @file TestProxy.h * * Created on: Jan 2, 2017 * Project: sdbus-c++ diff --git a/tests/unittests/mocks/SdBusMock.h b/tests/unittests/mocks/SdBusMock.h index 9e74df0..29a6ba2 100644 --- a/tests/unittests/mocks/SdBusMock.h +++ b/tests/unittests/mocks/SdBusMock.h @@ -92,6 +92,8 @@ public: MOCK_METHOD2(sd_bus_creds_get_egid, int(sd_bus_creds *, gid_t *)); MOCK_METHOD2(sd_bus_creds_get_supplementary_gids, int(sd_bus_creds *, const gid_t **)); MOCK_METHOD2(sd_bus_creds_get_selinux_context, int(sd_bus_creds *, const char **)); + + MOCK_METHOD1(sd_bus_get_event, sd_event *(sd_bus *bus)); }; #endif //SDBUS_CXX_SDBUS_MOCK_H