TEST_F(DBusCommunicationTest, SameStubCanBeRegisteredSeveralTimes) {
    auto defaultTestProxy = runtime_->buildProxy<VERSION::commonapi::tests::TestInterfaceProxy>(domain_, serviceAddress_);
    auto defaultTestProxy2 = runtime_->buildProxy<VERSION::commonapi::tests::TestInterfaceProxy>(domain_, serviceAddress2_);
    auto defaultTestProxy3 = runtime_->buildProxy<VERSION::commonapi::tests::TestInterfaceProxy>(domain_, serviceAddress3_);
    ASSERT_TRUE((bool)defaultTestProxy);
    ASSERT_TRUE((bool)defaultTestProxy2);
    ASSERT_TRUE((bool)defaultTestProxy3);

    auto stub = std::make_shared<VERSION::commonapi::tests::TestInterfaceStubDefault>();
    interface_ = stub->getStubAdapter()->getInterface();

    bool serviceRegistered = runtime_->registerService(domain_, serviceAddress_, stub, "connection");
    bool serviceRegistered2 = runtime_->registerService(domain_, serviceAddress2_, stub, "connection");
    bool serviceRegistered3 = runtime_->registerService(domain_, serviceAddress3_, stub, "connection");
    for (unsigned int i = 0; (!serviceRegistered || !serviceRegistered2 || !serviceRegistered3) && i < 100; ++i) {
        if (!serviceRegistered) {
            serviceRegistered = runtime_->registerService(domain_, serviceAddress_, stub, "connection");
        }
        if (!serviceRegistered2) {
            serviceRegistered2 = runtime_->registerService(domain_, serviceAddress2_, stub, "connection");
        }
        if (!serviceRegistered3) {
            serviceRegistered3 = runtime_->registerService(domain_, serviceAddress3_, stub, "connection");
        }
        usleep(10000);
    }
    ASSERT_TRUE(serviceRegistered);
    ASSERT_TRUE(serviceRegistered2);
    ASSERT_TRUE(serviceRegistered3);

    for(unsigned int i = 0; (!defaultTestProxy->isAvailable() || !defaultTestProxy2->isAvailable() || !defaultTestProxy3->isAvailable()) && i < 100; ++i) {
        usleep(10000);
    }
    ASSERT_TRUE(defaultTestProxy->isAvailable());
    ASSERT_TRUE(defaultTestProxy2->isAvailable());
    ASSERT_TRUE(defaultTestProxy3->isAvailable());

    uint32_t v1 = 5;
    std::string v2 = "Ciao ;)";
    CommonAPI::CallStatus stat, stat2, stat3;
    defaultTestProxy->testVoidPredefinedTypeMethod(v1, v2, stat);
    defaultTestProxy2->testVoidPredefinedTypeMethod(v1, v2, stat2);
    defaultTestProxy3->testVoidPredefinedTypeMethod(v1, v2, stat3);

    EXPECT_EQ(stat, CommonAPI::CallStatus::SUCCESS);
    EXPECT_EQ(stat2, CommonAPI::CallStatus::SUCCESS);
    EXPECT_EQ(stat3, CommonAPI::CallStatus::SUCCESS);
}
TEST_F(DBusCommunicationTest, RemoteMethodCallSucceeds) {
    auto defaultTestProxy = runtime_->buildProxy<VERSION::commonapi::tests::TestInterfaceProxy>(domain_, serviceAddress_);
    ASSERT_TRUE((bool)defaultTestProxy);

    auto stub = std::make_shared<VERSION::commonapi::tests::TestInterfaceStubDefault>();
    interface_ = stub->getStubAdapter()->getInterface();

    bool serviceRegistered = runtime_->registerService(domain_, serviceAddress_, stub, "connection");
    for(unsigned int i = 0; !serviceRegistered && i < 100; ++i) {
        serviceRegistered = runtime_->registerService(domain_, serviceAddress_, stub, "connection");
        usleep(10000);
    }
    ASSERT_TRUE(serviceRegistered);

    for(unsigned int i = 0; !defaultTestProxy->isAvailable() && i < 100; ++i) {
        usleep(10000);
    }
    ASSERT_TRUE(defaultTestProxy->isAvailable());

    uint32_t v1 = 5;
    std::string v2 = "Ciao ;)";
    CommonAPI::CallStatus stat;
    defaultTestProxy->testVoidPredefinedTypeMethod(v1, v2, stat);

    EXPECT_EQ(stat, CommonAPI::CallStatus::SUCCESS);
}
TEST_F(AddressTranslatorTest, ServicesUsingPredefinedAddressesCanCommunicate) {
    std::shared_ptr<CommonAPI::Runtime> runtime = CommonAPI::Runtime::get();
    ASSERT_TRUE((bool)runtime);

    CommonAPI::Address commonApiAddress(commonApiAddresses[0]);
    auto defaultTestProxy = runtime->buildProxy<VERSION::commonapi::tests::TestInterfaceProxy>(commonApiAddress.getDomain(), commonApiAddress.getInstance());
    ASSERT_TRUE((bool)defaultTestProxy);

    auto stub = std::make_shared<VERSION::commonapi::tests::TestInterfaceStubDefault>();

    bool serviceNameAcquired = runtime->registerService(commonApiAddress.getDomain(), commonApiAddress.getInstance(), stub, "connection");
    for(unsigned int i = 0; !serviceNameAcquired && i < 100; i++) {
        serviceNameAcquired = runtime->registerService(commonApiAddress.getDomain(), commonApiAddress.getInstance(), stub, "connection");
        usleep(10000);
    }
    ASSERT_TRUE(serviceNameAcquired);

    for(unsigned int i = 0; !defaultTestProxy->isAvailable() && i < 100; ++i) {
        usleep(10000);
    }
    ASSERT_TRUE(defaultTestProxy->isAvailable());

    uint32_t v1 = 5;
    std::string v2 = "Hai :)";
    CommonAPI::CallStatus stat;
    defaultTestProxy->testVoidPredefinedTypeMethod(v1, v2, stat);

    ASSERT_EQ(stat, CommonAPI::CallStatus::SUCCESS);
    
    runtime->unregisterService(commonApiAddress.getDomain(), stub->getStubAdapter()->getInterface(), commonApiAddress.getInstance());
}
TEST_F(DBusCommunicationTest, MixedSyncAndAsyncCallsSucceed) {
    auto defaultTestProxy = runtime_->buildProxy<VERSION::commonapi::tests::TestInterfaceProxy>(domain_, serviceAddress5_);
    ASSERT_TRUE((bool)defaultTestProxy);

    auto stub = std::make_shared<VERSION::commonapi::tests::TestInterfaceStubDefault>();
    interface_ = stub->getStubAdapter()->getInterface();

    bool serviceRegistered = runtime_->registerService(domain_, serviceAddress5_, stub, "connection");
    for(unsigned int i = 0; !serviceRegistered && i < 100; ++i) {
        serviceRegistered = runtime_->registerService(domain_, serviceAddress5_, stub, "connection");
        usleep(10000);
    }
    ASSERT_TRUE(serviceRegistered);

    for (unsigned int i = 0; !defaultTestProxy->isAvailable() && i < 100; ++i) {
        usleep(10000);
    }
    ASSERT_TRUE(defaultTestProxy->isAvailable());

    uint32_t v1 = 5;
    std::string v2 = "Hai :)";
    CommonAPI::CallStatus stat;
    unsigned int responseCounter = 0;
    for (unsigned int i = 0; i < 10; i++) {
        defaultTestProxy->testVoidPredefinedTypeMethodAsync(v1, v2, [&responseCounter](const CommonAPI::CallStatus& status) {
                if(status == CommonAPI::CallStatus::SUCCESS) {
                    responseCounter++;
                }
            }
        );

        defaultTestProxy->testVoidPredefinedTypeMethod(v1, v2, stat);
        EXPECT_EQ(stat, CommonAPI::CallStatus::SUCCESS);
    }

    for (unsigned int i = 0; i < 500 && responseCounter < 10; i++) {
        usleep(1000);
    }
    EXPECT_EQ(10, responseCounter);
}
void TestInterfaceStubDefault::testVoidPredefinedTypeMethod(const std::shared_ptr<CommonAPI::ClientId> clientId, uint32_t uint32Value, std::string stringValue) {
    // Call old style methods in default 
    testVoidPredefinedTypeMethod(uint32Value, stringValue);
}