diff --git a/score/launch_manager/src/alive/src/alive.cpp b/score/launch_manager/src/alive/src/alive.cpp index c4399d38d..2b59a34de 100644 --- a/score/launch_manager/src/alive/src/alive.cpp +++ b/score/launch_manager/src/alive/src/alive.cpp @@ -18,9 +18,6 @@ #include "score/mw/launch_manager/alive_monitor/details/AliveImpl.h" #include "score/mw/lifecycle/alive.h" -// The public API is only sending alive notification. No need to support different checkpoints. -static constexpr std::uint32_t kDefaultCheckpointId{1U}; - namespace score::mw::lifecycle { @@ -38,7 +35,7 @@ void Alive::ReportAlive() const noexcept { if (aliveImplPtr.get() != nullptr) { - aliveImplPtr->ReportCheckpoint(kDefaultCheckpointId); + aliveImplPtr->ReportCheckpoint(); } } diff --git a/score/launch_manager/src/alive/src/details/AliveImpl.cpp b/score/launch_manager/src/alive/src/details/AliveImpl.cpp index 41c0d7a58..8b2cadc54 100644 --- a/score/launch_manager/src/alive/src/details/AliveImpl.cpp +++ b/score/launch_manager/src/alive/src/details/AliveImpl.cpp @@ -32,10 +32,9 @@ AliveImpl::AliveImpl( connectToPhmDaemon(); } -void AliveImpl::ReportCheckpoint(std::uint32_t f_checkpointId) const noexcept(true) +void AliveImpl::ReportCheckpoint() const noexcept(true) { - (void)ipcClient->sendEmplace( - score::mw::lifecycle::internal::saf::timers::OsClock::getMonotonicSystemClock(), f_checkpointId); + (void)ipcClient->sendEmplace(internal::saf::timers::OsClock::getMonotonicSystemClock()); } void AliveImpl::connectToPhmDaemon(void) noexcept(false) diff --git a/score/launch_manager/src/alive/src/details/AliveImpl.h b/score/launch_manager/src/alive/src/details/AliveImpl.h index a6473f47b..c8dde78f6 100644 --- a/score/launch_manager/src/alive/src/details/AliveImpl.h +++ b/score/launch_manager/src/alive/src/details/AliveImpl.h @@ -66,8 +66,7 @@ class AliveImpl virtual ~AliveImpl() = default; /// @brief Reports an occurrence of a Checkpoint - /// @param [in] f_checkpointId Checkpoint identifier. - void ReportCheckpoint(std::uint32_t f_checkpointId) const noexcept(true); + void ReportCheckpoint() const noexcept(true); private: /// @brief Connect the application process with PHM daemon using IPC diff --git a/score/launch_manager/src/alive/src/details/AliveImpl_UT.cpp b/score/launch_manager/src/alive/src/details/AliveImpl_UT.cpp index cb0481f76..147a9b9ad 100644 --- a/score/launch_manager/src/alive/src/details/AliveImpl_UT.cpp +++ b/score/launch_manager/src/alive/src/details/AliveImpl_UT.cpp @@ -54,7 +54,7 @@ TEST_F(AliveImplTest, ReportCheckpointSafeWhenNotConnected) setenv("LCM_ALIVE_INTERFACE_PATH", "nonexistent_ipc_path", 1); AliveImpl impl("test/instance"); - EXPECT_NO_THROW(impl.ReportCheckpoint(42U)); + EXPECT_NO_THROW(impl.ReportCheckpoint()); } } // namespace score::mw::lifecycle diff --git a/score/launch_manager/src/daemon/src/alive_monitor/details/common/AliveMonitorConfig.cpp b/score/launch_manager/src/daemon/src/alive_monitor/details/common/AliveMonitorConfig.cpp deleted file mode 100644 index 5a7073c6e..000000000 --- a/score/launch_manager/src/daemon/src/alive_monitor/details/common/AliveMonitorConfig.cpp +++ /dev/null @@ -1,61 +0,0 @@ -/******************************************************************************** - * Copyright (c) 2026 Contributors to the Eclipse Foundation - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * This program and the accompanying materials are made available under the - * terms of the Apache License Version 2.0 which is available at - * https://www.apache.org/licenses/LICENSE-2.0 - * - * SPDX-License-Identifier: Apache-2.0 - ********************************************************************************/ - -#include "score/mw/launch_manager/alive_monitor/details/common/AliveMonitorConfig.hpp" - -#include - -#include - -namespace score::mw::lifecycle::internal::alive -{ - -namespace -{ - -using ApplicationType = score::mw::lifecycle::internal::configuration::ApplicationType; - -bool isSupervisedType(ApplicationType app_type) -{ - return app_type == ApplicationType::ReportingAndSupervised || app_type == ApplicationType::StateManager; -} - -} // namespace - -AliveMonitorConfig aliveMonitorConfig(const score::mw::lifecycle::internal::configuration::Config& config) -{ - AliveMonitorConfig result{}; - result.evaluation_cycle_ms = config.aliveSupervision().evaluation_cycle_ms; - - for (const auto& comp : config.components()) - { - if (isSupervisedType(comp.component_properties.application_profile.application_type)) - { - SupervisedComponentConfig info{}; - info.name = comp.name; - info.alive_supervision = comp.component_properties.application_profile.alive_supervision; - info.uid = comp.deployment_config.sandbox.uid; - result.supervised_components.push_back(std::move(info)); - } - } - - // The evaluation cycle is only meaningful when there is something to supervise; a zero cycle from a config - // without an alive-supervision section is benign as long as no supervised components exist. - SCORE_LANGUAGE_FUTURECPP_ASSERT_PRD_MESSAGE( - result.supervised_components.empty() || result.evaluation_cycle_ms > 0, - "evaluation_cycle_ms cannot be zero when supervised components are configured"); - - return result; -} - -} // namespace score::mw::lifecycle::internal::alive diff --git a/score/launch_manager/src/daemon/src/alive_monitor/details/common/AliveMonitorConfig.hpp b/score/launch_manager/src/daemon/src/alive_monitor/details/common/AliveMonitorConfig.hpp deleted file mode 100644 index 7f5a4778c..000000000 --- a/score/launch_manager/src/daemon/src/alive_monitor/details/common/AliveMonitorConfig.hpp +++ /dev/null @@ -1,58 +0,0 @@ -/******************************************************************************** - * Copyright (c) 2026 Contributors to the Eclipse Foundation - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * This program and the accompanying materials are made available under the - * terms of the Apache License Version 2.0 which is available at - * https://www.apache.org/licenses/LICENSE-2.0 - * - * SPDX-License-Identifier: Apache-2.0 - ********************************************************************************/ -#ifndef ALIVE_MONITOR_CONFIG_HPP_INCLUDED -#define ALIVE_MONITOR_CONFIG_HPP_INCLUDED - -#include - -#include -#include -#include -#include - -#include "score/mw/launch_manager/configuration/config.hpp" - -namespace score::mw::lifecycle::internal::alive -{ - -/// @file AliveMonitorConfig.hpp -/// @brief Adds temporary functionality required to copy configuration data until we can, as part of our refactoring -/// efforts, move the configuration data to the entities intended for that purpose. - -/// @brief Supervised component configuration. -struct SupervisedComponentConfig -{ - /// @brief Component short name. - std::string name; - /// @brief Alive-supervision parameters. - std::optional alive_supervision; - /// @brief Uid the component runs as. - uid_t uid{}; -}; - -/// @brief AliveMonitor configuration. -struct AliveMonitorConfig -{ - /// @brief Configuration for every component that is subject to alive supervision. - std::vector supervised_components; - /// @brief Global supervision evaluation cycle, in milliseconds. - uint32_t evaluation_cycle_ms{}; -}; - -/// @brief Returns a copy of alive-monitor-relevant configuration. -/// @return AliveMonitor configuration -AliveMonitorConfig aliveMonitorConfig(const score::mw::lifecycle::internal::configuration::Config& config); - -} // namespace score::mw::lifecycle::internal::alive - -#endif // ALIVE_MONITOR_CONFIG_HPP_INCLUDED diff --git a/score/launch_manager/src/daemon/src/alive_monitor/details/common/AliveMonitorConfig_UT.cpp b/score/launch_manager/src/daemon/src/alive_monitor/details/common/AliveMonitorConfig_UT.cpp deleted file mode 100644 index c71bd99bb..000000000 --- a/score/launch_manager/src/daemon/src/alive_monitor/details/common/AliveMonitorConfig_UT.cpp +++ /dev/null @@ -1,133 +0,0 @@ -/******************************************************************************** - * Copyright (c) 2026 Contributors to the Eclipse Foundation - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * This program and the accompanying materials are made available under the - * terms of the Apache License Version 2.0 which is available at - * https://www.apache.org/licenses/LICENSE-2.0 - * - * SPDX-License-Identifier: Apache-2.0 - ********************************************************************************/ - -#include "score/mw/launch_manager/alive_monitor/details/common/AliveMonitorConfig.hpp" - -#include - -#include -#include - -namespace score::mw::lifecycle::internal::alive -{ -namespace -{ - -namespace cfg = configuration; - -cfg::ComponentConfig makeComponent( - const std::string& name, - cfg::ApplicationType type, - uid_t uid, - std::optional alive_supervision) -{ - cfg::ComponentConfig comp; - comp.name = name; - comp.component_properties.application_profile.application_type = type; - comp.component_properties.application_profile.alive_supervision = alive_supervision; - comp.deployment_config.sandbox.uid = uid; - return comp; -} - -cfg::Config makeConfig(std::vector components, uint32_t evaluation_cycle_ms) -{ - cfg::AliveSupervisionConfig alive; - alive.evaluation_cycle_ms = evaluation_cycle_ms; - - return cfg::ConfigBuilder{} - .setComponents(std::move(components)) - .setInitialRunTarget("Startup") - .setAliveSupervision(alive) - .build(); -} - -class AliveMonitorConfigTest : public ::testing::Test -{ - protected: - void SetUp() override - { - RecordProperty("TestType", "interface-test"); - RecordProperty("DerivationTechnique", "boundary-values"); - } -}; - -TEST_F(AliveMonitorConfigTest, CapturesOnlySupervisedComponents) -{ - RecordProperty("Description", "Only supervised component types are captured from the configuration."); - std::vector components; - components.push_back(makeComponent( - "supervised_reporting", - cfg::ApplicationType::ReportingAndSupervised, - 1001, - cfg::ComponentAliveSupervision{500, 2, 1, 3})); - components.push_back(makeComponent("native_app", cfg::ApplicationType::Native, 1002, std::nullopt)); - components.push_back(makeComponent("reporting_app", cfg::ApplicationType::Reporting, 1003, std::nullopt)); - components.push_back(makeComponent( - "state_manager", - cfg::ApplicationType::StateManager, - 1004, - cfg::ComponentAliveSupervision{100, 0, std::nullopt, std::nullopt})); - - const AliveMonitorConfig result = aliveMonitorConfig(makeConfig(std::move(components), 250)); - - ASSERT_EQ(result.supervised_components.size(), 2U); - EXPECT_EQ(result.supervised_components[0].name, "supervised_reporting"); - EXPECT_EQ(result.supervised_components[1].name, "state_manager"); -} - -TEST_F(AliveMonitorConfigTest, CopiesPerComponentFields) -{ - RecordProperty("Description", "Per-component fields are copied from the configuration."); - std::vector components; - components.push_back(makeComponent( - "supervised", - cfg::ApplicationType::ReportingAndSupervised, - 4242, - cfg::ComponentAliveSupervision{500, 2, 1, 3})); - - const AliveMonitorConfig result = aliveMonitorConfig(makeConfig(std::move(components), 250)); - - ASSERT_EQ(result.supervised_components.size(), 1U); - const auto& info = result.supervised_components[0]; - EXPECT_EQ(info.name, "supervised"); - EXPECT_EQ(info.uid, 4242U); - ASSERT_TRUE(info.alive_supervision.has_value()); - EXPECT_EQ(info.alive_supervision->reporting_cycle_ms, 500U); - EXPECT_EQ(info.alive_supervision->failed_cycles_tolerance, 2U); - EXPECT_EQ(info.alive_supervision->min_indications, 1U); - EXPECT_EQ(info.alive_supervision->max_indications, 3U); -} - -TEST_F(AliveMonitorConfigTest, CopiesGlobalEvaluationCycle) -{ - RecordProperty("Description", "The global evaluation cycle is copied from the configuration."); - const AliveMonitorConfig result = aliveMonitorConfig(makeConfig({}, 777)); - - EXPECT_TRUE(result.supervised_components.empty()); - EXPECT_EQ(result.evaluation_cycle_ms, 777U); -} - -TEST_F(AliveMonitorConfigTest, ZeroEvaluationCycleAllowedWithoutSupervisedComponents) -{ - RecordProperty("DerivationTechnique", "boundary-values"); - RecordProperty("Description", "A zero evaluation cycle is tolerated when no components are supervised."); - // A config lacking an alive-supervision section yields evaluation_cycle_ms == 0. That is benign as long as - // there is nothing to supervise, so it must not trip the production assertion. - const AliveMonitorConfig result = aliveMonitorConfig(makeConfig({}, 0)); - - EXPECT_TRUE(result.supervised_components.empty()); - EXPECT_EQ(result.evaluation_cycle_ms, 0U); -} - -} // namespace -} // namespace score::mw::lifecycle::internal::alive diff --git a/score/launch_manager/src/daemon/src/alive_monitor/details/common/BUILD b/score/launch_manager/src/daemon/src/alive_monitor/details/common/BUILD index e661616f3..2a229864b 100644 --- a/score/launch_manager/src/daemon/src/alive_monitor/details/common/BUILD +++ b/score/launch_manager/src/daemon/src/alive_monitor/details/common/BUILD @@ -13,27 +13,6 @@ load("@rules_cc//cc:defs.bzl", "cc_library") load("//tests/utils/bazel:unit_test.bzl", "lm_cc_test") -cc_library( - name = "alive_monitor_config", - srcs = ["AliveMonitorConfig.cpp"], - hdrs = ["AliveMonitorConfig.hpp"], - include_prefix = "score/mw/launch_manager/alive_monitor/details/common", - strip_include_prefix = "/score/launch_manager/src/daemon/src/alive_monitor/details/common", - visibility = ["//score/launch_manager/src/daemon/src/alive_monitor:__subpackages__"], - deps = [ - "//score/launch_manager/src/daemon/src/configuration:config", - ], -) - -lm_cc_test( - name = "alive_monitor_config_UT", - srcs = ["AliveMonitorConfig_UT.cpp"], - deps = [ - ":alive_monitor_config", - "@googletest//:gtest_main", - ], -) - cc_library( name = "observer", hdrs = ["Observer.hpp"], diff --git a/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/AliveMonitorImpl.cpp b/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/AliveMonitorImpl.cpp index 80a940cd7..958479054 100644 --- a/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/AliveMonitorImpl.cpp +++ b/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/AliveMonitorImpl.cpp @@ -27,7 +27,7 @@ AliveMonitorImpl::AliveMonitorImpl( const Config& config) : m_recovery_client(recovery_client), m_observable_event_receiver(std::move(observable_event_receiver)), - m_config(score::mw::lifecycle::internal::alive::aliveMonitorConfig(config)) + m_config(config) { } diff --git a/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/AliveMonitorImpl.hpp b/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/AliveMonitorImpl.hpp index 38edaf0f5..3cab63bb4 100644 --- a/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/AliveMonitorImpl.hpp +++ b/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/AliveMonitorImpl.hpp @@ -16,7 +16,6 @@ #include #include -#include "score/mw/launch_manager/alive_monitor/details/common/AliveMonitorConfig.hpp" #include "score/mw/launch_manager/alive_monitor/details/daemon/IAliveMonitor.hpp" #include "score/mw/launch_manager/configuration/config.hpp" @@ -41,7 +40,7 @@ using UptrISupervisionControlReceiver = std::unique_ptr; using OsClock = score::mw::lifecycle::internal::saf::timers::OsClockInterface; using Config = score::mw::lifecycle::internal::configuration::Config; -using AliveMonitorConfig = score::mw::lifecycle::internal::alive::AliveMonitorConfig; +using score::mw::lifecycle::internal::configuration::AliveSupervisionConfig; class AliveMonitorImpl : public IAliveMonitor { @@ -60,7 +59,7 @@ class AliveMonitorImpl : public IAliveMonitor UptrPhmDaemon m_daemon{nullptr}; OsClock m_osClock{}; UptrISupervisionControlReceiver m_observable_event_receiver; - AliveMonitorConfig m_config; + const Config& m_config; }; } // namespace daemon diff --git a/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/BUILD b/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/BUILD index 5e0180ece..00f8904b8 100644 --- a/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/BUILD +++ b/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/BUILD @@ -28,9 +28,7 @@ cc_library( strip_include_prefix = "/score/launch_manager/src/daemon/src/alive_monitor/details/daemon", visibility = ["//score/launch_manager/src/daemon/src/alive_monitor:__subpackages__"], deps = [ - "//score/launch_manager/src/daemon/src/alive_monitor/details/common:alive_monitor_config", "//score/launch_manager/src/daemon/src/alive_monitor/details/factory:flat_cfg_factory", - "//score/launch_manager/src/daemon/src/alive_monitor/details/factory:static_config", "//score/launch_manager/src/daemon/src/alive_monitor/details/ifappl:checkpoint", "//score/launch_manager/src/daemon/src/alive_monitor/details/ifappl:data_structures", "//score/launch_manager/src/daemon/src/alive_monitor/details/ifappl:monitor_if_daemon", @@ -39,6 +37,7 @@ cc_library( "//score/launch_manager/src/daemon/src/alive_monitor/details/supervision:alive", "//score/launch_manager/src/daemon/src/alive_monitor/details/timers:timers_os_clock", "//score/launch_manager/src/daemon/src/common:log", + "//score/launch_manager/src/daemon/src/configuration:config", ], ) @@ -52,9 +51,7 @@ cc_library( deps = [ ":phm_daemon_config", ":sw_cluster_handler", - "//score/launch_manager/src/daemon/src/alive_monitor/details/common:alive_monitor_config", "//score/launch_manager/src/daemon/src/alive_monitor/details/factory:flat_cfg_factory", - "//score/launch_manager/src/daemon/src/alive_monitor/details/factory:static_config", "//score/launch_manager/src/daemon/src/alive_monitor/details/ifappl:monitor_if_daemon", "//score/launch_manager/src/daemon/src/alive_monitor/details/ifexm:observable_event_reader", "//score/launch_manager/src/daemon/src/alive_monitor/details/supervision:alive", @@ -83,7 +80,6 @@ cc_library( visibility = ["//score/launch_manager/src/daemon:__subpackages__"], deps = [ ":i_health_monitor", - "//score/launch_manager/src/daemon/src/alive_monitor/details/common:alive_monitor_config", "//score/launch_manager/src/daemon/src/configuration:config", "@score_baselibs//score/language/futurecpp", ], diff --git a/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/PhmDaemon.cpp b/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/PhmDaemon.cpp index 55447eb22..2353a9aa2 100644 --- a/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/PhmDaemon.cpp +++ b/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/PhmDaemon.cpp @@ -28,7 +28,7 @@ namespace score::mw::lifecycle::internal::saf::daemon PhmDaemon::PhmDaemon(OsClock& f_osClock, std::unique_ptr f_observable_event_receiver) : osClock{f_osClock}, cycleTimer{&osClock}, - swClusterHandlers{}, + swClusterHandler{std::make_unique()}, processStateReader{std::move(f_observable_event_receiver)} { static_cast(f_osClock); @@ -46,10 +46,7 @@ void PhmDaemon::performCyclicTriggers(void) if (processStateReader.distributeChanges(syncTimestamp)) { - for (auto& phmHandler : swClusterHandlers) - { - phmHandler.performCyclicTriggers(syncTimestamp); - } + swClusterHandler.performCyclicTriggers(syncTimestamp); } else { @@ -58,42 +55,38 @@ void PhmDaemon::performCyclicTriggers(void) } } -bool PhmDaemon::construct(const AliveMonitorConfig& config, const SupervisionBufferConfig& f_bufferConfig_r) noexcept( - false) +bool PhmDaemon::construct(const std::vector& config) noexcept(false) { - bool isSuccess{true}; + const std::size_t supervised_components = + std::count_if(config.begin(), config.end(), [](const configuration::ComponentConfig& component) { + return component.component_properties.application_profile.alive_supervision.has_value(); + }); - score::Result> listSwClustersPhm{{"MainCluster"}}; - if (!listSwClustersPhm.has_value()) - { - LM_LOG_ERROR() << "Phm Daemon: retrieving the list of PHM software cluster configurations failed with error:" - << listSwClustersPhm.error().Message(); - isSuccess = false; - } - else + swClusterHandler.reserve(supervised_components); + + // In a later refactoring step, components will register their own alive supervision and provide their identifier. + // For now, we iterate through them all here. + + LM_LOG_DEBUG() << "Software Cluster Handler starts constructing workers"; + + for (const auto& comp : config) { - if (listSwClustersPhm.value().size() == 0U) + if (!comp.component_properties.application_profile.alive_supervision.has_value()) { - LM_LOG_WARN() << "Phm Daemon: is starting without any software cluster configurations!"; + continue; } - - // Reserve the vector swClusterHandlers obtained from flatcfg before constructing the SwClusters - swClusterHandlers.reserve(listSwClustersPhm.value().size()); - - for (auto strSwClusterName : listSwClustersPhm.value()) + const auto& alive = comp.component_properties.application_profile.alive_supervision.value(); + const auto name = IdentifierHash{comp.name}; + const auto uid = comp.deployment_config.sandbox.uid; + if (!swClusterHandler.constructWorker(name, alive, uid, recoveryClient, processStateReader)) { - swClusterHandlers.emplace_back(strSwClusterName); - isSuccess = - swClusterHandlers.back().constructWorkers(config, recoveryClient, processStateReader, f_bufferConfig_r); - if (!isSuccess) - { - LM_LOG_ERROR() << "Phm Daemon: failed to create worker objects for swclusterhandler:" - << strSwClusterName; - break; - } + + LM_LOG_ERROR() << "Software Cluster Handler is unable to construct the required worker objects."; + return false; } } - return isSuccess; + + return true; } } // namespace score::mw::lifecycle::internal::saf::daemon diff --git a/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/PhmDaemon.hpp b/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/PhmDaemon.hpp index ad6866ee0..cc8ad5dda 100644 --- a/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/PhmDaemon.hpp +++ b/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/PhmDaemon.hpp @@ -19,14 +19,14 @@ #include #include "score/launch_manager/src/daemon/src/common/log.hpp" -#include "score/mw/launch_manager/alive_monitor/details/common/AliveMonitorConfig.hpp" #include "score/mw/launch_manager/alive_monitor/details/daemon/PhmDaemonConfig.hpp" #include "score/mw/launch_manager/alive_monitor/details/daemon/SwClusterHandler.hpp" -#include "score/mw/launch_manager/alive_monitor/details/factory/StaticConfig.hpp" #include "score/mw/launch_manager/alive_monitor/details/ifexm/ObservableEventReader.hpp" #include "score/mw/launch_manager/alive_monitor/details/timers/CycleTimeValidator.hpp" #include "score/mw/launch_manager/alive_monitor/details/timers/CycleTimer.hpp" #include "score/mw/launch_manager/alive_monitor/details/timers/TimeConversion.hpp" +#include "score/mw/launch_manager/configuration/config.hpp" + namespace score { namespace mw::lifecycle::internal @@ -55,12 +55,11 @@ class PhmDaemon using OsClock = score::mw::lifecycle::internal::saf::timers::OsClockInterface; using SupervisionControlReceiver = score::mw::lifecycle::ISupervisionControlReceiver; using RecoveryClient = score::mw::lifecycle::IRecoveryClient; - using SupervisionBufferConfig = factory::SupervisionBufferConfig; using CycleTimer = score::mw::lifecycle::internal::saf::timers::CycleTimer; using CycleTimeValidator = score::mw::lifecycle::internal::saf::timers::CycleTimeValidator; using NanoSecondType = score::mw::lifecycle::internal::saf::timers::NanoSecondType; using ObservableEventReader = score::mw::lifecycle::internal::saf::ifexm::ObservableEventReader; - using AliveMonitorConfig = score::mw::lifecycle::internal::alive::AliveMonitorConfig; + using Config = score::mw::lifecycle::internal::configuration::Config; /* RULECHECKER_comment(0, 4, check_expensive_to_copy_in_parameter, "f_supervisionErrorInfo name is passed by value\ as same as generated function", true_no_defect) */ @@ -89,18 +88,19 @@ class PhmDaemon /// @brief Wraps the initialization steps of the PHM daemon /// (Constructing the workers, adjusting the cycle time, initialization of fixed step timer) /// @param[in] recovery_client Shared pointer to recovery client + /// @param[in] config Config holding alive monitor and component configuration /// @return See EInitCode definition - EInitCode init(std::shared_ptr recovery_client, const AliveMonitorConfig& config) noexcept(false) + EInitCode init(std::shared_ptr recovery_client, const Config& config) noexcept(false) { recoveryClient = recovery_client; - if (!construct(config, factory::StaticConfig::kDefaultSupervisionBufferConfig)) + if (!construct(config.components())) { return EInitCode::kConstructFlatCfgFactoryFailed; } - int64_t cycleTimeModified{ - static_cast(timers::TimeConversion::convertMilliSecToNanoSec(config.evaluation_cycle_ms))}; + int64_t cycleTimeModified{static_cast( + timers::TimeConversion::convertMilliSecToNanoSec(config.aliveSupervision().evaluation_cycle_ms))}; cycleTimeModified = CycleTimeValidator::adjustCycleTimeOnClockAccuracy(cycleTimeModified, osClock); @@ -196,9 +196,9 @@ class PhmDaemon private: /// @brief Create SwCluster objects & Invoke construction of worker objects /// @details Create the SwclusterHandler objects and the workers for the SwclusterHandler - /// @param[in] f_bufferConfig_r The buffer configuration used for worker construction + /// @param[in] config Config for all components /// @return bool true if workers creation succeeded, false otherwise - bool construct(const AliveMonitorConfig& config, const SupervisionBufferConfig& f_bufferConfig_r) noexcept(false); + bool construct(const std::vector& config) noexcept(false); /// @brief Perform cyclic execution of Phm daemon /// @details Perform cyclic execution of Phm daemon functionalities, for e.g., evaluation of supervisions. @@ -213,8 +213,8 @@ class PhmDaemon /// @brief Recovery interface to Launch Manager std::shared_ptr recoveryClient; - /// @brief Vector of SwCluster handler - std::vector swClusterHandlers; + /// @brief Handler to construct and store objects needed for alive supervision + SwClusterHandler swClusterHandler; /// @brief Observable Event Reader for PHM daemon ObservableEventReader processStateReader; diff --git a/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/SwClusterHandler.cpp b/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/SwClusterHandler.cpp index 8cbd120fb..25f6fda68 100644 --- a/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/SwClusterHandler.cpp +++ b/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/SwClusterHandler.cpp @@ -13,7 +13,6 @@ #include "score/mw/launch_manager/alive_monitor/details/daemon/SwClusterHandler.hpp" #include "score/launch_manager/src/daemon/src/common/log.hpp" -#include "score/mw/launch_manager/alive_monitor/details/factory/FlatCfgFactory.hpp" #include "score/mw/launch_manager/alive_monitor/details/ifappl/Checkpoint.hpp" #include "score/mw/launch_manager/alive_monitor/details/ifappl/MonitorIfDaemon.hpp" #include "score/mw/launch_manager/alive_monitor/details/supervision/Alive.hpp" @@ -21,61 +20,57 @@ namespace score::mw::lifecycle::internal::saf::daemon { -SwClusterHandler::SwClusterHandler(const std::string& f_swClusterName_r) - : f_swClusterName(f_swClusterName_r), - processStates{}, +SwClusterHandler::SwClusterHandler(std::unique_ptr factory) + : processStates{}, aliveIfIpcs{}, aliveInterfaces{}, checkpoints{}, - aliveSupervisions{} + aliveSupervisions{}, + flatCfgFactory{std::move(factory)} { - if (f_swClusterName_r.empty()) - { - LM_LOG_ERROR() << "Software Cluster Handler: Software cluster name is empty!"; - } } SwClusterHandler::~SwClusterHandler() = default; -/* RULECHECKER_comment(0, 3, check_max_cyclomatic_complexity, "Max cyclomatic complexity violation\ - is tolerated for this function. ", true_no_defect) */ -bool SwClusterHandler::constructWorkers( - const AliveMonitorConfig& config, - std::shared_ptr f_recoveryClient_r, - ifexm::ObservableEventReader& f_processStateReader_r, - const factory::SupervisionBufferConfig& f_bufferConfig_r) noexcept(false) +void SwClusterHandler::reserve(std::size_t size) { - bool isSuccess{false}; - factory::FlatCfgFactory flatCfgFactory{f_bufferConfig_r}; + processStates.reserve(size); + aliveIfIpcs.reserve(size); + aliveInterfaces.reserve(size); + checkpoints.reserve(size); + aliveSupervisions.reserve(size); +} - isSuccess = flatCfgFactory.init(config.supervised_components); - if (isSuccess) - { - LM_LOG_DEBUG() << "Software Cluster Handler starts constructing workers:" << f_swClusterName; - isSuccess = flatCfgFactory.createObservableEvents(processStates, f_processStateReader_r); - } - if (isSuccess) +bool SwClusterHandler::constructWorker( + const IdentifierHash& id, + const ComponentAliveSupervision& component_config, + const uid_t uid, + std::shared_ptr f_recoveryClient_r, + ifexm::ObservableEventReader& f_processStateReader_r) noexcept(false) +{ + if (!flatCfgFactory->createObservableEvent(processStates, id, f_processStateReader_r)) { - isSuccess = flatCfgFactory.createAliveIfIpcs(aliveIfIpcs); + return false; } - if (isSuccess) + if (!flatCfgFactory->createAliveIfIpc(aliveIfIpcs, id, uid)) { - isSuccess = flatCfgFactory.createAliveIf(aliveInterfaces, aliveIfIpcs, processStates); + return false; } - if (isSuccess) + if (!flatCfgFactory->createAliveIf(aliveInterfaces, aliveIfIpcs.back(), processStates.back())) { - isSuccess = flatCfgFactory.createSupervisionCheckpoints(checkpoints, aliveInterfaces, processStates); + return false; } - if (isSuccess) + if (!flatCfgFactory->createSupervisionCheckpoint(checkpoints, aliveInterfaces.back(), processStates.back(), id)) { - isSuccess = - flatCfgFactory.createAliveSupervisions(aliveSupervisions, checkpoints, processStates, f_recoveryClient_r); + return false; } - if (isSuccess == false) + if (!flatCfgFactory->createAliveSupervision( + aliveSupervisions, checkpoints.back(), processStates.back(), f_recoveryClient_r, id, component_config)) { - LM_LOG_ERROR() << "Software Cluster Handler is unable to construct the required worker objects."; + return false; } - return isSuccess; + + return true; } void SwClusterHandler::checkInterfaceForNewData(const timers::NanoSecondType f_syncTimestamp) diff --git a/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/SwClusterHandler.hpp b/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/SwClusterHandler.hpp index 8203ab5c6..490bc1c6f 100644 --- a/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/SwClusterHandler.hpp +++ b/score/launch_manager/src/daemon/src/alive_monitor/details/daemon/SwClusterHandler.hpp @@ -14,13 +14,12 @@ #ifndef SWCLUSTERHANDLER_HPP_INCLUDED #define SWCLUSTERHANDLER_HPP_INCLUDED -#include "score/mw/launch_manager/alive_monitor/details/factory/StaticConfig.hpp" +#include "score/mw/launch_manager/alive_monitor/details/factory/IPhmFactory.hpp" #include "score/mw/launch_manager/alive_monitor/details/ifappl/DataStructures.hpp" #include "score/mw/launch_manager/alive_monitor/details/ifexm/ObservableEvent.hpp" #include "score/mw/launch_manager/alive_monitor/details/ifexm/ObservableEventReader.hpp" #include "score/mw/launch_manager/alive_monitor/details/timers/Timers_OsClock.hpp" - -#include "score/mw/launch_manager/alive_monitor/details/common/AliveMonitorConfig.hpp" +#include "score/mw/launch_manager/configuration/config.hpp" #include #include @@ -54,7 +53,8 @@ class Alive; namespace daemon { -using AliveMonitorConfig = score::mw::lifecycle::internal::alive::AliveMonitorConfig; +using mw::lifecycle::internal::configuration::AliveSupervisionConfig; +using mw::lifecycle::internal::configuration::ComponentAliveSupervision; /// @brief Software Cluster Handler wraps the full PHM Supervision and Recovery Notification functionality for one /// Software Cluster. @@ -63,12 +63,9 @@ using AliveMonitorConfig = score::mw::lifecycle::internal::alive::AliveMonitorCo class SwClusterHandler { public: - /// @brief No Default Constructor - SwClusterHandler() = delete; - /// @brief Constructor - /// @param [in] f_swClusterName_r Software Cluster name which shall be handled - explicit SwClusterHandler(const std::string& f_swClusterName_r); + /// @param[in] factory Factory moved into the object to construct required alive supervision components + explicit SwClusterHandler(std::unique_ptr factory); /// @brief Destroys the workers virtual ~SwClusterHandler(); @@ -91,17 +88,24 @@ class SwClusterHandler /// @brief No Move Assignment SwClusterHandler& operator=(SwClusterHandler&&) = delete; - /// @brief Construct required worker objects for the Software Cluster + /// @brief Allocate all the vectors needed to store alive supervision components + /// @param[in] size Number of supervised components + void reserve(std::size_t size); + + /// @brief Construct required worker objects for provided component /// @details Construct the interfaces, checkpoints, supervisions and recovery notifications + /// @param [in] id Identifier of the component + /// @param [in] component_config Alive supervision configuration for the component + /// @param [in] uid The configured uid of the component. Used for IPC access control /// @param [in] f_recoveryClient_r Interface to the launch manager for recovery /// @param [in] f_processStateReader_r Process state reader object for PHM daemon - /// @param [in] f_bufferConfig_r Configuration settings for constructing workers /// @return Construction is successful (true), otherwise failure (false) - bool constructWorkers( - const AliveMonitorConfig& config, - std::shared_ptr f_recoveryClient_r, - ifexm::ObservableEventReader& f_processStateReader_r, - const factory::SupervisionBufferConfig& f_bufferConfig_r) noexcept(false); + bool constructWorker( + const IdentifierHash& id, + const ComponentAliveSupervision& component_config, + const uid_t uid, + std::shared_ptr f_recoveryClient_r, + ifexm::ObservableEventReader& f_processStateReader_r) noexcept(false); /// @brief Perform cyclic execution /// @details Perform cyclic execution required for supervision of the Software Cluster @@ -123,9 +127,6 @@ class SwClusterHandler /// @param [in] f_syncTimestamp Timestamp for cyclic synchronization void evaluateSupervisions(const timers::NanoSecondType f_syncTimestamp); - /// SwCluster Name for this SwCLusterHandler Object - const std::string f_swClusterName; - /// Vector of Process states std::vector processStates; @@ -140,6 +141,8 @@ class SwClusterHandler /// Vector of Alive Supervisions std::vector aliveSupervisions; + + std::unique_ptr flatCfgFactory; }; } // namespace daemon diff --git a/score/launch_manager/src/daemon/src/alive_monitor/details/factory/BUILD b/score/launch_manager/src/daemon/src/alive_monitor/details/factory/BUILD index 1e27d8edf..ef1f44e33 100644 --- a/score/launch_manager/src/daemon/src/alive_monitor/details/factory/BUILD +++ b/score/launch_manager/src/daemon/src/alive_monitor/details/factory/BUILD @@ -23,18 +23,6 @@ cc_library( ], ) -cc_library( - name = "static_config", - hdrs = ["StaticConfig.hpp"], - include_prefix = "score/mw/launch_manager/alive_monitor/details/factory", - strip_include_prefix = "/score/launch_manager/src/daemon/src/alive_monitor/details/factory", - visibility = ["//score/launch_manager/src/daemon/src/alive_monitor:__subpackages__"], - deps = [ - "//score/launch_manager/src/daemon/src/alive_monitor/details/ifappl:data_structures", - "//score/launch_manager/src/daemon/src/alive_monitor/details/timers:timers_os_clock", - ], -) - cc_library( name = "flat_cfg_factory", srcs = ["FlatCfgFactory.cpp"], @@ -44,19 +32,17 @@ cc_library( visibility = ["//score/launch_manager/src/daemon/src/alive_monitor:__subpackages__"], deps = [ ":i_phm_factory", - "//score/launch_manager/src/daemon/src/alive_monitor/details/common:alive_monitor_config", - "//score/launch_manager/src/daemon/src/alive_monitor/details/factory:static_config", "//score/launch_manager/src/daemon/src/alive_monitor/details/ifappl:checkpoint", "//score/launch_manager/src/daemon/src/alive_monitor/details/ifappl:monitor_if_daemon", "//score/launch_manager/src/daemon/src/alive_monitor/details/ifexm:observable_event", "//score/launch_manager/src/daemon/src/alive_monitor/details/ifexm:observable_event_reader", "//score/launch_manager/src/daemon/src/alive_monitor/details/supervision:alive", - "//score/launch_manager/src/daemon/src/alive_monitor/details/supervision:supervision_cfg", "//score/launch_manager/src/daemon/src/alive_monitor/details/timers:time_conversion", "//score/launch_manager/src/daemon/src/alive_monitor/details/timers:timers_os_clock", "//score/launch_manager/src/daemon/src/common:alive_interface_path", "//score/launch_manager/src/daemon/src/common:identifier_hash", "//score/launch_manager/src/daemon/src/common:log", + "//score/launch_manager/src/daemon/src/configuration:config", "@score_baselibs//score/language/futurecpp", ] + select({ "@platforms//os:qnx": [], diff --git a/score/launch_manager/src/daemon/src/alive_monitor/details/factory/FlatCfgFactory.cpp b/score/launch_manager/src/daemon/src/alive_monitor/details/factory/FlatCfgFactory.cpp index a0fc4f797..a43da4b89 100644 --- a/score/launch_manager/src/daemon/src/alive_monitor/details/factory/FlatCfgFactory.cpp +++ b/score/launch_manager/src/daemon/src/alive_monitor/details/factory/FlatCfgFactory.cpp @@ -21,12 +21,10 @@ #include "score/launch_manager/src/daemon/src/common/log.hpp" #include "score/mw/launch_manager/alive_monitor/details/factory/IPhmFactory.hpp" -#include "score/mw/launch_manager/alive_monitor/details/factory/StaticConfig.hpp" #include "score/mw/launch_manager/alive_monitor/details/ifappl/Checkpoint.hpp" #include "score/mw/launch_manager/alive_monitor/details/ifappl/MonitorIfDaemon.hpp" #include "score/mw/launch_manager/alive_monitor/details/ifexm/ObservableEvent.hpp" #include "score/mw/launch_manager/alive_monitor/details/supervision/Alive.hpp" -#include "score/mw/launch_manager/alive_monitor/details/supervision/SupervisionCfg.hpp" #include "score/mw/launch_manager/alive_monitor/details/timers/TimeConversion.hpp" #include "score/mw/launch_manager/alive_monitor/details/timers/Timers_OsClock.hpp" #include "score/mw/launch_manager/common/alive_interface_path.hpp" @@ -35,65 +33,35 @@ namespace score::mw::lifecycle::internal::saf::factory { -using BufferConfig = SupervisionBufferConfig; using RecoveryClient = score::mw::lifecycle::IRecoveryClient; using NanoSecondType = saf::timers::NanoSecondType; using IdentifierHash = score::mw::lifecycle::IdentifierHash; -FlatCfgFactory::FlatCfgFactory(const BufferConfig& f_bufferConfig_r) : IPhmFactory(), bufferConfig_r(f_bufferConfig_r) +FlatCfgFactory::FlatCfgFactory() : IPhmFactory() { } -bool FlatCfgFactory::init(const std::vector& supervised) +bool FlatCfgFactory::createObservableEvent( + std::vector& events, + const IdentifierHash component_id, + ifexm::ObservableEventReader& event_reader_) { - supervised_components_ = supervised; - return true; -} - -bool FlatCfgFactory::createObservableEvents( - std::vector& f_processStates_r, - ifexm::ObservableEventReader& f_processStateReader_r) -{ - bool isSuccess{true}; - try { - f_processStates_r.reserve(supervised_components_.size()); - for (const auto& comp : supervised_components_) + auto& res = events.emplace_back(component_id); + if (event_reader_.registerObservableEvent(res, component_id)) { - const auto id = IdentifierHash{comp.name}; - f_processStates_r.emplace_back(id); - isSuccess = f_processStateReader_r.registerObservableEvent(f_processStates_r.back(), id); - if (!isSuccess) - { - break; - } - - LM_LOG_DEBUG() << "Successfully created Observable Events:" << comp.name; + LM_LOG_DEBUG() << "Successfully created Observable Event:" << component_id; + return true; } } catch (const std::exception& f_exception_r) { - isSuccess = false; LM_LOG_ERROR() << "Could not create Observable Events due to exception:" << std::string_view{f_exception_r.what()}; } - if (isSuccess) - { - LM_LOG_DEBUG() << "Number of constructed Observable Events:" << static_cast(f_processStates_r.size()); - } - else - { - for (auto& processState_r : f_processStates_r) - { - f_processStateReader_r.deregisterObservableEvent(processState_r.event.id); - } - f_processStates_r.clear(); - LM_LOG_ERROR() << "Could not create all necessary Observable Events."; - } - - return isSuccess; + return false; } bool FlatCfgFactory::initIpcServerWithUidBasedAccess( @@ -117,204 +85,104 @@ bool FlatCfgFactory::initIpcServerWithUidBasedAccess( return true; } -bool FlatCfgFactory::createAliveIfIpcs(std::vector& f_interfaceIpcs_r) +bool FlatCfgFactory::createAliveIfIpc( + std::vector& servers, + const IdentifierHash component_id, + const uid_t uid) { - bool isSuccess{true}; try { - f_interfaceIpcs_r.reserve(supervised_components_.size()); + const std::string pathInterface = internal::aliveInterfacePath(component_id); + auto& server = servers.emplace_back(); - for (const auto& comp : supervised_components_) + if (initIpcServerWithUidBasedAccess(server, pathInterface, uid)) { - const std::string pathInterface = score::mw::lifecycle::internal::aliveInterfacePath(comp.name); - f_interfaceIpcs_r.emplace_back(); - const std::int32_t configuredUid = static_cast(comp.uid); - isSuccess = initIpcServerWithUidBasedAccess(f_interfaceIpcs_r.back(), pathInterface, configuredUid); - - if (isSuccess) - { - LM_LOG_DEBUG() << "Successfully created Monitor interface IPC with path:" << pathInterface; - } - else - { - LM_LOG_ERROR() << "Could not create Monitor interface IPC with path:" << pathInterface; - break; - } + LM_LOG_DEBUG() << "Successfully created Monitor interface IPC with path:" << pathInterface; + return true; + } + else + { + LM_LOG_ERROR() << "Could not create Monitor interface IPC with path:" << pathInterface; + return false; } } catch (const std::exception& f_exception_r) { - isSuccess = false; LM_LOG_ERROR() << "Could not create Monitor interface IPC due to exception:" << std::string_view{f_exception_r.what()}; + return false; } - - if (isSuccess) - { - LM_LOG_DEBUG() << "Number of constructed Monitor interface IPCs:" - << static_cast(f_interfaceIpcs_r.size()); - } - else - { - f_interfaceIpcs_r.clear(); - LM_LOG_ERROR() << "Could not create all necessary Monitor interface IPCs."; - } - - return isSuccess; } bool FlatCfgFactory::createAliveIf( - std::vector& f_interfaces_r, - std::vector& f_interfaceIpcs_r, - std::vector& f_processStates_r) + std::vector& interfaces, + ifappl::CheckpointIpcServer& ipc_server, + ifexm::ObservableEvent& event) { - bool isSuccess{true}; try { - f_interfaces_r.reserve(supervised_components_.size()); - for (std::size_t compIndex = 0; compIndex < supervised_components_.size(); ++compIndex) - { - auto& interfaceIpc = f_interfaceIpcs_r.at(compIndex); - f_interfaces_r.emplace_back(interfaceIpc, interfaceIpc.getPath().data()); - f_processStates_r.at(compIndex).attachObserver(f_interfaces_r.back()); - - LM_LOG_DEBUG() << "Successfully created MonitorInterface:" << f_interfaces_r.back().getInterfaceName(); - } + auto& interface = interfaces.emplace_back(ipc_server, ipc_server.getPath().data()); + event.attachObserver(interface); - LM_LOG_DEBUG() << "Number of constructed Monitor interfaces:" << static_cast(f_interfaces_r.size()); + LM_LOG_DEBUG() << "Successfully created MonitorInterface:" << interface.getInterfaceName(); + return true; } catch (const std::exception& f_exception_r) { - isSuccess = false; - f_interfaces_r.clear(); LM_LOG_ERROR() << "Could not create all necessary Monitor interfaces due to exception:" << std::string_view{f_exception_r.what()}; + return false; } - - return isSuccess; } -bool FlatCfgFactory::createSupervisionCheckpoints( - std::vector& f_checkpoints_r, - std::vector& f_interfaces_r, - std::vector& f_processStates_r) +bool FlatCfgFactory::createSupervisionCheckpoint( + std::vector& checkpoints, + ifappl::MonitorIfDaemon& interface, + ifexm::ObservableEvent& event, + const IdentifierHash component_id) { - bool isSuccess{true}; - try { - f_checkpoints_r.reserve(supervised_components_.size()); + const std::string checkpointCfgName = std::to_string(component_id.data()) + "_checkpoint"; + auto& checkpoint = checkpoints.emplace_back(checkpointCfgName.c_str(), &event); + interface.attachCheckpoint(checkpoint); - for (size_t idx = 0; idx < supervised_components_.size(); ++idx) - { - const auto& comp = supervised_components_[idx]; - const std::string checkpointCfgName = comp.name + "_checkpoint"; - const uint32_t checkpointId = StaticConfig::k_DefaultCheckpointId; - - const ifexm::ObservableEvent* process_p{&f_processStates_r.at(idx)}; - f_checkpoints_r.emplace_back(checkpointCfgName.c_str(), checkpointId, process_p); - f_interfaces_r.at(idx).attachCheckpoint(f_checkpoints_r.back()); + LM_LOG_DEBUG() << "Successfully created supervision checkpoint:" << checkpoint.getConfigName(); - LM_LOG_DEBUG() << "Successfully created supervision checkpoint:" << f_checkpoints_r.back().getConfigName(); - } + return true; } catch (const std::exception& f_exception_r) { - isSuccess = false; LM_LOG_ERROR() << "Could not create supervision worker objects, due to exception:" << std::string_view{f_exception_r.what()}; + return false; } - - if (isSuccess) - { - LM_LOG_DEBUG() << "Number of constructed supervision checkpoints:" - << static_cast(f_checkpoints_r.size()); - } - else - { - f_checkpoints_r.clear(); - LM_LOG_ERROR() << "Could not create all necessary supervision checkpoints."; - } - - return isSuccess; } -bool FlatCfgFactory::createAliveSupervisions( - std::vector& f_alive_r, - std::vector& f_checkpoints_r, - std::vector& f_processStates_r, - std::shared_ptr f_recoveryClient_r) +bool FlatCfgFactory::createAliveSupervision( + std::vector& supervisions, + ifappl::Checkpoint& checkpoint, + ifexm::ObservableEvent& event, + std::shared_ptr recovery_client, + const IdentifierHash component_id, + const ComponentAliveSupervision component_config) { - bool isSuccess{true}; - try { - f_alive_r.reserve(supervised_components_.size()); - alive_cfg_names_.clear(); - alive_cfg_names_.reserve(supervised_components_.size()); - - for (size_t idx = 0; idx < supervised_components_.size(); ++idx) - { - const auto& comp = supervised_components_[idx]; - const auto& alive_sup = comp.alive_supervision; - SCORE_LANGUAGE_FUTURECPP_ASSERT_MESSAGE( - alive_sup.has_value(), "Supervised component must have alive_supervision configured"); - - alive_cfg_names_.emplace_back(comp.name + "_alive_supervision"); - NanoSecondType aliveReferenceCycleCfg{ - timers::TimeConversion::convertMilliSecToNanoSec(static_cast(alive_sup->reporting_cycle_ms))}; - uint32_t minAliveIndicationsCfg = alive_sup->min_indications.value_or(0U); - uint32_t maxAliveIndicationsCfg = alive_sup->max_indications.value_or(0U); - bool isMinCheckDisabledCfg = (minAliveIndicationsCfg == 0U); - bool isMaxCheckDisabledCfg = (maxAliveIndicationsCfg == 0U); - uint32_t failedCyclesToleranceCfg = alive_sup->failed_cycles_tolerance; - - supervision::AliveSupervisionCfg aliveSupCfg{f_checkpoints_r.at(idx)}; + auto& alive = supervisions.emplace_back(component_id, component_config, recovery_client, checkpoint); - aliveSupCfg.cfgName_p = alive_cfg_names_.back().c_str(); - aliveSupCfg.aliveReferenceCycle = aliveReferenceCycleCfg; - aliveSupCfg.minAliveIndications = minAliveIndicationsCfg; - aliveSupCfg.maxAliveIndications = maxAliveIndicationsCfg; - aliveSupCfg.isMinCheckDisabled = isMinCheckDisabledCfg; - aliveSupCfg.isMaxCheckDisabled = isMaxCheckDisabledCfg; - aliveSupCfg.failedCyclesTolerance = failedCyclesToleranceCfg; - aliveSupCfg.checkpointBufferSize = bufferConfig_r.bufferSizeAliveSupervision; - aliveSupCfg.recoveryClient = f_recoveryClient_r; + event.attachObserver(alive); - aliveSupCfg.processIdentifier = getProcessId(comp); - - f_alive_r.emplace_back(aliveSupCfg); - - f_processStates_r.at(idx).attachObserver(f_alive_r.back()); - - LM_LOG_DEBUG() << "Successfully created alive supervision worker object:" - << f_alive_r.back().getConfigName(); - } + LM_LOG_DEBUG() << "Successfully created alive supervision worker object:" << alive.getConfigName(); + return true; } catch (const std::exception& f_exception_r) { - isSuccess = false; LM_LOG_ERROR() << "Could not create all necessary alive supervision " "worker objects, due to exception:" << std::string_view{f_exception_r.what()}; + return false; } - - if (isSuccess) - { - LM_LOG_DEBUG() << "Number of constructed alive supervisions:" << static_cast(f_alive_r.size()); - } - else - { - f_alive_r.clear(); - LM_LOG_ERROR() << "Could not create all necessary alive supervision worker objects"; - } - - return isSuccess; -} - -IdentifierHash FlatCfgFactory::getProcessId(const SupervisedComponentConfig& comp) noexcept(true) -{ - return IdentifierHash{comp.name}; } } // namespace score::mw::lifecycle::internal::saf::factory diff --git a/score/launch_manager/src/daemon/src/alive_monitor/details/factory/FlatCfgFactory.hpp b/score/launch_manager/src/daemon/src/alive_monitor/details/factory/FlatCfgFactory.hpp index 115f8b071..e61cb06f3 100644 --- a/score/launch_manager/src/daemon/src/alive_monitor/details/factory/FlatCfgFactory.hpp +++ b/score/launch_manager/src/daemon/src/alive_monitor/details/factory/FlatCfgFactory.hpp @@ -16,10 +16,9 @@ #include -#include "score/mw/launch_manager/alive_monitor/details/common/AliveMonitorConfig.hpp" #include "score/mw/launch_manager/alive_monitor/details/factory/IPhmFactory.hpp" -#include "score/mw/launch_manager/alive_monitor/details/factory/StaticConfig.hpp" #include "score/mw/launch_manager/alive_monitor/details/ifexm/ObservableEventReader.hpp" +#include "score/mw/launch_manager/configuration/config.hpp" #include #include @@ -41,8 +40,6 @@ namespace saf namespace factory { -using SupervisedComponentConfig = score::mw::lifecycle::internal::alive::SupervisedComponentConfig; - /// @brief PHM Factory for FlatCfg AR21-11 format /// @details Provides methods to create worker objects depending on a AR21-11 based PHM FlatCfg file /// and establishes required links between the worker objects automatically. @@ -50,8 +47,7 @@ class FlatCfgFactory : public IPhmFactory { public: /// @brief Constructor - /// @param [in] f_bufferConfig_r Buffer configuration used for constructing supervisions - explicit FlatCfgFactory(const factory::SupervisionBufferConfig& f_bufferConfig_r); + explicit FlatCfgFactory(); /// @brief Destructor /* RULECHECKER_comment(0, 5, check_min_instructions, "Default destructor is not provided\ @@ -67,44 +63,41 @@ class FlatCfgFactory : public IPhmFactory /// @brief No Move Assignment FlatCfgFactory& operator=(FlatCfgFactory&&) = delete; - /// @brief Initialize SW cluster - /// @param [in] supervised Vector of supervised component configurations - /// @return Initialization is successful (true), otherwise failure (false) - bool init(const std::vector& supervised); - /// @brief Refer to the description of the base class (IPhmFactory) - bool createObservableEvents( - std::vector& f_processStates_r, - ifexm::ObservableEventReader& f_processStateReader_r) override; + bool createObservableEvent( + std::vector& events, + const IdentifierHash component_id, + ifexm::ObservableEventReader& event_reader_) override; /// Refer to the description of the base class (IPhmFactory) - bool createAliveIfIpcs(std::vector& f_interfaceIpcs_r) override; + bool createAliveIfIpc( + std::vector& servers, + const IdentifierHash component_id, + const uid_t uid) override; /// Refer to the description of the base class (IPhmFactory) bool createAliveIf( - std::vector& f_interfaces_r, - std::vector& f_interfaceIpcs_r, - std::vector& f_processStates_r) override; + std::vector& interfaces, + ifappl::CheckpointIpcServer& ipc_server, + ifexm::ObservableEvent& event) override; /// Refer to the description of the base class (IPhmFactory) - bool createSupervisionCheckpoints( - std::vector& f_checkpoints_r, - std::vector& f_interfaces_r, - std::vector& f_processStates_r) override; + bool createSupervisionCheckpoint( + std::vector& checkpoints, + ifappl::MonitorIfDaemon& interface, + ifexm::ObservableEvent& event, + const IdentifierHash component_id) override; /// Refer to the description of the base class (IPhmFactory) - bool createAliveSupervisions( - std::vector& f_alive_r, - std::vector& f_checkpoints_r, - std::vector& f_processStates_r, - std::shared_ptr f_recoveryClient_r) override; + bool createAliveSupervision( + std::vector& supervisions, + ifappl::Checkpoint& checkpoint, + ifexm::ObservableEvent& event, + std::shared_ptr recovery_client, + const IdentifierHash component_id, + const ComponentAliveSupervision component_config) override; private: - /// @brief Get process id based on ASR path of process - /// @param[in] comp Reference to component configuration - /// @return process id - static score::mw::lifecycle::IdentifierHash getProcessId(const SupervisedComponentConfig& comp) noexcept(true); - /// @brief Create IPC Channel with uid-based access permission /// @details Only the given uid will ge granted r/w access, no group will be granted access /// @param[in,out] f_ipcServer_r The IPC server object @@ -115,12 +108,6 @@ class FlatCfgFactory : public IPhmFactory ifappl::CheckpointIpcServer& f_ipcServer_r, const std::string& f_ipcPath_r, const std::int32_t f_uid) noexcept(false); - - /// @brief The buffer configuration for constructing supervision objects - const factory::SupervisionBufferConfig& bufferConfig_r; - - std::vector supervised_components_; - std::vector alive_cfg_names_; }; } // namespace factory diff --git a/score/launch_manager/src/daemon/src/alive_monitor/details/factory/IPhmFactory.hpp b/score/launch_manager/src/daemon/src/alive_monitor/details/factory/IPhmFactory.hpp index aa8d2cf31..45d50a7a3 100644 --- a/score/launch_manager/src/daemon/src/alive_monitor/details/factory/IPhmFactory.hpp +++ b/score/launch_manager/src/daemon/src/alive_monitor/details/factory/IPhmFactory.hpp @@ -15,6 +15,8 @@ #define IPHMFACTORY_HPP_INCLUDED #include "score/mw/launch_manager/alive_monitor/details/ifappl/DataStructures.hpp" +#include "score/mw/launch_manager/common/identifier_hash.hpp" +#include "score/mw/launch_manager/configuration/config.hpp" #include namespace score @@ -53,6 +55,8 @@ class Alive; namespace factory { +using ComponentAliveSupervision = configuration::ComponentAliveSupervision; + /// @brief PHM Factory interface class /// @details Provides methods to create worker objects class IPhmFactory @@ -75,51 +79,63 @@ class IPhmFactory /// @brief No Move Assignment IPhmFactory& operator=(IPhmFactory&&) = delete; - /// @brief Create Observable Events - /// @param [out] f_processStates_r Vector of created Observable Events + /// @brief Create an Observable Event + /// @param [out] events Container to emplace the new event into + /// @param [in] component_id Identifier of the component we wish to monitor /// @param [in] f_processStateReader_r Process state reader object for PHM daemon /// @return Object creation successful (true), otherwise failed (false) - virtual bool createObservableEvents( - std::vector& f_processStates_r, - ifexm::ObservableEventReader& f_processStateReader_r) = 0; - - /// @brief Create IPCs for Alive Interfaces - /// @param [out] f_interfaceIpcs_r Vector of created Alive Interface IPCs + virtual bool createObservableEvent( + std::vector& events, + const IdentifierHash component_id, + ifexm::ObservableEventReader& event_reader_) = 0; + + /// @brief Create IPC for Alive Interface + /// @param [out] servers Container to emplace the new server into + /// @param [in] component_id Identifier of the component we wish to Monitor + /// @param [in] uid UID to setup the IPC channel with /// @return Object creation successful (true), otherwise failed (false) - virtual bool createAliveIfIpcs(std::vector& f_interfaceIpcs_r) = 0; - - /// @brief Create Alive Interfaces - /// @param [out] f_interfaces_r Vector of created Alive Interfaces - /// @param [in] f_interfaceIpcs_r Vector of Alive Interface IPCs required for interface creation. - /// @param [in,out] f_processStates_r Vector of Observable Events + virtual bool createAliveIfIpc( + std::vector& servers, + const IdentifierHash component_id, + const uid_t uid) = 0; + + /// @brief Create an Alive Interface + /// @param [out] interfaces Container to emplace the new interface into + /// @param [in] ipc_server IPC server for the interface to use + /// @param [in] event Event to attach observer to /// @return Object creation successful (true), otherwise failed (false) virtual bool createAliveIf( - std::vector& f_interfaces_r, - std::vector& f_interfaceIpcs_r, - std::vector& f_processStates_r) = 0; - - /// @brief Create Supervision Checkpoints - /// @param [out] f_checkpoints_r Vector of created Supervision Checkpoints - /// @param [in,out] f_interfaces_r Vector of Alive Interfaces required for attaching the checkpoints. - /// @param [in] f_processStates_r Vector of ObservableEvents required for constructing the Checkpoint - /// instances. + std::vector& interfaces, + ifappl::CheckpointIpcServer& ipc_server, + ifexm::ObservableEvent& event) = 0; + + /// @brief Create a Supervision Checkpoint + /// @param [out] checkpoints Container to emplace the new checkpoint into + /// @param [in] interface Alive Interface required for attaching the checkpoint. + /// @param [in] event ObservableEvents required for constructing the Checkpoint. + /// @param [in] component_id Component being supervised /// @return Object creation successful (true), otherwise failed (false) - virtual bool createSupervisionCheckpoints( - std::vector& f_checkpoints_r, - std::vector& f_interfaces_r, - std::vector& f_processStates_r) = 0; + virtual bool createSupervisionCheckpoint( + std::vector& checkpoints, + ifappl::MonitorIfDaemon& interface, + ifexm::ObservableEvent& event, + const IdentifierHash component_id) = 0; /// @brief Create alive supervision worker objects - /// @param [out] f_alive_r Vector of created alive supervision worker - /// @param [in,out] f_checkpoints_r Vector of Supervision Checkpoints - /// @param [in,out] f_processStates_r Vector of Observable Events - /// @param [in] f_recoveryClient_r Recovery interface invoked when a supervision expires + /// @param [out] supervisions Container to emplace the new alive supervision into + /// @param [in] checkpoint Checkpoint that is part of the supervision + /// @param [in] event Event to observe + /// @param [in] recovery_client Recovery interface invoked when a supervision expires + /// @param [in] component_id ID of the supervised component + /// @param [in] component_config Supervision configuration of the component /// @return Object creation successful (true), otherwise failed (false) - virtual bool createAliveSupervisions( - std::vector& f_alive_r, - std::vector& f_checkpoints_r, - std::vector& f_processStates_r, - std::shared_ptr f_recoveryClient_r) = 0; + virtual bool createAliveSupervision( + std::vector& supervisions, + ifappl::Checkpoint& checkpoint, + ifexm::ObservableEvent& event, + std::shared_ptr recovery_client, + const IdentifierHash component_id, + const ComponentAliveSupervision component_config) = 0; }; } // namespace factory diff --git a/score/launch_manager/src/daemon/src/alive_monitor/details/factory/StaticConfig.hpp b/score/launch_manager/src/daemon/src/alive_monitor/details/factory/StaticConfig.hpp deleted file mode 100644 index 2420305b4..000000000 --- a/score/launch_manager/src/daemon/src/alive_monitor/details/factory/StaticConfig.hpp +++ /dev/null @@ -1,67 +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 STATICCONFIG_HPP_INCLUDED -#define STATICCONFIG_HPP_INCLUDED - -#include - -#include "score/mw/launch_manager/alive_monitor/details/ifappl/DataStructures.hpp" -#include "score/mw/launch_manager/alive_monitor/details/timers/Timers_OsClock.hpp" - -namespace score -{ -namespace mw::lifecycle::internal -{ -namespace saf -{ -namespace factory -{ - -struct SupervisionBufferConfig -{ - /// @brief Configured buffer size for alive supervisions - std::uint16_t bufferSizeAliveSupervision{}; - /// @brief Configured buffer size for Monitor entities - std::uint16_t bufferSizeMonitor{}; -}; - -/// @brief Static configurations -/// @details Configuration parameters which are currently not extracted from the configuration -/// and default parameters values for optional configurations. -class StaticConfig -{ - public: - /// Default buffer size of Alive Supervision checkpoint buffer - static constexpr uint16_t k_DefaultAliveSupCheckpointBufferElements{100U}; - /// Default buffer size of a Monitor (shared memory) - static constexpr uint16_t k_DefaultMonitorBufferElements{ifappl::k_maxCheckpointBufferElements}; - - /// Default checkpoint ID used when creating supervision checkpoints - static constexpr uint32_t k_DefaultCheckpointId{1U}; - - /// @brief By default hm daemon shutdown is disabled - static constexpr bool k_hmDaemonDefaultShutdownEnabled{false}; - - /// @brief Defaults for supervision buffer sizes - static constexpr SupervisionBufferConfig kDefaultSupervisionBufferConfig{ - StaticConfig::k_DefaultAliveSupCheckpointBufferElements, - StaticConfig::k_DefaultMonitorBufferElements}; -}; - -} // namespace factory -} // namespace saf -} // namespace mw::lifecycle::internal -} // namespace score - -#endif diff --git a/score/launch_manager/src/daemon/src/alive_monitor/details/ifappl/Checkpoint.cpp b/score/launch_manager/src/daemon/src/alive_monitor/details/ifappl/Checkpoint.cpp index 4bee7c508..685e36727 100644 --- a/score/launch_manager/src/daemon/src/alive_monitor/details/ifappl/Checkpoint.cpp +++ b/score/launch_manager/src/daemon/src/alive_monitor/details/ifappl/Checkpoint.cpp @@ -18,11 +18,9 @@ namespace score::mw::lifecycle::internal::saf::ifappl Checkpoint::Checkpoint( const char* const f_checkpointCfgName_p, - const uint32_t f_checkpointId, const ifexm::ObservableEvent* f_processState_p) noexcept(false) : Observable(), k_configName(f_checkpointCfgName_p), - k_checkpointId(f_checkpointId), processState(f_processState_p), isDataLossEvent(false), timestamp(0U) @@ -30,11 +28,6 @@ Checkpoint::Checkpoint( static_cast(0U); } -uint32_t Checkpoint::getId(void) const noexcept(true) -{ - return k_checkpointId; -} - timers::NanoSecondType Checkpoint::getTimestamp(void) const noexcept(true) { return timestamp; diff --git a/score/launch_manager/src/daemon/src/alive_monitor/details/ifappl/Checkpoint.hpp b/score/launch_manager/src/daemon/src/alive_monitor/details/ifappl/Checkpoint.hpp index 29a873a95..5c2b81fe4 100644 --- a/score/launch_manager/src/daemon/src/alive_monitor/details/ifappl/Checkpoint.hpp +++ b/score/launch_manager/src/daemon/src/alive_monitor/details/ifappl/Checkpoint.hpp @@ -51,13 +51,9 @@ class Checkpoint : public saf::common::Observable /// @brief Constructor /// @param [in] f_checkpointCfgName_p Name of the corresponding configured supervision checkpoint container - /// @param [in] f_checkpointId ID of checkpoint /// @param [in] f_processState_p The process that is reporting this checkpoint /// @throws std::bad_alloc in case of insufficient memory for string allocation - Checkpoint( - const char* const f_checkpointCfgName_p, - const uint32_t f_checkpointId, - const ifexm::ObservableEvent* f_processState_p) noexcept(false); + Checkpoint(const char* const f_checkpointCfgName_p, const ifexm::ObservableEvent* f_processState_p) noexcept(false); /// @brief Default Move Constructor /// Cannot be noexcept, since the base class move constructor is not noexcept @@ -72,10 +68,6 @@ class Checkpoint : public saf::common::Observable /// @brief Default Destructor ~Checkpoint() override = default; - /// @brief Get checkpoint ID - /// @return uint32_t ID of checkpoint - uint32_t getId(void) const noexcept(true); - /// @brief Get timestamp /// @return NanoSecondType Timestamp value of the reported checkpoint in [nano seconds] score::mw::lifecycle::internal::saf::timers::NanoSecondType getTimestamp(void) const noexcept(true); @@ -106,9 +98,6 @@ class Checkpoint : public saf::common::Observable /// @brief Name of the corresponding configured SupervisionCheckpoint const std::string k_configName; - /// @brief Checkpoint identification - const uint32_t k_checkpointId; - /// @brief The process that is reporting this checkpoint const ifexm::ObservableEvent* processState; diff --git a/score/launch_manager/src/daemon/src/alive_monitor/details/ifappl/DataStructures.hpp b/score/launch_manager/src/daemon/src/alive_monitor/details/ifappl/DataStructures.hpp index 51f7d13f1..5efb5d08c 100644 --- a/score/launch_manager/src/daemon/src/alive_monitor/details/ifappl/DataStructures.hpp +++ b/score/launch_manager/src/daemon/src/alive_monitor/details/ifappl/DataStructures.hpp @@ -42,19 +42,14 @@ constexpr uint16_t k_maxCheckpointBufferElements{512U}; required for Vector and IPC APIs", true_no_defect) */ struct CheckpointBufferElement final { - score::mw::lifecycle::internal::saf::timers::NanoSecondType timestamp{0U}; ///< Timestamp - uint32_t checkpointId{0U}; ///< Checkpoint ID + internal::saf::timers::NanoSecondType timestamp{0U}; ///< Timestamp /// @brief Default constructor needed for storage in vector CheckpointBufferElement() = default; /// @brief Constructor for usage with emplace /// @param [in] f_timestamp The checkpoint timestamp - /// @param [in] f_checkpointId The checkpoint id - CheckpointBufferElement( - score::mw::lifecycle::internal::saf::timers::NanoSecondType f_timestamp, - uint32_t f_checkpointId) noexcept(true) - : timestamp(f_timestamp), checkpointId(f_checkpointId) + CheckpointBufferElement(internal::saf::timers::NanoSecondType f_timestamp) noexcept(true) : timestamp(f_timestamp) { } }; diff --git a/score/launch_manager/src/daemon/src/alive_monitor/details/ifappl/MonitorIfDaemon.cpp b/score/launch_manager/src/daemon/src/alive_monitor/details/ifappl/MonitorIfDaemon.cpp index 379f924af..68ecede39 100644 --- a/score/launch_manager/src/daemon/src/alive_monitor/details/ifappl/MonitorIfDaemon.cpp +++ b/score/launch_manager/src/daemon/src/alive_monitor/details/ifappl/MonitorIfDaemon.cpp @@ -122,10 +122,7 @@ void MonitorIfDaemon::pushCheckpointToObservers(CheckpointBufferElement& f_elem_ { for (auto& observer : checkpointObservers) { - if (f_elem_r.checkpointId == observer->getId()) - { - observer->pushData(f_elem_r.timestamp); - } + observer->pushData(f_elem_r.timestamp); } } diff --git a/score/launch_manager/src/daemon/src/alive_monitor/details/ifappl/MonitorIfDaemon_UT.cpp b/score/launch_manager/src/daemon/src/alive_monitor/details/ifappl/MonitorIfDaemon_UT.cpp index ca72c932f..e06fee7ae 100644 --- a/score/launch_manager/src/daemon/src/alive_monitor/details/ifappl/MonitorIfDaemon_UT.cpp +++ b/score/launch_manager/src/daemon/src/alive_monitor/details/ifappl/MonitorIfDaemon_UT.cpp @@ -48,7 +48,6 @@ class CheckpointMock : public common::Observer struct MonitorIfDaemonFixture { static constexpr std::string_view kCheckpointName = "test_cp"; - static constexpr uint32_t kCheckpointId = 1U; inline static const IdentifierHash kProcessId{"test_proc"}; static constexpr std::string_view kInterfaceName = "test_interface"; @@ -60,7 +59,7 @@ struct MonitorIfDaemonFixture MonitorIfDaemonFixture() : processState(kProcessId), - checkpoint(kCheckpointName.data(), kCheckpointId, &processState), + checkpoint(kCheckpointName.data(), &processState), ipcServer{}, monitor(ipcServer, kInterfaceName.data()) { @@ -93,9 +92,9 @@ struct MonitorIfDaemonFixture } /// Write a single checkpoint element into the IPC ring buffer. - void sendCheckpoint(uint32_t id, timers::NanoSecondType ts) + void sendCheckpoint(timers::NanoSecondType ts) { - ipcServer.sendEmplace(ts, id); + ipcServer.sendEmplace(ts); } /// Fill the IPC ring buffer past its capacity to set the overflow flag. @@ -104,7 +103,7 @@ struct MonitorIfDaemonFixture // Sending one element beyond capacity sets the ring-buffer overflow flag. for (uint32_t i = 0U; i <= ifappl::k_maxCheckpointBufferElements; ++i) { - ipcServer.sendEmplace(static_cast(i), 0U); + ipcServer.sendEmplace(static_cast(i)); } } }; @@ -187,7 +186,7 @@ TEST_F(MonitorIfDaemonTest, DeactivationBeforeActivation_RemainsInactive) fix.deactivateProcess(mockClock()); fix.monitor.checkForNewData(mockClock()); - fix.sendCheckpoint(MonitorIfDaemonFixture::kCheckpointId, mockClockOffset()); + fix.sendCheckpoint(mockClockOffset()); fix.monitor.checkForNewData(mockClock()); } @@ -203,7 +202,7 @@ TEST_F(MonitorIfDaemonTest, ActivationEvent_ActivatesMonitorOnNextCheckForNewDat fix.initIpc(); fix.activateProcess(mockClock()); const auto checkpoint_time = mockClockOffset(); - fix.sendCheckpoint(MonitorIfDaemonFixture::kCheckpointId, checkpoint_time); + fix.sendCheckpoint(checkpoint_time); fix.monitor.checkForNewData(mockClock()); // activates AND reads in the same call EXPECT_EQ(fix.checkpoint.getTimestamp(), checkpoint_time); @@ -227,7 +226,7 @@ TEST_F(MonitorIfDaemonTest, DeactivationEvent_DeactivatesMonitor_NoFurtherDataFo fix.monitor.checkForNewData(mockClock()); // reads remaining data, then -> kInactive // Data written AFTER the deactivation cycle must not reach the checkpoint. - fix.sendCheckpoint(MonitorIfDaemonFixture::kCheckpointId, mockClockOffset()); + fix.sendCheckpoint(mockClockOffset()); fix.monitor.checkForNewData(mockClock()); // kInactive, nothing read } @@ -243,7 +242,7 @@ TEST_F(MonitorIfDaemonTest, Active_CheckpointDataForwarded) fix.initIpc(); fix.activateProcess(mockClock()); const auto checkpoint_time = mockClock(); - fix.sendCheckpoint(MonitorIfDaemonFixture::kCheckpointId, checkpoint_time); + fix.sendCheckpoint(checkpoint_time); fix.monitor.checkForNewData(mockClock()); EXPECT_EQ(fix.checkpoint.getTimestamp(), checkpoint_time); @@ -259,7 +258,7 @@ TEST_F(MonitorIfDaemonTest, Active_FutureTimestamp_NotForwardedInCurrentCycle) EXPECT_CALL(fix.checkpointMock, updateData).Times(Exactly(0)); fix.initIpc(); fix.activateProcess(mockClock()); - fix.sendCheckpoint(MonitorIfDaemonFixture::kCheckpointId, mockClockFuture(5)); + fix.sendCheckpoint(mockClockFuture(5)); fix.monitor.checkForNewData(mockClock()); // future checkpoint not consumed } @@ -275,30 +274,13 @@ TEST_F(MonitorIfDaemonTest, Active_FutureTimestampCheckpoint_ConsumedInLaterCycl fix.initIpc(); fix.activateProcess(mockClock()); const auto future_time = mockClockFuture(2); - fix.sendCheckpoint(MonitorIfDaemonFixture::kCheckpointId, future_time); + fix.sendCheckpoint(future_time); fix.monitor.checkForNewData(mockClock()); // not consumed yet mockClockSkip(2); fix.monitor.checkForNewData(mockClock()); // now within window -> consumed EXPECT_EQ(fix.checkpoint.getTimestamp(), future_time); } -TEST_F(MonitorIfDaemonTest, Active_NonMatchingCheckpointId_NotForwarded) -{ - RecordProperty( - "Description", - "An IPC element whose checkpointId does not match any attached " - "Checkpoint must be silently discarded."); - - constexpr uint32_t kNonMatchingId = 99U; - - MonitorIfDaemonFixture fix; - EXPECT_CALL(fix.checkpointMock, updateData).Times(Exactly(0)); - fix.initIpc(); - fix.activateProcess(mockClock()); - fix.sendCheckpoint(kNonMatchingId, mockClock()); - fix.monitor.checkForNewData(mockClock()); -} - TEST_F(MonitorIfDaemonTest, Active_MultipleCheckpointsInOneCycle_AllForwarded) { RecordProperty( @@ -310,35 +292,9 @@ TEST_F(MonitorIfDaemonTest, Active_MultipleCheckpointsInOneCycle_AllForwarded) EXPECT_CALL(fix.checkpointMock, updateData).Times(3); fix.initIpc(); fix.activateProcess(mockClock()); - fix.sendCheckpoint(MonitorIfDaemonFixture::kCheckpointId, mockClock()); - fix.sendCheckpoint(MonitorIfDaemonFixture::kCheckpointId, mockClock()); - fix.sendCheckpoint(MonitorIfDaemonFixture::kCheckpointId, mockClock()); - fix.monitor.checkForNewData(mockClock()); -} - -TEST_F(MonitorIfDaemonTest, Active_TwoAttachedCheckpoints_RoutedByCheckpointId) -{ - RecordProperty( - "Description", - "When two Checkpoints with different IDs are attached, each IPC " - "element must be forwarded only to the Checkpoint whose ID matches."); - - constexpr uint32_t kCheckpointId2 = 2U; - - MonitorIfDaemonFixture fix; - EXPECT_CALL(fix.checkpointMock, updateData).Times(1); - fix.initIpc(); - - ifappl::Checkpoint checkpoint2("test_cp2", kCheckpointId2, &fix.processState); - CheckpointMock mock2; - EXPECT_CALL(mock2, updateData).Times(1); - checkpoint2.attachObserver(mock2); - fix.monitor.attachCheckpoint(checkpoint2); - - fix.activateProcess(mockClock()); - const auto checkpoint_time = mockClock(); - fix.sendCheckpoint(MonitorIfDaemonFixture::kCheckpointId, checkpoint_time); - fix.sendCheckpoint(kCheckpointId2, checkpoint_time); + fix.sendCheckpoint(mockClock()); + fix.sendCheckpoint(mockClock()); + fix.sendCheckpoint(mockClock()); fix.monitor.checkForNewData(mockClock()); } diff --git a/score/launch_manager/src/daemon/src/alive_monitor/details/supervision/Alive.cpp b/score/launch_manager/src/daemon/src/alive_monitor/details/supervision/Alive.cpp index 433c6308b..bc14611cc 100644 --- a/score/launch_manager/src/daemon/src/alive_monitor/details/supervision/Alive.cpp +++ b/score/launch_manager/src/daemon/src/alive_monitor/details/supervision/Alive.cpp @@ -24,19 +24,23 @@ namespace score::mw::lifecycle::internal::saf::supervision { -Alive::Alive(const AliveSupervisionCfg& f_aliveCfg_r) - : ISupervision(f_aliveCfg_r.cfgName_p), - k_aliveReferenceCycle(f_aliveCfg_r.aliveReferenceCycle), - k_minAliveIndications(f_aliveCfg_r.minAliveIndications), - k_maxAliveIndications(f_aliveCfg_r.maxAliveIndications), - k_isMinCheckDisabled(f_aliveCfg_r.isMinCheckDisabled), - k_isMaxCheckDisabled(f_aliveCfg_r.isMaxCheckDisabled), - k_failedSupervisionCyclesTolerance(f_aliveCfg_r.failedCyclesTolerance), - recoveryClient_p(f_aliveCfg_r.recoveryClient), - processIdentifier_(f_aliveCfg_r.processIdentifier), - timeSortingUpdateEventBuffer(common::TimeSortingBuffer(f_aliveCfg_r.checkpointBufferSize)) +Alive::Alive( + const IdentifierHash id, + const ComponentAliveSupervision& f_aliveCfg_r, + const std::shared_ptr recovery_client, + saf::ifappl::Checkpoint& checkpoint_r) + : ISupervision(id), + k_aliveReferenceCycle(timers::TimeConversion::convertMilliSecToNanoSec(f_aliveCfg_r.reporting_cycle_ms)), + k_minAliveIndications(f_aliveCfg_r.min_indications.value_or(0)), + k_maxAliveIndications(f_aliveCfg_r.max_indications.value_or(0)), + k_isMinCheckDisabled(k_minAliveIndications == 0), + k_isMaxCheckDisabled(k_maxAliveIndications == 0), + k_failedSupervisionCyclesTolerance(f_aliveCfg_r.failed_cycles_tolerance), + recoveryClient_p(recovery_client), + processIdentifier_(id), + timeSortingUpdateEventBuffer(common::TimeSortingBuffer(100U)) { - f_aliveCfg_r.checkpoint_r.attachObserver(*this); + checkpoint_r.attachObserver(*this); SCORE_LANGUAGE_FUTURECPP_PRECONDITION_PRD_MESSAGE( (k_aliveReferenceCycle != 0U), "k_aliveReferenceCycle=0 causes infinite loop during evaluation."); diff --git a/score/launch_manager/src/daemon/src/alive_monitor/details/supervision/Alive.hpp b/score/launch_manager/src/daemon/src/alive_monitor/details/supervision/Alive.hpp index 52b08135e..c20f9ba08 100644 --- a/score/launch_manager/src/daemon/src/alive_monitor/details/supervision/Alive.hpp +++ b/score/launch_manager/src/daemon/src/alive_monitor/details/supervision/Alive.hpp @@ -22,8 +22,9 @@ #include "score/mw/launch_manager/alive_monitor/details/ifappl/Checkpoint.hpp" #include "score/mw/launch_manager/alive_monitor/details/ifexm/ObservableEvent.hpp" #include "score/mw/launch_manager/alive_monitor/details/supervision/ISupervision.hpp" -#include "score/mw/launch_manager/alive_monitor/details/supervision/SupervisionCfg.hpp" #include "score/mw/launch_manager/alive_monitor/details/timers/Timers_OsClock.hpp" +#include "score/mw/launch_manager/configuration/config.hpp" +#include "score/mw/launch_manager/recovery_client/irecovery_client.h" namespace score { @@ -34,6 +35,8 @@ namespace saf namespace supervision { +using configuration::ComponentAliveSupervision; + /// @brief Alive Supervision /// @details Alive Supervision contains the logic for health monitoring - Alive supervision /* RULECHECKER_comment(0, 11, check_source_character_set, "Special character in comment is mandatory\ @@ -76,9 +79,15 @@ class Alive : public ISupervision, Alive& operator=(const Alive&) = delete; /// @brief Constructor + /// @param [in] id Id of the component to monitor /// @param [in] f_aliveCfg_r Alive Supervision configuration structure + /// @param [in] recovery_client Client to notify in case of a supervision failure /// @warning Constructor may throw std::exceptions - explicit Alive(const AliveSupervisionCfg& f_aliveCfg_r) noexcept(false); + explicit Alive( + const IdentifierHash id, + const ComponentAliveSupervision& f_aliveCfg_r, + const std::shared_ptr recovery_client, + saf::ifappl::Checkpoint& checkpoint_r) noexcept(false); /// @brief Destructor /* RULECHECKER_comment(0, 3, check_min_instructions, "Default destructor is not provided\ diff --git a/score/launch_manager/src/daemon/src/alive_monitor/details/supervision/Alive_UT.cpp b/score/launch_manager/src/daemon/src/alive_monitor/details/supervision/Alive_UT.cpp index 81b59fa4f..6531650b1 100644 --- a/score/launch_manager/src/daemon/src/alive_monitor/details/supervision/Alive_UT.cpp +++ b/score/launch_manager/src/daemon/src/alive_monitor/details/supervision/Alive_UT.cpp @@ -20,13 +20,13 @@ #include "score/mw/launch_manager/alive_monitor/details/ifappl/Checkpoint.hpp" #include "score/mw/launch_manager/alive_monitor/details/ifexm/ObservableEvent.hpp" #include "score/mw/launch_manager/alive_monitor/details/supervision/Alive.hpp" -#include "score/mw/launch_manager/alive_monitor/details/supervision/SupervisionCfg.hpp" #include "score/mw/launch_manager/common/identifier_hash.hpp" #include "score/mw/launch_manager/recovery_client/irecovery_client.h" using namespace testing; using EStatus = score::mw::lifecycle::internal::saf::supervision::Alive::EStatus; +using score::mw::lifecycle::internal::configuration::ComponentAliveSupervision; namespace { @@ -96,21 +96,15 @@ struct AliveFixture std::unique_ptr alive; - explicit AliveFixture(const Builder& bld) : processState(kProcessId), checkpoint(kCheckpointName, 1U, &processState) + explicit AliveFixture(const Builder& bld) : processState(kProcessId), checkpoint(kCheckpointName, &processState) { - score::mw::lifecycle::internal::saf::supervision::AliveSupervisionCfg cfg{checkpoint}; - cfg.cfgName_p = "test_alive"; - cfg.aliveReferenceCycle = bld.referenceCycleNs; - cfg.minAliveIndications = bld.minIndications; - cfg.maxAliveIndications = bld.maxIndications; - cfg.isMinCheckDisabled = (bld.minIndications == 0U); - cfg.isMaxCheckDisabled = (bld.maxIndications == 0U); - cfg.failedCyclesTolerance = bld.failedCyclesTolerance; - cfg.checkpointBufferSize = 16U; - cfg.recoveryClient = mockClient; - cfg.processIdentifier = kProcessIdentifier; - - alive = std::make_unique(cfg); + ComponentAliveSupervision cfg{}; + cfg.min_indications = bld.minIndications; + cfg.max_indications = bld.maxIndications; + cfg.failed_cycles_tolerance = bld.failedCyclesTolerance; + + alive = std::make_unique( + kProcessIdentifier, cfg, mockClient, checkpoint); processState.attachObserver(*alive); } diff --git a/score/launch_manager/src/daemon/src/alive_monitor/details/supervision/BUILD b/score/launch_manager/src/daemon/src/alive_monitor/details/supervision/BUILD index 2822a105e..7c776c635 100644 --- a/score/launch_manager/src/daemon/src/alive_monitor/details/supervision/BUILD +++ b/score/launch_manager/src/daemon/src/alive_monitor/details/supervision/BUILD @@ -13,18 +13,6 @@ load("@rules_cc//cc:defs.bzl", "cc_library") load("//tests/utils/bazel:unit_test.bzl", "lm_cc_test") -cc_library( - name = "supervision_cfg", - hdrs = ["SupervisionCfg.hpp"], - include_prefix = "score/mw/launch_manager/alive_monitor/details/supervision", - strip_include_prefix = "/score/launch_manager/src/daemon/src/alive_monitor/details/supervision", - visibility = ["//score/launch_manager/src/daemon/src/alive_monitor:__subpackages__"], - deps = [ - "//score/launch_manager/src/daemon/src/alive_monitor/details/ifexm:observable_event", - "//score/launch_manager/src/daemon/src/alive_monitor/details/timers:timers_os_clock", - ], -) - cc_library( name = "i_supervision", srcs = ["ISupervision.cpp"], @@ -34,6 +22,7 @@ cc_library( visibility = ["//score/launch_manager/src/daemon/src/alive_monitor:__subpackages__"], deps = [ "//score/launch_manager/src/daemon/src/alive_monitor/details/timers:timers_os_clock", + "//score/launch_manager/src/daemon/src/common:identifier_hash", ], ) @@ -46,13 +35,13 @@ cc_library( visibility = ["//score/launch_manager/src/daemon/src/alive_monitor:__subpackages__"], deps = [ ":i_supervision", - ":supervision_cfg", "//score/launch_manager/src/daemon/src/alive_monitor/details/common:time_sorting_buffer", "//score/launch_manager/src/daemon/src/alive_monitor/details/ifappl:checkpoint", "//score/launch_manager/src/daemon/src/alive_monitor/details/ifexm:observable_event", "//score/launch_manager/src/daemon/src/alive_monitor/details/timers:timers_os_clock", "//score/launch_manager/src/daemon/src/common:log", - "//score/launch_manager/src/daemon/src/recovery_client", + "//score/launch_manager/src/daemon/src/configuration:config", + "//score/launch_manager/src/daemon/src/recovery_client:irecovery_client", "@score_baselibs//score/language/futurecpp", ], ) diff --git a/score/launch_manager/src/daemon/src/alive_monitor/details/supervision/ISupervision.cpp b/score/launch_manager/src/daemon/src/alive_monitor/details/supervision/ISupervision.cpp index 9ae00e24e..304112727 100644 --- a/score/launch_manager/src/daemon/src/alive_monitor/details/supervision/ISupervision.cpp +++ b/score/launch_manager/src/daemon/src/alive_monitor/details/supervision/ISupervision.cpp @@ -16,13 +16,13 @@ namespace score::mw::lifecycle::internal::saf::supervision { -ISupervision::ISupervision(const char* const f_supervisionConfigName_p) : k_cfgName(f_supervisionConfigName_p) +ISupervision::ISupervision(const IdentifierHash f_supervisionConfigName_p) : k_cfgName(f_supervisionConfigName_p) { // Satisfy Misra for minimum number of instructions static_cast(0); } -std::string_view ISupervision::getConfigName(void) const noexcept +IdentifierHash ISupervision::getConfigName(void) const noexcept { return k_cfgName; } diff --git a/score/launch_manager/src/daemon/src/alive_monitor/details/supervision/ISupervision.hpp b/score/launch_manager/src/daemon/src/alive_monitor/details/supervision/ISupervision.hpp index e4df44e98..b8dc39940 100644 --- a/score/launch_manager/src/daemon/src/alive_monitor/details/supervision/ISupervision.hpp +++ b/score/launch_manager/src/daemon/src/alive_monitor/details/supervision/ISupervision.hpp @@ -17,6 +17,7 @@ #include #include "score/mw/launch_manager/alive_monitor/details/timers/Timers_OsClock.hpp" +#include "score/mw/launch_manager/common/identifier_hash.hpp" #include #include #include @@ -42,7 +43,7 @@ class ISupervision /// @brief Constructor /// @param [in] f_supervisionConfigName_p Unique name set by configuration /// @warning Constructor may throw std::exceptions - explicit ISupervision(const char* const f_supervisionConfigName_p) noexcept(false); + explicit ISupervision(const IdentifierHash f_supervisionConfigName_p) noexcept(false); /// @brief Default destructor /* RULECHECKER_comment(0, 3, check_min_instructions, "Default destructor is not provided\ @@ -58,7 +59,7 @@ class ISupervision /// @brief Get the name of the configuration element for the corresponding supervision container /// @return std::string_view View over the name of the corresponding supervision configuration container - std::string_view getConfigName(void) const noexcept; + IdentifierHash getConfigName(void) const noexcept; protected: /// @brief Default Move Constructor @@ -78,7 +79,7 @@ class ISupervision private: /// Unique name set by configuration - const std::string k_cfgName; + const IdentifierHash k_cfgName; }; } // namespace supervision diff --git a/score/launch_manager/src/daemon/src/alive_monitor/details/supervision/SupervisionCfg.hpp b/score/launch_manager/src/daemon/src/alive_monitor/details/supervision/SupervisionCfg.hpp deleted file mode 100644 index bce116ce4..000000000 --- a/score/launch_manager/src/daemon/src/alive_monitor/details/supervision/SupervisionCfg.hpp +++ /dev/null @@ -1,103 +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 SUPERVISIONCFG_HPP_INCLUDED -#define SUPERVISIONCFG_HPP_INCLUDED - -#include - -#include "score/mw/launch_manager/alive_monitor/details/ifexm/ObservableEvent.hpp" -#include "score/mw/launch_manager/alive_monitor/details/timers/Timers_OsClock.hpp" -#include "score/mw/launch_manager/recovery_client/irecovery_client.h" - -namespace score -{ -namespace mw::lifecycle::internal -{ -namespace saf -{ -namespace ifappl -{ -class Checkpoint; -} -namespace supervision -{ - -/* RULECHECKER_comment(0, 140, check_non_private_non_pod_field, "Supervision configuration are intended to be\ - data classes therefore scope is set intentionally to public.", true_no_defect) */ -/* RULECHECKER_comment(0, 140, check_scattered_data_member_initialization, "All POD values are initialized\ - during declaration, only references are set via constructor.", false) */ -/* RULECHECKER_comment(0, 140, check_mixed_non_static_data_member_initialization, "All POD values are initialized\ -during declaration, only references are set via constructor.", false) */ - -/// Alive Supervision configuration structure -class AliveSupervisionCfg final -{ - public: - /// Unique name set by configuration - const char* cfgName_p{nullptr}; - /// Number of elements which can be stored in the checkpoint buffer - uint16_t checkpointBufferSize{0U}; - - /// (Manifest Parameter) Alive reference cycle in [nano seconds] - saf::timers::NanoSecondType aliveReferenceCycle{0U}; - /// (Manifest Parameter) Minimum alive indications - uint32_t minAliveIndications{0U}; - /// (Manifest Parameter) Maximum alive indications - uint32_t maxAliveIndications{UINT32_MAX}; - /// Flag for disabled status for minimum alive indication check - bool isMinCheckDisabled{false}; - /// Flag for disabled status for maximum alive indication check - bool isMaxCheckDisabled{false}; - /// (Manifest Parameter) Failed supervision cycle tolerance - uint32_t failedCyclesTolerance{0U}; - /// Reference to checkpoint object - saf::ifappl::Checkpoint& checkpoint_r; - - /// Recovery client to invoke when supervision expires - std::shared_ptr recoveryClient{}; - /// Identifier of the supervised process, sent via recovery client when supervision expires - score::mw::lifecycle::IdentifierHash processIdentifier{}; - - /// Default destructor - ~AliveSupervisionCfg() = default; - - /// No Default Constructor - AliveSupervisionCfg() = delete; - - /// Alive Supervision configuration constructor - /// @param [in] f_checkpoint_r Reference to checkpoint object - explicit AliveSupervisionCfg(saf::ifappl::Checkpoint& f_checkpoint_r) : checkpoint_r(f_checkpoint_r) - { - } - - protected: - /// Default copy constructor - /* RULECHECKER_comment(0, 4, check_incomplete_data_member_construction, "All data members are initialized - by default copy constructor.", false) */ - /* RULECHECKER_comment(0, 2, check_unused_parameter, "Parameter is used.", false) */ - AliveSupervisionCfg(const AliveSupervisionCfg& cfg) = default; - /// No copy assignment operator - AliveSupervisionCfg& operator=(const AliveSupervisionCfg&) = delete; - /// No move constructor - AliveSupervisionCfg(AliveSupervisionCfg&&) = delete; - /// No move assignment operator - AliveSupervisionCfg& operator=(AliveSupervisionCfg&&) = delete; -}; - -} // namespace supervision -} // namespace saf -} // namespace mw::lifecycle::internal -} // namespace score - -#endif diff --git a/score/launch_manager/src/daemon/src/common/alive_interface_path.hpp b/score/launch_manager/src/daemon/src/common/alive_interface_path.hpp index eb1f15e74..907308263 100644 --- a/score/launch_manager/src/daemon/src/common/alive_interface_path.hpp +++ b/score/launch_manager/src/daemon/src/common/alive_interface_path.hpp @@ -14,6 +14,7 @@ #ifndef ALIVE_INTERFACE_PATH_HPP_INCLUDED #define ALIVE_INTERFACE_PATH_HPP_INCLUDED +#include "score/mw/launch_manager/common/identifier_hash.hpp" #include namespace score @@ -24,9 +25,16 @@ namespace internal { /// Returns the IPC socket path for the alive monitoring interface of a component. -inline std::string aliveInterfacePath(const std::string& component_name) +inline std::string aliveInterfacePath(const IdentifierHash& component_name) { - return "/lifecycle_health_" + component_name; + const std::lock_guard lock(IdentifierHash::get_registry_mutex()); + const auto& reg = IdentifierHash::get_registry(); + const auto it = reg.find(component_name.data()); + if (it != reg.end()) + { + return "/lifecycle_health_" + it->second; + } + return "/lifecycle_health_" + std::to_string(component_name.data()); } } // namespace internal diff --git a/score/launch_manager/src/daemon/src/configuration/configuration_adapter.cpp b/score/launch_manager/src/daemon/src/configuration/configuration_adapter.cpp index 20564194b..296795e85 100644 --- a/score/launch_manager/src/daemon/src/configuration/configuration_adapter.cpp +++ b/score/launch_manager/src/daemon/src/configuration/configuration_adapter.cpp @@ -171,8 +171,8 @@ void ConfigurationAdapter::appendAliveInterfaceEnvironment( return; } - std::string iface_path = - std::string(kAliveInterfaceEnvName) + "=" + score::mw::lifecycle::internal::aliveInterfacePath(comp.name); + std::string iface_path = std::string(kAliveInterfaceEnvName) + "=" + + mw::lifecycle::internal::aliveInterfacePath(IdentifierHash{comp.name}); startup.envp_[env_index++] = strdup(iface_path.c_str()); } diff --git a/score/launch_manager/src/daemon/src/recovery_client/BUILD b/score/launch_manager/src/daemon/src/recovery_client/BUILD index 48a69de9b..514f73769 100644 --- a/score/launch_manager/src/daemon/src/recovery_client/BUILD +++ b/score/launch_manager/src/daemon/src/recovery_client/BUILD @@ -13,13 +13,27 @@ load("@rules_cc//cc:defs.bzl", "cc_library") load("//tests/utils/bazel:unit_test.bzl", "lm_cc_test") +cc_library( + name = "irecovery_client", + hdrs = [ + "irecovery_client.h", + ], + include_prefix = "score/mw/launch_manager/recovery_client", + strip_include_prefix = "/score/launch_manager/src/daemon/src/recovery_client", + visibility = [ + "//score:__subpackages__", + ], + deps = [ + "//score/launch_manager/src/daemon/src/common:identifier_hash", + ], +) + cc_library( name = "recovery_client", srcs = [ "recovery_client.cpp", ], hdrs = [ - "irecovery_client.h", "recovery_client.hpp", ], include_prefix = "score/mw/launch_manager/recovery_client", @@ -28,7 +42,7 @@ cc_library( "//score:__subpackages__", ], deps = [ - "//score/launch_manager/src/daemon/src/common:identifier_hash", + ":irecovery_client", ], ) diff --git a/tests/integration/readme.md b/tests/integration/readme.md index 92d514dd3..e414c935e 100644 --- a/tests/integration/readme.md +++ b/tests/integration/readme.md @@ -11,8 +11,6 @@ SPDX-License-Identifier: Apache-2.0 ----------------------------------------------------------------------------- --> -# Local integration testing - ## Running the integration tests To run all tests, simply run `bazel test //tests/integration/... --config=x86_64-linux` @@ -23,3 +21,6 @@ Currently the following configs are supported: - `host` - `x86_64-linux` +## Debugging + +Using `config=host`, `--sandbox_add_mount_pair=/tmp`, and `--compilation_mode=dbg` tests and their binaries will be written to `/tmp/tests/`. From the test name directory, launch manager can be started with gdb using the following command: `sudo gdb --args ./launch_manager -c etc/.bin`. This should load debug symbols and allow breakpoints to be set. If `layout src` fails to load source files, use `dir ` to point gdb to the correct location \ No newline at end of file