Merge remote-tracking branch 'origin/main' into python-interop-example
All checks were successful
Rust/cfdp/pipeline/head This commit looks good
All checks were successful
Rust/cfdp/pipeline/head This commit looks good
This commit is contained in:
commit
e7d6663022
22
src/dest.rs
22
src/dest.rs
@ -561,6 +561,10 @@ impl<
|
|||||||
) {
|
) {
|
||||||
Ok(checksum_success) => {
|
Ok(checksum_success) => {
|
||||||
file_delivery_complete = checksum_success;
|
file_delivery_complete = checksum_success;
|
||||||
|
if !checksum_success {
|
||||||
|
self.tparams.tstate.delivery_code = DeliveryCode::Incomplete;
|
||||||
|
self.tparams.tstate.condition_code = ConditionCode::FileChecksumFailure;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Err(e) => match e {
|
Err(e) => match e {
|
||||||
FilestoreError::ChecksumTypeNotImplemented(_) => {
|
FilestoreError::ChecksumTypeNotImplemented(_) => {
|
||||||
@ -850,7 +854,7 @@ impl<
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use core::{borrow::BorrowMut, cell::Cell, sync::atomic::AtomicBool};
|
use core::{cell::Cell, sync::atomic::AtomicBool};
|
||||||
#[allow(unused_imports)]
|
#[allow(unused_imports)]
|
||||||
use std::println;
|
use std::println;
|
||||||
use std::{fs, string::String};
|
use std::{fs, string::String};
|
||||||
@ -860,11 +864,7 @@ mod tests {
|
|||||||
use spacepackets::{
|
use spacepackets::{
|
||||||
cfdp::{
|
cfdp::{
|
||||||
lv::Lv,
|
lv::Lv,
|
||||||
pdu::{
|
pdu::{finished::FinishedPduReader, metadata::MetadataPduCreator, WritablePduPacket},
|
||||||
finished::{self, FinishedPduReader},
|
|
||||||
metadata::MetadataPduCreator,
|
|
||||||
WritablePduPacket,
|
|
||||||
},
|
|
||||||
ChecksumType, TransmissionMode,
|
ChecksumType, TransmissionMode,
|
||||||
},
|
},
|
||||||
util::{UbfU16, UnsignedByteFieldU16},
|
util::{UbfU16, UnsignedByteFieldU16},
|
||||||
@ -1526,6 +1526,9 @@ mod tests {
|
|||||||
let transaction_id = tb.handler.transaction_id().unwrap();
|
let transaction_id = tb.handler.transaction_id().unwrap();
|
||||||
let mut fault_hook = tb.handler.local_cfg.user_fault_hook().borrow_mut();
|
let mut fault_hook = tb.handler.local_cfg.user_fault_hook().borrow_mut();
|
||||||
assert!(fault_hook.notice_of_suspension_queue.is_empty());
|
assert!(fault_hook.notice_of_suspension_queue.is_empty());
|
||||||
|
|
||||||
|
// The file checksum failure is ignored by default and check limit handling is now
|
||||||
|
// performed.
|
||||||
let ignored_queue = &mut fault_hook.ignored_queue;
|
let ignored_queue = &mut fault_hook.ignored_queue;
|
||||||
assert_eq!(ignored_queue.len(), 1);
|
assert_eq!(ignored_queue.len(), 1);
|
||||||
let cancelled = ignored_queue.pop_front().unwrap();
|
let cancelled = ignored_queue.pop_front().unwrap();
|
||||||
@ -1552,6 +1555,7 @@ mod tests {
|
|||||||
.expect("fsm error");
|
.expect("fsm error");
|
||||||
tb.state_check(State::Idle, TransactionStep::Idle);
|
tb.state_check(State::Idle, TransactionStep::Idle);
|
||||||
|
|
||||||
|
// Transaction is cancelled because the check limit is reached.
|
||||||
let mut fault_hook = tb.handler.local_cfg.user_fault_hook().borrow_mut();
|
let mut fault_hook = tb.handler.local_cfg.user_fault_hook().borrow_mut();
|
||||||
let cancelled_queue = &mut fault_hook.notice_of_cancellation_queue;
|
let cancelled_queue = &mut fault_hook.notice_of_cancellation_queue;
|
||||||
assert_eq!(cancelled_queue.len(), 1);
|
assert_eq!(cancelled_queue.len(), 1);
|
||||||
@ -1575,6 +1579,12 @@ mod tests {
|
|||||||
ConditionCode::CheckLimitReached
|
ConditionCode::CheckLimitReached
|
||||||
);
|
);
|
||||||
assert_eq!(finished_pdu.delivery_code(), DeliveryCode::Incomplete);
|
assert_eq!(finished_pdu.delivery_code(), DeliveryCode::Incomplete);
|
||||||
|
assert!(finished_pdu.fault_location().is_some());
|
||||||
|
assert_eq!(
|
||||||
|
*finished_pdu.fault_location().unwrap().entity_id(),
|
||||||
|
REMOTE_ID.into()
|
||||||
|
);
|
||||||
|
assert_eq!(finished_pdu.fs_responses_raw(), &[]);
|
||||||
assert!(tb.handler.pdu_sender.queue_empty());
|
assert!(tb.handler.pdu_sender.queue_empty());
|
||||||
tb.expected_full_data = faulty_file_data.to_vec();
|
tb.expected_full_data = faulty_file_data.to_vec();
|
||||||
}
|
}
|
||||||
|
104
src/lib.rs
104
src/lib.rs
@ -724,6 +724,7 @@ impl PduProvider for DummyPduProvider {
|
|||||||
pub struct PacketInfo<'raw_packet> {
|
pub struct PacketInfo<'raw_packet> {
|
||||||
pdu_type: PduType,
|
pdu_type: PduType,
|
||||||
file_directive_type: Option<FileDirectiveType>,
|
file_directive_type: Option<FileDirectiveType>,
|
||||||
|
packet_len: usize,
|
||||||
raw_packet: &'raw_packet [u8],
|
raw_packet: &'raw_packet [u8],
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -782,6 +783,7 @@ impl<'raw> PacketInfo<'raw> {
|
|||||||
return Ok(Self {
|
return Ok(Self {
|
||||||
pdu_type: pdu_header.pdu_type(),
|
pdu_type: pdu_header.pdu_type(),
|
||||||
file_directive_type: None,
|
file_directive_type: None,
|
||||||
|
packet_len: pdu_header.pdu_len(),
|
||||||
raw_packet,
|
raw_packet,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -801,12 +803,13 @@ impl<'raw> PacketInfo<'raw> {
|
|||||||
Ok(Self {
|
Ok(Self {
|
||||||
pdu_type: pdu_header.pdu_type(),
|
pdu_type: pdu_header.pdu_type(),
|
||||||
file_directive_type: Some(directive),
|
file_directive_type: Some(directive),
|
||||||
|
packet_len: pdu_header.pdu_len(),
|
||||||
raw_packet,
|
raw_packet,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn raw_packet(&self) -> &[u8] {
|
pub fn raw_packet(&self) -> &[u8] {
|
||||||
self.raw_packet
|
&self.raw_packet[0..self.packet_len]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1195,6 +1198,10 @@ pub(crate) mod tests {
|
|||||||
packet_info.file_directive_type().unwrap(),
|
packet_info.file_directive_type().unwrap(),
|
||||||
FileDirectiveType::MetadataPdu
|
FileDirectiveType::MetadataPdu
|
||||||
);
|
);
|
||||||
|
assert_eq!(
|
||||||
|
packet_info.raw_packet(),
|
||||||
|
&buf[0..metadata_pdu.len_written()]
|
||||||
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
packet_info.packet_target().unwrap(),
|
packet_info.packet_target().unwrap(),
|
||||||
PacketTarget::DestEntity
|
PacketTarget::DestEntity
|
||||||
@ -1210,6 +1217,10 @@ pub(crate) mod tests {
|
|||||||
.write_to_bytes(&mut buf)
|
.write_to_bytes(&mut buf)
|
||||||
.expect("writing file data PDU failed");
|
.expect("writing file data PDU failed");
|
||||||
let packet_info = PacketInfo::new(&buf).expect("creating packet info failed");
|
let packet_info = PacketInfo::new(&buf).expect("creating packet info failed");
|
||||||
|
assert_eq!(
|
||||||
|
packet_info.raw_packet(),
|
||||||
|
&buf[0..file_data_pdu.len_written()]
|
||||||
|
);
|
||||||
assert_eq!(packet_info.pdu_type(), PduType::FileData);
|
assert_eq!(packet_info.pdu_type(), PduType::FileData);
|
||||||
assert!(packet_info.file_directive_type().is_none());
|
assert!(packet_info.file_directive_type().is_none());
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
@ -1229,6 +1240,7 @@ pub(crate) mod tests {
|
|||||||
let packet_info = PacketInfo::new(&buf).expect("creating packet info failed");
|
let packet_info = PacketInfo::new(&buf).expect("creating packet info failed");
|
||||||
assert_eq!(packet_info.pdu_type(), PduType::FileDirective);
|
assert_eq!(packet_info.pdu_type(), PduType::FileDirective);
|
||||||
assert!(packet_info.file_directive_type().is_some());
|
assert!(packet_info.file_directive_type().is_some());
|
||||||
|
assert_eq!(packet_info.raw_packet(), &buf[0..eof_pdu.len_written()]);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
packet_info.file_directive_type().unwrap(),
|
packet_info.file_directive_type().unwrap(),
|
||||||
FileDirectiveType::EofPdu
|
FileDirectiveType::EofPdu
|
||||||
@ -1292,10 +1304,13 @@ pub(crate) mod tests {
|
|||||||
assert!(!remote_entity_cfg.remove_config(REMOTE_ID.value()));
|
assert!(!remote_entity_cfg.remove_config(REMOTE_ID.value()));
|
||||||
let remote_entity_retrieved = remote_entity_cfg.get(REMOTE_ID.value()).unwrap();
|
let remote_entity_retrieved = remote_entity_cfg.get(REMOTE_ID.value()).unwrap();
|
||||||
assert_eq!(remote_entity_retrieved.entity_id, REMOTE_ID.into());
|
assert_eq!(remote_entity_retrieved.entity_id, REMOTE_ID.into());
|
||||||
|
// Does not exist.
|
||||||
|
assert!(remote_entity_cfg.get(LOCAL_ID.value()).is_none());
|
||||||
|
assert!(remote_entity_cfg.get_mut(LOCAL_ID.value()).is_none());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_remote_cfg_provider_vector() {
|
fn test_remote_cfg_provider_std() {
|
||||||
let remote_entity_cfg = RemoteEntityConfig::new_with_default_values(
|
let remote_entity_cfg = RemoteEntityConfig::new_with_default_values(
|
||||||
REMOTE_ID.into(),
|
REMOTE_ID.into(),
|
||||||
1024,
|
1024,
|
||||||
@ -1304,7 +1319,7 @@ pub(crate) mod tests {
|
|||||||
TransmissionMode::Unacknowledged,
|
TransmissionMode::Unacknowledged,
|
||||||
ChecksumType::Crc32,
|
ChecksumType::Crc32,
|
||||||
);
|
);
|
||||||
let mut remote_cfg_provider = VecRemoteEntityConfigProvider::default();
|
let mut remote_cfg_provider = StdRemoteEntityConfigProvider::default();
|
||||||
assert!(remote_cfg_provider.0.is_empty());
|
assert!(remote_cfg_provider.0.is_empty());
|
||||||
remote_cfg_provider.add_config(&remote_entity_cfg);
|
remote_cfg_provider.add_config(&remote_entity_cfg);
|
||||||
assert_eq!(remote_cfg_provider.0.len(), 1);
|
assert_eq!(remote_cfg_provider.0.len(), 1);
|
||||||
@ -1326,6 +1341,44 @@ pub(crate) mod tests {
|
|||||||
assert_eq!(remote_cfg_provider.0.len(), 1);
|
assert_eq!(remote_cfg_provider.0.len(), 1);
|
||||||
let cfg_1_mut = remote_cfg_provider.get_mut(LOCAL_ID.value()).unwrap();
|
let cfg_1_mut = remote_cfg_provider.get_mut(LOCAL_ID.value()).unwrap();
|
||||||
cfg_1_mut.default_crc_type = ChecksumType::Crc32C;
|
cfg_1_mut.default_crc_type = ChecksumType::Crc32C;
|
||||||
|
assert!(!remote_cfg_provider.remove_config(REMOTE_ID.value()));
|
||||||
|
assert!(remote_cfg_provider.get_mut(REMOTE_ID.value()).is_none());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_remote_cfg_provider_vector() {
|
||||||
|
let mut remote_cfg_provider = VecRemoteEntityConfigProvider::default();
|
||||||
|
let remote_entity_cfg = RemoteEntityConfig::new_with_default_values(
|
||||||
|
REMOTE_ID.into(),
|
||||||
|
1024,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
TransmissionMode::Unacknowledged,
|
||||||
|
ChecksumType::Crc32,
|
||||||
|
);
|
||||||
|
assert!(remote_cfg_provider.0.is_empty());
|
||||||
|
remote_cfg_provider.add_config(&remote_entity_cfg);
|
||||||
|
assert_eq!(remote_cfg_provider.0.len(), 1);
|
||||||
|
let remote_entity_cfg_2 = RemoteEntityConfig::new_with_default_values(
|
||||||
|
LOCAL_ID.into(),
|
||||||
|
1024,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
TransmissionMode::Unacknowledged,
|
||||||
|
ChecksumType::Crc32,
|
||||||
|
);
|
||||||
|
let cfg_0 = remote_cfg_provider.get(REMOTE_ID.value()).unwrap();
|
||||||
|
assert_eq!(cfg_0.entity_id, REMOTE_ID.into());
|
||||||
|
remote_cfg_provider.add_config(&remote_entity_cfg_2);
|
||||||
|
assert_eq!(remote_cfg_provider.0.len(), 2);
|
||||||
|
let cfg_1 = remote_cfg_provider.get(LOCAL_ID.value()).unwrap();
|
||||||
|
assert_eq!(cfg_1.entity_id, LOCAL_ID.into());
|
||||||
|
assert!(remote_cfg_provider.remove_config(REMOTE_ID.value()));
|
||||||
|
assert_eq!(remote_cfg_provider.0.len(), 1);
|
||||||
|
let cfg_1_mut = remote_cfg_provider.get_mut(LOCAL_ID.value()).unwrap();
|
||||||
|
cfg_1_mut.default_crc_type = ChecksumType::Crc32C;
|
||||||
|
assert!(!remote_cfg_provider.remove_config(REMOTE_ID.value()));
|
||||||
|
assert!(remote_cfg_provider.get_mut(REMOTE_ID.value()).is_none());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -1352,4 +1405,49 @@ pub(crate) mod tests {
|
|||||||
Ok(PacketTarget::SourceEntity)
|
Ok(PacketTarget::SourceEntity)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_fault_handler_checksum_error_ignored_by_default() {
|
||||||
|
let fault_handler = FaultHandler::new(TestFaultHandler::default());
|
||||||
|
assert_eq!(
|
||||||
|
fault_handler.get_fault_handler(ConditionCode::FileChecksumFailure),
|
||||||
|
FaultHandlerCode::IgnoreError
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_fault_handler_unsupported_checksum_ignored_by_default() {
|
||||||
|
let fault_handler = FaultHandler::new(TestFaultHandler::default());
|
||||||
|
assert_eq!(
|
||||||
|
fault_handler.get_fault_handler(ConditionCode::UnsupportedChecksumType),
|
||||||
|
FaultHandlerCode::IgnoreError
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_fault_handler_basic() {
|
||||||
|
let mut fault_handler = FaultHandler::new(TestFaultHandler::default());
|
||||||
|
assert_eq!(
|
||||||
|
fault_handler.get_fault_handler(ConditionCode::FileChecksumFailure),
|
||||||
|
FaultHandlerCode::IgnoreError
|
||||||
|
);
|
||||||
|
fault_handler.set_fault_handler(
|
||||||
|
ConditionCode::FileChecksumFailure,
|
||||||
|
FaultHandlerCode::NoticeOfCancellation,
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
fault_handler.get_fault_handler(ConditionCode::FileChecksumFailure),
|
||||||
|
FaultHandlerCode::NoticeOfCancellation
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn transaction_id_hashable_usable_as_map_key() {
|
||||||
|
let mut map = HashMap::new();
|
||||||
|
let transaction_id_0 = TransactionId::new(
|
||||||
|
UnsignedByteFieldU8::new(1).into(),
|
||||||
|
UnsignedByteFieldU8::new(2).into(),
|
||||||
|
);
|
||||||
|
map.insert(transaction_id_0, 5_u32);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user