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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .bazelrc
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ build --credential_helper=*.qnx.com=%workspace%/scripts/internal/qnx_creds.py

# Common test flags for all platforms
test --test_output=errors
test --@score_baselibs//score/mw/log/flags:KRemote_Logging=False
test --@score_logging//score/mw/log/flags:KRemote_Logging=False
test --@score_baselibs//score/json:base_library=nlohmann
test --cxxopt=-Wno-deprecated-declarations

Expand All @@ -36,7 +36,7 @@ build:toolchain_common --incompatible_strict_action_env
build:toolchain_common --host_platform=@score_bazel_platforms//:x86_64-linux
## Ferrocene must be common compiler for HOST. To ensure metadata compatibility for proc macro crate
build:toolchain_common --extra_toolchains=@score_toolchains_rust//toolchains/ferrocene:ferrocene_x86_64_unknown_linux_gnu
build:stub --@score_baselibs//score/mw/log/flags:KRemote_Logging=False
build:stub --@score_logging//score/mw/log/flags:KRemote_Logging=False
build:stub --@score_baselibs//score/json:base_library=nlohmann

# Target configuration for CPU:x86-64|OS:Linux build (do not use it in case of system toolchains!)
Expand Down
9 changes: 9 additions & 0 deletions MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,15 @@ use_repo(pip, "pip_score_venv_test")

bazel_dep(name = "score_baselibs_rust", version = "0.1.0")
bazel_dep(name = "score_baselibs", version = "0.2.4")
bazel_dep(name = "score_logging", version = "0.1.0")

# TODO: remove once inherited properly from `score_logging`.
bazel_dep(name = "trlc", version = "0.0.0", dev_dependency = True)
git_override(
module_name = "trlc",
commit = "650b51a47264a4f232b3341f473527710fc32669", # trlc-2.0.2 release
remote = "https://github.com/bmw-software-engineering/trlc.git",
)

# Hedron's Compile Commands Extractor for Bazel
# https://github.com/hedronvision/bazel-compile-commands-extractor
Expand Down
551 changes: 551 additions & 0 deletions MODULE.bazel.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/control_client_lib/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,6 @@ cc_library(
"//src/launch_manager_daemon/common:log",
"//src/launch_manager_daemon/common:osal",
"@score_baselibs//score/concurrency/future",
"@score_baselibs//score/mw/log",
"@score_logging//score/mw/log",
],
)
86 changes: 82 additions & 4 deletions src/health_monitoring_lib/rust/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,13 @@
// *******************************************************************************

use crate::deadline::DeadlineEvaluationError;
use crate::heartbeat::HeartbeatEvaluationError;
use crate::log::ScoreDebug;
use crate::tag::MonitorTag;
use core::hash::Hash;
use core::time::Duration;
use std::sync::Arc;
use std::time::Instant;

/// Range of accepted time.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
Expand Down Expand Up @@ -48,7 +50,7 @@ pub(crate) trait Monitor {
#[allow(dead_code)]
pub(crate) enum MonitorEvaluationError {
Deadline(DeadlineEvaluationError),
Heartbeat,
Heartbeat(HeartbeatEvaluationError),
Logic,
}

Expand All @@ -58,12 +60,19 @@ impl From<DeadlineEvaluationError> for MonitorEvaluationError {
}
}

impl From<HeartbeatEvaluationError> for MonitorEvaluationError {
fn from(value: HeartbeatEvaluationError) -> Self {
MonitorEvaluationError::Heartbeat(value)
}
}

/// Trait for evaluating monitors and reporting errors to be used by HealthMonitor.
pub(crate) trait MonitorEvaluator {
/// Run monitor evaluation.
///
/// - `hmon_starting_point` - starting point of all monitors.
/// - `on_error` - error handling, containing tag of failing object and error code.
fn evaluate(&self, on_error: &mut dyn FnMut(&MonitorTag, MonitorEvaluationError));
fn evaluate(&self, hmon_starting_point: Instant, on_error: &mut dyn FnMut(&MonitorTag, MonitorEvaluationError));
}

/// Handle to a monitor evaluator, allowing for dynamic dispatch.
Expand All @@ -78,7 +87,76 @@ impl MonitorEvalHandle {
}

impl MonitorEvaluator for MonitorEvalHandle {
fn evaluate(&self, on_error: &mut dyn FnMut(&MonitorTag, MonitorEvaluationError)) {
self.inner.evaluate(on_error)
fn evaluate(&self, hmon_starting_point: Instant, on_error: &mut dyn FnMut(&MonitorTag, MonitorEvaluationError)) {
self.inner.evaluate(hmon_starting_point, on_error)
}
}

/// Get offset between HMON and monitor starting time points as integers.
pub(crate) fn hmon_time_offset<T>(hmon_starting_point: Instant, monitor_starting_point: Instant) -> T
where
T: TryFrom<u128>,
<T as TryFrom<u128>>::Error: core::fmt::Debug,
{
let result = hmon_starting_point.checked_duration_since(monitor_starting_point);
let duration_since = result.expect("HMON starting point is earlier than monitor starting point");
duration_to_int(duration_since)
}

/// Get duration as an integer.
pub(crate) fn duration_to_int<T>(duration: Duration) -> T
where
T: TryFrom<u128>,
<T as TryFrom<u128>>::Error: core::fmt::Debug,
{
let millis = duration.as_millis();
T::try_from(millis).expect("Monitor running for too long")
}

#[cfg(all(test, not(loom)))]
mod tests {
use crate::common::{duration_to_int, hmon_time_offset};
use core::time::Duration;
use std::time::Instant;

#[test]
fn hmon_time_offset_valid() {
let monitor_starting_point = Instant::now();
let hmon_starting_point = Instant::now();
let offset: u32 = hmon_time_offset(hmon_starting_point, monitor_starting_point);
// Allow small offset.
assert!(offset < 10);
}

#[test]
#[should_panic(expected = "HMON starting point is earlier than monitor starting point")]
fn hmon_time_offset_wrong_order() {
let hmon_starting_point = Instant::now();
let monitor_starting_point = Instant::now();
let _offset: u32 = hmon_time_offset(hmon_starting_point, monitor_starting_point);
}

#[test]
#[should_panic(expected = "Monitor running for too long")]
fn hmon_time_offset_diff_too_large() {
const HUNDRED_DAYS_AS_SECS: u64 = 100 * 24 * 60 * 60;
let monitor_starting_point = Instant::now();
let hmon_starting_point = Instant::now()
.checked_add(Duration::from_secs(HUNDRED_DAYS_AS_SECS))
.unwrap();
let _offset: u32 = hmon_time_offset(hmon_starting_point, monitor_starting_point);
}

#[test]
fn duration_to_int_valid() {
let result: u32 = duration_to_int(Duration::from_millis(1234));
assert_eq!(result, 1234);
}

#[test]
#[should_panic(expected = "Monitor running for too long")]
fn duration_to_int_too_large() {
const HUNDRED_DAYS_AS_SECS: u64 = 100 * 24 * 60 * 60;
let _result: u32 = duration_to_int(Duration::from_secs(HUNDRED_DAYS_AS_SECS));
}
}
Loading
Loading