This commit is contained in:
parent
8ea50f0a9a
commit
38f244f472
25
src/dest.rs
25
src/dest.rs
@ -1444,4 +1444,29 @@ mod tests {
|
|||||||
fn test_file_transfer_with_closure_check_limit_reached() {
|
fn test_file_transfer_with_closure_check_limit_reached() {
|
||||||
// TODO: Implement test.
|
// TODO: Implement test.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_finished_pdu_insertion_rejected() {
|
||||||
|
let fault_handler = TestFaultHandler::default();
|
||||||
|
let mut tb = DestHandlerTestbench::new(fault_handler, false);
|
||||||
|
let mut user = tb.test_user_from_cached_paths(0);
|
||||||
|
let finished_pdu = FinishedPduCreator::new_default(
|
||||||
|
PduHeader::new_no_file_data(CommonPduConfig::default(), 0),
|
||||||
|
DeliveryCode::Complete,
|
||||||
|
FileStatus::Retained,
|
||||||
|
);
|
||||||
|
let finished_pdu_raw = finished_pdu.to_vec().unwrap();
|
||||||
|
let packet_info = PacketInfo::new(&finished_pdu_raw).unwrap();
|
||||||
|
let error = tb.handler.state_machine(&mut user, Some(&packet_info));
|
||||||
|
assert!(error.is_err());
|
||||||
|
let error = error.unwrap_err();
|
||||||
|
if let DestError::CantProcessPacketType {
|
||||||
|
pdu_type,
|
||||||
|
directive_type,
|
||||||
|
} = error
|
||||||
|
{
|
||||||
|
assert_eq!(pdu_type, PduType::FileDirective);
|
||||||
|
assert_eq!(directive_type, Some(FileDirectiveType::FinishedPdu));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
97
src/lib.rs
97
src/lib.rs
@ -244,25 +244,28 @@ impl RemoteEntityConfigProvider for StdRemoteEntityConfigProvider {
|
|||||||
pub struct VecRemoteEntityConfigProvider(pub alloc::vec::Vec<RemoteEntityConfig>);
|
pub struct VecRemoteEntityConfigProvider(pub alloc::vec::Vec<RemoteEntityConfig>);
|
||||||
|
|
||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
impl RemoteEntityConfigProvider for alloc::vec::Vec<RemoteEntityConfig> {
|
impl RemoteEntityConfigProvider for VecRemoteEntityConfigProvider {
|
||||||
fn get(&self, remote_id: u64) -> Option<&RemoteEntityConfig> {
|
fn get(&self, remote_id: u64) -> Option<&RemoteEntityConfig> {
|
||||||
self.iter().find(|&cfg| cfg.entity_id.value() == remote_id)
|
self.0
|
||||||
|
.iter()
|
||||||
|
.find(|&cfg| cfg.entity_id.value() == remote_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_mut(&mut self, remote_id: u64) -> Option<&mut RemoteEntityConfig> {
|
fn get_mut(&mut self, remote_id: u64) -> Option<&mut RemoteEntityConfig> {
|
||||||
self.iter_mut()
|
self.0
|
||||||
|
.iter_mut()
|
||||||
.find(|cfg| cfg.entity_id.value() == remote_id)
|
.find(|cfg| cfg.entity_id.value() == remote_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_config(&mut self, cfg: &RemoteEntityConfig) -> bool {
|
fn add_config(&mut self, cfg: &RemoteEntityConfig) -> bool {
|
||||||
self.push(*cfg);
|
self.0.push(*cfg);
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remove_config(&mut self, remote_id: u64) -> bool {
|
fn remove_config(&mut self, remote_id: u64) -> bool {
|
||||||
for (idx, cfg) in self.iter().enumerate() {
|
for (idx, cfg) in self.0.iter().enumerate() {
|
||||||
if cfg.entity_id.value() == remote_id {
|
if cfg.entity_id.value() == remote_id {
|
||||||
self.remove(idx);
|
self.0.remove(idx);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1159,6 +1162,16 @@ pub(crate) mod tests {
|
|||||||
PduHeader::new_no_file_data(pdu_conf, 0)
|
PduHeader::new_no_file_data(pdu_conf, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_transaction_id() {
|
||||||
|
let transaction_id = TransactionId::new(
|
||||||
|
UnsignedByteFieldU16::new(1).into(),
|
||||||
|
UnsignedByteFieldU16::new(2).into(),
|
||||||
|
);
|
||||||
|
assert_eq!(transaction_id.source_id().value(), 1);
|
||||||
|
assert_eq!(transaction_id.seq_num().value(), 2);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_metadata_pdu_info() {
|
fn test_metadata_pdu_info() {
|
||||||
let mut buf: [u8; 128] = [0; 128];
|
let mut buf: [u8; 128] = [0; 128];
|
||||||
@ -1246,7 +1259,7 @@ pub(crate) mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_remote_cfg_provider_single() {
|
fn test_remote_cfg_provider_single() {
|
||||||
let remote_entity_cfg = RemoteEntityConfig::new_with_default_values(
|
let mut remote_entity_cfg = RemoteEntityConfig::new_with_default_values(
|
||||||
REMOTE_ID.into(),
|
REMOTE_ID.into(),
|
||||||
1024,
|
1024,
|
||||||
true,
|
true,
|
||||||
@ -1255,7 +1268,63 @@ pub(crate) mod tests {
|
|||||||
ChecksumType::Crc32,
|
ChecksumType::Crc32,
|
||||||
);
|
);
|
||||||
let remote_entity_retrieved = remote_entity_cfg.get(REMOTE_ID.value()).unwrap();
|
let remote_entity_retrieved = remote_entity_cfg.get(REMOTE_ID.value()).unwrap();
|
||||||
ssert_eq!(remote_entity_retrieved.entity_id, REMOTE_ID.into());
|
assert_eq!(remote_entity_retrieved.entity_id, REMOTE_ID.into());
|
||||||
|
assert_eq!(remote_entity_retrieved.max_packet_len, 1024);
|
||||||
|
assert!(remote_entity_retrieved.closure_requested_by_default);
|
||||||
|
assert!(!remote_entity_retrieved.crc_on_transmission_by_default);
|
||||||
|
assert_eq!(
|
||||||
|
remote_entity_retrieved.default_crc_type,
|
||||||
|
ChecksumType::Crc32
|
||||||
|
);
|
||||||
|
let remote_entity_mut = remote_entity_cfg.get_mut(REMOTE_ID.value()).unwrap();
|
||||||
|
assert_eq!(remote_entity_mut.entity_id, REMOTE_ID.into());
|
||||||
|
let dummy = RemoteEntityConfig::new_with_default_values(
|
||||||
|
LOCAL_ID.into(),
|
||||||
|
1024,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
TransmissionMode::Unacknowledged,
|
||||||
|
ChecksumType::Crc32,
|
||||||
|
);
|
||||||
|
assert!(!remote_entity_cfg.add_config(&dummy));
|
||||||
|
// Removal is no-op.
|
||||||
|
assert!(!remote_entity_cfg.remove_config(REMOTE_ID.value()));
|
||||||
|
let remote_entity_retrieved = remote_entity_cfg.get(REMOTE_ID.value()).unwrap();
|
||||||
|
assert_eq!(remote_entity_retrieved.entity_id, REMOTE_ID.into());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_remote_cfg_provider_vector() {
|
||||||
|
let remote_entity_cfg = RemoteEntityConfig::new_with_default_values(
|
||||||
|
REMOTE_ID.into(),
|
||||||
|
1024,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
TransmissionMode::Unacknowledged,
|
||||||
|
ChecksumType::Crc32,
|
||||||
|
);
|
||||||
|
let mut remote_cfg_provider = VecRemoteEntityConfigProvider::default();
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -1270,4 +1339,16 @@ pub(crate) mod tests {
|
|||||||
user_hook_dummy.abandoned_cb(transaction_id, ConditionCode::NoError, 0);
|
user_hook_dummy.abandoned_cb(transaction_id, ConditionCode::NoError, 0);
|
||||||
user_hook_dummy.ignore_cb(transaction_id, ConditionCode::NoError, 0);
|
user_hook_dummy.ignore_cb(transaction_id, ConditionCode::NoError, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn dummy_pdu_provider_test() {
|
||||||
|
let dummy_pdu_provider = DummyPduProvider(());
|
||||||
|
assert_eq!(dummy_pdu_provider.pdu_type(), PduType::FileData);
|
||||||
|
assert!(dummy_pdu_provider.file_directive_type().is_none());
|
||||||
|
assert_eq!(dummy_pdu_provider.pdu(), &[]);
|
||||||
|
assert_eq!(
|
||||||
|
dummy_pdu_provider.packet_target(),
|
||||||
|
Ok(PacketTarget::SourceEntity)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -584,7 +584,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_put_request_path_checks() {
|
fn test_put_request_path_checks_source_too_long() {
|
||||||
let mut invalid_path = String::from("/tmp/");
|
let mut invalid_path = String::from("/tmp/");
|
||||||
invalid_path += "a".repeat(u8::MAX as usize).as_str();
|
invalid_path += "a".repeat(u8::MAX as usize).as_str();
|
||||||
let dest_file = "/tmp/hello2.txt";
|
let dest_file = "/tmp/hello2.txt";
|
||||||
@ -596,7 +596,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_put_request_path_checks_dest_file() {
|
fn test_put_request_path_checks_dest_file_too_long() {
|
||||||
let mut invalid_path = String::from("/tmp/");
|
let mut invalid_path = String::from("/tmp/");
|
||||||
invalid_path += "a".repeat(u8::MAX as usize).as_str();
|
invalid_path += "a".repeat(u8::MAX as usize).as_str();
|
||||||
let source_file = "/tmp/hello2.txt";
|
let source_file = "/tmp/hello2.txt";
|
||||||
@ -607,6 +607,40 @@ mod tests {
|
|||||||
assert_eq!(u8::MAX as usize + 5, error.0);
|
assert_eq!(u8::MAX as usize + 5, error.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_owned_put_request_path_checks_source_too_long() {
|
||||||
|
let mut invalid_path = String::from("/tmp/");
|
||||||
|
invalid_path += "a".repeat(u8::MAX as usize).as_str();
|
||||||
|
let dest_file = "/tmp/hello2.txt";
|
||||||
|
let error = PutRequestOwned::new_regular_request(
|
||||||
|
DEST_ID.into(),
|
||||||
|
&invalid_path,
|
||||||
|
dest_file,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
assert!(error.is_err());
|
||||||
|
let error = error.unwrap_err();
|
||||||
|
assert_eq!(u8::MAX as usize + 5, error.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_owned_put_request_path_checks_dest_file_too_long() {
|
||||||
|
let mut invalid_path = String::from("/tmp/");
|
||||||
|
invalid_path += "a".repeat(u8::MAX as usize).as_str();
|
||||||
|
let source_file = "/tmp/hello2.txt";
|
||||||
|
let error = PutRequestOwned::new_regular_request(
|
||||||
|
DEST_ID.into(),
|
||||||
|
source_file,
|
||||||
|
&invalid_path,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
assert!(error.is_err());
|
||||||
|
let error = error.unwrap_err();
|
||||||
|
assert_eq!(u8::MAX as usize + 5, error.0);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_put_request_basic_small_ctor() {
|
fn test_put_request_basic_small_ctor() {
|
||||||
let src_file = "/tmp/hello.txt";
|
let src_file = "/tmp/hello.txt";
|
||||||
@ -701,6 +735,7 @@ mod tests {
|
|||||||
.expect("creating msgs to user only put request failed");
|
.expect("creating msgs to user only put request failed");
|
||||||
let msg_to_user_iter = put_request.msgs_to_user();
|
let msg_to_user_iter = put_request.msgs_to_user();
|
||||||
assert!(msg_to_user_iter.is_some());
|
assert!(msg_to_user_iter.is_some());
|
||||||
|
assert!(put_request.check_tlv_type_validities());
|
||||||
let msg_to_user_iter = msg_to_user_iter.unwrap();
|
let msg_to_user_iter = msg_to_user_iter.unwrap();
|
||||||
for msg_to_user_tlv in msg_to_user_iter {
|
for msg_to_user_tlv in msg_to_user_iter {
|
||||||
assert_eq!(msg_to_user_tlv.value(), msg_to_user.value());
|
assert_eq!(msg_to_user_tlv.value(), msg_to_user.value());
|
||||||
@ -715,6 +750,7 @@ mod tests {
|
|||||||
let put_request = PutRequest::new_msgs_to_user_only(DEST_ID.into(), binding)
|
let put_request = PutRequest::new_msgs_to_user_only(DEST_ID.into(), binding)
|
||||||
.expect("creating msgs to user only put request failed");
|
.expect("creating msgs to user only put request failed");
|
||||||
let msg_to_user_iter = put_request.msgs_to_user();
|
let msg_to_user_iter = put_request.msgs_to_user();
|
||||||
|
assert!(put_request.check_tlv_type_validities());
|
||||||
assert!(msg_to_user_iter.is_some());
|
assert!(msg_to_user_iter.is_some());
|
||||||
let msg_to_user_iter = msg_to_user_iter.unwrap();
|
let msg_to_user_iter = msg_to_user_iter.unwrap();
|
||||||
for msg_to_user_tlv in msg_to_user_iter {
|
for msg_to_user_tlv in msg_to_user_iter {
|
||||||
@ -722,4 +758,20 @@ mod tests {
|
|||||||
assert_eq!(msg_to_user_tlv.tlv_type().unwrap(), TlvType::MsgToUser);
|
assert_eq!(msg_to_user_tlv.tlv_type().unwrap(), TlvType::MsgToUser);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_put_request_to_owned() {
|
||||||
|
let src_file = "/tmp/hello.txt";
|
||||||
|
let dest_file = "/tmp/hello2.txt";
|
||||||
|
let put_request =
|
||||||
|
PutRequest::new_regular_request(DEST_ID.into(), src_file, dest_file, None, None)
|
||||||
|
.unwrap();
|
||||||
|
let put_request_owned: PutRequestOwned = put_request.into();
|
||||||
|
assert_eq!(put_request_owned.destination_id(), DEST_ID.into());
|
||||||
|
assert_eq!(put_request_owned.source_file().unwrap(), src_file);
|
||||||
|
assert_eq!(put_request_owned.dest_file().unwrap(), dest_file);
|
||||||
|
assert!(put_request_owned.msgs_to_user().is_none());
|
||||||
|
assert!(put_request_owned.trans_mode().is_none());
|
||||||
|
assert!(put_request_owned.closure_requested().is_none());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,8 +13,8 @@ use cfdp::{
|
|||||||
request::{PutRequestOwned, StaticPutRequestCacher},
|
request::{PutRequestOwned, StaticPutRequestCacher},
|
||||||
source::SourceHandler,
|
source::SourceHandler,
|
||||||
user::{CfdpUser, FileSegmentRecvdParams, MetadataReceivedParams, TransactionFinishedParams},
|
user::{CfdpUser, FileSegmentRecvdParams, MetadataReceivedParams, TransactionFinishedParams},
|
||||||
EntityType, IndicationConfig, LocalEntityConfig, PduWithInfo, RemoteEntityConfig,
|
DummyPduProvider, EntityType, IndicationConfig, LocalEntityConfig, PduWithInfo,
|
||||||
StdCheckTimerCreator, TransactionId, UserFaultHookProvider,
|
RemoteEntityConfig, StdCheckTimerCreator, TransactionId, UserFaultHookProvider,
|
||||||
};
|
};
|
||||||
use spacepackets::{
|
use spacepackets::{
|
||||||
cfdp::{ChecksumType, ConditionCode, TransmissionMode},
|
cfdp::{ChecksumType, ConditionCode, TransmissionMode},
|
||||||
|
Loading…
Reference in New Issue
Block a user