Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
136 changes: 136 additions & 0 deletions score/mw/com/test/common_test_resources/proxy_container.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,19 @@
#ifndef SCORE_MW_COM_TEST_METHODS_METHODS_TEST_RESOURCES_PROXY_CONTAINER_H
#define SCORE_MW_COM_TEST_METHODS_METHODS_TEST_RESOURCES_PROXY_CONTAINER_H

#include "score/concurrency/notification.h"
#include "score/mw/com/test/common_test_resources/fail_test.h"
#include "score/mw/com/types.h"

#include <chrono>
#include <condition_variable>
#include <cstdint>
#include <iostream>
#include <memory>
#include <mutex>
#include <optional>
#include <string>
#include <utility>

namespace score::mw::com::test
{
Expand All @@ -39,6 +43,13 @@ class ProxyContainer
return *proxy_;
}

Proxy&& Extract()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

directory structure:
move_semantics/
....proxy_event/
....skeleton_event/

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done in the PR - #610

{
SCORE_LANGUAGE_FUTURECPP_ASSERT_PRD_MESSAGE(proxy_ != nullptr,
"Proxy was not successfully created! Cannot extract it!");
return std::move(*proxy_);
}

private:
std::unique_ptr<typename Proxy::HandleType> handle_{nullptr};
std::mutex proxy_creation_mutex_{};
Expand All @@ -47,6 +58,131 @@ class ProxyContainer
std::unique_ptr<Proxy> proxy_{nullptr};
};

template <typename ProxyEventType>
class ProxyStateChangeNotifier
{
public:
explicit ProxyStateChangeNotifier(ProxyEventType& proxy_event) : proxy_event_{proxy_event}
{
auto state_change_handler = [this](const SubscriptionState new_state) -> bool {
std::cout << "Service state changed, new state: " << static_cast<std::uint32_t>(new_state) << std::endl;
std::lock_guard lock(mutex_);
last_seen_state_ = new_state;
condition_variable_.notify_all();
return true;
};
proxy_event_.SetSubscriptionStateChangeHandler(state_change_handler);
}

~ProxyStateChangeNotifier()
{
proxy_event_.UnsetSubscriptionStateChangeHandler();
}

ProxyStateChangeNotifier(const ProxyStateChangeNotifier&) = delete;
ProxyStateChangeNotifier& operator=(const ProxyStateChangeNotifier&) = delete;
ProxyStateChangeNotifier(const ProxyStateChangeNotifier&&) = delete;
ProxyStateChangeNotifier& operator=(const ProxyStateChangeNotifier&&) = delete;

bool WaitForStateChange(const score::cpp::stop_token& stop_token, SubscriptionState desired_state)
{
std::unique_lock lock(mutex_);
return condition_variable_.wait(lock, stop_token, [this, desired_state]() {
return last_seen_state_.has_value() && last_seen_state_.value() == desired_state;
});
}

private:
std::mutex mutex_{};
concurrency::InterruptibleConditionalVariable condition_variable_{};
std::optional<SubscriptionState> last_seen_state_{};
ProxyEventType& proxy_event_;
};

template <typename ProxyEventType, typename SampleType = std::uint32_t>
class ProxyEventReceiver
{
public:
ProxyEventReceiver(ProxyEventType& proxy_event, std::string failure_message_prefix)
: failure_message_prefix_{std::move(failure_message_prefix)}, proxy_event_{proxy_event}
{
auto receive_handler = [&received_sample_notification = received_sample_notification_]() {
std::cout << "Received event notification" << std::endl;
received_sample_notification.notify();
};
proxy_event_.SetReceiveHandler(receive_handler);
}

~ProxyEventReceiver()
{
proxy_event_.UnsetReceiveHandler();
}

ProxyEventReceiver(const ProxyEventReceiver&) = delete;
ProxyEventReceiver& operator=(const ProxyEventReceiver&) = delete;
ProxyEventReceiver(const ProxyEventReceiver&&) = delete;
ProxyEventReceiver& operator=(const ProxyEventReceiver&&) = delete;

void WaitForSamples(const score::cpp::stop_token& stop_token, const std::size_t num_samples_to_receive)
{
std::size_t received_count{0U};
while (!stop_token.stop_requested())
{
auto get_samples_result = proxy_event_.GetNewSamples(
[this](SamplePtr<SampleType> sample) {
GetNewSamplesCallback(std::move(sample));
},
num_samples_to_receive);
if (!get_samples_result.has_value())
{
FailTest(failure_message_prefix_, " GetNewSamples failed: ", get_samples_result.error());
}

received_count += get_samples_result.value();
std::cout << "Received " << get_samples_result.value() << " samples. " << received_count
<< " samples so far" << std::endl;

if (received_count == num_samples_to_receive)
{
break;
}

const auto notification_received = received_sample_notification_.waitWithAbort(stop_token);
if (!notification_received)
{
continue;
}

received_sample_notification_.reset();
}
std::cout << "\nConsumer: Done receiving samples, received " << received_count << " samples in total\n";
}

private:
void GetNewSamplesCallback(SamplePtr<SampleType> sample)
{
if (sample == nullptr)
{
FailTest(failure_message_prefix_, " received null sample");
}
const SampleType expected_value = latest_value_.has_value() ? latest_value_.value() + 1U : 1U;
if (*sample != expected_value)
{
FailTest(failure_message_prefix_,
" received value ",
*sample,
" does not match expected value ",
expected_value);
}
latest_value_ = *sample;
}

std::string failure_message_prefix_;
concurrency::Notification received_sample_notification_{};
std::optional<SampleType> latest_value_{};
ProxyEventType& proxy_event_;
};

template <typename Proxy>
void ProxyContainer<Proxy>::CreateProxy(InstanceSpecifier instance_specifier, const std::string& failure_message_prefix)
{
Expand Down
167 changes: 167 additions & 0 deletions score/mw/com/test/move_semantics/proxy_event/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
# *******************************************************************************
# 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/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"
}
Loading
Loading