From d1bdf66974c9214fc2a70ef56b08fb7e446e553c Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 23 Sep 2025 15:43:04 +0200 Subject: [PATCH] add success test cases --- src/dest.rs | 145 +++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 109 insertions(+), 36 deletions(-) diff --git a/src/dest.rs b/src/dest.rs index 51bc911..f4f4f83 100644 --- a/src/dest.rs +++ b/src/dest.rs @@ -2040,6 +2040,49 @@ mod tests { assert_eq!(finished_indication.condition_code, ConditionCode::NoError); } + fn check_eof_ack_pdu(&mut self, cond_code: ConditionCode) { + assert!(!self.pdu_queue_empty()); + let pdu = self.get_next_pdu().unwrap(); + assert_eq!(pdu.pdu_type, PduType::FileDirective); + assert_eq!(pdu.file_directive_type.unwrap(), FileDirectiveType::AckPdu); + let ack_pdu = AckPdu::from_bytes(&pdu.raw_pdu).unwrap(); + assert_eq!(ack_pdu.condition_code(), cond_code); + assert_eq!(ack_pdu.transaction_status(), TransactionStatus::Active); + assert_eq!( + ack_pdu.directive_code_of_acked_pdu(), + FileDirectiveType::EofPdu + ); + } + + fn check_finished_pdu_success(&mut self) { + let pdu = self.get_next_pdu().unwrap(); + assert_eq!(pdu.pdu_type, PduType::FileDirective); + assert_eq!( + pdu.file_directive_type.unwrap(), + FileDirectiveType::FinishedPdu + ); + let finished_pdu = FinishedPduReader::from_bytes(&pdu.raw_pdu).unwrap(); + assert_eq!(finished_pdu.delivery_code(), DeliveryCode::Complete); + assert_eq!(finished_pdu.file_status(), FileStatus::Retained); + assert_eq!(finished_pdu.condition_code(), ConditionCode::NoError); + assert!(finished_pdu.fault_location().is_none()); + } + + fn acknowledge_finished_pdu( + &mut self, + user: &mut impl CfdpUser, + transfer_info: &TransferInfo, + ) { + let ack_pdu = AckPdu::new_for_finished_pdu( + transfer_info.header, + ConditionCode::NoError, + TransactionStatus::Active, + ); + self.handler + .state_machine(user, Some(&create_packet_info(&ack_pdu, &mut self.buf))) + .expect("handling ack PDU failed"); + } + fn state_check(&self, state: State, step: TransactionStep) { assert_eq!(self.handler.state(), state); assert_eq!(self.handler.step(), step); @@ -2060,7 +2103,7 @@ mod tests { ); } assert!(self.all_fault_queues_empty(), "fault queues not empty, "); - assert!(self.handler.pdu_sender.queue_empty()); + assert!(self.pdu_queue_empty()); if self.check_handler_idle_at_drop { self.state_check(State::Idle, TransactionStep::Idle); } @@ -2191,45 +2234,24 @@ mod tests { tb.generic_eof_no_error(&mut test_user, Vec::new()) .expect("EOF no error insertion failed"); tb.check_completion_indication_success(&mut test_user); - assert!(test_user.indication_queues_empty()); } #[test] fn test_empty_file_transfer_acked() { let fault_handler = TestFaultHandler::default(); let mut tb = DestHandlerTestbench::new_with_fixed_paths(fault_handler, false); - let mut test_user = tb.test_user_from_cached_paths(0); + let mut user = tb.test_user_from_cached_paths(0); let transfer_info = tb - .generic_transfer_init(&mut test_user, 0, TransmissionMode::Acknowledged) + .generic_transfer_init(&mut user, 0, TransmissionMode::Acknowledged) .expect("transfer init failed"); tb.state_check(State::Busy, TransactionStep::ReceivingFileDataPdus); - tb.generic_eof_no_error(&mut test_user, Vec::new()) + tb.generic_eof_no_error(&mut user, Vec::new()) .expect("EOF no error insertion failed"); - tb.check_completion_indication_success(&mut test_user); - assert!(!tb.pdu_queue_empty()); + tb.check_completion_indication_success(&mut user); assert_eq!(tb.pdu_queue_len(), 2); - let pdu = tb.get_next_pdu().unwrap(); - assert_eq!(pdu.pdu_type, PduType::FileDirective); - assert_eq!(pdu.file_directive_type.unwrap(), FileDirectiveType::AckPdu); - assert!(!tb.pdu_queue_empty()); - let pdu = tb.get_next_pdu().unwrap(); - assert_eq!(pdu.pdu_type, PduType::FileDirective); - assert_eq!( - pdu.file_directive_type.unwrap(), - FileDirectiveType::FinishedPdu - ); - let ack_pdu = AckPdu::new_for_finished_pdu( - transfer_info.header, - ConditionCode::NoError, - TransactionStatus::Active, - ); - tb.handler - .state_machine( - &mut test_user, - Some(&create_packet_info(&ack_pdu, &mut tb.buf)), - ) - .expect("handling ack PDU failed"); - assert!(test_user.indication_queues_empty()); + tb.check_eof_ack_pdu(ConditionCode::NoError); + tb.check_finished_pdu_success(); + tb.acknowledge_finished_pdu(&mut user, &transfer_info); } #[test] @@ -2240,16 +2262,40 @@ mod tests { let fault_handler = TestFaultHandler::default(); let mut tb = DestHandlerTestbench::new_with_fixed_paths(fault_handler, false); - let mut test_user = tb.test_user_from_cached_paths(file_size); - tb.generic_transfer_init(&mut test_user, file_size, TransmissionMode::Unacknowledged) + let mut user = tb.test_user_from_cached_paths(file_size); + let _transfer_info = tb + .generic_transfer_init(&mut user, file_size, TransmissionMode::Unacknowledged) .expect("transfer init failed"); tb.state_check(State::Busy, TransactionStep::ReceivingFileDataPdus); - tb.generic_file_data_insert(&mut test_user, 0, file_data) + tb.generic_file_data_insert(&mut user, 0, file_data) .expect("file data insertion failed"); - tb.generic_eof_no_error(&mut test_user, file_data.to_vec()) + tb.generic_eof_no_error(&mut user, file_data.to_vec()) .expect("EOF no error insertion failed"); - tb.check_completion_indication_success(&mut test_user); - assert!(test_user.indication_queues_empty()); + tb.check_completion_indication_success(&mut user); + } + + #[test] + fn test_small_file_transfer_acked() { + let file_data_str = "Hello World!"; + let file_data = file_data_str.as_bytes(); + let file_size = file_data.len() as u64; + let fault_handler = TestFaultHandler::default(); + + let mut tb = DestHandlerTestbench::new_with_fixed_paths(fault_handler, false); + let mut user = tb.test_user_from_cached_paths(file_size); + let transfer_info = tb + .generic_transfer_init(&mut user, file_size, TransmissionMode::Acknowledged) + .expect("transfer init failed"); + tb.state_check(State::Busy, TransactionStep::ReceivingFileDataPdus); + tb.generic_file_data_insert(&mut user, 0, file_data) + .expect("file data insertion failed"); + tb.generic_eof_no_error(&mut user, file_data.to_vec()) + .expect("EOF no error insertion failed"); + tb.check_completion_indication_success(&mut user); + assert_eq!(tb.pdu_queue_len(), 2); + tb.check_eof_ack_pdu(ConditionCode::NoError); + tb.check_finished_pdu_success(); + tb.acknowledge_finished_pdu(&mut user, &transfer_info); } #[test] @@ -2277,7 +2323,34 @@ mod tests { tb.generic_eof_no_error(&mut test_user, random_data.to_vec()) .expect("EOF no error insertion failed"); tb.check_completion_indication_success(&mut test_user); - assert!(test_user.indication_queues_empty()); + } + + #[test] + fn test_segmented_file_transfer_acked() { + let mut rng = rand::rng(); + let mut random_data = [0u8; 512]; + rng.fill(&mut random_data); + let file_size = random_data.len() as u64; + let segment_len = 256; + let fault_handler = TestFaultHandler::default(); + + let mut tb = DestHandlerTestbench::new_with_fixed_paths(fault_handler, false); + let mut user = tb.test_user_from_cached_paths(file_size); + let transfer_info = tb + .generic_transfer_init(&mut user, file_size, TransmissionMode::Acknowledged) + .expect("transfer init failed"); + tb.state_check(State::Busy, TransactionStep::ReceivingFileDataPdus); + tb.generic_file_data_insert(&mut user, 0, &random_data[0..segment_len]) + .expect("file data insertion failed"); + tb.generic_file_data_insert(&mut user, segment_len as u64, &random_data[segment_len..]) + .expect("file data insertion failed"); + tb.generic_eof_no_error(&mut user, random_data.to_vec()) + .expect("EOF no error insertion failed"); + tb.check_completion_indication_success(&mut user); + assert_eq!(tb.pdu_queue_len(), 2); + tb.check_eof_ack_pdu(ConditionCode::NoError); + tb.check_finished_pdu_success(); + tb.acknowledge_finished_pdu(&mut user, &transfer_info); } #[test]