-
Notifications
You must be signed in to change notification settings - Fork 86
mw/com: Add the integration tests for moving proxyEvent #607
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| /******************************************************************************** | ||
| * Copyright (c) 2026 Contributors to the Eclipse Foundation | ||
| * | ||
| * See the NOTICE file(s) distributed with this work for additional | ||
| * information regarding copyright ownership. | ||
| * | ||
| * This program and the accompanying materials are made available under the | ||
| * terms of the Apache License Version 2.0 which is available at | ||
| * https://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * SPDX-License-Identifier: Apache-2.0 | ||
| ********************************************************************************/ | ||
| #include "score/mw/com/test/common_test_resources/proxy_event_consumer.h" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,109 @@ | ||
| /******************************************************************************** | ||
| * Copyright (c) 2026 Contributors to the Eclipse Foundation | ||
| * | ||
| * See the NOTICE file(s) distributed with this work for additional | ||
| * information regarding copyright ownership. | ||
| * | ||
| * This program and the accompanying materials are made available under the | ||
| * terms of the Apache License Version 2.0 which is available at | ||
| * https://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * SPDX-License-Identifier: Apache-2.0 | ||
| ********************************************************************************/ | ||
| #ifndef SCORE_MW_COM_TEST_COMMON_TEST_RESOURCES_PROXY_EVENT_CONSUMER_H | ||
| #define SCORE_MW_COM_TEST_COMMON_TEST_RESOURCES_PROXY_EVENT_CONSUMER_H | ||
|
|
||
| #include "score/mw/com/test/common_test_resources/fail_test.h" | ||
| #include "score/mw/com/types.h" | ||
|
|
||
| #include <score/stop_token.hpp> | ||
|
|
||
| #include <cstddef> | ||
| #include <cstdint> | ||
| #include <iostream> | ||
| #include <optional> | ||
|
|
||
| namespace score::mw::com::test | ||
| { | ||
|
|
||
| inline auto MakeSampleSequenceCallback(std::optional<std::uint32_t>& latest_value, const char* failure_message_prefix) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. IMO, these functions are quite specific to the move semantic tests, so I wouldn't put them in the test resources. |
||
| { | ||
| return [&latest_value, failure_message_prefix](SamplePtr<std::uint32_t> sample) { | ||
| if (sample == nullptr) | ||
| { | ||
| FailTest(failure_message_prefix, " received null sample"); | ||
| } | ||
| // After a reset latest_value is empty, so the next sample is accepted as the new baseline. | ||
| const std::uint32_t expected_value = latest_value.has_value() ? latest_value.value() + 1U : *sample; | ||
| if (*sample != expected_value) | ||
| { | ||
| FailTest( | ||
| failure_message_prefix, " received value ", *sample, " does not match expected value ", expected_value); | ||
| } | ||
| latest_value = *sample; | ||
| }; | ||
| } | ||
|
|
||
| /// \brief Waits until subscribed, receives the expected number of samples, and notifies the provider once - repeated | ||
| /// for the given number of iterations. | ||
| template <typename ProxyEventReceiverType, typename ProxyStateChangeNotifierType, typename ProcessSynchronizerType> | ||
| void ReceiveAndNotify(ProxyEventReceiverType& proxy_event_receiver, | ||
| ProxyStateChangeNotifierType& proxy_state_change_notifier, | ||
| ProcessSynchronizerType& process_synchronizer, | ||
| const std::size_t num_samples_to_receive, | ||
| const std::size_t num_iterations, | ||
| const score::cpp::stop_token& stop_token) | ||
| { | ||
| for (std::size_t iteration = 0U; iteration < num_iterations; ++iteration) | ||
| { | ||
| std::cout << "\nConsumer: Iteration " << (iteration + 1U) << " of " << num_iterations << std::endl; | ||
| const bool subscribed = | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why are you waiting for a state change on every iteration? |
||
| proxy_state_change_notifier.WaitForStateChange(stop_token, SubscriptionState::kSubscribed); | ||
| if (!subscribed) | ||
| { | ||
| FailTest("proxy_event_move_semantics consumer failed: WaitForStateChange was interrupted by stop_token"); | ||
| } | ||
|
|
||
| const bool received = proxy_event_receiver.WaitForSamples(stop_token, num_samples_to_receive); | ||
| if (!received) | ||
| { | ||
| FailTest("proxy_event_move_semantics consumer failed: WaitForSamples was interrupted by stop_token"); | ||
| } | ||
| process_synchronizer.Notify(); | ||
| } | ||
| } | ||
|
|
||
| /// \brief Coordinates a proxy re-subscription across a provider re-offer. Waits until the provider has withdrawn its | ||
| /// offer (kSubscriptionPending), unsubscribes and subscribes again while the service is withdrawn, then notifies the | ||
| /// provider so that it re-offers. This ordering guarantees that the samples received afterwards come from the fresh | ||
| /// offer instead of being stale buffered samples from the previous offer. | ||
| template <typename ProxyEventType, typename ProxyStateChangeNotifierType, typename ProcessSynchronizerType> | ||
| void ResubscribeAcrossReoffer(ProxyEventType& proxy_event, | ||
| ProxyStateChangeNotifierType& proxy_state_change_notifier, | ||
| ProcessSynchronizerType& process_synchronizer, | ||
| const std::size_t num_samples_to_receive, | ||
| const score::cpp::stop_token& stop_token) | ||
| { | ||
| std::cout << "\nConsumer: Waiting for provider to withdraw its offer" << std::endl; | ||
| const bool withdrawn = | ||
| proxy_state_change_notifier.WaitForStateChange(stop_token, SubscriptionState::kSubscriptionPending); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. kSubscriptionPending shouldn't really be used to determine whether a provider is alive or not. I think you should probably use a ProcessSynchronizer instead. Although to be honest, I think it would also be fine to unsubscribe and subscribe without the provider reoffering. Is there a particular reason why you want to wait for the skeleton to reoffer? |
||
| if (!withdrawn) | ||
| { | ||
| FailTest("proxy_event_move_semantics consumer failed: WaitForStateChange was interrupted by stop_token"); | ||
| } | ||
|
|
||
| std::cout << "Consumer: Unsubscribe and subscribe again" << std::endl; | ||
| proxy_event.Unsubscribe(); | ||
| const auto subscribe_result = proxy_event.Subscribe(num_samples_to_receive); | ||
| if (!subscribe_result.has_value()) | ||
| { | ||
| FailTest("proxy_event_move_semantics consumer failed: Re-subscribe failed: ", subscribe_result.error()); | ||
| } | ||
|
|
||
| // Tell the provider we have re-subscribed so that it can re-offer the service. | ||
| process_synchronizer.Notify(); | ||
| } | ||
|
|
||
| } // namespace score::mw::com::test | ||
|
|
||
| #endif // SCORE_MW_COM_TEST_COMMON_TEST_RESOURCES_PROXY_EVENT_CONSUMER_H | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,168 @@ | ||
| # ******************************************************************************* | ||
| # Copyright (c) 2026 Contributors to the Eclipse Foundation | ||
| # | ||
| # See the NOTICE file(s) distributed with this work for additional | ||
| # information regarding copyright ownership. | ||
| # | ||
| # This program and the accompanying materials are made available under the | ||
| # terms of the Apache License Version 2.0 which is available at | ||
| # https://www.apache.org/licenses/LICENSE-2.0 | ||
| # | ||
| # SPDX-License-Identifier: Apache-2.0 | ||
| # ******************************************************************************* | ||
|
|
||
| load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library") | ||
| load("@score_baselibs//score/language/safecpp:toolchain_features.bzl", "COMPILER_WARNING_FEATURES") | ||
| load("//bazel/tools:json_schema_validator.bzl", "validate_json_schema_test") | ||
| load("//score/mw/com/test:pkg_application.bzl", "pkg_application") | ||
|
|
||
| validate_json_schema_test( | ||
| name = "validate_config_schema", | ||
| json = "config/mw_com_config.json", | ||
| schema = "//score/mw/com:config_schema", | ||
| tags = ["lint"], | ||
| ) | ||
|
|
||
| cc_library( | ||
| name = "test_event_datatype", | ||
| srcs = ["test_event_datatype.cpp"], | ||
| hdrs = ["test_event_datatype.h"], | ||
| features = COMPILER_WARNING_FEATURES, | ||
| deps = [ | ||
| "//score/mw/com", | ||
| ], | ||
| ) | ||
|
|
||
| cc_library( | ||
| name = "test_parameters", | ||
| srcs = ["test_parameters.cpp"], | ||
| hdrs = ["test_parameters.h"], | ||
| features = COMPILER_WARNING_FEATURES, | ||
| deps = [ | ||
| "//score/mw/com", | ||
| "//score/mw/com/test/common_test_resources:command_line_parser", | ||
| "//score/mw/com/test/common_test_resources:fail_test", | ||
| ], | ||
| ) | ||
|
|
||
| cc_library( | ||
| name = "provider", | ||
| srcs = ["provider.cpp"], | ||
| hdrs = ["provider.h"], | ||
| features = COMPILER_WARNING_FEATURES, | ||
| deps = [ | ||
| ":test_event_datatype", | ||
| ":test_parameters", | ||
| "//score/mw/com", | ||
| "//score/mw/com/test/common_test_resources:fail_test", | ||
| "//score/mw/com/test/common_test_resources:skeleton_container", | ||
| "//score/mw/com/test/methods/methods_test_resources:process_synchronizer", | ||
| ], | ||
| ) | ||
|
|
||
| cc_library( | ||
| name = "consumer", | ||
| srcs = ["consumer.cpp"], | ||
| hdrs = ["consumer.h"], | ||
| features = COMPILER_WARNING_FEATURES, | ||
| deps = [ | ||
| ":test_event_datatype", | ||
| ":test_parameters", | ||
| "//score/mw/com", | ||
| "//score/mw/com/test/common_test_resources:fail_test", | ||
| "//score/mw/com/test/common_test_resources:proxy_container", | ||
| "//score/mw/com/test/common_test_resources:proxy_event_consumer", | ||
| "//score/mw/com/test/methods/methods_test_resources:process_synchronizer", | ||
| ], | ||
| ) | ||
|
|
||
| cc_binary( | ||
| name = "main_provider", | ||
| srcs = ["main_provider.cpp"], | ||
| data = ["config/mw_com_config.json"], | ||
| features = COMPILER_WARNING_FEATURES + [ | ||
| "aborts_upon_exception", | ||
| ], | ||
| deps = [ | ||
| ":provider", | ||
| ":test_parameters", | ||
| "//score/mw/com", | ||
| "//score/mw/com/test/common_test_resources:assert_handler", | ||
| "//score/mw/com/test/common_test_resources:fail_test", | ||
| "//score/mw/com/test/common_test_resources:stop_token_sig_term_handler", | ||
| ], | ||
| ) | ||
|
|
||
| cc_binary( | ||
| name = "main_consumer", | ||
| srcs = ["main_consumer.cpp"], | ||
| data = ["config/mw_com_config.json"], | ||
| features = COMPILER_WARNING_FEATURES + [ | ||
| "aborts_upon_exception", | ||
| ], | ||
| deps = [ | ||
| ":consumer", | ||
| ":test_parameters", | ||
| "//score/mw/com", | ||
| "//score/mw/com/test/common_test_resources:assert_handler", | ||
| "//score/mw/com/test/common_test_resources:fail_test", | ||
| "//score/mw/com/test/common_test_resources:stop_token_sig_term_handler", | ||
| ], | ||
| ) | ||
|
|
||
| cc_binary( | ||
| name = "main_consumer_and_provider", | ||
| srcs = ["main_consumer_and_provider.cpp"], | ||
| data = ["config/mw_com_config.json"], | ||
| features = COMPILER_WARNING_FEATURES + [ | ||
| "aborts_upon_exception", | ||
| ], | ||
| deps = [ | ||
| ":consumer", | ||
| ":provider", | ||
| ":test_parameters", | ||
| "//score/mw/com", | ||
| "//score/mw/com/test/common_test_resources:assert_handler", | ||
| "//score/mw/com/test/common_test_resources:fail_test", | ||
| "//score/mw/com/test/common_test_resources:stop_token_sig_term_handler", | ||
| ], | ||
| ) | ||
|
|
||
| pkg_application( | ||
| name = "main_provider-pkg", | ||
| app_name = "MainProviderApp", | ||
| bin = [":main_provider"], | ||
| etc = [ | ||
| "config/mw_com_config.json", | ||
| "config/logging.json", | ||
| ], | ||
| visibility = [ | ||
| "//score/mw/com/test/move_semantics/proxy_event:__subpackages__", | ||
| ], | ||
| ) | ||
|
|
||
| pkg_application( | ||
| name = "main_consumer-pkg", | ||
| app_name = "MainConsumerApp", | ||
| bin = [":main_consumer"], | ||
| etc = [ | ||
| "config/mw_com_config.json", | ||
| "config/logging.json", | ||
| ], | ||
| visibility = [ | ||
| "//score/mw/com/test/move_semantics/proxy_event:__subpackages__", | ||
| ], | ||
| ) | ||
|
|
||
| pkg_application( | ||
| name = "main_consumer_and_provider-pkg", | ||
| app_name = "MainConsumerAndProviderApp", | ||
| bin = [":main_consumer_and_provider"], | ||
| etc = [ | ||
| "config/mw_com_config.json", | ||
| "config/logging.json", | ||
| ], | ||
| visibility = [ | ||
| "//score/mw/com/test/move_semantics/proxy_event:__subpackages__", | ||
| ], | ||
| ) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| { | ||
| "appId": "PRMS", | ||
| "appDesc": "proxy_event_move_semantics", | ||
| "logLevel": "kDebug", | ||
| "logLevelThresholdConsole": "kDebug", | ||
| "logMode": "kRemote|kConsole" | ||
| } |
Uh oh!
There was an error while loading. Please reload this page.