Skip to content
Open
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
169 changes: 169 additions & 0 deletions score/mw/com/test/move_semantics/skeleton_method/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
# *******************************************************************************
# 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_method_datatype",
srcs = ["test_method_datatype.cpp"],
hdrs = ["test_method_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_method_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",
"@score_baselibs//score/language/futurecpp",
],
)

cc_library(
name = "consumer",
srcs = ["consumer.cpp"],
hdrs = ["consumer.h"],
features = COMPILER_WARNING_FEATURES,
deps = [
":test_method_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",
"@score_baselibs//score/language/futurecpp",
],
)

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/skeleton_method:__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/skeleton_method:__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/skeleton_method:__subpackages__",
],
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"appId": "SMMS",
"appDesc": "skeleton_method_move_semantics",
"logLevel": "kDebug",
"logLevelThresholdConsole": "kDebug",
"logMode": "kRemote|kConsole"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
{
"serviceTypes": [
{
"serviceTypeName": "/test/move_semantics/skeleton_method/SkeletonMethodMoveInterface",
"version": {
"major": 1,
"minor": 0
},
"bindings": [
{
"binding": "SHM",
"serviceId": 2200,
"methods": [
{
"methodName": "moved_method",
"methodId": 1
}
]
}
]
}
],
"serviceInstances": [
{
"instanceSpecifier": "test/move_semantics/skeleton_method/SkeletonMethodMoveInterfaceMovedTo",
"serviceTypeName": "/test/move_semantics/skeleton_method/SkeletonMethodMoveInterface",
"version": {
"major": 1,
"minor": 0
},
"instances": [
{
"instanceId": 1,
"asil-level": "QM",
"binding": "SHM",
"methods": [
{
"methodName": "moved_method",
"queueSize": 1
}
],
"allowedConsumer": {
"QM": [
0
],
"B": [
0
]
},
"allowedProvider": {
"QM": [
0
],
"B": [
0
]
}
}
]
},
{
"instanceSpecifier": "test/move_semantics/skeleton_method/SkeletonMethodMoveInterfaceMovedFrom",
"serviceTypeName": "/test/move_semantics/skeleton_method/SkeletonMethodMoveInterface",
"version": {
"major": 1,
"minor": 0
},
"instances": [
{
"instanceId": 2,
"asil-level": "QM",
"binding": "SHM",
"methods": [
{
"methodName": "moved_method",
"queueSize": 1
}
],
"allowedConsumer": {
"QM": [
0
],
"B": [
0
]
},
"allowedProvider": {
"QM": [
0
],
"B": [
0
]
}
}
]
}
]
}
120 changes: 120 additions & 0 deletions score/mw/com/test/move_semantics/skeleton_method/consumer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
/********************************************************************************
* 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/move_semantics/skeleton_method/consumer.h"

#include "score/mw/com/test/common_test_resources/fail_test.h"
#include "score/mw/com/test/common_test_resources/proxy_container.h"
#include "score/mw/com/test/methods/methods_test_resources/process_synchronizer.h"
#include "score/mw/com/test/move_semantics/skeleton_method/test_method_datatype.h"
#include "score/mw/com/test/move_semantics/skeleton_method/test_parameters.h"

#include <score/stop_token.hpp>

#include <iostream>

namespace score::mw::com::test
{
namespace
{

const std::string kProxyDoneShmPath{"/skeleton_method_move_semantics_proxy_done_sync"};
const std::string kSkeletonReadyShmPath{"/skeleton_method_move_semantics_skeleton_ready_sync"};

} // namespace

void RunConsumer(const SkeletonMoveScenario& scenario, const score::cpp::stop_token& stop_token)
{
auto proxy_done_sync = ProcessSynchronizer::Create(kProxyDoneShmPath);
if (!proxy_done_sync.has_value())
{
FailTest("Consumer: Failed to create proxy_done ProcessSynchronizer");
}

// Safety guard: always notify provider on exit so it does not wait indefinitely on failure
ExitFunctionGuard done_guard{[&proxy_done_sync]() {
proxy_done_sync->Notify();
}};

// Step 1. Create proxy for kInstanceSpecifierMovedTo
std::cout << "\nConsumer: Step 1 - Create proxy (kMovedTo)" << std::endl;
ProxyContainer<SkeletonMethodMoveProxy> proxy_moved_to_container{};
proxy_moved_to_container.CreateProxy(kInstanceSpecifierMovedTo, "skeleton_method_move_semantics");
auto& proxy_moved_to = proxy_moved_to_container.GetProxy();

// Step 2. For kMoveAssignAfterOffered: also create proxy for kInstanceSpecifierMovedFrom
// (both skeletons are offered; creating the proxy confirms SHM exists for both)
std::optional<ProxyContainer<SkeletonMethodMoveProxy>> proxy_moved_from_container{};
if (scenario == SkeletonMoveScenario::kMoveAssignAfterOffered)
{
std::cout << "\nConsumer: Step 2 - Create proxy (kMovedFrom)" << std::endl;
proxy_moved_from_container.emplace();
proxy_moved_from_container->CreateProxy(kInstanceSpecifierMovedFrom, "skeleton_method_move_semantics");
}

// Step 3. For after-offered scenarios: signal provider that proxy/proxies are created
if (IsAfterOffered(scenario))
{
std::cout << "\nConsumer: Step 3 - Notify provider: proxy/proxies created" << std::endl;
proxy_done_sync->Notify();
}

// Step 4. Create skeleton_ready synchronizer for after-offered scenarios
std::unique_ptr<ProcessSynchronizer> skeleton_ready_sync{};
if (IsAfterOffered(scenario))
{
skeleton_ready_sync = ProcessSynchronizer::CreateUniquePtr(kSkeletonReadyShmPath);
}

// Step 5. Call loop: one iteration for before-offered, two for after-offered
const std::size_t num_iterations = GetNumberOfCallIterations(scenario);
for (std::size_t iteration = 0U; iteration < num_iterations; ++iteration)
{
std::cout << "\nConsumer: Iteration " << (iteration + 1U) << " of " << num_iterations << std::endl;

// For after-offered scenarios: wait for provider to signal ready
// iter 0 → move complete; iter 1 → next handler registered
if (IsAfterOffered(scenario))
{
std::cout << "\nConsumer: Wait for skeleton_ready signal" << std::endl;
if (!skeleton_ready_sync->WaitWithAbort(stop_token))
{
FailTest("Consumer: skeleton_ready WaitWithAbort was stopped by stop_token");
}
skeleton_ready_sync->Reset();
}

// Call the method
std::cout << "\nConsumer: Calling moved_method_(" << kTestArgA << ", " << kTestArgB << ")" << std::endl;
auto result = proxy_moved_to.moved_method_(kTestArgA, kTestArgB);
if (!result.has_value())
{
FailTest("Consumer: moved_method_ call failed: ", result.error());
}
const std::int32_t actual = *(result.value());

// Verify result.
const std::int32_t expected = GetExpectedResult(scenario, iteration);
if (actual != expected)
{
FailTest("Consumer: iteration ", iteration, " expected ", expected, " but got ", actual);
}
std::cout << "\nConsumer: Iteration " << (iteration + 1U) << " passed (result=" << actual << ")" << std::endl;

// Notify provider: call done
proxy_done_sync->Notify();
}

std::cout << "\nConsumer: All iterations done" << std::endl;
}

} // namespace score::mw::com::test
Loading
Loading