// Copyright (c) 2020 by Robert Bosch GmbH. 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. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // // SPDX-License-Identifier: Apache-2.0 #include "iceoryx_binding_c/internal/cpp2c_enum_translation.hpp" #include "iceoryx_binding_c/internal/cpp2c_subscriber.hpp" #include "iceoryx_hoofs/testing/timing_test.hpp" #include "iceoryx_posh/iceoryx_posh_types.hpp" #include "iceoryx_posh/internal/popo/ports/subscriber_port_user.hpp" #include "iceoryx_posh/popo/untyped_client.hpp" #include "iceoryx_posh/popo/untyped_server.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; using namespace iox::popo; using namespace iox::runtime; extern "C" { #include "iceoryx_binding_c/subscriber.h" #include "iceoryx_binding_c/types.h" #include "iceoryx_binding_c/user_trigger.h" #include "iceoryx_binding_c/wait_set.h" } #include "test.hpp" #include #include namespace { using namespace ::testing; namespace { class iox_ws_test : public Test { public: void SetUp() override { m_callbackOrigin = nullptr; m_contextData = nullptr; for (uint64_t i = 0U; i <= MAX_NUMBER_OF_ATTACHMENTS_PER_WAITSET; ++i) { m_portDataVector.emplace_back(TEST_SERVICE_DESCRIPTION, "someAppName", iox::cxx::VariantQueueTypes::SoFi_SingleProducerSingleConsumer, m_subscriberOptions); m_subscriberVector.emplace_back(); m_subscriberVector[i].m_portData = &m_portDataVector[i]; } for (uint64_t i = 0U; i <= MAX_NUMBER_OF_ATTACHMENTS_PER_WAITSET; ++i) { m_userTrigger.emplace_back(iox_user_trigger_init(&m_userTriggerStorage[i])); } } void TearDown() override { delete m_sut; for (auto trigger : m_userTrigger) { iox_user_trigger_deinit(trigger); } } std::unique_ptr 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 m_portDataVector; cxx::vector m_subscriberVector; ConditionVariableData m_condVar{"Horscht"}; WaitSetMock* m_sut = new WaitSetMock{m_condVar}; iox_user_trigger_storage_t m_userTriggerStorage[MAX_NUMBER_OF_ATTACHMENTS_PER_WAITSET + 1]; cxx::vector m_userTrigger; iox_notification_info_t m_eventInfoStorage[MAX_NUMBER_OF_ATTACHMENTS_PER_WAITSET]; uint64_t m_missedElements = 0U; uint64_t m_numberOfTriggeredConditions = 0U; timespec m_timeout{0, 0}; iox::mepoo::MemoryManager memoryManager; ClientPortData clientPortData{{"ServiceA", "InstanceA", "EventA"}, "rudi_ruessel", ClientOptions(), &memoryManager}; iox_client_storage_t clientStorage; ServerPortData serverPortData{ {"ServiceA", "InstanceA", "EventA"}, "hypnotoad_loves_iceoryx", ServerOptions(), &memoryManager}; iox_server_storage_t serverStorage; static void* m_callbackOrigin; static void* m_contextData; }; void* iox_ws_test::m_callbackOrigin = nullptr; void* iox_ws_test::m_contextData = nullptr; void subscriberCallback(iox_sub_t subscriber) { iox_ws_test::m_callbackOrigin = subscriber; } void subscriberCallbackWithContextData(iox_sub_t subscriber, void* const contextData) { iox_ws_test::m_callbackOrigin = subscriber; iox_ws_test::m_contextData = contextData; } void userTriggerCallback(iox::popo::UserTrigger* userTrigger) { iox_ws_test::m_callbackOrigin = userTrigger; } void userTriggerCallbackWithContextData(iox::popo::UserTrigger* userTrigger, void* const contextData) { iox_ws_test::m_callbackOrigin = userTrigger; iox_ws_test::m_contextData = contextData; } void clientCallback(iox::popo::UntypedClient* client) { iox_ws_test::m_callbackOrigin = client; } void clientCallbackWithContextData(iox::popo::UntypedClient* client, void* const contextData) { iox_ws_test::m_callbackOrigin = client; iox_ws_test::m_contextData = contextData; } void serverCallback(iox::popo::UntypedServer* server) { iox_ws_test::m_callbackOrigin = server; } void serverCallbackWithContextData(iox::popo::UntypedServer* server, void* const contextData) { iox_ws_test::m_callbackOrigin = server; 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 /// @todo iox-#1106 will be enabled when worked on this issue TEST_F(iox_ws_test, DISABLED_InitWaitSetWithNullptrForStorageReturnsNullptr) { ::testing::Test::RecordProperty("TEST_ID", "c0f6b413-de1f-441f-916e-aa158fbfdde3"); EXPECT_EQ(iox_ws_init(nullptr), nullptr); } TEST_F(iox_ws_test, CapacityIsCorrect) { ::testing::Test::RecordProperty("TEST_ID", "ab5c64d3-0f74-4aa5-8e8d-8419c3ad71ed"); EXPECT_EQ(iox_ws_capacity(m_sut), MAX_NUMBER_OF_ATTACHMENTS_PER_WAITSET); } TEST_F(iox_ws_test, SizeIsZeroWhenConstructed) { ::testing::Test::RecordProperty("TEST_ID", "64bf992a-0089-43ba-a3ef-bfd411843b27"); EXPECT_EQ(iox_ws_size(m_sut), 0U); } TEST_F(iox_ws_test, SizeIsOneWhenOneUserTriggerIsAttached) { ::testing::Test::RecordProperty("TEST_ID", "3fd08c7e-7eda-4586-a737-e803ca3ba995"); EXPECT_EQ(iox_ws_attach_user_trigger_event(m_sut, m_userTrigger[0U], 0U, userTriggerCallback), iox_WaitSetResult::WaitSetResult_SUCCESS); EXPECT_EQ(iox_ws_size(m_sut), 1U); } TEST_F(iox_ws_test, SizeIsOneWhenOneSubscriberStateIsAttached) { ::testing::Test::RecordProperty("TEST_ID", "401d63e6-0708-49a2-b8b1-f8447d82e660"); constexpr uint64_t customId = 123U; EXPECT_EQ(iox_ws_attach_subscriber_state( m_sut, &m_subscriberVector[0U], SubscriberState_HAS_DATA, customId, subscriberCallback), iox_WaitSetResult::WaitSetResult_SUCCESS); EXPECT_EQ(iox_ws_size(m_sut), 1U); } TEST_F(iox_ws_test, SizeIsOneWhenOneUserTriggerWithNullptrCallBackIsAttached) { ::testing::Test::RecordProperty("TEST_ID", "3bb92cc8-a3cf-4ac8-8df8-6047ea1228c2"); EXPECT_EQ(iox_ws_attach_user_trigger_event(m_sut, m_userTrigger[0U], 0U, NULL), iox_WaitSetResult::WaitSetResult_SUCCESS); EXPECT_EQ(iox_ws_size(m_sut), 1U); } TEST_F(iox_ws_test, SizeIsOneWhenOneSubscriberStateWithNullptrCallBackIsAttached) { ::testing::Test::RecordProperty("TEST_ID", "dd04bf28-3ae5-4903-b46b-f09da31b46ce"); constexpr uint64_t customId = 123U; EXPECT_EQ(iox_ws_attach_subscriber_state(m_sut, &m_subscriberVector[0U], SubscriberState_HAS_DATA, customId, NULL), iox_WaitSetResult::WaitSetResult_SUCCESS); EXPECT_EQ(iox_ws_size(m_sut), 1U); } TEST_F(iox_ws_test, SizeIsOneWhenOneSubscriberEventIsAttached) { ::testing::Test::RecordProperty("TEST_ID", "2becf5a5-f6ba-4e65-abfb-8880b1f0789d"); constexpr uint64_t customId = 123U; EXPECT_EQ(iox_ws_attach_subscriber_event( m_sut, &m_subscriberVector[0U], SubscriberEvent_DATA_RECEIVED, customId, subscriberCallback), iox_WaitSetResult::WaitSetResult_SUCCESS); EXPECT_EQ(iox_ws_size(m_sut), 1U); } TEST_F(iox_ws_test, SizeIsOneWhenOneSubscriberEventWithNullptrCallBackIsAttached) { ::testing::Test::RecordProperty("TEST_ID", "b6aafb13-8da0-4058-bcbf-d84d4dc39aa5"); constexpr uint64_t customId = 123U; EXPECT_EQ( iox_ws_attach_subscriber_event(m_sut, &m_subscriberVector[0U], SubscriberEvent_DATA_RECEIVED, customId, NULL), iox_WaitSetResult::WaitSetResult_SUCCESS); EXPECT_EQ(iox_ws_size(m_sut), 1U); } TEST_F(iox_ws_test, AttachingMoreUserTriggerThanCapacityAvailableFails) { ::testing::Test::RecordProperty("TEST_ID", "c696900b-7ef0-4f32-8666-7340b52cef1e"); for (uint64_t i = 0U; i < MAX_NUMBER_OF_ATTACHMENTS_PER_WAITSET; ++i) { EXPECT_EQ(iox_ws_attach_user_trigger_event(m_sut, m_userTrigger[i], 0U, userTriggerCallback), iox_WaitSetResult::WaitSetResult_SUCCESS); EXPECT_EQ(iox_ws_size(m_sut), i + 1U); } EXPECT_EQ(iox_ws_attach_user_trigger_event( m_sut, m_userTrigger[MAX_NUMBER_OF_ATTACHMENTS_PER_WAITSET], 0U, userTriggerCallback), iox_WaitSetResult::WaitSetResult_WAIT_SET_FULL); } TEST_F(iox_ws_test, AttachingMoreSubscriberStatesThanCapacityAvailableFails) { ::testing::Test::RecordProperty("TEST_ID", "f69eb949-255a-483d-bcde-9af45ec67ab8"); constexpr uint64_t customId = 123U; for (uint64_t i = 0U; i < MAX_NUMBER_OF_ATTACHMENTS_PER_WAITSET; ++i) { EXPECT_EQ(iox_ws_attach_subscriber_state( m_sut, &m_subscriberVector[i], SubscriberState_HAS_DATA, customId, subscriberCallback), iox_WaitSetResult::WaitSetResult_SUCCESS); EXPECT_EQ(iox_ws_size(m_sut), i + 1U); } EXPECT_EQ(iox_ws_attach_subscriber_state(m_sut, &m_subscriberVector[MAX_NUMBER_OF_ATTACHMENTS_PER_WAITSET], SubscriberState_HAS_DATA, customId, subscriberCallback), iox_WaitSetResult::WaitSetResult_WAIT_SET_FULL); } TEST_F(iox_ws_test, AttachingMoreSubscriberEventsThanCapacityAvailableFails) { ::testing::Test::RecordProperty("TEST_ID", "555dd52c-222a-40da-8311-15046db418eb"); constexpr uint64_t customId = 123U; for (uint64_t i = 0U; i < MAX_NUMBER_OF_ATTACHMENTS_PER_WAITSET; ++i) { EXPECT_EQ(iox_ws_attach_subscriber_event( m_sut, &m_subscriberVector[i], SubscriberEvent_DATA_RECEIVED, customId, subscriberCallback), iox_WaitSetResult::WaitSetResult_SUCCESS); EXPECT_EQ(iox_ws_size(m_sut), i + 1U); } EXPECT_EQ(iox_ws_attach_subscriber_event(m_sut, &m_subscriberVector[MAX_NUMBER_OF_ATTACHMENTS_PER_WAITSET], SubscriberEvent_DATA_RECEIVED, customId, subscriberCallback), iox_WaitSetResult::WaitSetResult_WAIT_SET_FULL); } TEST_F(iox_ws_test, SizeDecreasesWhenAttachedUserTriggerIsDeinitialized) { ::testing::Test::RecordProperty("TEST_ID", "7d1dccce-0712-4242-b6c9-54060d4827f6"); iox_ws_attach_user_trigger_event(m_sut, m_userTrigger[0U], 0U, userTriggerCallback); iox_ws_detach_user_trigger_event(m_sut, m_userTrigger[0U]); EXPECT_EQ(iox_ws_size(m_sut), 0U); } TEST_F(iox_ws_test, SizeDecreasesWhenAttachedSubscriberStateIsDeinitialized) { ::testing::Test::RecordProperty("TEST_ID", "a985dee5-7e4f-43f5-b6f3-7f8a2a500202"); constexpr uint64_t customId = 123U; EXPECT_EQ(iox_ws_attach_subscriber_state( m_sut, &m_subscriberVector[0U], SubscriberState_HAS_DATA, customId, subscriberCallback), iox_WaitSetResult::WaitSetResult_SUCCESS); iox_ws_detach_subscriber_state(m_sut, &m_subscriberVector[0U], SubscriberState_HAS_DATA); EXPECT_EQ(iox_ws_size(m_sut), 0U); } TEST_F(iox_ws_test, SizeDecreasesWhenAttachedSubscriberEventIsDeinitialized) { ::testing::Test::RecordProperty("TEST_ID", "f332215a-d2b6-49c9-a2bd-ba71c7ee3612"); constexpr uint64_t customId = 123U; EXPECT_EQ(iox_ws_attach_subscriber_event( m_sut, &m_subscriberVector[0U], SubscriberEvent_DATA_RECEIVED, customId, subscriberCallback), iox_WaitSetResult::WaitSetResult_SUCCESS); iox_ws_detach_subscriber_event(m_sut, &m_subscriberVector[0U], SubscriberEvent_DATA_RECEIVED); EXPECT_EQ(iox_ws_size(m_sut), 0U); } TEST_F(iox_ws_test, NumberOfTriggeredConditionsIsOneWhenOneWasTriggered) { ::testing::Test::RecordProperty("TEST_ID", "b1fbf9fd-fbae-439d-94f5-41e5d9756fd2"); iox_ws_attach_user_trigger_event(m_sut, m_userTrigger[0U], 0U, userTriggerCallback); iox_user_trigger_trigger(m_userTrigger[0U]); EXPECT_EQ(iox_ws_wait(m_sut, m_eventInfoStorage, MAX_NUMBER_OF_ATTACHMENTS_PER_WAITSET, &m_missedElements), 1U); } TEST_F(iox_ws_test, NumberOfTriggeredConditionsIsCorrectWhenMultipleWereTriggered) { ::testing::Test::RecordProperty("TEST_ID", "da1f3eaa-fbdd-4ab1-844e-ba48ba6989f9"); for (uint64_t i = 0U; i < 10U; ++i) { iox_ws_attach_user_trigger_event(m_sut, m_userTrigger[i], 0U, userTriggerCallback); iox_user_trigger_trigger(m_userTrigger[i]); } EXPECT_EQ(iox_ws_wait(m_sut, m_eventInfoStorage, MAX_NUMBER_OF_ATTACHMENTS_PER_WAITSET, &m_missedElements), 10U); } TEST_F(iox_ws_test, NumberOfTriggeredConditionsIsCorrectWhenAllWereTriggered) { ::testing::Test::RecordProperty("TEST_ID", "74a629b1-bd15-4acb-8ae0-4ee926c594a8"); for (uint64_t i = 0U; i < MAX_NUMBER_OF_ATTACHMENTS_PER_WAITSET; ++i) { iox_ws_attach_user_trigger_event(m_sut, m_userTrigger[i], 0U, userTriggerCallback); iox_user_trigger_trigger(m_userTrigger[i]); } EXPECT_EQ(iox_ws_wait(m_sut, m_eventInfoStorage, MAX_NUMBER_OF_ATTACHMENTS_PER_WAITSET, &m_missedElements), MAX_NUMBER_OF_ATTACHMENTS_PER_WAITSET); } TEST_F(iox_ws_test, SingleTriggerCaseWaitReturnsCorrectTrigger) { ::testing::Test::RecordProperty("TEST_ID", "dd35162d-a076-43b3-bc3b-fcc574c6b5cf"); iox_ws_attach_user_trigger_event(m_sut, m_userTrigger[0], 5678U, userTriggerCallback); iox_user_trigger_trigger(m_userTrigger[0U]); iox_ws_wait(m_sut, m_eventInfoStorage, MAX_NUMBER_OF_ATTACHMENTS_PER_WAITSET, &m_missedElements); iox_notification_info_t eventInfo = m_eventInfoStorage[0U]; EXPECT_EQ(iox_notification_info_get_notification_id(eventInfo), 5678U); EXPECT_TRUE(iox_notification_info_does_originate_from_user_trigger(eventInfo, m_userTrigger[0U])); } TEST_F(iox_ws_test, MultiTriggerCaseWaitReturnsCorrectTrigger) { ::testing::Test::RecordProperty("TEST_ID", "c3bfe540-950b-4f70-bb8b-7f7c1500de29"); for (uint64_t i = 0U; i < 8; ++i) { iox_ws_attach_user_trigger_event(m_sut, m_userTrigger[i], 1337U + i, userTriggerCallback); iox_user_trigger_trigger(m_userTrigger[i]); } iox_ws_wait(m_sut, m_eventInfoStorage, MAX_NUMBER_OF_ATTACHMENTS_PER_WAITSET, &m_missedElements); for (uint64_t i = 0U; i < 8; ++i) { iox_notification_info_t eventInfo = m_eventInfoStorage[i]; EXPECT_EQ(iox_notification_info_get_notification_id(eventInfo), 1337U + i); EXPECT_TRUE(iox_notification_info_does_originate_from_user_trigger(eventInfo, m_userTrigger[i])); } } TEST_F(iox_ws_test, MaxTriggerCaseWaitReturnsCorrectTrigger) { ::testing::Test::RecordProperty("TEST_ID", "a76d77ee-cc02-4532-b792-209794200bf8"); for (uint64_t i = 0U; i < MAX_NUMBER_OF_ATTACHMENTS_PER_WAITSET; ++i) { iox_ws_attach_user_trigger_event(m_sut, m_userTrigger[i], 42U * i + 1U, userTriggerCallback); iox_user_trigger_trigger(m_userTrigger[i]); } iox_ws_wait(m_sut, m_eventInfoStorage, MAX_NUMBER_OF_ATTACHMENTS_PER_WAITSET, &m_missedElements); for (uint64_t i = 0U; i < MAX_NUMBER_OF_ATTACHMENTS_PER_WAITSET; ++i) { iox_notification_info_t eventInfo = m_eventInfoStorage[i]; EXPECT_EQ(iox_notification_info_get_notification_id(eventInfo), 42U * i + 1U); EXPECT_TRUE(iox_notification_info_does_originate_from_user_trigger(eventInfo, m_userTrigger[i])); } } TEST_F(iox_ws_test, TimedWaitNumberOfTriggeredConditionsIsOneWhenOneWasTriggered) { ::testing::Test::RecordProperty("TEST_ID", "6648bcce-acfc-4e2c-b2ed-1e8ad3284a51"); iox_ws_attach_user_trigger_event(m_sut, m_userTrigger[0U], 0U, userTriggerCallback); iox_user_trigger_trigger(m_userTrigger[0U]); EXPECT_EQ(iox_ws_timed_wait( m_sut, m_timeout, m_eventInfoStorage, MAX_NUMBER_OF_ATTACHMENTS_PER_WAITSET, &m_missedElements), 1U); } TEST_F(iox_ws_test, TimedWaitNumberOfTriggeredConditionsIsCorrectWhenMultipleWereTriggered) { ::testing::Test::RecordProperty("TEST_ID", "3630ed3f-3cbe-4724-b802-c45556e5d7ba"); for (uint64_t i = 0U; i < 10U; ++i) { iox_ws_attach_user_trigger_event(m_sut, m_userTrigger[i], 0U, userTriggerCallback); iox_user_trigger_trigger(m_userTrigger[i]); } EXPECT_EQ(iox_ws_timed_wait( m_sut, m_timeout, m_eventInfoStorage, MAX_NUMBER_OF_ATTACHMENTS_PER_WAITSET, &m_missedElements), 10U); } TEST_F(iox_ws_test, TimedWaitNumberOfTriggeredConditionsIsCorrectWhenAllWereTriggered) { ::testing::Test::RecordProperty("TEST_ID", "028f2b58-42b7-4300-8da9-b1ed036a51d8"); for (uint64_t i = 0U; i < MAX_NUMBER_OF_ATTACHMENTS_PER_WAITSET; ++i) { iox_ws_attach_user_trigger_event(m_sut, m_userTrigger[i], 0U, userTriggerCallback); iox_user_trigger_trigger(m_userTrigger[i]); } EXPECT_EQ(iox_ws_timed_wait( m_sut, m_timeout, m_eventInfoStorage, MAX_NUMBER_OF_ATTACHMENTS_PER_WAITSET, &m_missedElements), MAX_NUMBER_OF_ATTACHMENTS_PER_WAITSET); } TEST_F(iox_ws_test, SingleTriggerCaseTimedWaitReturnsCorrectTrigger) { ::testing::Test::RecordProperty("TEST_ID", "6fae144f-056b-4ac6-a849-3cd47135e2db"); iox_ws_attach_user_trigger_event(m_sut, m_userTrigger[0U], 5678U, userTriggerCallback); iox_user_trigger_trigger(m_userTrigger[0U]); iox_ws_timed_wait(m_sut, m_timeout, m_eventInfoStorage, MAX_NUMBER_OF_ATTACHMENTS_PER_WAITSET, &m_missedElements); iox_notification_info_t eventInfo = m_eventInfoStorage[0U]; EXPECT_EQ(iox_notification_info_get_notification_id(eventInfo), 5678U); EXPECT_TRUE(iox_notification_info_does_originate_from_user_trigger(eventInfo, m_userTrigger[0U])); } TEST_F(iox_ws_test, MultiTriggerCaseTimedWaitReturnsCorrectTrigger) { ::testing::Test::RecordProperty("TEST_ID", "f1e8811e-117d-4a73-a46f-7ecbb26b0bf5"); for (uint64_t i = 0U; i < 8U; ++i) { iox_ws_attach_user_trigger_event(m_sut, m_userTrigger[i], 1337U + i, userTriggerCallback); iox_user_trigger_trigger(m_userTrigger[i]); } iox_ws_timed_wait(m_sut, m_timeout, m_eventInfoStorage, MAX_NUMBER_OF_ATTACHMENTS_PER_WAITSET, &m_missedElements); for (uint64_t i = 0U; i < 8U; ++i) { iox_notification_info_t eventInfo = m_eventInfoStorage[i]; EXPECT_EQ(iox_notification_info_get_notification_id(eventInfo), 1337U + i); EXPECT_TRUE(iox_notification_info_does_originate_from_user_trigger(eventInfo, m_userTrigger[i])); } } TEST_F(iox_ws_test, MaxTriggerCaseTimedWaitReturnsCorrectTrigger) { ::testing::Test::RecordProperty("TEST_ID", "343429f9-acba-498f-8b9b-20379960daf6"); for (uint64_t i = 0U; i < MAX_NUMBER_OF_ATTACHMENTS_PER_WAITSET; ++i) { iox_ws_attach_user_trigger_event(m_sut, m_userTrigger[i], 42U * i + 1U, userTriggerCallback); iox_user_trigger_trigger(m_userTrigger[i]); } iox_ws_timed_wait(m_sut, m_timeout, m_eventInfoStorage, MAX_NUMBER_OF_ATTACHMENTS_PER_WAITSET, &m_missedElements); for (uint64_t i = 0U; i < MAX_NUMBER_OF_ATTACHMENTS_PER_WAITSET; ++i) { iox_notification_info_t eventInfo = m_eventInfoStorage[i]; EXPECT_EQ(iox_notification_info_get_notification_id(eventInfo), 42U * i + 1U); EXPECT_TRUE(iox_notification_info_does_originate_from_user_trigger(eventInfo, m_userTrigger[i])); } } TEST_F(iox_ws_test, MissedElementsIsZeroWhenNothingWasMissed) { ::testing::Test::RecordProperty("TEST_ID", "4080a285-1b64-4be2-9a50-909c102f05cd"); for (uint64_t i = 0U; i < 12U; ++i) { iox_ws_attach_user_trigger_event(m_sut, m_userTrigger[i], 0U, userTriggerCallback); iox_user_trigger_trigger(m_userTrigger[i]); } iox_ws_wait(m_sut, m_eventInfoStorage, MAX_NUMBER_OF_ATTACHMENTS_PER_WAITSET, &m_missedElements); EXPECT_EQ(m_missedElements, 0U); } TEST_F(iox_ws_test, MissedElementsIsCorrectWhenSomethingWasMissed) { ::testing::Test::RecordProperty("TEST_ID", "3b0fa82f-3358-4faa-b83e-569e71fad362"); for (uint64_t i = 0U; i < 12U; ++i) { iox_ws_attach_user_trigger_event(m_sut, m_userTrigger[i], 0U, userTriggerCallback); iox_user_trigger_trigger(m_userTrigger[i]); } iox_ws_wait(m_sut, m_eventInfoStorage, 8U, &m_missedElements); EXPECT_EQ(m_missedElements, 4U); } TEST_F(iox_ws_test, MissedElementsIsCorrectWhenAllWereMissed) { ::testing::Test::RecordProperty("TEST_ID", "502a351f-3388-40a2-bf77-96c019b986f1"); for (uint64_t i = 0U; i < MAX_NUMBER_OF_ATTACHMENTS_PER_WAITSET; ++i) { iox_ws_attach_user_trigger_event(m_sut, m_userTrigger[i], 0U, userTriggerCallback); iox_user_trigger_trigger(m_userTrigger[i]); } iox_ws_wait(m_sut, m_eventInfoStorage, 0U, &m_missedElements); EXPECT_EQ(m_missedElements, MAX_NUMBER_OF_ATTACHMENTS_PER_WAITSET); } TIMING_TEST_F(iox_ws_test, WaitIsBlockingTillTriggered, Repeat(5), [&] { iox_ws_attach_user_trigger_event(m_sut, m_userTrigger[0U], 0U, userTriggerCallback); std::atomic_bool waitWasCalled{false}; std::thread t([&] { iox_ws_wait(m_sut, NULL, 0U, &m_missedElements); waitWasCalled.store(true); }); std::this_thread::sleep_for(std::chrono::milliseconds(100)); TIMING_TEST_EXPECT_FALSE(waitWasCalled.load()); iox_user_trigger_trigger(m_userTrigger[0U]); t.join(); TIMING_TEST_EXPECT_TRUE(waitWasCalled.load()); }); TIMING_TEST_F(iox_ws_test, WaitIsNonBlockingAfterMarkForDestruction, Repeat(5), [&] { std::atomic_bool waitWasCalled{false}; std::thread t([&] { iox_ws_wait(m_sut, NULL, 0U, &m_missedElements); iox_ws_wait(m_sut, NULL, 0U, &m_missedElements); iox_ws_wait(m_sut, NULL, 0U, &m_missedElements); waitWasCalled.store(true); }); std::this_thread::sleep_for(std::chrono::milliseconds(100)); TIMING_TEST_EXPECT_FALSE(waitWasCalled.load()); iox_ws_mark_for_destruction(m_sut); t.join(); TIMING_TEST_EXPECT_TRUE(waitWasCalled.load()); }); TIMING_TEST_F(iox_ws_test, TimedWaitIsBlockingTillTriggered, Repeat(5), [&] { iox_ws_attach_user_trigger_event(m_sut, m_userTrigger[0U], 0U, userTriggerCallback); std::atomic_bool waitWasCalled{false}; std::thread t([&] { iox_ws_timed_wait(m_sut, {1000, 1000}, NULL, 0U, &m_missedElements); waitWasCalled.store(true); }); std::this_thread::sleep_for(std::chrono::milliseconds(100)); TIMING_TEST_EXPECT_FALSE(waitWasCalled.load()); iox_user_trigger_trigger(m_userTrigger[0U]); t.join(); TIMING_TEST_EXPECT_TRUE(waitWasCalled.load()); }); TIMING_TEST_F(iox_ws_test, TimedWaitIsNonBlockingAfterMarkForDestruction, Repeat(5), [&] { std::atomic_bool waitWasCalled{false}; std::thread t([&] { iox_ws_timed_wait(m_sut, {1000, 1000}, NULL, 0U, &m_missedElements); iox_ws_timed_wait(m_sut, {1000, 1000}, NULL, 0U, &m_missedElements); iox_ws_timed_wait(m_sut, {1000, 1000}, NULL, 0U, &m_missedElements); waitWasCalled.store(true); }); std::this_thread::sleep_for(std::chrono::milliseconds(100)); TIMING_TEST_EXPECT_FALSE(waitWasCalled.load()); iox_ws_mark_for_destruction(m_sut); t.join(); TIMING_TEST_EXPECT_TRUE(waitWasCalled.load()); }); TIMING_TEST_F(iox_ws_test, TimedWaitBlocksTillTimeout, Repeat(5), [&] { iox_ws_attach_user_trigger_event(m_sut, m_userTrigger[0U], 0U, userTriggerCallback); std::atomic_bool waitWasCalled{false}; std::thread t([&] { constexpr long hundredMsInNanoSeconds = 100000000L; iox_ws_timed_wait(m_sut, {0, hundredMsInNanoSeconds}, NULL, 0U, &m_missedElements); waitWasCalled.store(true); }); std::this_thread::sleep_for(std::chrono::milliseconds(75)); TIMING_TEST_EXPECT_FALSE(waitWasCalled.load()); std::this_thread::sleep_for(std::chrono::milliseconds(75)); TIMING_TEST_EXPECT_TRUE(waitWasCalled.load()); t.join(); }); TEST_F(iox_ws_test, SubscriberEventCallbackIsCalled) { ::testing::Test::RecordProperty("TEST_ID", "431a93cb-a3ac-4ec8-9f7d-1739cd8bb748"); iox_ws_attach_subscriber_event( m_sut, &m_subscriberVector[0], iox_SubscriberEvent::SubscriberEvent_DATA_RECEIVED, 0, &subscriberCallback); m_subscriberVector[0].m_trigger.trigger(); ASSERT_THAT(iox_ws_wait(m_sut, m_eventInfoStorage, 1U, &m_missedElements), Eq(1U)); EXPECT_EQ(m_missedElements, 0U); iox_notification_info_call(m_eventInfoStorage[0]); EXPECT_THAT(m_callbackOrigin, Eq(&m_subscriberVector[0])); } TEST_F(iox_ws_test, NullptrSubscriberEventCallbackIsCalledWithoutError) { ::testing::Test::RecordProperty("TEST_ID", "5a1ad4d9-cfdb-4e3c-b3b9-82a42e8f2e31"); iox_ws_attach_subscriber_event( m_sut, &m_subscriberVector[0], iox_SubscriberEvent::SubscriberEvent_DATA_RECEIVED, 0, NULL); m_subscriberVector[0].m_trigger.trigger(); ASSERT_THAT(iox_ws_wait(m_sut, m_eventInfoStorage, 1U, &m_missedElements), Eq(1U)); EXPECT_EQ(m_missedElements, 0U); iox_notification_info_call(m_eventInfoStorage[0]); EXPECT_THAT(m_callbackOrigin, nullptr); } TEST_F(iox_ws_test, SubscriberEventCallbackWithContextDataIsCalled) { ::testing::Test::RecordProperty("TEST_ID", "9ae20a03-cd0a-4e42-bfa0-83ef77dc5ea3"); uint64_t someContextData = 0U; iox_ws_attach_subscriber_event_with_context_data(m_sut, &m_subscriberVector[0], iox_SubscriberEvent::SubscriberEvent_DATA_RECEIVED, 0, &subscriberCallbackWithContextData, &someContextData); m_subscriberVector[0].m_trigger.trigger(); ASSERT_THAT(iox_ws_wait(m_sut, m_eventInfoStorage, 1U, &m_missedElements), Eq(1U)); EXPECT_EQ(m_missedElements, 0U); iox_notification_info_call(m_eventInfoStorage[0]); EXPECT_THAT(m_callbackOrigin, Eq(&m_subscriberVector[0])); EXPECT_THAT(m_contextData, Eq(&someContextData)); } TEST_F(iox_ws_test, SubscriberStateCallbackIsCalled) { ::testing::Test::RecordProperty("TEST_ID", "1c4443a6-c3f8-441e-baad-ee7058eadbb6"); iox_ws_attach_subscriber_state( m_sut, &m_subscriberVector[0], iox_SubscriberState::SubscriberState_HAS_DATA, 0, &subscriberCallback); m_subscriberVector[0].m_portData->m_chunkReceiverData.m_queue.push(iox::mepoo::ShmSafeUnmanagedChunk()); m_subscriberVector[0].m_trigger.trigger(); ASSERT_THAT(iox_ws_wait(m_sut, m_eventInfoStorage, 1U, &m_missedElements), Eq(1U)); EXPECT_EQ(m_missedElements, 0U); iox_notification_info_call(m_eventInfoStorage[0]); EXPECT_THAT(m_callbackOrigin, Eq(&m_subscriberVector[0])); } TEST_F(iox_ws_test, SubscriberStateCallbackWithContextDataIsCalled) { ::testing::Test::RecordProperty("TEST_ID", "3cb801d8-6ae3-40d9-ac0c-92bcc65b29b5"); uint64_t someContextData = 0U; iox_ws_attach_subscriber_state_with_context_data(m_sut, &m_subscriberVector[0], iox_SubscriberState::SubscriberState_HAS_DATA, 0, &subscriberCallbackWithContextData, &someContextData); m_subscriberVector[0].m_portData->m_chunkReceiverData.m_queue.push(iox::mepoo::ShmSafeUnmanagedChunk()); m_subscriberVector[0].m_trigger.trigger(); ASSERT_THAT(iox_ws_wait(m_sut, m_eventInfoStorage, 1U, &m_missedElements), Eq(1U)); EXPECT_EQ(m_missedElements, 0U); iox_notification_info_call(m_eventInfoStorage[0]); EXPECT_THAT(m_callbackOrigin, Eq(&m_subscriberVector[0])); EXPECT_THAT(m_contextData, Eq(&someContextData)); } TEST_F(iox_ws_test, UserTriggerCallbackIsCalled) { ::testing::Test::RecordProperty("TEST_ID", "f0e72c64-1da7-48c3-8677-79cc0c441b8a"); iox_ws_attach_user_trigger_event(m_sut, m_userTrigger[0], 0, &userTriggerCallback); iox_user_trigger_trigger(m_userTrigger[0]); ASSERT_THAT(iox_ws_wait(m_sut, m_eventInfoStorage, 1U, &m_missedElements), Eq(1U)); EXPECT_EQ(m_missedElements, 0U); iox_notification_info_call(m_eventInfoStorage[0]); EXPECT_THAT(m_callbackOrigin, Eq(m_userTrigger[0])); } TEST_F(iox_ws_test, NullptrUserTriggerCallbackIsCalledWithoutError) { ::testing::Test::RecordProperty("TEST_ID", "dcaa2891-b5b3-4c6e-9344-74cef54a6520"); iox_ws_attach_user_trigger_event(m_sut, m_userTrigger[0], 0, NULL); iox_user_trigger_trigger(m_userTrigger[0]); ASSERT_THAT(iox_ws_wait(m_sut, m_eventInfoStorage, 1U, &m_missedElements), Eq(1U)); EXPECT_EQ(m_missedElements, 0U); iox_notification_info_call(m_eventInfoStorage[0]); EXPECT_THAT(m_callbackOrigin, nullptr); } TEST_F(iox_ws_test, UserTriggerCallbackWithContextDataIsCalled) { ::testing::Test::RecordProperty("TEST_ID", "901ceeb3-8c3c-4007-a980-f8928044fa83"); uint64_t someContextData = 0U; iox_ws_attach_user_trigger_event_with_context_data( m_sut, m_userTrigger[0], 0, &userTriggerCallbackWithContextData, &someContextData); iox_user_trigger_trigger(m_userTrigger[0]); ASSERT_THAT(iox_ws_wait(m_sut, m_eventInfoStorage, 1U, &m_missedElements), Eq(1U)); EXPECT_EQ(m_missedElements, 0U); iox_notification_info_call(m_eventInfoStorage[0]); EXPECT_THAT(m_callbackOrigin, Eq(m_userTrigger[0])); EXPECT_THAT(m_contextData, Eq(&someContextData)); } TEST_F(iox_ws_test, AttachingClientEventWorks) { ::testing::Test::RecordProperty("TEST_ID", "8024ff87-166a-4d4c-8cc9-c1f277d30247"); EXPECT_CALL(*runtimeMock, getMiddlewareClient(_, _, _)).WillOnce(Return(&clientPortData)); iox_client_t client = iox_client_init(&clientStorage, "ServiceA", "InstanceA", "EventA", nullptr); EXPECT_THAT(iox_ws_size(m_sut), Eq(0U)); iox_ws_attach_client_event(m_sut, client, ClientEvent_RESPONSE_RECEIVED, 0, nullptr); EXPECT_THAT(iox_ws_size(m_sut), Eq(1U)); iox_ws_detach_client_event(m_sut, client, ClientEvent_RESPONSE_RECEIVED); EXPECT_THAT(iox_ws_size(m_sut), Eq(0U)); iox_client_deinit(client); } void notifyClient(ClientPortData& portData) { portData.m_connectRequested.store(true); portData.m_connectionState = iox::ConnectionState::CONNECTED; iox::popo::ChunkQueuePusher pusher{&portData.m_chunkReceiverData}; pusher.push(iox::mepoo::SharedChunk()); EXPECT_FALSE(portData.m_chunkReceiverData.m_conditionVariableDataPtr->m_semaphore.post().has_error()); } TEST_F(iox_ws_test, NotifyingClientEventWorks) { ::testing::Test::RecordProperty("TEST_ID", "7d460351-f1ee-4538-94ee-40a59e82e877"); EXPECT_CALL(*runtimeMock, getMiddlewareClient(_, _, _)).WillOnce(Return(&clientPortData)); iox_client_t client = iox_client_init(&clientStorage, "ServiceA", "InstanceA", "EventA", nullptr); iox_ws_attach_client_event(m_sut, client, ClientEvent_RESPONSE_RECEIVED, 13137, &clientCallback); notifyClient(clientPortData); ASSERT_THAT(iox_ws_wait(m_sut, m_eventInfoStorage, MAX_NUMBER_OF_ATTACHMENTS_PER_WAITSET, &m_missedElements), Eq(1U)); EXPECT_THAT(iox_notification_info_get_notification_id(m_eventInfoStorage[0]), Eq(13137)); EXPECT_THAT(iox_notification_info_get_client_origin(m_eventInfoStorage[0]), Eq(client)); EXPECT_TRUE(iox_notification_info_does_originate_from_client(m_eventInfoStorage[0], client)); iox_notification_info_call(m_eventInfoStorage[0]); EXPECT_THAT(m_callbackOrigin, Eq(static_cast(client))); EXPECT_THAT(m_contextData, Eq(nullptr)); iox_ws_detach_client_event(m_sut, client, ClientEvent_RESPONSE_RECEIVED); iox_client_deinit(client); } TEST_F(iox_ws_test, NotifyingClientEventWithContextDataWorks) { ::testing::Test::RecordProperty("TEST_ID", "6f1017b4-5edf-44aa-80ab-a4e438816082"); EXPECT_CALL(*runtimeMock, getMiddlewareClient(_, _, _)).WillOnce(Return(&clientPortData)); iox_client_t client = iox_client_init(&clientStorage, "ServiceA", "InstanceA", "EventA", nullptr); uint64_t someContextData = 0U; iox_ws_attach_client_event_with_context_data( m_sut, client, ClientEvent_RESPONSE_RECEIVED, 89123, &clientCallbackWithContextData, &someContextData); notifyClient(clientPortData); 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_client_origin(m_eventInfoStorage[0]), Eq(client)); EXPECT_TRUE(iox_notification_info_does_originate_from_client(m_eventInfoStorage[0], client)); EXPECT_THAT(iox_notification_info_get_notification_id(m_eventInfoStorage[0]), Eq(89123)); iox_notification_info_call(m_eventInfoStorage[0]); EXPECT_THAT(m_callbackOrigin, Eq(static_cast(client))); EXPECT_THAT(m_contextData, Eq(static_cast(&someContextData))); iox_ws_detach_client_event(m_sut, client, ClientEvent_RESPONSE_RECEIVED); iox_client_deinit(client); } TEST_F(iox_ws_test, AttachingClientStateWorks) { ::testing::Test::RecordProperty("TEST_ID", "3eecba2f-07be-4073-8596-a7d2d2966f96"); EXPECT_CALL(*runtimeMock, getMiddlewareClient(_, _, _)).WillOnce(Return(&clientPortData)); iox_client_t client = iox_client_init(&clientStorage, "ServiceA", "InstanceA", "EventA", nullptr); EXPECT_THAT(iox_ws_size(m_sut), Eq(0)); iox_ws_attach_client_state(m_sut, client, ClientState_HAS_RESPONSE, 0, nullptr); EXPECT_THAT(iox_ws_size(m_sut), Eq(1)); iox_ws_detach_client_state(m_sut, client, ClientState_HAS_RESPONSE); EXPECT_THAT(iox_ws_size(m_sut), Eq(0)); iox_client_deinit(client); } TEST_F(iox_ws_test, NotifyingClientStateWorks) { ::testing::Test::RecordProperty("TEST_ID", "9464c3a0-4669-43fe-9edf-0996f744801e"); EXPECT_CALL(*runtimeMock, getMiddlewareClient(_, _, _)).WillOnce(Return(&clientPortData)); iox_client_t client = iox_client_init(&clientStorage, "ServiceA", "InstanceA", "EventA", nullptr); iox_ws_attach_client_state(m_sut, client, ClientState_HAS_RESPONSE, 1589123, &clientCallback); notifyClient(clientPortData); 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(1589123)); EXPECT_THAT(iox_notification_info_get_client_origin(m_eventInfoStorage[0]), Eq(client)); EXPECT_TRUE(iox_notification_info_does_originate_from_client(m_eventInfoStorage[0], client)); iox_notification_info_call(m_eventInfoStorage[0]); EXPECT_THAT(m_callbackOrigin, Eq(static_cast(client))); EXPECT_THAT(m_contextData, Eq(nullptr)); iox_ws_detach_client_state(m_sut, client, ClientState_HAS_RESPONSE); iox_client_deinit(client); } TEST_F(iox_ws_test, NotifyingClientStateWithContextDataWorks) { ::testing::Test::RecordProperty("TEST_ID", "f0f25612-dc08-40a9-9b2c-646b2e003e85"); EXPECT_CALL(*runtimeMock, getMiddlewareClient(_, _, _)).WillOnce(Return(&clientPortData)); iox_client_t client = iox_client_init(&clientStorage, "ServiceA", "InstanceA", "EventA", nullptr); uint64_t someContextData = 0U; iox_ws_attach_client_state_with_context_data( m_sut, client, ClientState_HAS_RESPONSE, 0, &clientCallbackWithContextData, &someContextData); notifyClient(clientPortData); 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_client_origin(m_eventInfoStorage[0]), Eq(client)); EXPECT_TRUE(iox_notification_info_does_originate_from_client(m_eventInfoStorage[0], client)); iox_notification_info_call(m_eventInfoStorage[0]); EXPECT_THAT(m_callbackOrigin, Eq(static_cast(client))); EXPECT_THAT(m_contextData, Eq(static_cast(&someContextData))); iox_ws_detach_client_state(m_sut, client, ClientState_HAS_RESPONSE); iox_client_deinit(client); } ////////////////////// /// BEGIN server tests ////////////////////// void notifyServer(ServerPortData& portData) { iox::popo::ChunkQueuePusher pusher{&portData.m_chunkReceiverData}; pusher.push(iox::mepoo::SharedChunk()); EXPECT_FALSE(portData.m_chunkReceiverData.m_conditionVariableDataPtr->m_semaphore.post().has_error()); } TEST_F(iox_ws_test, AttachingServerEventWorks) { ::testing::Test::RecordProperty("TEST_ID", "a4e3fe5f-59a4-4cba-851d-77d4951eed72"); iox_server_storage_t serverStorage; EXPECT_CALL(*runtimeMock, getMiddlewareServer(_, _, _)).WillOnce(Return(&serverPortData)); iox_server_t server = iox_server_init(&serverStorage, "ServiceA", "InstanceA", "EventA", nullptr); EXPECT_THAT(iox_ws_size(m_sut), Eq(0)); iox_ws_attach_server_event(m_sut, server, ServerEvent_REQUEST_RECEIVED, 0, nullptr); EXPECT_THAT(iox_ws_size(m_sut), Eq(1)); iox_ws_detach_server_event(m_sut, server, ServerEvent_REQUEST_RECEIVED); EXPECT_THAT(iox_ws_size(m_sut), Eq(0)); iox_server_deinit(server); } TEST_F(iox_ws_test, AttachingServerEventWithContextDataWorks) { ::testing::Test::RecordProperty("TEST_ID", "1254df23-88ff-46fe-ba37-239066599b35"); iox_server_storage_t serverStorage; EXPECT_CALL(*runtimeMock, getMiddlewareServer(_, _, _)).WillOnce(Return(&serverPortData)); iox_server_t server = iox_server_init(&serverStorage, "ServiceA", "InstanceA", "EventA", nullptr); uint64_t someContextData = 0U; EXPECT_THAT(iox_ws_size(m_sut), Eq(0)); iox_ws_attach_server_event_with_context_data( m_sut, server, ServerEvent_REQUEST_RECEIVED, 0, serverCallbackWithContextData, &someContextData); EXPECT_THAT(iox_ws_size(m_sut), Eq(1)); iox_ws_detach_server_event(m_sut, server, ServerEvent_REQUEST_RECEIVED); EXPECT_THAT(iox_ws_size(m_sut), Eq(0)); iox_server_deinit(server); } TEST_F(iox_ws_test, NotifyingServerEventWorks) { ::testing::Test::RecordProperty("TEST_ID", "003b92c9-3607-4247-8385-3d03085fa574"); EXPECT_CALL(*runtimeMock, getMiddlewareServer(_, _, _)).WillOnce(Return(&serverPortData)); iox_server_t server = iox_server_init(&serverStorage, "ServiceA", "InstanceA", "EventA", nullptr); constexpr uint64_t SOME_EVENT_ID = 1313799; iox_ws_attach_server_event(m_sut, server, ServerEvent_REQUEST_RECEIVED, SOME_EVENT_ID, &serverCallback); notifyServer(serverPortData); 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(SOME_EVENT_ID)); EXPECT_THAT(iox_notification_info_get_server_origin(m_eventInfoStorage[0]), Eq(server)); EXPECT_TRUE(iox_notification_info_does_originate_from_server(m_eventInfoStorage[0], server)); iox_notification_info_call(m_eventInfoStorage[0]); EXPECT_THAT(m_callbackOrigin, Eq(static_cast(server))); EXPECT_THAT(m_contextData, Eq(nullptr)); iox_ws_detach_server_event(m_sut, server, ServerEvent_REQUEST_RECEIVED); iox_server_deinit(server); } TEST_F(iox_ws_test, NotifyingServerEventWithContextDataWorks) { ::testing::Test::RecordProperty("TEST_ID", "a08df13b-ad50-4753-9a1d-07b306d6f8d2"); EXPECT_CALL(*runtimeMock, getMiddlewareServer(_, _, _)).WillOnce(Return(&serverPortData)); iox_server_t server = iox_server_init(&serverStorage, "ServiceA", "InstanceA", "EventA", nullptr); constexpr uint64_t SOME_EVENT_ID = 5123901293; uint64_t someContextData = 0U; iox_ws_attach_server_event_with_context_data( m_sut, server, ServerEvent_REQUEST_RECEIVED, SOME_EVENT_ID, &serverCallbackWithContextData, &someContextData); notifyServer(serverPortData); 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(SOME_EVENT_ID)); EXPECT_THAT(iox_notification_info_get_server_origin(m_eventInfoStorage[0]), Eq(server)); EXPECT_TRUE(iox_notification_info_does_originate_from_server(m_eventInfoStorage[0], server)); iox_notification_info_call(m_eventInfoStorage[0]); EXPECT_THAT(m_callbackOrigin, Eq(static_cast(server))); EXPECT_THAT(m_contextData, Eq(static_cast(&someContextData))); iox_ws_detach_server_event(m_sut, server, ServerEvent_REQUEST_RECEIVED); iox_server_deinit(server); } TEST_F(iox_ws_test, AttachingServerStateWorks) { ::testing::Test::RecordProperty("TEST_ID", "7a29c16e-f164-420e-8824-785df24ae8f3"); EXPECT_CALL(*runtimeMock, getMiddlewareServer(_, _, _)).WillOnce(Return(&serverPortData)); iox_server_t server = iox_server_init(&serverStorage, "ServiceA", "InstanceA", "EventA", nullptr); EXPECT_THAT(iox_ws_size(m_sut), Eq(0)); iox_ws_attach_server_state(m_sut, server, ServerState_HAS_REQUEST, 0, nullptr); EXPECT_THAT(iox_ws_size(m_sut), Eq(1)); iox_ws_detach_server_state(m_sut, server, ServerState_HAS_REQUEST); EXPECT_THAT(iox_ws_size(m_sut), Eq(0)); iox_server_deinit(server); } TEST_F(iox_ws_test, NotifyingServerStateWorks) { ::testing::Test::RecordProperty("TEST_ID", "0fc37898-5aa1-416c-ab19-e64a428ad5ba"); EXPECT_CALL(*runtimeMock, getMiddlewareServer(_, _, _)).WillOnce(Return(&serverPortData)); constexpr uint64_t SOME_EVENT_ID = 9012314; iox_server_t server = iox_server_init(&serverStorage, "ServiceA", "InstanceA", "EventA", nullptr); iox_ws_attach_server_state(m_sut, server, ServerState_HAS_REQUEST, SOME_EVENT_ID, &serverCallback); notifyServer(serverPortData); 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(SOME_EVENT_ID)); EXPECT_THAT(iox_notification_info_get_server_origin(m_eventInfoStorage[0]), Eq(server)); EXPECT_TRUE(iox_notification_info_does_originate_from_server(m_eventInfoStorage[0], server)); iox_notification_info_call(m_eventInfoStorage[0]); EXPECT_THAT(m_callbackOrigin, Eq(static_cast(server))); EXPECT_THAT(m_contextData, Eq(nullptr)); iox_ws_detach_server_state(m_sut, server, ServerState_HAS_REQUEST); iox_server_deinit(server); } TEST_F(iox_ws_test, NotifyingServerStateWithContextDataWorks) { ::testing::Test::RecordProperty("TEST_ID", "29905ac6-e146-4bd8-a1d9-a0626ff0ee54"); EXPECT_CALL(*runtimeMock, getMiddlewareServer(_, _, _)).WillOnce(Return(&serverPortData)); constexpr uint64_t SOME_EVENT_ID = 912371012314; iox_server_t server = iox_server_init(&serverStorage, "ServiceA", "InstanceA", "EventA", nullptr); uint64_t someContextData = 0U; iox_ws_attach_server_state_with_context_data( m_sut, server, ServerState_HAS_REQUEST, SOME_EVENT_ID, &serverCallbackWithContextData, &someContextData); notifyServer(serverPortData); 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(SOME_EVENT_ID)); EXPECT_THAT(iox_notification_info_get_server_origin(m_eventInfoStorage[0]), Eq(server)); EXPECT_TRUE(iox_notification_info_does_originate_from_server(m_eventInfoStorage[0], server)); iox_notification_info_call(m_eventInfoStorage[0]); EXPECT_THAT(m_callbackOrigin, Eq(static_cast(server))); EXPECT_THAT(m_contextData, Eq(static_cast(&someContextData))); iox_ws_detach_server_state(m_sut, server, ServerState_HAS_REQUEST); iox_server_deinit(server); } //////////////////// /// END server tests //////////////////// 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)); iox_service_discovery_deinit(serviceDiscovery); } 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)); iox_service_discovery_deinit(serviceDiscovery); } void notifyServiceDiscovery(SubscriberPortData& portData) { iox::popo::ChunkQueuePusher pusher{&portData.m_chunkReceiverData}; pusher.push(iox::mepoo::SharedChunk()); EXPECT_FALSE(portData.m_chunkReceiverData.m_conditionVariableDataPtr->m_semaphore.post().has_error()); } TEST_F(iox_ws_test, NotifyingServiceDiscoveryEventWorks) { ::testing::Test::RecordProperty("TEST_ID", "945dcf94-4679-469f-aa47-1a87d536da72"); constexpr uint64_t EVENT_ID = 13; 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, EVENT_ID, &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(EVENT_ID)); 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(serviceDiscovery))); EXPECT_THAT(m_contextData, Eq(nullptr)); iox_ws_detach_service_discovery_event(m_sut, serviceDiscovery, ServiceDiscoveryEvent_SERVICE_REGISTRY_CHANGED); iox_service_discovery_deinit(serviceDiscovery); } TEST_F(iox_ws_test, NotifyingServiceDiscoveryEventWithContextDataWorks) { ::testing::Test::RecordProperty("TEST_ID", "510a0351-afeb-4c0f-a4b6-3032f1f3f831"); constexpr uint64_t EVENT_ID = 31; 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); uint64_t someContextData = 0U; iox_ws_attach_service_discovery_event_with_context_data(m_sut, serviceDiscovery, ServiceDiscoveryEvent_SERVICE_REGISTRY_CHANGED, EVENT_ID, &serviceDiscoveryCallbackWithContextData, &someContextData); 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(EVENT_ID)); 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(serviceDiscovery))); EXPECT_THAT(m_contextData, Eq(static_cast(&someContextData))); iox_ws_detach_service_discovery_event(m_sut, serviceDiscovery, ServiceDiscoveryEvent_SERVICE_REGISTRY_CHANGED); iox_service_discovery_deinit(serviceDiscovery); } } // namespace