summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArnaud Fietzke <fietzke@itestra.de>2013-11-11 14:22:29 +0100
committerPhilip Rauwolf <rauwolf@itestra.de>2013-12-16 10:22:57 +0100
commita5f3bfd678f780cecfc496d68ae7100594ce7cb1 (patch)
tree2694dfea24784fed212d53d4b610cf65bd25463f
parent4218ceee3afcb1db298faaa1ede58c2be7563b48 (diff)
downloadgenivi-common-api-dbus-runtime-a5f3bfd678f780cecfc496d68ae7100594ce7cb1.tar.gz
LoadTest using async calls
Change-Id: Ib58ab810586bd13261da4cea2d30461f34bdf667
-rw-r--r--Makefile.am10
-rw-r--r--src/test/DBusLoadTest.cpp304
2 files changed, 313 insertions, 1 deletions
diff --git a/Makefile.am b/Makefile.am
index 0edb9fa..f2175f4 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -217,7 +217,8 @@ check_PROGRAMS = \
DBusServicePublisherTest \
DBusClientIdTest \
DBusSelectiveBroadcastTest \
- DBusPolymorphicTest
+ DBusPolymorphicTest \
+ DBusLoadTest
noinst_PROGRAMS = ${check_PROGRAMS}
TESTS = ${check_PROGRAMS}
@@ -393,6 +394,13 @@ DBusPolymorphicTest_CPPFLAGS = ${AM_CPPFLAGS} ${GTEST_CPPFLAGS}
DBusPolymorphicTest_CXXFLAGS = ${GTEST_CXXFLAGS}
DBusPolymorphicTest_LDADD = ${LDADD_FOR_GTEST}
+DBusLoadTest_SOURCES = \
+ src/test/DBusLoadTest.cpp \
+ ${TestInterfaceDBusSources}
+DBusLoadTest_CPPFLAGS = ${AM_CPPFLAGS} ${GTEST_CPPFLAGS}
+DBusLoadTest_CXXFLAGS = ${GTEST_CXXFLAGS}
+DBusLoadTest_LDADD = ${LDADD_FOR_GTEST}
+
endif
diff --git a/src/test/DBusLoadTest.cpp b/src/test/DBusLoadTest.cpp
new file mode 100644
index 0000000..8dc3707
--- /dev/null
+++ b/src/test/DBusLoadTest.cpp
@@ -0,0 +1,304 @@
+/* Copyright (C) 2013 BMW Group
+ * Author: Manfred Bathelt (manfred.bathelt@bmw.de)
+ * Author: Juergen Gehring (juergen.gehring@bmw.de)
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include <gtest/gtest.h>
+
+#include <cassert>
+#include <cstdint>
+#include <iostream>
+#include <functional>
+#include <memory>
+#include <stdint.h>
+#include <string>
+#include <array>
+#include <utility>
+#include <tuple>
+#include <type_traits>
+#include <future>
+
+#include <CommonAPI/CommonAPI.h>
+
+#define COMMONAPI_INTERNAL_COMPILATION
+
+#include <CommonAPI/DBus/DBusConnection.h>
+#include <CommonAPI/DBus/DBusProxy.h>
+#include <CommonAPI/DBus/DBusRuntime.h>
+
+#include "commonapi/tests/PredefinedTypeCollection.h"
+#include "commonapi/tests/DerivedTypeCollection.h"
+#include "commonapi/tests/TestInterfaceProxy.h"
+#include "commonapi/tests/TestInterfaceStubDefault.h"
+
+#include "commonapi/tests/TestInterfaceDBusProxy.h"
+
+class TestInterfaceStubFinal: public commonapi::tests::TestInterfaceStubDefault {
+public:
+ void testPredefinedTypeMethod(const std::shared_ptr<CommonAPI::ClientId> clientId,
+ uint32_t uint32InValue,
+ std::string stringInValue,
+ uint32_t& uint32OutValue,
+ std::string& stringOutValue) {
+ uint32OutValue = uint32InValue;
+ stringOutValue = stringInValue;
+ }
+};
+
+class DBusLoadTest: public ::testing::Test {
+protected:
+ virtual void SetUp() {
+ runtime_ = CommonAPI::Runtime::load();
+ ASSERT_TRUE((bool )runtime_);
+ CommonAPI::DBus::DBusRuntime* dbusRuntime = dynamic_cast<CommonAPI::DBus::DBusRuntime*>(&(*runtime_));
+ ASSERT_TRUE(dbusRuntime != NULL);
+
+ proxyFactory_ = runtime_->createFactory();
+ ASSERT_TRUE((bool )proxyFactory_);
+ stubFactory_ = runtime_->createFactory();
+ ASSERT_TRUE((bool )stubFactory_);
+
+ servicePublisher_ = runtime_->getServicePublisher();
+ ASSERT_TRUE((bool )servicePublisher_);
+
+ callSucceeded_.resize(numCallsPerProxy_ * numProxies_);
+ std::fill(callSucceeded_.begin(), callSucceeded_.end(), false);
+ }
+
+ virtual void TearDown() {
+ sleep(3);
+ }
+
+public:
+ void TestPredefinedTypeMethodAsyncCallback(
+ const uint32_t callId,
+ const uint32_t in1,
+ const std::string in2,
+ const CommonAPI::CallStatus& callStatus,
+ const uint32_t& out1,
+ const std::string& out2) {
+ EXPECT_EQ(callStatus, CommonAPI::CallStatus::SUCCESS);
+ EXPECT_EQ(out1, in1);
+ EXPECT_EQ(out2, in2);
+ if (callStatus == CommonAPI::CallStatus::SUCCESS) {
+ ASSERT_FALSE(callSucceeded_[callId]);
+ callSucceeded_[callId] = true;
+ }
+ }
+
+ std::shared_ptr<CommonAPI::Runtime> runtime_;
+ std::shared_ptr<CommonAPI::Factory> proxyFactory_;
+ std::shared_ptr<CommonAPI::Factory> stubFactory_;
+ std::shared_ptr<CommonAPI::ServicePublisher> servicePublisher_;
+ std::vector<bool> callSucceeded_;
+
+ static const std::string serviceAddress_;
+ static const uint32_t numCallsPerProxy_;
+ static const uint32_t numProxies_;
+};
+
+const std::string DBusLoadTest::serviceAddress_ =
+ "local:CommonAPI.DBus.tests.DBusProxyTestInterface:CommonAPI.DBus.tests.DBusProxyTestService";
+const uint32_t DBusLoadTest::numCallsPerProxy_ = 100;
+const uint32_t DBusLoadTest::numProxies_ = 100;
+
+// Multiple proxies in one thread, one stub
+TEST_F(DBusLoadTest, SingleClientMultipleProxiesSingleStubCallsSucceed) {
+ std::array<std::shared_ptr<commonapi::tests::TestInterfaceProxyBase>, numProxies_> testProxies;
+
+ for (auto i = 0; i < numProxies_; i++) {
+ testProxies[i] = proxyFactory_->buildProxy < commonapi::tests::TestInterfaceProxy > (serviceAddress_);
+ ASSERT_TRUE((bool )testProxies[i]);
+ }
+
+ auto stub = std::make_shared<TestInterfaceStubFinal>();
+ bool serviceRegistered = servicePublisher_->registerService(stub, serviceAddress_, stubFactory_);
+ for (auto i = 0; !serviceRegistered && i < 100; ++i) {
+ serviceRegistered = servicePublisher_->registerService(stub, serviceAddress_, stubFactory_);
+ usleep(10000);
+ }
+ ASSERT_TRUE(serviceRegistered);
+
+ bool allProxiesAvailable = false;
+ for (auto i = 0; !allProxiesAvailable && i < 100; ++i) {
+ allProxiesAvailable = true;
+ for (auto j = 0; j < numProxies_; ++j) {
+ allProxiesAvailable = allProxiesAvailable && testProxies[j]->isAvailable();
+ }
+ if (!allProxiesAvailable)
+ usleep(10000);
+ }
+ ASSERT_TRUE(allProxiesAvailable);
+
+ uint32_t callId = 0;
+ for (auto i = 0; i < numCallsPerProxy_; i++) {
+ for (auto j = 0; j < numProxies_; j++) {
+ uint32_t in1 = i;
+ std::string in2 = "string" + std::to_string(i) + "_" + std::to_string(j);
+ testProxies[j]->testPredefinedTypeMethodAsync(
+ in1,
+ in2,
+ std::bind(
+ &DBusLoadTest::TestPredefinedTypeMethodAsyncCallback,
+ this,
+ callId++,
+ in1,
+ in2,
+ std::placeholders::_1,
+ std::placeholders::_2,
+ std::placeholders::_3));
+ }
+ }
+
+ bool allCallsSucceeded = false;
+ for (auto i = 0; !allCallsSucceeded && i < 100; ++i) {
+ allCallsSucceeded = std::all_of(callSucceeded_.cbegin(), callSucceeded_.cend(), [](int b){ return b; });
+ if (!allCallsSucceeded)
+ usleep(100000);
+ }
+ ASSERT_TRUE(allCallsSucceeded);
+
+ servicePublisher_->unregisterService(serviceAddress_);
+}
+
+// Multiple proxies in separate threads, one stub
+TEST_F(DBusLoadTest, MultipleClientsSingleStubCallsSucceed) {
+ std::array<std::shared_ptr<CommonAPI::Factory>, numProxies_> testProxyFactories;
+ std::array<std::shared_ptr<commonapi::tests::TestInterfaceProxyBase>, numProxies_> testProxies;
+
+ for (auto i = 0; i < numProxies_; i++) {
+ testProxyFactories[i] = runtime_->createFactory();
+ ASSERT_TRUE((bool )testProxyFactories[i]);
+ testProxies[i] = testProxyFactories[i]->buildProxy < commonapi::tests::TestInterfaceProxy > (serviceAddress_);
+ ASSERT_TRUE((bool )testProxies[i]);
+ }
+
+ auto stub = std::make_shared<TestInterfaceStubFinal>();
+ bool serviceRegistered = false;
+ for (auto i = 0; !serviceRegistered && i < 100; ++i) {
+ serviceRegistered = servicePublisher_->registerService(stub, serviceAddress_, stubFactory_);
+ if(!serviceRegistered)
+ usleep(10000);
+ }
+ ASSERT_TRUE(serviceRegistered);
+
+ bool allProxiesAvailable = false;
+ for (auto i = 0; !allProxiesAvailable && i < 100; ++i) {
+ allProxiesAvailable = true;
+ for (auto j = 0; j < numProxies_; ++j) {
+ allProxiesAvailable = allProxiesAvailable && testProxies[j]->isAvailable();
+ }
+ if (!allProxiesAvailable)
+ usleep(10000);
+ }
+ ASSERT_TRUE(allProxiesAvailable);
+
+ uint32_t callId = 0;
+ for (auto i = 0; i < numCallsPerProxy_; i++) {
+ for (auto j = 0; j < numProxies_; j++) {
+ uint32_t in1 = i;
+ std::string in2 = "string" + std::to_string(i) + "_" + std::to_string(j);
+ testProxies[j]->testPredefinedTypeMethodAsync(
+ in1,
+ in2,
+ std::bind(
+ &DBusLoadTest::TestPredefinedTypeMethodAsyncCallback,
+ this,
+ callId++,
+ in1,
+ in2,
+ std::placeholders::_1,
+ std::placeholders::_2,
+ std::placeholders::_3));
+ }
+ }
+
+ bool allCallsSucceeded = false;
+ for (auto i = 0; !allCallsSucceeded && i < 100; ++i) {
+ allCallsSucceeded = std::all_of(callSucceeded_.cbegin(), callSucceeded_.cend(), [](int b){ return b; });
+ if (!allCallsSucceeded)
+ usleep(100000);
+ }
+ ASSERT_TRUE(allCallsSucceeded);
+
+ servicePublisher_->unregisterService(serviceAddress_);
+}
+
+// Multiple proxies in separate threads, multiple stubs in separate threads
+TEST_F(DBusLoadTest, MultipleClientsMultipleServersCallsSucceed) {
+ std::array<std::shared_ptr<CommonAPI::Factory>, numProxies_> testProxyFactories;
+ std::array<std::shared_ptr<CommonAPI::Factory>, numProxies_> testStubFactories;
+ std::array<std::shared_ptr<commonapi::tests::TestInterfaceProxyBase>, numProxies_> testProxies;
+ std::array<std::shared_ptr<commonapi::tests::TestInterfaceStub>, numProxies_> testStubs;
+
+ for (auto i = 0; i < numProxies_; i++) {
+ testProxyFactories[i] = runtime_->createFactory();
+ ASSERT_TRUE((bool )testProxyFactories[i]);
+ testProxies[i] = testProxyFactories[i]->buildProxy < commonapi::tests::TestInterfaceProxy > (serviceAddress_+std::to_string(i));
+ ASSERT_TRUE((bool )testProxies[i]);
+ }
+
+ for (auto i = 0; i < numProxies_; i++) {
+ testStubFactories[i] = runtime_->createFactory();
+ ASSERT_TRUE((bool )testStubFactories[i]);
+ testStubs[i] = std::make_shared<TestInterfaceStubFinal>();
+ ASSERT_TRUE((bool )testStubs[i]);
+ bool serviceRegistered = false;
+ for (auto j = 0; !serviceRegistered && j < 100; ++j) {
+ serviceRegistered = servicePublisher_->registerService(testStubs[i], serviceAddress_+std::to_string(i), testStubFactories[i]);
+ if(!serviceRegistered)
+ usleep(10000);
+ }
+ ASSERT_TRUE(serviceRegistered);
+ }
+
+ bool allProxiesAvailable = false;
+ for (auto i = 0; !allProxiesAvailable && i < 100; ++i) {
+ allProxiesAvailable = true;
+ for (auto j = 0; j < numProxies_; ++j) {
+ allProxiesAvailable = allProxiesAvailable && testProxies[j]->isAvailable();
+ }
+ if (!allProxiesAvailable)
+ sleep(1);
+ }
+ ASSERT_TRUE(allProxiesAvailable);
+
+ uint32_t callId = 0;
+ for (auto i = 0; i < numCallsPerProxy_; i++) {
+ for (auto j = 0; j < numProxies_; j++) {
+ uint32_t in1 = i;
+ std::string in2 = "string" + std::to_string(i) + "_" + std::to_string(j);
+ testProxies[j]->testPredefinedTypeMethodAsync(
+ in1,
+ in2,
+ std::bind(
+ &DBusLoadTest::TestPredefinedTypeMethodAsyncCallback,
+ this,
+ callId++,
+ in1,
+ in2,
+ std::placeholders::_1,
+ std::placeholders::_2,
+ std::placeholders::_3));
+ }
+ }
+
+ bool allCallsSucceeded = false;
+ for (auto i = 0; !allCallsSucceeded && i < 100; ++i) {
+ allCallsSucceeded = std::all_of(callSucceeded_.cbegin(), callSucceeded_.cend(), [](int b){ return b; });
+ if (!allCallsSucceeded)
+ usleep(100000);
+ }
+ ASSERT_TRUE(allCallsSucceeded);
+
+ for (auto i = 0; i < numProxies_; i++) {
+ servicePublisher_->unregisterService(serviceAddress_+std::to_string(i));
+ }
+}
+
+int main(int argc, char** argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}