diff --git a/src/Connection.cpp b/src/Connection.cpp index db385f3..3341275 100644 --- a/src/Connection.cpp +++ b/src/Connection.cpp @@ -35,6 +35,10 @@ #include #include +#include +#include +#define gettid() syscall(SYS_gettid) + namespace sdbus { namespace internal { Connection::Connection(std::unique_ptr&& interface, const BusFactory& busFactory) @@ -47,6 +51,7 @@ Connection::Connection(std::unique_ptr&& interface, const BusFactory& bu Connection::Connection(std::unique_ptr&& interface, system_bus_t) : Connection(std::move(interface), [this](sd_bus** bus){ return iface_->sd_bus_open_system(bus); }) { +printf("Here: %p\n", this); } Connection::Connection(std::unique_ptr&& interface, session_bus_t) @@ -102,6 +107,40 @@ void Connection::enterProcessingLoopAsync() { if (!asyncLoopThread_.joinable()) asyncLoopThread_ = std::thread([this](){ enterProcessingLoop(); }); +// if (!asyncLoopThread2_.joinable()) +// asyncLoopThread2_ = std::thread([this](){ +// enterProcessingLoop(); +//// while (true) +//// { +//// auto bus = bus_.get(); + +//// assert(bus != nullptr); +//// assert(loopExitFd_.fd != 0); + +//// auto sdbusPollData = getProcessLoopPollData(); +//// struct pollfd fds[] = {{sdbusPollData.fd, sdbusPollData.events, 0}, {loopExitFd_.fd, POLLIN, 0}}; +//// auto fdsCount = sizeof(fds)/sizeof(fds[0]); + +//// printf("Thread 2: Going to poll %p\n", this); + +//// auto timeout = sdbusPollData.timeout_usec == (uint64_t) -1 ? (uint64_t)-1 : (sdbusPollData.timeout_usec+999)/1000; +//// auto r = poll(fds, fdsCount, timeout); + +//// printf("Thread 2: Poll woken up %p\n", this); + +//// if (r < 0 && errno == EINTR) +//// continue; + +//// SDBUS_THROW_ERROR_IF(r < 0, "Failed to wait on the bus", -errno); + +//// if (fds[1].revents & POLLIN) +//// { +//// clearExitNotification(); +//// printf("Thread 2: Exiting %p\n", this); +//// break; +//// } +//// } +// }); } void Connection::leaveProcessingLoop() @@ -332,6 +371,8 @@ void Connection::joinWithProcessingLoop() { if (asyncLoopThread_.joinable()) asyncLoopThread_.join(); +// if (asyncLoopThread2_.joinable()) +// asyncLoopThread2_.join(); } bool Connection::processPendingRequest() @@ -356,8 +397,13 @@ bool Connection::waitForNextRequest() struct pollfd fds[] = {{sdbusPollData.fd, sdbusPollData.events, 0}, {loopExitFd_.fd, POLLIN, 0}}; auto fdsCount = sizeof(fds)/sizeof(fds[0]); + printf("Thread %d: Going to poll %p\n", gettid(), this); + auto timeout = sdbusPollData.timeout_usec == (uint64_t) -1 ? (uint64_t)-1 : (sdbusPollData.timeout_usec+999)/1000; auto r = poll(fds, fdsCount, timeout); + //auto r = ppoll(fds, fdsCount, nullptr, nullptr); + + printf("Thread %d: Poll woken up %p\n", gettid(), this); if (r < 0 && errno == EINTR) return true; // Try again @@ -367,6 +413,7 @@ bool Connection::waitForNextRequest() if (fds[1].revents & POLLIN) { clearExitNotification(); + printf("Thread %d: Exiting %p\n", gettid(), this); return false; } diff --git a/src/Connection.h b/src/Connection.h index d5c6b57..4f100ea 100644 --- a/src/Connection.h +++ b/src/Connection.h @@ -130,6 +130,7 @@ namespace sdbus { namespace internal { std::unique_ptr iface_; BusPtr bus_; std::thread asyncLoopThread_; + std::thread asyncLoopThread2_; LoopExitEventFd loopExitFd_; }; diff --git a/tests/integrationtests/AdaptorAndProxy_test.cpp b/tests/integrationtests/AdaptorAndProxy_test.cpp index 68753a0..0c52e74 100644 --- a/tests/integrationtests/AdaptorAndProxy_test.cpp +++ b/tests/integrationtests/AdaptorAndProxy_test.cpp @@ -61,12 +61,13 @@ public: static void SetUpTestCase() { s_connection->requestName(INTERFACE_NAME); - s_connection->enterProcessingLoopAsync(); + m_t = std::thread([](){s_connection->enterProcessingLoop();}); } static void TearDownTestCase() { s_connection->leaveProcessingLoop(); + m_t.join(); s_connection->releaseName(INTERFACE_NAME); } @@ -88,7 +89,9 @@ private: void SetUp() override { m_adaptor = std::make_unique(*s_connection); + printf("PROXY BEGIN!\n"); m_proxy = std::make_unique(INTERFACE_NAME, OBJECT_PATH); + printf("PROXY END!\n"); std::this_thread::sleep_for(50ms); // Give time for the proxy to start listening to signals } @@ -103,9 +106,13 @@ public: std::unique_ptr m_adaptor; std::unique_ptr m_proxy; + + static std::thread m_t; }; std::unique_ptr AdaptorAndProxyFixture::s_connection = sdbus::createSystemBusConnection(); +std::thread AdaptorAndProxyFixture::m_t; + } /*-------------------------------------*/ @@ -132,511 +139,522 @@ TEST_F(SdbusTestObject, CallsEmptyMethodSuccesfully) ASSERT_NO_THROW(m_proxy->noArgNoReturn()); } -TEST_F(SdbusTestObject, CallsMethodsWithBaseTypesSuccesfully) +TEST_F(SdbusTestObject, RequestsSignalEmission) { - 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)); + printf("BEGIN !!!\n"); + ASSERT_THAT(m_proxy->doSignalEmission(), Gt(0)); + printf("END !!!\n"); + std::this_thread::sleep_for(1s); +// printf("\n"); +// m_adaptor->emitSimpleSignal(); +// std::this_thread::sleep_for(1s); } -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> a{}; - auto vectorRes = m_proxy->getInts16FromStruct(a); - ASSERT_THAT(vectorRes, Eq(std::vector{0})); // because second item is by default initialized to 0 - - - sdbus::Struct> 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_VALUE, INT16_VALUE, -INT16_VALUE})); -} - -TEST_F(SdbusTestObject, CallsMethodWithVariantSuccesfully) -{ - sdbus::Variant v{DOUBLE_VALUE}; - auto variantRes = m_proxy->processVariant(v); - ASSERT_THAT(variantRes.get(), Eq(static_cast(DOUBLE_VALUE))); -} - -TEST_F(SdbusTestObject, CallsMethodWithStructVariantsAndGetMapSuccesfully) -{ - std::vector x{-2, 0, 2}; - sdbus::Struct y{false, true}; - auto mapOfVariants = m_proxy->getMapOfVariants(x, y); - decltype(mapOfVariants) res{{-2, false}, {0, false}, {2, true}}; - - ASSERT_THAT(mapOfVariants[-2].get(), Eq(res[-2].get())); - ASSERT_THAT(mapOfVariants[0].get(), Eq(res[0].get())); - ASSERT_THAT(mapOfVariants[2].get(), Eq(res[2].get())); -} - -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, CallsMethodWithUnixFdSuccesfully) -{ - auto resUnixFd = m_proxy->getUnixFd(); - ASSERT_THAT(resUnixFd.get(), Gt(UNIX_FD_VALUE)); -} - -TEST_F(SdbusTestObject, CallsMethodWithComplexTypeSuccesfully) -{ - auto resComplex = m_proxy->getComplex(); - ASSERT_THAT(resComplex.count(0), Eq(1)); -} - -TEST_F(SdbusTestObject, CallsMultiplyMethodWithNoReplyFlag) -{ - m_proxy->multiplyWithNoReply(INT64_VALUE, DOUBLE_VALUE); - - ASSERT_TRUE(waitUntil(m_adaptor->m_wasMultiplyCalled)); - ASSERT_THAT(m_adaptor->m_multiplyResult, Eq(INT64_VALUE * DOUBLE_VALUE)); -} - -TEST_F(SdbusTestObject, CallsMethodWithCustomTimeoutSuccessfully) -{ - auto res = m_proxy->doOperationWith500msTimeout(20); // The operation will take 20ms, but the timeout is 500ms, so we are fine - ASSERT_THAT(res, Eq(20)); -} - -TEST_F(SdbusTestObject, ThrowsTimeoutErrorWhenMethodTimesOut) -{ - try - { - m_proxy->doOperationWith500msTimeout(1000); // The operation will take 1s, but the timeout is 500ms, so we should time out - FAIL() << "Expected sdbus::Error exception"; - } - catch (const sdbus::Error& e) - { - ASSERT_THAT(e.getName(), Eq("org.freedesktop.DBus.Error.Timeout")); - ASSERT_THAT(e.getMessage(), Eq("Connection timed out")); - } - catch(...) - { - FAIL() << "Expected sdbus::Error exception"; - } -} - -TEST_F(SdbusTestObject, CallsMethodThatThrowsError) -{ - try - { - m_proxy->throwError(); - FAIL() << "Expected sdbus::Error exception"; - } - catch (const sdbus::Error& e) - { - ASSERT_THAT(e.getName(), Eq("org.freedesktop.DBus.Error.AccessDenied")); - ASSERT_THAT(e.getMessage(), Eq("A test error occurred (Operation not permitted)")); - } - catch(...) - { - FAIL() << "Expected sdbus::Error exception"; - } -} - -TEST_F(SdbusTestObject, CallsErrorThrowingMethodWithDontExpectReplySet) -{ - ASSERT_NO_THROW(m_proxy->throwErrorWithNoReply()); - - ASSERT_TRUE(waitUntil(m_adaptor->m_wasThrowErrorCalled)); -} - -TEST_F(SdbusTestObject, RunsServerSideAsynchoronousMethodAsynchronously) -{ - // Yeah, this is kinda timing-dependent test, but times should be safe... - std::mutex mtx; - std::vector results; - std::atomic invoke{}; - std::atomic startedCount{}; - auto call = [&](uint32_t param) - { - TestingProxy proxy{INTERFACE_NAME, OBJECT_PATH}; - ++startedCount; - while (!invoke) ; - auto result = proxy.doOperationAsync(param); - std::lock_guard guard(mtx); - results.push_back(result); - }; - - std::thread invocations[]{std::thread{call, 1500}, std::thread{call, 1000}, std::thread{call, 500}}; - while (startedCount != 3) ; - invoke = true; - std::for_each(std::begin(invocations), std::end(invocations), [](auto& t){ t.join(); }); - - ASSERT_THAT(results, ElementsAre(500, 1000, 1500)); -} - -TEST_F(SdbusTestObject, HandlesCorrectlyABulkOfParallelServerSideAsyncMethods) -{ - std::atomic resultCount{}; - std::atomic invoke{}; - std::atomic startedCount{}; - auto call = [&]() - { - TestingProxy proxy{INTERFACE_NAME, OBJECT_PATH}; - ++startedCount; - while (!invoke) ; - - size_t localResultCount{}; - for (size_t i = 0; i < 500; ++i) - { - auto result = proxy.doOperationAsync(i % 2); - if (result == (i % 2)) // Correct return value? - localResultCount++; - } - - resultCount += localResultCount; - }; - - std::thread invocations[]{std::thread{call}, std::thread{call}, std::thread{call}}; - while (startedCount != 3) ; - invoke = true; - std::for_each(std::begin(invocations), std::end(invocations), [](auto& t){ t.join(); }); - - ASSERT_THAT(resultCount, Eq(1500)); -} - -TEST_F(SdbusTestObject, InvokesMethodAsynchronouslyOnClientSide) -{ - std::promise promise; - auto future = promise.get_future(); - m_proxy->installDoOperationClientSideAsyncReplyHandler([&](uint32_t res, const sdbus::Error* err) - { - if (err == nullptr) - promise.set_value(res); - else - promise.set_exception(std::make_exception_ptr(*err)); - }); - - m_proxy->doOperationClientSideAsync(100); - - ASSERT_THAT(future.get(), Eq(100)); -} - -TEST_F(SdbusTestObject, InvokesErroneousMethodAsynchronouslyOnClientSide) -{ - std::promise promise; - auto future = promise.get_future(); - m_proxy->installDoOperationClientSideAsyncReplyHandler([&](uint32_t res, const sdbus::Error* err) - { - if (err == nullptr) - promise.set_value(res); - else - promise.set_exception(std::make_exception_ptr(*err)); - }); - - m_proxy->doErroneousOperationClientSideAsync(); - - ASSERT_THROW(future.get(), sdbus::Error); -} - -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("sdbuscpp.destination.that.does.not.exist", OBJECT_PATH); - ASSERT_THROW(proxy.getInt(), sdbus::Error); -} - -TEST_F(SdbusTestObject, FailsCallingMethodOnNonexistentObject) -{ - TestingProxy proxy(INTERFACE_NAME, "/sdbuscpp/path/that/does/not/exist"); - ASSERT_THROW(proxy.getInt(), sdbus::Error); -} - -#if LIBSYSTEMD_VERSION>=240 -TEST_F(SdbusTestObject, CanSetGeneralMethodTimeoutWithLibsystemdVersionGreaterThan239) -{ - s_connection->setMethodCallTimeout(5000000); - ASSERT_THAT(s_connection->getMethodCallTimeout(), Eq(5000000)); -} -#else -TEST_F(SdbusTestObject, CannotSetGeneralMethodTimeoutWithLibsystemdVersionLessThan240) -{ - ASSERT_THROW(s_connection->setMethodCallTimeout(5000000), sdbus::Error); - ASSERT_THROW(s_connection->getMethodCallTimeout(), sdbus::Error); -} -#endif - -// Signals - -TEST_F(SdbusTestObject, EmitsSimpleSignalSuccesfully) -{ - m_adaptor->emitSimpleSignal(); - - ASSERT_TRUE(waitUntil(m_proxy->m_gotSimpleSignal)); -} - -TEST_F(SdbusTestObject, EmitsSignalWithMapSuccesfully) -{ - m_adaptor->emitSignalWithMap({{0, "zero"}, {1, "one"}}); - - ASSERT_TRUE(waitUntil(m_proxy->m_gotSignalWithMap)); - ASSERT_THAT(m_proxy->m_mapFromSignal[0], Eq("zero")); - ASSERT_THAT(m_proxy->m_mapFromSignal[1], Eq("one")); -} - -TEST_F(SdbusTestObject, EmitsSignalWithVariantSuccesfully) -{ - double d = 3.14; - m_adaptor->emitSignalWithVariant(d); - - ASSERT_TRUE(waitUntil(m_proxy->m_gotSignalWithVariant)); - ASSERT_THAT(m_proxy->m_variantFromSignal, DoubleEq(d)); -} - -TEST_F(SdbusTestObject, EmitsSignalWithoutRegistrationSuccesfully) -{ - m_adaptor->emitSignalWithoutRegistration({"platform", {"av"}}); - - ASSERT_TRUE(waitUntil(m_proxy->m_gotSignalWithSignature)); - ASSERT_THAT(m_proxy->m_signatureFromSignal["platform"], Eq("av")); -} - -// Properties - -TEST_F(SdbusTestObject, ReadsReadOnlyPropertySuccesfully) -{ - ASSERT_THAT(m_proxy->state(), Eq(DEFAULT_STATE_VALUE)); -} - -TEST_F(SdbusTestObject, FailsWritingToReadOnlyProperty) -{ - ASSERT_THROW(m_proxy->state("new_value"), sdbus::Error); -} - -TEST_F(SdbusTestObject, WritesAndReadsReadWritePropertySuccesfully) -{ - uint32_t newActionValue = 5678; - - m_proxy->action(newActionValue); - - ASSERT_THAT(m_proxy->action(), Eq(newActionValue)); -} - -// Standard D-Bus interfaces - -TEST_F(SdbusTestObject, PingsViaPeerInterface) -{ - ASSERT_NO_THROW(m_proxy->Ping()); -} - -TEST_F(SdbusTestObject, AnswersMachineUuidViaPeerInterface) -{ - // If /etc/machine-id does not exist in your system (which is very likely because you have - // a non-systemd Linux), org.freedesktop.DBus.Peer.GetMachineId() will not work. To solve - // this, you can create /etc/machine-id yourself as symlink to /var/lib/dbus/machine-id, - // and then org.freedesktop.DBus.Peer.GetMachineId() will start to work. - if (::access("/etc/machine-id", F_OK) == -1) - GTEST_SKIP() << "/etc/machine-id file does not exist, GetMachineId() will not work"; - - ASSERT_NO_THROW(m_proxy->GetMachineId()); -} - -TEST_F(SdbusTestObject, AnswersXmlApiDescriptionViaIntrospectableInterface) -{ - ASSERT_THAT(m_proxy->Introspect(), Eq(m_adaptor->getExpectedXmlApiDescription())); -} - -TEST_F(SdbusTestObject, GetsPropertyViaPropertiesInterface) -{ - ASSERT_THAT(m_proxy->Get(INTERFACE_NAME, "state").get(), Eq(DEFAULT_STATE_VALUE)); -} - -TEST_F(SdbusTestObject, SetsPropertyViaPropertiesInterface) -{ - uint32_t newActionValue = 2345; - - m_proxy->Set(INTERFACE_NAME, "action", newActionValue); - - ASSERT_THAT(m_proxy->action(), Eq(newActionValue)); -} - -TEST_F(SdbusTestObject, GetsAllPropertiesViaPropertiesInterface) -{ - const auto properties = m_proxy->GetAll(INTERFACE_NAME); - - ASSERT_THAT(properties, SizeIs(3)); - EXPECT_THAT(properties.at("state").get(), Eq(DEFAULT_STATE_VALUE)); - EXPECT_THAT(properties.at("action").get(), Eq(DEFAULT_ACTION_VALUE)); - EXPECT_THAT(properties.at("blocking").get(), Eq(DEFAULT_BLOCKING_VALUE)); -} - -TEST_F(SdbusTestObject, EmitsPropertyChangedSignalForSelectedProperties) -{ - std::atomic signalReceived{false}; - m_proxy->m_onPropertiesChangedHandler = [&signalReceived]( const std::string& interfaceName - , const std::map& changedProperties - , const std::vector& /*invalidatedProperties*/ ) - { - EXPECT_THAT(interfaceName, Eq(INTERFACE_NAME)); - EXPECT_THAT(changedProperties, SizeIs(1)); - EXPECT_THAT(changedProperties.at("blocking").get(), Eq(!DEFAULT_BLOCKING_VALUE)); - signalReceived = true; - }; - - m_proxy->blocking(!DEFAULT_BLOCKING_VALUE); - m_proxy->action(DEFAULT_ACTION_VALUE*2); - m_adaptor->emitPropertiesChangedSignal(INTERFACE_NAME, {"blocking"}); - - ASSERT_TRUE(waitUntil(signalReceived)); -} - -TEST_F(SdbusTestObject, EmitsPropertyChangedSignalForAllProperties) -{ - std::atomic signalReceived{false}; - m_proxy->m_onPropertiesChangedHandler = [&signalReceived]( const std::string& interfaceName - , const std::map& changedProperties - , const std::vector& invalidatedProperties ) - { - EXPECT_THAT(interfaceName, Eq(INTERFACE_NAME)); - EXPECT_THAT(changedProperties, SizeIs(1)); - EXPECT_THAT(changedProperties.at("blocking").get(), Eq(DEFAULT_BLOCKING_VALUE)); - ASSERT_THAT(invalidatedProperties, SizeIs(1)); - EXPECT_THAT(invalidatedProperties[0], Eq("action")); - signalReceived = true; - }; - - m_adaptor->emitPropertiesChangedSignal(INTERFACE_NAME); - - ASSERT_TRUE(waitUntil(signalReceived)); -} - -TEST_F(SdbusTestObject, GetsZeroManagedObjectsIfHasNoSubPathObjects) -{ - const auto objectsInterfacesAndProperties = m_proxy->GetManagedObjects(); - - ASSERT_THAT(objectsInterfacesAndProperties, SizeIs(0)); -} - -TEST_F(SdbusTestObject, GetsManagedObjectsSuccessfully) -{ - auto subObject1 = sdbus::createObject(*s_connection, "/sub/path1"); - subObject1->registerProperty("aProperty1").onInterface("org.sdbuscpp.integrationtests.iface1").withGetter([]{return uint8_t{123};}); - subObject1->finishRegistration(); - auto subObject2 = sdbus::createObject(*s_connection, "/sub/path2"); - subObject2->registerProperty("aProperty2").onInterface("org.sdbuscpp.integrationtests.iface2").withGetter([]{return "hi";}); - subObject2->finishRegistration(); - - const auto objectsInterfacesAndProperties = m_proxy->GetManagedObjects(); - - ASSERT_THAT(objectsInterfacesAndProperties, SizeIs(2)); - EXPECT_THAT(objectsInterfacesAndProperties.at("/sub/path1").at("org.sdbuscpp.integrationtests.iface1").at("aProperty1").get(), Eq(123)); - EXPECT_THAT(objectsInterfacesAndProperties.at("/sub/path2").at("org.sdbuscpp.integrationtests.iface2").at("aProperty2").get(), Eq("hi")); -} - -TEST_F(SdbusTestObject, EmitsInterfacesAddedSignalForSelectedObjectInterfaces) -{ - std::atomic signalReceived{false}; - m_proxy->m_onInterfacesAddedHandler = [&signalReceived]( const sdbus::ObjectPath& objectPath - , const std::map>& interfacesAndProperties ) - { - EXPECT_THAT(objectPath, Eq(OBJECT_PATH)); - EXPECT_THAT(interfacesAndProperties, SizeIs(1)); - EXPECT_THAT(interfacesAndProperties.count(INTERFACE_NAME), Eq(1)); - EXPECT_THAT(interfacesAndProperties.at(INTERFACE_NAME), SizeIs(3)); - signalReceived = true; - }; - - m_adaptor->emitInterfacesAddedSignal({INTERFACE_NAME}); - - ASSERT_TRUE(waitUntil(signalReceived)); -} - -TEST_F(SdbusTestObject, EmitsInterfacesAddedSignalForAllObjectInterfaces) -{ - std::atomic signalReceived{false}; - m_proxy->m_onInterfacesAddedHandler = [&signalReceived]( const sdbus::ObjectPath& objectPath - , const std::map>& interfacesAndProperties ) - { - EXPECT_THAT(objectPath, Eq(OBJECT_PATH)); - EXPECT_THAT(interfacesAndProperties, SizeIs(5)); // INTERFACE_NAME + 4 standard interfaces - EXPECT_THAT(interfacesAndProperties.at(INTERFACE_NAME), SizeIs(3)); // 3 properties under INTERFACE_NAME - signalReceived = true; - }; - - m_adaptor->emitInterfacesAddedSignal(); - - ASSERT_TRUE(waitUntil(signalReceived)); -} - -TEST_F(SdbusTestObject, EmitsInterfacesRemovedSignalForSelectedObjectInterfaces) -{ - std::atomic signalReceived{false}; - m_proxy->m_onInterfacesRemovedHandler = [&signalReceived]( const sdbus::ObjectPath& objectPath - , const std::vector& interfaces ) - { - EXPECT_THAT(objectPath, Eq(OBJECT_PATH)); - ASSERT_THAT(interfaces, SizeIs(1)); - EXPECT_THAT(interfaces[0], Eq(INTERFACE_NAME)); - signalReceived = true; - }; - - m_adaptor->emitInterfacesRemovedSignal({INTERFACE_NAME}); - - ASSERT_TRUE(waitUntil(signalReceived)); -} - -TEST_F(SdbusTestObject, EmitsInterfacesRemovedSignalForAllObjectInterfaces) -{ - std::atomic signalReceived{false}; - m_proxy->m_onInterfacesRemovedHandler = [&signalReceived]( const sdbus::ObjectPath& objectPath - , const std::vector& interfaces ) - { - EXPECT_THAT(objectPath, Eq(OBJECT_PATH)); - ASSERT_THAT(interfaces, SizeIs(5)); // INTERFACE_NAME + 4 standard interfaces - signalReceived = true; - }; - - m_adaptor->emitInterfacesRemovedSignal(); - - ASSERT_TRUE(waitUntil(signalReceived)); -} +//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> a{}; +// auto vectorRes = m_proxy->getInts16FromStruct(a); +// ASSERT_THAT(vectorRes, Eq(std::vector{0})); // because second item is by default initialized to 0 + + +// sdbus::Struct> 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_VALUE, INT16_VALUE, -INT16_VALUE})); +//} + +//TEST_F(SdbusTestObject, CallsMethodWithVariantSuccesfully) +//{ +// sdbus::Variant v{DOUBLE_VALUE}; +// auto variantRes = m_proxy->processVariant(v); +// ASSERT_THAT(variantRes.get(), Eq(static_cast(DOUBLE_VALUE))); +//} + +//TEST_F(SdbusTestObject, CallsMethodWithStructVariantsAndGetMapSuccesfully) +//{ +// std::vector x{-2, 0, 2}; +// sdbus::Struct y{false, true}; +// auto mapOfVariants = m_proxy->getMapOfVariants(x, y); +// decltype(mapOfVariants) res{{-2, false}, {0, false}, {2, true}}; + +// ASSERT_THAT(mapOfVariants[-2].get(), Eq(res[-2].get())); +// ASSERT_THAT(mapOfVariants[0].get(), Eq(res[0].get())); +// ASSERT_THAT(mapOfVariants[2].get(), Eq(res[2].get())); +//} + +//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, CallsMethodWithUnixFdSuccesfully) +//{ +// auto resUnixFd = m_proxy->getUnixFd(); +// ASSERT_THAT(resUnixFd.get(), Gt(UNIX_FD_VALUE)); +//} + +//TEST_F(SdbusTestObject, CallsMethodWithComplexTypeSuccesfully) +//{ +// auto resComplex = m_proxy->getComplex(); +// ASSERT_THAT(resComplex.count(0), Eq(1)); +//} + +//TEST_F(SdbusTestObject, CallsMultiplyMethodWithNoReplyFlag) +//{ +// m_proxy->multiplyWithNoReply(INT64_VALUE, DOUBLE_VALUE); + +// ASSERT_TRUE(waitUntil(m_adaptor->m_wasMultiplyCalled)); +// ASSERT_THAT(m_adaptor->m_multiplyResult, Eq(INT64_VALUE * DOUBLE_VALUE)); +//} + +//TEST_F(SdbusTestObject, CallsMethodWithCustomTimeoutSuccessfully) +//{ +// auto res = m_proxy->doOperationWith500msTimeout(20); // The operation will take 20ms, but the timeout is 500ms, so we are fine +// ASSERT_THAT(res, Eq(20)); +//} + +//TEST_F(SdbusTestObject, ThrowsTimeoutErrorWhenMethodTimesOut) +//{ +// try +// { +// m_proxy->doOperationWith500msTimeout(1000); // The operation will take 1s, but the timeout is 500ms, so we should time out +// FAIL() << "Expected sdbus::Error exception"; +// } +// catch (const sdbus::Error& e) +// { +// ASSERT_THAT(e.getName(), Eq("org.freedesktop.DBus.Error.Timeout")); +// ASSERT_THAT(e.getMessage(), Eq("Connection timed out")); +// } +// catch(...) +// { +// FAIL() << "Expected sdbus::Error exception"; +// } +//} + +//TEST_F(SdbusTestObject, CallsMethodThatThrowsError) +//{ +// try +// { +// m_proxy->throwError(); +// FAIL() << "Expected sdbus::Error exception"; +// } +// catch (const sdbus::Error& e) +// { +// ASSERT_THAT(e.getName(), Eq("org.freedesktop.DBus.Error.AccessDenied")); +// ASSERT_THAT(e.getMessage(), Eq("A test error occurred (Operation not permitted)")); +// } +// catch(...) +// { +// FAIL() << "Expected sdbus::Error exception"; +// } +//} + +//TEST_F(SdbusTestObject, CallsErrorThrowingMethodWithDontExpectReplySet) +//{ +// ASSERT_NO_THROW(m_proxy->throwErrorWithNoReply()); + +// ASSERT_TRUE(waitUntil(m_adaptor->m_wasThrowErrorCalled)); +//} + +//TEST_F(SdbusTestObject, RunsServerSideAsynchoronousMethodAsynchronously) +//{ +// // Yeah, this is kinda timing-dependent test, but times should be safe... +// std::mutex mtx; +// std::vector results; +// std::atomic invoke{}; +// std::atomic startedCount{}; +// auto call = [&](uint32_t param) +// { +// TestingProxy proxy{INTERFACE_NAME, OBJECT_PATH}; +// ++startedCount; +// while (!invoke) ; +// auto result = proxy.doOperationAsync(param); +// std::lock_guard guard(mtx); +// results.push_back(result); +// }; + +// std::thread invocations[]{std::thread{call, 1500}, std::thread{call, 1000}, std::thread{call, 500}}; +// while (startedCount != 3) ; +// invoke = true; +// std::for_each(std::begin(invocations), std::end(invocations), [](auto& t){ t.join(); }); + +// ASSERT_THAT(results, ElementsAre(500, 1000, 1500)); +//} + +//TEST_F(SdbusTestObject, HandlesCorrectlyABulkOfParallelServerSideAsyncMethods) +//{ +// std::atomic resultCount{}; +// std::atomic invoke{}; +// std::atomic startedCount{}; +// auto call = [&]() +// { +// TestingProxy proxy{INTERFACE_NAME, OBJECT_PATH}; +// ++startedCount; +// while (!invoke) ; + +// size_t localResultCount{}; +// for (size_t i = 0; i < 500; ++i) +// { +// auto result = proxy.doOperationAsync(i % 2); +// if (result == (i % 2)) // Correct return value? +// localResultCount++; +// } + +// resultCount += localResultCount; +// }; + +// std::thread invocations[]{std::thread{call}, std::thread{call}, std::thread{call}}; +// while (startedCount != 3) ; +// invoke = true; +// std::for_each(std::begin(invocations), std::end(invocations), [](auto& t){ t.join(); }); + +// ASSERT_THAT(resultCount, Eq(1500)); +//} + +//TEST_F(SdbusTestObject, InvokesMethodAsynchronouslyOnClientSide) +//{ +// std::promise promise; +// auto future = promise.get_future(); +// m_proxy->installDoOperationClientSideAsyncReplyHandler([&](uint32_t res, const sdbus::Error* err) +// { +// if (err == nullptr) +// promise.set_value(res); +// else +// promise.set_exception(std::make_exception_ptr(*err)); +// }); + +// m_proxy->doOperationClientSideAsync(100); + +// ASSERT_THAT(future.get(), Eq(100)); +//} + +//TEST_F(SdbusTestObject, InvokesErroneousMethodAsynchronouslyOnClientSide) +//{ +// std::promise promise; +// auto future = promise.get_future(); +// m_proxy->installDoOperationClientSideAsyncReplyHandler([&](uint32_t res, const sdbus::Error* err) +// { +// if (err == nullptr) +// promise.set_value(res); +// else +// promise.set_exception(std::make_exception_ptr(*err)); +// }); + +// m_proxy->doErroneousOperationClientSideAsync(); + +// ASSERT_THROW(future.get(), sdbus::Error); +//} + +//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("sdbuscpp.destination.that.does.not.exist", OBJECT_PATH); +// ASSERT_THROW(proxy.getInt(), sdbus::Error); +//} + +//TEST_F(SdbusTestObject, FailsCallingMethodOnNonexistentObject) +//{ +// TestingProxy proxy(INTERFACE_NAME, "/sdbuscpp/path/that/does/not/exist"); +// ASSERT_THROW(proxy.getInt(), sdbus::Error); +//} + +//#if LIBSYSTEMD_VERSION>=240 +//TEST_F(SdbusTestObject, CanSetGeneralMethodTimeoutWithLibsystemdVersionGreaterThan239) +//{ +// s_connection->setMethodCallTimeout(5000000); +// ASSERT_THAT(s_connection->getMethodCallTimeout(), Eq(5000000)); +//} +//#else +//TEST_F(SdbusTestObject, CannotSetGeneralMethodTimeoutWithLibsystemdVersionLessThan240) +//{ +// ASSERT_THROW(s_connection->setMethodCallTimeout(5000000), sdbus::Error); +// ASSERT_THROW(s_connection->getMethodCallTimeout(), sdbus::Error); +//} +//#endif + +//// Signals + +//TEST_F(SdbusTestObject, EmitsSimpleSignalSuccesfully) +//{ +// m_adaptor->emitSimpleSignal(); + +// ASSERT_TRUE(waitUntil(m_proxy->m_gotSimpleSignal)); +//} + +//TEST_F(SdbusTestObject, EmitsSignalWithMapSuccesfully) +//{ +// m_adaptor->emitSignalWithMap({{0, "zero"}, {1, "one"}}); + +// ASSERT_TRUE(waitUntil(m_proxy->m_gotSignalWithMap)); +// ASSERT_THAT(m_proxy->m_mapFromSignal[0], Eq("zero")); +// ASSERT_THAT(m_proxy->m_mapFromSignal[1], Eq("one")); +//} + +//TEST_F(SdbusTestObject, EmitsSignalWithVariantSuccesfully) +//{ +// double d = 3.14; +// m_adaptor->emitSignalWithVariant(d); + +// ASSERT_TRUE(waitUntil(m_proxy->m_gotSignalWithVariant)); +// ASSERT_THAT(m_proxy->m_variantFromSignal, DoubleEq(d)); +//} + +//TEST_F(SdbusTestObject, EmitsSignalWithoutRegistrationSuccesfully) +//{ +// m_adaptor->emitSignalWithoutRegistration({"platform", {"av"}}); + +// ASSERT_TRUE(waitUntil(m_proxy->m_gotSignalWithSignature)); +// ASSERT_THAT(m_proxy->m_signatureFromSignal["platform"], Eq("av")); +//} + +//// Properties + +//TEST_F(SdbusTestObject, ReadsReadOnlyPropertySuccesfully) +//{ +// ASSERT_THAT(m_proxy->state(), Eq(DEFAULT_STATE_VALUE)); +//} + +//TEST_F(SdbusTestObject, FailsWritingToReadOnlyProperty) +//{ +// ASSERT_THROW(m_proxy->state("new_value"), sdbus::Error); +//} + +//TEST_F(SdbusTestObject, WritesAndReadsReadWritePropertySuccesfully) +//{ +// uint32_t newActionValue = 5678; + +// m_proxy->action(newActionValue); + +// ASSERT_THAT(m_proxy->action(), Eq(newActionValue)); +//} + +//// Standard D-Bus interfaces + +//TEST_F(SdbusTestObject, PingsViaPeerInterface) +//{ +// ASSERT_NO_THROW(m_proxy->Ping()); +//} + +//TEST_F(SdbusTestObject, AnswersMachineUuidViaPeerInterface) +//{ +// // If /etc/machine-id does not exist in your system (which is very likely because you have +// // a non-systemd Linux), org.freedesktop.DBus.Peer.GetMachineId() will not work. To solve +// // this, you can create /etc/machine-id yourself as symlink to /var/lib/dbus/machine-id, +// // and then org.freedesktop.DBus.Peer.GetMachineId() will start to work. +// if (::access("/etc/machine-id", F_OK) == -1) +// GTEST_SKIP() << "/etc/machine-id file does not exist, GetMachineId() will not work"; + +// ASSERT_NO_THROW(m_proxy->GetMachineId()); +//} + +//TEST_F(SdbusTestObject, AnswersXmlApiDescriptionViaIntrospectableInterface) +//{ +// ASSERT_THAT(m_proxy->Introspect(), Eq(m_adaptor->getExpectedXmlApiDescription())); +//} + +//TEST_F(SdbusTestObject, GetsPropertyViaPropertiesInterface) +//{ +// ASSERT_THAT(m_proxy->Get(INTERFACE_NAME, "state").get(), Eq(DEFAULT_STATE_VALUE)); +//} + +//TEST_F(SdbusTestObject, SetsPropertyViaPropertiesInterface) +//{ +// uint32_t newActionValue = 2345; + +// m_proxy->Set(INTERFACE_NAME, "action", newActionValue); + +// ASSERT_THAT(m_proxy->action(), Eq(newActionValue)); +//} + +//TEST_F(SdbusTestObject, GetsAllPropertiesViaPropertiesInterface) +//{ +// const auto properties = m_proxy->GetAll(INTERFACE_NAME); + +// ASSERT_THAT(properties, SizeIs(3)); +// EXPECT_THAT(properties.at("state").get(), Eq(DEFAULT_STATE_VALUE)); +// EXPECT_THAT(properties.at("action").get(), Eq(DEFAULT_ACTION_VALUE)); +// EXPECT_THAT(properties.at("blocking").get(), Eq(DEFAULT_BLOCKING_VALUE)); +//} + +//TEST_F(SdbusTestObject, EmitsPropertyChangedSignalForSelectedProperties) +//{ +// std::atomic signalReceived{false}; +// m_proxy->m_onPropertiesChangedHandler = [&signalReceived]( const std::string& interfaceName +// , const std::map& changedProperties +// , const std::vector& /*invalidatedProperties*/ ) +// { +// EXPECT_THAT(interfaceName, Eq(INTERFACE_NAME)); +// EXPECT_THAT(changedProperties, SizeIs(1)); +// EXPECT_THAT(changedProperties.at("blocking").get(), Eq(!DEFAULT_BLOCKING_VALUE)); +// signalReceived = true; +// }; + +// m_proxy->blocking(!DEFAULT_BLOCKING_VALUE); +// m_proxy->action(DEFAULT_ACTION_VALUE*2); +// m_adaptor->emitPropertiesChangedSignal(INTERFACE_NAME, {"blocking"}); + +// ASSERT_TRUE(waitUntil(signalReceived)); +//} + +//TEST_F(SdbusTestObject, EmitsPropertyChangedSignalForAllProperties) +//{ +// std::atomic signalReceived{false}; +// m_proxy->m_onPropertiesChangedHandler = [&signalReceived]( const std::string& interfaceName +// , const std::map& changedProperties +// , const std::vector& invalidatedProperties ) +// { +// EXPECT_THAT(interfaceName, Eq(INTERFACE_NAME)); +// EXPECT_THAT(changedProperties, SizeIs(1)); +// EXPECT_THAT(changedProperties.at("blocking").get(), Eq(DEFAULT_BLOCKING_VALUE)); +// ASSERT_THAT(invalidatedProperties, SizeIs(1)); +// EXPECT_THAT(invalidatedProperties[0], Eq("action")); +// signalReceived = true; +// }; + +// m_adaptor->emitPropertiesChangedSignal(INTERFACE_NAME); + +// ASSERT_TRUE(waitUntil(signalReceived)); +//} + +//TEST_F(SdbusTestObject, GetsZeroManagedObjectsIfHasNoSubPathObjects) +//{ +// const auto objectsInterfacesAndProperties = m_proxy->GetManagedObjects(); + +// ASSERT_THAT(objectsInterfacesAndProperties, SizeIs(0)); +//} + +//TEST_F(SdbusTestObject, GetsManagedObjectsSuccessfully) +//{ +// auto subObject1 = sdbus::createObject(*s_connection, "/sub/path1"); +// subObject1->registerProperty("aProperty1").onInterface("org.sdbuscpp.integrationtests.iface1").withGetter([]{return uint8_t{123};}); +// subObject1->finishRegistration(); +// auto subObject2 = sdbus::createObject(*s_connection, "/sub/path2"); +// subObject2->registerProperty("aProperty2").onInterface("org.sdbuscpp.integrationtests.iface2").withGetter([]{return "hi";}); +// subObject2->finishRegistration(); + +// const auto objectsInterfacesAndProperties = m_proxy->GetManagedObjects(); + +// ASSERT_THAT(objectsInterfacesAndProperties, SizeIs(2)); +// EXPECT_THAT(objectsInterfacesAndProperties.at("/sub/path1").at("org.sdbuscpp.integrationtests.iface1").at("aProperty1").get(), Eq(123)); +// EXPECT_THAT(objectsInterfacesAndProperties.at("/sub/path2").at("org.sdbuscpp.integrationtests.iface2").at("aProperty2").get(), Eq("hi")); +//} + +//TEST_F(SdbusTestObject, EmitsInterfacesAddedSignalForSelectedObjectInterfaces) +//{ +// std::atomic signalReceived{false}; +// m_proxy->m_onInterfacesAddedHandler = [&signalReceived]( const sdbus::ObjectPath& objectPath +// , const std::map>& interfacesAndProperties ) +// { +// EXPECT_THAT(objectPath, Eq(OBJECT_PATH)); +// EXPECT_THAT(interfacesAndProperties, SizeIs(1)); +// EXPECT_THAT(interfacesAndProperties.count(INTERFACE_NAME), Eq(1)); +// EXPECT_THAT(interfacesAndProperties.at(INTERFACE_NAME), SizeIs(3)); +// signalReceived = true; +// }; + +// m_adaptor->emitInterfacesAddedSignal({INTERFACE_NAME}); + +// ASSERT_TRUE(waitUntil(signalReceived)); +//} + +//TEST_F(SdbusTestObject, EmitsInterfacesAddedSignalForAllObjectInterfaces) +//{ +// std::atomic signalReceived{false}; +// m_proxy->m_onInterfacesAddedHandler = [&signalReceived]( const sdbus::ObjectPath& objectPath +// , const std::map>& interfacesAndProperties ) +// { +// EXPECT_THAT(objectPath, Eq(OBJECT_PATH)); +// EXPECT_THAT(interfacesAndProperties, SizeIs(5)); // INTERFACE_NAME + 4 standard interfaces +// EXPECT_THAT(interfacesAndProperties.at(INTERFACE_NAME), SizeIs(3)); // 3 properties under INTERFACE_NAME +// signalReceived = true; +// }; + +// m_adaptor->emitInterfacesAddedSignal(); + +// ASSERT_TRUE(waitUntil(signalReceived)); +//} + +//TEST_F(SdbusTestObject, EmitsInterfacesRemovedSignalForSelectedObjectInterfaces) +//{ +// std::atomic signalReceived{false}; +// m_proxy->m_onInterfacesRemovedHandler = [&signalReceived]( const sdbus::ObjectPath& objectPath +// , const std::vector& interfaces ) +// { +// EXPECT_THAT(objectPath, Eq(OBJECT_PATH)); +// ASSERT_THAT(interfaces, SizeIs(1)); +// EXPECT_THAT(interfaces[0], Eq(INTERFACE_NAME)); +// signalReceived = true; +// }; + +// m_adaptor->emitInterfacesRemovedSignal({INTERFACE_NAME}); + +// ASSERT_TRUE(waitUntil(signalReceived)); +//} + +//TEST_F(SdbusTestObject, EmitsInterfacesRemovedSignalForAllObjectInterfaces) +//{ +// std::atomic signalReceived{false}; +// m_proxy->m_onInterfacesRemovedHandler = [&signalReceived]( const sdbus::ObjectPath& objectPath +// , const std::vector& interfaces ) +// { +// EXPECT_THAT(objectPath, Eq(OBJECT_PATH)); +// ASSERT_THAT(interfaces, SizeIs(5)); // INTERFACE_NAME + 4 standard interfaces +// signalReceived = true; +// }; + +// m_adaptor->emitInterfacesRemovedSignal(); + +// ASSERT_TRUE(waitUntil(signalReceived)); +//} diff --git a/tests/integrationtests/TestingAdaptor.h b/tests/integrationtests/TestingAdaptor.h index 19caa2b..00d0adb 100644 --- a/tests/integrationtests/TestingAdaptor.h +++ b/tests/integrationtests/TestingAdaptor.h @@ -50,6 +50,20 @@ public: protected: + int32_t doSignalEmission() override + { + static int32_t counter = 0; + emitSimpleSignal(); + printf("First simple signal thrown\n"); + counter++; + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + //emitSimpleSignal(); + //printf("Second simple signal thrown\n"); + counter++; + + return counter; + } + void noArgNoReturn() const { } diff --git a/tests/integrationtests/TestingProxy.h b/tests/integrationtests/TestingProxy.h index d45254e..a183119 100644 --- a/tests/integrationtests/TestingProxy.h +++ b/tests/integrationtests/TestingProxy.h @@ -30,6 +30,10 @@ #include "proxy-glue.h" #include +#include +#include +#define gettid() syscall(SYS_gettid) + class TestingProxy : public sdbus::ProxyInterfaces< ::testing_proxy , sdbus::Peer_proxy , sdbus::Introspectable_proxy @@ -57,6 +61,7 @@ protected: void onSimpleSignal() override { m_gotSimpleSignal = true; + printf("Thread %d: Got simple signal\n", gettid()); } void onSignalWithMap(const std::map& m) override diff --git a/tests/integrationtests/adaptor-glue.h b/tests/integrationtests/adaptor-glue.h index 88bdaf8..1131cd9 100644 --- a/tests/integrationtests/adaptor-glue.h +++ b/tests/integrationtests/adaptor-glue.h @@ -59,6 +59,8 @@ protected: { object_.setInterfaceFlags(INTERFACE_NAME).markAsDeprecated().withPropertyUpdateBehavior(sdbus::Flags::EMITS_NO_SIGNAL); + object_.registerMethod("doSignalEmission").onInterface(INTERFACE_NAME).implementedAs([this](){ return this->doSignalEmission(); }); + 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(); }); @@ -150,6 +152,7 @@ private: protected: + virtual int32_t doSignalEmission() = 0; virtual void noArgNoReturn() const = 0; virtual int32_t getInt() const = 0; virtual std::tuple getTuple() const = 0; diff --git a/tests/integrationtests/proxy-glue.h b/tests/integrationtests/proxy-glue.h index fb2b768..8323a9a 100644 --- a/tests/integrationtests/proxy-glue.h +++ b/tests/integrationtests/proxy-glue.h @@ -56,6 +56,14 @@ protected: virtual void onDoOperationReply(uint32_t returnValue, const sdbus::Error* error) = 0; public: + int32_t doSignalEmission() + { + int32_t result; + object_.callMethod("doSignalEmission").onInterface(INTERFACE_NAME).storeResultsTo(result); + //object_.callMethodAsync("doSignalEmission").onInterface(INTERFACE_NAME).uponReplyInvoke([this](const sdbus::Error* error, int32_t returnValue){ printf("Async reply handler\n"); }); + return result; + } + void noArgNoReturn() { object_.callMethod("noArgNoReturn").onInterface(INTERFACE_NAME);