forked from Kistler-Group/sdbus-cpp
Add stress tests for sdbus-c++
This commit is contained in:
@ -51,6 +51,22 @@ set(INTEGRATIONTESTS_SRCS
|
|||||||
${INTEGRATIONTESTS_SOURCE_DIR}/TestingAdaptor.h
|
${INTEGRATIONTESTS_SOURCE_DIR}/TestingAdaptor.h
|
||||||
${INTEGRATIONTESTS_SOURCE_DIR}/TestingProxy.h)
|
${INTEGRATIONTESTS_SOURCE_DIR}/TestingProxy.h)
|
||||||
|
|
||||||
|
set(PERFTESTS_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/perftests)
|
||||||
|
set(STRESSTESTS_CLIENT_SRCS
|
||||||
|
${PERFTESTS_SOURCE_DIR}/client.cpp
|
||||||
|
${PERFTESTS_SOURCE_DIR}/perftest-proxy.h)
|
||||||
|
set(STRESSTESTS_SERVER_SRCS
|
||||||
|
${PERFTESTS_SOURCE_DIR}/server.cpp
|
||||||
|
${PERFTESTS_SOURCE_DIR}/perftest-adaptor.h)
|
||||||
|
|
||||||
|
set(STRESSTESTS_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/stresstests)
|
||||||
|
set(STRESSTESTS_SRCS
|
||||||
|
${STRESSTESTS_SOURCE_DIR}/stresstests.cpp
|
||||||
|
${STRESSTESTS_SOURCE_DIR}/fahrenheit-thermometer-adaptor.h
|
||||||
|
${STRESSTESTS_SOURCE_DIR}/fahrenheit-thermometer-proxy.h
|
||||||
|
${STRESSTESTS_SOURCE_DIR}/concatenator-adaptor.h
|
||||||
|
${STRESSTESTS_SOURCE_DIR}/concatenator-proxy.h)
|
||||||
|
|
||||||
#-------------------------------
|
#-------------------------------
|
||||||
# GENERAL COMPILER CONFIGURATION
|
# GENERAL COMPILER CONFIGURATION
|
||||||
#-------------------------------
|
#-------------------------------
|
||||||
@ -74,12 +90,22 @@ target_link_libraries(libsdbus-c++_integrationtests sdbus-c++ gmock gmock_main)
|
|||||||
# Manual performance tests
|
# Manual performance tests
|
||||||
option(ENABLE_PERFTESTS "Build and install manual performance tests (default OFF)" OFF)
|
option(ENABLE_PERFTESTS "Build and install manual performance tests (default OFF)" OFF)
|
||||||
if(ENABLE_PERFTESTS)
|
if(ENABLE_PERFTESTS)
|
||||||
add_executable(libsdbus-c++_perftests_client perftests/client.cpp perftests/perftest-proxy.h)
|
add_executable(libsdbus-c++_perftests_client ${STRESSTESTS_CLIENT_SRCS})
|
||||||
target_link_libraries(libsdbus-c++_perftests_client sdbus-c++)
|
target_link_libraries(libsdbus-c++_perftests_client sdbus-c++)
|
||||||
add_executable(libsdbus-c++_perftests_server perftests/server.cpp perftests/perftest-adaptor.h)
|
add_executable(libsdbus-c++_perftests_server ${STRESSTESTS_SERVER_SRCS})
|
||||||
target_link_libraries(libsdbus-c++_perftests_server sdbus-c++)
|
target_link_libraries(libsdbus-c++_perftests_server sdbus-c++)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# Manual stress tests
|
||||||
|
option(ENABLE_STRESSTESTS "Build and install manual stress tests (default OFF)" ON)
|
||||||
|
if(ENABLE_STRESSTESTS)
|
||||||
|
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||||
|
find_package(Threads REQUIRED)
|
||||||
|
|
||||||
|
add_executable(sdbus-c++-stress-tests ${STRESSTESTS_SRCS})
|
||||||
|
target_link_libraries(sdbus-c++-stress-tests sdbus-c++ Threads::Threads)
|
||||||
|
endif()
|
||||||
|
|
||||||
#----------------------------------
|
#----------------------------------
|
||||||
# INSTALLATION
|
# INSTALLATION
|
||||||
#----------------------------------
|
#----------------------------------
|
||||||
@ -94,6 +120,11 @@ if(ENABLE_PERFTESTS)
|
|||||||
install(FILES perftests/files/org.sdbuscpp.perftest.conf DESTINATION ${CMAKE_INSTALL_SYSCONFDIR}/dbus-1/system.d)
|
install(FILES perftests/files/org.sdbuscpp.perftest.conf DESTINATION ${CMAKE_INSTALL_SYSCONFDIR}/dbus-1/system.d)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(ENABLE_STRESSTESTS)
|
||||||
|
install(TARGETS sdbus-c++-stress-tests DESTINATION /opt/test/bin)
|
||||||
|
install(FILES perftests/files/org.sdbuscpp.stresstest.conf DESTINATION ${CMAKE_INSTALL_SYSCONFDIR}/dbus-1/system.d)
|
||||||
|
endif()
|
||||||
|
|
||||||
#----------------------------------
|
#----------------------------------
|
||||||
# RUNNING THE TESTS UPON BUILD
|
# RUNNING THE TESTS UPON BUILD
|
||||||
#----------------------------------
|
#----------------------------------
|
||||||
|
39
test/stresstests/celsius-thermometer-adaptor.h
Executable file
39
test/stresstests/celsius-thermometer-adaptor.h
Executable file
@ -0,0 +1,39 @@
|
|||||||
|
|
||||||
|
/*
|
||||||
|
* This file was automatically generated by sdbuscpp-xml2cpp; DO NOT EDIT!
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __sdbuscpp__celsius_thermometer_adaptor_h__adaptor__H__
|
||||||
|
#define __sdbuscpp__celsius_thermometer_adaptor_h__adaptor__H__
|
||||||
|
|
||||||
|
#include <sdbus-c++/sdbus-c++.h>
|
||||||
|
#include <string>
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
|
namespace org {
|
||||||
|
namespace sdbuscpp {
|
||||||
|
namespace stresstest {
|
||||||
|
namespace celsius {
|
||||||
|
|
||||||
|
class thermometer_adaptor
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static constexpr const char* interfaceName = "org.sdbuscpp.stresstest.celsius.thermometer";
|
||||||
|
|
||||||
|
protected:
|
||||||
|
thermometer_adaptor(sdbus::IObject& object)
|
||||||
|
: object_(object)
|
||||||
|
{
|
||||||
|
object_.registerMethod("getCurrentTemperature").onInterface(interfaceName).implementedAs([this](){ return this->getCurrentTemperature(); });
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
virtual uint32_t getCurrentTemperature() = 0;
|
||||||
|
|
||||||
|
private:
|
||||||
|
sdbus::IObject& object_;
|
||||||
|
};
|
||||||
|
|
||||||
|
}}}} // namespaces
|
||||||
|
|
||||||
|
#endif
|
43
test/stresstests/celsius-thermometer-proxy.h
Executable file
43
test/stresstests/celsius-thermometer-proxy.h
Executable file
@ -0,0 +1,43 @@
|
|||||||
|
|
||||||
|
/*
|
||||||
|
* This file was automatically generated by sdbuscpp-xml2cpp; DO NOT EDIT!
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __sdbuscpp__celsius_thermometer_proxy_h__proxy__H__
|
||||||
|
#define __sdbuscpp__celsius_thermometer_proxy_h__proxy__H__
|
||||||
|
|
||||||
|
#include <sdbus-c++/sdbus-c++.h>
|
||||||
|
#include <string>
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
|
namespace org {
|
||||||
|
namespace sdbuscpp {
|
||||||
|
namespace stresstest {
|
||||||
|
namespace celsius {
|
||||||
|
|
||||||
|
class thermometer_proxy
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static constexpr const char* interfaceName = "org.sdbuscpp.stresstest.celsius.thermometer";
|
||||||
|
|
||||||
|
protected:
|
||||||
|
thermometer_proxy(sdbus::IObjectProxy& object)
|
||||||
|
: object_(object)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
uint32_t getCurrentTemperature()
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
object_.callMethod("getCurrentTemperature").onInterface(interfaceName).storeResultsTo(result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
sdbus::IObjectProxy& object_;
|
||||||
|
};
|
||||||
|
|
||||||
|
}}}} // namespaces
|
||||||
|
|
||||||
|
#endif
|
45
test/stresstests/concatenator-adaptor.h
Normal file
45
test/stresstests/concatenator-adaptor.h
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
|
||||||
|
/*
|
||||||
|
* This file was automatically generated by sdbuscpp-xml2cpp; DO NOT EDIT!
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __sdbuscpp__concatenator_adaptor_h__adaptor__H__
|
||||||
|
#define __sdbuscpp__concatenator_adaptor_h__adaptor__H__
|
||||||
|
|
||||||
|
#include <sdbus-c++/sdbus-c++.h>
|
||||||
|
#include <string>
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
|
namespace org {
|
||||||
|
namespace sdbuscpp {
|
||||||
|
namespace stresstest {
|
||||||
|
|
||||||
|
class concatenator_adaptor
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static constexpr const char* interfaceName = "org.sdbuscpp.stresstest.concatenator";
|
||||||
|
|
||||||
|
protected:
|
||||||
|
concatenator_adaptor(sdbus::IObject& object)
|
||||||
|
: object_(object)
|
||||||
|
{
|
||||||
|
object_.registerMethod("concatenate").onInterface(interfaceName).implementedAs([this](sdbus::Result<std::string>&& result, std::map<std::string, sdbus::Variant> params){ this->concatenate(std::move(result), std::move(params)); });
|
||||||
|
object_.registerSignal("concatenatedSignal").onInterface(interfaceName).withParameters<std::string>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
void concatenatedSignal(const std::string& concatenatedString)
|
||||||
|
{
|
||||||
|
object_.emitSignal("concatenatedSignal").onInterface(interfaceName).withArguments(concatenatedString);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
virtual void concatenate(sdbus::Result<std::string>&& result, std::map<std::string, sdbus::Variant> params) = 0;
|
||||||
|
|
||||||
|
private:
|
||||||
|
sdbus::IObject& object_;
|
||||||
|
};
|
||||||
|
|
||||||
|
}}} // namespaces
|
||||||
|
|
||||||
|
#endif
|
45
test/stresstests/concatenator-proxy.h
Normal file
45
test/stresstests/concatenator-proxy.h
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
|
||||||
|
/*
|
||||||
|
* This file was automatically generated by sdbuscpp-xml2cpp; DO NOT EDIT!
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __sdbuscpp__concatenator_proxy_h__proxy__H__
|
||||||
|
#define __sdbuscpp__concatenator_proxy_h__proxy__H__
|
||||||
|
|
||||||
|
#include <sdbus-c++/sdbus-c++.h>
|
||||||
|
#include <string>
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
|
namespace org {
|
||||||
|
namespace sdbuscpp {
|
||||||
|
namespace stresstest {
|
||||||
|
|
||||||
|
class concatenator_proxy
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static constexpr const char* interfaceName = "org.sdbuscpp.stresstest.concatenator";
|
||||||
|
|
||||||
|
protected:
|
||||||
|
concatenator_proxy(sdbus::IObjectProxy& object)
|
||||||
|
: object_(object)
|
||||||
|
{
|
||||||
|
object_.uponSignal("concatenatedSignal").onInterface(interfaceName).call([this](const std::string& concatenatedString){ this->onConcatenatedSignal(concatenatedString); });
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void onConcatenatedSignal(const std::string& concatenatedString) = 0;
|
||||||
|
|
||||||
|
virtual void onConcatenateReply(const std::string& result, const sdbus::Error* error) = 0;
|
||||||
|
|
||||||
|
public:
|
||||||
|
void concatenate(const std::map<std::string, sdbus::Variant>& params)
|
||||||
|
{
|
||||||
|
object_.callMethodAsync("concatenate").onInterface(interfaceName).withArguments(params).uponReplyInvoke([this](const sdbus::Error* error, const std::string& result){ this->onConcatenateReply(result, error); });
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
sdbus::IObjectProxy& object_;
|
||||||
|
};
|
||||||
|
|
||||||
|
}}} // namespaces
|
||||||
|
|
||||||
|
#endif
|
39
test/stresstests/fahrenheit-thermometer-adaptor.h
Normal file
39
test/stresstests/fahrenheit-thermometer-adaptor.h
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
|
||||||
|
/*
|
||||||
|
* This file was automatically generated by sdbuscpp-xml2cpp; DO NOT EDIT!
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __sdbuscpp__fahrenheit_thermometer_adaptor_h__adaptor__H__
|
||||||
|
#define __sdbuscpp__fahrenheit_thermometer_adaptor_h__adaptor__H__
|
||||||
|
|
||||||
|
#include <sdbus-c++/sdbus-c++.h>
|
||||||
|
#include <string>
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
|
namespace org {
|
||||||
|
namespace sdbuscpp {
|
||||||
|
namespace stresstest {
|
||||||
|
namespace fahrenheit {
|
||||||
|
|
||||||
|
class thermometer_adaptor
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static constexpr const char* interfaceName = "org.sdbuscpp.stresstest.fahrenheit.thermometer";
|
||||||
|
|
||||||
|
protected:
|
||||||
|
thermometer_adaptor(sdbus::IObject& object)
|
||||||
|
: object_(object)
|
||||||
|
{
|
||||||
|
object_.registerMethod("getCurrentTemperature").onInterface(interfaceName).implementedAs([this](){ return this->getCurrentTemperature(); });
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
virtual uint32_t getCurrentTemperature() = 0;
|
||||||
|
|
||||||
|
private:
|
||||||
|
sdbus::IObject& object_;
|
||||||
|
};
|
||||||
|
|
||||||
|
}}}} // namespaces
|
||||||
|
|
||||||
|
#endif
|
43
test/stresstests/fahrenheit-thermometer-proxy.h
Normal file
43
test/stresstests/fahrenheit-thermometer-proxy.h
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
|
||||||
|
/*
|
||||||
|
* This file was automatically generated by sdbuscpp-xml2cpp; DO NOT EDIT!
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __sdbuscpp__fahrenheit_thermometer_proxy_h__proxy__H__
|
||||||
|
#define __sdbuscpp__fahrenheit_thermometer_proxy_h__proxy__H__
|
||||||
|
|
||||||
|
#include <sdbus-c++/sdbus-c++.h>
|
||||||
|
#include <string>
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
|
namespace org {
|
||||||
|
namespace sdbuscpp {
|
||||||
|
namespace stresstest {
|
||||||
|
namespace fahrenheit {
|
||||||
|
|
||||||
|
class thermometer_proxy
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static constexpr const char* interfaceName = "org.sdbuscpp.stresstest.fahrenheit.thermometer";
|
||||||
|
|
||||||
|
protected:
|
||||||
|
thermometer_proxy(sdbus::IObjectProxy& object)
|
||||||
|
: object_(object)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
uint32_t getCurrentTemperature()
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
object_.callMethod("getCurrentTemperature").onInterface(interfaceName).storeResultsTo(result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
sdbus::IObjectProxy& object_;
|
||||||
|
};
|
||||||
|
|
||||||
|
}}}} // namespaces
|
||||||
|
|
||||||
|
#endif
|
22
test/stresstests/files/org.sdbuscpp.stresstest.conf
Executable file
22
test/stresstests/files/org.sdbuscpp.stresstest.conf
Executable file
@ -0,0 +1,22 @@
|
|||||||
|
<!-- This configuration file specifies the required security policies
|
||||||
|
for the Kistler DBUS example to run core daemon to work. -->
|
||||||
|
|
||||||
|
<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
|
||||||
|
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
|
||||||
|
<busconfig>
|
||||||
|
|
||||||
|
<!-- ../system.conf have denied everything, so we just punch some holes -->
|
||||||
|
|
||||||
|
<policy context="default">
|
||||||
|
<allow own="org.sdbuscpp.stresstest.service1"/>
|
||||||
|
<allow send_destination="org.sdbuscpp.stresstest.service1"/>
|
||||||
|
<allow send_interface="org.sdbuscpp.stresstest.service1"/>
|
||||||
|
</policy>
|
||||||
|
|
||||||
|
<policy context="default">
|
||||||
|
<allow own="org.sdbuscpp.stresstest.service2"/>
|
||||||
|
<allow send_destination="org.sdbuscpp.stresstest.service2"/>
|
||||||
|
<allow send_interface="org.sdbuscpp.stresstest.service2"/>
|
||||||
|
</policy>
|
||||||
|
|
||||||
|
</busconfig>
|
9
test/stresstests/org.sdbuscpp.stresstest.celsius.thermometer.xml
Executable file
9
test/stresstests/org.sdbuscpp.stresstest.celsius.thermometer.xml
Executable file
@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<node name="/org/sdbuscpp/stresstest/celsius/thermometer">
|
||||||
|
<interface name="org.sdbuscpp.stresstest.celsius.thermometer">
|
||||||
|
<method name="getCurrentTemperature">
|
||||||
|
<arg type="u" name="result" direction="out" />
|
||||||
|
</method>
|
||||||
|
</interface>
|
||||||
|
</node>
|
14
test/stresstests/org.sdbuscpp.stresstest.concatenator.xml
Executable file
14
test/stresstests/org.sdbuscpp.stresstest.concatenator.xml
Executable file
@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<node name="/org/sdbuscpp/stresstest/concatenator">
|
||||||
|
<interface name="org.sdbuscpp.stresstest.concatenator">
|
||||||
|
<method name="concatenate">
|
||||||
|
<arg type="a{sv}" name="params" direction="in" />
|
||||||
|
<arg type="s" name="result" direction="out" />
|
||||||
|
<annotation name="org.freedesktop.DBus.Method.Async" value="clientserver" />
|
||||||
|
</method>
|
||||||
|
<signal name="concatenatedSignal">
|
||||||
|
<arg type="s" name="concatenatedString" />
|
||||||
|
</signal>
|
||||||
|
</interface>
|
||||||
|
</node>
|
9
test/stresstests/org.sdbuscpp.stresstest.fahrenheit.thermometer.xml
Executable file
9
test/stresstests/org.sdbuscpp.stresstest.fahrenheit.thermometer.xml
Executable file
@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<node name="/org/sdbuscpp/stresstest/fahrenheit/thermometer">
|
||||||
|
<interface name="org.sdbuscpp.stresstest.fahrenheit.thermometer">
|
||||||
|
<method name="getCurrentTemperature">
|
||||||
|
<arg type="u" name="result" direction="out" />
|
||||||
|
</method>
|
||||||
|
</interface>
|
||||||
|
</node>
|
322
test/stresstests/stresstests.cpp
Executable file
322
test/stresstests/stresstests.cpp
Executable file
@ -0,0 +1,322 @@
|
|||||||
|
/**
|
||||||
|
* (C) 2019 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||||
|
*
|
||||||
|
* @file stresstests.cpp
|
||||||
|
*
|
||||||
|
* Created on: Jan 25, 2019
|
||||||
|
* Project: sdbus-c++
|
||||||
|
* Description: High-level D-Bus IPC C++ library based on sd-bus
|
||||||
|
*
|
||||||
|
* This file is part of sdbus-c++.
|
||||||
|
*
|
||||||
|
* sdbus-c++ is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 2.1 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* sdbus-c++ is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with sdbus-c++. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "celsius-thermometer-adaptor.h"
|
||||||
|
#include "celsius-thermometer-proxy.h"
|
||||||
|
#include "fahrenheit-thermometer-adaptor.h"
|
||||||
|
#include "fahrenheit-thermometer-proxy.h"
|
||||||
|
#include "concatenator-adaptor.h"
|
||||||
|
#include "concatenator-proxy.h"
|
||||||
|
#include <sdbus-c++/sdbus-c++.h>
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
#include <iostream>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <thread>
|
||||||
|
#include <chrono>
|
||||||
|
#include <cassert>
|
||||||
|
#include <atomic>
|
||||||
|
#include <sstream>
|
||||||
|
#include <mutex>
|
||||||
|
#include <condition_variable>
|
||||||
|
#include <queue>
|
||||||
|
|
||||||
|
using namespace std::chrono_literals;
|
||||||
|
using namespace std::string_literals;
|
||||||
|
|
||||||
|
#define SERVICE_1_BUS_NAME "org.sdbuscpp.stresstest.service1"
|
||||||
|
#define SERVICE_2_BUS_NAME "org.sdbuscpp.stresstest.service2"
|
||||||
|
#define CELSIUS_THERMOMETER_OBJECT_PATH "/org/sdbuscpp/stresstest/celsius/thermometer"
|
||||||
|
#define FAHRENHEIT_THERMOMETER_OBJECT_PATH "/org/sdbuscpp/stresstest/fahrenheit/thermometer"
|
||||||
|
#define CONCATENATOR_OBJECT_PATH "/org/sdbuscpp/stresstest/concatenator"
|
||||||
|
|
||||||
|
class CelsiusThermometerAdaptor : public sdbus::Interfaces<org::sdbuscpp::stresstest::celsius::thermometer_adaptor>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using sdbus::Interfaces<org::sdbuscpp::stresstest::celsius::thermometer_adaptor>::Interfaces;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual uint32_t getCurrentTemperature() override
|
||||||
|
{
|
||||||
|
return m_currentTemperature++;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint32_t m_currentTemperature{};
|
||||||
|
};
|
||||||
|
|
||||||
|
class CelsiusThermometerProxy : public sdbus::ProxyInterfaces<org::sdbuscpp::stresstest::celsius::thermometer_proxy>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using sdbus::ProxyInterfaces<org::sdbuscpp::stresstest::celsius::thermometer_proxy>::ProxyInterfaces;
|
||||||
|
};
|
||||||
|
|
||||||
|
class FahrenheitThermometerAdaptor : public sdbus::Interfaces<org::sdbuscpp::stresstest::fahrenheit::thermometer_adaptor>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FahrenheitThermometerAdaptor(sdbus::IConnection& connection, std::string objectPath)
|
||||||
|
: sdbus::Interfaces<org::sdbuscpp::stresstest::fahrenheit::thermometer_adaptor>(connection, std::move(objectPath))
|
||||||
|
, celsiusProxy_(connection, SERVICE_2_BUS_NAME, CELSIUS_THERMOMETER_OBJECT_PATH)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual uint32_t getCurrentTemperature() override
|
||||||
|
{
|
||||||
|
// In this D-Bus call, make yet another D-Bus call to another service over the same connection
|
||||||
|
return static_cast<uint32_t>(celsiusProxy_.getCurrentTemperature() * 1.8 + 32.);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
CelsiusThermometerProxy celsiusProxy_;
|
||||||
|
};
|
||||||
|
|
||||||
|
class FahrenheitThermometerProxy : public sdbus::ProxyInterfaces<org::sdbuscpp::stresstest::fahrenheit::thermometer_proxy>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using sdbus::ProxyInterfaces<org::sdbuscpp::stresstest::fahrenheit::thermometer_proxy>::ProxyInterfaces;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ConcatenatorAdaptor : public sdbus::Interfaces<org::sdbuscpp::stresstest::concatenator_adaptor>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ConcatenatorAdaptor(sdbus::IConnection& connection, std::string objectPath)
|
||||||
|
: sdbus::Interfaces<org::sdbuscpp::stresstest::concatenator_adaptor>(connection, std::move(objectPath))
|
||||||
|
{
|
||||||
|
unsigned int workers = std::thread::hardware_concurrency();
|
||||||
|
if (workers < 4)
|
||||||
|
workers = 4;
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < workers; ++i)
|
||||||
|
workers_.emplace_back([this]()
|
||||||
|
{
|
||||||
|
//std::cout << "Created worker thread 0x" << std::hex << std::this_thread::get_id() << std::dec << std::endl;
|
||||||
|
|
||||||
|
while(!exit_)
|
||||||
|
{
|
||||||
|
// Pop a work item from the queue
|
||||||
|
std::unique_lock<std::mutex> lock(mutex_);
|
||||||
|
cond_.wait(lock, [this]{return !requests_.empty() || exit_;});
|
||||||
|
if (exit_)
|
||||||
|
break;
|
||||||
|
auto request = std::move(requests_.front());
|
||||||
|
requests_.pop();
|
||||||
|
lock.unlock();
|
||||||
|
|
||||||
|
// Do concatenation work, return results and fire signal
|
||||||
|
auto aString = request.input.at("key1").get<std::string>();
|
||||||
|
auto aNumber = request.input.at("key2").get<uint32_t>();
|
||||||
|
auto resultString = aString + " " + std::to_string(aNumber);
|
||||||
|
|
||||||
|
request.result.returnResults(resultString);
|
||||||
|
|
||||||
|
concatenatedSignal(resultString);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
~ConcatenatorAdaptor()
|
||||||
|
{
|
||||||
|
exit_ = true;
|
||||||
|
cond_.notify_all();
|
||||||
|
for (auto& worker : workers_)
|
||||||
|
worker.join();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void concatenate(sdbus::Result<std::string>&& result, std::map<std::string, sdbus::Variant> params) override
|
||||||
|
{
|
||||||
|
std::unique_lock<std::mutex> lock(mutex_);
|
||||||
|
requests_.push(WorkItem{std::move(params), std::move(result)});
|
||||||
|
lock.unlock();
|
||||||
|
cond_.notify_one();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct WorkItem
|
||||||
|
{
|
||||||
|
std::map<std::string, sdbus::Variant> input;
|
||||||
|
sdbus::Result<std::string> result;
|
||||||
|
};
|
||||||
|
std::mutex mutex_;
|
||||||
|
std::condition_variable cond_;
|
||||||
|
std::queue<WorkItem> requests_;
|
||||||
|
std::vector<std::thread> workers_;
|
||||||
|
std::atomic<bool> exit_{};
|
||||||
|
};
|
||||||
|
|
||||||
|
class ConcatenatorProxy : public sdbus::ProxyInterfaces<org::sdbuscpp::stresstest::concatenator_proxy>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using sdbus::ProxyInterfaces<org::sdbuscpp::stresstest::concatenator_proxy>::ProxyInterfaces;
|
||||||
|
|
||||||
|
private:
|
||||||
|
virtual void onConcatenateReply(const std::string& result, const sdbus::Error* error) override
|
||||||
|
{
|
||||||
|
assert(error == nullptr);
|
||||||
|
|
||||||
|
std::stringstream str(result);
|
||||||
|
std::string aString;
|
||||||
|
str >> aString;
|
||||||
|
assert(aString == "sdbus-c++-stress-tests");
|
||||||
|
|
||||||
|
uint32_t aNumber;
|
||||||
|
str >> aNumber;
|
||||||
|
assert(aNumber >= 0);
|
||||||
|
|
||||||
|
++repliesReceived_;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void onConcatenatedSignal(const std::string& concatenatedString) override
|
||||||
|
{
|
||||||
|
std::stringstream str(concatenatedString);
|
||||||
|
std::string aString;
|
||||||
|
str >> aString;
|
||||||
|
assert(aString == "sdbus-c++-stress-tests");
|
||||||
|
|
||||||
|
uint32_t aNumber;
|
||||||
|
str >> aNumber;
|
||||||
|
assert(aNumber >= 0);
|
||||||
|
|
||||||
|
++signalsReceived_;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
std::atomic<uint32_t> repliesReceived_;
|
||||||
|
std::atomic<uint32_t> signalsReceived_;
|
||||||
|
};
|
||||||
|
|
||||||
|
//-----------------------------------------
|
||||||
|
int main(int /*argc*/, char */*argv*/[])
|
||||||
|
{
|
||||||
|
auto service2Connection = sdbus::createSystemBusConnection(SERVICE_2_BUS_NAME);
|
||||||
|
std::thread service2Thread([&con = *service2Connection]()
|
||||||
|
{
|
||||||
|
CelsiusThermometerAdaptor thermometer(con, CELSIUS_THERMOMETER_OBJECT_PATH);
|
||||||
|
con.enterProcessingLoop();
|
||||||
|
});
|
||||||
|
|
||||||
|
auto service1Connection = sdbus::createSystemBusConnection(SERVICE_1_BUS_NAME);
|
||||||
|
std::thread service1Thread([&con = *service1Connection]()
|
||||||
|
{
|
||||||
|
ConcatenatorAdaptor concatenator(con, CONCATENATOR_OBJECT_PATH);
|
||||||
|
FahrenheitThermometerAdaptor thermometer(con, FAHRENHEIT_THERMOMETER_OBJECT_PATH);
|
||||||
|
con.enterProcessingLoop();
|
||||||
|
});
|
||||||
|
|
||||||
|
std::this_thread::sleep_for(100ms);
|
||||||
|
|
||||||
|
std::atomic<uint32_t> concatenationCallsMade{0};
|
||||||
|
std::atomic<uint32_t> concatenationRepliesReceived{0};
|
||||||
|
std::atomic<uint32_t> concatenationSignalsReceived{0};
|
||||||
|
std::atomic<uint32_t> thermometerCallsMade{0};
|
||||||
|
|
||||||
|
auto clientConnection = sdbus::createSystemBusConnection();
|
||||||
|
std::thread clientThread([&, &con = *clientConnection]()
|
||||||
|
{
|
||||||
|
std::atomic<bool> stopClients{false};
|
||||||
|
|
||||||
|
std::thread concatenatorThread([&]()
|
||||||
|
{
|
||||||
|
ConcatenatorProxy concatenator(con, SERVICE_1_BUS_NAME, CONCATENATOR_OBJECT_PATH);
|
||||||
|
|
||||||
|
uint32_t localCounter{};
|
||||||
|
|
||||||
|
// Issue async concatenate calls densely one after another
|
||||||
|
while (!stopClients)
|
||||||
|
{
|
||||||
|
std::map<std::string, sdbus::Variant> param;
|
||||||
|
param["key1"] = "sdbus-c++-stress-tests";
|
||||||
|
param["key2"] = localCounter++;
|
||||||
|
|
||||||
|
concatenator.concatenate(param);
|
||||||
|
|
||||||
|
if ((localCounter % 10) == 0)
|
||||||
|
{
|
||||||
|
// Make sure the system is catching up with our async requests,
|
||||||
|
// otherwise sleep a bit to slow down flooding the server.
|
||||||
|
assert(localCounter >= concatenator.repliesReceived_);
|
||||||
|
while ((localCounter - concatenator.repliesReceived_) > 20 && !stopClients)
|
||||||
|
std::this_thread::sleep_for(2ms);
|
||||||
|
|
||||||
|
// Update statistics
|
||||||
|
concatenationCallsMade = localCounter;
|
||||||
|
concatenationRepliesReceived = (uint32_t)concatenator.repliesReceived_;
|
||||||
|
concatenationSignalsReceived = (uint32_t)concatenator.signalsReceived_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
std::thread thermometerThread([&]()
|
||||||
|
{
|
||||||
|
FahrenheitThermometerProxy thermometer(con, SERVICE_1_BUS_NAME, FAHRENHEIT_THERMOMETER_OBJECT_PATH);
|
||||||
|
uint32_t localCounter{};
|
||||||
|
uint32_t previousTemperature{};
|
||||||
|
|
||||||
|
while (!stopClients)
|
||||||
|
{
|
||||||
|
localCounter++;
|
||||||
|
auto temperature = thermometer.getCurrentTemperature();
|
||||||
|
assert(temperature >= previousTemperature); // The temperature shall rise continually
|
||||||
|
previousTemperature = temperature;
|
||||||
|
std::this_thread::sleep_for(5ms);
|
||||||
|
|
||||||
|
if ((localCounter % 10) == 0)
|
||||||
|
thermometerCallsMade = localCounter;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
con.enterProcessingLoop();
|
||||||
|
|
||||||
|
stopClients = true;
|
||||||
|
concatenatorThread.join();
|
||||||
|
thermometerThread.join();
|
||||||
|
});
|
||||||
|
|
||||||
|
std::atomic<bool> exitLogger{};
|
||||||
|
std::thread loggerThread([&]()
|
||||||
|
{
|
||||||
|
while (!exitLogger)
|
||||||
|
{
|
||||||
|
std::this_thread::sleep_for(1s);
|
||||||
|
|
||||||
|
std::cout << "Made " << concatenationCallsMade << " concatenation calls, received " << concatenationRepliesReceived << " replies and " << concatenationSignalsReceived << " signals so far." << std::endl;
|
||||||
|
std::cout << "Made " << thermometerCallsMade << " thermometer calls so far." << std::endl << std::endl;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
getchar();
|
||||||
|
|
||||||
|
exitLogger = true;
|
||||||
|
loggerThread.join();
|
||||||
|
clientConnection->leaveProcessingLoop();
|
||||||
|
clientThread.join();
|
||||||
|
service1Connection->leaveProcessingLoop();
|
||||||
|
service1Thread.join();
|
||||||
|
service2Connection->leaveProcessingLoop();
|
||||||
|
service2Thread.join();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
Reference in New Issue
Block a user