From 38f244f4720d4c051f8f136b65379cab5e63432d Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 23 Aug 2024 20:26:50 +0200 Subject: [PATCH] some more tests --- src/dest.rs | 25 ++++++++++++ src/lib.rs | 97 +++++++++++++++++++++++++++++++++++++++++---- src/request.rs | 56 +++++++++++++++++++++++++- tests/end-to-end.rs | 4 +- 4 files changed, 170 insertions(+), 12 deletions(-) diff --git a/src/dest.rs b/src/dest.rs index cdb95b9..c5a4d4c 100644 --- a/src/dest.rs +++ b/src/dest.rs @@ -1444,4 +1444,29 @@ mod tests { fn test_file_transfer_with_closure_check_limit_reached() { // 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)); + } + } } diff --git a/src/lib.rs b/src/lib.rs index edafbef..84f9428 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -244,25 +244,28 @@ impl RemoteEntityConfigProvider for StdRemoteEntityConfigProvider { pub struct VecRemoteEntityConfigProvider(pub alloc::vec::Vec); #[cfg(feature = "alloc")] -impl RemoteEntityConfigProvider for alloc::vec::Vec { +impl RemoteEntityConfigProvider for VecRemoteEntityConfigProvider { 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> { - self.iter_mut() + self.0 + .iter_mut() .find(|cfg| cfg.entity_id.value() == remote_id) } fn add_config(&mut self, cfg: &RemoteEntityConfig) -> bool { - self.push(*cfg); + self.0.push(*cfg); true } 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 { - self.remove(idx); + self.0.remove(idx); return true; } } @@ -1159,6 +1162,16 @@ pub(crate) mod tests { 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] fn test_metadata_pdu_info() { let mut buf: [u8; 128] = [0; 128]; @@ -1246,7 +1259,7 @@ pub(crate) mod tests { #[test] 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(), 1024, true, @@ -1255,7 +1268,63 @@ pub(crate) mod tests { ChecksumType::Crc32, ); 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] @@ -1270,4 +1339,16 @@ pub(crate) mod tests { user_hook_dummy.abandoned_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) + ); + } } diff --git a/src/request.rs b/src/request.rs index 5efbcc3..1d51941 100644 --- a/src/request.rs +++ b/src/request.rs @@ -584,7 +584,7 @@ mod tests { } #[test] - fn test_put_request_path_checks() { + fn test_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"; @@ -596,7 +596,7 @@ mod tests { } #[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/"); invalid_path += "a".repeat(u8::MAX as usize).as_str(); let source_file = "/tmp/hello2.txt"; @@ -607,6 +607,40 @@ mod tests { 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] fn test_put_request_basic_small_ctor() { let src_file = "/tmp/hello.txt"; @@ -701,6 +735,7 @@ mod tests { .expect("creating msgs to user only put request failed"); let msg_to_user_iter = put_request.msgs_to_user(); assert!(msg_to_user_iter.is_some()); + assert!(put_request.check_tlv_type_validities()); let msg_to_user_iter = msg_to_user_iter.unwrap(); for msg_to_user_tlv in msg_to_user_iter { 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) .expect("creating msgs to user only put request failed"); let msg_to_user_iter = put_request.msgs_to_user(); + assert!(put_request.check_tlv_type_validities()); assert!(msg_to_user_iter.is_some()); let msg_to_user_iter = msg_to_user_iter.unwrap(); 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); } } + + #[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()); + } } diff --git a/tests/end-to-end.rs b/tests/end-to-end.rs index bb4a285..bd44b0b 100644 --- a/tests/end-to-end.rs +++ b/tests/end-to-end.rs @@ -13,8 +13,8 @@ use cfdp::{ request::{PutRequestOwned, StaticPutRequestCacher}, source::SourceHandler, user::{CfdpUser, FileSegmentRecvdParams, MetadataReceivedParams, TransactionFinishedParams}, - EntityType, IndicationConfig, LocalEntityConfig, PduWithInfo, RemoteEntityConfig, - StdCheckTimerCreator, TransactionId, UserFaultHookProvider, + DummyPduProvider, EntityType, IndicationConfig, LocalEntityConfig, PduWithInfo, + RemoteEntityConfig, StdCheckTimerCreator, TransactionId, UserFaultHookProvider, }; use spacepackets::{ cfdp::{ChecksumType, ConditionCode, TransmissionMode},