Skip to content
Merged
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
1 change: 0 additions & 1 deletion score/mw/com/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,6 @@ cc_library(
deps = [
"@score_baselibs//score/filesystem",
"@score_baselibs//score/language/futurecpp",
"@score_baselibs//score/string_manipulation:string_literal",
],
)

Expand Down
4 changes: 2 additions & 2 deletions score/mw/com/api_surface.lock.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
"name": "InitializeRuntime",
"qualified_name": "score::mw::com::runtime::InitializeRuntime",
"kind": "function",
"signature": "InitializeRuntime : void (const std::int32_t, score::StringLiteral *)"
"signature": "InitializeRuntime : void (const cpp::span<safecpp::zstring_view>)"

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.

That is interesting, I do not get why you need to change it and you do not have to add it. I would expect that if we have both (the new overload and the deprecated API) then you have to add one and keep also the old.

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.

@castler this looks like the API surface checker has issues with overloads.

},
{
"name": "InitializeRuntime",
Expand All @@ -47,7 +47,7 @@
"name": "RuntimeConfiguration",
"qualified_name": "score::mw::com::runtime::RuntimeConfiguration::RuntimeConfiguration",
"kind": "constructor",
"signature": "RuntimeConfiguration : void (const std::int32_t, score::StringLiteral *)"
"signature": "RuntimeConfiguration : void (cpp::span<safecpp::zstring_view>)"
},
{
"name": "RuntimeConfiguration",
Expand Down
3 changes: 1 addition & 2 deletions score/mw/com/design/configuration/structural_view.puml
Original file line number Diff line number Diff line change
Expand Up @@ -201,8 +201,7 @@ class "score::mw::com::impl::Runtime" {
- configuration : Configuration const&
__
- Runtime(std::pair<Configuration&&, std::optional<tracing::TracingFilterConfig>&&> configs)
{static} + Initialize() : void
{static} + Initialize(const score::cpp::span<const score::StringLiteral> arguments) : void
{static} + Initialize(const runtime::RuntimeConfiguration& runtime_configuration) : void
{static} + getInstance() : Runtime&
+ resolve(const InstanceSpecifier&): score::mw::com::InstanceIdentifierContainer
+ GetBindingRuntime(const BindingType binding) const : IBindingRuntime*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,7 @@ class "score::mw::com::impl::Runtime" {
- configuration_ : Configuration const&
- parsing_strategy_ : std::unique_ptr<IConfigurationParsingStrategy>
__
{static} + Initialize() : void
{static} + Initialize(arguments : score::cpp::span<const score::StringLiteral>) : void
{static} + Initialize(const runtime::RuntimeConfiguration& runtime_configuration) : void
{static} + getInstance() : Runtime&
+ resolve(const InstanceSpecifier&) : InstanceIdentifierContainer
}
Expand Down
4 changes: 1 addition & 3 deletions score/mw/com/design/ipc_tracing/structural_view.puml
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,7 @@ abstract class "mw::com::impl::IRuntime" {

class "mw::com::impl::Runtime" {
-binding_runtimes_ : std:unordered_map<BindingType, std::unique_ptr<IBindingRuntime>>
{static} +Initialize() : void
{static} +Initialize(int argc, score::StringLiteral argv) : void
{static} +Initialize(std::string const&) : void
{static} +Initialize(runtime::RuntimeConfiguration&) : void

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.

Can we move this changes to a separate PR together with https://github.com/eclipse-score/communication/pull/745/changes#r3656356347? That is not really a change in the API, it is just fixing the puml that was wrong.

{static} +getInstance() : Runtime&
+Runtime(Configuration&& config)
+resolve(const InstanceSpecifier&) : std::vector<InstanceIdentifier>
Expand Down
4 changes: 1 addition & 3 deletions score/mw/com/design/runtime/runtime_structural_view.puml
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,7 @@ enum BindingType {

class "mw::com::impl::Runtime" as Runtime {
-binding_runtimes_ : std::unordered_map<BindingType, std::unique_ptr<IBindingRuntime>>
+{static} Initialize() : void
+{static} Initialize(int argc, score::StringLiteral argv) : void
+{static} Initialize(std::string const&) : void
+{static} Initialize(const runtime::RuntimeConfiguration& runtime_configuration) : void
+{static} getInstance() : Runtime&
+Runtime(Configuration&& config)
+resolve(const InstanceSpecifier&) : std::vector<InstanceIdentifier>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class "ComErrorDomain" {
}

class "<< Stereotype >>\nglobal function" as GlobalFunction {
+MakeError(code : ComErrc, message : score::StringLiteral) : score::result::Error
+MakeError(code : ComErrc, message : std::string_view) : score::result::Error
}

note top of ScoreResultErrorDomain
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class "ComErrorDomain" {
}

class "<< Stereotype >>\nglobal function" as GlobalFunction {
+MakeError(code : ComErrc, message : score::StringLiteral) : score::result::Error
+MakeError(code : ComErrc, message : std::string_view) : score::result::Error
Comment thread
limdor marked this conversation as resolved.
}

note top of ScoreResultErrorDomain
Expand Down
1 change: 0 additions & 1 deletion score/mw/com/mocking/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ cc_library(
"//score/mw/com/impl:instance_specifier",
"@score_baselibs//score/language/futurecpp",
"@score_baselibs//score/result",
"@score_baselibs//score/string_manipulation:string_literal",
],
)

Expand Down
8 changes: 5 additions & 3 deletions score/mw/com/mocking/i_runtime.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,9 @@
#define SCORE_MW_COM_MOCKING_I_RUNTIME_H

#include "score/mw/com/runtime_configuration.h"

#include "score/mw/com/types.h"

#include "score/result/result.h"
#include "score/string_manipulation/string_literal.h"

#include <score/span.hpp>

Expand All @@ -34,7 +32,11 @@ class IRuntime
virtual ~IRuntime() = default;

virtual score::Result<InstanceIdentifierContainer> ResolveInstanceIDs(const InstanceSpecifier model_name) = 0;
virtual void InitializeRuntime(const std::int32_t argc, score::cpp::span<const score::StringLiteral> argv) = 0;
[[deprecated(
"Please use InitializeRuntime(cpp::span<safecpp::zstring_view> command_line_arguments) for guaranteed NULL "
"terminated arguments")]]
virtual void InitializeRuntime(const std::int32_t argc, score::cpp::span<const char*> argv) = 0;

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.

Suggested change
virtual void InitializeRuntime(const std::int32_t argc, score::cpp::span<const char*> argv) = 0;
[[deprecated("Please use InitializeRuntime(cpp::span<safecpp::zstring_view> command_line_arguments) for guaranteed NULL terminated arguments")]]
virtual void InitializeRuntime(const std::int32_t argc, score::cpp::span<const char*> argv) = 0;

If we add the deprecation attribute also in the interface it also serve us as a reminder that this is deprecated.

virtual void InitializeRuntime(const cpp::span<safecpp::zstring_view> command_line_arguments) = 0;
virtual void InitializeRuntime(const runtime::RuntimeConfiguration& runtime_configuration) = 0;

protected:
Expand Down
6 changes: 2 additions & 4 deletions score/mw/com/mocking/runtime_mock.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,8 @@ class RuntimeMock : public IRuntime
{
public:
MOCK_METHOD(score::Result<InstanceIdentifierContainer>, ResolveInstanceIDs, (const InstanceSpecifier), (override));
MOCK_METHOD(void,
InitializeRuntime,
(const std::int32_t, score::cpp::span<const score::StringLiteral>),
(override));
MOCK_METHOD(void, InitializeRuntime, (const std::int32_t, score::cpp::span<const char*>), (override));
MOCK_METHOD(void, InitializeRuntime, (const cpp::span<safecpp::zstring_view> command_line_arguments), (override));
MOCK_METHOD(void, InitializeRuntime, (const runtime::RuntimeConfiguration&), (override));
};

Expand Down
39 changes: 32 additions & 7 deletions score/mw/com/mocking/runtime_mock_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
#include "score/mw/com/runtime_configuration.h"

#include "score/filesystem/path.h"
#include "score/string_manipulation/string_literal.h"

#include <gmock/gmock.h>
#include <gtest/gtest.h>
Expand Down Expand Up @@ -82,17 +81,18 @@ TEST_F(RuntimeMockFixture, ResolveInstanceIdsReturnsErrorWhenMockReturnsError)
EXPECT_EQ(resolve_instance_ids_result.error(), error_code);
}

// TODO: Once InitializeRuntime(argc, argv) is removed, this test will also be removed
TEST_F(RuntimeMockFixture, InitializeRuntimeDispatchesToMockAfterInjectingMock)
{
// Given that a mocked runtime has been injected

// Expecting that InitializeRuntime will be called on the mock with the same argc / argv that is passed to
// InitializeRuntime (where argv has been converted to an score::cpp::span
constexpr std::int32_t argc{1U};
score::StringLiteral argv[] = {"some_argument"};

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.

Please add a note to this test mentioning that once the deprecated InitializeRuntime(argc, argv) is removed, the test needs to be removed also. This helps to identify that these char* here are only needed for testing this deprecated API.

// TODO: Once InitializeRuntime(argc, argv) is removed, this test will also be removed
TEST_F(RuntimeMockFixture, InitializeRuntimeDispatchesToMockAfterInjectingMock)

const char* argv[] = {"some_argument"};
EXPECT_CALL(runtime_mock_, InitializeRuntime(argc, _)).WillOnce(Invoke([argv](auto, auto argv_span) {
const score::cpp::span<const score::StringLiteral> expected_argv_span(
argv, static_cast<score::cpp::span<const score::StringLiteral>::size_type>(argc));
const score::cpp::span<const char*> expected_argv_span(
const_cast<const char**>(argv), static_cast<score::cpp::span<const char*>::size_type>(argc));
ASSERT_EQ(argv_span.size(), expected_argv_span.size());
for (std::size_t i = 0; i < argv_span.size(); ++i)
{
Expand All @@ -104,15 +104,40 @@ TEST_F(RuntimeMockFixture, InitializeRuntimeDispatchesToMockAfterInjectingMock)
InitializeRuntime(argc, argv);
}

TEST_F(RuntimeMockFixture, InitializeRuntimeWithZStringViewsDispatchesToMockAfterInjectingMock)
{
// Given that a mocked runtime has been injected

// Expecting that InitializeRuntime will be called on the mock with the same span that is passed to
// InitializeRuntime
using safecpp::literals::operator""_zsv;
constexpr auto kDummyApplicationNameZsv = "dummyname"_zsv;
safecpp::zstring_view argv[] = {kDummyApplicationNameZsv};
score::cpp::span<safecpp::zstring_view> argv_span(argv, std::size(argv));

EXPECT_CALL(runtime_mock_, InitializeRuntime(An<cpp::span<safecpp::zstring_view>>()))
.WillOnce(Invoke([argv_span](auto arguments_span) {
ASSERT_EQ(argv_span.size(), arguments_span.size());
for (std::size_t i = 0; i < argv_span.size(); ++i)
{
EXPECT_EQ(argv_span.data()[i], arguments_span.data()[i]);
}
}));

// When calling InitializeRuntime
InitializeRuntime(argv);
}

TEST_F(RuntimeMockFixture, InitializeRuntimeWithRuntimeConfigurationDispatchesToMockAfterInjectingMock)
{
// Given that a mocked runtime has been injected

// Expecting that InitializeRuntime will be called on the mock
RuntimeConfiguration runtime_configuration{kDummyConfigurationPath};
EXPECT_CALL(runtime_mock_, InitializeRuntime(_)).WillOnce(Invoke([](auto& runtime_configuration) {
EXPECT_EQ(runtime_configuration.GetConfigurationPath(), kDummyConfigurationPath);
}));
EXPECT_CALL(runtime_mock_, InitializeRuntime(An<const RuntimeConfiguration&>()))
.WillOnce(Invoke([](auto& runtime_configuration) {
EXPECT_EQ(runtime_configuration.GetConfigurationPath(), kDummyConfigurationPath);
}));

// When calling InitializeRuntime
InitializeRuntime(runtime_configuration);
Expand Down
22 changes: 17 additions & 5 deletions score/mw/com/runtime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
#include "score/mw/com/impl/runtime.h"

#include "score/result/result.h"
#include "score/string_manipulation/string_literal.h"

#include <score/span.hpp>

Expand Down Expand Up @@ -48,13 +47,14 @@ score::Result<InstanceIdentifierContainer> ResolveInstanceIDs(const impl::Instan
return instance_identifier_container;
}

// NOLINTNEXTLINE(modernize-avoid-c-arrays):C-style array tolerated for command line arguments
void InitializeRuntime(const std::int32_t argc, score::StringLiteral argv[])
// NOLINTNEXTLINE(modernize-avoid-c-arrays):C-style array tolerated for command line arguments. This API is deprecated
// and it will be removed.
void InitializeRuntime(const std::int32_t argc, const char* argv[])
{
if (auto* const runtime_mock_holder = detail::RuntimeMockHolder::GetRuntimeMock())
{
const score::cpp::span<const score::StringLiteral> argv_span(
argv, static_cast<score::cpp::span<const score::StringLiteral>::size_type>(argc));
const score::cpp::span<const char*> argv_span(argv,
static_cast<score::cpp::span<const char*>::size_type>(argc));
runtime_mock_holder->InitializeRuntime(argc, argv_span);
return;
}
Expand All @@ -63,6 +63,18 @@ void InitializeRuntime(const std::int32_t argc, score::StringLiteral argv[])
InitializeRuntime(runtime_configuration);
}

void InitializeRuntime(const cpp::span<safecpp::zstring_view> command_line_arguments)
{
if (auto* const runtime_mock_holder = detail::RuntimeMockHolder::GetRuntimeMock())
{
runtime_mock_holder->InitializeRuntime(command_line_arguments);
return;
}

const RuntimeConfiguration runtime_configuration{command_line_arguments};
InitializeRuntime(runtime_configuration);
}

void InitializeRuntime(const RuntimeConfiguration& runtime_configuration)
{
if (auto* const runtime_mock_holder = detail::RuntimeMockHolder::GetRuntimeMock())
Expand Down
33 changes: 29 additions & 4 deletions score/mw/com/runtime.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@
#ifndef SCORE_MW_COM_RUNTIME_H
#define SCORE_MW_COM_RUNTIME_H

#include "score/language/safecpp/string_view/zstring_view.h"
#include "score/mw/com/mocking/i_runtime.h"
#include "score/mw/com/runtime_configuration.h"
#include "score/mw/com/types.h"

#include "score/result/result.h"
#include "score/string_manipulation/string_literal.h"
#include "score/span.hpp"

#include <cstdint>

Expand Down Expand Up @@ -76,12 +76,37 @@ score::Result<score::mw::com::InstanceIdentifierContainer> ResolveInstanceIDs(co
* \brief Initializes mw::com subsystem with the given configuration referenced in the command-line options.
* \details This call is optional for a mw::com user. Only if the mw::com configuration (json) is not located in the
* default manifest path, this function shall be called with the commandline option
* "-service_instance_manifest" pointing to the json config file to be used.
* "--service_instance_manifest" pointing to the json config file to be used.
* \attention This function shall only be called ONCE per application/process lifetime! A second call may have no
* effect after an internal runtime singleton has been already created/is in use!
* The arguments contained in argv are expected to be NULL-terminated.
*
* \param argc number of arguments in the upcoming argv array
* \param argv array of NULL-terminated c-style strings as handed over to applications main() entry-point.
*
* \deprecated Use InitializeRuntime(cpp::span<safecpp::zstring_view> command_line_arguments) for guaranteed NULL
* terminated arguments
*/
[[deprecated(
"Please use InitializeRuntime(cpp::span<safecpp::zstring_view> command_line_arguments) for guaranteed NULL "
"terminated arguments")]]
// NOLINTNEXTLINE(modernize-avoid-c-arrays):C-style array tolerated for command line arguments
void InitializeRuntime(const std::int32_t argc, score::StringLiteral argv[]);
void InitializeRuntime(const std::int32_t argc, const char* argv[]);

/**
* \api
* \brief Initializes mw::com subsystem with the given configuration referenced in the command-line options.
* \details This call is optional for a mw::com user. Only if the mw::com configuration (json) is not located in the
* default manifest path, this function shall be called with the commandline option
* "--service_instance_manifest" pointing to the json config file to be used.
* \attention This function shall only be called ONCE per application/process lifetime! A second call may have no
* effect after an internal runtime singleton has been already created/is in use!
* Users should hand over the arguments received from const char* argv[] argument of main(). Since there the
* OS assures, that each element in argv is a NULL-terminated string, user can build up each
* safecpp::zstring_view in command_line_arguments by creating it from std::string_view(argv[i])
* @param command_line_arguments
*/
void InitializeRuntime(const cpp::span<safecpp::zstring_view> command_line_arguments);

/**
* \api
Expand Down
35 changes: 26 additions & 9 deletions score/mw/com/runtime_configuration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,7 @@

#include "score/filesystem/path.h"
#include "score/mw/log/logging.h"
#include "score/string_manipulation/string_literal.h"

#include <score/assert.hpp>
#include <score/span.hpp>

#include <cstddef>
Expand Down Expand Up @@ -45,10 +43,26 @@ RuntimeConfiguration::RuntimeConfiguration(filesystem::Path configuration_path)
}

// NOLINTNEXTLINE(modernize-avoid-c-arrays):C-style array tolerated for command line arguments
RuntimeConfiguration::RuntimeConfiguration(const std::int32_t argc, score::StringLiteral argv[]) : configuration_path_{}
RuntimeConfiguration::RuntimeConfiguration(const std::int32_t argc, const char* argv[]) : configuration_path_{}
{
// We convert the const char* arguments into safecpp::zstring_views to ensure that they are null-terminated and safe
// to use.
// This is a deprecated API for a reason! If the given argv[] is not null-terminated, it can lead to undefined
// behavior. But this isn't introduced newly by this conversion!
std::vector<safecpp::zstring_view> command_line_arguments{};
for (std::int32_t arg_idx = 0U; arg_idx < argc; arg_idx++)
{
auto argument = std::string_view{argv[arg_idx]};
command_line_arguments.push_back(safecpp::zstring_view{argument.data(), argument.size()});
}

auto configuration_path = ParseConfigurationPath(command_line_arguments);
configuration_path_ =
configuration_path.has_value() ? std::move(configuration_path).value() : kDefaultConfigurationPath;
}

RuntimeConfiguration::RuntimeConfiguration(cpp::span<safecpp::zstring_view> command_line_arguments)
{
const score::cpp::span<const score::StringLiteral> command_line_arguments(
argv, static_cast<score::cpp::span<const score::StringLiteral>::size_type>(argc));
auto configuration_path = ParseConfigurationPath(command_line_arguments);
configuration_path_ =
configuration_path.has_value() ? std::move(configuration_path).value() : kDefaultConfigurationPath;
Expand All @@ -60,15 +74,16 @@ const filesystem::Path& RuntimeConfiguration::GetConfigurationPath() const&
}

std::optional<filesystem::Path> RuntimeConfiguration::ParseConfigurationPath(
const score::cpp::span<const score::StringLiteral> command_line_args)
const score::cpp::span<safecpp::zstring_view> command_line_args)
{
const auto num_args = command_line_args.size();

std::optional<std::string> configuration_path{};
for (std::uint32_t arg_idx = 0U; arg_idx < num_args; arg_idx++)
{
// TODO: Adapt code that we do not need to call `.data()` and that we do not have to rely on life time extension
const std::string& command_line_argument_key{

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.

Suggested change
const std::string& command_line_argument_key{
// TODO: Adapt code that we do not need to call `.data()` and that we do not have to rely on life time extension
const std::string& command_line_argument_key{

score::cpp::at(command_line_args, static_cast<std::ptrdiff_t>(arg_idx))};
score::cpp::at(command_line_args, static_cast<std::ptrdiff_t>(arg_idx)).data()};
if (command_line_argument_key == kConfigurationPathCommandLineKey)
{
const auto index_of_configuration_path = arg_idx + 1U;
Expand All @@ -79,7 +94,8 @@ std::optional<filesystem::Path> RuntimeConfiguration::ParseConfigurationPath(
<< "\" but no corresponding value. Terminating.";
std::terminate();
}
return score::cpp::at(command_line_args, static_cast<std::ptrdiff_t>(index_of_configuration_path));
// TODO: Adapt code that we do not need to call `.data()` and we can provide zstring_view to a filepath
return score::cpp::at(command_line_args, static_cast<std::ptrdiff_t>(index_of_configuration_path)).data();

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.

Suggested change
return score::cpp::at(command_line_args, static_cast<std::ptrdiff_t>(index_of_configuration_path)).data();
// TODO: Adapt code that we do not need to call `.data()` and we can provide zstring_view to a filepath
return score::cpp::at(command_line_args, static_cast<std::ptrdiff_t>(index_of_configuration_path)).data();

}
if (command_line_argument_key == kDeprecatedConfigurationPathCommandLineKey)
{
Expand All @@ -93,7 +109,8 @@ std::optional<filesystem::Path> RuntimeConfiguration::ParseConfigurationPath(
<< "\" but no corresponding value. Terminating.";
std::terminate();
}
return score::cpp::at(command_line_args, static_cast<std::ptrdiff_t>(index_of_configuration_path));
// TODO: Adapt code that we do not need to call `.data()` and we can provide zstring_view to a filepath
return score::cpp::at(command_line_args, static_cast<std::ptrdiff_t>(index_of_configuration_path)).data();

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.

Suggested change
return score::cpp::at(command_line_args, static_cast<std::ptrdiff_t>(index_of_configuration_path)).data();
// TODO: Adapt code that we do not need to call `.data()` and we can provide zstring_view to a filepath
return score::cpp::at(command_line_args, static_cast<std::ptrdiff_t>(index_of_configuration_path)).data();

}
}
return configuration_path;
Expand Down
Loading
Loading