Coverage Update #47

Merged
muellerr merged 35 commits from coverage-update into main 2023-12-06 18:05:57 +01:00
6 changed files with 183 additions and 32 deletions
Showing only changes of commit 13b9ca356c - Show all commits

View File

@ -201,6 +201,24 @@ mod tests {
use super::*;
fn verify_state(ack_pdu: &AckPdu, expected_crc_flag: CrcFlag, expected_dir: Direction) {
assert_eq!(ack_pdu.condition_code(), ConditionCode::NoError);
assert_eq!(ack_pdu.transaction_status(), TransactionStatus::Active);
assert_eq!(ack_pdu.crc_flag(), expected_crc_flag);
assert_eq!(ack_pdu.file_flag(), LargeFileFlag::Normal);
assert_eq!(ack_pdu.pdu_type(), PduType::FileDirective);
assert_eq!(
ack_pdu.file_directive_type(),
Some(FileDirectiveType::AckPdu)
);
assert_eq!(ack_pdu.transmission_mode(), TransmissionMode::Acknowledged);
assert_eq!(ack_pdu.direction(), expected_dir);
assert_eq!(ack_pdu.source_id(), TEST_SRC_ID.into());
assert_eq!(ack_pdu.dest_id(), TEST_DEST_ID.into());
assert_eq!(ack_pdu.transaction_seq_num(), TEST_SEQ_NUM.into());
}
#[test]
fn test_basic() {
let pdu_conf = common_pdu_conf(CrcFlag::NoCrc, LargeFileFlag::Normal);
@ -216,21 +234,7 @@ mod tests {
ack_pdu.directive_code_of_acked_pdu(),
FileDirectiveType::FinishedPdu
);
assert_eq!(ack_pdu.condition_code(), ConditionCode::NoError);
assert_eq!(ack_pdu.transaction_status(), TransactionStatus::Active);
assert_eq!(ack_pdu.crc_flag(), CrcFlag::NoCrc);
assert_eq!(ack_pdu.file_flag(), LargeFileFlag::Normal);
assert_eq!(ack_pdu.pdu_type(), PduType::FileDirective);
assert_eq!(
ack_pdu.file_directive_type(),
Some(FileDirectiveType::AckPdu)
);
assert_eq!(ack_pdu.transmission_mode(), TransmissionMode::Acknowledged);
assert_eq!(ack_pdu.direction(), Direction::TowardsReceiver);
assert_eq!(ack_pdu.source_id(), TEST_SRC_ID.into());
assert_eq!(ack_pdu.dest_id(), TEST_DEST_ID.into());
assert_eq!(ack_pdu.transaction_seq_num(), TEST_SEQ_NUM.into());
verify_state(&ack_pdu, CrcFlag::NoCrc, Direction::TowardsReceiver);
}
fn generic_serialization_test(
@ -296,4 +300,20 @@ mod tests {
AckPdu::from_bytes(&ack_vec).expect("ACK PDU deserialization failed");
assert_eq!(ack_deserialized, ack_pdu);
}
#[test]
fn test_for_eof_pdu() {
let pdu_conf = common_pdu_conf(CrcFlag::WithCrc, LargeFileFlag::Normal);
let pdu_header = PduHeader::new_no_file_data(pdu_conf, 0);
let ack_pdu = AckPdu::new_for_eof_pdu(
pdu_header,
ConditionCode::NoError,
TransactionStatus::Active,
);
assert_eq!(
ack_pdu.directive_code_of_acked_pdu(),
FileDirectiveType::EofPdu
);
verify_state(&ack_pdu, CrcFlag::WithCrc, Direction::TowardsSender);
}
}

View File

@ -334,6 +334,7 @@ mod tests {
let written = finished_pdu.write_to_bytes(&mut buf);
assert!(written.is_ok());
let written = written.unwrap();
assert_eq!(written, 9);
assert_eq!(written, finished_pdu.len_written());
assert_eq!(written, finished_pdu.pdu_header().header_len() + 2);
assert_eq!(
@ -423,4 +424,47 @@ mod tests {
panic!("expected crc error");
}
}
#[test]
fn test_with_fault_location() {
let pdu_header =
PduHeader::new_no_file_data(common_pdu_conf(CrcFlag::NoCrc, LargeFileFlag::Normal), 0);
let finished_pdu = FinishedPdu::new_with_error(
pdu_header,
ConditionCode::NakLimitReached,
DeliveryCode::Incomplete,
FileStatus::DiscardDeliberately,
EntityIdTlv::new(TEST_DEST_ID.into()),
);
let finished_pdu_vec = finished_pdu.to_vec().unwrap();
assert_eq!(finished_pdu_vec.len(), 12);
assert_eq!(finished_pdu_vec[9], TlvType::EntityId.into());
assert_eq!(finished_pdu_vec[10], 1);
assert_eq!(finished_pdu_vec[11], TEST_DEST_ID.value());
assert_eq!(
finished_pdu.fault_location().unwrap().entity_id(),
&TEST_DEST_ID.into()
);
}
#[test]
fn test_deserialization_with_fault_location() {
let pdu_header =
PduHeader::new_no_file_data(common_pdu_conf(CrcFlag::NoCrc, LargeFileFlag::Normal), 0);
let entity_id_tlv = EntityIdTlv::new(TEST_DEST_ID.into());
let finished_pdu = FinishedPdu::new_with_error(
pdu_header,
ConditionCode::NakLimitReached,
DeliveryCode::Incomplete,
FileStatus::DiscardDeliberately,
entity_id_tlv,
);
let finished_pdu_vec = finished_pdu.to_vec().unwrap();
let finished_pdu_deserialized = FinishedPdu::from_bytes(&finished_pdu_vec).unwrap();
assert!(finished_pdu_deserialized.fault_location().is_some());
assert_eq!(
finished_pdu_deserialized.fault_location().unwrap(),
entity_id_tlv
)
}
}

View File

@ -131,6 +131,13 @@ impl<'data> Tlv<'data> {
})
}
pub fn new_with_custom_type(tlv_type: u8, data: &[u8]) -> Result<Tlv, TlvLvError> {
Ok(Tlv {
tlv_type_field: TlvTypeField::Custom(tlv_type),
lv: Lv::new(data)?,
})
}
/// Creates a TLV with an empty value field.
pub fn new_empty(tlv_type: TlvType) -> Tlv<'data> {
Tlv {
@ -608,10 +615,24 @@ mod tests {
let mut buf: [u8; 16] = [0; 16];
let written_len = entity_id_tlv.write_to_bytes(&mut buf).unwrap();
assert_eq!(written_len, entity_id_tlv.len_full());
assert_eq!(entity_id_tlv.len_value(), 2);
assert!(entity_id_tlv.is_standard_tlv());
assert_eq!(entity_id_tlv.tlv_type().unwrap(), TlvType::EntityId);
assert_eq!(buf[0], TlvType::EntityId as u8);
assert_eq!(buf[1], 2);
assert_eq!(u16::from_be_bytes(buf[2..4].try_into().unwrap()), 0x0102);
let entity_id_as_vec = entity_id_tlv.to_vec();
assert_eq!(entity_id_as_vec, buf[0..written_len].to_vec());
}
#[test]
fn test_entity_id_from_generic_tlv() {
let entity_id = UbfU16::new(0x0102);
let entity_id_tlv = EntityIdTlv::new(entity_id.into());
let mut buf: [u8; 16] = [0; 16];
let entity_id_as_tlv: Tlv = entity_id_tlv.to_tlv(&mut buf).unwrap();
let entity_id_converted_back: EntityIdTlv = entity_id_as_tlv.try_into().unwrap();
assert_eq!(entity_id_converted_back, entity_id_tlv);
}
#[test]
@ -932,4 +953,19 @@ mod tests {
panic!("unexpected error");
}
}
#[test]
fn test_custom_tlv() {
let custom_tlv = Tlv::new_with_custom_type(20, &[]).unwrap();
assert!(custom_tlv.tlv_type().is_none());
if let TlvTypeField::Custom(val) = custom_tlv.tlv_type_field() {
assert_eq!(val, 20);
} else {
panic!("unexpected type field");
}
let tlv_as_vec = custom_tlv.to_vec();
assert_eq!(tlv_as_vec.len(), 2);
assert_eq!(tlv_as_vec[0], 20);
assert_eq!(tlv_as_vec[1], 0);
}
}

