diff --git a/include/sdbus-c++/IObject.h b/include/sdbus-c++/IObject.h index 5196665..b2bf96b 100644 --- a/include/sdbus-c++/IObject.h +++ b/include/sdbus-c++/IObject.h @@ -32,6 +32,7 @@ #include #include #include +#include // Forward declarations namespace sdbus { @@ -177,7 +178,7 @@ namespace sdbus { virtual Signal createSignal(const std::string& interfaceName, const std::string& signalName) = 0; /*! - * @brief Emits signal on D-Bus + * @brief Emits signal for this object path * * @param[in] message Signal message to be sent out * @@ -188,7 +189,7 @@ namespace sdbus { virtual void emitSignal(const sdbus::Signal& message) = 0; /*! - * @brief Emits PropertyChanged signal for specified properties under a given interface + * @brief Emits PropertyChanged signal for specified properties under a given interface of this object path * * @param[in] interfaceName Name of an interface that properties belong to * @param[in] propNames Names of properties that will be included in the PropertiesChanged signal @@ -198,7 +199,7 @@ namespace sdbus { virtual void emitPropertiesChangedSignal(const std::string& interfaceName, const std::vector& propNames) = 0; /*! - * @brief Emits PropertyChanged signal for all properties of a given interface + * @brief Emits PropertyChanged signal for all properties on a given interface of this object path * * @param[in] interfaceName Name of an interface * @@ -207,11 +208,55 @@ namespace sdbus { virtual void emitPropertiesChangedSignal(const std::string& interfaceName) = 0; /*! - * @brief Provides D-Bus connection used by the object - * - * @return Reference to the D-Bus connection - */ - virtual sdbus::IConnection& getConnection() const = 0; + * @brief Emits InterfacesAdded signal on this object path + * + * This emits an InterfacesAdded signal on this object path, by iterating all registered + * interfaces on the path. All properties are queried and included in the signal. + * This call is equivalent to emitInterfacesAddedSignal() with an explicit list of + * registered interfaces. However, unlike emitInterfacesAddedSignal(interfaces), this + * call can figure out the list of supported interfaces itself. Furthermore, it properly + * adds the builtin org.freedesktop.DBus.* interfaces. + * + * @throws sdbus::Error in case of failure + */ + virtual void emitInterfacesAddedSignal() = 0; + + /*! + * @brief Emits InterfacesAdded signal on this object path + * + * This emits an InterfacesAdded signal on this object path with explicitly provided list + * of registered interfaces. As sdbus-c++ does currently not supported adding/removing + * interfaces of an existing object at run time (an object has a fixed set of interfaces + * registered by the time of invoking finishRegistration()), emitInterfacesAddedSignal(void) + * is probably what you are looking for. + * + * @throws sdbus::Error in case of failure + */ + virtual void emitInterfacesAddedSignal(const std::vector& interfaces) = 0; + + /*! + * @brief Emits InterfacesRemoved signal on this object path + * + * This is like sd_bus_emit_object_added(), but emits an InterfacesRemoved signal on this + * object path. This only includes any registered interfaces but skips the properties. + * This function shall be called (just) before destroying the object. + * + * @throws sdbus::Error in case of failure + */ + virtual void emitInterfacesRemovedSignal() = 0; + + /*! + * @brief Emits InterfacesRemoved signal on this object path + * + * This emits an InterfacesRemoved signal on the given path with explicitly provided list + * of registered interfaces. As sdbus-c++ does currently not supported adding/removing + * interfaces of an existing object at run time (an object has a fixed set of interfaces + * registered by the time of invoking finishRegistration()), emitInterfacesRemovedSignal(void) + * is probably what you are looking for. + * + * @throws sdbus::Error in case of failure + */ + virtual void emitInterfacesRemovedSignal(const std::vector& interfaces) = 0; /*! * @brief Adds an ObjectManager interface at the path of this D-Bus object @@ -237,6 +282,13 @@ namespace sdbus { */ virtual bool hasObjectManager() const = 0; + /*! + * @brief Provides D-Bus connection used by the object + * + * @return Reference to the D-Bus connection + */ + virtual sdbus::IConnection& getConnection() const = 0; + /*! * @brief Registers method that the object will provide on D-Bus * diff --git a/include/sdbus-c++/StandardInterfaces.h b/include/sdbus-c++/StandardInterfaces.h index 7d006e6..6c4a46f 100644 --- a/include/sdbus-c++/StandardInterfaces.h +++ b/include/sdbus-c++/StandardInterfaces.h @@ -181,6 +181,7 @@ namespace sdbus { // is provided by underlying libsystemd implementation. The exception is Properties_adaptor and // ObjectManager_adaptor, which provide convenience functionality to emit signals. + // Adaptor for properties class Properties_adaptor { static constexpr const char* INTERFACE_NAME = "org.freedesktop.DBus.Properties"; @@ -206,6 +207,42 @@ namespace sdbus { sdbus::IObject& object_; }; + // Adaptor for object manager + class ObjectManager_adaptor + { + static constexpr const char* INTERFACE_NAME = "org.freedesktop.DBus.ObjectManager"; + + protected: + ObjectManager_adaptor(sdbus::IObject& object) + : object_(object) + { + } + + public: + void emitInterfacesAddedSignal() + { + object_.emitInterfacesAddedSignal(); + } + + void emitInterfacesAddedSignal(const std::vector& interfaces) + { + object_.emitInterfacesAddedSignal(interfaces); + } + + void emitInterfacesRemovedSignal() + { + object_.emitInterfacesRemovedSignal(); + } + + void emitInterfacesRemovedSignal(const std::vector& interfaces) + { + object_.emitInterfacesRemovedSignal(interfaces); + } + + private: + sdbus::IObject& object_; + }; + } #endif /* SDBUS_CXX_STANDARDINTERFACES_H_ */ diff --git a/src/Connection.cpp b/src/Connection.cpp index b041662..42fa192 100644 --- a/src/Connection.cpp +++ b/src/Connection.cpp @@ -203,6 +203,44 @@ void Connection::emitPropertiesChangedSignal( const std::string& objectPath SDBUS_THROW_ERROR_IF(r < 0, "Failed to emit PropertiesChanged signal", -r); } +void Connection::emitInterfacesAddedSignal(const std::string& objectPath) +{ + auto r = iface_->sd_bus_emit_object_added(bus_.get(), objectPath.c_str()); + + SDBUS_THROW_ERROR_IF(r < 0, "Failed to emit InterfacesAdded signal for all registered interfaces", -r); +} + +void Connection::emitInterfacesAddedSignal( const std::string& objectPath + , const std::vector& interfaces ) +{ + auto names = to_strv(interfaces); + + auto r = iface_->sd_bus_emit_interfaces_added_strv( bus_.get() + , objectPath.c_str() + , interfaces.empty() ? nullptr : &names[0] ); + + SDBUS_THROW_ERROR_IF(r < 0, "Failed to emit InterfacesAdded signal", -r); +} + +void Connection::emitInterfacesRemovedSignal(const std::string& objectPath) +{ + auto r = iface_->sd_bus_emit_object_removed(bus_.get(), objectPath.c_str()); + + SDBUS_THROW_ERROR_IF(r < 0, "Failed to emit InterfacesRemoved signal for all registered interfaces", -r); +} + +void Connection::emitInterfacesRemovedSignal( const std::string& objectPath + , const std::vector& interfaces ) +{ + auto names = to_strv(interfaces); + + auto r = iface_->sd_bus_emit_interfaces_removed_strv( bus_.get() + , objectPath.c_str() + , interfaces.empty() ? nullptr : &names[0] ); + + SDBUS_THROW_ERROR_IF(r < 0, "Failed to emit InterfacesRemoved signal", -r); +} + SlotPtr Connection::registerSignalHandler( const std::string& objectPath , const std::string& interfaceName , const std::string& signalName diff --git a/src/Connection.h b/src/Connection.h index 1451a40..1590bd3 100644 --- a/src/Connection.h +++ b/src/Connection.h @@ -76,9 +76,16 @@ namespace sdbus { namespace internal { Signal createSignal( const std::string& objectPath , const std::string& interfaceName , const std::string& signalName ) const override; + void emitPropertiesChangedSignal( const std::string& objectPath , const std::string& interfaceName , const std::vector& propNames ) override; + void emitInterfacesAddedSignal(const std::string& objectPath) override; + void emitInterfacesAddedSignal( const std::string& objectPath + , const std::vector& interfaces ) override; + void emitInterfacesRemovedSignal(const std::string& objectPath) override; + void emitInterfacesRemovedSignal( const std::string& objectPath + , const std::vector& interfaces ) override; SlotPtr registerSignalHandler( const std::string& objectPath , const std::string& interfaceName diff --git a/src/IConnection.h b/src/IConnection.h index 37c6892..7fec3a0 100644 --- a/src/IConnection.h +++ b/src/IConnection.h @@ -30,6 +30,7 @@ #include #include #include +#include // Forward declaration namespace sdbus { @@ -68,9 +69,18 @@ namespace internal { virtual Signal createSignal( const std::string& objectPath , const std::string& interfaceName , const std::string& signalName ) const = 0; + virtual void emitPropertiesChangedSignal( const std::string& objectPath , const std::string& interfaceName , const std::vector& propNames ) = 0; + virtual void emitInterfacesAddedSignal(const std::string& objectPath) = 0; + virtual void emitInterfacesAddedSignal( const std::string& objectPath + , const std::vector& interfaces ) = 0; + virtual void emitInterfacesRemovedSignal(const std::string& objectPath) = 0; + virtual void emitInterfacesRemovedSignal( const std::string& objectPath + , const std::vector& interfaces ) = 0; + + virtual SlotPtr addObjectManager(const std::string& objectPath, void* /*dummy*/ = nullptr) = 0; virtual SlotPtr registerSignalHandler( const std::string& objectPath , const std::string& interfaceName @@ -80,8 +90,6 @@ namespace internal { virtual void enterProcessingLoopAsync() = 0; virtual void leaveProcessingLoop() = 0; - - virtual SlotPtr addObjectManager(const std::string& objectPath, void* /*dummy*/ = nullptr) = 0; }; } diff --git a/src/ISdBus.h b/src/ISdBus.h index ca4710c..0dc1716 100644 --- a/src/ISdBus.h +++ b/src/ISdBus.h @@ -54,6 +54,10 @@ namespace sdbus { namespace internal { virtual int sd_bus_message_new_method_error(sd_bus_message *call, sd_bus_message **m, const sd_bus_error *e) = 0; virtual int sd_bus_emit_properties_changed_strv(sd_bus *bus, const char *path, const char *interface, char **names) = 0; + virtual int sd_bus_emit_object_added(sd_bus *bus, const char *path) = 0; + virtual int sd_bus_emit_object_removed(sd_bus *bus, const char *path) = 0; + virtual int sd_bus_emit_interfaces_added_strv(sd_bus *bus, const char *path, char **interfaces) = 0; + virtual int sd_bus_emit_interfaces_removed_strv(sd_bus *bus, const char *path, char **interfaces) = 0; virtual int sd_bus_open_user(sd_bus **ret) = 0; virtual int sd_bus_open_system(sd_bus **ret) = 0; diff --git a/src/Object.cpp b/src/Object.cpp index 9ed7561..c3db8e2 100644 --- a/src/Object.cpp +++ b/src/Object.cpp @@ -145,9 +145,24 @@ void Object::emitPropertiesChangedSignal(const std::string& interfaceName) Object::emitPropertiesChangedSignal(interfaceName, {}); } -sdbus::IConnection& Object::getConnection() const +void Object::emitInterfacesAddedSignal() { - return dynamic_cast(connection_); + connection_.emitInterfacesAddedSignal(objectPath_); +} + +void Object::emitInterfacesAddedSignal(const std::vector& interfaces) +{ + connection_.emitInterfacesAddedSignal(objectPath_, interfaces); +} + +void Object::emitInterfacesRemovedSignal() +{ + connection_.emitInterfacesRemovedSignal(objectPath_); +} + +void Object::emitInterfacesRemovedSignal(const std::vector& interfaces) +{ + connection_.emitInterfacesRemovedSignal(objectPath_, interfaces); } void Object::addObjectManager() @@ -165,6 +180,11 @@ bool Object::hasObjectManager() const return objectManagerSlot_ != nullptr; } +sdbus::IConnection& Object::getConnection() const +{ + return dynamic_cast(connection_); +} + const std::vector& Object::createInterfaceVTable(InterfaceData& interfaceData) { auto& vtable = interfaceData.vtable_; diff --git a/src/Object.h b/src/Object.h index ca921d5..1529a86 100644 --- a/src/Object.h +++ b/src/Object.h @@ -79,13 +79,17 @@ namespace internal { void emitSignal(const sdbus::Signal& message) override; void emitPropertiesChangedSignal(const std::string& interfaceName, const std::vector& propNames) override; void emitPropertiesChangedSignal(const std::string& interfaceName) override; - - sdbus::IConnection& getConnection() const override; + void emitInterfacesAddedSignal() override; + void emitInterfacesAddedSignal(const std::vector& interfaces) override; + void emitInterfacesRemovedSignal() override; + void emitInterfacesRemovedSignal(const std::vector& interfaces) override; void addObjectManager() override; void removeObjectManager() override; bool hasObjectManager() const override; + sdbus::IConnection& getConnection() const override; + private: using InterfaceName = std::string; struct InterfaceData diff --git a/src/SdBus.cpp b/src/SdBus.cpp index 0e4d665..8db21ab 100644 --- a/src/SdBus.cpp +++ b/src/SdBus.cpp @@ -98,6 +98,34 @@ int SdBus::sd_bus_emit_properties_changed_strv(sd_bus *bus, const char *path, co return ::sd_bus_emit_properties_changed_strv(bus, path, interface, names); } +int SdBus::sd_bus_emit_object_added(sd_bus *bus, const char *path) +{ + std::unique_lock lock(sdbusMutex_); + + return ::sd_bus_emit_object_added(bus, path); +} + +int SdBus::sd_bus_emit_object_removed(sd_bus *bus, const char *path) +{ + std::unique_lock lock(sdbusMutex_); + + return ::sd_bus_emit_object_removed(bus, path); +} + +int SdBus::sd_bus_emit_interfaces_added_strv(sd_bus *bus, const char *path, char **interfaces) +{ + std::unique_lock lock(sdbusMutex_); + + return ::sd_bus_emit_interfaces_added_strv(bus, path, interfaces); +} + +int SdBus::sd_bus_emit_interfaces_removed_strv(sd_bus *bus, const char *path, char **interfaces) +{ + std::unique_lock lock(sdbusMutex_); + + return ::sd_bus_emit_interfaces_removed_strv(bus, path, interfaces); +} + int SdBus::sd_bus_open_user(sd_bus **ret) { return ::sd_bus_open_user(ret); diff --git a/src/SdBus.h b/src/SdBus.h index 052e5c2..f5ad198 100644 --- a/src/SdBus.h +++ b/src/SdBus.h @@ -48,6 +48,10 @@ public: virtual int sd_bus_message_new_method_error(sd_bus_message *call, sd_bus_message **m, const sd_bus_error *e) override; virtual int sd_bus_emit_properties_changed_strv(sd_bus *bus, const char *path, const char *interface, char **names) override; + virtual int sd_bus_emit_object_added(sd_bus *bus, const char *path) override; + virtual int sd_bus_emit_object_removed(sd_bus *bus, const char *path) override; + virtual int sd_bus_emit_interfaces_added_strv(sd_bus *bus, const char *path, char **interfaces) override; + virtual int sd_bus_emit_interfaces_removed_strv(sd_bus *bus, const char *path, char **interfaces) override; virtual int sd_bus_open_user(sd_bus **ret) override; virtual int sd_bus_open_system(sd_bus **ret) override; diff --git a/tests/integrationtests/AdaptorAndProxy_test.cpp b/tests/integrationtests/AdaptorAndProxy_test.cpp index de7642d..4668835 100644 --- a/tests/integrationtests/AdaptorAndProxy_test.cpp +++ b/tests/integrationtests/AdaptorAndProxy_test.cpp @@ -472,7 +472,9 @@ TEST_F(SdbusTestObject, GetsAllPropertiesViaPropertiesInterface) TEST_F(SdbusTestObject, EmitsPropertyChangedSignalForSelectedProperties) { std::atomic signalReceived{false}; - m_proxy->m_onPropertiesChangedHandler = [&signalReceived](const std::string& interfaceName, const std::map& changedProperties, const std::vector& invalidatedProperties) + 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)); @@ -483,13 +485,16 @@ TEST_F(SdbusTestObject, EmitsPropertyChangedSignalForSelectedProperties) m_proxy->blocking(!DEFAULT_BLOCKING_VALUE); m_proxy->action(DEFAULT_ACTION_VALUE*2); m_adaptor->emitPropertiesChangedSignal(INTERFACE_NAME, {"blocking"}); + waitUntil(signalReceived); } TEST_F(SdbusTestObject, EmitsPropertyChangedSignalForAllProperties) { std::atomic signalReceived{false}; - m_proxy->m_onPropertiesChangedHandler = [&signalReceived](const std::string& interfaceName, const std::map& changedProperties, const std::vector& invalidatedProperties) + 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)); @@ -500,6 +505,7 @@ TEST_F(SdbusTestObject, EmitsPropertyChangedSignalForAllProperties) }; m_adaptor->emitPropertiesChangedSignal(INTERFACE_NAME); + waitUntil(signalReceived); } @@ -540,3 +546,75 @@ TEST_F(SdbusTestObject, GetsManagedObjectsSuccessfully) EXPECT_THAT(objectsInterfacesAndProperties.at("/sub/path1").at("org.sdbuscpp.integrationtests.iface1").at("aProperty1").get(), Eq(123)); EXPECT_THAT(objectsInterfacesAndProperties.at("/sub/path2").at("org.sdbuscpp.integrationtests.iface2").at("aProperty2").get(), Eq("hi")); } + +TEST_F(SdbusTestObject, EmitsInterfacesAddedSignalForSelectedObjectInterfaces) +{ + std::atomic signalReceived{false}; + m_proxy->m_onInterfacesAddedHandler = [&signalReceived]( const sdbus::ObjectPath& objectPath + , const std::map>& interfacesAndProperties ) + { + EXPECT_THAT(objectPath, Eq(OBJECT_PATH)); + EXPECT_THAT(interfacesAndProperties, SizeIs(1)); + EXPECT_THAT(interfacesAndProperties.count(INTERFACE_NAME), Eq(1)); + EXPECT_THAT(interfacesAndProperties.at(INTERFACE_NAME), SizeIs(3)); + signalReceived = true; + }; + m_adaptor->addObjectManager(); // ObjectManager interface needs to be activated explicitly + + m_adaptor->emitInterfacesAddedSignal({INTERFACE_NAME}); + + waitUntil(signalReceived); +} + +TEST_F(SdbusTestObject, EmitsInterfacesAddedSignalForAllObjectInterfaces) +{ + std::atomic signalReceived{false}; + m_proxy->m_onInterfacesAddedHandler = [&signalReceived]( const sdbus::ObjectPath& objectPath + , const std::map>& interfacesAndProperties ) + { + EXPECT_THAT(objectPath, Eq(OBJECT_PATH)); + EXPECT_THAT(interfacesAndProperties, SizeIs(5)); // INTERFACE_NAME + 4 standard interfaces + EXPECT_THAT(interfacesAndProperties.at(INTERFACE_NAME), SizeIs(3)); // 3 properties under INTERFACE_NAME + signalReceived = true; + }; + m_adaptor->addObjectManager(); // ObjectManager interface needs to be activated explicitly + + m_adaptor->emitInterfacesAddedSignal(); + + waitUntil(signalReceived); +} + +TEST_F(SdbusTestObject, EmitsInterfacesRemovedSignalForSelectedObjectInterfaces) +{ + std::atomic signalReceived{false}; + m_proxy->m_onInterfacesRemovedHandler = [&signalReceived]( const sdbus::ObjectPath& objectPath + , const std::vector& interfaces ) + { + EXPECT_THAT(objectPath, Eq(OBJECT_PATH)); + ASSERT_THAT(interfaces, SizeIs(1)); + EXPECT_THAT(interfaces[0], Eq(INTERFACE_NAME)); + signalReceived = true; + }; + m_adaptor->addObjectManager(); // ObjectManager interface needs to be activated explicitly + + m_adaptor->emitInterfacesRemovedSignal({INTERFACE_NAME}); + + waitUntil(signalReceived); +} + +TEST_F(SdbusTestObject, EmitsInterfacesRemovedSignalForAllObjectInterfaces) +{ + std::atomic signalReceived{false}; + m_proxy->m_onInterfacesRemovedHandler = [&signalReceived]( const sdbus::ObjectPath& objectPath + , const std::vector& interfaces ) + { + EXPECT_THAT(objectPath, Eq(OBJECT_PATH)); + ASSERT_THAT(interfaces, SizeIs(5)); // INTERFACE_NAME + 4 standard interfaces + signalReceived = true; + }; + m_adaptor->addObjectManager(); // ObjectManager interface needs to be activated explicitly + + m_adaptor->emitInterfacesRemovedSignal(); + + waitUntil(signalReceived); +} diff --git a/tests/integrationtests/TestingAdaptor.h b/tests/integrationtests/TestingAdaptor.h index b3b4233..86a4d54 100644 --- a/tests/integrationtests/TestingAdaptor.h +++ b/tests/integrationtests/TestingAdaptor.h @@ -32,7 +32,8 @@ #include class TestingAdaptor : public sdbus::AdaptorInterfaces< testing_adaptor - , sdbus::Properties_adaptor > + , sdbus::Properties_adaptor + , sdbus::ObjectManager_adaptor > { public: TestingAdaptor(sdbus::IConnection& connection) : diff --git a/tests/integrationtests/TestingProxy.h b/tests/integrationtests/TestingProxy.h index fc60ef0..4dc2a9f 100644 --- a/tests/integrationtests/TestingProxy.h +++ b/tests/integrationtests/TestingProxy.h @@ -87,15 +87,17 @@ protected: m_onPropertiesChangedHandler(interfaceName, changedProperties, invalidatedProperties); } - void onInterfacesAdded( const sdbus::ObjectPath& /*objectPath*/ - , const std::map>& /*interfacesAndProperties*/) override + void onInterfacesAdded( const sdbus::ObjectPath& objectPath + , const std::map>& interfacesAndProperties) override { - // Intentionally left empty + if (m_onInterfacesAddedHandler) + m_onInterfacesAddedHandler(objectPath, interfacesAndProperties); } - void onInterfacesRemoved( const sdbus::ObjectPath& /*objectPath*/ - , const std::vector& /*interfaces*/) override + void onInterfacesRemoved( const sdbus::ObjectPath& objectPath + , const std::vector& interfaces) override { - // Intentionally left empty + if (m_onInterfacesRemovedHandler) + m_onInterfacesRemovedHandler(objectPath, interfaces); } //private: @@ -106,7 +108,9 @@ public: std::map m_signature; std::function m_DoOperationClientSideAsyncReplyHandler; - std::function& changedProperties, const std::vector& invalidatedProperties)> m_onPropertiesChangedHandler; + std::function&, const std::vector&)> m_onPropertiesChangedHandler; + std::function>&)> m_onInterfacesAddedHandler; + std::function&)> m_onInterfacesRemovedHandler; }; diff --git a/tests/unittests/mocks/SdBusMock.h b/tests/unittests/mocks/SdBusMock.h index c099ccf..1c8b339 100644 --- a/tests/unittests/mocks/SdBusMock.h +++ b/tests/unittests/mocks/SdBusMock.h @@ -47,6 +47,10 @@ public: MOCK_METHOD3(sd_bus_message_new_method_error, int(sd_bus_message *call, sd_bus_message **m, const sd_bus_error *e)); MOCK_METHOD4(sd_bus_emit_properties_changed_strv, int(sd_bus *bus, const char *path, const char *interface, char **names)); + MOCK_METHOD2(sd_bus_emit_object_added, int(sd_bus *bus, const char *path)); + MOCK_METHOD2(sd_bus_emit_object_removed, int(sd_bus *bus, const char *path)); + MOCK_METHOD3(sd_bus_emit_interfaces_added_strv, int(sd_bus *bus, const char *path, char **interfaces)); + MOCK_METHOD3(sd_bus_emit_interfaces_removed_strv, int(sd_bus *bus, const char *path, char **interfaces)); MOCK_METHOD1(sd_bus_open_user, int(sd_bus **ret)); MOCK_METHOD1(sd_bus_open_system, int(sd_bus **ret));