Skip to content

Commit

Permalink
iox-eclipse-iceoryx#1142 Add missing functions to waitset and notific…
Browse files Browse the repository at this point in the history
…ation_info

Signed-off-by: Marika Lehmann <[email protected]>
  • Loading branch information
FerdinandSpitzschnueffler committed Feb 23, 2022
1 parent 2121d9e commit 6ff6404
Show file tree
Hide file tree
Showing 5 changed files with 227 additions and 5 deletions.
15 changes: 14 additions & 1 deletion iceoryx_binding_c/include/iceoryx_binding_c/notification_info.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2020 by Apex.AI Inc. All rights reserved.
// Copyright (c) 2020 - 2022 by Apex.AI Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand All @@ -18,6 +18,7 @@
#define IOX_BINDING_C_EVENT_INFO_H

#include "iceoryx_binding_c/internal/c2cpp_binding.h"
#include "iceoryx_binding_c/service_discovery.h"
#include "iceoryx_binding_c/subscriber.h"
#include "iceoryx_binding_c/user_trigger.h"

Expand All @@ -43,6 +44,13 @@ bool iox_notification_info_does_originate_from_subscriber(iox_notification_info_
bool iox_notification_info_does_originate_from_user_trigger(iox_notification_info_t const self,
iox_user_trigger_t const user_trigger);

/// @brief does the notification originate from a certain service discovery
/// @param[in] self handle to notification info
/// @param[in] serviceDiscovery handle to serviceDiscovery in question
/// @return true if the notifiaction originates from the service discovery, otherwise false
bool iox_notification_info_does_originate_from_service_discovery(iox_notification_info_t const self,
iox_service_discovery_t const serviceDiscovery);

/// @brief acquires the handle of the subscriber origin
/// @param[in] self handle to notification info
/// @return the handle to the subscriber if the notification originated from a subscriber, otherwise NULL
Expand All @@ -53,6 +61,11 @@ iox_sub_t iox_notification_info_get_subscriber_origin(iox_notification_info_t co
/// @return the handle to the user trigger if the notification originated from a user trigger, otherwise NULL
iox_user_trigger_t iox_notification_info_get_user_trigger_origin(iox_notification_info_t const self);

/// @brief acquires the handle of the service discovery origin
/// @param[in] self handle to the notification info
/// @return the handle to the service discovery if the notification originated from a service discovery, otherwise NULL
iox_service_discovery_t iox_notification_info_get_service_discovery_origin(iox_notification_info_t const self);

/// @brief calls the callback of the notification
/// @param[in] self handle to notification info
void iox_notification_info_call(iox_notification_info_t const self);
Expand Down
42 changes: 41 additions & 1 deletion iceoryx_binding_c/include/iceoryx_binding_c/wait_set.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Copyright (c) 2020 by Robert Bosch GmbH. All rights reserved.
// Copyright (c) 2020 - 2021 Apex.AI Inc. All rights reserved.
// Copyright (c) 2020 - 2022 Apex.AI Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand All @@ -21,6 +21,7 @@
#include "iceoryx_binding_c/enums.h"
#include "iceoryx_binding_c/internal/c2cpp_binding.h"
#include "iceoryx_binding_c/notification_info.h"
#include "iceoryx_binding_c/service_discovery.h"
#include "iceoryx_binding_c/subscriber.h"
#include "iceoryx_binding_c/types.h"
#include "iceoryx_binding_c/user_trigger.h"
Expand Down Expand Up @@ -189,4 +190,43 @@ void iox_ws_detach_subscriber_state(iox_ws_t const self,
/// @param[in] usertrigger the user trigger which should be detached
void iox_ws_detach_user_trigger_event(iox_ws_t const self, iox_user_trigger_t const userTrigger);

/// @brief attaches a service discovery event to a waitset
/// @param[in] self handle to the waitset
/// @param[in] serviceDiscovery service discovery which emits the event
/// @param[in] serviceDiscoveryEvent the event which should be attached
/// @param[in] eventId an arbitrary id which will be tagged to the event
/// @param[in] callback a callback which is attached to the event
/// @return if the attaching was successfull it returns WaitSetResult_SUCCESS, otherwise
/// an enum which describes the error
ENUM iox_WaitSetResult iox_ws_attach_service_discovery_event(const iox_ws_t self,
const iox_service_discovery_t serviceDiscovery,
const ENUM iox_ServiceDiscoveryEvent serviceDiscoveryEvent,
const uint64_t eventId,
void (*callback)(iox_service_discovery_t));

/// @brief attaches a service discovery event to a waitset with additional context data for the callback
/// @param[in] self handle to the waitset
/// @param[in] serviceDiscovery service discovery which emits the event
/// @param[in] serviceDiscoveryEvent the event which should be attached
/// @param[in] eventId an arbitrary id which will be tagged to the event
/// @param[in] callback a callback which is attached to the event
/// @param[in] contextData a void pointer which is provided as second argument to the callback
/// @return if the attaching was successfull it returns WaitSetResult_SUCCESS, otherwise
/// an enum which describes the error
ENUM iox_WaitSetResult
iox_ws_attach_service_discovery_event_with_context_data(iox_ws_t const self,
iox_service_discovery_t const serviceDiscovery,
const ENUM iox_ServiceDiscoveryEvent serviceDiscoveryEvent,
const uint64_t eventId,
void (*callback)(iox_service_discovery_t, void*),
void* const contextData);

/// @brief detaches a service discovery event from a waitset
/// @param[in] self handle to the waitset
/// @param[in] serviceDiscovery the service discovery which should be detached
/// @param[in] serviceDiscoveryEvent the event which should be detached from the service discovery
void iox_ws_detach_service_discovery_event(iox_ws_t const self,
iox_service_discovery_t const serviceDiscovery,
const ENUM iox_ServiceDiscoveryEvent serviceDiscoveryEvent);

#endif
15 changes: 14 additions & 1 deletion iceoryx_binding_c/source/c_notification_info.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2020 by Apex.AI Inc. All rights reserved.
// Copyright (c) 2020 - 2022 by Apex.AI Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand All @@ -17,9 +17,11 @@
#include "iceoryx_binding_c/internal/cpp2c_subscriber.hpp"
#include "iceoryx_posh/popo/notification_info.hpp"
#include "iceoryx_posh/popo/user_trigger.hpp"
#include "iceoryx_posh/runtime/service_discovery.hpp"

using namespace iox;
using namespace iox::popo;
using namespace iox::runtime;

extern "C" {
#include "iceoryx_binding_c/notification_info.h"
Expand All @@ -44,6 +46,12 @@ bool iox_notification_info_does_originate_from_user_trigger(iox_notification_inf
return self->doesOriginateFrom(user_trigger);
}

bool iox_notification_info_does_originate_from_service_discovery(iox_notification_info_t const self,
iox_service_discovery_t const serviceDiscovery)
{
return self->doesOriginateFrom(serviceDiscovery);
}

iox_sub_t iox_notification_info_get_subscriber_origin(iox_notification_info_t const self)
{
return self->getOrigin<cpp2c_Subscriber>();
Expand All @@ -54,6 +62,11 @@ iox_user_trigger_t iox_notification_info_get_user_trigger_origin(iox_notificatio
return self->getOrigin<UserTrigger>();
}

iox_service_discovery_t iox_notification_info_get_service_discovery_origin(iox_notification_info_t const self)
{
return self->getOrigin<ServiceDiscovery>();
}

void iox_notification_info_call(iox_notification_info_t const self)
{
(*self)();
Expand Down
47 changes: 46 additions & 1 deletion iceoryx_binding_c/source/c_wait_set.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Copyright (c) 2020 by Robert Bosch GmbH. All rights reserved.
// Copyright (c) 2020 - 2021 by Apex.AI Inc. All rights reserved.
// Copyright (c) 2020 - 2022 by Apex.AI Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand All @@ -25,6 +25,7 @@

using namespace iox;
using namespace iox::popo;
using namespace iox::runtime;

extern "C" {
#include "iceoryx_binding_c/wait_set.h"
Expand Down Expand Up @@ -201,3 +202,47 @@ void iox_ws_detach_user_trigger_event(iox_ws_t const self, iox_user_trigger_t co
{
self->detachEvent(*userTrigger);
}

iox_WaitSetResult iox_ws_attach_service_discovery_event(const iox_ws_t self,
const iox_service_discovery_t serviceDiscovery,
const ENUM iox_ServiceDiscoveryEvent serviceDiscoveryEvent,
const uint64_t eventId,
void (*callback)(iox_service_discovery_t))
{
iox::cxx::Expects(self != nullptr);
iox::cxx::Expects(serviceDiscovery != nullptr);

auto result = self->attachEvent(
*serviceDiscovery, c2cpp::serviceDiscoveryEvent(serviceDiscoveryEvent), eventId, {callback, nullptr});
return (result.has_error()) ? cpp2c::waitSetResult(result.get_error()) : iox_WaitSetResult::WaitSetResult_SUCCESS;
}

iox_WaitSetResult
iox_ws_attach_service_discovery_event_with_context_data(iox_ws_t const self,
iox_service_discovery_t const serviceDiscovery,
const ENUM iox_ServiceDiscoveryEvent serviceDiscoveryEvent,
const uint64_t eventId,
void (*callback)(iox_service_discovery_t, void*),
void* const contextData)
{
iox::cxx::Expects(self != nullptr);
iox::cxx::Expects(serviceDiscovery != nullptr);

NotificationCallback<std::remove_pointer_t<iox_service_discovery_t>, void> notificationCallback;
notificationCallback.m_callback = callback;
notificationCallback.m_contextData = contextData;

auto result = self->attachEvent(
*serviceDiscovery, c2cpp::serviceDiscoveryEvent(serviceDiscoveryEvent), eventId, notificationCallback);
return (result.has_error()) ? cpp2c::waitSetResult(result.get_error()) : iox_WaitSetResult::WaitSetResult_SUCCESS;
}

void iox_ws_detach_service_discovery_event(iox_ws_t const self,
iox_service_discovery_t const serviceDiscovery,
const ENUM iox_ServiceDiscoveryEvent serviceDiscoveryEvent)
{
iox::cxx::Expects(self != nullptr);
iox::cxx::Expects(serviceDiscovery != nullptr);

self->detachEvent(*serviceDiscovery, c2cpp::serviceDiscoveryEvent(serviceDiscoveryEvent));
}
113 changes: 112 additions & 1 deletion iceoryx_binding_c/test/moduletests/test_wait_set.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Copyright (c) 2020 by Robert Bosch GmbH. All rights reserved.
// Copyright (c) 2021 by Apex.AI Inc. All rights reserved.
// Copyright (c) 2021 - 2022 by Apex.AI Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand All @@ -21,6 +21,8 @@
#include "iceoryx_posh/iceoryx_posh_types.hpp"
#include "iceoryx_posh/internal/popo/ports/subscriber_port_user.hpp"
#include "iceoryx_posh/popo/user_trigger.hpp"
#include "iceoryx_posh/runtime/service_discovery.hpp"
#include "iceoryx_posh/testing/mocks/posh_runtime_mock.hpp"
#include "mocks/wait_set_mock.hpp"

using namespace iox;
Expand Down Expand Up @@ -78,6 +80,7 @@ class iox_ws_test : public Test
}
}

std::unique_ptr<PoshRuntimeMock> runtimeMock = PoshRuntimeMock::create("rudi_ruessel");
const iox::capro::ServiceDescription TEST_SERVICE_DESCRIPTION{"a", "b", "c"};
iox::popo::SubscriberOptions m_subscriberOptions{MAX_CHUNKS_HELD_PER_SUBSCRIBER_SIMULTANEOUSLY, 0U};
cxx::vector<iox::popo::SubscriberPortData, MAX_NUMBER_OF_ATTACHMENTS_PER_WAITSET + 1U> m_portDataVector;
Expand Down Expand Up @@ -123,6 +126,17 @@ void userTriggerCallbackWithContextData(iox::popo::UserTrigger* userTrigger, voi
iox_ws_test::m_contextData = contextData;
}

void serviceDiscoveryCallback(iox_service_discovery_t serviceDiscovery)
{
iox_ws_test::m_callbackOrigin = serviceDiscovery;
}

void serviceDiscoveryCallbackWithContextData(iox_service_discovery_t serviceDiscovery, void* const contextData)
{
iox_ws_test::m_callbackOrigin = serviceDiscovery;
iox_ws_test::m_contextData = contextData;
}

} // namespace

TEST_F(iox_ws_test, InitWaitSetWithNullptrForStorageReturnsNullptr)
Expand Down Expand Up @@ -725,4 +739,101 @@ TEST_F(iox_ws_test, UserTriggerCallbackWithContextDataIsCalled)
EXPECT_THAT(m_contextData, Eq(&someContextData));
}

TEST_F(iox_ws_test, AttachingServiceDiscoveryEventWorks)
{
::testing::Test::RecordProperty("TEST_ID", "a8be9cbd-d9b6-45a3-b34f-d58fb864d40d");
iox_service_discovery_storage_t serviceDiscoveryStorage;
EXPECT_CALL(*runtimeMock, getMiddlewareSubscriber(_, _, _)).WillOnce(Return(&m_portDataVector[0]));

iox_service_discovery_t serviceDiscovery = iox_service_discovery_init(&serviceDiscoveryStorage);

EXPECT_THAT(iox_ws_size(m_sut), Eq(0));
iox_ws_attach_service_discovery_event(
m_sut, serviceDiscovery, ServiceDiscoveryEvent_SERVICE_REGISTRY_CHANGED, 0, nullptr);
EXPECT_THAT(iox_ws_size(m_sut), Eq(1));

iox_ws_detach_service_discovery_event(m_sut, serviceDiscovery, ServiceDiscoveryEvent_SERVICE_REGISTRY_CHANGED);
EXPECT_THAT(iox_ws_size(m_sut), Eq(0));
}

TEST_F(iox_ws_test, AttachingServiceDiscoveryEventWithContextDataWorks)
{
::testing::Test::RecordProperty("TEST_ID", "69515627-1590-4616-8502-975cd9256ecf");
iox_service_discovery_storage_t serviceDiscoveryStorage;
EXPECT_CALL(*runtimeMock, getMiddlewareSubscriber(_, _, _)).WillOnce(Return(&m_portDataVector[0]));

iox_service_discovery_t serviceDiscovery = iox_service_discovery_init(&serviceDiscoveryStorage);

EXPECT_THAT(iox_ws_size(m_sut), Eq(0));
iox_ws_attach_service_discovery_event_with_context_data(
m_sut, serviceDiscovery, ServiceDiscoveryEvent_SERVICE_REGISTRY_CHANGED, 0, nullptr, nullptr);
EXPECT_THAT(iox_ws_size(m_sut), Eq(1));

iox_ws_detach_service_discovery_event(m_sut, serviceDiscovery, ServiceDiscoveryEvent_SERVICE_REGISTRY_CHANGED);
EXPECT_THAT(iox_ws_size(m_sut), Eq(0));
}

void notifyServiceDiscovery(SubscriberPortData& portData)
{
iox::popo::ChunkQueuePusher<SubscriberChunkReceiverData_t> pusher{&portData.m_chunkReceiverData};
pusher.push(iox::mepoo::SharedChunk());
portData.m_chunkReceiverData.m_conditionVariableDataPtr->m_semaphore.post();
}

TEST_F(iox_ws_test, NotifyingServiceDiscoveryEventWorks)
{
::testing::Test::RecordProperty("TEST_ID", "945dcf94-4679-469f-aa47-1a87d536da72");
iox_service_discovery_storage_t serviceDiscoveryStorage;
EXPECT_CALL(*runtimeMock, getMiddlewareSubscriber(_, _, _)).WillOnce(Return(&m_portDataVector[0]));

iox_service_discovery_t serviceDiscovery = iox_service_discovery_init(&serviceDiscoveryStorage);

iox_ws_attach_service_discovery_event(
m_sut, serviceDiscovery, ServiceDiscoveryEvent_SERVICE_REGISTRY_CHANGED, 13, &serviceDiscoveryCallback);

notifyServiceDiscovery(m_portDataVector[0]);

ASSERT_THAT(iox_ws_wait(m_sut, m_eventInfoStorage, MAX_NUMBER_OF_ATTACHMENTS_PER_WAITSET, &m_missedElements),
Eq(1));
EXPECT_THAT(iox_notification_info_get_notification_id(m_eventInfoStorage[0]), Eq(13));
EXPECT_THAT(iox_notification_info_get_service_discovery_origin(m_eventInfoStorage[0]), Eq(serviceDiscovery));
EXPECT_TRUE(iox_notification_info_does_originate_from_service_discovery(m_eventInfoStorage[0], serviceDiscovery));
iox_notification_info_call(m_eventInfoStorage[0]);

EXPECT_THAT(m_callbackOrigin, Eq(static_cast<void*>(serviceDiscovery)));
EXPECT_THAT(m_contextData, Eq(nullptr));

iox_ws_detach_service_discovery_event(m_sut, serviceDiscovery, ServiceDiscoveryEvent_SERVICE_REGISTRY_CHANGED);
}

TEST_F(iox_ws_test, NotifyingServiceDiscoveryEventWithContextDataWorks)
{
::testing::Test::RecordProperty("TEST_ID", "510a0351-afeb-4c0f-a4b6-3032f1f3f831");
iox_service_discovery_storage_t serviceDiscoveryStorage;
EXPECT_CALL(*runtimeMock, getMiddlewareSubscriber(_, _, _)).WillOnce(Return(&m_portDataVector[0]));

iox_service_discovery_t serviceDiscovery = iox_service_discovery_init(&serviceDiscoveryStorage);

iox_ws_attach_service_discovery_event_with_context_data(m_sut,
serviceDiscovery,
ServiceDiscoveryEvent_SERVICE_REGISTRY_CHANGED,
31,
&serviceDiscoveryCallbackWithContextData,
&serviceDiscoveryStorage);

notifyServiceDiscovery(m_portDataVector[0]);

ASSERT_THAT(iox_ws_wait(m_sut, m_eventInfoStorage, MAX_NUMBER_OF_ATTACHMENTS_PER_WAITSET, &m_missedElements),
Eq(1));
EXPECT_THAT(iox_notification_info_get_notification_id(m_eventInfoStorage[0]), Eq(31));
EXPECT_THAT(iox_notification_info_get_service_discovery_origin(m_eventInfoStorage[0]), Eq(serviceDiscovery));
EXPECT_TRUE(iox_notification_info_does_originate_from_service_discovery(m_eventInfoStorage[0], serviceDiscovery));
iox_notification_info_call(m_eventInfoStorage[0]);

EXPECT_THAT(m_callbackOrigin, Eq(static_cast<void*>(serviceDiscovery)));
EXPECT_THAT(m_contextData, Eq(static_cast<void*>(&serviceDiscoveryStorage)));

iox_ws_detach_service_discovery_event(m_sut, serviceDiscovery, ServiceDiscoveryEvent_SERVICE_REGISTRY_CHANGED);
}

} // namespace

0 comments on commit 6ff6404

Please sign in to comment.