View File

@ -57,7 +57,7 @@ impl<'data> MsgToUserTlv<'data> {
let msg_to_user = Self {
tlv: Tlv::from_bytes(buf)?,
};
match msg_to_user.tlv_type_field() {
match msg_to_user.tlv.tlv_type_field() {
TlvTypeField::Standard(tlv_type) => {
if tlv_type != TlvType::MsgToUser {
return Err(TlvLvError::InvalidTlvTypeField {
@ -91,13 +91,14 @@ impl WritableTlv for MsgToUserTlv<'_> {
impl GenericTlv for MsgToUserTlv<'_> {
fn tlv_type_field(&self) -> TlvTypeField {
TlvTypeField::Standard(TlvType::MsgToUser)
self.tlv.tlv_type_field()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_basic() {
let custom_value: [u8; 4] = [1, 2, 3, 4];
@ -106,6 +107,10 @@ mod tests {
let msg_to_user = msg_to_user.unwrap();
assert!(msg_to_user.is_standard_tlv());
assert_eq!(msg_to_user.tlv_type().unwrap(), TlvType::MsgToUser);
assert_eq!(
msg_to_user.tlv_type_field(),
TlvTypeField::Standard(TlvType::MsgToUser)
);
assert_eq!(msg_to_user.value(), custom_value);
assert_eq!(msg_to_user.value().len(), 4);
assert_eq!(msg_to_user.len_value(), 4);
@ -115,6 +120,48 @@ mod tests {
assert!(!msg_to_user.is_reserved_cfdp_msg());
}
#[test]
fn test_reserved_msg_serialization() {
let custom_value: [u8; 4] = [1, 2, 3, 4];
let msg_to_user = MsgToUserTlv::new(&custom_value).unwrap();
let mut buf: [u8; 6] = [0; 6];
msg_to_user.write_to_bytes(&mut buf).unwrap();
assert_eq!(
buf,
[
TlvType::MsgToUser as u8,
custom_value.len() as u8,
1,
2,
3,
4
]
);
}
#[test]
fn test_reserved_msg_deserialization() {
let custom_value: [u8; 3] = [1, 2, 3];
let msg_to_user = MsgToUserTlv::new(&custom_value).unwrap();
let msg_to_user_vec = msg_to_user.to_vec();
let msg_to_user_from_bytes = MsgToUserTlv::from_bytes(&msg_to_user_vec).unwrap();
assert!(!msg_to_user.is_reserved_cfdp_msg());
assert_eq!(msg_to_user_from_bytes, msg_to_user);
assert_eq!(msg_to_user_from_bytes.value(), msg_to_user.value());
assert_eq!(msg_to_user_from_bytes.tlv_type(), msg_to_user.tlv_type());
}
#[test]
fn test_reserved_msg_deserialization_invalid_type() {
let trash: [u8; 5] = [TlvType::FlowLabel as u8, 3, 1, 2, 3];
let error = MsgToUserTlv::from_bytes(&trash).unwrap_err();
if let TlvLvError::InvalidTlvTypeField { found, expected } = error {
assert_eq!(found, TlvType::FlowLabel as u8);
assert_eq!(expected, Some(TlvType::MsgToUser as u8));
} else {
panic!("Wrong error type returned: {:?}", error);
}
}
#[test]
fn test_reserved_msg() {
let reserved_str = "cfdp";

View File

@ -315,11 +315,11 @@ pub trait EcssEnumerationExt: EcssEnumeration + Debug + Copy + Clone + PartialEq
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct GenericEcssEnumWrapper<TYPE> {
pub struct GenericEcssEnumWrapper<TYPE: Copy> {
field: GenericUnsignedByteField<TYPE>,
}
impl<TYPE> GenericEcssEnumWrapper<TYPE> {
impl<TYPE: Copy> GenericEcssEnumWrapper<TYPE> {
pub const fn ptc() -> PacketTypeCodes {
PacketTypeCodes::Enumerated
}
@ -331,7 +331,7 @@ impl<TYPE> GenericEcssEnumWrapper<TYPE> {
}
}
impl<TYPE: ToBeBytes> UnsignedEnum for GenericEcssEnumWrapper<TYPE> {
impl<TYPE: Copy + ToBeBytes> UnsignedEnum for GenericEcssEnumWrapper<TYPE> {
fn size(&self) -> usize {
(self.pfc() / 8) as usize
}
@ -341,7 +341,7 @@ impl<TYPE: ToBeBytes> UnsignedEnum for GenericEcssEnumWrapper<TYPE> {
}
}
impl<TYPE: ToBeBytes> EcssEnumeration for GenericEcssEnumWrapper<TYPE> {
impl<TYPE: Copy + ToBeBytes> EcssEnumeration for GenericEcssEnumWrapper<TYPE> {
fn pfc(&self) -> u8 {
size_of::<TYPE>() as u8 * 8_u8
}

View File

@ -207,17 +207,21 @@ impl UnsignedEnum for UnsignedByteField {
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct GenericUnsignedByteField<TYPE> {
pub struct GenericUnsignedByteField<TYPE: Copy> {
value: TYPE,
}
impl<TYPE> GenericUnsignedByteField<TYPE> {
impl<TYPE: Copy> GenericUnsignedByteField<TYPE> {
pub const fn new(val: TYPE) -> Self {
Self { value: val }
}
pub const fn value(&self) -> TYPE {
self.value
}
}
impl<TYPE: ToBeBytes> UnsignedEnum for GenericUnsignedByteField<TYPE> {
impl<TYPE: Copy + ToBeBytes> UnsignedEnum for GenericUnsignedByteField<TYPE> {
fn size(&self) -> usize {
self.value.written_len()
}
@ -344,8 +348,8 @@ pub mod tests {
.expect("writing to raw buffer failed");
assert_eq!(len, 1);
assert_eq!(buf[0], 5);
for i in 1..8 {
assert_eq!(buf[i], 0);
for val in buf.iter().skip(1) {
assert_eq!(*val, 0);
}
}
@ -360,8 +364,8 @@ pub mod tests {
assert_eq!(len, 2);
let raw_val = u16::from_be_bytes(buf[0..2].try_into().unwrap());
assert_eq!(raw_val, 3823);
for i in 2..8 {
assert_eq!(buf[i], 0);
for val in buf.iter().skip(2) {
assert_eq!(*val, 0);
}
}
@ -376,9 +380,9 @@ pub mod tests {
assert_eq!(len, 4);
let raw_val = u32::from_be_bytes(buf[0..4].try_into().unwrap());
assert_eq!(raw_val, 80932);
for i in 4..8 {
(4..8).for_each(|i| {
assert_eq!(buf[i], 0);
}
});
}
#[test]
@ -544,8 +548,8 @@ pub mod tests {
.expect("writing to raw buffer failed");
let raw_val = u16::from_be_bytes(buf[0..2].try_into().unwrap());
assert_eq!(raw_val, 3823);
for i in 2..8 {
assert_eq!(buf[i], 0);
for val in buf.iter().skip(2) {
assert_eq!(*val, 0);
}
}