Skip to content

Commit

Permalink
Add a new telemetry message for EOL tests
Browse files Browse the repository at this point in the history
Fix #34
  • Loading branch information
dsferruzza committed Jan 9, 2021
1 parent 4a93a1f commit d484262
Show file tree
Hide file tree
Showing 5 changed files with 257 additions and 0 deletions.
5 changes: 5 additions & 0 deletions src/cli/bin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,7 @@ fn stats(cfg: Stats) {
let mut nb_stopped_messages: u32 = 0;
let mut nb_control_ack: u32 = 0;
let mut nb_fatal_error: u32 = 0;
let mut nb_eol_test_snapshots: u32 = 0;

loop {
match rx.try_recv() {
Expand Down Expand Up @@ -347,6 +348,9 @@ fn stats(cfg: Stats) {
TelemetryMessage::FatalError(_) => {
nb_fatal_error += 1;
}
TelemetryMessage::EolTestSnapshot(_) => {
nb_eol_test_snapshots += 1;
}
}
telemetry_messages.push(message);
}
Expand All @@ -363,6 +367,7 @@ fn stats(cfg: Stats) {
println!("Nb StoppedMessage: {}", nb_stopped_messages);
println!("Nb ControlAck: {}", nb_control_ack);
println!("Nb FatalError: {}", nb_fatal_error);
println!("Nb EolTestSnapshot: {}", nb_eol_test_snapshots);
println!(
"Estimated duration: {:.3} seconds",
compute_duration(telemetry_messages) as f32 / 1000_f32
Expand Down
3 changes: 3 additions & 0 deletions src/cli/convert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,9 @@ pub fn telemetry_to_gts(message: &TelemetryMessage, source_label: &Option<String
TelemetryMessage::FatalError(_) => {
// Do nothing: we don't want this kind of messages
}
TelemetryMessage::EolTestSnapshot(_) => {
// Do nothing: we don't want this kind of messages
}
};
output.iter().fold(String::new(), |mut acc, cur| {
acc.push_str(cur);
Expand Down
6 changes: 6 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,12 @@ pub fn display_message(message: TelemetryChannelType) {
}))) => {
info!("***** FATAL ERROR ***** {:?}", &error);
}
Ok(TelemetryMessageOrError::Message(TelemetryMessage::EolTestSnapshot(_))) => {
info!(
" {:?}",
&message.expect("failed unwrapping message for EOL test snapshot")
);
}
Ok(TelemetryMessageOrError::Error(e)) => {
warn!("a high-level error occurred: {:?}", e);
}
Expand Down
129 changes: 129 additions & 0 deletions src/parsers/v2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,30 @@ fn fatal_error_details(input: &[u8]) -> IResult<&[u8], FatalErrorDetails> {
}
}

named!(
eol_test_step<EolTestStep>,
map_res!(be_u8, |step| EolTestStep::try_from(step))
);

fn eol_test_snapshot_content(input: &[u8]) -> IResult<&[u8], EolTestSnapshotContent> {
use nom::error::{Error, ErrorKind};
use nom::Err::Failure;
use EolTestSnapshotContent::*;

let (input, content_type) = be_u8(input)?;
match content_type {
0 => Ok((input, InProgress)),
1 => {
do_parse!(
input,
sep >> error: u8_array >> (Error(String::from_utf8_lossy(&error).into_owned()))
)
}
2 => Ok((input, Success)),
_ => Err(Failure(Error::new(input, ErrorKind::Switch))),
}
}

named!(
boot<TelemetryMessage>,
do_parse!(
Expand Down Expand Up @@ -579,6 +603,37 @@ named!(
)
);

named!(
eol_test_snapshot<TelemetryMessage>,
do_parse!(
tag!("L:")
>> tag!([VERSION])
>> software_version_len: be_u8
>> software_version:
map_res!(take!(software_version_len), |bytes| std::str::from_utf8(
bytes
))
>> device_id1: be_u32
>> device_id2: be_u32
>> device_id3: be_u32
>> sep
>> systick: be_u64
>> sep
>> current_step: eol_test_step
>> sep
>> content: eol_test_snapshot_content
>> end
>> (TelemetryMessage::EolTestSnapshot(EolTestSnapshot {
telemetry_version: VERSION,
version: software_version.to_string(),
device_id: format!("{}-{}-{}", device_id1, device_id2, device_id3),
systick,
current_step,
content,
}))
)
);

/// Transform bytes into a structured telemetry message
///
/// * `input` - Bytes to parse.
Expand All @@ -593,6 +648,7 @@ pub fn message(input: &[u8]) -> IResult<&[u8], TelemetryMessage, TelemetryError<
alarm_trap,
control_ack,
fatal_error,
eol_test_snapshot,
))(input)
.map_err(nom::Err::convert)
}
Expand Down Expand Up @@ -689,6 +745,26 @@ mod tests {
}
}

