style(v0.4): rustfmt thermal/protocol/coprocessor/service/integration
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: Alexander <akotenev2003@gmail.com>
This commit is contained in:
@@ -42,7 +42,9 @@ impl SocToMcu {
|
|||||||
pub fn from_wire(t: u8, p: &[u8]) -> Option<Self> {
|
pub fn from_wire(t: u8, p: &[u8]) -> Option<Self> {
|
||||||
match t {
|
match t {
|
||||||
wire::HEARTBEAT => Some(SocToMcu::Heartbeat),
|
wire::HEARTBEAT => Some(SocToMcu::Heartbeat),
|
||||||
wire::SHUTDOWN_IMMINENT => Some(SocToMcu::ShutdownImminent { budget: *p.first()? }),
|
wire::SHUTDOWN_IMMINENT => Some(SocToMcu::ShutdownImminent {
|
||||||
|
budget: *p.first()?,
|
||||||
|
}),
|
||||||
wire::SAFE_TO_CUT => Some(SocToMcu::SafeToCut),
|
wire::SAFE_TO_CUT => Some(SocToMcu::SafeToCut),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
@@ -68,7 +70,9 @@ impl McuToSoc {
|
|||||||
pub fn from_wire(t: u8, p: &[u8]) -> Option<Self> {
|
pub fn from_wire(t: u8, p: &[u8]) -> Option<Self> {
|
||||||
match t {
|
match t {
|
||||||
wire::ACK => Some(McuToSoc::Ack),
|
wire::ACK => Some(McuToSoc::Ack),
|
||||||
wire::ACC => Some(McuToSoc::Acc { on: *p.first()? != 0 }),
|
wire::ACC => Some(McuToSoc::Acc {
|
||||||
|
on: *p.first()? != 0,
|
||||||
|
}),
|
||||||
wire::VOLTAGE => Some(McuToSoc::Voltage {
|
wire::VOLTAGE => Some(McuToSoc::Voltage {
|
||||||
mv: u16::from_be_bytes([*p.first()?, *p.get(1)?]),
|
mv: u16::from_be_bytes([*p.first()?, *p.get(1)?]),
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -303,7 +303,9 @@ impl PowerMock {
|
|||||||
|
|
||||||
/// Тишина линка: SoC-сторона деградирует (лог, не self-cut — red-line). MCU-политика cut-vs-hold — B §12/HW.
|
/// Тишина линка: SoC-сторона деградирует (лог, не self-cut — red-line). MCU-политика cut-vs-hold — B §12/HW.
|
||||||
async fn mcu_link_loss(&self) {
|
async fn mcu_link_loss(&self) {
|
||||||
tracing::warn!("coprocessor: MCU link loss — SoC деградирует (cut-vs-hold политика — HW/§12)");
|
tracing::warn!(
|
||||||
|
"coprocessor: MCU link loss — SoC деградирует (cut-vs-hold политика — HW/§12)"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -230,28 +230,61 @@ mod policy_tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn rises_by_entry_thresholds() {
|
fn rises_by_entry_thresholds() {
|
||||||
assert_eq!(ThermalPolicy::next(ThermalLevel::Normal, 70), ThermalLevel::Normal);
|
assert_eq!(
|
||||||
assert_eq!(ThermalPolicy::next(ThermalLevel::Normal, 75), ThermalLevel::Warn);
|
ThermalPolicy::next(ThermalLevel::Normal, 70),
|
||||||
assert_eq!(ThermalPolicy::next(ThermalLevel::Warn, 85), ThermalLevel::Throttle(1));
|
ThermalLevel::Normal
|
||||||
assert_eq!(ThermalPolicy::next(ThermalLevel::Throttle(1), 95), ThermalLevel::Critical);
|
);
|
||||||
|
assert_eq!(
|
||||||
|
ThermalPolicy::next(ThermalLevel::Normal, 75),
|
||||||
|
ThermalLevel::Warn
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
ThermalPolicy::next(ThermalLevel::Warn, 85),
|
||||||
|
ThermalLevel::Throttle(1)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
ThermalPolicy::next(ThermalLevel::Throttle(1), 95),
|
||||||
|
ThermalLevel::Critical
|
||||||
|
);
|
||||||
// прыжок вверх через банды
|
// прыжок вверх через банды
|
||||||
assert_eq!(ThermalPolicy::next(ThermalLevel::Normal, 99), ThermalLevel::Critical);
|
assert_eq!(
|
||||||
|
ThermalPolicy::next(ThermalLevel::Normal, 99),
|
||||||
|
ThermalLevel::Critical
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn hysteresis_holds_until_below_exit() {
|
fn hysteresis_holds_until_below_exit() {
|
||||||
// critical держится до < 90 (95−5)
|
// critical держится до < 90 (95−5)
|
||||||
assert_eq!(ThermalPolicy::next(ThermalLevel::Critical, 92), ThermalLevel::Critical);
|
assert_eq!(
|
||||||
assert_eq!(ThermalPolicy::next(ThermalLevel::Critical, 89), ThermalLevel::Throttle(1));
|
ThermalPolicy::next(ThermalLevel::Critical, 92),
|
||||||
|
ThermalLevel::Critical
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
ThermalPolicy::next(ThermalLevel::Critical, 89),
|
||||||
|
ThermalLevel::Throttle(1)
|
||||||
|
);
|
||||||
// warn держится до < 70
|
// warn держится до < 70
|
||||||
assert_eq!(ThermalPolicy::next(ThermalLevel::Warn, 73), ThermalLevel::Warn);
|
assert_eq!(
|
||||||
assert_eq!(ThermalPolicy::next(ThermalLevel::Warn, 69), ThermalLevel::Normal);
|
ThermalPolicy::next(ThermalLevel::Warn, 73),
|
||||||
|
ThermalLevel::Warn
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
ThermalPolicy::next(ThermalLevel::Warn, 69),
|
||||||
|
ThermalLevel::Normal
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn no_oscillation_at_boundary() {
|
fn no_oscillation_at_boundary() {
|
||||||
// на 84 (чуть ниже entry throttle=85): зависит от prev (Schmitt), не дёргается
|
// на 84 (чуть ниже entry throttle=85): зависит от prev (Schmitt), не дёргается
|
||||||
assert_eq!(ThermalPolicy::next(ThermalLevel::Throttle(1), 84), ThermalLevel::Throttle(1));
|
assert_eq!(
|
||||||
assert_eq!(ThermalPolicy::next(ThermalLevel::Warn, 84), ThermalLevel::Warn);
|
ThermalPolicy::next(ThermalLevel::Throttle(1), 84),
|
||||||
|
ThermalLevel::Throttle(1)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
ThermalPolicy::next(ThermalLevel::Warn, 84),
|
||||||
|
ThermalLevel::Warn
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,10 @@ use std::sync::Arc;
|
|||||||
#[ignore = "нужна session-шина: just test-integration"]
|
#[ignore = "нужна session-шина: just test-integration"]
|
||||||
async fn power_state_and_fake_acc() {
|
async fn power_state_and_fake_acc() {
|
||||||
let svc = PowerService::new();
|
let svc = PowerService::new();
|
||||||
let mock = svc.mock(Arc::new(MockTempSource::new(20)), Arc::new(MockCoprocessor::new()));
|
let mock = svc.mock(
|
||||||
|
Arc::new(MockTempSource::new(20)),
|
||||||
|
Arc::new(MockCoprocessor::new()),
|
||||||
|
);
|
||||||
|
|
||||||
// сервер: Power1 + dev.PowerMock1 на одном пути (владеет ru.shturman.Power)
|
// сервер: Power1 + dev.PowerMock1 на одном пути (владеет ru.shturman.Power)
|
||||||
let server = zbus::Connection::session().await.unwrap();
|
let server = zbus::Connection::session().await.unwrap();
|
||||||
@@ -56,7 +59,10 @@ async fn power_state_and_fake_acc() {
|
|||||||
#[ignore = "нужна session-шина: just test-integration"]
|
#[ignore = "нужна session-шина: just test-integration"]
|
||||||
async fn shutdown_imminent_then_abort() {
|
async fn shutdown_imminent_then_abort() {
|
||||||
let svc = PowerService::new();
|
let svc = PowerService::new();
|
||||||
let mock = svc.mock(Arc::new(MockTempSource::new(20)), Arc::new(MockCoprocessor::new()));
|
let mock = svc.mock(
|
||||||
|
Arc::new(MockTempSource::new(20)),
|
||||||
|
Arc::new(MockCoprocessor::new()),
|
||||||
|
);
|
||||||
let server = zbus::Connection::session().await.unwrap();
|
let server = zbus::Connection::session().await.unwrap();
|
||||||
server
|
server
|
||||||
.object_server()
|
.object_server()
|
||||||
@@ -193,7 +199,7 @@ async fn mcu_failsafe_cuts_on_hang() {
|
|||||||
// дать coproc-циклу послать ≥1 heartbeat (иначе last_heartbeat=0 и guard не даст cut)
|
// дать coproc-циклу послать ≥1 heartbeat (иначе last_heartbeat=0 и guard не даст cut)
|
||||||
tokio::time::sleep(std::time::Duration::from_millis(1300)).await;
|
tokio::time::sleep(std::time::Duration::from_millis(1300)).await;
|
||||||
copro.hang(); // SoC завис → heartbeat не освежает таймер
|
copro.hang(); // SoC завис → heartbeat не освежает таймер
|
||||||
// ждём, пока coproc-цикл (HEARTBEAT=1с) накопит > FAILSAFE_MISS окон и сделает FailsafeCut
|
// ждём, пока coproc-цикл (HEARTBEAT=1с) накопит > FAILSAFE_MISS окон и сделает FailsafeCut
|
||||||
for _ in 0..10 {
|
for _ in 0..10 {
|
||||||
tokio::time::sleep(std::time::Duration::from_millis(700)).await;
|
tokio::time::sleep(std::time::Duration::from_millis(700)).await;
|
||||||
if power.power_state().await.unwrap() == PowerState::Off {
|
if power.power_state().await.unwrap() == PowerState::Off {
|
||||||
|
|||||||
Reference in New Issue
Block a user