use crate::TaskId;
#[derive(Clone, Debug)]
pub struct CycleObservation {
pub cycle_index: u64,
pub task_id: TaskId,
pub task_index: u32,
pub faulted: bool,
pub period_ns: u64,
pub pre_ns: u64,
pub actual_period_ns: Option<u64>,
pub jitter_ns: Option<u64>,
pub lateness_ns: Option<i64>,
pub took_ns: Option<u64>,
}
#[derive(Clone, Debug)]
pub struct TaskStatsEntry {
pub task_id: TaskId,
pub p50_ns: u64,
pub p95_ns: u64,
pub p99_ns: u64,
pub min_ns: u64,
pub max_ns: u64,
pub max_jitter_ns: u64,
pub max_lateness_ns: u64,
pub overrun_count: u64,
}
#[derive(Clone, Debug)]
pub struct StatsSnapshot {
pub per_task: Vec<TaskStatsEntry>,
}
#[cfg(test)]
mod tests {
use super::*;
use crate::TaskId;
#[test]
fn cycle_observation_is_clone_and_holds_all_fields() {
let obs = CycleObservation {
cycle_index: 3,
task_id: TaskId::from("t0"),
task_index: 0,
faulted: false,
period_ns: 10_000_000,
pre_ns: 0,
actual_period_ns: Some(10_050_000),
jitter_ns: Some(50_000),
lateness_ns: Some(-120),
took_ns: Some(1_000_000),
};
let copy = obs.clone();
assert_eq!(obs.cycle_index, 3);
assert_eq!(copy.cycle_index, obs.cycle_index);
assert_eq!(copy.task_id.as_str(), "t0");
assert_eq!(copy.lateness_ns, Some(-120));
}
#[test]
fn stats_snapshot_holds_per_task_entries() {
let snap = StatsSnapshot {
per_task: vec![TaskStatsEntry {
task_id: TaskId::from("t0"),
p50_ns: 1,
p95_ns: 2,
p99_ns: 3,
min_ns: 1,
max_ns: 4,
max_jitter_ns: 5,
max_lateness_ns: 6,
overrun_count: 7,
}],
};
assert_eq!(snap.per_task.len(), 1);
assert_eq!(snap.per_task[0].overrun_count, 7);
}
}