diff --git a/.bazelrc b/.bazelrc index ef11493..0f4104e 100644 --- a/.bazelrc +++ b/.bazelrc @@ -24,7 +24,7 @@ common --//score/datarouter/build_configuration_flags:persistent_logging=False common --//score/datarouter/build_configuration_flags:persistent_config_feature_enabled=False common --//score/datarouter/build_configuration_flags:enable_nonverbose_dlt=False common --//score/datarouter/build_configuration_flags:enable_dynamic_configuration_in_datarouter=False -common --//score/datarouter/build_configuration_flags:file_transfer=False +common --//score/datarouter/build_configuration_flags:dlt_file_transfer_feature=False common --//score/datarouter/build_configuration_flags:use_local_vlan=True build --incompatible_strict_action_env diff --git a/MODULE.bazel b/MODULE.bazel index a04b937..cfd7162 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -95,14 +95,14 @@ bazel_dep(name = "rapidjson", version = "1.1.0") bazel_dep(name = "score_communication", version = "0.1.2") git_override( module_name = "score_communication", - commit = "42eb047495099ec70b5c8773f29783cc205bf7df", + commit = "5a70133dd8bd632f5c07f200a5ee4bc9f507c23b", remote = "https://github.com/eclipse-score/communication.git", ) bazel_dep(name = "score_baselibs", version = "0.2.0") git_override( module_name = "score_baselibs", - commit = "99d49637a2199f33a71edc479d39970e3bdcb271", + commit = "3c65b223e9f516f95935bb4cd2e83d6088ca016f", remote = "https://github.com/eclipse-score/baselibs.git", ) diff --git a/score/datarouter/BUILD b/score/datarouter/BUILD index f685111..77f4fdc 100644 --- a/score/datarouter/BUILD +++ b/score/datarouter/BUILD @@ -37,8 +37,8 @@ cc_library( strip_include_prefix = "include", visibility = [ "//score/datarouter/dlt_filetransfer_trigger_lib:__pkg__", - "//score/datarouter/src/file_transfer:__subpackages__", - "//score/datarouter/src/persistent_logging/persistent_logging:__pkg__", + "//score/datarouter/file_transfer:__subpackages__", + "//score/datarouter/persistent_logging/persistent_logging:__pkg__", "//score/datarouter/test:__subpackages__", ], deps = [ @@ -109,7 +109,6 @@ cc_library( "//score/datarouter/dynamic_configuration/i_session", "@score_baselibs//score/os:pthread", "@score_baselibs//score/os:sys_poll", - "@score_baselibs//score/quality/compiler_warnings", ], ) @@ -129,7 +128,6 @@ cc_library( "//score/datarouter/dynamic_configuration/i_session", "@score_baselibs//score/os:pthread", "@score_baselibs//score/os:sys_poll", - "@score_baselibs//score/quality/compiler_warnings", ], ) @@ -164,11 +162,11 @@ cc_library( features = COMPILER_WARNING_FEATURES, strip_include_prefix = "include", visibility = [ + "//score/datarouter/file_transfer:__subpackages__", "//score/datarouter/nonverbose_dlt:__pkg__", "//score/datarouter/nonverbose_dlt_stub:__pkg__", - "//score/datarouter/src/file_transfer:__subpackages__", - "//score/datarouter/src/persistent_logging:__pkg__", - "//score/datarouter/src/persistent_logging/persistent_logging:__pkg__", + "//score/datarouter/persistent_logging:__pkg__", + "//score/datarouter/persistent_logging/persistent_logging:__pkg__", "//score/datarouter/test:__subpackages__", ], deps = [ @@ -187,11 +185,11 @@ cc_library( features = COMPILER_WARNING_FEATURES, strip_include_prefix = "include", visibility = [ + "//score/datarouter/file_transfer:__subpackages__", "//score/datarouter/nonverbose_dlt:__pkg__", "//score/datarouter/nonverbose_dlt_stub:__pkg__", - "//score/datarouter/src/file_transfer:__subpackages__", - "//score/datarouter/src/persistent_logging:__pkg__", - "//score/datarouter/src/persistent_logging/persistent_logging:__pkg__", + "//score/datarouter/persistent_logging:__pkg__", + "//score/datarouter/persistent_logging/persistent_logging:__pkg__", ], deps = [ ":datarouter_types", @@ -450,7 +448,7 @@ cc_library( features = COMPILER_WARNING_FEATURES, strip_include_prefix = "include", visibility = [ - "//score/datarouter/src/file_transfer:__subpackages__", + "//score/datarouter/file_transfer:__subpackages__", ], deps = [ ":dltprotocol", @@ -494,7 +492,7 @@ cc_library( ], "//conditions:default": [], }) + select({ - "//score/datarouter/build_configuration_flags:config_file_transfer": ["DLT_FILE_TRANSFER_FEATURE"], + "//score/datarouter/build_configuration_flags:config_dlt_file_transfer": ["DLT_FILE_TRANSFER_FEATURE"], "//conditions:default": [], }) + select({ "//score/datarouter/build_configuration_flags:config_persistent_logging": ["PERSISTENT_LOGGING"], @@ -510,11 +508,11 @@ cc_library( ], "//conditions:default": ["//score/datarouter/src/persistency/stub_persistent_dictionary:stub_persistent_dictionary_factory"], }) + select({ - "//score/datarouter/build_configuration_flags:config_file_transfer": [ - "//score/datarouter/src/file_transfer/file_transfer_impl:file_transfer_stream_handler", + "//score/datarouter/build_configuration_flags:config_dlt_file_transfer": [ + "//score/datarouter/file_transfer/file_transfer_impl:file_transfer_stream_handler", ], "//conditions:default": [ - "//score/datarouter/src/file_transfer/file_transfer_stub:file_transfer_stream_handler_stub", + "//score/datarouter/file_transfer/file_transfer_stub:file_transfer_stream_handler_stub", ], }) + select({ "//score/datarouter/build_configuration_flags:config_datarouter_nonverbose_dlt": [ @@ -532,10 +530,10 @@ cc_library( ], }) + select({ "//score/datarouter/build_configuration_flags:config_persistent_logging": [ - "//score/datarouter/src/persistent_logging/persistent_logging_stub:sysedr_stub", + "//score/datarouter/persistent_logging/persistent_logging_stub:sysedr_stub", ], "//conditions:default": [ - "//score/datarouter/src/persistent_logging/persistent_logging_stub:sysedr_stub", + "//score/datarouter/persistent_logging/persistent_logging_stub:sysedr_stub", ], }), ) @@ -595,7 +593,7 @@ cc_library( ":udp_stream_output", ":unixdomain_server", "//score/datarouter/network:vlan", - "//score/datarouter/src/persistent_logging/persistent_logging_stub:sysedr_stub", + "//score/datarouter/persistent_logging/persistent_logging_stub:sysedr_stub", "@score_baselibs//score/language/futurecpp", "@score_baselibs//score/mw/log/configuration:nvconfig", "@score_baselibs//score/os:socket", @@ -762,10 +760,7 @@ cc_library( "//conditions:default": [], }), strip_include_prefix = "include", - visibility = [ - "//score/datarouter:__pkg__", - "//score/datarouter/test:__subpackages__", - ], + visibility = ["//visibility:private"], deps = [ ":datarouter_feature_config", ":datarouter_lib", @@ -775,7 +770,7 @@ cc_library( "@score_baselibs//score/mw/log/configuration:nvconfigfactory", ] + select({ "//score/datarouter/build_configuration_flags:config_persistent_logging": [ - "//score/datarouter/src/persistent_logging/persistent_logging_stub:sysedr_stub", + "//score/datarouter/persistent_logging/persistent_logging_stub:sysedr_stub", ], "//conditions:default": [], }), @@ -807,7 +802,7 @@ cc_library( "@score_baselibs//score/mw/log/configuration:nvconfigfactory", ] + select({ "//score/datarouter/build_configuration_flags:config_persistent_logging": [ - "//score/datarouter/src/persistent_logging/persistent_logging_stub:sysedr_stub", + "//score/datarouter/persistent_logging/persistent_logging_stub:sysedr_stub", ], "//conditions:default": [], }), @@ -863,9 +858,8 @@ cc_library( "//score/datarouter/daemon_communication:daemon_session_handle_interface", "//score/mw/log/detail/data_router:message_passing_interface", "//score/mw/log/detail/data_router/shared_memory:reader", - "@score_baselibs//score/concurrency", "@score_baselibs//score/os:pthread", - "@score_communication//score/message_passing", + "@score_communication//score/mw/com/message_passing", ], ) @@ -1043,7 +1037,7 @@ cc_library( ":log", "@score_baselibs//score/mw/log/configuration:nvconfig", "//score/datarouter/dlt_filetransfer_trigger_lib:filetransfer_message_types", - "//score/datarouter/src/persistent_logging/persistent_logging_stub:sysedr_stub", + "//score/datarouter/persistent_logging/persistent_logging_stub:sysedr_stub", ], ) @@ -1054,7 +1048,6 @@ cc_library( test_suite( name = "unit_tests", tests = [ - "//score/datarouter/lib/synchronized:synchronized_test", #"//score/datarouter/persistent_log_request:unit_tests", #"//score/datarouter/test:unit_tests", #"//score/datarouter/tools/generator:unit_tests", diff --git a/score/datarouter/build_configuration_flags/BUILD b/score/datarouter/build_configuration_flags/BUILD index 08a775d..e570218 100644 --- a/score/datarouter/build_configuration_flags/BUILD +++ b/score/datarouter/build_configuration_flags/BUILD @@ -71,14 +71,14 @@ config_setting( ) bool_flag( - name = "file_transfer", + name = "dlt_file_transfer_feature", build_setting_default = True, ) config_setting( - name = "config_file_transfer", + name = "config_dlt_file_transfer", flag_values = { - ":file_transfer": "True", + ":dlt_file_transfer_feature": "True", }, visibility = [ "//score/datarouter:__subpackages__", diff --git a/score/datarouter/daemon_communication/BUILD b/score/datarouter/daemon_communication/BUILD index e66e9ba..136356e 100644 --- a/score/datarouter/daemon_communication/BUILD +++ b/score/datarouter/daemon_communication/BUILD @@ -13,18 +13,6 @@ load("@rules_cc//cc:defs.bzl", "cc_library") load("@score_baselibs//score/language/safecpp:toolchain_features.bzl", "COMPILER_WARNING_FEATURES") -load("@score_baselibs//score/quality/clang_tidy:extra_checks.bzl", "clang_tidy_extra_checks") - -clang_tidy_extra_checks( - name = "clang_tidy_extra_checks", - extra_features = [ - "spp_code_style_check_header_guards", - "spp_code_style_check_method_names", - "spp_code_style_check_readability", - "spp_code_style_check_type_names", - "spp_code_style_check_variable_names", - ], -) cc_library( name = "daemon_session_handle_interface", diff --git a/score/datarouter/daemon_communication/session_handle_interface.h b/score/datarouter/daemon_communication/session_handle_interface.h index b5a1691..2d4a9df 100644 --- a/score/datarouter/daemon_communication/session_handle_interface.h +++ b/score/datarouter/daemon_communication/session_handle_interface.h @@ -26,7 +26,7 @@ namespace daemon class ISessionHandle { public: - virtual bool AcquireRequest() const = 0; + virtual void AcquireRequest() const = 0; virtual ~ISessionHandle() = default; }; diff --git a/score/datarouter/daemon_communication/session_handle_mock.h b/score/datarouter/daemon_communication/session_handle_mock.h index 79df25c..f09fe20 100644 --- a/score/datarouter/daemon_communication/session_handle_mock.h +++ b/score/datarouter/daemon_communication/session_handle_mock.h @@ -24,7 +24,7 @@ namespace score::platform::internal::daemon::mock class SessionHandleMock : public score::platform::internal::daemon::ISessionHandle { public: - MOCK_METHOD(bool, AcquireRequest, (), (const, override)); + MOCK_METHOD(void, AcquireRequest, (), (const, override)); }; } // namespace score::platform::internal::daemon::mock diff --git a/score/datarouter/datarouter/data_router.cpp b/score/datarouter/datarouter/data_router.cpp index b36b405..a64b307 100644 --- a/score/datarouter/datarouter/data_router.cpp +++ b/score/datarouter/datarouter/data_router.cpp @@ -122,6 +122,8 @@ std::unique_ptr DataRouter::new_source_session_impl( std::unique_ptr reader, const score::mw::log::NvConfig& nvConfig) { + std::lock_guard lock(subscriber_mutex_); + auto sourceSession = std::make_unique(*this, std::move(reader), @@ -132,19 +134,6 @@ std::unique_ptr DataRouter::new_source_session_impl( quota_enforcement_enabled, stats_logger_, std::make_unique(nvConfig)); - - if (!sourceSession) - { - return nullptr; - } - - std::lock_guard lock(subscriber_mutex_); - - // Insert is protected by subscriber_mutex_ held by caller (new_source_session_impl). - // This relies on the calling convention that SourceSession is only constructed - // from new_source_session_impl() which acquires the lock before construction. - std::ignore = sources_.insert(sourceSession.get()); - if (sourceCallback_) { sourceCallback_(std::move(sourceSession->get_parser())); @@ -279,8 +268,9 @@ void DataRouter::SourceSession::processAndRouteLogMessages(uint64_t& message_cou if ((peek_bytes.has_value() && peek_bytes.value() > 0) || (cmd->ticks_without_write > kTicksWithoutAcquireWhileNoWrites)) { - cmd->acquire_requested = request_acquire(); - needs_fast_reschedule = cmd->acquire_requested; + cmd->acquire_requested = true; + request_acquire(); + needs_fast_reschedule = true; } else { @@ -289,8 +279,9 @@ void DataRouter::SourceSession::processAndRouteLogMessages(uint64_t& message_cou } else { - cmd->acquire_requested = request_acquire(); - needs_fast_reschedule = cmd->acquire_requested; + cmd->acquire_requested = true; + request_acquire(); + needs_fast_reschedule = true; } } } @@ -386,6 +377,8 @@ DataRouter::SourceSession::SourceSession(DataRouter& router, stats->name = name; } + std::ignore = router_.sources_.insert(this); + { auto stats = stats_data_.lock(); if (stats->name == "DR") @@ -531,26 +524,19 @@ void DataRouter::SourceSession::show_stats() } } -bool DataRouter::SourceSession::request_acquire() +void DataRouter::SourceSession::request_acquire() { - const bool acquire_result = - score::cpp::visit(score::cpp::overload( - [](UnixDomainServer::SessionHandle& handle) { - handle.pass_message("<"); - return true; - }, - [](score::cpp::pmr::unique_ptr& handle) { - return handle->AcquireRequest(); - // For the quality team argumentation, kindly, check Ticket-200702 and Ticket-229594. - }), // LCOV_EXCL_LINE : tooling issue. no code to test in this line. - handle_); - - if (acquire_result) - { - ++(stats_data_.lock()->count_acquire_requests); - } - - return acquire_result; + ++(stats_data_.lock()->count_acquire_requests); + + score::cpp::visit(score::cpp::overload( + [](UnixDomainServer::SessionHandle& handle) { + handle.pass_message("<"); + }, + [](score::cpp::pmr::unique_ptr& handle) { + handle->AcquireRequest(); + // For the quality team argumentation, kindly, check Ticket-200702 and Ticket-229594. + }), // LCOV_EXCL_LINE : tooling issue. no code to test in this line. + handle_); } void DataRouter::SourceSession::on_acquire_response(const score::mw::log::detail::ReadAcquireResult& acq) diff --git a/score/datarouter/datarouter/data_router.h b/score/datarouter/datarouter/data_router.h index 0f86428..27d2926 100644 --- a/score/datarouter/datarouter/data_router.h +++ b/score/datarouter/datarouter/data_router.h @@ -182,7 +182,7 @@ class DataRouter void on_closed_by_peer() override; void checkAndSetQuotaEnforcement(); - bool request_acquire(); + void request_acquire(); Synchronized local_subscriber_data_; Synchronized command_data_; diff --git a/score/datarouter/dlt_filetransfer_trigger_lib/BUILD b/score/datarouter/dlt_filetransfer_trigger_lib/BUILD index 5e3eb57..d910cbd 100644 --- a/score/datarouter/dlt_filetransfer_trigger_lib/BUILD +++ b/score/datarouter/dlt_filetransfer_trigger_lib/BUILD @@ -13,18 +13,6 @@ load("@rules_cc//cc:defs.bzl", "cc_library") load("@score_baselibs//score/language/safecpp:toolchain_features.bzl", "COMPILER_WARNING_FEATURES") -load("@score_baselibs//score/quality/clang_tidy:extra_checks.bzl", "clang_tidy_extra_checks") - -clang_tidy_extra_checks( - name = "clang_tidy_extra_checks", - extra_features = [ - "spp_code_style_check_header_guards", - "spp_code_style_check_method_names", - "spp_code_style_check_readability", - "spp_code_style_check_type_names", - "spp_code_style_check_variable_names", - ], -) ## =========================================================================== ## File transfer diff --git a/score/datarouter/dlt_filetransfer_trigger_lib/filetransfer_message.h b/score/datarouter/dlt_filetransfer_trigger_lib/filetransfer_message.h index 4f2a998..5fb864e 100644 --- a/score/datarouter/dlt_filetransfer_trigger_lib/filetransfer_message.h +++ b/score/datarouter/dlt_filetransfer_trigger_lib/filetransfer_message.h @@ -31,7 +31,7 @@ struct FileTransferEntry // Unavoidable use of of union type, in future dltit_t with LoggingIdentifier. // coverity[autosar_cpp14_a9_5_1_violation] see above score::platform::dltid_t ctxid{}; - std::string file_name{}; + std::string file_name = ""; uint8_t delete_file = 0; }; diff --git a/score/datarouter/dlt_filetransfer_trigger_lib/include/file_transfer.h b/score/datarouter/dlt_filetransfer_trigger_lib/include/file_transfer.h index 5989082..8a0c2da 100644 --- a/score/datarouter/dlt_filetransfer_trigger_lib/include/file_transfer.h +++ b/score/datarouter/dlt_filetransfer_trigger_lib/include/file_transfer.h @@ -11,8 +11,8 @@ * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ -#ifndef SCORE_PAS_LOGGING_DLT_FILETRANSFER_TRIGGER_LIB_INCLUDE_FILE_TRANSFER_H -#define SCORE_PAS_LOGGING_DLT_FILETRANSFER_TRIGGER_LIB_INCLUDE_FILE_TRANSFER_H +#ifndef BMW_LIB_LOGGING_FILE_TRANSFER_H +#define BMW_LIB_LOGGING_FILE_TRANSFER_H #include "ifile_transfer.h" @@ -32,4 +32,4 @@ class FileTransfer final : public IFileTransfer } // namespace score::logging -#endif // SCORE_PAS_LOGGING_DLT_FILETRANSFER_TRIGGER_LIB_INCLUDE_FILE_TRANSFER_H +#endif // BMW_LIB_LOGGING_IFILE_TRANSFER_H diff --git a/score/datarouter/dlt_filetransfer_trigger_lib/include/ifile_transfer.h b/score/datarouter/dlt_filetransfer_trigger_lib/include/ifile_transfer.h index 373bc6c..12d8aad 100644 --- a/score/datarouter/dlt_filetransfer_trigger_lib/include/ifile_transfer.h +++ b/score/datarouter/dlt_filetransfer_trigger_lib/include/ifile_transfer.h @@ -11,8 +11,8 @@ * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ -#ifndef SCORE_PAS_LOGGING_DLT_FILETRANSFER_TRIGGER_LIB_INCLUDE_IFILE_TRANSFER_H -#define SCORE_PAS_LOGGING_DLT_FILETRANSFER_TRIGGER_LIB_INCLUDE_IFILE_TRANSFER_H +#ifndef AAS_PAS_LOGGING_DLT_FILETRANSFER_TRIGGER_LIB_INCLUDE_IFILE_TRANSFER_H +#define AAS_PAS_LOGGING_DLT_FILETRANSFER_TRIGGER_LIB_INCLUDE_IFILE_TRANSFER_H #include #include @@ -44,4 +44,4 @@ using IFileTransferPtr = std::unique_ptr; } // namespace score::logging -#endif // SCORE_PAS_LOGGING_DLT_FILETRANSFER_TRIGGER_LIB_INCLUDE_IFILE_TRANSFER_H +#endif // AAS_PAS_LOGGING_DLT_FILETRANSFER_TRIGGER_LIB_INCLUDE_IFILE_TRANSFER_H diff --git a/score/datarouter/dynamic_configuration/config_session_factory/BUILD b/score/datarouter/dynamic_configuration/config_session_factory/BUILD index b9a1343..c94f857 100644 --- a/score/datarouter/dynamic_configuration/config_session_factory/BUILD +++ b/score/datarouter/dynamic_configuration/config_session_factory/BUILD @@ -13,18 +13,6 @@ load("@rules_cc//cc:defs.bzl", "cc_library") load("@score_baselibs//score/language/safecpp:toolchain_features.bzl", "COMPILER_WARNING_FEATURES") -load("@score_baselibs//score/quality/clang_tidy:extra_checks.bzl", "clang_tidy_extra_checks") - -clang_tidy_extra_checks( - name = "clang_tidy_extra_checks", - extra_features = [ - "spp_code_style_check_header_guards", - "spp_code_style_check_method_names", - "spp_code_style_check_readability", - "spp_code_style_check_type_names", - "spp_code_style_check_variable_names", - ], -) [ cc_library( diff --git a/score/datarouter/dynamic_configuration/config_session_stub/BUILD b/score/datarouter/dynamic_configuration/config_session_stub/BUILD index 1c1848c..fd8e2a5 100644 --- a/score/datarouter/dynamic_configuration/config_session_stub/BUILD +++ b/score/datarouter/dynamic_configuration/config_session_stub/BUILD @@ -13,18 +13,6 @@ load("@rules_cc//cc:defs.bzl", "cc_library") load("@score_baselibs//score/language/safecpp:toolchain_features.bzl", "COMPILER_WARNING_FEATURES") -load("@score_baselibs//score/quality/clang_tidy:extra_checks.bzl", "clang_tidy_extra_checks") - -clang_tidy_extra_checks( - name = "clang_tidy_extra_checks", - extra_features = [ - "spp_code_style_check_header_guards", - "spp_code_style_check_method_names", - "spp_code_style_check_readability", - "spp_code_style_check_type_names", - "spp_code_style_check_variable_names", - ], -) [ cc_library( diff --git a/score/datarouter/dynamic_configuration/i_session/BUILD b/score/datarouter/dynamic_configuration/i_session/BUILD index c6450ed..7cdb71f 100644 --- a/score/datarouter/dynamic_configuration/i_session/BUILD +++ b/score/datarouter/dynamic_configuration/i_session/BUILD @@ -13,18 +13,6 @@ load("@rules_cc//cc:defs.bzl", "cc_library") load("@score_baselibs//score/language/safecpp:toolchain_features.bzl", "COMPILER_WARNING_FEATURES") -load("@score_baselibs//score/quality/clang_tidy:extra_checks.bzl", "clang_tidy_extra_checks") - -clang_tidy_extra_checks( - name = "clang_tidy_extra_checks", - extra_features = [ - "spp_code_style_check_header_guards", - "spp_code_style_check_method_names", - "spp_code_style_check_readability", - "spp_code_style_check_type_names", - "spp_code_style_check_variable_names", - ], -) cc_library( name = "i_session", diff --git a/score/datarouter/error/BUILD b/score/datarouter/error/BUILD index 9fd0a03..237e02d 100644 --- a/score/datarouter/error/BUILD +++ b/score/datarouter/error/BUILD @@ -13,18 +13,6 @@ load("@rules_cc//cc:defs.bzl", "cc_library") load("@score_baselibs//score/language/safecpp:toolchain_features.bzl", "COMPILER_WARNING_FEATURES") -load("@score_baselibs//score/quality/clang_tidy:extra_checks.bzl", "clang_tidy_extra_checks") - -clang_tidy_extra_checks( - name = "clang_tidy_extra_checks", - extra_features = [ - "spp_code_style_check_header_guards", - "spp_code_style_check_method_names", - "spp_code_style_check_readability", - "spp_code_style_check_type_names", - "spp_code_style_check_variable_names", - ], -) cc_library( name = "logging_error", diff --git a/score/datarouter/error/error.cpp b/score/datarouter/error/error.cpp index 221b87f..569dd2a 100644 --- a/score/datarouter/error/error.cpp +++ b/score/datarouter/error/error.cpp @@ -50,12 +50,12 @@ std::string_view LoggingErrorDomain::MessageFor(const score::result::ErrorCode& namespace { -constexpr LoggingErrorDomain kLoggingErrorDomain; +constexpr LoggingErrorDomain logging_error_domain; } score::result::Error MakeError(const LoggingErrorCode code, const std::string_view user_message) noexcept { - return {static_cast(code), kLoggingErrorDomain, user_message}; + return {static_cast(code), logging_error_domain, user_message}; } } // namespace error diff --git a/score/datarouter/error/error.h b/score/datarouter/error/error.h index 5685b74..5ab78b9 100644 --- a/score/datarouter/error/error.h +++ b/score/datarouter/error/error.h @@ -11,8 +11,8 @@ * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ -#ifndef SCORE_PAS_LOGGING_ERROR_ERROR_H -#define SCORE_PAS_LOGGING_ERROR_ERROR_H +#ifndef DLT_LOGGING_ERROR_ERROR_H_ +#define DLT_LOGGING_ERROR_ERROR_H_ #include "score/result/error.h" @@ -43,4 +43,4 @@ score::result::Error MakeError(const LoggingErrorCode code, const std::string_vi } // namespace logging } // namespace score -#endif // SCORE_PAS_LOGGING_ERROR_ERROR_H +#endif // DLT_LOGGING_ERROR_ERROR_H_ diff --git a/score/datarouter/src/file_transfer/BUILD b/score/datarouter/file_transfer/BUILD similarity index 94% rename from score/datarouter/src/file_transfer/BUILD rename to score/datarouter/file_transfer/BUILD index 5de30db..867f662 100644 --- a/score/datarouter/src/file_transfer/BUILD +++ b/score/datarouter/file_transfer/BUILD @@ -21,7 +21,7 @@ cc_library( ], features = COMPILER_WARNING_FEATURES, visibility = [ - "//score/datarouter/src/file_transfer:__subpackages__", + "//score/datarouter/file_transfer:__subpackages__", "//score/datarouter/test:__subpackages__", ], deps = [ diff --git a/score/datarouter/src/file_transfer/file_transfer_handler_factory.hpp b/score/datarouter/file_transfer/file_transfer_handler_factory.hpp similarity index 100% rename from score/datarouter/src/file_transfer/file_transfer_handler_factory.hpp rename to score/datarouter/file_transfer/file_transfer_handler_factory.hpp diff --git a/score/datarouter/src/file_transfer/file_transfer_stub/BUILD b/score/datarouter/file_transfer/file_transfer_stub/BUILD similarity index 95% rename from score/datarouter/src/file_transfer/file_transfer_stub/BUILD rename to score/datarouter/file_transfer/file_transfer_stub/BUILD index d550980..225dd3d 100644 --- a/score/datarouter/src/file_transfer/file_transfer_stub/BUILD +++ b/score/datarouter/file_transfer/file_transfer_stub/BUILD @@ -27,7 +27,7 @@ cc_library( deps = [ ":file_transfer_stream_handler_stub", "//score/datarouter:logparser", - "//score/datarouter/src/file_transfer:file_transfer_handler_factory", + "//score/datarouter/file_transfer:file_transfer_handler_factory", ], ) diff --git a/score/datarouter/src/file_transfer/file_transfer_stub/file_transfer_handler_factory_stub.h b/score/datarouter/file_transfer/file_transfer_stub/file_transfer_handler_factory_stub.h similarity index 91% rename from score/datarouter/src/file_transfer/file_transfer_stub/file_transfer_handler_factory_stub.h rename to score/datarouter/file_transfer/file_transfer_stub/file_transfer_handler_factory_stub.h index 15a36f1..420452f 100644 --- a/score/datarouter/src/file_transfer/file_transfer_stub/file_transfer_handler_factory_stub.h +++ b/score/datarouter/file_transfer/file_transfer_stub/file_transfer_handler_factory_stub.h @@ -15,8 +15,8 @@ #define PAS_LOGGING_FILE_TRANSFER_HANDLER_FACTORY_STUB_H #include "logparser/logparser.h" -#include "score/datarouter/src/file_transfer/file_transfer_handler_factory.hpp" -#include "score/datarouter/src/file_transfer/file_transfer_stub/file_transfer_stream_handler_stub.h" +#include "score/datarouter/file_transfer/file_transfer_handler_factory.hpp" +#include "score/datarouter/file_transfer/file_transfer_stub/file_transfer_stream_handler_stub.h" #include namespace score diff --git a/score/datarouter/src/file_transfer/file_transfer_stub/file_transfer_stream_handler_stub.h b/score/datarouter/file_transfer/file_transfer_stub/file_transfer_stream_handler_stub.h similarity index 100% rename from score/datarouter/src/file_transfer/file_transfer_stub/file_transfer_stream_handler_stub.h rename to score/datarouter/file_transfer/file_transfer_stub/file_transfer_stream_handler_stub.h diff --git a/score/datarouter/include/applications/datarouter_feature_config.h b/score/datarouter/include/applications/datarouter_feature_config.h index 0799ce2..586b881 100644 --- a/score/datarouter/include/applications/datarouter_feature_config.h +++ b/score/datarouter/include/applications/datarouter_feature_config.h @@ -38,15 +38,15 @@ #endif #if defined(DLT_FILE_TRANSFER_FEATURE) -#include "score/datarouter/src/file_transfer/file_transfer_impl/filetransfer_stream.h" +#include "score/datarouter/file_transfer/file_transfer_impl/filetransfer_stream.h" #else -#include "score/datarouter/src/file_transfer/file_transfer_stub/file_transfer_stream_handler_stub.h" +#include "score/datarouter/file_transfer/file_transfer_stub/file_transfer_stream_handler_stub.h" #endif #if defined(PERSISTENT_LOGGING) -#include "score/datarouter/src/persistent_logging/persistent_logging/sysedr_concrete_factory.h" +#include "score/datarouter/persistent_logging/persistent_logging/sysedr_concrete_factory.h" #else -#include "score/datarouter/src/persistent_logging/persistent_logging_stub/stub_sysedr_factory.h" +#include "score/datarouter/persistent_logging/persistent_logging_stub/stub_sysedr_factory.h" #endif namespace score diff --git a/score/datarouter/include/daemon/dlt_log_server.h b/score/datarouter/include/daemon/dlt_log_server.h index 1879521..4da19b5 100644 --- a/score/datarouter/include/daemon/dlt_log_server.h +++ b/score/datarouter/include/daemon/dlt_log_server.h @@ -322,7 +322,7 @@ class DltLogServer : score::platform::datarouter::DltNonverboseHandlerType::IOut std::unique_ptr sysedr_handler_; - void SendNonVerbose(const score::mw::log::config::NvMsgDescriptor& desc, + void sendNonVerbose(const score::mw::log::config::NvMsgDescriptor& desc, uint32_t tmsp, const void* data, size_t size) override final; diff --git a/score/datarouter/include/daemon/message_passing_server.h b/score/datarouter/include/daemon/message_passing_server.h index 3836534..28ee774 100644 --- a/score/datarouter/include/daemon/message_passing_server.h +++ b/score/datarouter/include/daemon/message_passing_server.h @@ -18,20 +18,15 @@ #include "score/mw/log/detail/data_router/shared_memory/common.h" -#include "score/message_passing/i_client_factory.h" -#include "score/message_passing/i_server_connection.h" -#include "score/message_passing/i_server_factory.h" +#include "score/mw/com/message_passing/receiver_factory.h" +#include "score/mw/com/message_passing/sender_factory.h" #include "score/mw/log/detail/logging_identifier.h" #include "score/datarouter/daemon_communication/session_handle_interface.h" #include - -#include "score/concurrency/interruptible_wait.h" -#include #include #include #include -#include #include #include #include @@ -52,19 +47,6 @@ class IMessagePassingServerSessionWrapper virtual void EnqueueTickWhileLocked(pid_t /*pid*/) = 0; }; -/// QNX message passing server for handling logging client connections. -/// -/// Manages multiple client sessions and processes their log data asynchronously. -/// Uses a single worker thread to read from client shared memory buffers and route -/// log messages through the DataRouter pipeline. -/// -/// Threading model: -/// - Dispatch thread: Created by QnxDispatchEngine; receives connection requests and -/// messages via QNX message passing (dispatch_block loop in QnxDispatchEngine::RunOnThread) -/// - Worker thread: Processes session tick events to read shared memory and route logs -/// -/// Each client session is scheduled on the worker thread via a work queue to avoid -/// blocking the dispatch thread during potentially slow shared memory operations. class MessagePassingServer : public IMessagePassingServerSessionWrapper { public: @@ -73,18 +55,17 @@ class MessagePassingServer : public IMessagePassingServerSessionWrapper public: SessionHandle(pid_t pid, MessagePassingServer* server, - score::cpp::pmr::unique_ptr sender) - : daemon::ISessionHandle(), sender_(std::move(sender)), pid_(pid), server_(server), sender_state_{} + score::cpp::pmr::unique_ptr sender) + : daemon::ISessionHandle(), sender_(std::move(sender)), pid_(pid), server_(server) { } - bool AcquireRequest() const override; + void AcquireRequest() const override; private: - score::cpp::pmr::unique_ptr sender_; + score::cpp::pmr::unique_ptr sender_; pid_t pid_; MessagePassingServer* server_; - mutable std::optional sender_state_; }; class ISession @@ -102,20 +83,19 @@ class MessagePassingServer : public IMessagePassingServerSessionWrapper const score::mw::log::detail::ConnectMessageFromClient&, score::cpp::pmr::unique_ptr)>; - MessagePassingServer(SessionFactory factory, - std::shared_ptr server_factory = nullptr, - std::shared_ptr client_factory = nullptr); + MessagePassingServer(SessionFactory factory, ::score::concurrency::Executor& executor); ~MessagePassingServer() noexcept; // for unit test only. to keep rest of functions in private class MessagePassingServerForTest; private: + static score::mw::com::message_passing::ShortMessage PrepareAcquireRequestMessage() noexcept; + void NotifyAcquireRequestFailed(std::int32_t pid); - void MessageCallback(const score::cpp::span message, const pid_t pid); - void OnConnectRequest(const score::cpp::span message, const pid_t pid); - void OnAcquireResponse(const score::cpp::span message, const pid_t pid); + void OnConnectRequest(const score::mw::com::message_passing::MediumMessagePayload payload, const pid_t pid); + void OnAcquireResponse(const score::mw::com::message_passing::MediumMessagePayload payload, const pid_t pid); using timestamp_t = std::chrono::steady_clock::time_point; @@ -177,7 +157,7 @@ class MessagePassingServer : public IMessagePassingServerSessionWrapper SessionFactory factory_; - score::cpp::pmr::unique_ptr receiver_; + score::cpp::pmr::unique_ptr receiver_; std::mutex mutex_; score::cpp::stop_source stop_source_; @@ -186,12 +166,9 @@ class MessagePassingServer : public IMessagePassingServerSessionWrapper std::condition_variable worker_cond_; // to wake up worker thread std::unordered_map pid_session_map_; std::queue work_queue_; - std::atomic workers_exit_; + bool workers_exit_; std::condition_variable server_cond_; // to wake up server thread bool session_finishing_; - - std::shared_ptr server_factory_; - std::shared_ptr client_factory_; }; } // namespace internal diff --git a/score/datarouter/include/daemon/socketserver.h b/score/datarouter/include/daemon/socketserver.h index dce4823..e6040e6 100644 --- a/score/datarouter/include/daemon/socketserver.h +++ b/score/datarouter/include/daemon/socketserver.h @@ -27,40 +27,6 @@ #include #include #include -#include - -// Forward declaration for testing -namespace score -{ -namespace mw -{ -namespace log -{ -namespace detail -{ -class ConnectMessageFromClient; -} -} // namespace log -} // namespace mw -} // namespace score - -namespace score -{ -namespace os -{ -class Pthread; -} // namespace os -} // namespace score - -#ifdef __QNX__ -#include "score/message_passing/qnx_dispatch/qnx_dispatch_client_factory.h" -#include "score/message_passing/qnx_dispatch/qnx_dispatch_engine.h" -#include "score/message_passing/qnx_dispatch/qnx_dispatch_server_factory.h" -#else -#include "score/message_passing/unix_domain/unix_domain_client_factory.h" -#include "score/message_passing/unix_domain/unix_domain_engine.h" -#include "score/message_passing/unix_domain/unix_domain_server_factory.h" -#endif namespace score { @@ -69,14 +35,6 @@ namespace platform namespace datarouter { -#ifdef __QNX__ -using ServerFactory = score::message_passing::QnxDispatchServerFactory; -using ClientFactory = score::message_passing::QnxDispatchClientFactory; -#else -using ServerFactory = score::message_passing::UnixDomainServerFactory; -using ClientFactory = score::message_passing::UnixDomainClientFactory; -#endif - class SocketServer { public: @@ -92,9 +50,6 @@ class SocketServer static SocketServer server; server.doWork(exit_requested, no_adaptive_runtime); } - // static void run(const std::atomic_bool& exit_requested, const bool no_adaptive_runtime); - - /// @internal Test helpers - do not use in production code static PersistentStorageHandlers InitializePersistentStorage( std::unique_ptr& persistent_dictionary); @@ -138,11 +93,6 @@ class SocketServer DataRouter& router, score::logging::dltserver::DltLogServer& dlt_server, score::mw::log::Logger& stats_logger); - // Testable helper functions - static void SetThreadName() noexcept; - static void SetThreadName(score::os::Pthread& pthread_instance) noexcept; - static std::string ResolveSharedMemoryFileName(const score::mw::log::detail::ConnectMessageFromClient& conn, - const std::string& appid); private: void doWork(const std::atomic_bool& exit_requested, const bool no_adaptive_runtime); diff --git a/score/datarouter/include/unix_domain/unix_domain_common.h b/score/datarouter/include/unix_domain/unix_domain_common.h index 4f4861f..00bd37a 100644 --- a/score/datarouter/include/unix_domain/unix_domain_common.h +++ b/score/datarouter/include/unix_domain/unix_domain_common.h @@ -60,7 +60,7 @@ class UnixDomainSockAddr bool is_abstract() { - return addr_.sun_path[0] == 0U; + return !addr_.sun_path[0]; } struct sockaddr_un addr_; diff --git a/score/datarouter/lib/synchronized/BUILD b/score/datarouter/lib/synchronized/BUILD index cec9b01..a9b787f 100644 --- a/score/datarouter/lib/synchronized/BUILD +++ b/score/datarouter/lib/synchronized/BUILD @@ -12,18 +12,6 @@ # ******************************************************************************* load("@rules_cc//cc:defs.bzl", "cc_library", "cc_test") -load("@score_baselibs//score/quality/clang_tidy:extra_checks.bzl", "clang_tidy_extra_checks") - -clang_tidy_extra_checks( - name = "clang_tidy_extra_checks", - extra_features = [ - "spp_code_style_check_header_guards", - "spp_code_style_check_method_names", - "spp_code_style_check_readability", - "spp_code_style_check_type_names", - "spp_code_style_check_variable_names", - ], -) # Synchronized utility BUILD file diff --git a/score/datarouter/lib/synchronized/synchronized.h b/score/datarouter/lib/synchronized/synchronized.h index 789f649..404bfd4 100644 --- a/score/datarouter/lib/synchronized/synchronized.h +++ b/score/datarouter/lib/synchronized/synchronized.h @@ -11,8 +11,8 @@ * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ -#ifndef SCORE_PAS_LOGGING_LIB_SYNCHRONIZED_SYNCHRONIZED_H -#define SCORE_PAS_LOGGING_LIB_SYNCHRONIZED_SYNCHRONIZED_H +#ifndef SCORE_PAS_LOGGING_LIB_SYNCHRONIZED_SYNCHRONIZED_H_ +#define SCORE_PAS_LOGGING_LIB_SYNCHRONIZED_SYNCHRONIZED_H_ #include #include @@ -48,7 +48,7 @@ class Synchronized public: template explicit Synchronized(Args&&... args) noexcept(std::is_nothrow_constructible_v) - : obj_(std::forward(args)...) + : obj(std::forward(args)...) { } @@ -60,37 +60,37 @@ class Synchronized [[nodiscard]] auto lock() { - auto unlocker = [ul = std::unique_lock(mut_)](T*) mutable {}; - return std::unique_ptr(&obj_, std::move(unlocker)); + auto unlocker = [ul = std::unique_lock(mut)](T*) mutable {}; + return std::unique_ptr(&obj, std::move(unlocker)); } [[nodiscard]] auto lock() const { - auto unlocker = [ul = std::unique_lock(mut_)](const T*) mutable {}; - return std::unique_ptr(&obj_, std::move(unlocker)); + auto unlocker = [ul = std::unique_lock(mut)](const T*) mutable {}; + return std::unique_ptr(&obj, std::move(unlocker)); } template - auto WithLock(Func&& f) + auto with_lock(Func&& f) { auto guard = lock(); return std::invoke(std::forward(f), *guard); } template - auto WithLock(Func&& f) const + auto with_lock(Func&& f) const { auto guard = lock(); return std::invoke(std::forward(f), *guard); } private: - mutable Mutex mut_; - T obj_; + mutable Mutex mut; + T obj; }; } // namespace datarouter } // namespace platform } // namespace score -#endif // SCORE_PAS_LOGGING_LIB_SYNCHRONIZED_SYNCHRONIZED_H +#endif // SCORE_PAS_LOGGING_LIB_SYNCHRONIZED_SYNCHRONIZED_H_ diff --git a/score/datarouter/lib/synchronized/synchronized_test.cpp b/score/datarouter/lib/synchronized/synchronized_test.cpp index 93fbc24..f2d98cd 100644 --- a/score/datarouter/lib/synchronized/synchronized_test.cpp +++ b/score/datarouter/lib/synchronized/synchronized_test.cpp @@ -26,7 +26,7 @@ struct TestStruct { int value; - int Sum() const + int sum() const { return value + 50; } @@ -69,11 +69,11 @@ struct ParameterizedObject ParameterizedObject(int x_val, int y_val, const std::string& n) : x(x_val), y(y_val), name(n) {} - int Sum() const + int sum() const { return x + y; } - const std::string& GetName() const + const std::string& get_name() const { return name; } @@ -87,16 +87,16 @@ class SynchronizedUtilityTest : public ::testing::Test { Synchronized sync_value(42); - int result = sync_value.WithLock([](const auto& value) noexcept { + int result = sync_value.with_lock([](const auto& value) noexcept { return value; }); EXPECT_EQ(result, 42); - sync_value.WithLock([](auto& value) noexcept { + sync_value.with_lock([](auto& value) noexcept { value = 100; }); - result = sync_value.WithLock([](const auto& value) noexcept { + result = sync_value.with_lock([](const auto& value) noexcept { return value; }); EXPECT_EQ(result, 100); @@ -123,7 +123,7 @@ TEST_F(SynchronizedUtilityTest, TestThreadSafety) threads.push_back(std::thread([&counter]() noexcept { for (int j = 0; j < increments_per_thread; ++j) { - counter.WithLock([](auto& value) noexcept { + counter.with_lock([](auto& value) noexcept { ++value; }); } @@ -135,7 +135,7 @@ TEST_F(SynchronizedUtilityTest, TestThreadSafety) thread.join(); } - int result = counter.WithLock([](auto& value) noexcept { + int result = counter.with_lock([](auto& value) noexcept { return value; }); @@ -153,7 +153,7 @@ TEST_F(SynchronizedUtilityTest, LockMethodBasic) EXPECT_EQ(*locked_ptr, 100); } - sync_int.WithLock([](int& value) { + sync_int.with_lock([](int& value) { EXPECT_EQ(value, 100); }); } @@ -172,7 +172,7 @@ TEST_F(SynchronizedUtilityTest, TestStructLockReturnValue) EXPECT_EQ(locked_ptr->value, 100); EXPECT_EQ((*locked_ptr).value, 100); - EXPECT_EQ((*locked_ptr).Sum(), 150); + EXPECT_EQ((*locked_ptr).sum(), 150); } } @@ -185,10 +185,10 @@ TEST_F(SynchronizedUtilityTest, TestStructConstLockBehavior) EXPECT_EQ(const_locked_ptr->value, 42); // const_locked_ptr->value = 100; // Should not compile EXPECT_EQ((*const_locked_ptr).value, 42); - EXPECT_EQ((*const_locked_ptr).Sum(), 92); + EXPECT_EQ((*const_locked_ptr).sum(), 92); } - const_sync_struct.WithLock([](const TestStruct& s) noexcept { + const_sync_struct.with_lock([](const TestStruct& s) noexcept { EXPECT_EQ(s.value, 42); }); } @@ -197,20 +197,20 @@ TEST_F(SynchronizedUtilityTest, TestStructWithLockVariations) { Synchronized sync_struct(TestStruct{42}); - sync_struct.WithLock([](TestStruct& s) noexcept { + sync_struct.with_lock([](TestStruct& s) noexcept { s.value = 100; }); - int result = sync_struct.WithLock([](const TestStruct& s) noexcept { + int result = sync_struct.with_lock([](const TestStruct& s) noexcept { return s.value; }); EXPECT_EQ(result, 100); - sync_struct.WithLock([](TestStruct& s) noexcept { + sync_struct.with_lock([](TestStruct& s) noexcept { s.value = s.value * 2; }); - result = sync_struct.WithLock([](const TestStruct& s) noexcept { + result = sync_struct.with_lock([](const TestStruct& s) noexcept { return s.value; }); EXPECT_EQ(result, 200); @@ -220,7 +220,7 @@ TEST_F(SynchronizedUtilityTest, TestStructMemberFunctionPointers) { Synchronized sync_struct(TestStruct{42}); - auto result = sync_struct.WithLock([](const TestStruct& s) noexcept { + auto result = sync_struct.with_lock([](const TestStruct& s) noexcept { return s.value; }); EXPECT_EQ(result, 42); @@ -234,9 +234,9 @@ TEST_F(SynchronizedUtilityTest, TestStructFreeFunctionPointers) s.value = 999; }; - sync_struct.WithLock(process_struct); + sync_struct.with_lock(process_struct); - auto result = sync_struct.WithLock([](const TestStruct& s) noexcept { + auto result = sync_struct.with_lock([](const TestStruct& s) noexcept { return s.value; }); EXPECT_EQ(result, 999); @@ -252,7 +252,7 @@ TEST_F(SynchronizedUtilityTest, TestStructLockNonConst) EXPECT_EQ(locked_ptr->value, 77); } - auto result = sync_struct.WithLock([](const TestStruct& s) noexcept { + auto result = sync_struct.with_lock([](const TestStruct& s) noexcept { return s.value; }); EXPECT_EQ(result, 77); @@ -268,7 +268,7 @@ TEST_F(SynchronizedUtilityTest, TestStructLockConst) // const_sync_struct->value = 100; // Should not compile } - const_sync_struct.WithLock([](const TestStruct& s) noexcept { + const_sync_struct.with_lock([](const TestStruct& s) noexcept { EXPECT_EQ(s.value, 42); }); } @@ -280,22 +280,22 @@ TEST_F(SynchronizedUtilityTest, TestStructLambdaCaptureModes) int external_value = 10; // Test lambda with value capture - sync_struct.WithLock([external_value](TestStruct& s) noexcept { + sync_struct.with_lock([external_value](TestStruct& s) noexcept { s.value = external_value * 5; }); - auto result = sync_struct.WithLock([](const TestStruct& s) noexcept { + auto result = sync_struct.with_lock([](const TestStruct& s) noexcept { return s.value; }); EXPECT_EQ(result, 50); // Test lambda with reference capture int multiplier = 4; - sync_struct.WithLock([&multiplier](TestStruct& s) noexcept { + sync_struct.with_lock([&multiplier](TestStruct& s) noexcept { s.value = s.value * multiplier; }); - result = sync_struct.WithLock([](const TestStruct& s) noexcept { + result = sync_struct.with_lock([](const TestStruct& s) noexcept { return s.value; }); EXPECT_EQ(result, 200); @@ -305,11 +305,11 @@ TEST_F(SynchronizedUtilityTest, TestStructVoidReturningLambdas) { Synchronized sync_struct(TestStruct{42}); - sync_struct.WithLock([](TestStruct& s) noexcept -> void { + sync_struct.with_lock([](TestStruct& s) noexcept -> void { s.value = 123; }); - auto result = sync_struct.WithLock([](const TestStruct& s) noexcept { + auto result = sync_struct.with_lock([](const TestStruct& s) noexcept { return s.value; }); EXPECT_EQ(result, 123); @@ -319,7 +319,7 @@ TEST_F(SynchronizedUtilityTest, TestStructCopyVsMoveSemantics) { // Test construction from temporary (move semantics) Synchronized sync_struct1(TestStruct{42}); - auto val = sync_struct1.WithLock([](const TestStruct& s) noexcept { + auto val = sync_struct1.with_lock([](const TestStruct& s) noexcept { return s.value; }); EXPECT_EQ(val, 42); @@ -327,14 +327,14 @@ TEST_F(SynchronizedUtilityTest, TestStructCopyVsMoveSemantics) // Test construction from lvalue (copy semantics) TestStruct temp_struct{55}; Synchronized sync_struct2(temp_struct); - auto val1 = sync_struct2.WithLock([](const TestStruct& s) noexcept { + auto val1 = sync_struct2.with_lock([](const TestStruct& s) noexcept { return s.value; }); EXPECT_EQ(val1, 55); // Test in-place construction Synchronized sync_struct3(TestStruct{77}); - auto val2 = sync_struct3.WithLock([](const TestStruct& s) noexcept { + auto val2 = sync_struct3.with_lock([](const TestStruct& s) noexcept { return s.value; }); EXPECT_EQ(val2, 77); @@ -345,16 +345,16 @@ TEST_F(SynchronizedUtilityTest, TestMoveOnlyObject) { Synchronized sync_obj(150); - auto result = sync_obj.WithLock([](const auto& obj) noexcept { + auto result = sync_obj.with_lock([](const auto& obj) noexcept { return obj.value; }); EXPECT_EQ(result, 150); - sync_obj.WithLock([](auto& obj) noexcept { + sync_obj.with_lock([](auto& obj) noexcept { obj.value = 300; }); - auto val = sync_obj.WithLock([](const auto& obj) noexcept { + auto val = sync_obj.with_lock([](const auto& obj) noexcept { return obj.value; }); EXPECT_EQ(val, 300); @@ -365,16 +365,16 @@ TEST_F(SynchronizedUtilityTest, TestNoCopyNoMoveObject) { Synchronized sync_obj(250); - auto result = sync_obj.WithLock([](const auto& obj) noexcept { + auto result = sync_obj.with_lock([](const auto& obj) noexcept { return obj.value; }); EXPECT_EQ(result, 250); - sync_obj.WithLock([](auto& obj) noexcept { + sync_obj.with_lock([](auto& obj) noexcept { obj.value = 500; }); - auto val = sync_obj.WithLock([](const auto& obj) noexcept { + auto val = sync_obj.with_lock([](const auto& obj) noexcept { return obj.value; }); EXPECT_EQ(val, 500); @@ -385,16 +385,16 @@ TEST_F(SynchronizedUtilityTest, TestDefaultConstructedObject) { Synchronized sync_obj{}; - auto result = sync_obj.WithLock([](const auto& obj) noexcept { + auto result = sync_obj.with_lock([](const auto& obj) noexcept { return obj.value; }); EXPECT_EQ(result, 42); - sync_obj.WithLock([](auto& obj) noexcept { + sync_obj.with_lock([](auto& obj) noexcept { obj.value = 100; }); - auto val = sync_obj.WithLock([](const auto& obj) noexcept { + auto val = sync_obj.with_lock([](const auto& obj) noexcept { return obj.value; }); EXPECT_EQ(val, 100); @@ -405,23 +405,23 @@ TEST_F(SynchronizedUtilityTest, TestParameterizedConstruction) { Synchronized sync_obj(10, 20, "test_object"); - auto result = sync_obj.WithLock([](const auto& obj) noexcept { - return obj.Sum(); + auto result = sync_obj.with_lock([](const auto& obj) noexcept { + return obj.sum(); }); EXPECT_EQ(result, 30); - auto name = sync_obj.WithLock([](const auto& obj) noexcept { - return obj.GetName(); + auto name = sync_obj.with_lock([](const auto& obj) noexcept { + return obj.get_name(); }); EXPECT_EQ(name, "test_object"); - sync_obj.WithLock([](auto& obj) noexcept { + sync_obj.with_lock([](auto& obj) noexcept { obj.x = 15; obj.y = 25; }); - result = sync_obj.WithLock([](const auto& obj) noexcept { - return obj.Sum(); + result = sync_obj.with_lock([](const auto& obj) noexcept { + return obj.sum(); }); EXPECT_EQ(result, 40); } @@ -430,7 +430,7 @@ TEST_F(SynchronizedUtilityTest, TestConstOperations) { const Synchronized const_sync_struct(TestStruct{42}); - auto result = const_sync_struct.WithLock([](const TestStruct& s) noexcept { + auto result = const_sync_struct.with_lock([](const TestStruct& s) noexcept { return s.value; }); EXPECT_EQ(result, 42); @@ -451,26 +451,26 @@ TEST_F(SynchronizedUtilityTest, LockAndWithLock) EXPECT_EQ(locked_ptr->value, 150); } - sync_struct.WithLock([](TestStruct& s) noexcept { + sync_struct.with_lock([](TestStruct& s) noexcept { s.value = 200; }); - auto result = sync_struct.WithLock([](const TestStruct& s) { - return s.Sum(); + auto result = sync_struct.with_lock([](const TestStruct& s) { + return s.sum(); }); EXPECT_EQ(result, 250); - auto val1 = sync_struct.WithLock([](const TestStruct& s) noexcept { + auto val1 = sync_struct.with_lock([](const TestStruct& s) noexcept { return s.value; }); EXPECT_EQ(val1, 200); EXPECT_NO_THROW({ - sync_struct.WithLock([](const TestStruct& s) noexcept { + sync_struct.with_lock([](const TestStruct& s) noexcept { EXPECT_EQ(s.value, 200); }); }); - auto val2 = sync_struct.WithLock([](const TestStruct& s) noexcept { + auto val2 = sync_struct.with_lock([](const TestStruct& s) noexcept { return s.value; }); EXPECT_EQ(val2, 200); @@ -480,26 +480,26 @@ TEST_F(SynchronizedUtilityTest, TestStructExceptionSafetyDetailed) { Synchronized sync_struct(TestStruct{42}); - sync_struct.WithLock([](TestStruct& s) noexcept { + sync_struct.with_lock([](TestStruct& s) noexcept { s.value = 100; }); EXPECT_NO_THROW({ - sync_struct.WithLock([](TestStruct& s) noexcept { + sync_struct.with_lock([](TestStruct& s) noexcept { s.value = 999; EXPECT_EQ(s.value, 999); }); }); - auto val = sync_struct.WithLock([](const TestStruct& s) noexcept { + auto val = sync_struct.with_lock([](const TestStruct& s) noexcept { return s.value; }); EXPECT_EQ(val, 999); - sync_struct.WithLock([](TestStruct& s) noexcept { + sync_struct.with_lock([](TestStruct& s) noexcept { s.value = 200; }); - auto val2 = sync_struct.WithLock([](const TestStruct& s) noexcept { + auto val2 = sync_struct.with_lock([](const TestStruct& s) noexcept { return s.value; }); EXPECT_EQ(val2, 200); diff --git a/score/datarouter/network/BUILD b/score/datarouter/network/BUILD index 6128587..9aee0a2 100644 --- a/score/datarouter/network/BUILD +++ b/score/datarouter/network/BUILD @@ -12,18 +12,6 @@ # ******************************************************************************* load("@rules_cc//cc:defs.bzl", "cc_library") -load("@score_baselibs//score/quality/clang_tidy:extra_checks.bzl", "clang_tidy_extra_checks") - -clang_tidy_extra_checks( - name = "clang_tidy_extra_checks", - extra_features = [ - "spp_code_style_check_header_guards", - "spp_code_style_check_method_names", - "spp_code_style_check_readability", - "spp_code_style_check_type_names", - "spp_code_style_check_variable_names", - ], -) cc_library( name = "vlan", diff --git a/score/datarouter/network/vlan_local.h b/score/datarouter/network/vlan_local.h index a805db2..d820d6c 100644 --- a/score/datarouter/network/vlan_local.h +++ b/score/datarouter/network/vlan_local.h @@ -29,10 +29,6 @@ class Vlan : public ObjectSeam public: /// \brief thread-safe singleton accessor /// \return Either concrete OS-dependent instance or respective set mock instance - - // Follows naming convention of public Vlan API defined in score/network/vlan.h - // As this class serves as internal implementation stub - // NOLINTNEXTLINE(readability-identifier-naming): Justification above static Vlan& instance() noexcept; /// \brief Sets the IEEE 802.1Q PCP field for a given file descriptor to define the priority of the packets sent by diff --git a/score/datarouter/nonverbose_dlt_stub/BUILD b/score/datarouter/nonverbose_dlt_stub/BUILD index 5ae03b5..e4e672c 100644 --- a/score/datarouter/nonverbose_dlt_stub/BUILD +++ b/score/datarouter/nonverbose_dlt_stub/BUILD @@ -13,18 +13,6 @@ load("@rules_cc//cc:defs.bzl", "cc_library") load("@score_baselibs//score/language/safecpp:toolchain_features.bzl", "COMPILER_WARNING_FEATURES") -load("@score_baselibs//score/quality/clang_tidy:extra_checks.bzl", "clang_tidy_extra_checks") - -clang_tidy_extra_checks( - name = "clang_tidy_extra_checks", - extra_features = [ - "spp_code_style_check_header_guards", - "spp_code_style_check_method_names", - "spp_code_style_check_readability", - "spp_code_style_check_type_names", - "spp_code_style_check_variable_names", - ], -) [ cc_library( diff --git a/score/datarouter/nonverbose_dlt_stub/stub_nonverbose_dlt.h b/score/datarouter/nonverbose_dlt_stub/stub_nonverbose_dlt.h index 02937db..6bf0d2e 100644 --- a/score/datarouter/nonverbose_dlt_stub/stub_nonverbose_dlt.h +++ b/score/datarouter/nonverbose_dlt_stub/stub_nonverbose_dlt.h @@ -33,7 +33,7 @@ class StubDltNonverboseHandler : public LogParser::AnyHandler class IOutput { public: - virtual void SendNonVerbose(const score::mw::log::config::NvMsgDescriptor& desc, + virtual void sendNonVerbose(const score::mw::log::config::NvMsgDescriptor& desc, uint32_t tmsp, const void* data, size_t size) = 0; diff --git a/score/datarouter/src/persistent_logging/BUILD b/score/datarouter/persistent_logging/BUILD similarity index 64% rename from score/datarouter/src/persistent_logging/BUILD rename to score/datarouter/persistent_logging/BUILD index 7811b88..194f120 100644 --- a/score/datarouter/src/persistent_logging/BUILD +++ b/score/datarouter/persistent_logging/BUILD @@ -12,25 +12,13 @@ # ******************************************************************************* load("@rules_cc//cc:defs.bzl", "cc_library") -load("@score_baselibs//score/quality/clang_tidy:extra_checks.bzl", "clang_tidy_extra_checks") - -clang_tidy_extra_checks( - name = "clang_tidy_extra_checks", - extra_features = [ - "spp_code_style_check_header_guards", - "spp_code_style_check_method_names", - "spp_code_style_check_readability", - "spp_code_style_check_type_names", - "spp_code_style_check_variable_names", - ], -) cc_library( name = "sysedr_handler_interface", hdrs = [ "isysedr_handler.h", ], - visibility = ["//score/datarouter/src/persistent_logging:__subpackages__"], + visibility = ["//score/datarouter/persistent_logging:__subpackages__"], deps = [ "//score/datarouter:logparser", ], @@ -42,7 +30,7 @@ cc_library( "sysedr_factory.hpp", ], visibility = [ - "//score/datarouter/src/persistent_logging:__subpackages__", + "//score/datarouter/persistent_logging:__subpackages__", "//score/datarouter/test:__subpackages__", ], deps = [ diff --git a/score/datarouter/src/persistent_logging/isysedr_handler.h b/score/datarouter/persistent_logging/isysedr_handler.h similarity index 86% rename from score/datarouter/src/persistent_logging/isysedr_handler.h rename to score/datarouter/persistent_logging/isysedr_handler.h index f4a0c9f..922d2d9 100644 --- a/score/datarouter/src/persistent_logging/isysedr_handler.h +++ b/score/datarouter/persistent_logging/isysedr_handler.h @@ -11,8 +11,8 @@ * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ -#ifndef SCORE_PAS_LOGGING_SRC_PERSISTENT_LOGGING_ISYSEDR_HANDLER_H -#define SCORE_PAS_LOGGING_SRC_PERSISTENT_LOGGING_ISYSEDR_HANDLER_H +#ifndef SCORE_PAS_LOGGING_INCLUDE_SYSEDR_ISYSEDR_HANDLER_H +#define SCORE_PAS_LOGGING_INCLUDE_SYSEDR_ISYSEDR_HANDLER_H #include "logparser/logparser.h" @@ -47,4 +47,4 @@ class ISysedrHandler : public LogParser::TypeHandler, public LogParser::AnyHandl } // namespace platform } // namespace score -#endif // SCORE_PAS_LOGGING_SRC_PERSISTENT_LOGGING_ISYSEDR_HANDLER_H +#endif // SCORE_PAS_LOGGING_INCLUDE_SYSEDR_ISYSEDR_HANDLER_H diff --git a/score/datarouter/src/persistent_logging/persistent_logging_stub/BUILD b/score/datarouter/persistent_logging/persistent_logging_stub/BUILD similarity index 86% rename from score/datarouter/src/persistent_logging/persistent_logging_stub/BUILD rename to score/datarouter/persistent_logging/persistent_logging_stub/BUILD index a66bf6e..3f9fb32 100644 --- a/score/datarouter/src/persistent_logging/persistent_logging_stub/BUILD +++ b/score/datarouter/persistent_logging/persistent_logging_stub/BUILD @@ -26,7 +26,7 @@ cc_library( visibility = ["//score/datarouter:__subpackages__"], deps = [ "//score/datarouter:log", - "//score/datarouter/src/persistent_logging:sysedr_factory", - "//score/datarouter/src/persistent_logging:sysedr_handler_interface", + "//score/datarouter/persistent_logging:sysedr_factory", + "//score/datarouter/persistent_logging:sysedr_handler_interface", ], ) diff --git a/score/datarouter/src/persistent_logging/persistent_logging_stub/stub_sysedr_factory.cpp b/score/datarouter/persistent_logging/persistent_logging_stub/stub_sysedr_factory.cpp similarity index 91% rename from score/datarouter/src/persistent_logging/persistent_logging_stub/stub_sysedr_factory.cpp rename to score/datarouter/persistent_logging/persistent_logging_stub/stub_sysedr_factory.cpp index 6803f8c..d14c004 100644 --- a/score/datarouter/src/persistent_logging/persistent_logging_stub/stub_sysedr_factory.cpp +++ b/score/datarouter/persistent_logging/persistent_logging_stub/stub_sysedr_factory.cpp @@ -11,7 +11,7 @@ * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ -#include "score/datarouter/src/persistent_logging/persistent_logging_stub/stub_sysedr_factory.h" +#include "score/datarouter/persistent_logging/persistent_logging_stub/stub_sysedr_factory.h" #include "score/mw/log/logging.h" namespace score diff --git a/score/datarouter/src/persistent_logging/persistent_logging_stub/stub_sysedr_factory.h b/score/datarouter/persistent_logging/persistent_logging_stub/stub_sysedr_factory.h similarity index 65% rename from score/datarouter/src/persistent_logging/persistent_logging_stub/stub_sysedr_factory.h rename to score/datarouter/persistent_logging/persistent_logging_stub/stub_sysedr_factory.h index fc4866f..54594c8 100644 --- a/score/datarouter/src/persistent_logging/persistent_logging_stub/stub_sysedr_factory.h +++ b/score/datarouter/persistent_logging/persistent_logging_stub/stub_sysedr_factory.h @@ -11,11 +11,11 @@ * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ -#ifndef SCORE_PAS_LOGGING_SRC_PERSISTENT_LOGGING_PERSISTENT_LOGGING_STUB_STUB_SYSEDR_FACTORY_H -#define SCORE_PAS_LOGGING_SRC_PERSISTENT_LOGGING_PERSISTENT_LOGGING_STUB_STUB_SYSEDR_FACTORY_H +#ifndef SCORE_PAS_LOGGING_INCLUDE_SYSEDR_STUB_SYSEDR_FACTORY_H +#define SCORE_PAS_LOGGING_INCLUDE_SYSEDR_STUB_SYSEDR_FACTORY_H -#include "score/datarouter/src/persistent_logging/persistent_logging_stub/stub_sysedr_handler.h" -#include "score/datarouter/src/persistent_logging/sysedr_factory.hpp" +#include "score/datarouter/persistent_logging/persistent_logging_stub/stub_sysedr_handler.h" +#include "score/datarouter/persistent_logging/sysedr_factory.hpp" namespace score { @@ -34,4 +34,4 @@ class StubSysedrFactory : public SysedrFactory } // namespace platform } // namespace score -#endif // SCORE_PAS_LOGGING_SRC_PERSISTENT_LOGGING_PERSISTENT_LOGGING_STUB_STUB_SYSEDR_FACTORY_H +#endif // SCORE_PAS_LOGGING_INCLUDE_SYSEDR_STUB_SYSEDR_FACTORY_H diff --git a/score/datarouter/src/persistent_logging/persistent_logging_stub/stub_sysedr_handler.cpp b/score/datarouter/persistent_logging/persistent_logging_stub/stub_sysedr_handler.cpp similarity index 81% rename from score/datarouter/src/persistent_logging/persistent_logging_stub/stub_sysedr_handler.cpp rename to score/datarouter/persistent_logging/persistent_logging_stub/stub_sysedr_handler.cpp index 8d48028..694540f 100644 --- a/score/datarouter/src/persistent_logging/persistent_logging_stub/stub_sysedr_handler.cpp +++ b/score/datarouter/persistent_logging/persistent_logging_stub/stub_sysedr_handler.cpp @@ -11,7 +11,7 @@ * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ -#include "score/datarouter/src/persistent_logging/persistent_logging_stub/stub_sysedr_handler.h" +#include "score/datarouter/persistent_logging/persistent_logging_stub/stub_sysedr_handler.h" namespace score { @@ -25,7 +25,7 @@ namespace internal void StubSysedrHandler::handle(timestamp_t /* timestamp */, const char* data, bufsize_t size) {} // LogParser::AnyHandler -void StubSysedrHandler::handle(const TypeInfo& type_info, timestamp_t timestamp, const char* data, bufsize_t size) {} +void StubSysedrHandler::handle(const TypeInfo& typeInfo, timestamp_t timestamp, const char* data, bufsize_t size) {} // LCOV_EXCL_STOP diff --git a/score/datarouter/src/persistent_logging/persistent_logging_stub/stub_sysedr_handler.h b/score/datarouter/persistent_logging/persistent_logging_stub/stub_sysedr_handler.h similarity index 66% rename from score/datarouter/src/persistent_logging/persistent_logging_stub/stub_sysedr_handler.h rename to score/datarouter/persistent_logging/persistent_logging_stub/stub_sysedr_handler.h index e23be0e..9c34524 100644 --- a/score/datarouter/src/persistent_logging/persistent_logging_stub/stub_sysedr_handler.h +++ b/score/datarouter/persistent_logging/persistent_logging_stub/stub_sysedr_handler.h @@ -11,10 +11,10 @@ * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ -#ifndef SCORE_PAS_LOGGING_SRC_PERSISTENT_LOGGING_PERSISTENT_LOGGING_STUB_STUB_SYSEDR_HANDLER_H -#define SCORE_PAS_LOGGING_SRC_PERSISTENT_LOGGING_PERSISTENT_LOGGING_STUB_STUB_SYSEDR_HANDLER_H +#ifndef SCORE_PAS_LOGGING_INCLUDE_SYSEDR_STUB_SYSEDR_HANDLER_H +#define SCORE_PAS_LOGGING_INCLUDE_SYSEDR_STUB_SYSEDR_HANDLER_H -#include "score/datarouter/src/persistent_logging/isysedr_handler.h" +#include "score/datarouter/persistent_logging/isysedr_handler.h" namespace score { @@ -31,11 +31,11 @@ class StubSysedrHandler final : public ISysedrHandler void handle(timestamp_t /* timestamp */, const char* data, bufsize_t size) override; // LogParser::AnyHandler - void handle(const TypeInfo& type_info, timestamp_t timestamp, const char* data, bufsize_t size) override; + void handle(const TypeInfo& typeInfo, timestamp_t timestamp, const char* data, bufsize_t size) override; }; } // namespace internal } // namespace platform } // namespace score -#endif // SCORE_PAS_LOGGING_SRC_PERSISTENT_LOGGING_PERSISTENT_LOGGING_STUB_STUB_SYSEDR_HANDLER_H +#endif // SCORE_PAS_LOGGING_INCLUDE_SYSEDR_STUB_SYSEDR_HANDLER_H diff --git a/score/datarouter/src/persistent_logging/sysedr_factory.hpp b/score/datarouter/persistent_logging/sysedr_factory.hpp similarity index 84% rename from score/datarouter/src/persistent_logging/sysedr_factory.hpp rename to score/datarouter/persistent_logging/sysedr_factory.hpp index fad6fee..186dbd1 100644 --- a/score/datarouter/src/persistent_logging/sysedr_factory.hpp +++ b/score/datarouter/persistent_logging/sysedr_factory.hpp @@ -11,10 +11,10 @@ * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ -#ifndef SCORE_PAS_LOGGING_SRC_PERSISTENT_LOGGING_SYSEDR_FACTORY_HPP -#define SCORE_PAS_LOGGING_SRC_PERSISTENT_LOGGING_SYSEDR_FACTORY_HPP +#ifndef SCORE_PAS_LOGGING_INCLUDE_SYSEDR_SYSEDR_FACTORY_H +#define SCORE_PAS_LOGGING_INCLUDE_SYSEDR_SYSEDR_FACTORY_H -#include "score/datarouter/src/persistent_logging/isysedr_handler.h" +#include "score/datarouter/persistent_logging/isysedr_handler.h" #include namespace score @@ -54,4 +54,4 @@ class SysedrFactory } // namespace platform } // namespace score -#endif // SCORE_PAS_LOGGING_SRC_PERSISTENT_LOGGING_SYSEDR_FACTORY_HPP +#endif // SCORE_PAS_LOGGING_INCLUDE_SYSEDR_SYSEDR_FACTORY_H diff --git a/score/datarouter/src/applications/main_nonadaptive.cpp b/score/datarouter/src/applications/main_nonadaptive.cpp index 7a2cbc1..044e59e 100644 --- a/score/datarouter/src/applications/main_nonadaptive.cpp +++ b/score/datarouter/src/applications/main_nonadaptive.cpp @@ -16,7 +16,6 @@ // LCOV_EXCL_START #include -#include "score/os/errno_logging.h" #include "score/os/utils/signal_impl.h" #include "score/mw/log/logging.h" @@ -46,23 +45,10 @@ int main(std::int32_t argc, const char* argv[]) } score::os::SignalImpl sig{}; - struct sigaction old_sigaction; - struct sigaction sig_handler; - sigset_t sig_set; - // NOLINTNEXTLINE(score-banned-function) This is testcode only, cf. line 3 - auto res = sig.SigEmptySet(sig_set); - if (!res.has_value()) - { - score::mw::log::LogError() << res.error(); - } - sig_handler.sa_handler = signal_handler; - sig_handler.sa_mask = sig_set; - sig_handler.sa_flags = 0; - res = sig.SigAction(SIGTERM, sig_handler, old_sigaction); - if (!res.has_value()) - { - score::mw::log::LogError() << res.error(); - } + // score::os wrappers are better suited for dependency injection, + // So suppressed here as it is safely used, and it is among safety headers. + // NOLINTNEXTLINE(score-banned-function) see comment above. + sig.signal(SIGTERM, signal_handler); score::logging::datarouter::datarouter_app_init(); score::logging::datarouter::datarouter_app_run(exit_requested); score::logging::datarouter::datarouter_app_shutdown(); diff --git a/score/datarouter/src/daemon/dlt_log_server.cpp b/score/datarouter/src/daemon/dlt_log_server.cpp index 52543ba..0d52c85 100644 --- a/score/datarouter/src/daemon/dlt_log_server.cpp +++ b/score/datarouter/src/daemon/dlt_log_server.cpp @@ -30,7 +30,7 @@ namespace logging namespace dltserver { -void DltLogServer::SendNonVerbose(const score::mw::log::config::NvMsgDescriptor& desc, +void DltLogServer::sendNonVerbose(const score::mw::log::config::NvMsgDescriptor& desc, uint32_t tmsp, const void* data, size_t size) diff --git a/score/datarouter/src/daemon/message_passing_server.cpp b/score/datarouter/src/daemon/message_passing_server.cpp index 8e0e8df..ee89059 100644 --- a/score/datarouter/src/daemon/message_passing_server.cpp +++ b/score/datarouter/src/daemon/message_passing_server.cpp @@ -14,7 +14,6 @@ #include "daemon/message_passing_server.h" #include "score/os/pthread.h" #include "score/os/unistd.h" -#include "score/mw/log/detail/data_router/message_passing_config.h" #include "score/memory.hpp" #include @@ -33,7 +32,34 @@ namespace internal { using score::mw::log::detail::DatarouterMessageIdentifier; -using score::mw::log::detail::MessagePassingConfig; +using score::mw::log::detail::ToMessageId; + +namespace +{ + +#if !defined(__QNXNTO__) + +// In Linux, MQueue size is usually limited to 10 for non-privileged processes +std::int32_t kReceiverQueueMaxSize = 10; + +#else + +std::int32_t kReceiverQueueMaxSize = 128; + +#endif + +constexpr std::uint32_t kConnectionTimeoutInMs = 1000UL; +constexpr std::int32_t kMaxNumbersOfRetry = 5; +constexpr std::chrono::milliseconds kSendRetryDelay{}; +constexpr std::chrono::milliseconds kConnectRetryDelay = std::chrono::milliseconds{5}; +/* + this functions is seen by this file only. +*/ +// LCOV_EXCL_START +void DropLogs(const score::mw::com::message_passing::LogFunction) {} +// LCOV_EXCL_STOP + +} // namespace void MessagePassingServer::SessionWrapper::enqueue_for_delete_while_locked(bool by_peer) { @@ -98,21 +124,12 @@ void MessagePassingServer::SessionWrapper::enqueue_tick_while_locked() */ // coverity[autosar_cpp14_a3_1_1_violation] MessagePassingServer::MessagePassingServer(MessagePassingServer::SessionFactory factory, - std::shared_ptr server_factory, - std::shared_ptr client_factory) + ::score::concurrency::Executor& executor) : IMessagePassingServerSessionWrapper(), factory_{std::move(factory)}, - mutex_{}, - stop_source_{}, connection_timeout_{}, - worker_cond_{}, - pid_session_map_{}, - work_queue_{}, workers_exit_{false}, - server_cond_{}, - session_finishing_{false}, - server_factory_{server_factory}, - client_factory_{client_factory} + session_finishing_{false} { worker_thread_ = score::cpp::jthread([this]() { RunWorkerThread(); @@ -124,47 +141,24 @@ MessagePassingServer::MessagePassingServer(MessagePassingServer::SessionFactory std::cerr << "setname_np: " << ret_pthread.error() << std::endl; } - const score::message_passing::ServiceProtocolConfig service_protocol_config{ - MessagePassingConfig::kDatarouterReceiverIdentifier, - MessagePassingConfig::kMaxMessageSize, - MessagePassingConfig::kMaxReplySize, - MessagePassingConfig::kMaxNotifySize}; - - const score::message_passing::IServerFactory::ServerConfig server_config{MessagePassingConfig::kMaxReceiverQueueSize, - MessagePassingConfig::kPreAllocConnections, - MessagePassingConfig::kMaxQueuedNotifies}; - receiver_ = server_factory_->Create(service_protocol_config, server_config); - - auto connect_callback = [](score::message_passing::IServerConnection& connection) noexcept -> std::uintptr_t { - const pid_t client_pid = connection.GetClientIdentity().pid; - return static_cast(client_pid); - }; - auto disconnect_callback = [this](score::message_passing::IServerConnection& connection) noexcept { - std::unique_lock lock(mutex_); - const auto found = pid_session_map_.find(connection.GetClientIdentity().pid); - if (found != pid_session_map_.end()) - { - SessionWrapper& wrapper = found->second; - wrapper.to_force_finish_ = true; - found->second.enqueue_for_delete_while_locked(true); - } - }; - auto received_send_message_callback = [this](score::message_passing::IServerConnection& connection, - const score::cpp::span message) noexcept -> score::cpp::blank { - const pid_t client_pid = connection.GetClientIdentity().pid; - this->MessageCallback(message, client_pid); - return {}; - }; - auto received_send_message_with_reply_callback = - [](score::message_passing::IServerConnection& /*connection*/, - score::cpp::span /*message*/) noexcept -> score::cpp::blank { - return {}; - }; - - auto ret_listening = receiver_->StartListening(connect_callback, - disconnect_callback, - received_send_message_callback, - received_send_message_with_reply_callback); + using namespace ::score::mw::com::message_passing; + const std::string receiver_id{"/logging.datarouter_recv"}; + const std::vector allowed_uids{}; + score::mw::com::message_passing::ReceiverConfig receiver_config{}; + receiver_config.max_number_message_in_queue = kReceiverQueueMaxSize; + receiver_ = ReceiverFactory::Create(receiver_id, executor, allowed_uids, receiver_config); + + receiver_->Register(ToMessageId(DatarouterMessageIdentifier::kConnect), + [this](const MediumMessagePayload payload, const pid_t pid) noexcept { + this->OnConnectRequest(payload, pid); + }); + receiver_->Register(ToMessageId(DatarouterMessageIdentifier::kAcquireResponse), + [this](const MediumMessagePayload payload, const pid_t pid) noexcept { + this->OnAcquireResponse(payload, pid); + }); + + // all callbacks shall be registered before listening starts + auto ret_listening = receiver_->StartListening(); if (!ret_listening) { std::cerr << "StartListening: " << ret_listening.error() << std::endl; @@ -196,8 +190,10 @@ MessagePassingServer::~MessagePassingServer() noexcept receiver_.reset(); // now, we can safely end the worker thread - workers_exit_.store(true); - + { + std::lock_guard lock(mutex_); + workers_exit_ = true; + } worker_cond_.notify_all(); if (worker_thread_.joinable()) { @@ -290,15 +286,9 @@ void MessagePassingServer::RunWorkerThread() lock.lock(); // LCOV_EXCL_STOP } - // Extract the session wrapper to destroy it outside the mutex lock - // to avoid deadlock when destructor blocks (e.g., ClientConnection::~ClientConnection) - auto node = pid_session_map_.extract(pid); + pid_session_map_.erase(pid); session_finishing_ = false; server_cond_.notify_all(); - lock.unlock(); - // Destroy the extracted node here (destructor runs without holding mutex) - node = {}; - lock.lock(); } else if (wrapper.reset_running_while_locked(requeue)) { @@ -308,12 +298,7 @@ void MessagePassingServer::RunWorkerThread() } else if (wrapper.is_marked_for_delete()) { - // Extract the session wrapper to destroy it outside the mutex lock - auto node = pid_session_map_.extract(pid); - lock.unlock(); - // Destroy the extracted node here (destructor runs without holding mutex) - node = {}; - lock.lock(); + pid_session_map_.erase(pid); } } } @@ -361,58 +346,32 @@ void MessagePassingServer::FinishPreviousSessionWhileLocked( }); } -void MessagePassingServer::MessageCallback(const score::cpp::span message, const pid_t pid) +void MessagePassingServer::OnConnectRequest(const score::mw::com::message_passing::MediumMessagePayload payload, + const pid_t pid) { - if (message.size() < 1) - { - std::cerr << "MessagePassingServer: Empty message received from " << pid; - return; - } - - const auto message_type = message.front(); - const auto payload = message.subspan(1); - switch (message_type) + std::unique_lock lock(mutex_); + const auto found = pid_session_map_.find(pid); + if (found != pid_session_map_.end()) { - case score::cpp::to_underlying(DatarouterMessageIdentifier::kConnect): - OnConnectRequest(payload, pid); - break; - case score::cpp::to_underlying(DatarouterMessageIdentifier::kAcquireResponse): - OnAcquireResponse(payload, pid); - break; - case score::cpp::to_underlying(DatarouterMessageIdentifier::kAcquireRequest): - std::cerr << "MessagePassingServer: Unsupported Acquire Message received from " << pid; - break; - default: - std::cerr << "MessagePassingServer: Unsupported MessageType received from " << pid; - break; + // old pid owner died without us noticing, finish the old session + FinishPreviousSessionWhileLocked(found, lock); } -} - -void MessagePassingServer::OnConnectRequest(const score::cpp::span message, const pid_t pid) -{ - score::mw::log::detail::ConnectMessageFromClient conn; - if (message.size() < sizeof(conn)) - { - std::cout << "ConnectMessageFromClient too small" << std::endl; - stop_source_ = score::cpp::stop_source(); - return; - } + static_assert(payload.size() >= sizeof(conn), "ConnectMessageFromClient too big"); /* Deviation from Rule M5-2-8: - Rule M5-2-8 (required, implementation, automated) An object with integer type or pointer to void type shall not be converted to an object with pointer type. Justification: - - This is safe since we convert void conn object to it's raw form to fill it from message . + - This is safe since we convert void conn object to it's raw form to fill it from payload . */ // coverity[autosar_cpp14_m5_2_8_violation] score::cpp::span conn_span{static_cast(static_cast(&conn)), sizeof(conn)}; - std::ignore = std::copy(message.begin(), message.end(), conn_span.begin()); + std::ignore = std::copy_n(payload.begin(), sizeof(conn), conn_span.begin()); auto appid_sv = conn.GetAppId().GetStringView(); std::string appid{appid_sv.data(), appid_sv.size()}; - // LCOV_EXCL_START: false positive since it is tested. std::string client_receiver_name; // LCOV_EXCL_STOP @@ -435,14 +394,21 @@ void MessagePassingServer::OnConnectRequest(const score::cpp::spanCreate(protocol_config, client_config); + connection_timeout_ = timestamp_t{}; // check for timeout or exit request if (stop_source_.stop_requested()) @@ -458,6 +424,7 @@ void MessagePassingServer::OnConnectRequest(const score::cpp::span session_handle{ ::score::cpp::pmr::make_unique(memory_resource, pid, this, std::move(sender))}; @@ -474,39 +441,39 @@ void MessagePassingServer::OnConnectRequest(const score::cpp::span lock(mutex_); auto emplace_result = pid_session_map_.emplace(pid, SessionWrapper{this, pid, std::move(session)}); // enqueue the tick to speed up processing connection emplace_result.first->second.enqueue_tick_while_locked(); } } -void MessagePassingServer::OnAcquireResponse(const score::cpp::span message, const pid_t pid) +void MessagePassingServer::OnAcquireResponse(const score::mw::com::message_passing::MediumMessagePayload payload, + const pid_t pid) { std::lock_guard lock(mutex_); const auto found = pid_session_map_.find(pid); if (found != pid_session_map_.end()) { - auto& [key, session] = *found; - std::ignore = key; score::mw::log::detail::ReadAcquireResult acq{}; + static_assert(payload.size() >= sizeof(acq), "MwsrDataReadAcquired too big"); /* Deviation from Rule M5-2-8: - Rule M5-2-8 (required, implementation, automated) An object with integer type or pointer to void type shall not be converted to an object with pointer type. Justification: - - This is safe since we convert void acq_span object to it's raw form to fill it from message . + - This is safe since we convert void acq_span object to it's raw form to fill it from payload . */ // coverity[autosar_cpp14_m5_2_8_violation] score::cpp::span acq_span{static_cast(static_cast(&acq)), sizeof(acq)}; - std::ignore = std::copy(message.begin(), message.end(), acq_span.begin()); - session.session_->on_acquire_response(acq); + std::ignore = std::copy_n(payload.begin(), sizeof(acq), acq_span.begin()); + found->second.session_->on_acquire_response(acq); // enqueue the tick to speed up processing acquire response - session.enqueue_tick_while_locked(); + found->second.enqueue_tick_while_locked(); } } @@ -526,31 +493,35 @@ void MessagePassingServer::NotifyAcquireRequestFailed(std::int32_t pid) } found->second.enqueue_for_delete_while_locked(true); } - -bool MessagePassingServer::SessionHandle::AcquireRequest() const +/* + Deviation from Rule A3-1-1: + - It shall be possible to include any header file + in multiple translation units without violating the One Definition Rule. + Justification: + - This is false positive. Function is declared only once. +*/ +// coverity[autosar_cpp14_a3_1_1_violation] +score::mw::com::message_passing::ShortMessage MessagePassingServer::PrepareAcquireRequestMessage() noexcept { - if (!sender_state_.has_value()) - { - sender_->Start(score::message_passing::IClientConnection::StateCallback{}, - score::message_passing::IClientConnection::NotifyCallback{}); - } + const auto my_pid = ::score::os::Unistd::instance().getpid(); + score::mw::com::message_passing::ShortMessage message{}; + message.id = ToMessageId(DatarouterMessageIdentifier::kAcquireRequest); + message.pid = my_pid; // the receiver will check if the pid matches the sending process + message.payload = 0; + return message; +} - sender_state_ = sender_->GetState(); - if (sender_state_ != score::message_passing::IClientConnection::State::kReady) - { - return false; - } - const std::array message{score::cpp::to_underlying(DatarouterMessageIdentifier::kAcquireRequest)}; +void MessagePassingServer::SessionHandle::AcquireRequest() const +{ + const score::mw::com::message_passing::ShortMessage message = MessagePassingServer::PrepareAcquireRequestMessage(); auto ret = sender_->Send(message); if (!ret) { if (server_ != nullptr) { server_->NotifyAcquireRequestFailed(pid_); - return true; } } - return true; } } // namespace internal diff --git a/score/datarouter/src/daemon/socketserver.cpp b/score/datarouter/src/daemon/socketserver.cpp index 2083e5d..39671d5 100644 --- a/score/datarouter/src/daemon/socketserver.cpp +++ b/score/datarouter/src/daemon/socketserver.cpp @@ -55,17 +55,13 @@ constexpr auto* LOG_CHANNELS_PATH = "./etc/log-channels.json"; constexpr std::uint32_t statistics_log_period_us{10000000U}; constexpr std::uint32_t dlt_flush_period_us{100000U}; constexpr std::uint32_t throttle_time_us{100000U}; - -} // namespace - -void SocketServer::SetThreadName() noexcept -{ - SetThreadName(score::os::Pthread::instance()); -} - -void SocketServer::SetThreadName(score::os::Pthread& pthread_instance) noexcept +/* + - this is local functions in this file so it cannot be tested +*/ +// LCOV_EXCL_START +void SetThreadName() noexcept { - auto ret = pthread_instance.setname_np(pthread_instance.self(), "socketserver"); + auto ret = score::os::Pthread::instance().setname_np(score::os::Pthread::instance().self(), "socketserver"); if (!ret.has_value()) { auto errstr = ret.error().ToString(); @@ -73,17 +69,15 @@ void SocketServer::SetThreadName(score::os::Pthread& pthread_instance) noexcept } } -std::string SocketServer::ResolveSharedMemoryFileName(const score::mw::log::detail::ConnectMessageFromClient& conn, - const std::string& appid) +std::string ResolveSharedMemoryFileName(const score::mw::log::detail::ConnectMessageFromClient& conn, + const std::string& appid) { std::string return_file_name_string; // constuct the file from the 6 random chars if (true == conn.GetUseDynamicIdentifier()) { - // The LCOV considered the below line as uncovered which impossible according to the code flow, For the quality - // team argumentation, it may related to Ticket-213937 - std::string random_part{}; // LCOV_EXCL_LINE + std::string random_part; for (const auto& s : conn.GetRandomPart()) { random_part += s; @@ -97,6 +91,9 @@ std::string SocketServer::ResolveSharedMemoryFileName(const score::mw::log::deta return_file_name_string += ".shmem"; return return_file_name_string; } +// LCOV_EXCL_STOP + +} // namespace SocketServer::PersistentStorageHandlers SocketServer::InitializePersistentStorage( std::unique_ptr& persistent_dictionary) @@ -106,9 +103,11 @@ SocketServer::PersistentStorageHandlers SocketServer::InitializePersistentStorag handlers.load_dlt = [&persistent_dictionary]() { return readDlt(*persistent_dictionary); }; + handlers.store_dlt = [&persistent_dictionary](const score::logging::dltserver::PersistentConfig& config) { writeDlt(config, *persistent_dictionary); }; + handlers.is_dlt_enabled = readDltEnabled(*persistent_dictionary); /* @@ -390,10 +389,12 @@ void SocketServer::doWork(const std::atomic_bool& exit_requested, const bool no_ std::placeholders::_2, // conn std::placeholders::_3); // handle - std::shared_ptr server_factory = std::make_shared(); - std::shared_ptr client_factory = - std::make_shared(/*server_factory_->GetEngine() Ticket-234313*/); - + // Create message passing server with thread pool + // As documented in aas/mw/com/message_passing/design/README.md, the Receiver implementation will use just 1 thread + // from the thread pool for MQueue (Linux). For Resource Manager (QNX), it is supposed to use 2 threads. If it + // cannot allocate the second thread, it will work with just one thread, with reduced functionality (still enough + // for our use case, where every client's Sender runs on a dedicated thread) and likely with higher latency. + score::concurrency::ThreadPool executor{2}; /* Deviation from Rule A5-1-4: - A lambda expression object shall not outlive any of its reference captured objects. @@ -401,7 +402,7 @@ void SocketServer::doWork(const std::atomic_bool& exit_requested, const bool no_ - mp_server does not exist inside any lambda. */ // coverity[autosar_cpp14_a5_1_4_violation: FALSE] - MessagePassingServer mp_server(mp_factory, std::move(server_factory), std::move(client_factory)); + MessagePassingServer mp_server(mp_factory, executor); // Run main event loop RunEventLoop(exit_requested, router, *dlt_server, stats_logger); diff --git a/score/datarouter/src/daemon/socketserver_config.cpp b/score/datarouter/src/daemon/socketserver_config.cpp index cdb26c1..1ce6e50 100644 --- a/score/datarouter/src/daemon/socketserver_config.cpp +++ b/score/datarouter/src/daemon/socketserver_config.cpp @@ -196,7 +196,7 @@ score::logging::dltserver::PersistentConfig readDlt(IPersistentDictionary& pd) using rapidjson::ParseResult; score::logging::dltserver::PersistentConfig config{}; - const std::string json = pd.GetString(CONFIG_DATABASE_KEY, "{}"); + const std::string json = pd.getString(CONFIG_DATABASE_KEY, "{}"); Document d = createRJDocument(); ParseResult ok = d.Parse(json.c_str()); @@ -332,12 +332,12 @@ void writeDlt(const score::logging::dltserver::PersistentConfig& config, IPersis d.Accept(writer); const std::string json = buffer.GetString(); - pd.SetString(CONFIG_DATABASE_KEY, json); + pd.setString(CONFIG_DATABASE_KEY, json); } bool readDltEnabled(IPersistentDictionary& pd) { - const bool enabled = pd.GetBool(CONFIG_OUTPUT_ENABLED_KEY, true); + const bool enabled = pd.getBool(CONFIG_OUTPUT_ENABLED_KEY, true); if constexpr (kPersistentConfigFeatureEnabled) { std::cout << "Loaded output enable = " << enabled << " from KVS" << std::endl; @@ -347,7 +347,7 @@ bool readDltEnabled(IPersistentDictionary& pd) void writeDltEnabled(bool enabled, IPersistentDictionary& pd) { - pd.SetBool(CONFIG_OUTPUT_ENABLED_KEY, enabled); + pd.setBool(CONFIG_OUTPUT_ENABLED_KEY, enabled); } } // namespace datarouter diff --git a/score/datarouter/src/persistency/BUILD b/score/datarouter/src/persistency/BUILD index 17ad2f0..9df2222 100644 --- a/score/datarouter/src/persistency/BUILD +++ b/score/datarouter/src/persistency/BUILD @@ -13,18 +13,6 @@ load("@rules_cc//cc:defs.bzl", "cc_library") load("@score_baselibs//score/language/safecpp:toolchain_features.bzl", "COMPILER_WARNING_FEATURES") -load("@score_baselibs//score/quality/clang_tidy:extra_checks.bzl", "clang_tidy_extra_checks") - -clang_tidy_extra_checks( - name = "clang_tidy_extra_checks", - extra_features = [ - "spp_code_style_check_header_guards", - "spp_code_style_check_method_names", - "spp_code_style_check_readability", - "spp_code_style_check_type_names", - "spp_code_style_check_variable_names", - ], -) cc_library( name = "interface", diff --git a/score/datarouter/src/persistency/i_persistent_dictionary.h b/score/datarouter/src/persistency/i_persistent_dictionary.h index 2a83876..a3d7ac1 100644 --- a/score/datarouter/src/persistency/i_persistent_dictionary.h +++ b/score/datarouter/src/persistency/i_persistent_dictionary.h @@ -32,11 +32,11 @@ class IPersistentDictionary public: // Public interface shall be thread-safe. - virtual std::string GetString(const std::string& key, const std::string& default_value) = 0; - virtual bool GetBool(const std::string& key, const bool default_value) = 0; + virtual std::string getString(const std::string& key, const std::string& defaultValue) = 0; + virtual bool getBool(const std::string& key, const bool defaultValue) = 0; - virtual void SetString(const std::string& key, const std::string& value) = 0; - virtual void SetBool(const std::string& key, const bool value) = 0; + virtual void setString(const std::string& key, const std::string& value) = 0; + virtual void setBool(const std::string& key, const bool value) = 0; virtual ~IPersistentDictionary() = default; }; diff --git a/score/datarouter/src/persistency/mock_persistent_dictionary.h b/score/datarouter/src/persistency/mock_persistent_dictionary.h index 38f1313..5616457 100644 --- a/score/datarouter/src/persistency/mock_persistent_dictionary.h +++ b/score/datarouter/src/persistency/mock_persistent_dictionary.h @@ -29,11 +29,11 @@ namespace datarouter class MockPersistentDictionary : public ::score::platform::datarouter::IPersistentDictionary { public: - MOCK_METHOD(std::string, GetString, (const std::string& key, const std::string& defaultValue), (override final)); - MOCK_METHOD(bool, GetBool, (const std::string& key, const bool defaultValue), (override final)); + MOCK_METHOD(std::string, getString, (const std::string& key, const std::string& defaultValue), (override final)); + MOCK_METHOD(bool, getBool, (const std::string& key, const bool defaultValue), (override final)); - MOCK_METHOD(void, SetString, (const std::string& key, const std::string& value), (override final)); - MOCK_METHOD(void, SetBool, (const std::string& key, const bool value), (override final)); + MOCK_METHOD(void, setString, (const std::string& key, const std::string& value), (override final)); + MOCK_METHOD(void, setBool, (const std::string& key, const bool value), (override final)); protected: ~MockPersistentDictionary() = default; diff --git a/score/datarouter/src/persistency/persistent_dictionary_factory.hpp b/score/datarouter/src/persistency/persistent_dictionary_factory.hpp index 4b31576..d097a5c 100644 --- a/score/datarouter/src/persistency/persistent_dictionary_factory.hpp +++ b/score/datarouter/src/persistency/persistent_dictionary_factory.hpp @@ -11,8 +11,8 @@ * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ -#ifndef SCORE_PAS_LOGGING_SRC_PERSISTENCY_PERSISTENT_DICTIONARY_FACTORY_HPP -#define SCORE_PAS_LOGGING_SRC_PERSISTENCY_PERSISTENT_DICTIONARY_FACTORY_HPP +#ifndef SCORE_PAS_LOGGING_SRC_PERSISTENT_DICTIONARY_FACTORY_HPP +#define SCORE_PAS_LOGGING_SRC_PERSISTENT_DICTIONARY_FACTORY_HPP #include "i_persistent_dictionary.h" #include @@ -60,4 +60,4 @@ class PersistentDictionaryFactory } // namespace platform } // namespace score -#endif // SCORE_PAS_LOGGING_SRC_PERSISTENCY_PERSISTENT_DICTIONARY_FACTORY_HPP +#endif // SCORE_PAS_LOGGING_SRC_PERSISTENT_DICTIONARY_FACTORY_HPP diff --git a/score/datarouter/src/persistency/stub_persistent_dictionary/stub_persistent_dictionary.cpp b/score/datarouter/src/persistency/stub_persistent_dictionary/stub_persistent_dictionary.cpp index 42cdc25..ebae94b 100644 --- a/score/datarouter/src/persistency/stub_persistent_dictionary/stub_persistent_dictionary.cpp +++ b/score/datarouter/src/persistency/stub_persistent_dictionary/stub_persistent_dictionary.cpp @@ -20,21 +20,21 @@ namespace platform namespace datarouter { -std::string StubPersistentDictionary::GetString(const std::string& /*key*/, const std::string& default_value) +std::string StubPersistentDictionary::getString(const std::string& /*key*/, const std::string& defaultValue) { - return default_value; + return defaultValue; } -bool StubPersistentDictionary::GetBool(const std::string& /*key*/, const bool default_value) +bool StubPersistentDictionary::getBool(const std::string& /*key*/, const bool defaultValue) { - return default_value; + return defaultValue; } // LCOV_EXCL_START : will suppress this function since there nothing to assert through UT as its void empty function -void StubPersistentDictionary::SetString(const std::string& /*key*/, const std::string& /*value*/) {} +void StubPersistentDictionary::setString(const std::string& /*key*/, const std::string& /*value*/) {} // LCOV_EXCL_STOP // LCOV_EXCL_START : will suppress this function since there nothing to assert through UT as its void empty function -void StubPersistentDictionary::SetBool(const std::string& /*key*/, const bool /*value*/) {} +void StubPersistentDictionary::setBool(const std::string& /*key*/, const bool /*value*/) {} // LCOV_EXCL_STOP } // namespace datarouter diff --git a/score/datarouter/src/persistency/stub_persistent_dictionary/stub_persistent_dictionary.h b/score/datarouter/src/persistency/stub_persistent_dictionary/stub_persistent_dictionary.h index 2e2ceb6..be38514 100644 --- a/score/datarouter/src/persistency/stub_persistent_dictionary/stub_persistent_dictionary.h +++ b/score/datarouter/src/persistency/stub_persistent_dictionary/stub_persistent_dictionary.h @@ -26,11 +26,11 @@ namespace datarouter class StubPersistentDictionary final : public IPersistentDictionary { public: - std::string GetString(const std::string& key, const std::string& default_value) override; - bool GetBool(const std::string& key, const bool default_value) override; + std::string getString(const std::string& key, const std::string& defaultValue) override; + bool getBool(const std::string& key, const bool defaultValue) override; - void SetString(const std::string& key, const std::string& value) override; - void SetBool(const std::string& key, const bool value) override; + void setString(const std::string& key, const std::string& value) override; + void setBool(const std::string& key, const bool value) override; }; } // namespace datarouter diff --git a/score/datarouter/src/unix_domain/unix_domain_server.cpp b/score/datarouter/src/unix_domain/unix_domain_server.cpp index a3c3d77..49bf6cc 100644 --- a/score/datarouter/src/unix_domain/unix_domain_server.cpp +++ b/score/datarouter/src/unix_domain/unix_domain_server.cpp @@ -18,7 +18,6 @@ #include "score/os/sys_poll.h" #include "score/os/unistd.h" #include "score/os/utils/signal_impl.h" -#include "score/quality/compiler_warnings/warnings.h" #include #include @@ -231,11 +230,22 @@ void UnixDomainServer::process_server_iteration(ConnectionState& state, // NOLINTBEGIN(score-banned-function) see comment above score::cpp::expected poll_ret; #ifdef __QNX__ - DISABLE_WARNING_PUSH - DISABLE_WARNING_USELESS_CAST +// NOLINTBEGIN(score-banned-preprocessor-directives) : required due to compiler warning for qnx +/* +Deviation from Rule A16-7-1: +- The #pragma directive shall not be used +Justification: +- required due to compiler warning for qnx +*/ +// coverity[autosar_cpp14_a16_7_1_violation] see above +#pragma GCC diagnostic push +// coverity[autosar_cpp14_a16_7_1_violation] see above +#pragma GCC diagnostic ignored "-Wuseless-cast" poll_ret = score::os::SysPoll::instance().poll(state.connection_pollfd_list.data(), static_cast(size), timeout); - DISABLE_WARNING_POP +// coverity[autosar_cpp14_a16_7_1_violation] see above +#pragma GCC diagnostic pop +// NOLINTEND(score-banned-preprocessor-directives) #else poll_ret = score::os::SysPoll::instance().poll(state.connection_pollfd_list.data(), size, timeout); #endif diff --git a/score/datarouter/test/ut/ut_logging/BUILD b/score/datarouter/test/ut/ut_logging/BUILD index 0f92458..3979213 100644 --- a/score/datarouter/test/ut/ut_logging/BUILD +++ b/score/datarouter/test/ut/ut_logging/BUILD @@ -133,7 +133,7 @@ cc_test( "filetransferTest.cpp", ], defines = select({ - "//score/datarouter/build_configuration_flags:config_file_transfer": ["DLT_FILE_TRANSFER_FEATURE"], + "//score/datarouter/build_configuration_flags:config_dlt_file_transfer": ["DLT_FILE_TRANSFER_FEATURE"], "//conditions:default": [], }), features = FEAT_COMPILER_WARNINGS_AS_ERRORS, @@ -152,14 +152,14 @@ cc_test( tags = ["unit"], deps = [ "//score/datarouter:datarouter_feature_config", - "//score/datarouter/src/file_transfer:file_transfer_handler_factory", + "//score/datarouter/file_transfer:file_transfer_handler_factory", "@googletest//:gtest_main", ] + select({ - "//score/datarouter/build_configuration_flags:config_file_transfer": [ - "//score/datarouter/src/file_transfer/file_transfer_impl:file_transfer_stream_handler_factory", + "//score/datarouter/build_configuration_flags:config_dlt_file_transfer": [ + "//score/datarouter/file_transfer/file_transfer_impl:file_transfer_stream_handler_factory", ], "//conditions:default": [ - "//score/datarouter/src/file_transfer/file_transfer_stub:file_transfer_handler_factory_stub", + "//score/datarouter/file_transfer/file_transfer_stub:file_transfer_handler_factory_stub", ], }), ) @@ -216,7 +216,7 @@ cc_test( ], "//conditions:default": [], }) + select({ - "//score/datarouter/build_configuration_flags:config_file_transfer": ["test_filetransfer_stream.cpp"], + "//score/datarouter/build_configuration_flags:config_dlt_file_transfer": ["test_filetransfer_stream.cpp"], "//conditions:default": [], }), features = FEAT_COMPILER_WARNINGS_AS_ERRORS, @@ -313,7 +313,6 @@ cc_test( "//score/datarouter/src/persistency:mock", "@googletest//:gtest_main", "@score_baselibs//score/mw/log/configuration:nvconfig_mock", - "@score_baselibs//score/os/mocklib:pthread_mock", "@score_baselibs//score/os/mocklib:unistd_mock", ], ) @@ -331,7 +330,7 @@ cc_test( "@googletest//:gtest_main", "@score_baselibs//score/os/mocklib:pthread_mock", "@score_baselibs//score/os/mocklib:unistd_mock", - "@score_communication//score/message_passing:mock", + "@score_communication//score/mw/com/message_passing:mock", ], ) diff --git a/score/datarouter/test/ut/ut_logging/test_dltserver.cpp b/score/datarouter/test/ut/ut_logging/test_dltserver.cpp index c81c89d..9f3303a 100644 --- a/score/datarouter/test/ut/ut_logging/test_dltserver.cpp +++ b/score/datarouter/test/ut/ut_logging/test_dltserver.cpp @@ -28,6 +28,24 @@ namespace platform inline namespace { +bool operator<(const dltid_t c1, const dltid_t c2) +{ + return c1.value < c2.value; +} + +bool operator==(const std::vector& c1, const std::vector& c2) +{ + if (c1.size() != c2.size()) + { + return false; + } + std::vector c1s{c1}; + std::sort(c1s.begin(), c1s.end()); + std::vector c2s{c2}; + std::sort(c2s.begin(), c2s.end()); + return std::equal(c1s.begin(), c1s.end(), c2s.begin()); +} + } // namespace } // namespace platform @@ -42,6 +60,7 @@ namespace dltserver inline namespace { +constexpr auto kSizeChannelName{4UL}; // Declared those constants for readability purposes constexpr auto kCommandSize{1UL}; constexpr auto kCommandResponseSize{1UL}; @@ -76,6 +95,51 @@ constexpr auto kCommandResponseSize{1UL}; } \ } while (0) +#define EXPECT_NAMES_OR_NOOP(resp, n1, n2) \ + do \ + { \ + if (!(resp).empty()) \ + { \ + EXPECT_GE((resp).size(), kCommandResponseSize); \ + EXPECT_THAT((resp).substr(1, (resp).size()), ::testing::HasSubstr(n1)); \ + EXPECT_THAT((resp).substr(1, (resp).size()), ::testing::HasSubstr(n2)); \ + } \ + else \ + { \ + SUCCEED(); \ + } \ + } while (0) + +bool operator==(const PersistentConfig::ChannelDescription& c1, const PersistentConfig::ChannelDescription& c2) +{ + return c1.channelThreshold == c2.channelThreshold; +} + +bool operator==(const PersistentConfig& c1, const PersistentConfig& c2) +{ + if (c1.channels != c2.channels) + { + return false; + } + if (c1.filteringEnabled != c2.filteringEnabled) + { + return false; + } + if (c1.defaultThreshold != c2.defaultThreshold) + { + return false; + } + if (c1.channelAssignments != c2.channelAssignments) + { + return false; + } + if (c1.messageThresholds != c2.messageThresholds) + { + return false; + } + return true; +} + } // namespace } // namespace dltserver @@ -108,7 +172,7 @@ class DltLogServer::DltLogServerTest : public DltLogServer public: using DltLogServer::sendFTVerbose; - using DltLogServer::SendNonVerbose; + using DltLogServer::sendNonVerbose; using DltLogServer::sendVerbose; }; @@ -206,6 +270,18 @@ class DltServerCreatedWithConfigFixture : public ::testing::Test false}; PersistentConfig pConfig{}; + PersistentConfig pConfigCompare{ + { + {"DFLT", {score::mw::log::LogLevel::kFatal}}, + {"CORE", {score::mw::log::LogLevel::kError}}, + }, + true, + score::mw::log::LogLevel::kOff, + { + {dltid_t("APP0"), {{dltid_t("CTX0"), bothChannels}}}, + }, + {{dltid_t("APP0"), {{dltid_t("CTX0"), score::mw::log::LogLevel::kOff}}}}, + }; testing::StrictMock> readCallback_; testing::StrictMock> writeCallback_; @@ -213,6 +289,22 @@ class DltServerCreatedWithConfigFixture : public ::testing::Test LogSenderMock* log_sender_mock_raw_ptr_{nullptr}; }; +TEST_F(DltServerCreatedWithConfigFixture, WhenCreatedWithConfig) +{ + EXPECT_CALL(readCallback_, Call()).Times(1).WillOnce(Return(pConfig)); + EXPECT_CALL(writeCallback_, Call(pConfigCompare)).Times(::testing::AtMost(1)); + + DltLogServer dltServer(sConfig, readCallback_.AsStdFunction(), writeCallback_.AsStdFunction(), true); + + std::string response{}; + auto session = dltServer.new_config_session( + score::platform::datarouter::ConfigSessionHandleType{0, nullptr, std::reference_wrapper{response}}); + + session->on_command(std::string(kCommandSize, config::STORE_DLT_CONFIG)); + + EXPECT_OK_OR_NOOP(response); +} + TEST_F(DltServerCreatedWithConfigFixture, FlushChannelsExpectNoThrowException) { EXPECT_CALL(readCallback_, Call()).Times(1).WillOnce(Return(pConfig)); @@ -242,6 +334,82 @@ TEST_F(DltServerCreatedWithConfigFixture, GetQuotaCorrectWrongAppNameExpectDefau EXPECT_EQ(ret_val, 1.0); } +TEST_F(DltServerCreatedWithConfigFixture, ReadLogChannelsWithShortNameCommandExpectChannelsList) +{ + using namespace std::string_literals; + + EXPECT_CALL(readCallback_, Call()).Times(1).WillOnce(Return(pConfig)); + EXPECT_CALL(writeCallback_, Call(_)).Times(0); + + auto config_short_channel_name = sConfig; + config_short_channel_name.channels = { + // channels as std::unordered_map + {dltid_t("DFLT"), {dltid_t("ECU0"), "", 3490U, "", 3491U, score::mw::log::LogLevel::kFatal, "160.48.199.34"}}, + {dltid_t("SR"), {dltid_t("ECU0"), "", 3489U, "", 3493U, score::mw::log::LogLevel::kError, "160.48.199.101"}}, + {dltid_t("CORE"), {dltid_t("ECU0"), "", 3490U, "", 3492U, score::mw::log::LogLevel::kError, "160.48.199.101"}}, + }; + // Extend SetUp expectation of the channel construction: + EXPECT_CALL(outputs_, construct(_, _, 3493U, Eq(std::string("160.48.199.101")))).Times(1); + EXPECT_CALL(outputs_, bind(_, _, 3489U)).Times(1); + + DltLogServer dltServer( + config_short_channel_name, readCallback_.AsStdFunction(), writeCallback_.AsStdFunction(), true); + + std::string response{}; + auto session = dltServer.new_config_session( + score::platform::datarouter::ConfigSessionHandleType{0, nullptr, std::reference_wrapper{response}}); + + session->on_command(std::string(kCommandSize, config::READ_LOG_CHANNEL_NAMES)); + + const std::string kResponse = {"CORESR\0\0DFLT"s}; + // Verify content only when dynamic configuration is enabled + if (!response.empty()) + { + EXPECT_EQ(response.size(), kCommandResponseSize + 3 * kSizeChannelName); + EXPECT_THAT(response.substr(1, response.size()), ::testing::HasSubstr("DFLT")); + EXPECT_THAT(response.substr(1, response.size()), ::testing::HasSubstr("SR\0\0"s)); + EXPECT_THAT(response.substr(1, response.size()), ::testing::HasSubstr("CORE")); + } + else + { + SUCCEED(); + } +} + +TEST_F(DltServerCreatedWithConfigFixture, ReadLogChannelsCommandExpectChannelsList) +{ + EXPECT_CALL(readCallback_, Call()).Times(1).WillOnce(Return(pConfig)); + EXPECT_CALL(writeCallback_, Call(_)).Times(0); + + DltLogServer dltServer(sConfig, readCallback_.AsStdFunction(), writeCallback_.AsStdFunction(), true); + + std::string response{}; + std::reference_wrapper reference_to_response{response}; + auto session = dltServer.new_config_session( + score::platform::datarouter::ConfigSessionHandleType{0, nullptr, reference_to_response}); + + session->on_command(std::string(kCommandSize, config::READ_LOG_CHANNEL_NAMES)); + + const std::string kResponse{"COREDFLT"}; + EXPECT_NAMES_OR_NOOP(response, "DFLT", "CORE"); +} + +TEST_F(DltServerCreatedWithConfigFixture, ResetToDefaultCommandExpectTwoReadCallbacks) +{ + EXPECT_CALL(readCallback_, Call()).Times(::testing::AtMost(2)).WillOnce(Return(pConfig)); + EXPECT_CALL(writeCallback_, Call(_)).Times(::testing::AtMost(1)); + + DltLogServer dltServer(sConfig, readCallback_.AsStdFunction(), writeCallback_.AsStdFunction(), true); + + std::string response{}; + auto session = dltServer.new_config_session( + score::platform::datarouter::ConfigSessionHandleType{0, nullptr, std::reference_wrapper{response}}); + + session->on_command(std::string(kCommandSize, config::RESET_TO_DEFAULT)); + + EXPECT_OK_OR_NOOP(response); +} + TEST(ResetToDefaultTest, ResetToDefaultCommandEmptyChannelsNoReadCallback) { testing::StrictMock outputs; @@ -387,6 +555,41 @@ TEST_F(DltServerCreatedWithConfigFixture, SetDefaultTraceStateCommandExpectReadC EXPECT_OK_OR_NOOP(response); } +TEST_F(DltServerCreatedWithConfigFixture, SetLogChannelAssignmentWrongCommandExpectReadCallback) +{ + EXPECT_CALL(readCallback_, Call()).Times(1).WillOnce(Return(pConfig)); + EXPECT_CALL(writeCallback_, Call(_)).Times(0); + + DltLogServer dltServer(sConfig, readCallback_.AsStdFunction(), writeCallback_.AsStdFunction(), true); + + std::string response{}; + auto session = dltServer.new_config_session( + score::platform::datarouter::ConfigSessionHandleType{0, nullptr, std::reference_wrapper{response}}); + + session->on_command(std::string(kCommandSize, config::SET_LOG_CHANNEL_ASSIGNMENT)); + + EXPECT_ERR_OR_NOOP(response); +} + +TEST_F(DltServerCreatedWithConfigFixture, SetLogChannelAssignmentCommandNoChannelsExpectReadCallback) +{ + EXPECT_CALL(readCallback_, Call()).Times(1).WillOnce(Return(pConfig)); + EXPECT_CALL(writeCallback_, Call(_)).Times(0); + + DltLogServer dltServer(sConfig, readCallback_.AsStdFunction(), writeCallback_.AsStdFunction(), true); + + std::string response{}; + auto session = dltServer.new_config_session( + score::platform::datarouter::ConfigSessionHandleType{0, nullptr, std::reference_wrapper{response}}); + + std::array command_buffer{ + config::SET_LOG_CHANNEL_ASSIGNMENT, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}; + const std::string command{command_buffer.begin(), command_buffer.end()}; + session->on_command(command); + + EXPECT_ERR_OR_NOOP(response); +} + TEST_F(DltServerCreatedWithConfigFixture, SetLogChannelAssignmentCommandFoundChannelAssignmentFoundExpectReadCallback) { EXPECT_CALL(readCallback_, Call()).Times(1).WillOnce(Return(pConfig)); @@ -508,38 +711,86 @@ TEST_F(DltServerCreatedWithConfigFixture, SetLogChannelAssignmentWrongChannel) EXPECT_EQ(response[0], config::RET_ERROR); } -TEST_F(DltServerCreatedWithConfigFixture, SetLogChannelAssignmentBehaviorRemovesChannel) +TEST_F(DltServerCreatedWithConfigFixture, SetDltOutputEnableWrongCommandExpectReadCallback) { EXPECT_CALL(readCallback_, Call()).Times(1).WillOnce(Return(pConfig)); EXPECT_CALL(writeCallback_, Call(_)).Times(0); - // Setup: add CORE so APP0/CTX0 is routed to DFLT + CORE. - score::logging::dltserver::DltLogServer::DltLogServerTest dltServer( - sConfig, readCallback_.AsStdFunction(), writeCallback_.AsStdFunction(), true, std::move(log_sender_mock_)); + DltLogServer dltServer(sConfig, readCallback_.AsStdFunction(), writeCallback_.AsStdFunction(), true); - const score::mw::log::detail::LoggingIdentifier app_id{"APP0"}; - const score::mw::log::detail::LoggingIdentifier ctx_id{"CTX0"}; - const score::mw::log::detail::log_entry_deserialization::LogEntryDeserializationReflection entry{ - app_id, ctx_id, {}, 0, score::mw::log::LogLevel::kOff}; + std::string response{}; + auto session = dltServer.new_config_session( + score::platform::datarouter::ConfigSessionHandleType{0, nullptr, std::reference_wrapper{response}}); - const auto resp_add = - dltServer.SetLogChannelAssignment(dltid_t{"APP0"}, dltid_t{"CTX0"}, dltid_t{"CORE"}, AssignmentAction::Add); - ASSERT_FALSE(resp_add.empty()); - EXPECT_EQ(resp_add[0], static_cast(config::RET_OK)); + session->on_command(std::string(kCommandSize, config::SET_DLT_OUTPUT_ENABLE)); - // With both channels assigned: 2 sends. - EXPECT_CALL(*log_sender_mock_raw_ptr_, SendVerbose(_, _, _)).Times(2); - dltServer.sendVerbose(100U, entry); - ::testing::Mock::VerifyAndClearExpectations(log_sender_mock_raw_ptr_); + EXPECT_ERR_OR_NOOP(response); +} - const auto resp_remove = - dltServer.SetLogChannelAssignment(dltid_t{"APP0"}, dltid_t{"CTX0"}, dltid_t{"CORE"}, AssignmentAction::Remove); - ASSERT_FALSE(resp_remove.empty()); - EXPECT_EQ(resp_remove[0], static_cast(config::RET_OK)); +TEST_F(DltServerCreatedWithConfigFixture, SetDltOutputEnableCommandEnableExpectReadCallback) +{ + EXPECT_CALL(readCallback_, Call()).Times(1).WillOnce(Return(pConfig)); + EXPECT_CALL(writeCallback_, Call(_)).Times(0); - // After removing CORE: back to DFLT-only -> 1 send. - EXPECT_CALL(*log_sender_mock_raw_ptr_, SendVerbose(_, _, _)).Times(1); - dltServer.sendVerbose(100U, entry); + DltLogServer dltServer(sConfig, readCallback_.AsStdFunction(), writeCallback_.AsStdFunction(), true); + + std::string response{}; + auto session = dltServer.new_config_session( + score::platform::datarouter::ConfigSessionHandleType{0, nullptr, std::reference_wrapper{response}}); + + std::array command_buffer{config::SET_DLT_OUTPUT_ENABLE, 1}; + const std::string command{command_buffer.begin(), command_buffer.end()}; + session->on_command(command); + + const auto dlt_enabled = dltServer.GetDltEnabled(); + if (!response.empty()) + { + EXPECT_TRUE(dlt_enabled); + } + + EXPECT_OK_OR_NOOP(response); +} + +TEST_F(DltServerCreatedWithConfigFixture, SetDltOutputEnableCommandDisableExpectReadCallback) +{ + EXPECT_CALL(readCallback_, Call()).Times(1).WillOnce(Return(pConfig)); + EXPECT_CALL(writeCallback_, Call(_)).Times(0); + + DltLogServer dltServer(sConfig, readCallback_.AsStdFunction(), writeCallback_.AsStdFunction(), true); + + std::string response{}; + auto session = dltServer.new_config_session( + score::platform::datarouter::ConfigSessionHandleType{0, nullptr, std::reference_wrapper{response}}); + + std::array command_buffer{config::SET_DLT_OUTPUT_ENABLE, 0}; + const std::string command{command_buffer.begin(), command_buffer.end()}; + session->on_command(command); + + const auto dlt_enabled = dltServer.GetDltEnabled(); + if (!response.empty()) + { + EXPECT_FALSE(dlt_enabled); + } + + EXPECT_OK_OR_NOOP(response); +} + +TEST_F(DltServerCreatedWithConfigFixture, SetDltOutputEnableCommandWrongValueExpectReadCallback) +{ + EXPECT_CALL(readCallback_, Call()).Times(1).WillOnce(Return(pConfig)); + EXPECT_CALL(writeCallback_, Call(_)).Times(0); + + DltLogServer dltServer(sConfig, readCallback_.AsStdFunction(), writeCallback_.AsStdFunction(), true); + + std::string response{}; + auto session = dltServer.new_config_session( + score::platform::datarouter::ConfigSessionHandleType{0, nullptr, std::reference_wrapper{response}}); + + std::array command_buffer{config::SET_DLT_OUTPUT_ENABLE, 2}; + const std::string command{command_buffer.begin(), command_buffer.end()}; + session->on_command(command); + + EXPECT_ERR_OR_NOOP(response); } TEST_F(DltServerCreatedWithConfigFixture, SetDltOutputEnableCommandCallbackEnabledExpectCallbackCall) @@ -762,7 +1013,7 @@ TEST_F(DltServerCreatedWithConfigFixture, SendNonVerboseFilteringDisabledExpectS sConfig, readCallback_.AsStdFunction(), writeCallback_.AsStdFunction(), true, std::move(log_sender_mock_)); EXPECT_CALL(*log_sender_mock_raw_ptr_, SendNonVerbose(_, _, _, _, _)).Times(1); - dltServer.SendNonVerbose({}, 100U, nullptr, 0); + dltServer.sendNonVerbose({}, 100U, nullptr, 0); } TEST_F(DltServerCreatedWithConfigFixture, @@ -775,7 +1026,7 @@ TEST_F(DltServerCreatedWithConfigFixture, sConfig, readCallback_.AsStdFunction(), writeCallback_.AsStdFunction(), true, std::move(log_sender_mock_)); EXPECT_CALL(*log_sender_mock_raw_ptr_, SendNonVerbose(_, _, _, _, _)).Times(1); - dltServer.SendNonVerbose({}, 100U, nullptr, 0); + dltServer.sendNonVerbose({}, 100U, nullptr, 0); } TEST_F(DltServerCreatedWithConfigFixture, SendNonVerboseAppIdAcceptedByFilteringExpectSendCallTwice) @@ -790,7 +1041,7 @@ TEST_F(DltServerCreatedWithConfigFixture, SendNonVerboseAppIdAcceptedByFiltering const score::mw::log::config::NvMsgDescriptor desc{100U, app_id, ctx_id, score::mw::log::LogLevel::kOff}; EXPECT_CALL(*log_sender_mock_raw_ptr_, SendNonVerbose(_, _, _, _, _)).Times(2); - dltServer.SendNonVerbose(desc, 100U, nullptr, 0); + dltServer.sendNonVerbose(desc, 100U, nullptr, 0); } // sendVerbose test. @@ -1037,99 +1288,4 @@ TEST_F(DltServerCreatedWithConfigFixture, SetDltOutputEnableDirectCall) EXPECT_FALSE(dltServer.GetDltEnabled()); } -TEST_F(DltServerCreatedWithConfigFixture, SetDltOutputEnableBehaviorBlocksAllSends) -{ - // Prove that enabling/disabling output affects the observable server state. - // Note: sendVerbose()/sendNonVerbose() are not gated by this flag in the current implementation; - // the flag controls the DLT output enable state exposed via GetDltEnabled(). - EXPECT_CALL(readCallback_, Call()).Times(1).WillOnce(Return(pConfig)); - EXPECT_CALL(writeCallback_, Call(_)).Times(0); - - score::logging::dltserver::DltLogServer::DltLogServerTest dltServer( - sConfig, readCallback_.AsStdFunction(), writeCallback_.AsStdFunction(), true, std::move(log_sender_mock_)); - - const score::mw::log::detail::LoggingIdentifier app_id{"APP0"}; - const score::mw::log::detail::LoggingIdentifier ctx_id{"CTX0"}; - const score::mw::log::detail::log_entry_deserialization::LogEntryDeserializationReflection entry{ - app_id, ctx_id, {}, 0, score::mw::log::LogLevel::kOff}; - - // Disable output: this should gate sending completely. - const auto disable_resp = dltServer.SetDltOutputEnable(false); - EXPECT_EQ(disable_resp.size(), kCommandResponseSize); - EXPECT_EQ(disable_resp[0], static_cast(config::RET_OK)); - EXPECT_FALSE(dltServer.GetDltEnabled()); - - // Re-enable output: sending should resume. - const auto enable_resp = dltServer.SetDltOutputEnable(true); - EXPECT_EQ(enable_resp.size(), kCommandResponseSize); - EXPECT_EQ(enable_resp[0], static_cast(config::RET_OK)); - EXPECT_TRUE(dltServer.GetDltEnabled()); - - // Basic sanity: calling sendVerbose still forwards to the log sender (2 channels). - EXPECT_CALL(*log_sender_mock_raw_ptr_, SendVerbose(_, _, _)).Times(2); - dltServer.sendVerbose(100U, entry); -} - -TEST_F(DltServerCreatedWithConfigFixture, ResetToDefaultBehaviorRestoresInitialThresholds) -{ - // Verify that ResetToDefault() restores initial thresholds, affecting message filtering. - // Load persistent config with 2 read calls expected (constructor + ResetToDefault) - EXPECT_CALL(readCallback_, Call()).Times(2).WillRepeatedly(Return(pConfig)); - EXPECT_CALL(writeCallback_, Call(_)).Times(1); - - // Use test subclass to access sendVerbose - score::logging::dltserver::DltLogServer::DltLogServerTest dltServer( - sConfig, readCallback_.AsStdFunction(), writeCallback_.AsStdFunction(), true, std::move(log_sender_mock_)); - - const score::mw::log::detail::LoggingIdentifier app_id{"APP0"}; - const score::mw::log::detail::LoggingIdentifier ctx_id{"CTX0"}; - const score::mw::log::detail::log_entry_deserialization::LogEntryDeserializationReflection verbose_entry{ - app_id, ctx_id, {}, 0, score::mw::log::LogLevel::kVerbose}; - - // Initially threshold for APP0/CTX0 is kOff, so verbose should be filtered out - EXPECT_CALL(*log_sender_mock_raw_ptr_, SendVerbose(_, _, _)).Times(0); - dltServer.sendVerbose(100U, verbose_entry); - ::testing::Mock::VerifyAndClearExpectations(log_sender_mock_raw_ptr_); - - // Increase threshold to kVerbose so verbose messages pass filtering - const threshold_t new_threshold{loglevel_t{score::mw::log::LogLevel::kVerbose}}; - const auto resp = dltServer.SetLogLevel(dltid_t{"APP0"}, dltid_t{"CTX0"}, new_threshold); - EXPECT_EQ(resp[0], static_cast(config::RET_OK)); - - // Verify verbose now passes (2 channels: DFLT + CORE) - EXPECT_CALL(*log_sender_mock_raw_ptr_, SendVerbose(_, _, _)).Times(2); - dltServer.sendVerbose(100U, verbose_entry); - ::testing::Mock::VerifyAndClearExpectations(log_sender_mock_raw_ptr_); - - // Call ResetToDefault() to restore initial thresholds - const auto reset_resp = dltServer.ResetToDefault(); - EXPECT_EQ(reset_resp.size(), kCommandResponseSize); - EXPECT_EQ(reset_resp[0], static_cast(config::RET_OK)); - - // After reset, threshold should be back to kOff, so verbose is filtered again - EXPECT_CALL(*log_sender_mock_raw_ptr_, SendVerbose(_, _, _)).Times(0); - dltServer.sendVerbose(100U, verbose_entry); -} - -TEST_F(DltServerCreatedWithConfigFixture, ReadLogChannelNamesDirectCallContainsExpectedChannels) -{ - // Enhanced test to verify ReadLogChannelNames() returns actual channel names, not just OK status. - EXPECT_CALL(readCallback_, Call()).Times(1).WillOnce(Return(pConfig)); - EXPECT_CALL(writeCallback_, Call(_)).Times(0); - - DltLogServer dltServer(sConfig, readCallback_.AsStdFunction(), writeCallback_.AsStdFunction(), true); - - // Directly call ReadLogChannelNames() - const auto response = dltServer.ReadLogChannelNames(); - - // Should return OK status and channel names - ASSERT_GT(response.size(), kCommandResponseSize); - EXPECT_EQ(response[0], static_cast(config::RET_OK)); - - // Verify response contains expected channel names from sConfig - const std::string response_str(response.begin() + kCommandResponseSize, response.end()); - EXPECT_NE(response_str.find("DFLT"), std::string::npos) << "Response should contain DFLT channel"; - EXPECT_NE(response_str.find("CORE"), std::string::npos) << "Response should contain CORE channel"; -} - } // namespace test diff --git a/score/datarouter/test/ut/ut_logging/test_file_transfer_handler_factory.cpp b/score/datarouter/test/ut/ut_logging/test_file_transfer_handler_factory.cpp index 1ac05e4..1e6df52 100644 --- a/score/datarouter/test/ut/ut_logging/test_file_transfer_handler_factory.cpp +++ b/score/datarouter/test/ut/ut_logging/test_file_transfer_handler_factory.cpp @@ -11,13 +11,13 @@ * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ +#include "score/datarouter/file_transfer/file_transfer_handler_factory.hpp" #include "score/datarouter/include/applications/datarouter_feature_config.h" -#include "score/datarouter/src/file_transfer/file_transfer_handler_factory.hpp" #if defined(DLT_FILE_TRANSFER_FEATURE) -#include "score/datarouter/src/file_transfer/file_transfer_impl/file_transfer_stream_handler_factory.h" +#include "score/datarouter/file_transfer/file_transfer_impl/file_transfer_stream_handler_factory.h" #else -#include "score/datarouter/src/file_transfer/file_transfer_stub/file_transfer_handler_factory_stub.h" +#include "score/datarouter/file_transfer/file_transfer_stub/file_transfer_handler_factory_stub.h" #endif #include diff --git a/score/datarouter/test/ut/ut_logging/test_filetransfer_stream.cpp b/score/datarouter/test/ut/ut_logging/test_filetransfer_stream.cpp index 1c42974..1e52326 100644 --- a/score/datarouter/test/ut/ut_logging/test_filetransfer_stream.cpp +++ b/score/datarouter/test/ut/ut_logging/test_filetransfer_stream.cpp @@ -13,7 +13,7 @@ #include "gmock/gmock.h" #include "gtest/gtest.h" -#include "score/datarouter/src/file_transfer/file_transfer_impl/filetransfer_stream.h" +#include "score/datarouter/file_transfer/file_transfer_impl/filetransfer_stream.h" #include #include #include diff --git a/score/datarouter/test/ut/ut_logging/test_message_passing_server.cpp b/score/datarouter/test/ut/ut_logging/test_message_passing_server.cpp index 56b4952..8a972e9 100644 --- a/score/datarouter/test/ut/ut_logging/test_message_passing_server.cpp +++ b/score/datarouter/test/ut/ut_logging/test_message_passing_server.cpp @@ -13,13 +13,12 @@ #include "score/datarouter/include/daemon/message_passing_server.h" -#include "score/message_passing/mock/client_connection_mock.h" -#include "score/message_passing/mock/client_factory_mock.h" -#include "score/message_passing/mock/server_connection_mock.h" -#include "score/message_passing/mock/server_factory_mock.h" -#include "score/message_passing/mock/server_mock.h" +#include "score/concurrency/thread_pool.h" #include "score/os/mocklib/mock_pthread.h" #include "score/os/mocklib/unistdmock.h" +#include "score/mw/com/message_passing/message.h" +#include "score/mw/com/message_passing/receiver_mock.h" +#include "score/mw/com/message_passing/sender_mock.h" #include "score/datarouter/daemon_communication/session_handle_mock.h" #include "score/optional.hpp" @@ -31,7 +30,7 @@ #include #include -using namespace score::message_passing; +using namespace score::mw::com::message_passing; namespace score { @@ -40,27 +39,6 @@ namespace platform namespace internal { -MATCHER_P(CompareServiceProtocol, expected, "") -{ - if (arg.identifier != expected.identifier || arg.max_send_size != expected.max_send_size || - arg.max_reply_size != expected.max_reply_size || arg.max_notify_size != expected.max_notify_size) - { - return false; - } - return true; -} - -MATCHER_P(CompareServerConfig, expected, "") -{ - if (arg.max_queued_sends != expected.max_queued_sends || - arg.pre_alloc_connections != expected.pre_alloc_connections || - arg.max_queued_notifies != expected.max_queued_notifies) - { - return false; - } - return true; -} - using ::testing::_; using ::testing::An; using ::testing::AnyNumber; @@ -70,19 +48,16 @@ using ::testing::Field; using ::testing::InSequence; using ::testing::Matcher; using ::testing::Return; -using ::testing::ReturnRef; using ::testing::StrictMock; using score::mw::log::detail::DatarouterMessageIdentifier; +using score::mw::log::detail::ToMessageId; constexpr pid_t OUR_PID = 4444; constexpr pid_t CLIENT0_PID = 1000; constexpr pid_t CLIENT1_PID = 1001; constexpr pid_t CLIENT2_PID = 1002; -constexpr std::uint32_t kMaxSendBytes{17U}; - -std::uint32_t kReceiverQueueMaxSize = 0; class MockSession : public MessagePassingServer::ISession { @@ -141,23 +116,17 @@ class MessagePassingServerFixture : public ::testing::Test void SetUp() override { - server_factory_mock_ = std::make_shared>(); - client_factory_mock_ = std::make_shared>(); - - const score::message_passing::IServerFactory::ServerConfig server_config{kReceiverQueueMaxSize, 0U, 0U}; - - auto server = score::cpp::pmr::make_unique>( - score::cpp::pmr::get_default_resource()); - server_mock_ = server.get(); - - EXPECT_CALL( - *server_factory_mock_, - Create(CompareServiceProtocol(ServiceProtocolConfig{"/logging.datarouter_recv", kMaxSendBytes, 0U, 0U}), - CompareServerConfig(server_config))) - .WillOnce(Return(ByMove(std::move(server)))); + using namespace ::score::mw::com; + message_passing::ReceiverFactory::InjectReceiverMock(&receiver_mock_); + message_passing::SenderFactory::InjectSenderMock(&sender_mock_); } - void TearDown() override {} + void TearDown() override + { + using namespace ::score::mw::com; + message_passing::ReceiverFactory::InjectReceiverMock(nullptr); + message_passing::SenderFactory::InjectSenderMock(nullptr); + } auto GetCountingSessionFactory() { @@ -201,15 +170,7 @@ class MessagePassingServerFixture : public ::testing::Test return session; }; } - void ExpectClientDestruction(StrictMock<::score::message_passing::ClientConnectionMock>* client_mock) - { - EXPECT_CALL(*client_mock, Destruct()).Times(AnyNumber()); - } - void ExpectServerDestruction() - { - EXPECT_CALL(*server_mock_, Destruct()).Times(AnyNumber()); - } void CheckWaitTickUnblock() { // atomic fast path, to avoid introduction of explicit thread serialization on tick_blocker_mutex_ @@ -225,62 +186,26 @@ class MessagePassingServerFixture : public ::testing::Test void InstantiateServer(MessagePassingServer::SessionFactory factory = {}) { + using namespace ::score::mw::com; + // capture MessagePassingServer-installed callbacks when provided - EXPECT_CALL(*server_mock_, - StartListening(Matcher(_), - Matcher(_), - Matcher(_), - Matcher(_))) - .WillOnce([this](score::message_passing::ConnectCallback con_callback, - score::message_passing::DisconnectCallback discon_callback, - score::message_passing::MessageCallback sn_callback, - score::message_passing::MessageCallback sn_rep_callback) { - this->connect_callback_ = std::move(con_callback); - this->disconnect_callback_ = std::move(discon_callback); - this->sent_callback_ = std::move(sn_callback); - this->sent_with_reply_callback_ = std::move(sn_rep_callback); - return score::cpp::expected_blank{}; + EXPECT_CALL(receiver_mock_, + Register(ToMessageId(DatarouterMessageIdentifier::kConnect), + (An()))) + .WillOnce([this](auto /*id*/, auto callback) { + connect_callback_ = std::move(callback); + }); + EXPECT_CALL(receiver_mock_, + Register(ToMessageId(DatarouterMessageIdentifier::kAcquireResponse), + (An()))) + .WillOnce([this](auto /*id*/, auto callback) { + acquire_response_callback_ = std::move(callback); }); - // instantiate MessagePassingServer - server_.emplace(factory, server_factory_mock_, client_factory_mock_); - } - - auto CreateConnectMessageSample(const pid_t) - { - score::mw::log::detail::ConnectMessageFromClient msg; - score::mw::log::detail::LoggingIdentifier app_id{""}; - msg.SetAppId(app_id); - msg.SetUid(0U); - msg.SetUseDynamicIdentifier(false); - std::array message{}; - message[0] = score::cpp::to_underlying(DatarouterMessageIdentifier::kConnect); - // NOLINTNEXTLINE(score-banned-function) serialization of trivially copyable - std::memcpy(&message[1], &msg, sizeof(msg)); - return message; - } - - StrictMock<::score::message_passing::ClientConnectionMock>* ExpectConnectCallBackCalledAndClientCreated( - const pid_t pid) - { - auto client = score::cpp::pmr::make_unique>( - score::cpp::pmr::get_default_resource()); - - auto client_mock = client.get(); - - EXPECT_CALL(*client_factory_mock_, - Create(Matcher(_), - Matcher(_))) - .WillOnce(Return(ByMove(std::move(client)))); - - StrictMock<::score::message_passing::ServerConnectionMock> connection; - score::message_passing::ClientIdentity client_identity{pid, 0, 0}; - EXPECT_CALL(connection, GetClientIdentity()).Times(AnyNumber()).WillRepeatedly(ReturnRef(client_identity)); - - auto message = CreateConnectMessageSample(pid); - sent_callback_(connection, message); + EXPECT_CALL(receiver_mock_, StartListening()).WillOnce(Return(score::cpp::expected_blank{})); - return client_mock; + // instantiate MessagePassingServer + server_.emplace(factory, executor_); } void UninstantiateServer() @@ -293,15 +218,14 @@ class MessagePassingServerFixture : public ::testing::Test EXPECT_CALL(*unistd_mock_, getpid()).WillRepeatedly(Return(OUR_PID)); } - void ExpectMessageSendInSequence(const DatarouterMessageIdentifier& id, - ::testing::Sequence& seq, - StrictMock<::score::message_passing::ClientConnectionMock>* client_mock) + void ExpectShortMessageSendInSequence(const DatarouterMessageIdentifier& id, ::testing::Sequence& seq) { - EXPECT_CALL(*client_mock, Send(An>())) + using namespace ::score::mw::com; + EXPECT_CALL(sender_mock_, Send(An())) .InSequence(seq) - .WillOnce([id](const auto m) { + .WillOnce([id](const auto& m) { score::cpp::expected_blank ret{}; - if (m.front() != score::cpp::to_underlying(id)) + if (m.pid != OUR_PID || m.id != ToMessageId(id)) { ret = score::cpp::make_unexpected(score::os::Error::createFromErrno(EINVAL)); } @@ -309,22 +233,37 @@ class MessagePassingServerFixture : public ::testing::Test }); } - void ExpectAndFailShortMessageSend(StrictMock<::score::message_passing::ClientConnectionMock>* client_mock) + void ExpectShortMessageSend(const std::uint8_t id) + { + using namespace ::score::mw::com; + EXPECT_CALL(sender_mock_, Send(An())).WillOnce([id](const auto& m) { + score::cpp::expected_blank ret{}; + if (m.pid != OUR_PID || m.id != id) + { + ret = score::cpp::make_unexpected(score::os::Error::createFromErrno(EINVAL)); + } + return ret; + }); + } + + void ExpectAndFailShortMessageSend(const DatarouterMessageIdentifier& id) { - EXPECT_CALL(*client_mock, Send(Matcher>(_))) + using namespace ::score::mw::com; + EXPECT_CALL(sender_mock_, + Send(Matcher( + Field(&message_passing::ShortMessage::id, Eq(ToMessageId(id)))))) .WillOnce(Return(score::cpp::make_unexpected(score::os::Error::createFromErrno(EINVAL)))); } - StrictMock<::score::message_passing::ServerMock>* server_mock_{}; - std::shared_ptr> client_factory_mock_; - std::shared_ptr> server_factory_mock_; + StrictMock<::score::mw::com::message_passing::ReceiverMock> receiver_mock_{}; + StrictMock<::score::mw::com::message_passing::SenderMock> sender_mock_{}; ::score::os::MockGuard unistd_mock_{}; + ::score::concurrency::ThreadPool executor_{2}; score::cpp::optional server_; - score::message_passing::ConnectCallback connect_callback_; - score::message_passing::DisconnectCallback disconnect_callback_; - score::message_passing::MessageCallback sent_callback_; - score::message_passing::MessageCallback sent_with_reply_callback_; + score::cpp::callback connect_callback_; + score::cpp::callback acquire_response_callback_; + score::cpp::callback release_response_callback_; std::mutex map_mutex_; std::condition_variable map_cond_; // currently only used for destruction @@ -347,7 +286,6 @@ class MessagePassingServerFixture : public ::testing::Test TEST_F(MessagePassingServerFixture, TestNoSession) { InstantiateServer(); - ExpectServerDestruction(); UninstantiateServer(); } @@ -359,33 +297,32 @@ TEST_F(MessagePassingServerFixture, TestFailedForSettingThreadName) .WillOnce(Return(score::cpp::make_unexpected(score::os::Error::createFromErrno()))); InstantiateServer(); score::os::Pthread::restore_instance(); - ExpectServerDestruction(); UninstantiateServer(); } TEST_F(MessagePassingServerFixture, TestFailedStartListening) { + using namespace ::score::mw::com; MessagePassingServer::SessionFactory factory = {}; // capture MessagePassingServer-installed callbacks when provided - EXPECT_CALL(*server_mock_, - StartListening(Matcher(_), - Matcher(_), - Matcher(_), - Matcher(_))) - .WillOnce([this](score::message_passing::ConnectCallback con_callback, - score::message_passing::DisconnectCallback discon_callback, - score::message_passing::MessageCallback sn_callback, - score::message_passing::MessageCallback sn_rep_callback) { - this->connect_callback_ = std::move(con_callback); - this->disconnect_callback_ = std::move(discon_callback); - this->sent_callback_ = std::move(sn_callback); - this->sent_with_reply_callback_ = std::move(sn_rep_callback); - return score::cpp::expected_blank{}; + EXPECT_CALL(receiver_mock_, + Register(ToMessageId(DatarouterMessageIdentifier::kConnect), + (An()))) + .WillOnce([this](auto /*id*/, auto callback) { + connect_callback_ = std::move(callback); + }); + EXPECT_CALL(receiver_mock_, + Register(ToMessageId(DatarouterMessageIdentifier::kAcquireResponse), + (An()))) + .WillOnce([this](auto /*id*/, auto callback) { + acquire_response_callback_ = std::move(callback); }); + + EXPECT_CALL(receiver_mock_, StartListening()) + .WillOnce(Return(score::cpp::make_unexpected(score::os::Error::createFromErrno()))); // instantiate MessagePassingServer - server_.emplace(factory, server_factory_mock_, client_factory_mock_); - ExpectServerDestruction(); + server_.emplace(factory, executor_); UninstantiateServer(); } @@ -398,41 +335,23 @@ TEST_F(MessagePassingServerFixture, TestOneConnectAcquireRelease) EXPECT_EQ(tick_count_, 0); EXPECT_EQ(construct_count_, 0); - - auto client = ExpectConnectCallBackCalledAndClientCreated(CLIENT0_PID); - + ::score::mw::com::message_passing::MediumMessagePayload msg_connect{}; + connect_callback_(msg_connect, CLIENT0_PID); EXPECT_EQ(construct_count_, 1); - EXPECT_CALL(*client, - Start(Matcher(_), - Matcher(_))); - - EXPECT_CALL(*client, GetState()).WillRepeatedly(Return(score::message_passing::IClientConnection::State::kReady)); ::testing::Sequence seq; - ExpectMessageSendInSequence(DatarouterMessageIdentifier::kAcquireRequest, seq, client); + ExpectShortMessageSendInSequence(DatarouterMessageIdentifier::kAcquireRequest, seq); session_map_.at(CLIENT0_PID).handle_->AcquireRequest(); EXPECT_EQ(acquire_response_count_, 0); - - StrictMock<::score::message_passing::ServerConnectionMock> connection; - score::message_passing::ClientIdentity client_identity{CLIENT0_PID, 0, 0}; - EXPECT_CALL(connection, GetClientIdentity()).Times(AnyNumber()).WillRepeatedly(ReturnRef(client_identity)); - - score::mw::log::detail::ReadAcquireResult acquire_result{0U}; - std::array message{}; - message[0] = score::cpp::to_underlying(DatarouterMessageIdentifier::kAcquireResponse); - std::memcpy(&message[1], &acquire_result, sizeof(acquire_result)); - - sent_callback_(connection, message); - + ::score::mw::com::message_passing::MediumMessagePayload msg_acquire{}; + acquire_response_callback_(msg_acquire, CLIENT0_PID); EXPECT_EQ(acquire_response_count_, 1); EXPECT_EQ(closed_by_peer_count_, 0); EXPECT_FALSE(session_map_.empty()); - ExpectAndFailShortMessageSend(client); - ExpectServerDestruction(); - ExpectClientDestruction(client); + ExpectAndFailShortMessageSend(DatarouterMessageIdentifier::kAcquireRequest); session_map_.at(CLIENT0_PID).handle_->AcquireRequest(); { // let the worker thread process the fault; wait until it erases the client @@ -444,10 +363,12 @@ TEST_F(MessagePassingServerFixture, TestOneConnectAcquireRelease) EXPECT_GE(tick_count_, 1); EXPECT_EQ(closed_by_peer_count_, 1); + EXPECT_EQ(destruct_count_, 1); UninstantiateServer(); EXPECT_EQ(destruct_count_, 1); } + TEST_F(MessagePassingServerFixture, TestTripleConnectDifferentPids) { ExpectOurPidIsQueried(); @@ -455,17 +376,12 @@ TEST_F(MessagePassingServerFixture, TestTripleConnectDifferentPids) InstantiateServer(GetCountingSessionFactory()); EXPECT_EQ(construct_count_, 0); - - auto client0 = ExpectConnectCallBackCalledAndClientCreated(CLIENT0_PID); - auto client1 = ExpectConnectCallBackCalledAndClientCreated(CLIENT1_PID); - auto client2 = ExpectConnectCallBackCalledAndClientCreated(CLIENT2_PID); + ::score::mw::com::message_passing::MediumMessagePayload msg_connect{}; + connect_callback_(msg_connect, CLIENT0_PID); + connect_callback_(msg_connect, CLIENT1_PID); + connect_callback_(msg_connect, CLIENT2_PID); EXPECT_EQ(construct_count_, 3); - ExpectServerDestruction(); - ExpectClientDestruction(client0); - ExpectClientDestruction(client1); - ExpectClientDestruction(client2); - EXPECT_EQ(closed_by_peer_count_, 0); EXPECT_EQ(destruct_count_, 0); @@ -477,34 +393,18 @@ TEST_F(MessagePassingServerFixture, TestTripleConnectDifferentPids) TEST_F(MessagePassingServerFixture, TestTripleConnectSamePid) { - StrictMock<::score::message_passing::ServerConnectionMock> connection; - score::message_passing::ClientIdentity client_identity{CLIENT0_PID, 0, 0}; - ExpectOurPidIsQueried(); + InstantiateServer(GetCountingSessionFactory()); EXPECT_EQ(tick_count_, 0); EXPECT_EQ(construct_count_, 0); - - // Recieving new connect with old pid means that old pid owner died and disconnect_callback was called. - auto client0 = ExpectConnectCallBackCalledAndClientCreated(CLIENT0_PID); - EXPECT_CALL(connection, GetClientIdentity()).WillOnce(ReturnRef(client_identity)); - ExpectClientDestruction(client0); - this->disconnect_callback_(connection); - using namespace std::chrono_literals; - std::this_thread::sleep_for(100ms); - auto client1 = ExpectConnectCallBackCalledAndClientCreated(CLIENT0_PID); - EXPECT_CALL(connection, GetClientIdentity()).WillOnce(ReturnRef(client_identity)); - ExpectClientDestruction(client1); - this->disconnect_callback_(connection); - std::this_thread::sleep_for(100ms); - - auto client2 = ExpectConnectCallBackCalledAndClientCreated(CLIENT0_PID); - ExpectClientDestruction(client2); + ::score::mw::com::message_passing::MediumMessagePayload msg_connect{}; + connect_callback_(msg_connect, CLIENT0_PID); + connect_callback_(msg_connect, CLIENT0_PID); + connect_callback_(msg_connect, CLIENT0_PID); EXPECT_EQ(construct_count_, 3); - ExpectServerDestruction(); - EXPECT_EQ(closed_by_peer_count_, 2); EXPECT_EQ(destruct_count_, 2); EXPECT_GE(tick_count_, 2); @@ -517,7 +417,6 @@ TEST_F(MessagePassingServerFixture, TestTripleConnectSamePid) TEST_F(MessagePassingServerFixture, TestSamePidWhileRunning) { - ExpectOurPidIsQueried(); InstantiateServer(GetCountingSessionFactory()); @@ -525,32 +424,22 @@ TEST_F(MessagePassingServerFixture, TestSamePidWhileRunning) tick_blocker_ = true; EXPECT_EQ(tick_count_, 0); EXPECT_EQ(construct_count_, 0); - auto client0 = ExpectConnectCallBackCalledAndClientCreated(CLIENT0_PID); - auto client1 = ExpectConnectCallBackCalledAndClientCreated(CLIENT1_PID); - auto client2 = ExpectConnectCallBackCalledAndClientCreated(CLIENT2_PID); + ::score::mw::com::message_passing::MediumMessagePayload msg_connect{}; + connect_callback_(msg_connect, CLIENT0_PID); + connect_callback_(msg_connect, CLIENT1_PID); + connect_callback_(msg_connect, CLIENT2_PID); EXPECT_EQ(construct_count_, 3); - ExpectServerDestruction(); - - // ExpectClientDestruction(client0); - // wait until CLIENT0 is blocked inside the first tick + // wait until CLIENT0 is blocked inside the first tick session_map_.at(CLIENT0_PID).WaitStartOfFirstTick(); // accumulate other ticks in the queue using namespace std::chrono_literals; - std::this_thread::sleep_for(100ms); + std::this_thread::sleep_for(250ms); // we will need to unblock the tick before the callback returns, so start it on a separate thread std::thread connect_thread([&]() { - StrictMock<::score::message_passing::ServerConnectionMock> connection; - score::message_passing::ClientIdentity client_identity{CLIENT0_PID, 0, 0}; - EXPECT_CALL(connection, GetClientIdentity()).WillOnce(ReturnRef(client_identity)); - ExpectClientDestruction(client0); - this->disconnect_callback_(connection); - std::this_thread::sleep_for(100ms); - - auto new_client = ExpectConnectCallBackCalledAndClientCreated(CLIENT0_PID); - ExpectClientDestruction(new_client); + connect_callback_(msg_connect, CLIENT0_PID); }); EXPECT_EQ(destruct_count_, 0); // no destruction while we are still in the tick @@ -563,8 +452,6 @@ TEST_F(MessagePassingServerFixture, TestSamePidWhileRunning) EXPECT_EQ(destruct_count_, 1); EXPECT_GE(tick_count_, 2); - ExpectClientDestruction(client1); - ExpectClientDestruction(client2); UninstantiateServer(); EXPECT_EQ(closed_by_peer_count_, 1); @@ -580,13 +467,12 @@ TEST_F(MessagePassingServerFixture, TestSamePidWhileQueued) tick_blocker_ = true; EXPECT_EQ(tick_count_, 0); EXPECT_EQ(construct_count_, 0); - auto client0 = ExpectConnectCallBackCalledAndClientCreated(CLIENT0_PID); - auto client1 = ExpectConnectCallBackCalledAndClientCreated(CLIENT1_PID); - auto client2 = ExpectConnectCallBackCalledAndClientCreated(CLIENT2_PID); + ::score::mw::com::message_passing::MediumMessagePayload msg_connect{}; + connect_callback_(msg_connect, CLIENT0_PID); + connect_callback_(msg_connect, CLIENT1_PID); + connect_callback_(msg_connect, CLIENT2_PID); EXPECT_EQ(construct_count_, 3); - ExpectServerDestruction(); - // wait until CLIENT0 is blocked inside the first tick session_map_.at(CLIENT0_PID).WaitStartOfFirstTick(); @@ -596,15 +482,7 @@ TEST_F(MessagePassingServerFixture, TestSamePidWhileQueued) // we will need to unblock the tick before the callback returns, so start it on a separate thread std::thread connect_thread([&]() { - StrictMock<::score::message_passing::ServerConnectionMock> connection; - score::message_passing::ClientIdentity client_identity{CLIENT2_PID, 0, 0}; - EXPECT_CALL(connection, GetClientIdentity()).WillOnce(ReturnRef(client_identity)); - ExpectClientDestruction(client2); - this->disconnect_callback_(connection); - std::this_thread::sleep_for(100ms); - - auto new_client = ExpectConnectCallBackCalledAndClientCreated(CLIENT2_PID); - ExpectClientDestruction(new_client); + connect_callback_(msg_connect, CLIENT2_PID); }); EXPECT_EQ(destruct_count_, 0); // no destruction while we are still in the tick @@ -617,14 +495,36 @@ TEST_F(MessagePassingServerFixture, TestSamePidWhileQueued) EXPECT_EQ(destruct_count_, 1); EXPECT_GE(tick_count_, 2); - ExpectClientDestruction(client0); - ExpectClientDestruction(client1); UninstantiateServer(); EXPECT_EQ(closed_by_peer_count_, 1); EXPECT_EQ(destruct_count_, 4); } +TEST_F(MessagePassingServerFixture, TestConnectionTimeoutReached) +{ + ::score::mw::com::message_passing::SenderFactory::InjectSenderMock(&sender_mock_, + [](const score::cpp::stop_token& token) noexcept { + while (not token.stop_requested()) + { + } + }); + + ExpectOurPidIsQueried(); + + InstantiateServer(GetCountingSessionFactory()); + + EXPECT_EQ(tick_count_, 0); + EXPECT_EQ(construct_count_, 0); + ::score::mw::com::message_passing::MediumMessagePayload msg_connect{}; + connect_callback_(msg_connect, CLIENT0_PID); + EXPECT_EQ(construct_count_, 0); + + UninstantiateServer(); + + EXPECT_EQ(destruct_count_, 0); +} + class MessagePassingServer::MessagePassingServerForTest : public MessagePassingServer { public: @@ -658,25 +558,15 @@ TEST(MessagePassingServerTests, sessionWrapperCreateTest) TEST(MessagePassingServerTests, sessionHandleCreateTest) { const pid_t pid = 0; - - auto client = score::cpp::pmr::make_unique(score::cpp::pmr::get_default_resource()); - - auto client_raw_ptr = client.get(); + auto sender = score::cpp::pmr::make_unique<::score::mw::com::message_passing::SenderMock>(score::cpp::pmr::get_default_resource()); + auto sender_raw_ptr = sender.get(); MessagePassingServer* msg_server = nullptr; - EXPECT_CALL(*client_raw_ptr, - Start(Matcher(_), - Matcher(_))); - - EXPECT_CALL(*client_raw_ptr, GetState()) - .WillRepeatedly(Return(score::message_passing::IClientConnection::State::kReady)); - - EXPECT_CALL(*client_raw_ptr, Send(An>())).Times(1); + EXPECT_CALL(*sender_raw_ptr, Send(An())).Times(1); - MessagePassingServer::SessionHandle session_handle(pid, msg_server, std::move(client)); + MessagePassingServer::SessionHandle session_handle(pid, msg_server, std::move(sender)); EXPECT_NO_FATAL_FAILURE(session_handle.AcquireRequest()); - EXPECT_CALL(*client_raw_ptr, Destruct()).Times(AnyNumber()); } struct TestParams diff --git a/score/datarouter/test/ut/ut_logging/test_nonverbosedlt.cpp b/score/datarouter/test/ut/ut_logging/test_nonverbosedlt.cpp index a1cc2d1..3d0d519 100644 --- a/score/datarouter/test/ut/ut_logging/test_nonverbosedlt.cpp +++ b/score/datarouter/test/ut/ut_logging/test_nonverbosedlt.cpp @@ -43,7 +43,7 @@ class MockDltOutput : public DltNonverboseHandler::IOutput { public: MOCK_METHOD(void, - SendNonVerbose, + sendNonVerbose, (const score::mw::log::config::NvMsgDescriptor& desc, uint32_t tmsp, const void* data, size_t size), (override)); virtual ~MockDltOutput() = default; @@ -88,7 +88,7 @@ TEST(DltNonverboseHandler_T, HandleShouldNotCallSendNonVerboseWhenDescriptorIsNu MockDltOutput mockOutput; DltNonverboseHandler handler(mockOutput); - EXPECT_CALL(mockOutput, SendNonVerbose(_, _, _, _)).Times(0); + EXPECT_CALL(mockOutput, sendNonVerbose(_, _, _, _)).Times(0); handler.handle(typeInfo, timestamp, data, size); } @@ -102,7 +102,7 @@ TEST(DltNonverboseHandler_T, HandleCallSendNonVerboseWhenDltMsgDesc) score::mw::log::detail::LoggingIdentifier{"CTX0"}, score::mw::log::LogLevel::kOff}; - EXPECT_CALL(mockOutput, SendNonVerbose(_, _, _, _)).Times(1); + EXPECT_CALL(mockOutput, sendNonVerbose(_, _, _, _)).Times(1); DltNonverboseHandler handler(mockOutput); diff --git a/score/datarouter/test/ut/ut_logging/test_socketserver.cpp b/score/datarouter/test/ut/ut_logging/test_socketserver.cpp index ff530df..cbf3097 100644 --- a/score/datarouter/test/ut/ut_logging/test_socketserver.cpp +++ b/score/datarouter/test/ut/ut_logging/test_socketserver.cpp @@ -14,11 +14,8 @@ #include "applications/datarouter_feature_config.h" #include "daemon/socketserver.h" #include "logparser/logparser.h" -#include "score/os/mocklib/mock_pthread.h" #include "score/os/mocklib/unistdmock.h" #include "score/mw/log/configuration/invconfig_mock.h" -#include "score/mw/log/detail/data_router/data_router_messages.h" -#include "score/mw/log/detail/logging_identifier.h" #include "score/datarouter/datarouter/data_router.h" #include "score/datarouter/src/persistency/mock_persistent_dictionary.h" @@ -26,14 +23,9 @@ #include "gtest/gtest.h" #include -#include #include -#include using namespace testing; -using score::mw::log::detail::ConnectMessageFromClient; -using score::mw::log::detail::LoggingIdentifier; -using score::platform::datarouter::SocketServer; namespace score { @@ -66,7 +58,7 @@ TEST_F(SocketServerInitializePersistentStorageTest, InitializeWithDltEnabled) RecordProperty("DerivationTechnique", "Analysis of boundary values"); // Expect readDltEnabled to be called and return true - EXPECT_CALL(*dynamic_cast(mock_pd_.get()), GetBool(CONFIG_OUTPUT_ENABLED_KEY, true)) + EXPECT_CALL(*dynamic_cast(mock_pd_.get()), getBool(CONFIG_OUTPUT_ENABLED_KEY, true)) .WillOnce(Return(true)); auto handlers = SocketServer::InitializePersistentStorage(mock_pd_); @@ -94,7 +86,7 @@ TEST_F(SocketServerInitializePersistentStorageTest, InitializeWithDltDisabled) RecordProperty("DerivationTechnique", "Analysis of boundary values"); // Expect readDltEnabled to be called and return false - EXPECT_CALL(*dynamic_cast(mock_pd_.get()), GetBool(CONFIG_OUTPUT_ENABLED_KEY, true)) + EXPECT_CALL(*dynamic_cast(mock_pd_.get()), getBool(CONFIG_OUTPUT_ENABLED_KEY, true)) .WillOnce(Return(false)); auto handlers = SocketServer::InitializePersistentStorage(mock_pd_); @@ -122,13 +114,13 @@ TEST_F(SocketServerInitializePersistentStorageTest, LoadDltLambdaCallsReadDlt) RecordProperty("DerivationTechnique", "Error guessing based on knowledge or experience"); // Expect readDltEnabled to be called - EXPECT_CALL(*dynamic_cast(mock_pd_.get()), GetBool(CONFIG_OUTPUT_ENABLED_KEY, true)) + EXPECT_CALL(*dynamic_cast(mock_pd_.get()), getBool(CONFIG_OUTPUT_ENABLED_KEY, true)) .WillOnce(Return(true)); auto handlers = SocketServer::InitializePersistentStorage(mock_pd_); // Expect getString to be called when load_dlt lambda is invoked (by readDlt) - EXPECT_CALL(*dynamic_cast(mock_pd_.get()), GetString(CONFIG_DATABASE_KEY, _)) + EXPECT_CALL(*dynamic_cast(mock_pd_.get()), getString(CONFIG_DATABASE_KEY, _)) .WillOnce(Return("{}")); // Call the load_dlt lambda - it should successfully return a PersistentConfig @@ -146,13 +138,13 @@ TEST_F(SocketServerInitializePersistentStorageTest, StoreDltLambdaCallsWriteDlt) RecordProperty("DerivationTechnique", "Error guessing based on knowledge or experience"); // Expect readDltEnabled to be called - EXPECT_CALL(*dynamic_cast(mock_pd_.get()), GetBool(CONFIG_OUTPUT_ENABLED_KEY, true)) + EXPECT_CALL(*dynamic_cast(mock_pd_.get()), getBool(CONFIG_OUTPUT_ENABLED_KEY, true)) .WillOnce(Return(true)); auto handlers = SocketServer::InitializePersistentStorage(mock_pd_); // Expect setString to be called when store_dlt lambda is invoked (by writeDlt) - EXPECT_CALL(*dynamic_cast(mock_pd_.get()), SetString(CONFIG_DATABASE_KEY, _)).Times(1); + EXPECT_CALL(*dynamic_cast(mock_pd_.get()), setString(CONFIG_DATABASE_KEY, _)).Times(1); // Create a test config score::logging::dltserver::PersistentConfig test_config; @@ -377,7 +369,7 @@ TEST_F(SocketServerRemainingFunctionsTest, CreateEnableHandlerCreatesCallbackSuc DataRouter router(logger, source_setup); // Expect writeDltEnabled to be called when the handler lambda executes - EXPECT_CALL(*dynamic_cast(mock_pd_.get()), SetBool(CONFIG_OUTPUT_ENABLED_KEY, _)) + EXPECT_CALL(*dynamic_cast(mock_pd_.get()), setBool(CONFIG_OUTPUT_ENABLED_KEY, _)) .Times(1); // Create the enable handler - this covers lines 160-171 (function body and lambda creation) @@ -589,100 +581,6 @@ TEST_F(SocketServerRemainingFunctionsTest, CreateMessagePassingSessionCloseFailu std::remove(test_shmem_file.c_str()); } -class SocketServerTest : public Test -{ - protected: - void SetUp() override - { - pthread_mock_ = std::make_unique>(); - } - - void TearDown() override - { - pthread_mock_.reset(); - } - - std::unique_ptr> pthread_mock_; -}; - -TEST_F(SocketServerTest, SetThreadNameSuccess) -{ - RecordProperty("Description", "Verify SetThreadName sets pthread name successfully"); - RecordProperty("TestType", "Interface test"); - RecordProperty("Verifies", "::score::platform::datarouter::SocketServer::SetThreadName()"); - RecordProperty("DerivationTechnique", "Generation and analysis of equivalence classes"); - - pthread_t thread_id = pthread_self(); - - EXPECT_CALL(*pthread_mock_, self()).WillOnce(Return(thread_id)); - EXPECT_CALL(*pthread_mock_, setname_np(thread_id, StrEq("socketserver"))) - .WillOnce(Return(score::cpp::expected_blank{})); - - EXPECT_NO_THROW(SocketServer::SetThreadName(*pthread_mock_)); -} - -TEST_F(SocketServerTest, SetThreadNameParameterless) -{ - RecordProperty("Description", "Verify SetThreadName() overload uses default pthread implementation"); - RecordProperty("TestType", "Interface test"); - RecordProperty("Verifies", "::score::platform::datarouter::SocketServer::SetThreadName()"); - RecordProperty("DerivationTechnique", "Error guessing based on knowledge or experience"); - - EXPECT_NO_THROW(SocketServer::SetThreadName()); -} - -TEST_F(SocketServerTest, SetThreadNameFailureHandling) -{ - RecordProperty("Description", "Verify SetThreadName handles pthread failures without throwing"); - RecordProperty("TestType", "Fault injection test"); - RecordProperty("Verifies", "::score::platform::datarouter::SocketServer::SetThreadName()"); - RecordProperty("DerivationTechnique", "Error guessing based on knowledge or experience"); - RecordProperty("InjectionPoints", "score::os::Pthread::setname_np returns unexpected error"); - RecordProperty("MeasurementPoints", "Function does not throw"); - - pthread_t thread_id = pthread_self(); - const score::os::Error error = score::os::Error::createFromErrno(EINVAL); - - EXPECT_CALL(*pthread_mock_, self()).WillOnce(Return(thread_id)); - EXPECT_CALL(*pthread_mock_, setname_np(thread_id, StrEq("socketserver"))) - .WillOnce(Return(score::cpp::unexpected(error))); - - // Should not throw even on failure (prints error to stderr and continues) - EXPECT_NO_THROW(SocketServer::SetThreadName(*pthread_mock_)); -} - -TEST(SocketServerHelperTest, ResolveSharedMemoryFileNameWithDynamicIdentifier) -{ - RecordProperty("Description", "Verify ResolveSharedMemoryFileName uses the random identifier when requested"); - RecordProperty("TestType", "Interface test"); - RecordProperty("Verifies", "::score::platform::datarouter::SocketServer::ResolveSharedMemoryFileName()"); - RecordProperty("DerivationTechnique", "Generation and analysis of equivalence classes"); - - LoggingIdentifier appid("TEST"); - const std::array random_part = {'a', 'b', 'c', 'd', 'e', 'f'}; - ConnectMessageFromClient conn(appid, 1000, true, random_part); - - const std::string result = SocketServer::ResolveSharedMemoryFileName(conn, "TEST"); - - EXPECT_EQ(result, "/tmp/logging-abcdef.shmem"); -} - -TEST(SocketServerHelperTest, ResolveSharedMemoryFileNameWithStaticIdentifier) -{ - RecordProperty("Description", "Verify ResolveSharedMemoryFileName uses app and pid for static identifier"); - RecordProperty("TestType", "Interface test"); - RecordProperty("Verifies", "::score::platform::datarouter::SocketServer::ResolveSharedMemoryFileName()"); - RecordProperty("DerivationTechnique", "Generation and analysis of equivalence classes"); - - LoggingIdentifier appid("MYAP"); - const std::array random_part = {}; - ConnectMessageFromClient conn(appid, 5000, false, random_part); - - const std::string result = SocketServer::ResolveSharedMemoryFileName(conn, "MYAP"); - - EXPECT_EQ(result, "/tmp/logging.MYAP.5000.shmem"); -} - } // namespace } // namespace datarouter } // namespace platform diff --git a/score/datarouter/test/ut/ut_logging/test_socketserver_config.cpp b/score/datarouter/test/ut/ut_logging/test_socketserver_config.cpp index 8da3594..64f3883 100644 --- a/score/datarouter/test/ut/ut_logging/test_socketserver_config.cpp +++ b/score/datarouter/test/ut/ut_logging/test_socketserver_config.cpp @@ -191,7 +191,7 @@ TEST(SocketserverConfigTest, JsonOldFormatErrorExpected) TEST(SocketserverConfigTest, PersistentDictionaryEmptyJsonErrorExpected) { StrictMock pd; - EXPECT_CALL(pd, GetString(StrEq("dltConfig"), "{}")).Times(1).WillOnce(Return("{}")); + EXPECT_CALL(pd, getString(StrEq("dltConfig"), "{}")).Times(1).WillOnce(Return("{}")); const auto result = readDlt(pd); EXPECT_THAT(result.channels, SizeIs(0)); } @@ -209,7 +209,7 @@ TEST(SocketserverConfigTest, PersistentDictionaryCorrectJsonNoErrorsExpected) "\"STAT\":\"kDebug\"},\"-NI-\":{\"\":\"kVerbose\"}}}"}; StrictMock pd; - EXPECT_CALL(pd, GetString(StrEq("dltConfig"), "{}")).Times(1).WillOnce(Return(expected_json)); + EXPECT_CALL(pd, getString(StrEq("dltConfig"), "{}")).Times(1).WillOnce(Return(expected_json)); const auto result = readDlt(pd); EXPECT_TRUE(result.filteringEnabled); EXPECT_THAT(result.channels, SizeIs(3)); @@ -226,7 +226,7 @@ TEST(SocketserverConfigTest, PersistentDictionaryEmptyChannelsErrorExpected) "\"kDebug\"},\"-NI-\":{\"\":\"kVerbose\"}}}"}; StrictMock pd; - EXPECT_CALL(pd, GetString(StrEq("dltConfig"), "{}")).Times(1).WillOnce(Return(expected_json)); + EXPECT_CALL(pd, getString(StrEq("dltConfig"), "{}")).Times(1).WillOnce(Return(expected_json)); const auto result = readDlt(pd); EXPECT_THAT(result.channels, SizeIs(0)); } @@ -244,7 +244,7 @@ TEST(SocketserverConfigTest, PersistentDictionaryNoFilteringEnabledExpectTrueByD "\"kDebug\"},\"-NI-\":{\"\":\"kVerbose\"}}}"}; StrictMock pd; - EXPECT_CALL(pd, GetString(StrEq("dltConfig"), "{}")).Times(1).WillOnce(Return(expected_json)); + EXPECT_CALL(pd, getString(StrEq("dltConfig"), "{}")).Times(1).WillOnce(Return(expected_json)); const auto result = readDlt(pd); EXPECT_TRUE(result.filteringEnabled); } @@ -254,7 +254,7 @@ TEST(SocketserverConfigTest, PersistentDictionaryNoFilteringEnabledExpectTrueByD TEST(SocketserverConfigTest, WriteDltEnabledCallSetBoolExpected) { StrictMock pd; - EXPECT_CALL(pd, SetBool(StrEq("dltOutputEnabled"), true)).Times(1); + EXPECT_CALL(pd, setBool(StrEq("dltOutputEnabled"), true)).Times(1); writeDltEnabled(true, pd); } @@ -263,7 +263,7 @@ TEST(SocketserverConfigTest, WriteDltEnabledCallSetBoolExpected) TEST(SocketserverConfigTest, ReadDltEnabledTrueResultExpected) { StrictMock pd; - EXPECT_CALL(pd, GetBool(StrEq("dltOutputEnabled"), true)).WillOnce(Return(true)); + EXPECT_CALL(pd, getBool(StrEq("dltOutputEnabled"), true)).WillOnce(Return(true)); const auto result = readDltEnabled(pd); EXPECT_TRUE(result); } @@ -283,7 +283,7 @@ TEST(SocketserverConfigTest, WriteDltFilledPersistentConfigNoErrorExpected) config.defaultThreshold = mw::log::LogLevel::kVerbose; config.channelAssignments[dltid_t("000")][dltid_t("111")].push_back(dltid_t("22222")); config.messageThresholds[dltid_t("000")][dltid_t("111")] = mw::log::LogLevel::kVerbose; - EXPECT_CALL(pd, SetString(StrEq("dltConfig"), expected_json)).Times(1); + EXPECT_CALL(pd, setString(StrEq("dltConfig"), expected_json)).Times(1); writeDlt(config, pd); } @@ -327,7 +327,7 @@ TEST(SocketserverConfigTest, GetStringCallExpected) { StubPersistentDictionary pd; const std::string json{}; - auto default_return = pd.GetString(CONFIG_DATABASE_KEY, json); + auto default_return = pd.getString(CONFIG_DATABASE_KEY, json); ASSERT_EQ(default_return, json); } @@ -336,7 +336,7 @@ TEST(SocketserverConfigTest, GetBoolCallExpected) StubPersistentDictionary pd; const std::string key{}; const bool defaultBoolValue{}; - auto default_return = pd.GetBool(key, defaultBoolValue); + auto default_return = pd.getBool(key, defaultBoolValue); ASSERT_EQ(default_return, defaultBoolValue); } diff --git a/score/mw/log/BUILD b/score/mw/log/BUILD index 004b98a..a86b2fd 100644 --- a/score/mw/log/BUILD +++ b/score/mw/log/BUILD @@ -13,16 +13,8 @@ load("@rules_cc//cc:defs.bzl", "cc_library") -COMPILER_WARNING_FEATURES = [ - "treat_warnings_as_errors", - "additional_warnings", - "strict_warnings", -] - cc_library( name = "log", - features = COMPILER_WARNING_FEATURES, - tags = ["FFI"], visibility = ["//visibility:public"], deps = [ "//score/mw/log/detail/common:recorder_factory", diff --git a/score/mw/log/detail/data_router/BUILD b/score/mw/log/detail/data_router/BUILD index 1aad812..9ebad9a 100644 --- a/score/mw/log/detail/data_router/BUILD +++ b/score/mw/log/detail/data_router/BUILD @@ -56,10 +56,7 @@ cc_library( "//score/mw/log/detail/common:dlt_content_formatting", "//score/mw/log/detail/common:statistics_reporter", "//score/mw/log/detail/data_router/shared_memory:writer", - "//score/mw/log/detail/utils/signal_handling", "//score/mw/log/legacy_non_verbose_api", - "@score_baselibs//score/concurrency", - "@score_baselibs//score/concurrency:thread_pool", "@score_baselibs//score/language/futurecpp", "@score_baselibs//score/memory/shared", # Preperation for full rollout of (Ticket-105741), build cyclic dependency is broken (runtime, in next commit) "@score_baselibs//score/mw/log:recorder", @@ -74,7 +71,7 @@ cc_library( "@score_baselibs//score/os:pthread", "@score_baselibs//score/os:stdlib", "@score_baselibs//score/os/utils:signal", - "@score_communication//score/message_passing", + "@score_communication//score/mw/com/message_passing", ], ) @@ -137,7 +134,7 @@ cc_test( "@score_baselibs//score/os/mocklib:stdlib_mock", "@score_baselibs//score/os/mocklib:unistd_mock", "@score_baselibs//score/os/utils/mocklib:signal_mock", - "@score_communication//score/message_passing:mock", + "@score_communication//score/mw/com/message_passing:mock", ], ) @@ -157,16 +154,15 @@ cc_library( ], hdrs = [ "data_router_messages.h", - "message_passing_config.h", ], features = COMPILER_WARNING_FEATURES, tags = ["FFI"], visibility = [ "//score/datarouter:__pkg__", - "//score/datarouter/test:__subpackages__", "//score/mw/log/detail/slog:__pkg__", ], deps = [ "@score_baselibs//score/mw/log/detail:logging_identifier", + "@score_communication//score/mw/com/message_passing", ], ) diff --git a/score/mw/log/detail/data_router/data_router_message_client_factory_test.cpp b/score/mw/log/detail/data_router/data_router_message_client_factory_test.cpp index bcc634c..1830fcc 100644 --- a/score/mw/log/detail/data_router/data_router_message_client_factory_test.cpp +++ b/score/mw/log/detail/data_router/data_router_message_client_factory_test.cpp @@ -15,6 +15,8 @@ #include "score/os/mocklib/mock_pthread.h" #include "score/os/mocklib/unistdmock.h" #include "score/os/utils/mocklib/signalmock.h" +#include "score/mw/com/message_passing/receiver_mock.h" +#include "score/mw/com/message_passing/sender_mock.h" #include "score/mw/log/configuration/configuration.h" #include "score/mw/log/detail/data_router/data_router_message_client_factory_impl.h" #include "score/mw/log/detail/data_router/data_router_message_client_impl.h" diff --git a/score/mw/log/detail/data_router/data_router_message_client_impl.cpp b/score/mw/log/detail/data_router/data_router_message_client_impl.cpp index 9692312..ab70fca 100644 --- a/score/mw/log/detail/data_router/data_router_message_client_impl.cpp +++ b/score/mw/log/detail/data_router/data_router_message_client_impl.cpp @@ -15,13 +15,12 @@ #include "score/assert.hpp" #include "score/os/utils/signal.h" -#include "score/mw/log/detail/data_router/message_passing_config.h" +#include "score/mw/log/detail/data_router/data_router_messages.h" #include "score/mw/log/detail/error.h" #include "score/mw/log/detail/initialization_reporter.h" -#include "score/os/utils/signal_impl.h" -#include "score/mw/log/detail/utils/signal_handling/signal_handling.h" #include +#include #include namespace score @@ -35,6 +34,31 @@ namespace detail using std::chrono_literals::operator"" ms; +namespace +{ + +constexpr std::size_t kNumberOfThread{1UL}; +constexpr std::size_t kMaxNumberMessagesInReceiverQueue{1UL}; +constexpr std::int32_t kSenderMaxNumberOfSendRetries{1000}; +constexpr std::chrono::milliseconds kSenderRetrySendDelay = std::chrono::milliseconds(100); +constexpr std::chrono::milliseconds kSenderRetryConnectDelay = std::chrono::milliseconds(100); +constexpr std::chrono::milliseconds kReceiverMessageLoopDelay = std::chrono::milliseconds(10); +constexpr std::size_t kStartIndexOfRandomFileName{13UL}; + +template +auto BuildMessageImpl(const DatarouterMessageIdentifier id, const Payload& payload, const pid_t pid) -> Message +{ + Message message; + message.payload = payload; + message.id = ToMessageId(id); + message.pid = pid; + return message; +} + +void SenderLoggerCallback(score::mw::com::message_passing::LogFunction) {} + +} // namespace + DatarouterMessageClientImpl::DatarouterMessageClientImpl(const MsgClientIdentifiers& ids, MsgClientBackend backend, MsgClientUtils utils, @@ -49,13 +73,15 @@ DatarouterMessageClientImpl::DatarouterMessageClientImpl(const MsgClientIdentifi shared_memory_writer_{backend.GetShMemWriter()}, writer_file_name_{backend.GetWriterFilename()}, message_passing_factory_{std::move(backend.GetMsgPassingFactory())}, + monotonic_resource_buffer_{}, + monotonic_resource_{monotonic_resource_buffer_.data(), + monotonic_resource_buffer_.size(), + score::cpp::pmr::null_memory_resource()}, stop_source_{stop_source}, - sender_state_change_mutex_{}, - state_condition_{}, - sender_state_{}, + thread_pool_{kNumberOfThread, &monotonic_resource_}, sender_{nullptr}, receiver_{nullptr}, - connect_thread_{} + connect_task_{} { } @@ -77,47 +103,20 @@ void DatarouterMessageClientImpl::Run() void DatarouterMessageClientImpl::RunConnectTask() { // Since waiting for Datarouter to connect is a blocking operation we have to do this asynchronously. - connect_thread_ = score::cpp::jthread([this]() noexcept { - ConnectToDatarouter(); - }); + // clang-format off + connect_task_ = thread_pool_.Submit( + [this](const score::cpp::stop_token&) noexcept + { + ConnectToDatarouter(); + }); } void DatarouterMessageClientImpl::ConnectToDatarouter() noexcept { BlockTermSignal(); - SetThreadName(); - - if (!CreateSender().has_value()) - { - ReportInitializationError(score::mw::log::detail::Error::kFailedToCreateMessagePassingClient, - "Failed to create Message Passing Client.", - msg_client_ids_.GetAppID().GetStringView()); - RequestInternalShutdown(); - return; - } - - // Wait for the sender to be in Ready state before starting receiver - { - std::unique_lock lock(sender_state_change_mutex_); - state_condition_.wait(lock, [this]() { - return (sender_state_.has_value() && - sender_state_.value() == score::message_passing::IClientConnection::State::kReady) || - stop_source_.stop_requested(); - }); - } - - if (stop_source_.stop_requested()) - { - RequestInternalShutdown(); - return; - } - - if (!sender_state_.has_value() || sender_state_.value() != score::message_passing::IClientConnection::State::kReady) - { - RequestInternalShutdown(); - return; - } + SetThreadName(); + CreateSender(); if (StartReceiver() == false) { RequestInternalShutdown(); @@ -178,46 +177,31 @@ void DatarouterMessageClientImpl::SetThreadName() noexcept void DatarouterMessageClientImpl::SetupReceiver() noexcept { - const score::message_passing::ServiceProtocolConfig service_protocol_config{ - msg_client_ids_.GetReceiverID(), MessagePassingConfig::kMaxMessageSize, 0U, 0U}; - - const score::message_passing::IServerFactory::ServerConfig server_config{ - MessagePassingConfig::kMaxReceiverQueueSize, 0U, 0U}; - receiver_ = message_passing_factory_->CreateServer(service_protocol_config, server_config); + // Initialization of Array with client ids + // coverity[autosar_cpp14_m8_5_2_violation] + const std::array allowed_uids{msg_client_ids_.GetDatarouterUID()}; + const score::mw::com::message_passing::ReceiverConfig receiver_config{ + static_cast(kMaxNumberMessagesInReceiverQueue), kReceiverMessageLoopDelay}; + receiver_ = message_passing_factory_->CreateReceiver( + msg_client_ids_.GetReceiverID(), thread_pool_, allowed_uids, receiver_config, &monotonic_resource_); + + // clang-format off + receiver_->Register(ToMessageId(DatarouterMessageIdentifier::kAcquireRequest), + [this](std::uint64_t, pid_t) noexcept + { + this->OnAcquireRequest(); + }); } bool DatarouterMessageClientImpl::StartReceiver() { // When the receiver starts listening, receive callbacks may be called that use the sender to reply. // Thus we must create the sender before starting to listen to messages. - // Note that the receiver callback may only be called after the connect task finished. + // Note since the thread_pool_ shall only have one thread, the receiver callback may only be called after the + // connect task finished. SCORE_LANGUAGE_FUTURECPP_PRECONDITION_PRD_MESSAGE(sender_ != nullptr, "The sender must be created before the receiver."); - auto connect_callback = [this](score::message_passing::IServerConnection& connection) noexcept -> std::uintptr_t { - const auto result = SignalHandling::PThreadBlockSigTerm(this->utils_.GetSignal()); - const pid_t client_pid = connection.GetClientIdentity().pid; - return static_cast(client_pid); - }; - auto disconnect_callback = [this](score::message_passing::IServerConnection& /*connection*/) noexcept { - this->RequestInternalShutdown(); - }; - auto received_send_message_callback = [this]( - score::message_passing::IServerConnection& /*connection*/, - const score::cpp::span /*message*/) noexcept -> score::cpp::blank { - this->OnAcquireRequest(); - return {}; - }; - auto received_send_message_with_reply_callback = - [](score::message_passing::IServerConnection& /*connection*/, - score::cpp::span /*message*/) noexcept -> score::cpp::blank { - return {}; - }; - - const auto result = receiver_->StartListening(connect_callback, - disconnect_callback, - received_send_message_callback, - received_send_message_with_reply_callback); - + const auto result = receiver_->StartListening(); if (result.has_value() == false) { const std::string underlying_error = result.error().ToString(); @@ -247,6 +231,7 @@ void DatarouterMessageClientImpl::RequestInternalShutdown() noexcept UnlinkSharedMemoryFile(); std::ignore = stop_source_.request_stop(); + thread_pool_.Shutdown(); } void DatarouterMessageClientImpl::CheckExitRequestAndSendConnectMessage() noexcept @@ -270,18 +255,28 @@ void DatarouterMessageClientImpl::SendConnectMessage() noexcept if (use_dynamic_datarouter_ids_ && (writer_file_name_.size() > - (MessagePassingConfig::kRandomFilenameStartIndex + msg.GetRandomPart().size() + static_cast(1)))) + (kStartIndexOfRandomFileName + msg.GetRandomPart().size() + static_cast(1)))) { auto start_iter = writer_file_name_.begin(); - std::advance(start_iter, static_cast(MessagePassingConfig::kRandomFilenameStartIndex)); + std::advance(start_iter, static_cast(kStartIndexOfRandomFileName)); auto random_part = msg.GetRandomPart(); std::ignore = std::copy_n(start_iter, random_part.size(), random_part.begin()); msg.SetRandomPart(random_part); } - const auto message = SerializeMessage(DatarouterMessageIdentifier::kConnect, msg); - - SendMessage(message); + score::mw::com::message_passing::MediumMessagePayload payload{}; + static_assert(sizeof(msg) <= payload.size(), "Connect message too large"); + static_assert(std::is_trivially_copyable::value, "Message must be copyable"); + // Suppress "AUTOSAR C++14 M5-2-8" rule. The rule declares: + // An object with integer type or pointer to void type shall not be converted to an object with pointer type. + // But we need to convert void pointer to bytes for serialization purposes, no out of bounds there + // coverity[autosar_cpp14_m5_2_8_violation] + const score::cpp::span message_span{static_cast(static_cast(&msg)), + sizeof(msg)}; + // coverity[autosar_cpp14_m5_0_16_violation:FALSE] + std::ignore = std::copy(message_span.begin(), message_span.end(), payload.begin()); + + SendMessage(BuildMessage(DatarouterMessageIdentifier::kConnect, payload)); } void DatarouterMessageClientImpl::Shutdown() noexcept @@ -291,52 +286,35 @@ void DatarouterMessageClientImpl::Shutdown() noexcept std::this_thread::sleep_for(std::chrono::milliseconds(100)); } std::ignore = stop_source_.request_stop(); - // Notify waiting threads in case they are waiting for state change - state_condition_.notify_all(); - - // Request the jthread to stop and wait for it to finish - if (connect_thread_.joinable()) + thread_pool_.Shutdown(); + if (connect_task_.Valid() == true) { - connect_thread_.request_stop(); - connect_thread_.join(); + connect_task_.Abort(); + std::ignore = connect_task_.Wait(); } - receiver_.reset(); - { - std::unique_lock lock(sender_mutex_); - sender_.reset(); - } + sender_.reset(); // Block until all pending tasks and threads have finished. UnlinkSharedMemoryFile(); } -score::cpp::expected_blank DatarouterMessageClientImpl::CreateSender() noexcept +void DatarouterMessageClientImpl::CreateSender() noexcept { - const score::message_passing::ServiceProtocolConfig& protocol_config{ - MessagePassingConfig::kDatarouterReceiverIdentifier, - MessagePassingConfig::kMaxMessageSize, - MessagePassingConfig::kMaxReplySize, - MessagePassingConfig::kMaxNotifySize}; - const score::message_passing::IClientFactory::ClientConfig& client_config{0, 10, false, true, false}; - sender_ = message_passing_factory_->CreateClient(protocol_config, client_config); - - if (sender_ == nullptr) - { - std::cerr << "[[mw::log]] Application (PID: " << msg_client_ids_.GetThisProcID() - << ") failed to create Message Passing Client." << '\n'; - return score::cpp::make_unexpected(score::os::Error::createFromErrno(ENOMEM)); - } - - auto state_callback = [this](score::message_passing::IClientConnection::State state) noexcept { - { - std::lock_guard callback_lock(sender_state_change_mutex_); - sender_state_ = state; - } - state_condition_.notify_all(); - }; - - sender_->Start(state_callback, score::message_passing::IClientConnection::NotifyCallback{}); - return {}; + // We are not using the stop token from the current task, because the sender shall be used even after the + // current task exited. The connect task thus can only be stopped if the stop_source_ is triggered. + const score::mw::com::message_passing::SenderConfig sender_config{ + kSenderMaxNumberOfSendRetries, kSenderRetrySendDelay, kSenderRetryConnectDelay}; + constexpr std::string_view kDatarouterReceiverIdentifier{"/logging.datarouter_recv"}; + sender_ = message_passing_factory_->CreateSender(kDatarouterReceiverIdentifier, + stop_source_.get_token(), + sender_config, + &SenderLoggerCallback, + &monotonic_resource_); + + // The creation of the sender is blocking until Datarouter is available. + // Thus at this point, either Datarouter was available, or the stop_source_ was triggered. + // The Sender interface currently does not expose the information if the Sender could be connected successfully to a + // receiver. } void DatarouterMessageClientImpl::OnAcquireRequest() noexcept @@ -346,9 +324,19 @@ void DatarouterMessageClientImpl::OnAcquireRequest() noexcept // Acquire data and prepare the response. const auto acquire_result = shared_memory_writer_.ReadAcquire(); - const auto message = SerializeMessage(DatarouterMessageIdentifier::kAcquireResponse, acquire_result); - - SendMessage(message); + // TODO: Use ShortMessagePayload instead: + score::mw::com::message_passing::MediumMessagePayload payload{}; + static_assert(sizeof(payload) >= sizeof(acquire_result), "payload shall be large enough"); + const score::cpp::span acquire_result_span{ + // Suppress "AUTOSAR C++14 M5-2-8" rule. The rule declares: + // An object with integer type or pointer to void type shall not be converted to an object with pointer type. + // But we need to convert void pointer to bytes for serialization purposes, no out of bounds there + // coverity[autosar_cpp14_m5_2_8_violation] + static_cast(static_cast(&acquire_result)), + sizeof(acquire_result)}; + // coverity[autosar_cpp14_m5_0_16_violation:FALSE] + std::ignore = std::copy(acquire_result_span.begin(), acquire_result_span.end(), payload.begin()); + SendMessage(BuildMessage(DatarouterMessageIdentifier::kAcquireResponse, payload)); } void DatarouterMessageClientImpl::HandleFirstMessageReceived() noexcept @@ -362,22 +350,15 @@ void DatarouterMessageClientImpl::HandleFirstMessageReceived() noexcept UnlinkSharedMemoryFile(); } -void DatarouterMessageClientImpl::SendMessage(const score::cpp::span& message) noexcept +template +void DatarouterMessageClientImpl::SendMessage(const Message& message) noexcept { - score::cpp::expected_blank result; - { - std::unique_lock lock(sender_mutex_); - if (sender_ != nullptr) - { - result = sender_->Send(message); - } - } + auto result = sender_->Send(message); if (result.has_value() == false) { // The sender will retry sending the message for 10 s (retry_delay * number_of_retries). // If sending the message does not succeed despite all retries we assume Datarouter has crashed or is hanging // and consequently shutdown the logging in the client. - // Send() already checks if the sender is in kReady state and returns EINVAL if not. const auto error_details = result.error().ToStringContainer(result.error()); ReportInitializationError(score::mw::log::detail::Error::kFailedToSendMessageToDatarouter, @@ -388,6 +369,15 @@ void DatarouterMessageClientImpl::SendMessage(const score::cpp::span( + id, payload, msg_client_ids_.GetThisProcID()); +} + void DatarouterMessageClientImpl::UnlinkSharedMemoryFile() noexcept { if (unlinked_shared_memory_file_) diff --git a/score/mw/log/detail/data_router/data_router_message_client_impl.h b/score/mw/log/detail/data_router/data_router_message_client_impl.h index 6d8ba66..4dabb37 100644 --- a/score/mw/log/detail/data_router/data_router_message_client_impl.h +++ b/score/mw/log/detail/data_router/data_router_message_client_impl.h @@ -14,21 +14,16 @@ #ifndef SCORE_MW_LOG_DETAIL_DATA_ROUTER_MESSAGE_CLIENT_IMPL_H #define SCORE_MW_LOG_DETAIL_DATA_ROUTER_MESSAGE_CLIENT_IMPL_H -#include "score/expected.hpp" -#include "score/jthread.hpp" #include "score/optional.hpp" -#include "score/stop_token.hpp" -#include "score/message_passing/i_server_connection.h" -#include "score/os/errno.h" +#include "score/concurrency/thread_pool.h" +#include "score/mw/com/message_passing/i_receiver.h" +#include "score/mw/com/message_passing/i_sender.h" #include "score/mw/log/detail/data_router/data_router_message_client.h" #include "score/mw/log/detail/data_router/data_router_message_client_backend.h" #include "score/mw/log/detail/data_router/data_router_message_client_identifiers.h" #include "score/mw/log/detail/data_router/data_router_message_client_utils.h" #include "score/mw/log/detail/data_router/data_router_messages.h" -#include -#include - namespace score { namespace mw @@ -49,8 +44,10 @@ constexpr std::size_t GetMonotonicResourceSize() noexcept /// Remarks on thread safety: /// The methods of the parent interface are not thread safe. /// The Shutdown() method must only be called after the Run() method. -/// After calling Run() there shall be a single background thread -/// that delivers callbacks to the On*Request() methods. +/// After calling Run() there shall be a single thread in the thread pool +/// that delivers callbacks to the On*Request() methods. Since the thread +/// pool only contains a single thread no additional internal synchronization +/// mutex is necessary. class DatarouterMessageClientImpl : public DatarouterMessageClient { public: @@ -71,10 +68,7 @@ class DatarouterMessageClientImpl : public DatarouterMessageClient void Shutdown() noexcept override; void SetupReceiver() noexcept; - - /// \brief Creates the message passing client (sender) for communication with Datarouter. - /// \returns An empty expected on success, or an error if the sender could not be created. - score::cpp::expected_blank CreateSender() noexcept; + void CreateSender() noexcept; /// \pre SetupReceiver and CreateSender() called before. /// \returns true if the receiver was started successfully. @@ -104,7 +98,12 @@ class DatarouterMessageClientImpl : public DatarouterMessageClient void RequestInternalShutdown() noexcept; void CheckExitRequestAndSendConnectMessage() noexcept; - void SendMessage(const score::cpp::span& message) noexcept; + score::mw::com::message_passing::MediumMessage BuildMessage( + const DatarouterMessageIdentifier& id, + const score::mw::com::message_passing::MediumMessagePayload& payload) const noexcept; + + template + void SendMessage(const Message& message) noexcept; bool run_started_; @@ -121,23 +120,22 @@ class DatarouterMessageClientImpl : public DatarouterMessageClient std::string writer_file_name_; std::unique_ptr message_passing_factory_; + std::array monotonic_resource_buffer_; + score::cpp::pmr::monotonic_buffer_resource monotonic_resource_; score::cpp::stop_source stop_source_; - mutable std::mutex sender_state_change_mutex_; - mutable std::mutex sender_mutex_; - std::condition_variable state_condition_; - score::cpp::optional sender_state_; + score::concurrency::ThreadPool thread_pool_; // The construction/destruction order is critical here! // Sender and receiver both may contain running tasks. // Receiver tasks (callbacks) may use the sender. - // Thus the receiver needs to destruct first, and then the sender. - // Finally it is safe to join the connect thread. + // Thus the receiver needs to destruct first, and then the receiver. + // Finally it is safe to destroy the thread pool. // Only then we can ensure that there are no concurrent tasks // accessing private data from another thread. - score::cpp::pmr::unique_ptr sender_; - score::cpp::pmr::unique_ptr receiver_; - score::cpp::jthread connect_thread_; + score::cpp::pmr::unique_ptr sender_; + score::cpp::pmr::unique_ptr receiver_; + score::concurrency::TaskResult connect_task_; }; } // namespace detail diff --git a/score/mw/log/detail/data_router/data_router_message_client_test.cpp b/score/mw/log/detail/data_router/data_router_message_client_test.cpp index 250830e..9c6df03 100644 --- a/score/mw/log/detail/data_router/data_router_message_client_test.cpp +++ b/score/mw/log/detail/data_router/data_router_message_client_test.cpp @@ -12,20 +12,17 @@ ********************************************************************************/ #include "score/assert_support.hpp" -#include "score/message_passing/mock/client_connection_mock.h" -#include "score/message_passing/mock/server_connection_mock.h" -#include "score/message_passing/mock/server_mock.h" -#include "score/message_passing/server_types.h" #include "score/os/mocklib/mock_pthread.h" #include "score/os/mocklib/unistdmock.h" #include "score/os/utils/mocklib/signalmock.h" +#include "score/mw/com/message_passing/receiver_mock.h" +#include "score/mw/com/message_passing/sender_mock.h" #include "score/mw/log/detail/data_router/data_router_message_client_impl.h" #include "score/mw/log/detail/data_router/message_passing_factory_mock.h" #include "gmock/gmock.h" #include "gtest/gtest.h" -#include -#include + namespace score { namespace mw @@ -46,39 +43,9 @@ using ::testing::Return; using ::testing::ReturnRef; using ::testing::StrEq; -MATCHER_P(CompareServiceProtocol, expected, "") -{ - if (arg.identifier != expected.identifier || arg.max_send_size != expected.max_send_size || - arg.max_reply_size != expected.max_reply_size || arg.max_notify_size != expected.max_notify_size) - { - - return false; - } - return true; -} - -MATCHER_P(CompareServerConfig, expected, "") -{ - if (arg.max_queued_sends != expected.max_queued_sends || - arg.pre_alloc_connections != expected.pre_alloc_connections || - arg.max_queued_notifies != expected.max_queued_notifies) - { - return false; - } - return true; -} - -MATCHER_P(CompareClientConfig, expected, "") -{ - if (arg.max_async_replies != expected.max_async_replies || arg.max_queued_sends != expected.max_queued_sends || - arg.fully_ordered != expected.fully_ordered || arg.truly_async != expected.truly_async) - { - return false; - } - return true; -} - const std::string_view kDatarouterReceiverIdentifier{"/logging.datarouter_recv"}; +const auto kAcquireRequestPayload = 0u; // Arbitrary value since payload is ignored. +const auto kDatarouterPid = 324u; const std::string kClientReceiverIdentifier = "/logging.app.1234"; const auto kMwsrFileName = "/tmp" + kClientReceiverIdentifier + ".shmem"; const auto kAppid = LoggingIdentifier{"TeAp"}; @@ -88,8 +55,6 @@ const pid_t kThisProcessPid = 99u; constexpr pthread_t kThreadId = 42; constexpr auto kLoggerThreadName = "logger"; constexpr uid_t datarouter_dummy_uid = 111; -constexpr std::uint32_t kMaxSendBytes{17U}; -constexpr std::uint32_t kMaxNumberMessagesInReceiverQueue{0UL}; class DatarouterMessageClientFixture : public ::testing::Test { @@ -109,7 +74,7 @@ class DatarouterMessageClientFixture : public ::testing::Test unistd_mock_ = unistd_mock.get(); auto pthread_mock = score::cpp::pmr::make_unique>(memory_resource); pthread_mock_ = pthread_mock.get(); - auto signal_mock = score::cpp::pmr::make_unique(memory_resource); + auto signal_mock = score::cpp::pmr::make_unique>(memory_resource); signal_mock_ = signal_mock.get(); auto message_passing_factory = std::make_unique>(); message_passing_factory_ = message_passing_factory.get(); @@ -153,120 +118,78 @@ class DatarouterMessageClientFixture : public ::testing::Test .WillOnce(Return(score::cpp::make_unexpected(score::os::Error::createUnspecifiedError()))); } - score::message_passing::ServerMock* ExpectReceiverCreated() + score::mw::com::message_passing::ReceiverMock* ExpectReceiverCreated() { - auto receiver = score::cpp::pmr::make_unique>( + auto receiver = score::cpp::pmr::make_unique>( score::cpp::pmr::get_default_resource()); auto receiver_ptr = receiver.get(); - const score::message_passing::ServiceProtocolConfig service_protocol_config{ - kClientReceiverIdentifier, kMaxSendBytes, 0U, 0U}; - - const score::message_passing::IServerFactory::ServerConfig server_config{ - kMaxNumberMessagesInReceiverQueue, 0U, 0U}; EXPECT_CALL(*message_passing_factory_, - CreateServer(CompareServiceProtocol(service_protocol_config), CompareServerConfig(server_config))) + CreateReceiver(Eq(std::string_view{kClientReceiverIdentifier}), _, _, _, _)) .WillOnce(Return(ByMove(std::move(receiver)))); return receiver_ptr; } - void ExpectReceiverStartListening( - score::message_passing::ServerMock* receiver_ptr, - score::message_passing::ConnectCallback* connect_callback = nullptr, - score::message_passing::DisconnectCallback* disconnect_callback = nullptr, - score::message_passing::MessageCallback* sent_callback = nullptr, - score::message_passing::MessageCallback* sent_with_reply_callback = nullptr, - score::cpp::expected_blank result = score::cpp::expected_blank{}) + void ExpectReceiverRegisterCallbacks( + score::mw::com::message_passing::ReceiverMock* receiver_ptr, + score::mw::com::message_passing::IReceiver::ShortMessageReceivedCallback* acquire_callback = nullptr) { EXPECT_CALL(*receiver_ptr, - StartListening(Matcher(_), - Matcher(_), - Matcher(_), - Matcher(_))) - .WillOnce([connect_callback, disconnect_callback, sent_callback, sent_with_reply_callback, result]( - score::message_passing::ConnectCallback con_callback, - score::message_passing::DisconnectCallback discon_callback, - score::message_passing::MessageCallback sn_callback, - score::message_passing::MessageCallback sn_rep_callback) { - if (connect_callback != nullptr) - { - *connect_callback = std::move(con_callback); - } - if (disconnect_callback != nullptr) - { - *disconnect_callback = std::move(discon_callback); - } - if (sent_callback != nullptr) - { - *sent_callback = std::move(sn_callback); - } - if (sent_with_reply_callback != nullptr) - { - *sent_with_reply_callback = std::move(sn_rep_callback); - } - return result; - }); + Register(static_cast(DatarouterMessageIdentifier::kAcquireRequest), + Matcher(_))) + .WillOnce( + [acquire_callback](std::int8_t, + score::mw::com::message_passing::IReceiver::ShortMessageReceivedCallback callback) { + if (acquire_callback != nullptr) + { + *acquire_callback = std::move(callback); + } + }); } - score::message_passing::ClientConnectionMock* ExpectSenderCreation( - score::message_passing::IClientConnection::StateCallback* state_callback = nullptr, - std::promise* callback_registered = nullptr) + void ExpectReceiverStartListening( + score::mw::com::message_passing::ReceiverMock* receiver_ptr, + score::cpp::expected_blank result = score::cpp::expected_blank{}) { - sender_mock_in_transit_ = - score::cpp::pmr::make_unique>( - score::cpp::pmr::get_default_resource()); - auto sender_mock = sender_mock_in_transit_.get(); - const score::message_passing::ServiceProtocolConfig service_protocol_config{ - kDatarouterReceiverIdentifier, kMaxSendBytes, 0U, 0U}; - - const score::message_passing::IClientFactory::ClientConfig& client_config{0, 10, false, true, false}; - - EXPECT_CALL(*message_passing_factory_, - CreateClient(CompareServiceProtocol(service_protocol_config), CompareClientConfig(client_config))) - .WillOnce(Return(ByMove(std::move(sender_mock_in_transit_)))); - - EXPECT_CALL(*sender_mock, - Start(Matcher(_), - Matcher(_))) - .WillOnce([state_callback, callback_registered]( - score::message_passing::IClientConnection::StateCallback st_callback, - score::message_passing::IClientConnection::NotifyCallback) { - if (state_callback != nullptr) - { - *state_callback = std::move(st_callback); - } - if (callback_registered != nullptr) - { - callback_registered->set_value(); - } - }); - - return sender_mock; + EXPECT_CALL(*receiver_ptr, StartListening()).WillOnce(Return(result)); } - void ExpectClientDestruction(score::message_passing::ClientConnectionMock* sender_mock) + score::mw::com::message_passing::SenderMock* ExpectSenderCreation() { - EXPECT_CALL(*sender_mock, Destruct()); + // We need to implicitly transfer the ownership to the callback via the class member. + // Necessary workaround because mutable&move capture callbacks are not accepted by gmock. + // Since the callback should be called exactly once there are no memory errors. + // If the code violates the expectation, the sanitizers and valgrind will detect memory errors. + sender_mock_in_transit_ = score::cpp::pmr::make_unique>( + score::cpp::pmr::get_default_resource()); + auto callback = [this](const std::string_view, + const score::cpp::stop_token&, + const score::mw::com::message_passing::SenderConfig&, + score::mw::com::message_passing::LoggingCallback log_callback, + score::cpp::pmr::memory_resource* /*resource*/) + -> score::cpp::pmr::unique_ptr { + log_callback([](std::ostream&) { + FAIL() << "expected to drop the logs"; + }); + return std::move(sender_mock_in_transit_); + }; + EXPECT_CALL(*message_passing_factory_, CreateSender(Eq(kDatarouterReceiverIdentifier), _, _, _, _)) + .WillOnce(callback); + return sender_mock_in_transit_.get(); } - void ExpectServerDestruction(score::message_passing::ServerMock* receiver_mock) - { - EXPECT_CALL(*receiver_mock, Destruct()); - } - void ExpectSendAcquireResponse(score::message_passing::ClientConnectionMock* sender_ptr, + void ExpectSendAcquireResponse(score::mw::com::message_passing::SenderMock* sender_ptr, ReadAcquireResult expected_content, score::cpp::expected_blank result = score::cpp::expected_blank{}) { - EXPECT_CALL(*sender_ptr, Send(Matcher>(_))) - .WillOnce( - [expected_content, result](score::cpp::span msg) -> score::cpp::expected_blank { - EXPECT_EQ(msg.front(), score::cpp::to_underlying(DatarouterMessageIdentifier::kAcquireResponse)); - ReadAcquireResult data; - const auto payload = msg.subspan(1); - - memcpy(&data, payload.data(), sizeof(data)); - EXPECT_EQ(data.acquired_buffer, expected_content.acquired_buffer); - return result; - }); + EXPECT_CALL(*sender_ptr, Send(Matcher(_))) + .WillOnce([expected_content, result](const score::mw::com::message_passing::MediumMessage& msg) + -> score::cpp::expected_blank { + EXPECT_EQ(msg.id, ToMessageId(DatarouterMessageIdentifier::kAcquireResponse)); + ReadAcquireResult data; + memcpy(&data, msg.payload.data(), sizeof(data)); + EXPECT_EQ(data.acquired_buffer, expected_content.acquired_buffer); + return result; + }); } void ExpectUnlinkMwsrWriterFile(bool unlink_successful = true) @@ -302,10 +225,11 @@ class DatarouterMessageClientFixture : public ::testing::Test }); } - void SendAcquireRequestAndExpectResponse(score::message_passing::MessageCallback& acquire_callback, - score::message_passing::ClientConnectionMock** sender_ptr, - bool first_message, - bool unlink_successful = true) + void SendAcquireRequestAndExpectResponse( + score::mw::com::message_passing::IReceiver::ShortMessageReceivedCallback& acquire_callback, + score::mw::com::message_passing::SenderMock** sender_ptr, + bool first_message, + bool unlink_successful = true) { ReadAcquireResult acquired_data{}; acquired_data.acquired_buffer = shared_data_.control_block.switch_count_points_active_for_writing.load(); @@ -318,32 +242,22 @@ class DatarouterMessageClientFixture : public ::testing::Test ExpectSendAcquireResponse(*sender_ptr, acquired_data); - score::message_passing::ServerConnectionMock connection; - const score::cpp::span message{}; - acquire_callback(connection, message); + acquire_callback(kAcquireRequestPayload, kDatarouterPid); } void ExpectSenderAndReceiverCreation( - score::message_passing::ServerMock** receiver_ptr, - score::message_passing::ClientConnectionMock** sender_ptr, - - score::message_passing::IClientConnection::StateCallback* state_callback = nullptr, - std::promise* callback_registered = nullptr, + score::mw::com::message_passing::ReceiverMock** receiver_ptr = nullptr, + score::mw::com::message_passing::SenderMock** sender_ptr = nullptr, score::cpp::expected_blank listen_result = score::cpp::expected_blank{}, - score::message_passing::ConnectCallback* connect_callback = nullptr, - score::message_passing::DisconnectCallback* disconnect_callback = nullptr, - score::message_passing::MessageCallback* sent_callback = nullptr, - score::message_passing::MessageCallback* sent_with_reply_callback = nullptr, - bool blockTerminationSignalPass = true, - bool receiver_start_listening = true) - + score::mw::com::message_passing::IReceiver::ShortMessageReceivedCallback* acquire_callback = nullptr, + bool blockTerminationSignalPass = true) { - std::ignore = blockTerminationSignalPass; // TODO: remove this param auto receiver = ExpectReceiverCreated(); if (receiver_ptr != nullptr) { *receiver_ptr = receiver; } + ExpectReceiverRegisterCallbacks(receiver, acquire_callback); if (blockTerminationSignalPass) { @@ -356,44 +270,37 @@ class DatarouterMessageClientFixture : public ::testing::Test ExpectSetLoggerThreadName(); - auto sender = ExpectSenderCreation(state_callback, callback_registered); + auto sender = ExpectSenderCreation(); if (sender_ptr != nullptr) { *sender_ptr = sender; } - if (receiver_start_listening) - { - ExpectReceiverStartListening(receiver, - connect_callback, - disconnect_callback, - sent_callback, - sent_with_reply_callback, - listen_result); - } + ExpectReceiverStartListening(receiver, listen_result); } - void ExpectSendConnectMessage(score::message_passing::ClientConnectionMock* sender_ptr) + void ExpectSendConnectMessage(score::mw::com::message_passing::SenderMock* sender_ptr) { - EXPECT_CALL(*sender_ptr, Send(Matcher>(_))) - .WillOnce([this](score::cpp::span msg) -> score::cpp::expected_blank { - EXPECT_EQ(msg.front(), score::cpp::to_underlying(DatarouterMessageIdentifier::kConnect)); - std::array random_part; - if (dynamicDataRouterIdentifiers_ && !mwsrFileName_.empty()) - { - memcpy(random_part.data(), &mwsrFileName_.data()[13], random_part.size()); - } - else - { - random_part = {}; - } - - ConnectMessageFromClient expected_msg(kAppid, kUid, dynamicDataRouterIdentifiers_, random_part); - ConnectMessageFromClient received_msg; - const auto payload = msg.subspan(1); - memcpy(&received_msg, payload.data(), sizeof(ConnectMessageFromClient)); - EXPECT_EQ(expected_msg, received_msg); - return {}; - }); + EXPECT_CALL(*sender_ptr, Send(An())) + .WillOnce( + [this](const score::mw::com::message_passing::MediumMessage& msg) -> score::cpp::expected_blank { + EXPECT_EQ(msg.pid, kThisProcessPid); + EXPECT_EQ(msg.id, ToMessageId(DatarouterMessageIdentifier::kConnect)); + std::array random_part; + if (dynamicDataRouterIdentifiers_ && !mwsrFileName_.empty()) + { + memcpy(random_part.data(), &mwsrFileName_.data()[13], random_part.size()); + } + else + { + random_part = {}; + } + + ConnectMessageFromClient expected_msg(kAppid, kUid, dynamicDataRouterIdentifiers_, random_part); + ConnectMessageFromClient received_msg; + memcpy(&received_msg, msg.payload.data(), sizeof(ConnectMessageFromClient)); + EXPECT_EQ(expected_msg, received_msg); + return {}; + }); } void ExpectSetLoggerThreadName(bool success = true) @@ -407,15 +314,12 @@ class DatarouterMessageClientFixture : public ::testing::Test EXPECT_CALL(*pthread_mock_, setname_np(kThreadId, StrEq(kLoggerThreadName))).WillOnce(Return(setname_result)); } - void ExecuteCreateSenderAndReceiverSequence( - bool expect_receiver_success = true, - score::message_passing::IClientConnection::StateCallback* state_callback = nullptr) + void ExecuteCreateSenderAndReceiverSequence(bool expect_receiver_success = true) { client_->SetupReceiver(); client_->BlockTermSignal(); client_->SetThreadName(); client_->CreateSender(); - (*state_callback)(score::message_passing::IClientConnection::State::kReady); EXPECT_EQ(client_->StartReceiver(), expect_receiver_success); } @@ -423,12 +327,11 @@ class DatarouterMessageClientFixture : public ::testing::Test bool dynamicDataRouterIdentifiers_{kDynamicDataRouterIdentifiers}; std::string mwsrFileName_{kMwsrFileName}; - score::cpp::pmr::unique_ptr> sender_mock_in_transit_; + score::cpp::pmr::unique_ptr> sender_mock_in_transit_; testing::StrictMock* unistd_mock_; testing::StrictMock* pthread_mock_; - // TODO: bring back testing signal calls: - score::os::SignalMock* signal_mock_; + testing::StrictMock* signal_mock_; SharedData shared_data_{}; SharedMemoryWriter shared_memory_writer_{InitializeSharedData(shared_data_), []() noexcept {}}; @@ -454,6 +357,20 @@ class MwsrFileNameEmptyFixture : public DatarouterMessageClientFixture MwsrFileNameEmptyFixture() : DatarouterMessageClientFixture(std::string()) {} }; +TEST_F(DatarouterMessageClientFixture, SetupReceiverShouldRegisterExpectedCallbacks) +{ + RecordProperty("ASIL", "B"); + RecordProperty("Description", + "Verifies that creating a distinct receiver will lead to registering of the proper callbacks."); + RecordProperty("TestType", "Interface test"); + RecordProperty("DerivationTechnique", "Generation and analysis of equivalence classes"); + + testing::InSequence order_matters; + auto receiver = ExpectReceiverCreated(); + ExpectReceiverRegisterCallbacks(receiver); + client_->SetupReceiver(); +} + TEST_F(DatarouterMessageClientFixture, CreateSenderShouldCreateSenderWithExpectedValues) { RecordProperty("ASIL", "B"); @@ -462,8 +379,7 @@ TEST_F(DatarouterMessageClientFixture, CreateSenderShouldCreateSenderWithExpecte RecordProperty("DerivationTechnique", "Generation and analysis of equivalence classes"); testing::InSequence order_matters; - auto sender = ExpectSenderCreation(); - ExpectClientDestruction(sender); + ExpectSenderCreation(); client_->CreateSender(); } @@ -476,15 +392,8 @@ TEST_F(DatarouterMessageClientFixture, StartReceiverShouldStartListenSuccessfull testing::InSequence order_matters; - score::message_passing::ClientConnectionMock* sender_ptr{}; - score::message_passing::ServerMock* receiver_ptr{}; - score::message_passing::IClientConnection::StateCallback state_callback; - - ExpectSenderAndReceiverCreation(&receiver_ptr, &sender_ptr, &state_callback); - - ExpectServerDestruction(receiver_ptr); - ExpectClientDestruction(sender_ptr); - ExecuteCreateSenderAndReceiverSequence(true, &state_callback); + ExpectSenderAndReceiverCreation(); + ExecuteCreateSenderAndReceiverSequence(); } TEST_F(DatarouterMessageClientFixture, StartReceiverWithoutSenderAndReceiverShouldFail) @@ -498,6 +407,7 @@ TEST_F(DatarouterMessageClientFixture, StartReceiverWithoutSenderAndReceiverShou EXPECT_DEATH(client_->StartReceiver(), ""); } + TEST_F(DatarouterMessageClientFixture, ReceiverStartListeningFailsShouldBeHandledGracefully) { RecordProperty("ASIL", "B"); @@ -507,16 +417,10 @@ TEST_F(DatarouterMessageClientFixture, ReceiverStartListeningFailsShouldBeHandle testing::InSequence order_matters; - score::message_passing::ClientConnectionMock* sender_ptr{}; - score::message_passing::ServerMock* receiver_ptr{}; - score::message_passing::IClientConnection::StateCallback state_callback; - auto start_listening_error = score::cpp::make_unexpected(score::os::Error::createFromErrno()); - ExpectSenderAndReceiverCreation(&receiver_ptr, &sender_ptr, &state_callback, nullptr, start_listening_error); + ExpectSenderAndReceiverCreation(nullptr, nullptr, start_listening_error); - ExpectServerDestruction(receiver_ptr); - ExpectClientDestruction(sender_ptr); - ExecuteCreateSenderAndReceiverSequence(false, &state_callback); + ExecuteCreateSenderAndReceiverSequence(false); } TEST_F(DatarouterMessageClientFixture, SendConnectMessageShouldSendExpectedPayload) @@ -526,15 +430,12 @@ TEST_F(DatarouterMessageClientFixture, SendConnectMessageShouldSendExpectedPaylo RecordProperty("TestType", "Interface test"); RecordProperty("DerivationTechnique", "Generation and analysis of equivalence classes"); - score::message_passing::IClientConnection::StateCallback state_callback; testing::InSequence order_matters; - auto sender = ExpectSenderCreation(&state_callback); + auto sender = ExpectSenderCreation(); ExpectSendConnectMessage(sender); - ExpectClientDestruction(sender); client_->CreateSender(); - state_callback(score::message_passing::IClientConnection::State::kReady); client_->SendConnectMessage(); } @@ -546,15 +447,12 @@ TEST_F(DynamicDataRouterIdentifiersFalseFixture, RecordProperty("TestType", "Interface test"); RecordProperty("DerivationTechnique", "Generation and analysis of equivalence classes"); - score::message_passing::IClientConnection::StateCallback state_callback; testing::InSequence order_matters; - auto sender = ExpectSenderCreation(&state_callback); + auto sender = ExpectSenderCreation(); ExpectSendConnectMessage(sender); - ExpectClientDestruction(sender); client_->CreateSender(); - state_callback(score::message_passing::IClientConnection::State::kReady); client_->SendConnectMessage(); } @@ -565,15 +463,12 @@ TEST_F(MwsrFileNameEmptyFixture, SendConnectMessageMwsrFileNameEmptyShouldSendEx RecordProperty("TestType", "Interface test"); RecordProperty("DerivationTechnique", "Generation and analysis of equivalence classes"); - score::message_passing::IClientConnection::StateCallback state_callback; testing::InSequence order_matters; - auto sender = ExpectSenderCreation(&state_callback); + auto sender = ExpectSenderCreation(); ExpectSendConnectMessage(sender); - ExpectClientDestruction(sender); client_->CreateSender(); - state_callback(score::message_passing::IClientConnection::State::kReady); client_->SendConnectMessage(); } @@ -583,29 +478,16 @@ TEST_F(DatarouterMessageClientFixture, ConnectToDatarouterShouldSendConnectMessa RecordProperty("Description", "Verifies the ability of sending connect message when connecting to datarouter."); RecordProperty("TestType", "Interface test"); RecordProperty("DerivationTechnique", "Generation and analysis of equivalence classes"); - score::message_passing::IClientConnection::StateCallback state_callback; - std::promise callback_registered; testing::InSequence order_matters; - score::message_passing::ClientConnectionMock* sender_ptr{}; - score::message_passing::ServerMock* receiver_ptr{}; + score::mw::com::message_passing::SenderMock* sender_ptr{}; - ExpectSenderAndReceiverCreation(&receiver_ptr, &sender_ptr, &state_callback, &callback_registered); + ExpectSenderAndReceiverCreation(nullptr, &sender_ptr); ExpectSendConnectMessage(sender_ptr); - ExpectServerDestruction(receiver_ptr); - ExpectClientDestruction(sender_ptr); client_->SetupReceiver(); - // We need to unblock waiting for the connection so we change the state in a separate thread - std::thread connect_thread([this]() noexcept { - client_->ConnectToDatarouter(); - }); - callback_registered.get_future().wait(); - - state_callback(score::message_passing::IClientConnection::State::kReady); - - connect_thread.join(); + client_->ConnectToDatarouter(); } TEST_F(DatarouterMessageClientFixture, ConnectToDatarouterGivenThatReceiverFailedShouldNotSendConnectMessage) @@ -617,31 +499,12 @@ TEST_F(DatarouterMessageClientFixture, ConnectToDatarouterGivenThatReceiverFaile testing::InSequence order_matters; - score::message_passing::ClientConnectionMock* sender_ptr{}; - score::message_passing::ServerMock* receiver_ptr{}; - score::message_passing::IClientConnection::StateCallback state_callback; - std::promise callback_registered; - - ExpectSenderAndReceiverCreation(&receiver_ptr, - &sender_ptr, - &state_callback, - &callback_registered, - score::cpp::make_unexpected(score::os::Error::createFromErrno())); - + ExpectSenderAndReceiverCreation( + nullptr, nullptr, score::cpp::make_unexpected(score::os::Error::createFromErrno())); ExpectUnlinkMwsrWriterFile(); - ExpectServerDestruction(receiver_ptr); - ExpectClientDestruction(sender_ptr); client_->SetupReceiver(); - // We need to unblock waiting for the connection so we change the state in a separate thread - std::thread connect_thread([this]() noexcept { - client_->ConnectToDatarouter(); - }); - - callback_registered.get_future().wait(); - state_callback(score::message_passing::IClientConnection::State::kReady); - - connect_thread.join(); + client_->ConnectToDatarouter(); } TEST_F(DatarouterMessageClientFixture, AcquireRequestShouldSendExpectedAcquireResponse) @@ -653,30 +516,15 @@ TEST_F(DatarouterMessageClientFixture, AcquireRequestShouldSendExpectedAcquireRe testing::InSequence order_matters; - score::message_passing::ClientConnectionMock* sender_ptr{}; - score::message_passing::ServerMock* receiver_ptr{}; - score::message_passing::ConnectCallback connect_callback; - score::message_passing::DisconnectCallback disconnect_callback; - score::message_passing::MessageCallback sent_callback; - score::message_passing::MessageCallback sent_with_reply_callback; - score::message_passing::IClientConnection::StateCallback state_callback; - - ExpectSenderAndReceiverCreation(&receiver_ptr, - &sender_ptr, - &state_callback, - nullptr, - {}, - &connect_callback, - &disconnect_callback, - &sent_callback, - &sent_with_reply_callback); - - ExecuteCreateSenderAndReceiverSequence(true, &state_callback); + score::mw::com::message_passing::SenderMock* sender_ptr{}; + score::mw::com::message_passing::ReceiverMock* receiver_ptr{}; + score::mw::com::message_passing::IReceiver::ShortMessageReceivedCallback acquire_callback; + ExpectSenderAndReceiverCreation(&receiver_ptr, &sender_ptr, {}, &acquire_callback); + + ExecuteCreateSenderAndReceiverSequence(); bool first_message = true; - SendAcquireRequestAndExpectResponse(sent_callback, &sender_ptr, first_message, false); - ExpectServerDestruction(receiver_ptr); - ExpectClientDestruction(sender_ptr); + SendAcquireRequestAndExpectResponse(acquire_callback, &sender_ptr, first_message, false); } TEST_F(DatarouterMessageClientFixture, SecondAcquireRequestShouldNotSetMwsrReader) @@ -688,33 +536,18 @@ TEST_F(DatarouterMessageClientFixture, SecondAcquireRequestShouldNotSetMwsrReade testing::InSequence order_matters; - score::message_passing::ClientConnectionMock* sender_ptr{}; - score::message_passing::ServerMock* receiver_ptr{}; - score::message_passing::ConnectCallback connect_callback; - score::message_passing::DisconnectCallback disconnect_callback; - score::message_passing::MessageCallback sent_callback; - score::message_passing::MessageCallback sent_with_reply_callback; - score::message_passing::IClientConnection::StateCallback state_callback; - - ExpectSenderAndReceiverCreation(&receiver_ptr, - &sender_ptr, - &state_callback, - nullptr, - {}, - &connect_callback, - &disconnect_callback, - &sent_callback, - &sent_with_reply_callback); - - ExecuteCreateSenderAndReceiverSequence(true, &state_callback); + score::mw::com::message_passing::SenderMock* sender_ptr{}; + score::mw::com::message_passing::ReceiverMock* receiver_ptr{}; + score::mw::com::message_passing::IReceiver::ShortMessageReceivedCallback acquire_callback; + ExpectSenderAndReceiverCreation(&receiver_ptr, &sender_ptr, {}, &acquire_callback); + + ExecuteCreateSenderAndReceiverSequence(); bool first_message = true; - SendAcquireRequestAndExpectResponse(sent_callback, &sender_ptr, first_message, false); + SendAcquireRequestAndExpectResponse(acquire_callback, &sender_ptr, first_message, false); first_message = false; - SendAcquireRequestAndExpectResponse(sent_callback, &sender_ptr, first_message); - ExpectServerDestruction(receiver_ptr); - ExpectClientDestruction(sender_ptr); + SendAcquireRequestAndExpectResponse(acquire_callback, &sender_ptr, first_message); } // Refactor to acquire request @@ -727,24 +560,12 @@ TEST_F(DatarouterMessageClientFixture, ClientShouldShutdownAfterFailingToSendMes testing::InSequence order_matters; - score::message_passing::ClientConnectionMock* sender_ptr{}; - score::message_passing::ServerMock* receiver_ptr{}; - score::message_passing::ConnectCallback connect_callback; - score::message_passing::DisconnectCallback disconnect_callback; - score::message_passing::MessageCallback sent_callback; - score::message_passing::MessageCallback sent_with_reply_callback; - score::message_passing::IClientConnection::StateCallback state_callback; - ExpectSenderAndReceiverCreation(&receiver_ptr, - &sender_ptr, - &state_callback, - nullptr, - {}, - &connect_callback, - &disconnect_callback, - &sent_callback, - &sent_with_reply_callback); - - ExecuteCreateSenderAndReceiverSequence(true, &state_callback); + score::mw::com::message_passing::SenderMock* sender_ptr{}; + score::mw::com::message_passing::ReceiverMock* receiver_ptr{}; + score::mw::com::message_passing::IReceiver::ShortMessageReceivedCallback acquire_callback; + ExpectSenderAndReceiverCreation(&receiver_ptr, &sender_ptr, {}, &acquire_callback); + + ExecuteCreateSenderAndReceiverSequence(); auto send_error = score::cpp::make_unexpected(score::os::Error::createFromErrno()); @@ -754,11 +575,7 @@ TEST_F(DatarouterMessageClientFixture, ClientShouldShutdownAfterFailingToSendMes ExpectUnlinkMwsrWriterFile(); ExpectSendAcquireResponse(sender_ptr, result, send_error); - score::message_passing::ServerConnectionMock connection; - const score::cpp::span message{}; - sent_callback(connection, message); - ExpectServerDestruction(receiver_ptr); - ExpectClientDestruction(sender_ptr); + acquire_callback(score::mw::com::message_passing::ShortMessagePayload{}, {}); } TEST_F(DatarouterMessageClientFixture, RunShouldSetupAndConnect) @@ -770,23 +587,11 @@ TEST_F(DatarouterMessageClientFixture, RunShouldSetupAndConnect) testing::InSequence order_matters; - score::message_passing::ClientConnectionMock* sender_ptr{}; - score::message_passing::ServerMock* receiver_ptr{}; - score::message_passing::IClientConnection::StateCallback state_callback; - std::promise callback_registered; - - ExpectSenderAndReceiverCreation(&receiver_ptr, &sender_ptr, &state_callback, &callback_registered); - + score::mw::com::message_passing::SenderMock* sender_ptr{}; + ExpectSenderAndReceiverCreation(nullptr, &sender_ptr); ExpectSendConnectMessage(sender_ptr); - ExpectServerDestruction(receiver_ptr); - ExpectClientDestruction(sender_ptr); ExpectUnlinkMwsrWriterFile(); client_->Run(); - - callback_registered.get_future().wait(); - - state_callback(score::message_passing::IClientConnection::State::kReady); - client_->Shutdown(); } @@ -798,24 +603,13 @@ TEST_F(DatarouterMessageClientFixture, RunShallNotBeCalledMoreThanOnce) RecordProperty("DerivationTechnique", "Generation and analysis of equivalence classes"); testing::InSequence order_matters; - - score::message_passing::ClientConnectionMock* sender_ptr{}; - score::message_passing::ServerMock* receiver_ptr{}; - score::message_passing::IClientConnection::StateCallback state_callback; - std::promise callback_registered; - - ExpectSenderAndReceiverCreation(&receiver_ptr, &sender_ptr, &state_callback, &callback_registered); + score::mw::com::message_passing::SenderMock* sender_ptr{}; + ExpectSenderAndReceiverCreation(nullptr, &sender_ptr); ExpectSendConnectMessage(sender_ptr); - - ExpectServerDestruction(receiver_ptr); - ExpectClientDestruction(sender_ptr); ExpectUnlinkMwsrWriterFile(); client_->Run(); - callback_registered.get_future().wait(); - - state_callback(score::message_passing::IClientConnection::State::kReady); EXPECT_DEATH(client_->Run(), ""); } @@ -855,20 +649,11 @@ TEST_F(DatarouterMessageClientFixture, FailedToChownOwnMsrWriterFileForDataRoute testing::InSequence order_matters; - score::message_passing::ClientConnectionMock* sender_ptr{}; - score::message_passing::ServerMock* receiver_ptr{}; - score::message_passing::IClientConnection::StateCallback state_callback; - std::promise callback_registered; - - ExpectSenderAndReceiverCreation(&receiver_ptr, &sender_ptr, &state_callback, &callback_registered); + score::mw::com::message_passing::SenderMock* sender_ptr{}; + ExpectSenderAndReceiverCreation(nullptr, &sender_ptr); ExpectSendConnectMessage(sender_ptr); - ExpectServerDestruction(receiver_ptr); - ExpectClientDestruction(sender_ptr); ExpectUnlinkMwsrWriterFile(false); client_->Run(); - - callback_registered.get_future().wait(); - state_callback(score::message_passing::IClientConnection::State::kReady); client_->Shutdown(); } @@ -882,24 +667,9 @@ TEST_F(DatarouterMessageClientFixture, GivenExitRequestDuringConnectionShouldNot testing::InSequence order_matters; - score::message_passing::ClientConnectionMock* sender_ptr{}; - score::message_passing::ServerMock* receiver_ptr{}; - - ExpectSenderAndReceiverCreation(&receiver_ptr, - &sender_ptr, - nullptr, - nullptr, - score::cpp::make_unexpected(score::os::Error::createFromErrno()), - nullptr, - nullptr, - nullptr, - nullptr, - true, - false); - + ExpectSenderAndReceiverCreation(); ExpectUnlinkMwsrWriterFile(); - ExpectServerDestruction(receiver_ptr); - ExpectClientDestruction(sender_ptr); + client_->SetupReceiver(); stop_source_.request_stop(); client_->ConnectToDatarouter(); @@ -914,35 +684,12 @@ TEST_F(DatarouterMessageClientFixture, FailedToEmptySignalSet) testing::InSequence order_matters; - score::message_passing::ClientConnectionMock* sender_ptr{}; - score::message_passing::ServerMock* receiver_ptr{}; - score::message_passing::IClientConnection::StateCallback state_callback; - std::promise callback_registered; - - ExpectSenderAndReceiverCreation(&receiver_ptr, - &sender_ptr, - &state_callback, - &callback_registered, - score::cpp::make_unexpected(score::os::Error::createFromErrno()), - nullptr, - nullptr, - nullptr, - nullptr, - false); + ExpectSenderAndReceiverCreation( + nullptr, nullptr, score::cpp::make_unexpected(score::os::Error::createFromErrno()), nullptr, false); ExpectUnlinkMwsrWriterFile(); - ExpectServerDestruction(receiver_ptr); - ExpectClientDestruction(sender_ptr); - client_->SetupReceiver(); - // We need to unblock waiting for the connection so we change the state in a separate thread - std::thread connect_thread([this]() noexcept { - client_->ConnectToDatarouter(); - }); - callback_registered.get_future().wait(); - - state_callback(score::message_passing::IClientConnection::State::kReady); - connect_thread.join(); + client_->ConnectToDatarouter(); } } // namespace diff --git a/score/mw/log/detail/data_router/data_router_messages.cpp b/score/mw/log/detail/data_router/data_router_messages.cpp index 5c5a72b..2de8472 100644 --- a/score/mw/log/detail/data_router/data_router_messages.cpp +++ b/score/mw/log/detail/data_router/data_router_messages.cpp @@ -36,6 +36,11 @@ bool operator!=(const ConnectMessageFromClient& lhs, const ConnectMessageFromCli return !(lhs == rhs); } +score::mw::com::message_passing::MessageId ToMessageId(const DatarouterMessageIdentifier& message_id) noexcept +{ + return static_cast>(message_id); +} + ConnectMessageFromClient::ConnectMessageFromClient(const LoggingIdentifier& appid, uid_t uid, bool use_dynamic_identifier, diff --git a/score/mw/log/detail/data_router/data_router_messages.h b/score/mw/log/detail/data_router/data_router_messages.h index 19fe9c0..de49ca8 100644 --- a/score/mw/log/detail/data_router/data_router_messages.h +++ b/score/mw/log/detail/data_router/data_router_messages.h @@ -14,13 +14,11 @@ #ifndef SCORE_MW_LOG_DETAIL_DATA_ROUTER_MESSAGES_H #define SCORE_MW_LOG_DETAIL_DATA_ROUTER_MESSAGES_H -#include "score/mw/log/detail/logging_identifier.h" +#include "score/mw/com/message_passing/message.h" -#include +#include "score/mw/log/detail/logging_identifier.h" #include -#include -#include namespace score { @@ -31,43 +29,14 @@ namespace log namespace detail { -enum class DatarouterMessageIdentifier : std::uint8_t +enum class DatarouterMessageIdentifier : score::mw::com::message_passing::MessageId { kConnect = 0x00, kAcquireRequest = 0x01, kAcquireResponse = 0x02, }; -/// \brief Returns a pointer to the raw memory of a trivially copyable object as uint8_t*. -/// \tparam T The type of the object. Must be trivially copyable. -/// \param obj The object to get the memory pointer for. -/// \returns A pointer to the object's memory as uint8_t*. -template -constexpr const std::uint8_t* AsBytes(const T& obj) noexcept -{ - static_assert(std::is_trivially_copyable::value, "T must be trivially copyable"); - return static_cast(static_cast(std::addressof(obj))); -} - -/// \brief Serializes a trivially copyable message with a message identifier prefix. -/// \tparam MessageType The type of the message payload. Must be trivially copyable. -/// \param identifier The message identifier to prepend to the serialized data. -/// \param payload The message payload to serialize. -/// \returns A std::array containing the message identifier followed by the serialized payload. -template -constexpr std::array SerializeMessage( - const DatarouterMessageIdentifier identifier, - const MessageType& payload) noexcept -{ - static_assert(std::is_trivially_copyable::value, "MessageType must be trivially copyable"); - - std::array message{}; - message[0] = score::cpp::to_underlying(identifier); - auto destination_iterator = message.begin(); - std::advance(destination_iterator, 1U); - std::ignore = std::copy_n(AsBytes(payload), sizeof(MessageType), destination_iterator); - return message; -} +score::mw::com::message_passing::MessageId ToMessageId(const DatarouterMessageIdentifier& message_id) noexcept; class ConnectMessageFromClient { diff --git a/score/mw/log/detail/data_router/message_passing_config.h b/score/mw/log/detail/data_router/message_passing_config.h deleted file mode 100644 index 7242bd9..0000000 --- a/score/mw/log/detail/data_router/message_passing_config.h +++ /dev/null @@ -1,63 +0,0 @@ -/******************************************************************************** - * Copyright (c) 2025 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_LOG_DETAIL_DATA_ROUTER_MESSAGE_PASSING_CONFIG_H -#define SCORE_MW_LOG_DETAIL_DATA_ROUTER_MESSAGE_PASSING_CONFIG_H - -#include - -namespace score -{ -namespace mw -{ -namespace log -{ -namespace detail -{ - -/// \brief Configuration constants for message passing between DataRouter and logging clients. -struct MessagePassingConfig -{ - /// \brief Maximum message size in bytes (1 byte for message ID + 16 bytes for payload). - static constexpr std::uint32_t kMaxMessageSize{17U}; - - /// \brief Maximum number of messages in receiver queue. - /// \note Value not used at the moment of integration with message passing library. May change in the future. - static constexpr std::uint32_t kMaxReceiverQueueSize{0U}; - - /// \brief Number of pre-allocated connections. - static constexpr std::uint32_t kPreAllocConnections{0U}; - - /// \brief Maximum number of queued notifications. - static constexpr std::uint32_t kMaxQueuedNotifies{0U}; - - /// \brief Maximum reply size in bytes. - static constexpr std::uint32_t kMaxReplySize{0U}; - - /// \brief Maximum notification size in bytes. - static constexpr std::uint32_t kMaxNotifySize{0U}; - - /// \brief The DataRouter receiver endpoint identifier. - static constexpr const char* kDatarouterReceiverIdentifier{"/logging.datarouter_recv"}; - - /// \brief Start index of random filename part in the shared memory file name. - /// \note The file name format is "/logging.shm_XXXXXX" where X is random. - static constexpr std::size_t kRandomFilenameStartIndex{13U}; -}; - -} // namespace detail -} // namespace log -} // namespace mw -} // namespace score - -#endif // SCORE_MW_LOG_DETAIL_DATA_ROUTER_MESSAGE_PASSING_CONFIG_H diff --git a/score/mw/log/detail/data_router/message_passing_factory.h b/score/mw/log/detail/data_router/message_passing_factory.h index c14a4aa..2870cf5 100644 --- a/score/mw/log/detail/data_router/message_passing_factory.h +++ b/score/mw/log/detail/data_router/message_passing_factory.h @@ -15,11 +15,11 @@ #define SCORE_MW_LOG_DETAIL_DATA_ROUTER_MESSAGE_PASSING_FACTORY_H #include "score/span.hpp" -#include "score/message_passing/i_client_connection.h" -#include "score/message_passing/i_client_factory.h" -#include "score/message_passing/i_server.h" -#include "score/message_passing/i_server_factory.h" -#include "score/message_passing/service_protocol_config.h" +#include "score/concurrency/executor.h" +#include "score/mw/com/message_passing/i_receiver.h" +#include "score/mw/com/message_passing/i_sender.h" +#include "score/mw/com/message_passing/receiver_config.h" +#include "score/mw/com/message_passing/sender_config.h" #include #include @@ -43,13 +43,19 @@ class MessagePassingFactory MessagePassingFactory& operator=(const MessagePassingFactory&) = delete; MessagePassingFactory& operator=(MessagePassingFactory&&) = delete; - virtual score::cpp::pmr::unique_ptr CreateServer( - const score::message_passing::ServiceProtocolConfig& protocol_config, - const score::message_passing::IServerFactory::ServerConfig& server_config) = 0; + virtual score::cpp::pmr::unique_ptr CreateReceiver( + const std::string_view identifier, + concurrency::Executor& executor, + const score::cpp::span allowed_user_ids, + const score::mw::com::message_passing::ReceiverConfig& receiver_config, + score::cpp::pmr::memory_resource* memory_resource) = 0; - virtual score::cpp::pmr::unique_ptr CreateClient( - const score::message_passing::ServiceProtocolConfig& protocol_config, - const score::message_passing::IClientFactory::ClientConfig& client_config) = 0; + virtual score::cpp::pmr::unique_ptr CreateSender( + const std::string_view identifier, + const score::cpp::stop_token& token, + const score::mw::com::message_passing::SenderConfig& sender_config, + score::mw::com::message_passing::LoggingCallback callback, + score::cpp::pmr::memory_resource* memory_resource) = 0; }; } // namespace detail diff --git a/score/mw/log/detail/data_router/message_passing_factory_impl.cpp b/score/mw/log/detail/data_router/message_passing_factory_impl.cpp index cf32b98..426ffe2 100644 --- a/score/mw/log/detail/data_router/message_passing_factory_impl.cpp +++ b/score/mw/log/detail/data_router/message_passing_factory_impl.cpp @@ -13,6 +13,9 @@ #include "score/mw/log/detail/data_router/message_passing_factory_impl.h" +#include "score/mw/com/message_passing/receiver_factory_impl.h" +#include "score/mw/com/message_passing/sender_factory_impl.h" + namespace score { namespace mw @@ -22,22 +25,26 @@ namespace log namespace detail { -MessagePassingFactoryImpl::MessagePassingFactoryImpl() : server_factory_{}, client_factory_{server_factory_.GetEngine()} -{ -} - -score::cpp::pmr::unique_ptr MessagePassingFactoryImpl::CreateServer( - const score::message_passing::ServiceProtocolConfig& protocol_config, - const score::message_passing::IServerFactory::ServerConfig& server_config) noexcept +score::cpp::pmr::unique_ptr MessagePassingFactoryImpl::CreateReceiver( + const std::string_view identifier, + concurrency::Executor& executor, + const score::cpp::span allowed_user_ids, + const score::mw::com::message_passing::ReceiverConfig& receiver_config, + score::cpp::pmr::memory_resource* const monotonic_memory_resource) noexcept { - return server_factory_.Create(protocol_config, server_config); + return score::mw::com::message_passing::ReceiverFactoryImpl::Create( + identifier, executor, allowed_user_ids, receiver_config, monotonic_memory_resource); } -score::cpp::pmr::unique_ptr MessagePassingFactoryImpl::CreateClient( - const score::message_passing::ServiceProtocolConfig& protocol_config, - const score::message_passing::IClientFactory::ClientConfig& client_config) noexcept +score::cpp::pmr::unique_ptr MessagePassingFactoryImpl::CreateSender( + const std::string_view identifier, + const score::cpp::stop_token& token, + const score::mw::com::message_passing::SenderConfig& sender_config, + score::mw::com::message_passing::LoggingCallback callback, + score::cpp::pmr::memory_resource* const monotonic_memory_resource) noexcept { - return client_factory_.Create(protocol_config, client_config); + return score::mw::com::message_passing::SenderFactoryImpl::Create( + identifier, token, sender_config, std::move(callback), monotonic_memory_resource); } } // namespace detail diff --git a/score/mw/log/detail/data_router/message_passing_factory_impl.h b/score/mw/log/detail/data_router/message_passing_factory_impl.h index bddcc0d..2f147f1 100644 --- a/score/mw/log/detail/data_router/message_passing_factory_impl.h +++ b/score/mw/log/detail/data_router/message_passing_factory_impl.h @@ -16,20 +16,6 @@ #include "score/mw/log/detail/data_router/message_passing_factory.h" -#include "score/message_passing/i_client_factory.h" -#include "score/message_passing/i_server_factory.h" -#include - -#ifdef __QNX__ -#include "score/message_passing/qnx_dispatch/qnx_dispatch_client_factory.h" -#include "score/message_passing/qnx_dispatch/qnx_dispatch_engine.h" -#include "score/message_passing/qnx_dispatch/qnx_dispatch_server_factory.h" -#else -#include "score/message_passing/unix_domain/unix_domain_client_factory.h" -#include "score/message_passing/unix_domain/unix_domain_engine.h" -#include "score/message_passing/unix_domain/unix_domain_server_factory.h" -#endif - namespace score { namespace mw @@ -39,43 +25,22 @@ namespace log namespace detail { -/* - Deviation from Rule A16-0-1: - - Rule A16-0-1 (required, implementation, automated) - The pre-processor shall only be used for unconditional and conditional file - inclusion and include guards, and using the following directives: (1) #ifndef, - #ifdef, (3) #if, (4) #if defined, (5) #elif, (6) #else, (7) #define, (8) #endif, (9) - #include. - Justification: - - Feature Flag to enable/disable Logging Modes in Production SW. - */ -// coverity[autosar_cpp14_a16_0_1_violation] see above -#ifdef __QNX__ -using ServerFactory = score::message_passing::QnxDispatchServerFactory; -using ClientFactory = score::message_passing::QnxDispatchClientFactory; -// coverity[autosar_cpp14_a16_0_1_violation] see above -#else -using ServerFactory = score::message_passing::UnixDomainServerFactory; -using ClientFactory = score::message_passing::UnixDomainClientFactory; -// coverity[autosar_cpp14_a16_0_1_violation] see above -#endif - class MessagePassingFactoryImpl : public MessagePassingFactory { public: - explicit MessagePassingFactoryImpl(); - - score::cpp::pmr::unique_ptr CreateServer( - const score::message_passing::ServiceProtocolConfig& protocol_config, - const score::message_passing::IServerFactory::ServerConfig& server_config) noexcept override; - - score::cpp::pmr::unique_ptr CreateClient( - const score::message_passing::ServiceProtocolConfig& protocol_config, - const score::message_passing::IClientFactory::ClientConfig& client_config) noexcept override; - - private: - ServerFactory server_factory_; - ClientFactory client_factory_; + score::cpp::pmr::unique_ptr CreateReceiver( + const std::string_view identifier, + concurrency::Executor& executor, + const score::cpp::span allowed_user_ids, + const score::mw::com::message_passing::ReceiverConfig& receiver_config, + score::cpp::pmr::memory_resource* const monotonic_memory_resource) noexcept override; + + score::cpp::pmr::unique_ptr CreateSender( + const std::string_view identifier, + const score::cpp::stop_token& token, + const score::mw::com::message_passing::SenderConfig& sender_config, + score::mw::com::message_passing::LoggingCallback callback, + score::cpp::pmr::memory_resource* const monotonic_memory_resource) noexcept override; }; } // namespace detail diff --git a/score/mw/log/detail/data_router/message_passing_factory_mock.h b/score/mw/log/detail/data_router/message_passing_factory_mock.h index 748bf13..18344bd 100644 --- a/score/mw/log/detail/data_router/message_passing_factory_mock.h +++ b/score/mw/log/detail/data_router/message_passing_factory_mock.h @@ -30,16 +30,22 @@ namespace detail class MessagePassingFactoryMock : public MessagePassingFactory { public: - MOCK_METHOD((score::cpp::pmr::unique_ptr), - CreateServer, - (const score::message_passing::ServiceProtocolConfig& protocol_config, - const score::message_passing::IServerFactory::ServerConfig& server_config), + MOCK_METHOD((score::cpp::pmr::unique_ptr), + CreateReceiver, + (const std::string_view, + concurrency::Executor&, + const score::cpp::span, + const score::mw::com::message_passing::ReceiverConfig&, + score::cpp::pmr::memory_resource*), (override)); - MOCK_METHOD((score::cpp::pmr::unique_ptr), - CreateClient, - (const score::message_passing::ServiceProtocolConfig& protocol_config, - const score::message_passing::IClientFactory::ClientConfig& client_config), + MOCK_METHOD((score::cpp::pmr::unique_ptr), + CreateSender, + (const std::string_view identifier, + const score::cpp::stop_token& token, + const score::mw::com::message_passing::SenderConfig& sender_config, + score::mw::com::message_passing::LoggingCallback callback, + score::cpp::pmr::memory_resource* memory_resource), (override)); }; diff --git a/score/mw/log/detail/data_router/message_passing_factory_test.cpp b/score/mw/log/detail/data_router/message_passing_factory_test.cpp index ae4daa8..0b1377d 100644 --- a/score/mw/log/detail/data_router/message_passing_factory_test.cpp +++ b/score/mw/log/detail/data_router/message_passing_factory_test.cpp @@ -39,10 +39,9 @@ TEST(MessagePassingFactoryTests, CreateReceiverShouldReturnValue) MessagePassingFactoryImpl factory{}; score::concurrency::ThreadPool thread_pool{2}; - const score::message_passing::ServiceProtocolConfig service_protocol_config{}; - - const score::message_passing::IServerFactory::ServerConfig server_config{}; - auto receiver = factory.CreateServer(service_protocol_config, server_config); + score::mw::com::message_passing::ReceiverConfig receiver_config{}; + auto receiver = + factory.CreateReceiver(kIdentifier, thread_pool, {}, receiver_config, score::cpp::pmr::get_default_resource()); EXPECT_NE(receiver, nullptr); } @@ -55,10 +54,14 @@ TEST(MessagePassingFactoryTests, CreateSenderShouldReturnValue) MessagePassingFactoryImpl factory{}; - const score::message_passing::ServiceProtocolConfig& protocol_config{kIdentifier, 9U, 0U, 0U}; - const score::message_passing::IClientFactory::ClientConfig& client_config{0, 0, false, false, false}; - - auto sender = factory.CreateClient(protocol_config, client_config); + score::cpp::stop_source s{}; + s.request_stop(); + const score::mw::com::message_passing::SenderConfig sender_config{}; + auto sender = factory.CreateSender(kIdentifier, + s.get_token(), + sender_config, + &score::mw::com::message_passing::DefaultLoggingCallback, + score::cpp::pmr::get_default_resource()); EXPECT_NE(sender, nullptr); } diff --git a/score/mw/log/detail/flags/BUILD b/score/mw/log/detail/flags/BUILD index 22b7be9..9005aee 100644 --- a/score/mw/log/detail/flags/BUILD +++ b/score/mw/log/detail/flags/BUILD @@ -44,3 +44,19 @@ config_setting( "@score_baselibs//score/mw/log:__subpackages__", ], ) + +bool_flag( + name = "KUse_Stub_Implementation_Only", + build_setting_default = False, +) + +config_setting( + name = "config_KUse_Stub_Implementation_Only", + flag_values = { + ":KUse_Stub_Implementation_Only": "True", + }, + visibility = [ + "//score/mw/log:__subpackages__", + "@score_baselibs//score/mw/log:__subpackages__", + ], +) diff --git a/score/mw/log/detail/utils/signal_handling/BUILD b/score/mw/log/detail/utils/signal_handling/BUILD deleted file mode 100644 index 43d75fe..0000000 --- a/score/mw/log/detail/utils/signal_handling/BUILD +++ /dev/null @@ -1,37 +0,0 @@ -# ******************************************************************************* -# Copyright (c) 2025 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 -# ******************************************************************************* - -COMPILER_WARNING_FEATURES = [ - "treat_warnings_as_errors", - "additional_warnings", - "strict_warnings", -] - -cc_library( - name = "signal_handling", - srcs = [ - "signal_handling.cpp", - ], - hdrs = [ - "signal_handling.h", - ], - features = COMPILER_WARNING_FEATURES, - tags = ["FFI"], - visibility = [ - "//score/mw/log:__subpackages__", - "@score_baselibs//score/mw/log:__subpackages__", - ], - deps = [ - "@score_baselibs//score/os/utils:signal", - ], -) diff --git a/score/mw/log/detail/utils/signal_handling/signal_handling.cpp b/score/mw/log/detail/utils/signal_handling/signal_handling.cpp deleted file mode 100644 index e23e1f6..0000000 --- a/score/mw/log/detail/utils/signal_handling/signal_handling.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/******************************************************************************** - * Copyright (c) 2025 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/log/detail/utils/signal_handling/signal_handling.h" - -namespace score::mw::log::detail -{ - -score::cpp::expected SignalHandling::PThreadBlockSigTerm(score::os::Signal& signal) noexcept -{ - sigset_t sig_set; - - score::cpp::expected return_error_result{}; - auto result = signal.SigEmptySet(sig_set); - if (result.has_value()) - { - // signal handling is tolerated by design. Argumentation: Ticket-101432 - // coverity[autosar_cpp14_m18_7_1_violation] - result = signal.SigAddSet(sig_set, SIGTERM); - if (result.has_value()) - { - /* NOLINTNEXTLINE(score-banned-function) using PthreadSigMask by design. Argumentation: Ticket-101432 */ - result = signal.PthreadSigMask(SIG_BLOCK, sig_set); - } - } - return result; -} - -score::cpp::expected SignalHandling::PThreadUnblockSigTerm(score::os::Signal& signal) noexcept -{ - sigset_t sig_set; - - score::cpp::expected return_error_result{}; - auto result = signal.SigEmptySet(sig_set); - if (result.has_value()) - { - // signal handling is tolerated by design. Argumentation: Ticket-101432 - // coverity[autosar_cpp14_m18_7_1_violation] - result = signal.SigAddSet(sig_set, SIGTERM); - if (result.has_value()) - { - /* NOLINTNEXTLINE(score-banned-function) using PthreadSigMask by design. Argumentation: Ticket-101432 */ - result = signal.PthreadSigMask(SIG_UNBLOCK, sig_set); - } - } - return result; -} - -} // namespace score::mw::log::detail diff --git a/score/mw/log/detail/utils/signal_handling/signal_handling.h b/score/mw/log/detail/utils/signal_handling/signal_handling.h deleted file mode 100644 index f53276a..0000000 --- a/score/mw/log/detail/utils/signal_handling/signal_handling.h +++ /dev/null @@ -1,58 +0,0 @@ -/******************************************************************************** - * Copyright (c) 2025 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_LOG_DETAIL_UTILS_SIGNAL_HANDLING_SIGNAL_HANDLING_H_ -#define SCORE_MW_LOG_DETAIL_UTILS_SIGNAL_HANDLING_SIGNAL_HANDLING_H_ - -#include "score/os/utils/signal.h" - -namespace score::mw::log::detail -{ - -class SignalHandling -{ - public: - /// \brief Blocks the SIGTERM signal for the current thread. - /// \param signal The signal interface to use for blocking. - /// \returns The result of the pthread_sigmask call, or an error if the operation failed. - static score::cpp::expected PThreadBlockSigTerm(score::os::Signal& signal) noexcept; - - /// \brief Unblocks the SIGTERM signal for the current thread. - /// \param signal The signal interface to use for unblocking. - /// \returns The result of the pthread_sigmask call, or an error if the operation failed. - static score::cpp::expected PThreadUnblockSigTerm(score::os::Signal& signal) noexcept; - - /// \brief Executes a function with SIGTERM blocked for the current thread. - /// \details This is a RAII-style helper that blocks SIGTERM before executing the provided function - /// and automatically unblocks it after the function completes (regardless of the outcome). - /// This is useful for protecting critical sections from being interrupted by termination signals. - /// \tparam Func The type of the callable to execute. - /// \param signal The signal interface to use for blocking/unblocking. - /// \param func The callable to execute while SIGTERM is blocked e.g. creating a new thread which should not - /// intercept SIGTERM handling. - /// \returns The result of the provided callable. - /// \note Errors from blocking/unblocking operations are silently ignored. - template - static auto WithSigTermBlocked(score::os::Signal& signal, Func&& func) noexcept -> decltype(func()) - { - const auto block_result = PThreadBlockSigTerm(signal); - auto result = func(); - const auto unblock_result = PThreadUnblockSigTerm(signal); - std::ignore = unblock_result; - return result; - } -}; - -} // namespace score::mw::log::detail - -#endif // SCORE_MW_LOG_DETAIL_UTILS_SIGNAL_HANDLING_SIGNAL_HANDLING_H_ diff --git a/score/mw/log/legacy_non_verbose_api/BUILD b/score/mw/log/legacy_non_verbose_api/BUILD index 3635582..6b07f5c 100644 --- a/score/mw/log/legacy_non_verbose_api/BUILD +++ b/score/mw/log/legacy_non_verbose_api/BUILD @@ -70,6 +70,7 @@ cc_test( "@score_baselibs//score/os/mocklib:stdlib_mock", "@score_baselibs//score/os/mocklib:unistd_mock", "@score_baselibs//score/os/utils/mocklib:signal_mock", + "@score_communication//score/mw/com/message_passing:mock", ], ) diff --git a/score/mw/log/legacy_non_verbose_api/tracing_test.cpp b/score/mw/log/legacy_non_verbose_api/tracing_test.cpp index c7e413f..49228bb 100644 --- a/score/mw/log/legacy_non_verbose_api/tracing_test.cpp +++ b/score/mw/log/legacy_non_verbose_api/tracing_test.cpp @@ -403,76 +403,6 @@ TEST_F(LoggerFixture, WhenTypeRegistrationFailsDroppedLogsCounterIsIncremented) EXPECT_EQ(static_cast(kNumberOfLogAttempts), log_entry_instance.get_dropped_logs_count()); } -TEST(TraceFixtureTest, TraceFatalFunctionCallsTraceLevel) -{ - RecordProperty("Requirement", "SCR-1633147"); - RecordProperty("ASIL", "B"); - RecordProperty("Description", "Verifies that TRACE_FATAL calls TRACE_LEVEL with kFatal level"); - RecordProperty("TestingTechnique", "Requirements-based test"); - RecordProperty("DerivationTechnique", "Analysis of requirements"); - - LogEntry entry{}; - auto& logger = LOG_ENTRY(); - TRACE_FATAL(entry); - EXPECT_EQ(true, logger.enabled_at(score::platform::LogLevel::kFatal)); -} - -TEST(TraceFixtureTest, TraceWarnFunctionCallsTraceLevel) -{ - RecordProperty("Requirement", "SCR-1633147"); - RecordProperty("ASIL", "B"); - RecordProperty("Description", "Verifies that TRACE_WARN calls TRACE_LEVEL with kWarn level"); - RecordProperty("TestingTechnique", "Requirements-based test"); - RecordProperty("DerivationTechnique", "Analysis of requirements"); - - LogEntry entry{}; - auto& logger = LOG_ENTRY(); - TRACE_WARN(entry); - EXPECT_EQ(true, logger.enabled_at(score::platform::LogLevel::kWarn)); -} - -TEST(TraceFixtureTest, TraceVerboseFunctionCallsTraceLevel) -{ - RecordProperty("Requirement", "SCR-1633147"); - RecordProperty("ASIL", "B"); - RecordProperty("Description", "Verifies that TRACE_VERBOSE calls TRACE_LEVEL with kVerbose level"); - RecordProperty("TestingTechnique", "Requirements-based test"); - RecordProperty("DerivationTechnique", "Analysis of requirements"); - - LogEntry entry{}; - auto& logger = LOG_ENTRY(); - TRACE_VERBOSE(entry); - EXPECT_EQ(true, logger.enabled_at(score::platform::LogLevel::kVerbose)); -} - -TEST(TraceFixtureTest, TraceDebugFunctionCallsTraceLevel) -{ - RecordProperty("Requirement", "SCR-1633147"); - RecordProperty("ASIL", "B"); - RecordProperty("Description", "Verifies that TRACE_DEBUG calls TRACE_LEVEL with kDebug level"); - RecordProperty("TestingTechnique", "Requirements-based test"); - RecordProperty("DerivationTechnique", "Analysis of requirements"); - - LogEntry entry{}; - auto& logger = LOG_ENTRY(); - TRACE_DEBUG(entry); - EXPECT_EQ(true, logger.enabled_at(score::platform::LogLevel::kDebug)); -} - -TEST(TraceFixtureTest, TraceInfoFunctionCallsTraceLevel) -{ - RecordProperty("Requirement", "SCR-1633147"); - RecordProperty("ASIL", "B"); - RecordProperty("Description", "Verifies that TRACE_INFO calls TRACE_LEVEL with kInfo level"); - RecordProperty("TestingTechnique", "Requirements-based test"); - RecordProperty("DerivationTechnique", "Analysis of requirements"); - - LogEntry entry{}; - auto& logger = LOG_ENTRY(); - TRACE_INFO(entry); - EXPECT_EQ(true, logger.enabled_at(score::platform::LogLevel::kInfo)); -} - } // namespace } // namespace detail } // namespace log diff --git a/score/mw/log/test/console_logging_environment/console_logging_environment.cpp b/score/mw/log/test/console_logging_environment/console_logging_environment.cpp index e4858e3..d003d0b 100644 --- a/score/mw/log/test/console_logging_environment/console_logging_environment.cpp +++ b/score/mw/log/test/console_logging_environment/console_logging_environment.cpp @@ -12,7 +12,11 @@ ********************************************************************************/ #include "score/mw/log/test/console_logging_environment/console_logging_environment.h" +#if (!defined KUSE_STUB_IMPLEMENTATION_ONLY) #include "score/mw/log/detail/common/recorder_factory.h" +#else +#include "score/mw/log/detail/recorder_factory_stub.h" +#endif #include "score/mw/log/runtime.h" @@ -25,10 +29,14 @@ namespace log void ConsoleLoggingEnvironment::SetUp() { +#if (!defined KUSE_STUB_IMPLEMENTATION_ONLY) score::mw::log::detail::Configuration config{}; config.SetLogMode({score::mw::LogMode::kConsole}); config.SetDefaultConsoleLogLevel(score::mw::log::LogLevel::kVerbose); recorder_ = score::mw::log::detail::RecorderFactory().CreateRecorderFromLogMode(score::mw::LogMode::kConsole, config); +#else + recorder_ = score::mw::log::detail::RecorderFactory().CreateWithConsoleLoggingOnly(nullptr); +#endif score::mw::log::detail::Runtime::SetRecorder(recorder_.get()); } diff --git a/score/mw/log/test/fake_recorder/BUILD b/score/mw/log/test/fake_recorder/BUILD deleted file mode 100644 index 353eeaa..0000000 --- a/score/mw/log/test/fake_recorder/BUILD +++ /dev/null @@ -1,28 +0,0 @@ -# ******************************************************************************* -# Copyright (c) 2025 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("@score_baselibs//score/language/safecpp:toolchain_features.bzl", "COMPILER_WARNING_FEATURES") - -cc_library( - name = "fake_recorder", - testonly = True, - srcs = ["fake_recorder.cpp"], - hdrs = ["fake_recorder.h"], - features = COMPILER_WARNING_FEATURES, - visibility = ["//visibility:public"], - deps = [ - "//score/datarouter/lib/synchronized:synchronized_utility", - "@score_baselibs//score/language/futurecpp", - "@score_baselibs//score/mw/log:recorder", - ], -) diff --git a/score/mw/log/test/fake_recorder/README.md b/score/mw/log/test/fake_recorder/README.md deleted file mode 100644 index c06c54c..0000000 --- a/score/mw/log/test/fake_recorder/README.md +++ /dev/null @@ -1,65 +0,0 @@ -# FakeRecorder – How to use in Unit Tests - -`FakeRecorder` is a test implementation of `score::mw::log::Recorder` used in unit tests. -When enabled, logging output is routed to **stdout**, which allows tests to validate log output using GTest's `testing::internal::CaptureStdout()`. - -## Enable FakeRecorder in your test target (BUILD) - -Add this dependency to your unit test target: - -```bzl -deps = [ - "//score/mw/log/test/fake_recorder_environment:auto_register_fake_recorder_env", -] -``` - -This target installs `FakeRecorder` via a **GTest Environment**, so most tests do not need to include any FakeRecorder headers or manually configure the recorder. - -**Recommended**: Do not include FakeRecorder headers in tests unless you explicitly need direct access to FakeRecorder APIs. - -## Typical test pattern: capture stdout and assert content - -```cpp -#include "score/mw/log/logging.h" - -#include -#include - -TEST(FakeRecorderUsage, CapturesLogOutput) -{ - testing::internal::CaptureStdout(); - - // Any mw::log statement will be routed to stdout when FakeRecorder is installed - score::mw::log::LogFatal("test") << "HELLO"; - - const std::string out = testing::internal::GetCapturedStdout(); - // Note: always call GetCapturedStdout() inside the test to finalize the capture. - EXPECT_THAT(out, ::testing::HasSubstr("HELLO")); -} -``` - -## What gets validated? - -The most reliable assertion is that the captured stdout **contains the text you streamed** into the logger (e.g. `"HELLO"`, `"EVENT"`, `"INVALID"`). - -Exact formatting of severity / context / metadata is not guaranteed by FakeRecorder and should not be asserted unless the logger itself guarantees it. - -## Thread-safety notes - -FakeRecorder serializes: - -* internal state updates using `Synchronized` -* stdout writes using a global mutex to avoid interleaved output - -When multiple threads log concurrently: - -* stdout writes are guarded to minimize interleaving -* ordering between threads may be nondeterministic (expected) - -## Real example in the repository - -`score/mw/com/impl/service_element_type_test.cpp` demonstrates the intended usage: - -* the test target depends on `auto_register_fake_recorder_env` -* the test captures stdout -* the test asserts that expected text appears in captured output diff --git a/score/mw/log/test/fake_recorder/fake_recorder.cpp b/score/mw/log/test/fake_recorder/fake_recorder.cpp deleted file mode 100644 index e4f49ac..0000000 --- a/score/mw/log/test/fake_recorder/fake_recorder.cpp +++ /dev/null @@ -1,251 +0,0 @@ -/******************************************************************************** - * Copyright (c) 2025 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/log/test/fake_recorder/fake_recorder.h" - -#include -#include -#include -#include -#include - -namespace score -{ -namespace mw -{ -namespace log -{ -namespace test -{ -namespace -{ -std::mutex g_stdout_mutex; - -/// Convert unsigned integer to binary string using std::bitset -template -std::string ToBinaryString(std::uint64_t value) -{ - return "0b" + std::bitset(value).to_string(); -} -} // namespace - -score::cpp::optional FakeRecorder::StartRecord(const std::string_view /*context_id*/, - const LogLevel /*log_level*/) noexcept -{ - return state_.WithLock([](State& s) -> score::cpp::optional { - for (std::size_t i = 0U; i < kMaxSlots; ++i) - { - if (!s.in_flight[i].has_value()) - { - s.in_flight[i].emplace(); - return SlotHandle(static_cast(i)); - } - } - return {}; - }); -} - -void FakeRecorder::StopRecord(const SlotHandle& slot) noexcept -{ - FlushSlot(slot); -} - -bool FakeRecorder::IsLogEnabled(const LogLevel& /*log_level*/, const std::string_view /*context*/) const noexcept -{ - return true; -} - -void FakeRecorder::Log(const SlotHandle& slot, const bool data) noexcept -{ - AppendToSlot(slot, data ? "true" : "false"); -} - -void FakeRecorder::Log(const SlotHandle& slot, const std::uint8_t data) noexcept -{ - AppendToSlot(slot, std::to_string(static_cast(data))); -} - -void FakeRecorder::Log(const SlotHandle& slot, const std::uint16_t data) noexcept -{ - AppendToSlot(slot, std::to_string(static_cast(data))); -} - -void FakeRecorder::Log(const SlotHandle& slot, const std::uint32_t data) noexcept -{ - AppendToSlot(slot, std::to_string(data)); -} - -void FakeRecorder::Log(const SlotHandle& slot, const std::uint64_t data) noexcept -{ - AppendToSlot(slot, std::to_string(data)); -} - -void FakeRecorder::Log(const SlotHandle& slot, const std::int8_t data) noexcept -{ - AppendToSlot(slot, std::to_string(static_cast(data))); -} - -void FakeRecorder::Log(const SlotHandle& slot, const std::int16_t data) noexcept -{ - AppendToSlot(slot, std::to_string(data)); -} - -void FakeRecorder::Log(const SlotHandle& slot, const std::int32_t data) noexcept -{ - AppendToSlot(slot, std::to_string(data)); -} - -void FakeRecorder::Log(const SlotHandle& slot, const std::int64_t data) noexcept -{ - AppendToSlot(slot, std::to_string(data)); -} - -void FakeRecorder::Log(const SlotHandle& slot, const float data) noexcept -{ - AppendToSlot(slot, std::to_string(data)); -} - -void FakeRecorder::Log(const SlotHandle& slot, const double data) noexcept -{ - AppendToSlot(slot, std::to_string(data)); -} - -void FakeRecorder::Log(const SlotHandle& slot, const std::string_view data) noexcept -{ - AppendToSlot(slot, data); -} - -void FakeRecorder::Log(const SlotHandle& slot, const LogRawBuffer data) noexcept -{ - const auto* begin = data.data(); - AppendToSlot(slot, std::string_view(begin, data.size())); -} - -void FakeRecorder::Log(const SlotHandle& slot, const LogSlog2Message /*data*/) noexcept -{ - AppendToSlot(slot, "[LogSlog2Message]"); -} - -void FakeRecorder::Log(const SlotHandle& slot, const LogHex8 data) noexcept -{ - char buf[8]; - std::snprintf(buf, sizeof(buf), "0x%02X", data.value); - AppendToSlot(slot, buf); -} - -void FakeRecorder::Log(const SlotHandle& slot, const LogHex16 data) noexcept -{ - char buf[16]; - std::snprintf(buf, sizeof(buf), "0x%04X", data.value); - AppendToSlot(slot, buf); -} - -void FakeRecorder::Log(const SlotHandle& slot, const LogHex32 data) noexcept -{ - char buf[16]; - std::snprintf(buf, sizeof(buf), "0x%08X", data.value); - AppendToSlot(slot, buf); -} - -void FakeRecorder::Log(const SlotHandle& slot, const LogHex64 data) noexcept -{ - char buf[24]; - std::snprintf(buf, sizeof(buf), "0x%016llX", static_cast(data.value)); - AppendToSlot(slot, buf); -} - -void FakeRecorder::Log(const SlotHandle& slot, const LogBin8 data) noexcept -{ - AppendToSlot(slot, ToBinaryString<8>(static_cast(data.value))); -} - -void FakeRecorder::Log(const SlotHandle& slot, const LogBin16 data) noexcept -{ - AppendToSlot(slot, ToBinaryString<16>(static_cast(data.value))); -} - -void FakeRecorder::Log(const SlotHandle& slot, const LogBin32 data) noexcept -{ - AppendToSlot(slot, ToBinaryString<32>(static_cast(data.value))); -} - -void FakeRecorder::Log(const SlotHandle& slot, const LogBin64 data) noexcept -{ - AppendToSlot(slot, ToBinaryString<64>(data.value)); -} - -std::vector FakeRecorder::GetRecordedMessages() const noexcept -{ - return state_.WithLock([](const State& s) { - return s.recorded_messages; - }); -} - -void FakeRecorder::ClearRecordedMessages() noexcept -{ - state_.WithLock([](State& s) { - s.recorded_messages.clear(); - for (auto& slot : s.in_flight) - { - slot.reset(); - } - }); -} - -void FakeRecorder::AppendToSlot(const SlotHandle& slot, const std::string_view text) noexcept -{ - const auto idx = static_cast(slot.GetSlotOfSelectedRecorder()); - state_.WithLock([idx, text](State& s) { - if (!s.in_flight[idx].has_value()) - { - return; - } - s.in_flight[idx]->append(text); - }); -} - -void FakeRecorder::FlushSlot(const SlotHandle& slot) noexcept -{ - const auto idx = static_cast(slot.GetSlotOfSelectedRecorder()); - std::string msg; - - state_.WithLock([&msg, idx](State& s) { - if (!s.in_flight[idx].has_value()) - { - return; - } - - msg = std::move(*s.in_flight[idx]); - s.in_flight[idx].reset(); - }); - - if (msg.empty()) - { - return; - } - - { - std::lock_guard out_lock(g_stdout_mutex); - std::fwrite(msg.c_str(), 1U, msg.size(), stdout); - std::fwrite("\n", 1U, 1U, stdout); - std::fflush(stdout); - } - - state_.WithLock([&msg](State& s) { - s.recorded_messages.push_back(std::move(msg)); - }); -} - -} // namespace test -} // namespace log -} // namespace mw -} // namespace score diff --git a/score/mw/log/test/fake_recorder/fake_recorder.h b/score/mw/log/test/fake_recorder/fake_recorder.h deleted file mode 100644 index 8732805..0000000 --- a/score/mw/log/test/fake_recorder/fake_recorder.h +++ /dev/null @@ -1,99 +0,0 @@ -/******************************************************************************** - * Copyright (c) 2025 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_LOG_TEST_FAKE_RECORDER_FAKE_RECORDER_H -#define SCORE_MW_LOG_TEST_FAKE_RECORDER_FAKE_RECORDER_H - -#include "score/mw/log/recorder.h" -#include "score/datarouter/lib/synchronized/synchronized.h" - -#include -#include -#include -#include -#include -#include -#include - -namespace score -{ -namespace mw -{ -namespace log -{ -namespace test -{ - -class FakeRecorder final : public score::mw::log::Recorder -{ - public: - FakeRecorder() = default; - ~FakeRecorder() noexcept override = default; - - FakeRecorder(const FakeRecorder&) = delete; - FakeRecorder& operator=(const FakeRecorder&) = delete; - FakeRecorder(FakeRecorder&&) = delete; - FakeRecorder& operator=(FakeRecorder&&) = delete; - - // Recorder interface implementation - score::cpp::optional StartRecord(std::string_view context_id, LogLevel log_level) noexcept override; - void StopRecord(const SlotHandle& slot) noexcept override; - bool IsLogEnabled(const LogLevel& log_level, const std::string_view context) const noexcept override; - - void Log(const SlotHandle& slot, bool data) noexcept override; - void Log(const SlotHandle& slot, std::uint8_t data) noexcept override; - void Log(const SlotHandle& slot, std::uint16_t data) noexcept override; - void Log(const SlotHandle& slot, std::uint32_t data) noexcept override; - void Log(const SlotHandle& slot, std::uint64_t data) noexcept override; - void Log(const SlotHandle& slot, std::int8_t data) noexcept override; - void Log(const SlotHandle& slot, std::int16_t data) noexcept override; - void Log(const SlotHandle& slot, std::int32_t data) noexcept override; - void Log(const SlotHandle& slot, std::int64_t data) noexcept override; - void Log(const SlotHandle& slot, float data) noexcept override; - void Log(const SlotHandle& slot, double data) noexcept override; - void Log(const SlotHandle& slot, std::string_view data) noexcept override; - void Log(const SlotHandle& slot, LogHex8 data) noexcept override; - void Log(const SlotHandle& slot, LogHex16 data) noexcept override; - void Log(const SlotHandle& slot, LogHex32 data) noexcept override; - void Log(const SlotHandle& slot, LogHex64 data) noexcept override; - void Log(const SlotHandle& slot, LogBin8 data) noexcept override; - void Log(const SlotHandle& slot, LogBin16 data) noexcept override; - void Log(const SlotHandle& slot, LogBin32 data) noexcept override; - void Log(const SlotHandle& slot, LogBin64 data) noexcept override; - void Log(const SlotHandle& slot, const LogRawBuffer data) noexcept override; - void Log(const SlotHandle& slot, const LogSlog2Message data) noexcept override; - - std::vector GetRecordedMessages() const noexcept; - - void ClearRecordedMessages() noexcept; - - private: - void AppendToSlot(const SlotHandle& slot, std::string_view text) noexcept; - void FlushSlot(const SlotHandle& slot) noexcept; - - static constexpr std::size_t kMaxSlots{256U}; - - struct State - { - std::array, kMaxSlots> in_flight{}; - std::vector recorded_messages{}; - }; - - score::platform::datarouter::Synchronized state_{}; -}; - -} // namespace test -} // namespace log -} // namespace mw -} // namespace score - -#endif // SCORE_MW_LOG_TEST_FAKE_RECORDER_FAKE_RECORDER_H diff --git a/score/mw/log/test/fake_recorder_environment/BUILD b/score/mw/log/test/fake_recorder_environment/BUILD deleted file mode 100644 index 24b4d09..0000000 --- a/score/mw/log/test/fake_recorder_environment/BUILD +++ /dev/null @@ -1,41 +0,0 @@ -# ******************************************************************************* -# Copyright (c) 2025 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("@score_baselibs//score/language/safecpp:toolchain_features.bzl", "COMPILER_WARNING_FEATURES") - -cc_library( - name = "fake_recorder_environment", - testonly = True, - srcs = ["fake_recorder_environment.cpp"], - hdrs = ["fake_recorder_environment.h"], - features = COMPILER_WARNING_FEATURES, - visibility = ["//visibility:public"], - deps = [ - "//score/mw/log/test/fake_recorder", - "@googletest//:gtest", - "@score_baselibs//score/mw/log:frontend", - ], -) - -cc_library( - name = "auto_register_fake_recorder_env", - testonly = True, - srcs = ["register_fake_recorder_environment.cpp"], - features = COMPILER_WARNING_FEATURES, - visibility = ["//visibility:public"], - deps = [ - ":fake_recorder_environment", - "@googletest//:gtest", - ], - alwayslink = True, # Ensure static initializer runs -) diff --git a/score/mw/log/test/fake_recorder_environment/fake_recorder_environment.cpp b/score/mw/log/test/fake_recorder_environment/fake_recorder_environment.cpp deleted file mode 100644 index 6a9f170..0000000 --- a/score/mw/log/test/fake_recorder_environment/fake_recorder_environment.cpp +++ /dev/null @@ -1,47 +0,0 @@ -/******************************************************************************** - * Copyright (c) 2025 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/log/test/fake_recorder_environment/fake_recorder_environment.h" - -#include "score/mw/log/runtime.h" - -namespace score -{ -namespace mw -{ -namespace log -{ -namespace test -{ - -void FakeRecorderEnvironment::SetUp() -{ - // Save current recorder (if any) before installing fake - previous_recorder_ = &score::mw::log::detail::Runtime::GetRecorder(); - - // Create and install fake recorder - recorder_ = std::make_unique(); - score::mw::log::detail::Runtime::SetRecorder(recorder_.get()); -} - -void FakeRecorderEnvironment::TearDown() -{ - // Restore previous recorder (or nullptr) - score::mw::log::detail::Runtime::SetRecorder(previous_recorder_); - recorder_.reset(); - previous_recorder_ = nullptr; -} - -} // namespace test -} // namespace log -} // namespace mw -} // namespace score diff --git a/score/mw/log/test/fake_recorder_environment/fake_recorder_environment.h b/score/mw/log/test/fake_recorder_environment/fake_recorder_environment.h deleted file mode 100644 index 94a0774..0000000 --- a/score/mw/log/test/fake_recorder_environment/fake_recorder_environment.h +++ /dev/null @@ -1,55 +0,0 @@ -/******************************************************************************** - * Copyright (c) 2025 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_LOG_TEST_FAKE_RECORDER_ENVIRONMENT_FAKE_RECORDER_ENVIRONMENT_H -#define SCORE_MW_LOG_TEST_FAKE_RECORDER_ENVIRONMENT_FAKE_RECORDER_ENVIRONMENT_H - -#include "score/mw/log/test/fake_recorder/fake_recorder.h" - -#include - -#include - -namespace score -{ -namespace mw -{ -namespace log -{ -namespace test -{ - -class FakeRecorderEnvironment : public ::testing::Environment -{ - public: - FakeRecorderEnvironment() noexcept = default; - ~FakeRecorderEnvironment() noexcept override = default; - - FakeRecorderEnvironment(const FakeRecorderEnvironment&) = delete; - FakeRecorderEnvironment& operator=(const FakeRecorderEnvironment&) = delete; - FakeRecorderEnvironment(FakeRecorderEnvironment&&) = delete; - FakeRecorderEnvironment& operator=(FakeRecorderEnvironment&&) = delete; - - void SetUp() override; - void TearDown() override; - - private: - std::unique_ptr recorder_; - score::mw::log::Recorder* previous_recorder_{nullptr}; -}; - -} // namespace test -} // namespace log -} // namespace mw -} // namespace score - -#endif // SCORE_MW_LOG_TEST_FAKE_RECORDER_ENVIRONMENT_FAKE_RECORDER_ENVIRONMENT_H diff --git a/score/mw/log/test/fake_recorder_environment/register_fake_recorder_environment.cpp b/score/mw/log/test/fake_recorder_environment/register_fake_recorder_environment.cpp deleted file mode 100644 index 64a668f..0000000 --- a/score/mw/log/test/fake_recorder_environment/register_fake_recorder_environment.cpp +++ /dev/null @@ -1,30 +0,0 @@ -/******************************************************************************** - * Copyright (c) 2025 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/log/test/fake_recorder_environment/fake_recorder_environment.h" - -#include - -namespace -{ - -struct AutoRegisterFakeRecorderEnvironment -{ - AutoRegisterFakeRecorderEnvironment() - { - ::testing::AddGlobalTestEnvironment(new score::mw::log::test::FakeRecorderEnvironment()); - } -}; - -static AutoRegisterFakeRecorderEnvironment auto_register_instance; - -} // namespace