Introduce sdbus-c++ v0.2.3

This commit is contained in:
Stanislav Angelovic
2017-11-27 14:13:55 +01:00
parent 32db1c22e3
commit 35f725a053
69 changed files with 9223 additions and 2 deletions
+68
View File
@@ -0,0 +1,68 @@
# Defines how to build and install libsdbus-c++ tests
AUTOMAKE_OPTIONS = subdir-objects
# Target dirs for test binaries, scripts and files
testbindir = /opt/test/bin
dbusconfdir = $(sysconfdir)/dbus-1/system.d
# ENABLE_TESTS is defined by configure when user enables tests during configuration
if ENABLE_TESTS
testbin_PROGRAMS = libsdbus-c++_unittests libsdbus-c++_integrationtests
dbusconf_DATA = integrationtests/files/libsdbus-cpp-test.conf
endif
# Setting per-file flags
AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/src
AM_CXXFLAGS = @libsdbus_cpp_CFLAGS@ @SYSTEMD_CFLAGS@ -W -Wall -Werror -pedantic -pipe -std=c++14
AM_LDFLAGS = @libsdbus_cpp_LIBS@ @SYSTEMD_LIBS@
CLEANFILES = *~ *.lo *.la
MOSTLYCLEANFILES = *.o
TESTS =
# Configuration for libsdbus-c++_unittests
libsdbus_c___unittests_SOURCES = \
unittests/libsdbus-c++_unittests.cpp \
unittests/TypeTraits_test.cpp \
unittests/Types_test.cpp \
unittests/Message_test.cpp
libsdbus_c___unittests_LDFLAGS = -L$(top_builddir)/src
libsdbus_c___unittests_LDADD = \
-lsdbus-c++ \
@libsdbus_cpp_LIBS@ \
@SYSTEMD_LIBS@ \
-lgmock
TESTS += libsdbus-c++_unittests
# Configuration for libsdbus-c++_integrationtests
libsdbus_c___integrationtests_SOURCES = \
integrationtests/libsdbus-c++_integrationtests.cpp \
integrationtests/Connection_test.cpp \
integrationtests/AdaptorAndProxy_test.cpp
libsdbus_c___integrationtests_LDFLAGS = -L$(top_builddir)/src
libsdbus_c___integrationtests_LDADD = \
-lsdbus-c++ \
@libsdbus_cpp_LIBS@ \
@SYSTEMD_LIBS@ \
-lgmock \
-lpthread
TESTS += libsdbus-c++_integrationtests
check_PROGRAMS = libsdbus-c++_unittests libsdbus-c++_integrationtests
DISTCLEANFILES = Makefile Makefile.in
# Post-build action: executing tests from the IDE
if ENABLE_TESTS
all-local: libsdbus-c++_unittests libsdbus-c++_integrationtests
if [ "${UNIT_TESTS_RUNNER}" ]; then "${UNIT_TESTS_RUNNER}" --deviceip="${TEST_DEVICE_IP}" --testbin=.libs/libsdbus-c++_unittests; fi; exit 0
if [ "${UNIT_TESTS_RUNNER}" ]; then "${UNIT_TESTS_RUNNER}" --deviceip="${TEST_DEVICE_IP}" --testbin=.libs/libsdbus-c++_integrationtests; fi; exit 0
endif
@@ -0,0 +1,289 @@
/**
* (C) 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
*
* @file AdaptorAndProxy_test.cpp
*
* Created on: Jan 2, 2017
* 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/>.
*/
// Own
#include "Connection.h"
#include "TestingAdaptor.h"
#include "TestingProxy.h"
// sdbus
#include "sdbus-c++/sdbus-c++.h"
// gmock
#include <gtest/gtest.h>
#include <gmock/gmock.h>
// STL
#include <string>
#include <thread>
#include <tuple>
using ::testing::Eq;
using ::testing::Gt;
namespace
{
class AdaptorAndProxyFixture : public ::testing::Test
{
public:
static void SetUpTestCase()
{
m_connection.requestName(INTERFACE_NAME);
m_connection.enterProcessingLoopAsync();
}
static void TearDownTestCase()
{
m_connection.leaveProcessingLoop();
m_connection.releaseName(INTERFACE_NAME);
}
private:
void SetUp() override
{
m_adaptor = std::make_unique<TestingAdaptor>(m_connection);
m_proxy = std::make_unique<TestingProxy>(INTERFACE_NAME, OBJECT_PATH);
usleep(50000); // Give time for the proxy to start listening to signals
}
void TearDown() override
{
m_proxy.reset();
m_adaptor.reset();
}
public:
static sdbus::internal::Connection m_connection;
std::unique_ptr<TestingAdaptor> m_adaptor;
std::unique_ptr<TestingProxy> m_proxy;
};
sdbus::internal::Connection AdaptorAndProxyFixture::m_connection{sdbus::internal::Connection::BusType::eSystem};
}
/*-------------------------------------*/
/* -- TEST CASES -- */
/*-------------------------------------*/
TEST(AdaptorAndProxy, CanBeConstructedSuccesfully)
{
auto connection = sdbus::createConnection();
connection->requestName(INTERFACE_NAME);
ASSERT_NO_THROW(TestingAdaptor adaptor(*connection));
ASSERT_NO_THROW(TestingProxy proxy(INTERFACE_NAME, OBJECT_PATH));
connection->releaseName(INTERFACE_NAME);
}
// Methods
using SdbusTestObject = AdaptorAndProxyFixture;
TEST_F(SdbusTestObject, CallsEmptyMethodSuccesfully)
{
ASSERT_NO_THROW(m_proxy->noArgNoReturn());
}
TEST_F(SdbusTestObject, CallsMethodsWithBaseTypesSuccesfully)
{
auto resInt = m_proxy->getInt();
ASSERT_THAT(resInt, Eq(INT32_VALUE));
auto multiplyRes = m_proxy->multiply(INT64_VALUE, DOUBLE_VALUE);
ASSERT_THAT(multiplyRes, Eq(INT64_VALUE * DOUBLE_VALUE));
}
TEST_F(SdbusTestObject, CallsMethodsWithTuplesSuccesfully)
{
auto resTuple = m_proxy->getTuple();
ASSERT_THAT(std::get<0>(resTuple), Eq(UINT32_VALUE));
ASSERT_THAT(std::get<1>(resTuple), Eq(STRING_VALUE));
}
TEST_F(SdbusTestObject, CallsMethodsWithStructSuccesfully)
{
sdbus::Struct<uint8_t, int16_t, double, std::string, std::vector<int16_t>> a{};
auto vectorRes = m_proxy->getInts16FromStruct(a);
ASSERT_THAT(vectorRes, Eq(std::vector<int16_t>{0})); // because second item is by default initialized to 0
sdbus::Struct<uint8_t, int16_t, double, std::string, std::vector<int16_t>> b{
UINT8_VALUE, INT16_VALUE, DOUBLE_VALUE, STRING_VALUE, {INT16_VALUE, -INT16_VALUE}
};
vectorRes = m_proxy->getInts16FromStruct(b);
ASSERT_THAT(vectorRes, Eq(std::vector<int16_t>{INT16_VALUE, INT16_VALUE, -INT16_VALUE}));
}
TEST_F(SdbusTestObject, CallsMethodWithVariantSuccesfully)
{
sdbus::Variant v{DOUBLE_VALUE};
auto variantRes = m_proxy->processVariant(v);
ASSERT_THAT(variantRes.get<int32_t>(), Eq(static_cast<int32_t>(DOUBLE_VALUE)));
}
TEST_F(SdbusTestObject, CallsMethodWithStructVariantsAndGetMapSuccesfully)
{
std::vector<int32_t> x{-2, 0, 2};
sdbus::Struct<sdbus::Variant, sdbus::Variant> y{false, true};
auto mapOfVariants = m_proxy->getMapOfVariants(x, y);
decltype(mapOfVariants) res{{-2, false}, {0, false}, {2, true}};
ASSERT_THAT(mapOfVariants[-2].get<bool>(), Eq(res[-2].get<bool>()));
ASSERT_THAT(mapOfVariants[0].get<bool>(), Eq(res[0].get<bool>()));
ASSERT_THAT(mapOfVariants[2].get<bool>(), Eq(res[2].get<bool>()));
}
TEST_F(SdbusTestObject, CallsMethodWithStructInStructSuccesfully)
{
auto val = m_proxy->getStructInStruct();
ASSERT_THAT(val.get<0>(), Eq(STRING_VALUE));
ASSERT_THAT(std::get<0>(std::get<1>(val))[INT32_VALUE], Eq(INT32_VALUE));
}
TEST_F(SdbusTestObject, CallsMethodWithTwoStructsSuccesfully)
{
auto val = m_proxy->sumStructItems({1, 2}, {3, 4});
ASSERT_THAT(val, Eq(1 + 2 + 3 + 4));
}
TEST_F(SdbusTestObject, CallsMethodWithTwoVectorsSuccesfully)
{
auto val = m_proxy->sumVectorItems({1, 7}, {2, 3});
ASSERT_THAT(val, Eq(1 + 7 + 2 + 3));
}
TEST_F(SdbusTestObject, CallsMethodWithSignatureSuccesfully)
{
auto resSignature = m_proxy->getSignature();
ASSERT_THAT(resSignature, Eq(SIGNATURE_VALUE));
}
TEST_F(SdbusTestObject, CallsMethodWithObjectPathSuccesfully)
{
auto resObjectPath = m_proxy->getObjectPath();
ASSERT_THAT(resObjectPath, Eq(OBJECT_PATH_VALUE));
}
TEST_F(SdbusTestObject, CallsMethodWithComplexTypeSuccesfully)
{
auto resComplex = m_proxy->getComplex();
ASSERT_THAT(resComplex.count(0), Eq(1));
}
TEST_F(SdbusTestObject, FailsCallingNonexistentMethod)
{
ASSERT_THROW(m_proxy->callNonexistentMethod(), sdbus::Error);
}
TEST_F(SdbusTestObject, FailsCallingMethodOnNonexistentInterface)
{
ASSERT_THROW(m_proxy->callMethodOnNonexistentInterface(), sdbus::Error);
}
TEST_F(SdbusTestObject, FailsCallingMethodOnNonexistentDestination)
{
TestingProxy proxy("wrongDestination", OBJECT_PATH);
ASSERT_THROW(proxy.getInt(), sdbus::Error);
}
TEST_F(SdbusTestObject, FailsCallingMethodOnNonexistentObject)
{
TestingProxy proxy(INTERFACE_NAME, "/wrong/path");
ASSERT_THROW(proxy.getInt(), sdbus::Error);
}
// Signals
TEST_F(SdbusTestObject, EmitsSimpleSignalSuccesfully)
{
auto count = m_proxy->getSimpleCallCount();
m_adaptor->simpleSignal();
usleep(10000);
ASSERT_THAT(m_proxy->getSimpleCallCount(), Eq(count + 1));
}
TEST_F(SdbusTestObject, EmitsSignalWithMapSuccesfully)
{
m_adaptor->signalWithMap({{0, "zero"}, {1, "one"}});
usleep(10000);
auto map = m_proxy->getMap();
ASSERT_THAT(map[0], Eq("zero"));
ASSERT_THAT(map[1], Eq("one"));
}
TEST_F(SdbusTestObject, EmitsSignalWithVariantSuccesfully)
{
double d = 3.14;
m_adaptor->signalWithVariant(3.14);
usleep(10000);
ASSERT_THAT(m_proxy->getVariantValue(), d);
}
TEST_F(SdbusTestObject, EmitsSignalWithoutRegistrationSuccesfully)
{
m_adaptor->signalWithoutRegistration({"platform", {"av"}});
usleep(10000);
auto signature = m_proxy->getSignatureFromSignal();
ASSERT_THAT(signature["platform"], Eq("av"));
}
TEST_F(SdbusTestObject, failsEmitingSignalOnNonexistentInterface)
{
ASSERT_THROW(m_adaptor->emitSignalOnNonexistentInterface(), sdbus::Error);
}
// Properties
TEST_F(SdbusTestObject, ReadsReadPropertySuccesfully)
{
ASSERT_THAT(m_proxy->state(), Eq(STRING_VALUE));
}
TEST_F(SdbusTestObject, WritesAndReadsReadWritePropertySuccesfully)
{
auto x = 42;
ASSERT_NO_THROW(m_proxy->action(x));
ASSERT_THAT(m_proxy->action(), Eq(x));
}
TEST_F(SdbusTestObject, WritesToWritePropertySuccesfully)
{
auto x = true;
ASSERT_NO_THROW(m_proxy->blocking(x));
}
TEST_F(SdbusTestObject, CannotReadFromWriteProperty)
{
ASSERT_THROW(m_proxy->blocking(), sdbus::Error);
}
+91
View File
@@ -0,0 +1,91 @@
/**
* (C) 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
*
* @file Connection_test.cpp
*
* Created on: Jan 2, 2017
* 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/>.
*/
// Own
#include "defs.h"
// sdbus
#include <sdbus-c++/Error.h>
#include <sdbus-c++/IConnection.h>
// gmock
#include <gtest/gtest.h>
#include <gmock/gmock.h>
// STL
#include <thread>
using ::testing::Eq;
/*-------------------------------------*/
/* -- TEST CASES -- */
/*-------------------------------------*/
TEST(Connection, CanBeDefaultConstructed)
{
ASSERT_NO_THROW(sdbus::createConnection());
}
TEST(Connection, CanRequestRegisteredDbusName)
{
auto connection = sdbus::createConnection();
ASSERT_NO_THROW(connection->requestName(INTERFACE_NAME));
connection->releaseName(INTERFACE_NAME);
}
TEST(Connection, CannotRequestNonregisteredDbusName)
{
auto connection = sdbus::createConnection();
ASSERT_THROW(connection->requestName("some_random_not_supported_dbus_name"), sdbus::Error);
}
TEST(Connection, CanReleasedRequestedName)
{
auto connection = sdbus::createConnection();
connection->requestName(INTERFACE_NAME);
ASSERT_NO_THROW(connection->releaseName(INTERFACE_NAME));
}
TEST(Connection, CannotReleaseNonrequestedName)
{
auto connection = sdbus::createConnection();
ASSERT_THROW(connection->releaseName("some_random_nonrequested_name"), sdbus::Error);
}
TEST(Connection, CanEnterAndLeaveProcessingLoop)
{
auto connection = sdbus::createConnection();
connection->requestName(INTERFACE_NAME);
std::thread t([&](){ connection->enterProcessingLoop(); });
connection->leaveProcessingLoop();
t.join();
connection->releaseName(INTERFACE_NAME);
}
+146
View File
@@ -0,0 +1,146 @@
/**
* (C) 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
*
* @file TestingAdaptor.h
*
* Created on: Jan 2, 2017
* 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/>.
*/
#ifndef SDBUS_CPP_INTEGRATIONTESTS_TESTINGADAPTOR_H_
#define SDBUS_CPP_INTEGRATIONTESTS_TESTINGADAPTOR_H_
#include "adaptor-glue.h"
class TestingAdaptor : public sdbus::Interfaces<testing_adaptor>
{
public:
TestingAdaptor(sdbus::IConnection& connection) :
sdbus::Interfaces<::testing_adaptor>(connection, OBJECT_PATH) { }
virtual ~TestingAdaptor() { }
protected:
void noArgNoReturn() const { }
int32_t getInt() const { return INT32_VALUE; }
std::tuple<uint32_t, std::string> getTuple() const { return std::make_tuple(UINT32_VALUE, STRING_VALUE); }
double multiply(const int64_t& a, const double& b) const { return a * b; }
std::vector<int16_t> getInts16FromStruct(const sdbus::Struct<uint8_t, int16_t, double, std::string, std::vector<int16_t>>& x) const
{
std::vector<int16_t> res{x.get<1>()};
auto y = std::get<std::vector<int16_t>>(x);
res.insert(res.end(), y.begin(), y.end());
return res;
}
sdbus::Variant processVariant(sdbus::Variant& v)
{
sdbus::Variant res = static_cast<int32_t>(v.get<double>());
return res;
}
std::map<int32_t, sdbus::Variant> getMapOfVariants(const std::vector<int32_t>& x, const sdbus::Struct<sdbus::Variant, sdbus::Variant>& y) const
{
std::map<int32_t, sdbus::Variant> res;
for (auto item : x)
{
res[item] = (item <= 0) ? std::get<0>(y) : std::get<1>(y);
}
return res;
}
sdbus::Struct<std::string, sdbus::Struct<std::map<int32_t, int32_t>>> getStructInStruct() const
{
sdbus::Struct<std::string, sdbus::Struct<std::map<int32_t, int32_t>>> x{STRING_VALUE, {{{INT32_VALUE, INT32_VALUE}}}};
return x;
}
int32_t sumStructItems(const sdbus::Struct<uint8_t, uint16_t>& a, const sdbus::Struct<int32_t, int64_t>& b)
{
int32_t res{0};
res += std::get<0>(a) + std::get<1>(a);
res += std::get<0>(b) + std::get<1>(b);
return res;
}
uint32_t sumVectorItems(const std::vector<uint16_t>& a, const std::vector<uint64_t>& b)
{
uint32_t res{0};
for (auto x : a)
{
res += x;
}
for (auto x : b)
{
res += x;
}
return res;
}
sdbus::Signature getSignature() const { return SIGNATURE_VALUE; }
sdbus::ObjectPath getObjectPath() const { return OBJECT_PATH_VALUE; }
ComplexType getComplex() const
{
return { // map
{
0, // uint_64_t
{ // struct
{ // map
{
'a', // uint8_t
{ // vector
{ // struct
"/object/path", // object path
false,
3.14,
{ // map
{0, "zero"}
}
}
}
}
},
"a{t(a{ya(obva{is})}gs)}", // signature
""
}
}
};
}
std::string state() { return STRING_VALUE; }
uint32_t action() { return m_action; }
void action(const uint32_t& value) { m_action = value; }
bool blocking() { return m_blocking; }
void blocking(const bool& value) { m_blocking = value; }
private:
uint32_t m_action;
bool m_blocking;
};
#endif /* INTEGRATIONTESTS_TESTINGADAPTOR_H_ */
+66
View File
@@ -0,0 +1,66 @@
/**
* (C) 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
*
* @file TestingProxy.h
*
* Created on: Jan 2, 2017
* 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/>.
*/
#ifndef SDBUS_CPP_INTEGRATIONTESTS_TESTINGPROXY_H_
#define SDBUS_CPP_INTEGRATIONTESTS_TESTINGPROXY_H_
#include "proxy-glue.h"
class TestingProxy : public sdbus::ProxyInterfaces<::testing_proxy>
{
public:
using sdbus::ProxyInterfaces<::testing_proxy>::ProxyInterfaces;
int getSimpleCallCount() const { return m_simpleCallCounter; }
std::map<int32_t, std::string> getMap() const { return m_map; }
double getVariantValue() const { return m_variantValue; }
std::map<std::string, std::string> getSignatureFromSignal() const { return m_signature; }
protected:
void onSimpleSignal() override { ++m_simpleCallCounter; }
void onSignalWithMap(const std::map<int32_t, std::string>& m) override { m_map = m; }
void onSignalWithVariant(const sdbus::Variant& v) override
{
m_variantValue = v.get<double>();
}
void onSignalWithoutRegistration(const sdbus::Struct<std::string, sdbus::Struct<sdbus::Signature>>& s) override
{
m_signature[std::get<0>(s)] = static_cast<std::string>(std::get<0>(std::get<1>(s)));
}
private:
int m_simpleCallCounter{};
std::map<int32_t, std::string> m_map;
double m_variantValue;
std::map<std::string, std::string> m_signature;
};
#endif /* SDBUS_CPP_INTEGRATIONTESTS_TESTINGPROXY_H_ */
+156
View File
@@ -0,0 +1,156 @@
/**
* (C) 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
*
* @file adaptor-glue.h
*
* Created on: Jan 2, 2017
* 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/>.
*/
#ifndef SDBUS_CPP_INTEGRATIONTESTS_ADAPTOR_GLUE_H_
#define SDBUS_CPP_INTEGRATIONTESTS_ADAPTOR_GLUE_H_
#include "defs.h"
// sdbus
#include "sdbus-c++/sdbus-c++.h"
using ComplexType = std::map<
uint64_t,
sdbus::Struct<
std::map<
uint8_t,
std::vector<
sdbus::Struct<
sdbus::ObjectPath,
bool,
sdbus::Variant,
std::map<int, std::string>
>
>
>,
sdbus::Signature,
std::string // char* leads to type and memory issues, std::string is best choice
>
>;
class testing_adaptor
{
protected:
testing_adaptor(sdbus::IObject& object) :
object_(object)
{
object_.registerMethod("noArgNoReturn").onInterface(INTERFACE_NAME).implementedAs([this](){ return this->noArgNoReturn(); });
object_.registerMethod("getInt").onInterface(INTERFACE_NAME).implementedAs([this](){ return this->getInt(); });
object_.registerMethod("getTuple").onInterface(INTERFACE_NAME).implementedAs([this](){ return this->getTuple(); });
object_.registerMethod("multiply").onInterface(INTERFACE_NAME).implementedAs([this](const int64_t& a, const double& b){ return this->multiply(a, b); });
object_.registerMethod("getInts16FromStruct").onInterface(INTERFACE_NAME).implementedAs([this](
const sdbus::Struct<uint8_t, int16_t, double, std::string, std::vector<int16_t>>& x){ return this->getInts16FromStruct(x); });
object_.registerMethod("processVariant").onInterface(INTERFACE_NAME).implementedAs([this](sdbus::Variant& v){ return this->processVariant(v); });
object_.registerMethod("getMapOfVariants").onInterface(INTERFACE_NAME).implementedAs([this](
const std::vector<int32_t>& x, const sdbus::Struct<sdbus::Variant, sdbus::Variant>& y){ return this->getMapOfVariants(x ,y); });
object_.registerMethod("getStructInStruct").onInterface(INTERFACE_NAME).implementedAs([this](){ return this->getStructInStruct(); });
object_.registerMethod("sumStructItems").onInterface(INTERFACE_NAME).implementedAs([this](
const sdbus::Struct<uint8_t, uint16_t>& a, const sdbus::Struct<int32_t, int64_t>& b){
return this->sumStructItems(a, b);
});
object_.registerMethod("sumVectorItems").onInterface(INTERFACE_NAME).implementedAs([this](
const std::vector<uint16_t>& a, const std::vector<uint64_t>& b){
return this->sumVectorItems(a, b);
});
object_.registerMethod("getSignature").onInterface(INTERFACE_NAME).implementedAs([this](){ return this->getSignature(); });
object_.registerMethod("getObjectPath").onInterface(INTERFACE_NAME).implementedAs([this](){ return this->getObjectPath(); });
object_.registerMethod("getComplex").onInterface(INTERFACE_NAME).implementedAs([this](){ return this->getComplex(); });
// registration of signals is optional, it is useful because of introspection
object_.registerSignal("simpleSignal").onInterface(INTERFACE_NAME);
object_.registerSignal("signalWithMap").onInterface(INTERFACE_NAME).withParameters<std::map<int32_t, std::string>>();
object_.registerSignal("signalWithVariant").onInterface(INTERFACE_NAME).withParameters<sdbus::Variant>();
object_.registerProperty("state").onInterface(INTERFACE_NAME).withGetter([this](){ return this->state(); });
object_.registerProperty("action").onInterface(INTERFACE_NAME).withGetter([this](){ return this->action(); }).withSetter([this](const uint32_t& value){ this->action(value); });
object_.registerProperty("blocking").onInterface(INTERFACE_NAME)./*withGetter([this](){ return this->blocking(); }).*/withSetter([this](const bool& value){ this->blocking(value); });
}
public:
void simpleSignal()
{
object_.emitSignal("simpleSignal").onInterface(INTERFACE_NAME);
}
void signalWithMap(const std::map<int32_t, std::string>& map)
{
object_.emitSignal("signalWithMap").onInterface(INTERFACE_NAME).withArguments(map);
}
void signalWithVariant(const sdbus::Variant& v)
{
object_.emitSignal("signalWithVariant").onInterface(INTERFACE_NAME).withArguments(v);
}
void signalWithoutRegistration(const sdbus::Struct<std::string, sdbus::Struct<sdbus::Signature>>& s)
{
object_.emitSignal("signalWithoutRegistration").onInterface(INTERFACE_NAME).withArguments(s);
}
void emitSignalOnNonexistentInterface()
{
object_.emitSignal("simpleSignal").onInterface("interfaceThatDoesNotExists");
}
private:
sdbus::IObject& object_;
protected:
virtual void noArgNoReturn() const = 0;
virtual int32_t getInt() const = 0;
virtual std::tuple<uint32_t, std::string> getTuple() const = 0;
virtual double multiply(const int64_t& a, const double& b) const = 0;
virtual std::vector<int16_t> getInts16FromStruct(const sdbus::Struct<uint8_t, int16_t, double, std::string, std::vector<int16_t>>& x) const = 0;
virtual sdbus::Variant processVariant(sdbus::Variant& v) = 0;
virtual std::map<int32_t, sdbus::Variant> getMapOfVariants(const std::vector<int32_t>& x, const sdbus::Struct<sdbus::Variant, sdbus::Variant>& y) const = 0;
virtual sdbus::Struct<std::string, sdbus::Struct<std::map<int32_t, int32_t>>> getStructInStruct() const = 0;
virtual int32_t sumStructItems(const sdbus::Struct<uint8_t, uint16_t>& a, const sdbus::Struct<int32_t, int64_t>& b) = 0;
virtual uint32_t sumVectorItems(const std::vector<uint16_t>& a, const std::vector<uint64_t>& b) = 0;
virtual sdbus::Signature getSignature() const = 0;
virtual sdbus::ObjectPath getObjectPath() const = 0;
virtual ComplexType getComplex() const = 0;
virtual std::string state() = 0;
virtual uint32_t action() = 0;
virtual void action(const uint32_t& value) = 0;
virtual bool blocking() = 0;
virtual void blocking(const bool& value) = 0;
};
#endif /* SDBUS_CPP_INTEGRATIONTESTS_ADAPTOR_GLUE_H_ */
+46
View File
@@ -0,0 +1,46 @@
/**
* (C) 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
*
* @file defs.h
*
* Created on: Jan 2, 2017
* 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/>.
*/
#ifndef SDBUS_CPP_INTEGRATIONTESTS_DEFS_H_
#define SDBUS_CPP_INTEGRATIONTESTS_DEFS_H_
#include "sdbus-c++/Types.h"
const std::string INTERFACE_NAME{"com.kistler.testsdbuscpp"};
const std::string OBJECT_PATH{"/"};
constexpr const uint8_t UINT8_VALUE{1};
constexpr const int16_t INT16_VALUE{21};
constexpr const uint32_t UINT32_VALUE{42};
constexpr const int32_t INT32_VALUE{-42};
constexpr const int32_t INT64_VALUE{-1024};
const std::string STRING_VALUE{"sdbus-c++-testing"};
const sdbus::Signature SIGNATURE_VALUE{"a{is}"};
const sdbus::ObjectPath OBJECT_PATH_VALUE{"/"};
constexpr const double DOUBLE_VALUE{3.24L};
#endif /* SDBUS_CPP_INTEGRATIONTESTS_DEFS_H_ */
@@ -0,0 +1,17 @@
<!-- 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="com.kistler.testsdbuscpp"/>
<allow send_destination="com.kistler.testsdbuscpp"/>
<allow send_interface="com.kistler.testsdbuscpp"/>
</policy>
</busconfig>
@@ -0,0 +1,33 @@
/**
* (C) 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
*
* @file libsdbus-c++_integrationtests.cpp
*
* Created on: Jan 2, 2017
* 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 "gmock/gmock.h"
int main(int argc, char **argv)
{
::testing::InitGoogleMock(&argc, argv);
return RUN_ALL_TESTS();
}
+190
View File
@@ -0,0 +1,190 @@
/**
* (C) 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
*
* @file proxy-glue.h
*
* Created on: Jan 2, 2017
* 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/>.
*/
#ifndef SDBUS_CPP_INTEGRATIONTESTS_PROXY_GLUE_H_
#define SDBUS_CPP_INTEGRATIONTESTS_PROXY_GLUE_H_
#include "defs.h"
// sdbus
#include "sdbus-c++/sdbus-c++.h"
class testing_proxy
{
protected:
testing_proxy(sdbus::IObjectProxy& object) :
object_(object)
{
object_.uponSignal("simpleSignal").onInterface(INTERFACE_NAME).call([this](){ this->onSimpleSignal(); });
object_.uponSignal("signalWithMap").onInterface(INTERFACE_NAME).call([this](const std::map<int32_t, std::string>& map){ this->onSignalWithMap(map); });
object_.uponSignal("signalWithVariant").onInterface(INTERFACE_NAME).call([this](const sdbus::Variant& v){ this->onSignalWithVariant(v); });
object_.uponSignal("signalWithoutRegistration").onInterface(INTERFACE_NAME).call([this](const sdbus::Struct<std::string, sdbus::Struct<sdbus::Signature>>& s)
{ this->onSignalWithoutRegistration(s); });
}
virtual void onSimpleSignal() = 0;
virtual void onSignalWithMap(const std::map<int32_t, std::string>& map) = 0;
virtual void onSignalWithVariant(const sdbus::Variant& v) = 0;
virtual void onSignalWithoutRegistration(const sdbus::Struct<std::string, sdbus::Struct<sdbus::Signature>>& s) = 0;
public:
void noArgNoReturn()
{
object_.callMethod("noArgNoReturn").onInterface(INTERFACE_NAME);
}
int32_t getInt()
{
int32_t result;
object_.callMethod("getInt").onInterface(INTERFACE_NAME).storeResultsTo(result);
return result;
}
std::tuple<uint32_t, std::string> getTuple()
{
std::tuple<uint32_t, std::string> result;
object_.callMethod("getTuple").onInterface(INTERFACE_NAME).storeResultsTo(result);
return result;
}
double multiply(const int64_t& a, const double& b)
{
double result;
object_.callMethod("multiply").onInterface(INTERFACE_NAME).withArguments(a, b).storeResultsTo(result);
return result;
}
std::vector<int16_t> getInts16FromStruct(const sdbus::Struct<uint8_t, int16_t, double, std::string, std::vector<int16_t>>& x)
{
std::vector<int16_t> result;
object_.callMethod("getInts16FromStruct").onInterface(INTERFACE_NAME).withArguments(x).storeResultsTo(result);
return result;
}
sdbus::Variant processVariant(const sdbus::Variant& v)
{
sdbus::Variant result;
object_.callMethod("processVariant").onInterface(INTERFACE_NAME).withArguments(v).storeResultsTo(result);
return result;
}
std::map<int32_t, sdbus::Variant> getMapOfVariants(const std::vector<int32_t>& x, const sdbus::Struct<sdbus::Variant, sdbus::Variant>& y)
{
std::map<int32_t, sdbus::Variant> result;
object_.callMethod("getMapOfVariants").onInterface(INTERFACE_NAME).withArguments(x, y).storeResultsTo(result);
return result;
}
sdbus::Struct<std::string, sdbus::Struct<std::map<int32_t, int32_t>>> getStructInStruct()
{
sdbus::Struct<std::string, sdbus::Struct<std::map<int32_t, int32_t>>> result;
object_.callMethod("getStructInStruct").onInterface(INTERFACE_NAME).withArguments().storeResultsTo(result);
return result;
}
int32_t sumStructItems(const sdbus::Struct<uint8_t, uint16_t>& a, const sdbus::Struct<int32_t, int64_t>& b)
{
int32_t result;
object_.callMethod("sumStructItems").onInterface(INTERFACE_NAME).withArguments(a, b).storeResultsTo(result);
return result;
}
uint32_t sumVectorItems(const std::vector<uint16_t>& a, const std::vector<uint64_t>& b)
{
uint32_t result;
object_.callMethod("sumVectorItems").onInterface(INTERFACE_NAME).withArguments(a, b).storeResultsTo(result);
return result;
}
sdbus::Signature getSignature()
{
sdbus::Signature result;
object_.callMethod("getSignature").onInterface(INTERFACE_NAME).storeResultsTo(result);
return result;
}
sdbus::ObjectPath getObjectPath()
{
sdbus::ObjectPath result;
object_.callMethod("getObjectPath").onInterface(INTERFACE_NAME).storeResultsTo(result);
return result;
}
ComplexType getComplex()
{
ComplexType result;
object_.callMethod("getComplex").onInterface(INTERFACE_NAME).storeResultsTo(result);
return result;
}
int32_t callNonexistentMethod()
{
int32_t result;
object_.callMethod("callNonexistentMethod").onInterface(INTERFACE_NAME).storeResultsTo(result);
return result;
}
int32_t callMethodOnNonexistentInterface()
{
int32_t result;
object_.callMethod("someMethod").onInterface("interfaceThatDoesNotExist").storeResultsTo(result);
return result;
}
std::string state()
{
return object_.getProperty("state").onInterface(INTERFACE_NAME);
}
uint32_t action()
{
return object_.getProperty("action").onInterface(INTERFACE_NAME);
}
void action(const uint32_t& value)
{
object_.setProperty("action").onInterface(INTERFACE_NAME).toValue(value);
}
bool blocking()
{
return object_.getProperty("blocking").onInterface(INTERFACE_NAME);
}
void blocking(const bool& value)
{
object_.setProperty("blocking").onInterface(INTERFACE_NAME).toValue(value);
}
private:
sdbus::IObjectProxy& object_;
};
#endif /* SDBUS_CPP_INTEGRATIONTESTS_PROXY_GLUE_H_ */
+230
View File
@@ -0,0 +1,230 @@
/**
* (C) 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
*
* @file Message_test.cpp
*
* Created on: Dec 3, 2016
* 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 <sdbus-c++/Types.h>
#include "MessageUtils.h"
#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include <cstdint>
using ::testing::Eq;
using ::testing::DoubleEq;
using namespace std::string_literals;
namespace
{
std::string deserializeString(sdbus::Message& msg)
{
std::string str;
msg >> str;
return str;
}
}
/*-------------------------------------*/
/* -- TEST CASES -- */
/*-------------------------------------*/
TEST(AMessage, CanBeDefaultConstructed)
{
ASSERT_NO_THROW(sdbus::Message());
}
TEST(AMessage, IsInvalidAfterDefaultConstructed)
{
sdbus::Message msg;
ASSERT_FALSE(msg.isValid());
}
TEST(AMessage, IsValidWhenConstructedAsRealMessage)
{
sdbus::Message msg{sdbus::createPlainMessage()};
ASSERT_TRUE(msg.isValid());
}
TEST(AMessage, CreatesShallowCopyWhenCopyConstructed)
{
sdbus::Message msg{sdbus::createPlainMessage()};
msg << "I am a string"s;
msg.seal();
sdbus::Message msgCopy = msg;
std::string str;
msgCopy >> str;
ASSERT_THAT(str, Eq("I am a string"));
ASSERT_THROW(msgCopy >> str, sdbus::Error);
}
TEST(AMessage, CreatesDeepCopyWhenEplicitlyCopied)
{
sdbus::Message msg{sdbus::createPlainMessage()};
msg << "I am a string"s;
msg.seal();
sdbus::Message msgCopy{sdbus::createPlainMessage()};
msg.copyTo(msgCopy, true);
msgCopy.seal(); // Seal to be able to read from it subsequently
msg.rewind(true); // Rewind to the beginning after copying
ASSERT_THAT(deserializeString(msg), Eq("I am a string"));
ASSERT_THAT(deserializeString(msgCopy), Eq("I am a string"));
}
TEST(AMessage, IsEmptyWhenContainsNoValue)
{
sdbus::Message msg{sdbus::createPlainMessage()};
ASSERT_TRUE(msg.isEmpty());
}
TEST(AMessage, IsNotEmptyWhenContainsAValue)
{
sdbus::Message msg{sdbus::createPlainMessage()};
msg << "I am a string"s;
ASSERT_FALSE(msg.isEmpty());
}
TEST(AMessage, ReturnsItsTypeWhenAsked)
{
sdbus::Message msg{sdbus::createPlainMessage()};
ASSERT_THAT(msg.getType(), Eq(sdbus::Message::Type::ePlainMessage));
}
TEST(AMessage, CanCarryASimpleInteger)
{
sdbus::Message msg{sdbus::createPlainMessage()};
int dataWritten = 5;
msg << dataWritten;
msg.seal();
int dataRead;
msg >> dataRead;
ASSERT_THAT(dataRead, Eq(dataWritten));
}
TEST(AMessage, CanCarryAVariant)
{
sdbus::Message msg{sdbus::createPlainMessage()};
auto dataWritten = sdbus::Variant((double)3.14);
msg << dataWritten;
msg.seal();
sdbus::Variant dataRead;
msg >> dataRead;
ASSERT_THAT(dataRead.get<double>(), Eq(dataWritten.get<double>()));
}
TEST(AMessage, CanCarryACollectionOfEmbeddedVariants)
{
sdbus::Message msg{sdbus::createPlainMessage()};
auto value = std::vector<sdbus::Variant>{"hello"s, (double)3.14};
auto dataWritten = sdbus::Variant{value};
msg << dataWritten;
msg.seal();
sdbus::Variant dataRead;
msg >> dataRead;
ASSERT_THAT(dataRead.get<decltype(value)>()[0].get<std::string>(), Eq(value[0].get<std::string>()));
ASSERT_THAT(dataRead.get<decltype(value)>()[1].get<double>(), Eq(value[1].get<double>()));
}
TEST(AMessage, CanCarryAnArray)
{
sdbus::Message msg{sdbus::createPlainMessage()};
std::vector<int64_t> dataWritten{3545342, 43643532, 324325};
msg << dataWritten;
msg.seal();
std::vector<int64_t> dataRead;
msg >> dataRead;
ASSERT_THAT(dataRead, Eq(dataWritten));
}
TEST(AMessage, CanCarryADictionary)
{
sdbus::Message msg{sdbus::createPlainMessage()};
std::map<int, std::string> dataWritten{{1, "one"}, {2, "two"}};
msg << dataWritten;
msg.seal();
std::map<int, std::string> dataRead;
msg >> dataRead;
ASSERT_THAT(dataRead, Eq(dataWritten));
}
TEST(AMessage, CanCarryAComplexType)
{
sdbus::Message msg{sdbus::createPlainMessage()};
using ComplexType = std::map<
uint64_t,
sdbus::Struct<
std::map<
uint8_t,
std::vector<
sdbus::Struct<
sdbus::ObjectPath,
bool,
int16_t,
/*sdbus::Variant,*/
std::map<int, std::string>
>
>
>,
sdbus::Signature,
double
>
>;
ComplexType dataWritten = { {1, {{{5, {{"/some/object", true, 45, {{6, "hello"}, {7, "world"}}}}}}, "av", 3.14}}};
msg << dataWritten;
msg.seal();
ComplexType dataRead;
msg >> dataRead;
ASSERT_THAT(dataRead, Eq(dataWritten));
}
+129
View File
@@ -0,0 +1,129 @@
/**
* (C) 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
*
* @file TypeTraits_test.cpp
*
* Created on: Nov 27, 2016
* 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 <sdbus-c++/TypeTraits.h>
#include <sdbus-c++/Types.h>
#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include <cstdint>
using ::testing::Eq;
namespace
{
// ---
// FIXTURE DEFINITION FOR TYPED TESTS
// ----
template <typename _T>
class Type2DBusTypeSignatureConversion
: public ::testing::Test
{
protected:
const std::string dbusTypeSignature_{getDBusTypeSignature()};
private:
static std::string getDBusTypeSignature();
};
#define TYPE(...) \
template <> \
std::string Type2DBusTypeSignatureConversion<__VA_ARGS__>::getDBusTypeSignature() \
/**/
#define HAS_DBUS_TYPE_SIGNATURE(_SIG) \
{ \
return (_SIG); \
} \
/**/
TYPE(bool)HAS_DBUS_TYPE_SIGNATURE("b")
TYPE(uint8_t)HAS_DBUS_TYPE_SIGNATURE("y")
TYPE(int16_t)HAS_DBUS_TYPE_SIGNATURE("n")
TYPE(uint16_t)HAS_DBUS_TYPE_SIGNATURE("q")
TYPE(int32_t)HAS_DBUS_TYPE_SIGNATURE("i")
TYPE(uint32_t)HAS_DBUS_TYPE_SIGNATURE("u")
TYPE(int64_t)HAS_DBUS_TYPE_SIGNATURE("x")
TYPE(uint64_t)HAS_DBUS_TYPE_SIGNATURE("t")
TYPE(double)HAS_DBUS_TYPE_SIGNATURE("d")
TYPE(const char*)HAS_DBUS_TYPE_SIGNATURE("s")
TYPE(std::string)HAS_DBUS_TYPE_SIGNATURE("s")
TYPE(sdbus::ObjectPath)HAS_DBUS_TYPE_SIGNATURE("o")
TYPE(sdbus::Signature)HAS_DBUS_TYPE_SIGNATURE("g")
TYPE(sdbus::Variant)HAS_DBUS_TYPE_SIGNATURE("v")
TYPE(sdbus::Struct<bool>)HAS_DBUS_TYPE_SIGNATURE("(b)")
TYPE(sdbus::Struct<uint16_t, double, std::string, sdbus::Variant>)HAS_DBUS_TYPE_SIGNATURE("(qdsv)")
TYPE(std::vector<int16_t>)HAS_DBUS_TYPE_SIGNATURE("an")
TYPE(std::map<int32_t, int64_t>)HAS_DBUS_TYPE_SIGNATURE("a{ix}")
using ComplexType = std::map<
uint64_t,
sdbus::Struct<
std::map<
uint8_t,
std::vector<
sdbus::Struct<
sdbus::ObjectPath,
bool,
sdbus::Variant,
std::map<int, std::string>
>
>
>,
sdbus::Signature,
const char*
>
>;
TYPE(ComplexType)HAS_DBUS_TYPE_SIGNATURE("a{t(a{ya(obva{is})}gs)}")
typedef ::testing::Types< bool
, uint8_t
, int16_t
, uint16_t
, int32_t
, uint32_t
, int64_t
, uint64_t
, double
, const char*
, std::string
, sdbus::ObjectPath
, sdbus::Signature
, sdbus::Variant
, sdbus::Struct<bool>
, sdbus::Struct<uint16_t, double, std::string, sdbus::Variant>
, std::vector<int16_t>
, std::map<int32_t, int64_t>
, ComplexType
> DBusSupportedTypes;
TYPED_TEST_CASE(Type2DBusTypeSignatureConversion, DBusSupportedTypes);
}
/*-------------------------------------*/
/* -- TEST CASES -- */
/*-------------------------------------*/
TYPED_TEST(Type2DBusTypeSignatureConversion, ConvertsTypeToProperDBusSignature)
{
ASSERT_THAT(sdbus::signature_of<TypeParam>::str(), Eq(this->dbusTypeSignature_));
}
+205
View File
@@ -0,0 +1,205 @@
/**
* (C) 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
*
* @file Types_test.cpp
*
* Created on: Dec 3, 2016
* 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 <sdbus-c++/Types.h>
#include "MessageUtils.h"
#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include <cstdint>
using ::testing::Eq;
using namespace std::string_literals;
namespace
{
constexpr const uint64_t ANY_UINT64 = 84578348354;
constexpr const double ANY_DOUBLE = 3.14;
}
/*-------------------------------------*/
/* -- TEST CASES -- */
/*-------------------------------------*/
TEST(AVariant, CanBeDefaultConstructed)
{
ASSERT_NO_THROW(sdbus::Variant());
}
TEST(AVariant, ContainsNoValueAfterDefaultConstructed)
{
sdbus::Variant v;
ASSERT_TRUE(v.isEmpty());
}
TEST(AVariant, CanBeConstructedFromASimpleValue)
{
int value = 5;
ASSERT_NO_THROW(sdbus::Variant{value});
}
TEST(AVariant, CanBeConstructedFromAComplexValue)
{
using ComplexType = std::map<uint64_t, std::vector<sdbus::Struct<std::string, double>>>;
ComplexType value{ {ANY_UINT64, ComplexType::mapped_type{sdbus::make_struct("hello", ANY_DOUBLE), sdbus::make_struct("world", ANY_DOUBLE)}} };
ASSERT_NO_THROW(sdbus::Variant(value));
}
TEST(AVariant, CanBeCopied)
{
auto value = "hello"s;
sdbus::Variant variant(value);
auto variantCopy1{variant};
auto variantCopy2 = variantCopy1;
ASSERT_THAT(variantCopy1.get<std::string>(), Eq(value));
ASSERT_THAT(variantCopy2.get<std::string>(), Eq(value));
}
TEST(AVariant, IsNotEmptyWhenContainsAValue)
{
sdbus::Variant v("hello");
ASSERT_FALSE(v.isEmpty());
}
TEST(ASimpleVariant, ReturnsTheSimpleValueWhenAsked)
{
int value = 5;
sdbus::Variant variant(value);
ASSERT_THAT(variant.get<int>(), Eq(value));
}
TEST(AComplexVariant, ReturnsTheComplexValueWhenAsked)
{
using ComplexType = std::map<uint64_t, std::vector<sdbus::Struct<std::string, double>>>;
ComplexType value{ {ANY_UINT64, ComplexType::mapped_type{sdbus::make_struct("hello", ANY_DOUBLE), sdbus::make_struct("world", ANY_DOUBLE)}} };
sdbus::Variant variant(value);
ASSERT_THAT(variant.get<decltype(value)>(), Eq(value));
}
TEST(AVariant, HasConceptuallyNonmutableGetMethodWhichCanBeCalledXTimes)
{
std::string value{"I am a string"};
sdbus::Variant variant(value);
ASSERT_THAT(variant.get<std::string>(), Eq(value));
ASSERT_THAT(variant.get<std::string>(), Eq(value));
ASSERT_THAT(variant.get<std::string>(), Eq(value));
}
TEST(AVariant, ReturnsTrueWhenAskedIfItContainsTheTypeItReallyContains)
{
using ComplexType = std::map<uint64_t, std::vector<sdbus::Struct<std::string, double>>>;
ComplexType value{ {ANY_UINT64, ComplexType::mapped_type{sdbus::make_struct("hello", ANY_DOUBLE), sdbus::make_struct("world", ANY_DOUBLE)}} };
sdbus::Variant variant(value);
ASSERT_TRUE(variant.containsValueOfType<ComplexType>());
}
TEST(ASimpleVariant, ReturnsFalseWhenAskedIfItContainsTypeItDoesntReallyContain)
{
int value = 5;
sdbus::Variant variant(value);
ASSERT_FALSE(variant.containsValueOfType<double>());
}
TEST(AVariant, CanContainOtherEmbeddedVariants)
{
using TypeWithVariants = std::vector<sdbus::Struct<sdbus::Variant, double>>;
TypeWithVariants value;
value.emplace_back(sdbus::make_struct(sdbus::Variant("a string"), ANY_DOUBLE));
value.emplace_back(sdbus::make_struct(sdbus::Variant(ANY_UINT64), ANY_DOUBLE));
sdbus::Variant variant(value);
ASSERT_TRUE(variant.containsValueOfType<TypeWithVariants>());
}
TEST(ANonEmptyVariant, SerializesSuccessfullyToAMessage)
{
sdbus::Variant variant("a string");
sdbus::Message msg = sdbus::createPlainMessage();
ASSERT_NO_THROW(variant.serializeTo(msg));
}
TEST(AnEmptyVariant, ThrowsWhenBeingSerializedToAMessage)
{
sdbus::Variant variant;
sdbus::Message msg = sdbus::createPlainMessage();
ASSERT_THROW(variant.serializeTo(msg), sdbus::Error);
}
TEST(ANonEmptyVariant, SerializesToAndDeserializesFromAMessageSuccessfully)
{
using ComplexType = std::map<uint64_t, std::vector<sdbus::Struct<std::string, double>>>;
ComplexType value{ {ANY_UINT64, ComplexType::mapped_type{sdbus::make_struct("hello", ANY_DOUBLE), sdbus::make_struct("world", ANY_DOUBLE)}} };
sdbus::Variant variant(value);
sdbus::Message msg = sdbus::createPlainMessage();
variant.serializeTo(msg);
msg.seal();
sdbus::Variant variant2;
variant2.deserializeFrom(msg);
ASSERT_THAT(variant2.get<decltype(value)>(), Eq(value));
}
TEST(CopiesOfVariant, SerializeToAndDeserializeFromMessageSuccessfully)
{
using ComplexType = std::map<uint64_t, std::vector<sdbus::Struct<std::string, double>>>;
ComplexType value{ {ANY_UINT64, ComplexType::mapped_type{sdbus::make_struct("hello", ANY_DOUBLE), sdbus::make_struct("world", ANY_DOUBLE)}} };
sdbus::Variant variant(value);
auto variantCopy1{variant};
auto variantCopy2 = variant;
sdbus::Message msg = sdbus::createPlainMessage();
variant.serializeTo(msg);
variantCopy1.serializeTo(msg);
variantCopy2.serializeTo(msg);
msg.seal();
sdbus::Variant receivedVariant1, receivedVariant2, receivedVariant3;
receivedVariant1.deserializeFrom(msg);
receivedVariant2.deserializeFrom(msg);
receivedVariant3.deserializeFrom(msg);
ASSERT_THAT(receivedVariant1.get<decltype(value)>(), Eq(value));
ASSERT_THAT(receivedVariant2.get<decltype(value)>(), Eq(value));
ASSERT_THAT(receivedVariant3.get<decltype(value)>(), Eq(value));
}
+33
View File
@@ -0,0 +1,33 @@
/**
* (C) 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
*
* @file libsdbus-c++_unittests.cpp
*
* Created on: Nov 27, 2016
* 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 "gmock/gmock.h"
int main(int argc, char **argv)
{
::testing::InitGoogleMock(&argc, argv);
return RUN_ALL_TESTS();
}