fn eol_test_step_strategy() -> impl Strategy<Value = EolTestStep> {
proptest::num::u8::ANY
.prop_filter_map("Invalid test step", |n| EolTestStep::try_from(n).ok())
}

fn eol_test_snapshot_content_strategy() -> BoxedStrategy<EolTestSnapshotContent> {
prop_oneof![
Just(EolTestSnapshotContent::InProgress),
eol_test_snapshot_content_error_strategy(),
Just(EolTestSnapshotContent::Success),
]
.boxed()
}

prop_compose! {
fn eol_test_snapshot_content_error_strategy()(reason in ".+") -> EolTestSnapshotContent {
EolTestSnapshotContent::Error(reason)
}
}

proptest! {
#[test]
fn test_boot_message_parser(
Expand Down Expand Up @@ -1326,4 +1402,57 @@ mod tests {
assert_eq!(nom::dbg_dmp(fatal_error, "fatal_error")(input), Ok((&[][..], expected)));
}
}

proptest! {
#[test]
fn test_eol_test_snapshot_message_parser(
version in ".*",
device_id1 in (0u32..),
device_id2 in (0u32..),
device_id3 in (0u32..),
systick in (0u64..),
current_step in eol_test_step_strategy(),
content in eol_test_snapshot_content_strategy(),
) {
let msg = EolTestSnapshot {
telemetry_version: VERSION,
version,
device_id: format!("{}-{}-{}", device_id1, device_id2, device_id3),
systick,
current_step,
content,
};

let eol_test_snapshot_content: Vec<u8> = match msg.content {
EolTestSnapshotContent::InProgress => vec![0],
EolTestSnapshotContent::Error(ref reason) => flat(&[
&[1],
b"\t",
&[reason.len() as u8],
&reason.as_bytes(),
]),
EolTestSnapshotContent::Success => vec![2],
};

let input = &flat(&[
b"L:",
&[VERSION],
&[msg.version.len() as u8],
&msg.version.as_bytes(),
&device_id1.to_be_bytes(),
&device_id2.to_be_bytes(),
&device_id3.to_be_bytes(),
b"\t",
&msg.systick.to_be_bytes(),
b"\t",
&[current_step as u8],
b"\t",
&eol_test_snapshot_content,
b"\n",
]);

let expected = TelemetryMessage::EolTestSnapshot(msg);
assert_eq!(nom::dbg_dmp(eol_test_snapshot, "eol_test_snapshot")(input), Ok((&[][..], expected)));
}
}
}
114 changes: 114 additions & 0 deletions src/structures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,94 @@ pub enum FatalErrorDetails {
},
}

/// Step of the end of line test
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
#[cfg_attr(feature = "serialize-messages", derive(serde::Serialize))]
#[allow(non_camel_case_types, missing_docs)]
pub enum EolTestStep {
START,
SUPPLY_TO_EXPANDER_NOT_CONNECTED,
CHECK_FAN,
TEST_BAT_DEAD,
BATTERY_DEEP_DISCHARGE,
DISCONNECT_MAINS,
CONNECT_MAINS,
CHECK_BUZZER,
CHECK_ALL_BUTTONS,
CHECK_UI_SCREEN,
PLUG_AIR_TEST_SYTEM,
REACH_MAX_PRESSURE,
MAX_PRESSURE_REACHED_OK,
MAX_PRESSURE_NOT_REACHED,
START_LEAK_MESURE,
LEAK_IS_TOO_HIGH,
REACH_NULL_PRESSURE,
MIN_PRESSURE_NOT_REACHED,
USER_CONFIRMATION_BEFORE_O2_TEST,
START_O2_TEST,
O2_PRESSURE_NOT_REACH,
WAIT_USER_BEFORE_LONG_RUN,
START_LONG_RUN_BLOWER,
PRESSURE_NOT_STABLE,
FLOW_NOT_STABLE,
END_SUCCESS,
DISPLAY_PRESSURE,
DISPLAY_FLOW,
}

