#[cfg(test)]
mod tests {
use crate::{dlt::*, proptest_strategies::argument_strategy};
use byteorder::ByteOrder;
use proptest::prelude::*;
use byteorder::{BigEndian, LittleEndian};
use pretty_assertions::assert_eq;
proptest! {
#[test]
fn convert_type_info_to_bytes_doesnt_crash(type_info: TypeInfo) {
let _ = type_info.as_bytes::<BigEndian>();
}
#[test]
fn length_of_dlt_arg_is_number_of_bytes(arg in argument_strategy()) {
let expected = arg.as_bytes::<BigEndian>().len();
let expected_using_little_endian = arg.as_bytes::<LittleEndian>().len();
let calculated = arg.len();
assert_eq!(
expected,
calculated
);
assert_eq!(
expected_using_little_endian,
calculated
);
}
}
#[test]
fn test_convert_header_to_bytes() {
let header: StandardHeader = StandardHeader {
version: 1,
endianness: Endianness::Big,
has_extended_header: true,
message_counter: 0x33,
payload_length: 0x1,
ecu_id: Some("abc".to_string()),
session_id: None,
timestamp: Some(5),
};
assert_eq!(
vec![
0x37, 0x33, 0x0, 0x17, 0x61, 0x62, 0x63, 0x0, 0x0, 0x0, 0x0, 0x5, ],
header.as_bytes()
);
}
#[test]
fn test_filter_nothing_with_invalid_level() {
let extended_header = ExtendedHeader {
argument_count: 1,
verbose: true,
message_type: MessageType::Log(LogLevel::Invalid(1)),
application_id: "abc".to_string(),
context_id: "CON".to_string(),
};
assert!(!extended_header.skip_with_level(LogLevel::Verbose));
assert!(!extended_header.skip_with_level(LogLevel::Invalid(0)));
assert!(!extended_header.skip_with_level(LogLevel::Invalid(1)));
assert!(extended_header.skip_with_level(LogLevel::Invalid(2)));
}
#[test]
fn test_filter_out_non_relevant_ext_headers() {
let extended_header = ExtendedHeader {
argument_count: 1,
verbose: true,
message_type: MessageType::Log(LogLevel::Debug),
application_id: "abc".to_string(),
context_id: "CON".to_string(),
};
assert!(!extended_header.skip_with_level(LogLevel::Verbose));
assert!(!extended_header.skip_with_level(LogLevel::Debug));
assert!(extended_header.skip_with_level(LogLevel::Info));
assert!(extended_header.skip_with_level(LogLevel::Warn));
assert!(extended_header.skip_with_level(LogLevel::Error));
assert!(extended_header.skip_with_level(LogLevel::Fatal));
let extended_header = ExtendedHeader {
argument_count: 1,
verbose: true,
message_type: MessageType::Control(ControlType::Request),
application_id: "abc".to_string(),
context_id: "CON".to_string(),
};
assert!(!extended_header.skip_with_level(LogLevel::Fatal));
}
#[test]
fn test_convert_extended_header_to_bytes() {
let extended_header = ExtendedHeader {
argument_count: 2,
verbose: true,
message_type: MessageType::Log(LogLevel::Warn),
application_id: "abc".to_string(),
context_id: "CON".to_string(),
};
assert_eq!(
vec![
0b0011_0001, 0x2, 0x61,
0x62,
0x63,
0x0, 0x43,
0x4F,
0x4E,
0x0, ],
extended_header.as_bytes()
);
}
#[test]
fn test_convert_storage_header_to_bytes() {
let timestamp = DltTimeStamp {
seconds: 0x4DC9_2C26,
microseconds: 0x000C_A2D8,
};
let storage_header = StorageHeader {
timestamp,
ecu_id: "abc".to_string(),
};
assert_eq!(
vec![
0x44, 0x4C, 0x54, 0x01, 0x26, 0x2C, 0xC9, 0x4D, 0xD8, 0xA2, 0x0C, 0x0, 0x61, 0x62, 0x63, 0x0, ],
storage_header.as_bytes()
);
}
#[test]
fn test_convert_typeinfo_to_bytes() {
let type_info = TypeInfo {
kind: TypeInfoKind::Bool,
coding: StringCoding::UTF8,
has_variable_info: true,
has_trace_info: false,
};
let type_info2 = TypeInfo {
kind: TypeInfoKind::UnsignedFixedPoint(FloatWidth::Width32),
coding: StringCoding::ASCII,
has_variable_info: false,
has_trace_info: false,
};
let type_info3 = TypeInfo {
kind: TypeInfoKind::StringType,
coding: StringCoding::UTF8,
has_variable_info: false,
has_trace_info: false,
};
let expected1: u32 = 0b0000_0000_0000_0000_1000_1000_0001_0000;
let expected2: u32 = 0b0000_0000_0000_0000_0001_0000_0100_0011;
let expected3: u32 = 0b0000_0000_0000_0000_1000_0010_0000_0000;
println!("expected: {:#b}", expected2);
println!(
"got : {:#b}",
BigEndian::read_u32(&type_info2.as_bytes::<BigEndian>()[..])
);
assert_eq!(
expected1,
BigEndian::read_u32(&type_info.as_bytes::<BigEndian>()[..])
);
assert_eq!(
expected1,
LittleEndian::read_u32(&type_info.as_bytes::<LittleEndian>()[..])
);
assert_eq!(
expected2,
BigEndian::read_u32(&type_info2.as_bytes::<BigEndian>()[..])
);
assert_eq!(
expected2,
LittleEndian::read_u32(&type_info2.as_bytes::<LittleEndian>()[..])
);
assert_eq!(
expected3,
BigEndian::read_u32(&type_info3.as_bytes::<BigEndian>()[..])
);
assert_eq!(
expected3,
LittleEndian::read_u32(&type_info3.as_bytes::<LittleEndian>()[..])
);
}
#[test]
fn test_convert_bool_argument_to_bytes() {
let type_info = TypeInfo {
kind: TypeInfoKind::Bool,
coding: StringCoding::UTF8,
has_variable_info: true,
has_trace_info: false,
};
let argument = Argument {
type_info: type_info.clone(),
name: Some("foo".to_string()),
unit: None,
fixed_point: None,
value: Value::Bool(0x1),
};
let mut expected = type_info.as_bytes::<BigEndian>();
expected.extend(vec![0x0, 0x4]); expected.extend(b"foo\0");
expected.extend(vec![0x1]); assert_eq!(expected, argument.as_bytes::<BigEndian>());
let type_info2 = TypeInfo {
kind: TypeInfoKind::Bool,
coding: StringCoding::UTF8,
has_variable_info: true,
has_trace_info: false,
};
let mut expected2 = type_info2.as_bytes::<BigEndian>();
let argument2 = Argument {
type_info: type_info2,
name: None,
unit: None,
fixed_point: None,
value: Value::Bool(0x1),
};
expected2.extend(vec![0x1]); assert_eq!(expected2, argument2.as_bytes::<BigEndian>());
}
#[test]
fn test_convert_uint_argument_to_bytes() {
let type_info = TypeInfo {
kind: TypeInfoKind::Unsigned(TypeLength::BitLength32),
coding: StringCoding::UTF8,
has_variable_info: true,
has_trace_info: false,
};
let mut expected = type_info.as_bytes::<BigEndian>();
let argument = Argument {
type_info,
name: Some("speed".to_string()),
unit: Some("mph".to_string()),
fixed_point: None,
value: Value::U32(0x33),
};
expected.extend(vec![0x0, 0x6]); expected.extend(vec![0x0, 0x4]); expected.extend(b"speed\0");
expected.extend(b"mph\0");
let mut buf = [0; 4];
BigEndian::write_u32(&mut buf, 0x33);
expected.extend(&buf); assert_eq!(expected, argument.as_bytes::<BigEndian>());
let type_info = TypeInfo {
kind: TypeInfoKind::Unsigned(TypeLength::BitLength32),
coding: StringCoding::UTF8,
has_variable_info: false,
has_trace_info: false,
};
let mut expected = type_info.as_bytes::<BigEndian>();
let argument = Argument {
type_info,
name: None,
unit: None,
fixed_point: None,
value: Value::U32(0x33),
};
let mut buf = [0; 4];
BigEndian::write_u32(&mut buf, 0x33);
expected.extend(&buf); assert_eq!(expected, argument.as_bytes::<BigEndian>());
}
#[test]
fn test_convert_sint_argument_to_bytes() {
let type_info = TypeInfo {
kind: TypeInfoKind::Signed(TypeLength::BitLength32),
coding: StringCoding::UTF8,
has_variable_info: true,
has_trace_info: false,
};
let mut expected = type_info.as_bytes::<BigEndian>();
let argument = Argument {
type_info,
name: Some("speed".to_string()),
unit: Some("mph".to_string()),
fixed_point: None,
value: Value::I32(-0x33),
};
expected.extend(vec![0x0, 0x6]); expected.extend(vec![0x0, 0x4]); expected.extend(b"speed\0");
expected.extend(b"mph\0");
let mut buf = [0; 4];
BigEndian::write_i32(&mut buf, -0x33);
expected.extend(&buf); assert_eq!(expected, argument.as_bytes::<BigEndian>());
let type_info = TypeInfo {
kind: TypeInfoKind::Signed(TypeLength::BitLength32),
coding: StringCoding::UTF8,
has_variable_info: false,
has_trace_info: false,
};
let mut expected = type_info.as_bytes::<BigEndian>();
let argument = Argument {
type_info,
name: None,
unit: None,
fixed_point: None,
value: Value::I32(-0x33),
};
let mut buf = [0; 4];
BigEndian::write_i32(&mut buf, -0x33);
expected.extend(&buf); assert_eq!(expected, argument.as_bytes::<BigEndian>());
}
#[test]
fn test_convert_float_argument_to_bytes() {
let type_info = TypeInfo {
kind: TypeInfoKind::Float(FloatWidth::Width32),
coding: StringCoding::UTF8,
has_variable_info: true,
has_trace_info: false,
};
let mut expected = type_info.as_bytes::<BigEndian>();
let argument = Argument {
type_info,
name: Some("speed".to_string()),
unit: Some("mph".to_string()),
fixed_point: None,
value: Value::F32(123.98f32),
};
expected.extend(vec![0x0, 0x6]); expected.extend(vec![0x0, 0x4]); expected.extend(b"speed\0");
expected.extend(b"mph\0");
let mut buf = [0; 4];
BigEndian::write_f32(&mut buf, 123.98f32);
expected.extend(&buf); assert_eq!(expected, argument.as_bytes::<BigEndian>());
let type_info = TypeInfo {
kind: TypeInfoKind::Float(FloatWidth::Width64),
coding: StringCoding::UTF8,
has_variable_info: false,
has_trace_info: false,
};
let mut expected = type_info.as_bytes::<BigEndian>();
let argument = Argument {
type_info,
name: None,
unit: None,
fixed_point: None,
value: Value::F64(123.98f64),
};
let mut buf = [0; 8];
BigEndian::write_f64(&mut buf, 123.98f64);
expected.extend(&buf); assert_eq!(expected, argument.as_bytes::<BigEndian>());
}
#[test]
fn test_convert_string_argument_to_bytes() {
let type_info = TypeInfo {
kind: TypeInfoKind::StringType,
coding: StringCoding::UTF8,
has_variable_info: true,
has_trace_info: false,
};
let mut expected = type_info.as_bytes::<BigEndian>();
let argument = Argument {
type_info,
name: Some("speed".to_string()),
unit: None,
fixed_point: None,
value: Value::StringVal("foo".to_string()),
};
expected.extend(vec![0x0, 0x4]); expected.extend(vec![0x0, 0x6]); expected.extend(b"speed\0"); expected.extend(b"foo\0"); assert_eq!(expected, argument.as_bytes::<BigEndian>());
let type_info = TypeInfo {
kind: TypeInfoKind::StringType,
coding: StringCoding::UTF8,
has_variable_info: false,
has_trace_info: false,
};
let mut expected = type_info.as_bytes::<BigEndian>();
let argument = Argument {
type_info,
name: None,
unit: None,
fixed_point: None,
value: Value::StringVal("foo".to_string()),
};
expected.extend(vec![0x0, 0x4]); expected.extend(b"foo\0"); let argument_bytes = argument.as_bytes::<BigEndian>();
println!("{:02X?}", argument_bytes);
assert_eq!(expected, argument_bytes);
}
#[test]
fn test_convert_fixedpoint_argument_to_bytes() {
let type_info = TypeInfo {
kind: TypeInfoKind::SignedFixedPoint(FloatWidth::Width32),
coding: StringCoding::UTF8,
has_variable_info: true,
has_trace_info: false,
};
let mut expected = type_info.as_bytes::<BigEndian>();
let argument = Argument {
type_info,
name: Some("speed".to_string()),
unit: Some("mph".to_string()),
value: Value::I32(-44),
fixed_point: Some(FixedPoint {
quantization: 1.5,
offset: FixedPointValue::I32(-200),
}),
};
expected.extend(vec![0x0, 0x6]); expected.extend(vec![0x0, 0x4]); expected.extend(b"speed\0");
expected.extend(b"mph\0");
let mut buf = [0; 4];
BigEndian::write_f32(&mut buf, 1.5f32);
expected.extend(&buf); BigEndian::write_i32(&mut buf, -200);
expected.extend(&buf); BigEndian::write_i32(&mut buf, -44);
expected.extend(&buf); assert_eq!(expected, argument.as_bytes::<BigEndian>());
let type_info = TypeInfo {
kind: TypeInfoKind::SignedFixedPoint(FloatWidth::Width32),
coding: StringCoding::UTF8,
has_variable_info: false,
has_trace_info: false,
};
let mut expected = type_info.as_bytes::<BigEndian>();
let argument = Argument {
type_info,
name: None,
unit: None,
value: Value::I32(-44),
fixed_point: Some(FixedPoint {
quantization: 1.5,
offset: FixedPointValue::I32(-200),
}),
};
let mut buf = [0; 4];
BigEndian::write_f32(&mut buf, 1.5f32);
expected.extend(&buf); BigEndian::write_i32(&mut buf, -200);
expected.extend(&buf); BigEndian::write_i32(&mut buf, -44);
expected.extend(&buf); assert_eq!(expected, argument.as_bytes::<BigEndian>());
}
#[test]
fn test_convert_raw_argument_to_bytes() {
let type_info = TypeInfo {
kind: TypeInfoKind::Raw,
coding: StringCoding::UTF8,
has_variable_info: true,
has_trace_info: false,
};
let mut expected = type_info.as_bytes::<BigEndian>();
let argument = Argument {
type_info,
name: Some("foo".to_string()),
unit: None,
value: Value::Raw(vec![0xD, 0xE, 0xA, 0xD]),
fixed_point: Some(FixedPoint {
quantization: 1.5,
offset: FixedPointValue::I32(-200),
}),
};
expected.extend(vec![0x0, 0x4]); expected.extend(vec![0x0, 0x4]); expected.extend(b"foo\0");
expected.extend(vec![0xD, 0xE, 0xA, 0xD]);
assert_eq!(expected, argument.as_bytes::<BigEndian>());
let type_info = TypeInfo {
kind: TypeInfoKind::Raw,
coding: StringCoding::UTF8,
has_variable_info: false,
has_trace_info: false,
};
let mut expected = type_info.as_bytes::<BigEndian>();
let argument = Argument {
type_info,
name: None,
unit: None,
value: Value::Raw(vec![0xD, 0xE, 0xA, 0xD]),
fixed_point: Some(FixedPoint {
quantization: 1.5,
offset: FixedPointValue::I32(-200),
}),
};
expected.extend(vec![0x0, 0x4]); expected.extend(vec![0xD, 0xE, 0xA, 0xD]);
assert_eq!(expected, argument.as_bytes::<BigEndian>());
}
}