int main(void) {
    auto dbusConnection = CommonAPI::DBus::DBusConnection::getBus(CommonAPI::DBus::DBusType_t::SESSION);

    if (!dbusConnection->isConnected())
        dbusConnection->connect();

    assert(dbusConnection->isConnected());

    const bool serviceNameAcquired = dbusConnection->requestServiceNameAndBlock(
                    "org.genivi.CommonAPI.DBus.TestDBusInterfaceAdapter");
    assert(serviceNameAcquired);

    auto testStub = std::make_shared<TestStub>();
    auto testStubAdapter = std::make_shared<TestDBusStubAdapter>(
                    "my:common.api:address.for.dbus",
                    "org.genivi.CommonAPI.DBus.TestDBusInterfaceAdapter",
                    "/common/api/dbus/TestDBusInterfaceAdapter",
                    dbusConnection,
                    testStub);
    testStubAdapter->init(testStubAdapter);

    auto dbusMessageCall = CommonAPI::DBus::DBusMessage::createMethodCall(CommonAPI::DBus::DBusAddress("org.genivi.CommonAPI.DBus.TestDBusInterfaceAdapter", testStubAdapter->getDBusAddress().getObjectPath().c_str(), testStubAdapter->getDBusAddress().getService().c_str()), "GetEmptyResponse");

    const bool messageSent = dbusConnection->sendDBusMessage(dbusMessageCall);
    assert(messageSent);

    for (int i = 0; i < 10; i++) {
        dbusConnection->readWriteDispatch(100);
    }

    assert(dispatchedMessageCount > 0);
    testStubAdapter->deinit();

    return 0;
}
int main(void) {
	auto dbusConnection = common::api::dbus::DBusConnection::getSessionBus();

	dbusConnection->connect();

	common::api::dbus::DBusNameCache dbusNameCache(dbusConnection);

	dbusConnection->requestServiceNameAndBlock("common.api.dbus.test.DBusNameCache");

	for (int i = 0; i < 5; i++)
		dbusConnection->readWriteDispatch(100);

	dbusConnection->releaseServiceName("common.api.dbus.test.DBusNameCache");

	for (int i = 0; i < 5; i++)
		dbusConnection->readWriteDispatch(100);

	return 0;
}
TEST_F(DBusConnectionTest, SendingAsyncDBusMessagesWorks) {
    const char busName[] = "commonapi.dbus.test.TestInterfaceHandler";
    const char objectPath[] = "/common/api/dbus/test/TestObject";
    const char interfaceName[] = "commonapi.dbus.test.TestInterface";
    const char methodName[] = "TestMethod";

    auto interfaceHandlerDBusConnection = CommonAPI::DBus::DBusConnection::getSessionBus();

    ASSERT_TRUE(interfaceHandlerDBusConnection->connect());
    ASSERT_TRUE(interfaceHandlerDBusConnection->requestServiceNameAndBlock(busName));

    uint32_t serviceHandlerDBusMessageCount = 0;
    uint32_t clientReplyHandlerDBusMessageCount = 0;

    interfaceHandlerDBusConnection->setObjectPathMessageHandler(
                    [&serviceHandlerDBusMessageCount, &interfaceHandlerDBusConnection] (CommonAPI::DBus::DBusMessage dbusMessage) -> bool {
                        ++serviceHandlerDBusMessageCount;
                        CommonAPI::DBus::DBusMessage dbusMessageReply = dbusMessage.createMethodReturn("");
                        interfaceHandlerDBusConnection->sendDBusMessage(dbusMessageReply);
                        return true;
                    }
                    );

    interfaceHandlerDBusConnection->registerObjectPath(objectPath);

    ASSERT_TRUE(dbusConnection_->connect());

    CommonAPI::DBus::DBusMessage dbusReplyMessage;

    for (uint32_t expectedDBusMessageCount = 1; expectedDBusMessageCount <= 10; expectedDBusMessageCount++) {
        CommonAPI::DBus::DBusMessage dbusMessageCall = CommonAPI::DBus::DBusMessage::createMethodCall(
                        busName,
                        objectPath,
                        interfaceName,
                        methodName,
                        "");

        CommonAPI::DBus::DBusOutputStream dbusOutputStream(dbusMessageCall);

        interfaceHandlerDBusConnection->sendDBusMessageWithReplyAsync(
                        dbusMessageCall,
                        CommonAPI::DBus::DBusProxyAsyncCallbackHandler<>::create(
                                        [&clientReplyHandlerDBusMessageCount](CommonAPI::CallStatus status) {
                                            ASSERT_EQ(CommonAPI::CallStatus::SUCCESS, status);
                                            ++clientReplyHandlerDBusMessageCount;
                                        })
                                        );

        for (int i = 0; i < 10 && serviceHandlerDBusMessageCount < expectedDBusMessageCount; i++) {
            interfaceHandlerDBusConnection->readWriteDispatch(100);
        }

        ASSERT_EQ(serviceHandlerDBusMessageCount, expectedDBusMessageCount);

        for (int i = 0; i < 10 && clientReplyHandlerDBusMessageCount < expectedDBusMessageCount; i++) {
            dbusConnection_->readWriteDispatch(100);
        }

        ASSERT_EQ(clientReplyHandlerDBusMessageCount, expectedDBusMessageCount);
    }

    dbusConnection_->disconnect();

    interfaceHandlerDBusConnection->unregisterObjectPath(objectPath);

    ASSERT_TRUE(interfaceHandlerDBusConnection->releaseServiceName(busName));
    interfaceHandlerDBusConnection->disconnect();
}