impl TryFrom<u8> for EolTestStep {
type Error = io::Error;

fn try_from(value: u8) -> Result<Self, Self::Error> {
match value {
0 => Ok(Self::START),
1 => Ok(Self::SUPPLY_TO_EXPANDER_NOT_CONNECTED),
2 => Ok(Self::CHECK_FAN),
3 => Ok(Self::TEST_BAT_DEAD),
4 => Ok(Self::BATTERY_DEEP_DISCHARGE),
5 => Ok(Self::DISCONNECT_MAINS),
6 => Ok(Self::CONNECT_MAINS),
7 => Ok(Self::CHECK_BUZZER),
8 => Ok(Self::CHECK_ALL_BUTTONS),
9 => Ok(Self::CHECK_UI_SCREEN),
10 => Ok(Self::PLUG_AIR_TEST_SYTEM),
11 => Ok(Self::REACH_MAX_PRESSURE),
12 => Ok(Self::MAX_PRESSURE_REACHED_OK),
13 => Ok(Self::MAX_PRESSURE_NOT_REACHED),
14 => Ok(Self::START_LEAK_MESURE),
15 => Ok(Self::LEAK_IS_TOO_HIGH),
16 => Ok(Self::REACH_NULL_PRESSURE),
17 => Ok(Self::MIN_PRESSURE_NOT_REACHED),
18 => Ok(Self::USER_CONFIRMATION_BEFORE_O2_TEST),
19 => Ok(Self::START_O2_TEST),
20 => Ok(Self::O2_PRESSURE_NOT_REACH),
21 => Ok(Self::WAIT_USER_BEFORE_LONG_RUN),
22 => Ok(Self::START_LONG_RUN_BLOWER),
23 => Ok(Self::PRESSURE_NOT_STABLE),
24 => Ok(Self::FLOW_NOT_STABLE),
25 => Ok(Self::END_SUCCESS),
26 => Ok(Self::DISPLAY_PRESSURE),
27 => Ok(Self::DISPLAY_FLOW),
_ => Err(io::Error::new(
io::ErrorKind::InvalidData,
format!("Invalid EOL test step {}", value),
)),
}
}
}

/// Content of end of line test snapshots
#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serialize-messages", derive(serde::Serialize))]
pub enum EolTestSnapshotContent {
/// Test is in progress
InProgress,
/// There was an error during test
Error(String),
/// End of line test succeeded
Success,
}

/// A telemetry message that is sent once every time the MCU boots
#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serialize-messages", derive(serde::Serialize))]
Expand Down Expand Up @@ -494,6 +582,24 @@ pub struct FatalError {
pub error: FatalErrorDetails,
}

/// [protocol v2] A message sent during end of line tests
#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serialize-messages", derive(serde::Serialize))]
pub struct EolTestSnapshot {
/// Version of the telemetry protocol
pub telemetry_version: u8,
/// Version of the MCU firmware
pub version: String,
/// Internal ID of the MCU
pub device_id: String,
/// Number of microseconds since the MCU booted
pub systick: u64,
/// Current step
pub current_step: EolTestStep,
/// Content of the snapshot
pub content: EolTestSnapshotContent,
}

/// Supported telemetry messages
#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serialize-messages", derive(serde::Serialize))]
Expand All @@ -513,6 +619,8 @@ pub enum TelemetryMessage {
ControlAck(ControlAck),
/// [protocol v2] A message sent when a fatal error occurs
FatalError(FatalError),
/// [protocol v2] A message sent during end of line tests
EolTestSnapshot(EolTestSnapshot),
}

impl TelemetryMessage {
Expand Down Expand Up @@ -540,6 +648,9 @@ impl TelemetryMessage {
Self::FatalError(FatalError {
telemetry_version, ..
}) => telemetry_version,
Self::EolTestSnapshot(EolTestSnapshot {
telemetry_version, ..
}) => telemetry_version,
};
*val
}
Expand All @@ -554,6 +665,7 @@ impl TelemetryMessage {
Self::AlarmTrap(AlarmTrap { version, .. }) => version,
Self::ControlAck(ControlAck { version, .. }) => version,
Self::FatalError(FatalError { version, .. }) => version,
Self::EolTestSnapshot(EolTestSnapshot { version, .. }) => version,
};
val.clone()
}
Expand All @@ -568,6 +680,7 @@ impl TelemetryMessage {
Self::AlarmTrap(AlarmTrap { device_id, .. }) => device_id,
Self::ControlAck(ControlAck { device_id, .. }) => device_id,
Self::FatalError(FatalError { device_id, .. }) => device_id,
Self::EolTestSnapshot(EolTestSnapshot { device_id, .. }) => device_id,
};
val.clone()
}
Expand All @@ -582,6 +695,7 @@ impl TelemetryMessage {
Self::AlarmTrap(AlarmTrap { systick, .. }) => systick,
Self::ControlAck(ControlAck { systick, .. }) => systick,
Self::FatalError(FatalError { systick, .. }) => systick,
Self::EolTestSnapshot(EolTestSnapshot { systick, .. }) => systick,
};
*val
}
Expand Down

0 comments on commit d484262

Please sign in to comment.