this is the last test
This commit is contained in:
329
src/dest.rs
329
src/dest.rs
@@ -1286,8 +1286,11 @@ impl<
|
||||
)?;
|
||||
sent_packets += 1;
|
||||
} else {
|
||||
sent_packets += self
|
||||
.write_multi_packet_nak_sequence(max_segment_reqs, acked_params.metadata_missing)?;
|
||||
sent_packets += self.write_multi_packet_nak_sequence(
|
||||
segments_to_send,
|
||||
max_segment_reqs,
|
||||
acked_params.metadata_missing,
|
||||
)?;
|
||||
}
|
||||
|
||||
Ok(sent_packets)
|
||||
@@ -1296,6 +1299,7 @@ impl<
|
||||
#[cold]
|
||||
fn write_multi_packet_nak_sequence(
|
||||
&mut self,
|
||||
mut segments_to_send: usize,
|
||||
max_segments: usize,
|
||||
first_segment_metadata: bool,
|
||||
) -> Result<u32, DestError> {
|
||||
@@ -1310,7 +1314,6 @@ impl<
|
||||
|
||||
let mut segment_index = 0;
|
||||
let mut buf_index = 0;
|
||||
let mut remaining = max_segments;
|
||||
let mut current_start_of_scope = 0;
|
||||
let mut current_end_of_scope = 0;
|
||||
let mut seg_buf = nak_pdu_creator.segment_request_buffer_mut();
|
||||
@@ -1338,13 +1341,13 @@ impl<
|
||||
&self.pdu_and_cksum_buffer.borrow()[..written_len],
|
||||
)?;
|
||||
sent_packets += 1;
|
||||
remaining = remaining.saturating_sub(max_segments);
|
||||
segments_to_send = segments_to_send.saturating_sub(max_segments);
|
||||
|
||||
// new PDU with the same capacity
|
||||
nak_pdu_creator = NakPduCreatorWithReservedSeqReqsBuf::new(
|
||||
self.pdu_and_cksum_buffer.get_mut(),
|
||||
pdu_header,
|
||||
core::cmp::min(remaining, max_segments),
|
||||
core::cmp::min(segments_to_send, max_segments),
|
||||
)
|
||||
.unwrap();
|
||||
seg_buf = nak_pdu_creator.segment_request_buffer_mut();
|
||||
@@ -1383,6 +1386,7 @@ impl<
|
||||
FileDirectiveType::NakPdu,
|
||||
&self.pdu_and_cksum_buffer.borrow()[..written_len],
|
||||
)?;
|
||||
sent_packets += 1;
|
||||
}
|
||||
Ok(sent_packets)
|
||||
}
|
||||
@@ -2425,6 +2429,37 @@ mod tests {
|
||||
tb.check_completion_indication_success(&mut test_user);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_empty_file_transfer_invalid_remote_id() {
|
||||
let fault_handler = TestFaultHandler::default();
|
||||
let mut tb = DestHandlerTestbench::new_with_fixed_paths(
|
||||
fault_handler,
|
||||
TransmissionMode::Unacknowledged,
|
||||
false,
|
||||
);
|
||||
let mut test_user = tb.test_user_from_cached_paths(0);
|
||||
let mut conf = tb.pdu_conf;
|
||||
// Just swap them..
|
||||
conf.set_source_and_dest_id(REMOTE_ID, LOCAL_ID).unwrap();
|
||||
let pdu_header = PduHeader::new_for_file_directive(conf, 0);
|
||||
let metadata_pdu = create_metadata_pdu(
|
||||
&pdu_header,
|
||||
tb.src_path.as_path(),
|
||||
tb.dest_path.as_path(),
|
||||
0,
|
||||
false,
|
||||
);
|
||||
let packet_info = create_packet_info(&metadata_pdu, &mut tb.buf);
|
||||
if let Err(DestError::NoRemoteConfigFound(id)) =
|
||||
tb.handler.state_machine(&mut test_user, Some(&packet_info))
|
||||
{
|
||||
assert_eq!(id, REMOTE_ID.into());
|
||||
} else {
|
||||
panic!("expected no remote config found error");
|
||||
}
|
||||
tb.check_dest_file = false;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_empty_file_transfer_acked() {
|
||||
let fault_handler = TestFaultHandler::default();
|
||||
@@ -3763,4 +3798,288 @@ mod tests {
|
||||
assert_eq!(cancellation.progress(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_multi_segment_nak() {
|
||||
let file_data_str = "Hello Wooorld!";
|
||||
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,
|
||||
TransmissionMode::Acknowledged,
|
||||
false,
|
||||
);
|
||||
// Disable this, we only want to check the deferred procedure.
|
||||
tb.remote_cfg_mut().immediate_nak_mode = false;
|
||||
let mut user = tb.test_user_from_cached_paths(file_size);
|
||||
let transfer_info = tb
|
||||
.generic_transfer_init(&mut user, file_size)
|
||||
.expect("transfer init failed");
|
||||
tb.state_check(State::Busy, TransactionStep::ReceivingFileDataPdus);
|
||||
|
||||
assert_eq!(
|
||||
tb.generic_file_data_insert(&mut user, 2, &file_data[2..4])
|
||||
.expect("file data insertion failed"),
|
||||
0
|
||||
);
|
||||
assert_eq!(
|
||||
tb.generic_file_data_insert(&mut user, 6, &file_data[6..8])
|
||||
.expect("file data insertion failed"),
|
||||
0
|
||||
);
|
||||
assert_eq!(
|
||||
tb.generic_file_data_insert(&mut user, 10, &file_data[10..])
|
||||
.expect("file data insertion failed"),
|
||||
0
|
||||
);
|
||||
assert_eq!(
|
||||
tb.generic_eof_no_error(&mut user, file_data.to_vec())
|
||||
.expect("EOF no error insertion failed"),
|
||||
2
|
||||
);
|
||||
assert_eq!(tb.pdu_queue_len(), 2);
|
||||
tb.check_eof_ack_pdu(ConditionCode::NoError);
|
||||
assert_eq!(tb.pdu_queue_len(), 1);
|
||||
let pdu = tb.get_next_pdu().unwrap();
|
||||
assert_eq!(pdu.pdu_type, PduType::FileDirective);
|
||||
assert_eq!(pdu.file_directive_type.unwrap(), FileDirectiveType::NakPdu);
|
||||
let nak_pdu = NakPduReader::new(&pdu.raw_pdu).unwrap();
|
||||
assert_eq!(nak_pdu.start_of_scope(), 0);
|
||||
assert_eq!(nak_pdu.end_of_scope(), file_size);
|
||||
let seg_reqs: Vec<(u64, u64)> = nak_pdu.get_segment_requests_iterator().unwrap().collect();
|
||||
assert_eq!(seg_reqs.len(), 3);
|
||||
assert_eq!(seg_reqs[0], (0, 2));
|
||||
assert_eq!(seg_reqs[1], (4, 6));
|
||||
assert_eq!(seg_reqs[2], (8, 10));
|
||||
|
||||
// We simulate the reply by re-inserting the missing file segment.
|
||||
tb.generic_file_data_insert(&mut user, 0, &file_data[0..2])
|
||||
.expect("file data insertion failed");
|
||||
tb.generic_file_data_insert(&mut user, 4, &file_data[4..6])
|
||||
.expect("file data insertion failed");
|
||||
tb.generic_file_data_insert(&mut user, 8, &file_data[8..10])
|
||||
.expect("file data insertion failed");
|
||||
tb.check_completion_indication_success(&mut user);
|
||||
assert_eq!(tb.pdu_queue_len(), 1);
|
||||
tb.check_finished_pdu_success();
|
||||
tb.acknowledge_finished_pdu(&mut user, &transfer_info);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_multi_packet_nak_sequence_large_file_flag() {
|
||||
let file_data = [0_u8; 64];
|
||||
let file_size = file_data.len() as u64;
|
||||
let fault_handler = TestFaultHandler::default();
|
||||
|
||||
let mut tb = DestHandlerTestbench::new_with_fixed_paths(
|
||||
fault_handler,
|
||||
TransmissionMode::Acknowledged,
|
||||
false,
|
||||
);
|
||||
// Disable this, we only want to check the deferred procedure.
|
||||
tb.remote_cfg_mut().immediate_nak_mode = false;
|
||||
let max_packet_len = 80;
|
||||
tb.remote_cfg_mut().max_packet_len = max_packet_len;
|
||||
tb.set_large_file_flag(LargeFileFlag::Large);
|
||||
let mut user = tb.test_user_from_cached_paths(file_size);
|
||||
let transfer_info = tb
|
||||
.generic_transfer_init(&mut user, file_size)
|
||||
.expect("transfer init failed");
|
||||
tb.state_check(State::Busy, TransactionStep::ReceivingFileDataPdus);
|
||||
|
||||
assert_eq!(
|
||||
NakPduCreatorWithReservedSeqReqsBuf::calculate_max_segment_requests(
|
||||
max_packet_len,
|
||||
&PduHeader::new_for_file_directive(tb.pdu_conf, 0),
|
||||
)
|
||||
.unwrap(),
|
||||
3
|
||||
);
|
||||
let missing_segs_0: &[(u64, u64)] = &[(0, 2), (4, 6), (8, 10)];
|
||||
let missing_segs_1: &[(u64, u64)] = &[(12, 14)];
|
||||
assert_eq!(
|
||||
tb.generic_file_data_insert(&mut user, 2, &file_data[2..4])
|
||||
.expect("file data insertion failed"),
|
||||
0
|
||||
);
|
||||
assert_eq!(
|
||||
tb.generic_file_data_insert(&mut user, 6, &file_data[6..8])
|
||||
.expect("file data insertion failed"),
|
||||
0
|
||||
);
|
||||
assert_eq!(
|
||||
tb.generic_file_data_insert(&mut user, 10, &file_data[10..12])
|
||||
.expect("file data insertion failed"),
|
||||
0
|
||||
);
|
||||
assert_eq!(
|
||||
tb.generic_file_data_insert(&mut user, 14, &file_data[14..file_size as usize])
|
||||
.expect("file data insertion failed"),
|
||||
0
|
||||
);
|
||||
assert_eq!(
|
||||
tb.generic_eof_no_error(&mut user, file_data.to_vec())
|
||||
.expect("EOF no error insertion failed"),
|
||||
3
|
||||
);
|
||||
assert_eq!(tb.pdu_queue_len(), 3);
|
||||
tb.check_eof_ack_pdu(ConditionCode::NoError);
|
||||
let pdu = tb.get_next_pdu().unwrap();
|
||||
assert_eq!(pdu.pdu_type, PduType::FileDirective);
|
||||
assert_eq!(pdu.file_directive_type.unwrap(), FileDirectiveType::NakPdu);
|
||||
let nak_pdu = NakPduReader::new(&pdu.raw_pdu).unwrap();
|
||||
assert_eq!(nak_pdu.start_of_scope(), 0);
|
||||
assert_eq!(nak_pdu.end_of_scope(), 10);
|
||||
let seg_reqs: Vec<(u64, u64)> = nak_pdu.get_segment_requests_iterator().unwrap().collect();
|
||||
assert_eq!(seg_reqs, missing_segs_0);
|
||||
|
||||
let pdu = tb.get_next_pdu().unwrap();
|
||||
assert_eq!(pdu.pdu_type, PduType::FileDirective);
|
||||
assert_eq!(pdu.file_directive_type.unwrap(), FileDirectiveType::NakPdu);
|
||||
let nak_pdu = NakPduReader::new(&pdu.raw_pdu).unwrap();
|
||||
assert_eq!(nak_pdu.start_of_scope(), 10);
|
||||
assert_eq!(nak_pdu.end_of_scope(), file_size);
|
||||
let seg_reqs: Vec<(u64, u64)> = nak_pdu.get_segment_requests_iterator().unwrap().collect();
|
||||
assert_eq!(seg_reqs, missing_segs_1);
|
||||
|
||||
for missing_seg in missing_segs_0 {
|
||||
assert_eq!(
|
||||
tb.generic_file_data_insert(
|
||||
&mut user,
|
||||
missing_seg.0,
|
||||
&file_data[missing_seg.0 as usize..missing_seg.1 as usize]
|
||||
)
|
||||
.expect("file data insertion failed"),
|
||||
0
|
||||
);
|
||||
}
|
||||
for missing_seg in missing_segs_1 {
|
||||
assert_eq!(
|
||||
tb.generic_file_data_insert(
|
||||
&mut user,
|
||||
missing_seg.0,
|
||||
&file_data[missing_seg.0 as usize..missing_seg.1 as usize]
|
||||
)
|
||||
.expect("file data insertion failed"),
|
||||
1
|
||||
);
|
||||
}
|
||||
|
||||
tb.check_completion_indication_success(&mut user);
|
||||
assert_eq!(tb.pdu_queue_len(), 1);
|
||||
tb.check_finished_pdu_success();
|
||||
tb.acknowledge_finished_pdu(&mut user, &transfer_info);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_multi_packet_nak_sequence_normal_file_flag() {
|
||||
let file_data = [0_u8; 64];
|
||||
let file_size = file_data.len() as u64;
|
||||
let fault_handler = TestFaultHandler::default();
|
||||
|
||||
let mut tb = DestHandlerTestbench::new_with_fixed_paths(
|
||||
fault_handler,
|
||||
TransmissionMode::Acknowledged,
|
||||
false,
|
||||
);
|
||||
// Disable this, we only want to check the deferred procedure.
|
||||
tb.remote_cfg_mut().immediate_nak_mode = false;
|
||||
let max_packet_len = 50;
|
||||
tb.remote_cfg_mut().max_packet_len = max_packet_len;
|
||||
let mut user = tb.test_user_from_cached_paths(file_size);
|
||||
let transfer_info = tb
|
||||
.generic_transfer_init(&mut user, file_size)
|
||||
.expect("transfer init failed");
|
||||
tb.state_check(State::Busy, TransactionStep::ReceivingFileDataPdus);
|
||||
|
||||
assert_eq!(
|
||||
NakPduCreatorWithReservedSeqReqsBuf::calculate_max_segment_requests(
|
||||
max_packet_len,
|
||||
&PduHeader::new_for_file_directive(tb.pdu_conf, 0),
|
||||
)
|
||||
.unwrap(),
|
||||
4
|
||||
);
|
||||
let missing_segs_0: &[(u64, u64)] = &[(0, 2), (4, 6), (8, 10), (12, 14)];
|
||||
let missing_segs_1: &[(u64, u64)] = &[(16, 18)];
|
||||
assert_eq!(
|
||||
tb.generic_file_data_insert(&mut user, 2, &file_data[2..4])
|
||||
.expect("file data insertion failed"),
|
||||
0
|
||||
);
|
||||
assert_eq!(
|
||||
tb.generic_file_data_insert(&mut user, 6, &file_data[6..8])
|
||||
.expect("file data insertion failed"),
|
||||
0
|
||||
);
|
||||
assert_eq!(
|
||||
tb.generic_file_data_insert(&mut user, 10, &file_data[10..12])
|
||||
.expect("file data insertion failed"),
|
||||
0
|
||||
);
|
||||
assert_eq!(
|
||||
tb.generic_file_data_insert(&mut user, 14, &file_data[14..16])
|
||||
.expect("file data insertion failed"),
|
||||
0
|
||||
);
|
||||
assert_eq!(
|
||||
tb.generic_file_data_insert(&mut user, 18, &file_data[18..file_size as usize])
|
||||
.expect("file data insertion failed"),
|
||||
0
|
||||
);
|
||||
assert_eq!(
|
||||
tb.generic_eof_no_error(&mut user, file_data.to_vec())
|
||||
.expect("EOF no error insertion failed"),
|
||||
3
|
||||
);
|
||||
assert_eq!(tb.pdu_queue_len(), 3);
|
||||
tb.check_eof_ack_pdu(ConditionCode::NoError);
|
||||
let pdu = tb.get_next_pdu().unwrap();
|
||||
assert_eq!(pdu.pdu_type, PduType::FileDirective);
|
||||
assert_eq!(pdu.file_directive_type.unwrap(), FileDirectiveType::NakPdu);
|
||||
let nak_pdu = NakPduReader::new(&pdu.raw_pdu).unwrap();
|
||||
assert_eq!(nak_pdu.start_of_scope(), 0);
|
||||
assert_eq!(nak_pdu.end_of_scope(), 14);
|
||||
let seg_reqs: Vec<(u64, u64)> = nak_pdu.get_segment_requests_iterator().unwrap().collect();
|
||||
assert_eq!(seg_reqs, missing_segs_0);
|
||||
|
||||
let pdu = tb.get_next_pdu().unwrap();
|
||||
assert_eq!(pdu.pdu_type, PduType::FileDirective);
|
||||
assert_eq!(pdu.file_directive_type.unwrap(), FileDirectiveType::NakPdu);
|
||||
let nak_pdu = NakPduReader::new(&pdu.raw_pdu).unwrap();
|
||||
assert_eq!(nak_pdu.start_of_scope(), 14);
|
||||
assert_eq!(nak_pdu.end_of_scope(), file_size);
|
||||
let seg_reqs: Vec<(u64, u64)> = nak_pdu.get_segment_requests_iterator().unwrap().collect();
|
||||
assert_eq!(seg_reqs, missing_segs_1);
|
||||
|
||||
for missing_seg in missing_segs_0 {
|
||||
assert_eq!(
|
||||
tb.generic_file_data_insert(
|
||||
&mut user,
|
||||
missing_seg.0,
|
||||
&file_data[missing_seg.0 as usize..missing_seg.1 as usize]
|
||||
)
|
||||
.expect("file data insertion failed"),
|
||||
0
|
||||
);
|
||||
}
|
||||
for missing_seg in missing_segs_1 {
|
||||
assert_eq!(
|
||||
tb.generic_file_data_insert(
|
||||
&mut user,
|
||||
missing_seg.0,
|
||||
&file_data[missing_seg.0 as usize..missing_seg.1 as usize]
|
||||
)
|
||||
.expect("file data insertion failed"),
|
||||
1
|
||||
);
|
||||
}
|
||||
|
||||
tb.check_completion_indication_success(&mut user);
|
||||
assert_eq!(tb.pdu_queue_len(), 1);
|
||||
tb.check_finished_pdu_success();
|
||||
tb.acknowledge_finished_pdu(&mut user, &transfer_info);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,7 +138,7 @@ impl CfdpUser for ExampleCfdpUser {
|
||||
}
|
||||
}
|
||||
|
||||
fn end_to_end_test(with_closure: bool) {
|
||||
fn end_to_end_test(transmission_mode: TransmissionMode, with_closure: bool) {
|
||||
// Simplified event handling using atomic signals.
|
||||
let stop_signal_source = Arc::new(AtomicBool::new(false));
|
||||
let stop_signal_dest = stop_signal_source.clone();
|
||||
@@ -173,7 +173,7 @@ fn end_to_end_test(with_closure: bool) {
|
||||
1024,
|
||||
with_closure,
|
||||
false,
|
||||
spacepackets::cfdp::TransmissionMode::Unacknowledged,
|
||||
transmission_mode,
|
||||
ChecksumType::Crc32,
|
||||
);
|
||||
let seq_count_provider = AtomicU16::default();
|
||||
@@ -199,7 +199,7 @@ fn end_to_end_test(with_closure: bool) {
|
||||
1024,
|
||||
true,
|
||||
false,
|
||||
spacepackets::cfdp::TransmissionMode::Unacknowledged,
|
||||
transmission_mode,
|
||||
ChecksumType::Crc32,
|
||||
);
|
||||
let mut dest_handler = DestinationHandler::new(
|
||||
@@ -217,7 +217,7 @@ fn end_to_end_test(with_closure: bool) {
|
||||
REMOTE_ID.into(),
|
||||
srcfile.to_str().expect("invaid path string"),
|
||||
destfile.to_str().expect("invaid path string"),
|
||||
Some(TransmissionMode::Unacknowledged),
|
||||
Some(transmission_mode),
|
||||
Some(with_closure),
|
||||
)
|
||||
.expect("put request creation failed");
|
||||
@@ -326,11 +326,16 @@ fn end_to_end_test(with_closure: bool) {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn end_to_end_test_no_closure() {
|
||||
end_to_end_test(false);
|
||||
fn end_to_end_unacknowledged_no_closure() {
|
||||
end_to_end_test(TransmissionMode::Unacknowledged, false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn end_to_end_test_with_closure() {
|
||||
end_to_end_test(true);
|
||||
fn end_to_end_unacknowledged_with_closure() {
|
||||
end_to_end_test(TransmissionMode::Unacknowledged, true);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn end_to_end_acknowledged() {
|
||||
end_to_end_test(TransmissionMode::Acknowledged, true);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user