CFDP extracted to library #201
@ -1,5 +1,4 @@
|
||||
use core::{cell::RefCell, ops::ControlFlow, str::Utf8Error};
|
||||
use std::println;
|
||||
|
||||
use spacepackets::{
|
||||
cfdp::{
|
||||
@ -748,11 +747,14 @@ impl<
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::path::PathBuf;
|
||||
use std::{path::PathBuf, string::ToString};
|
||||
|
||||
use alloc::string::String;
|
||||
use spacepackets::{
|
||||
cfdp::{pdu::metadata::MetadataPduReader, ChecksumType, CrcFlag},
|
||||
cfdp::{
|
||||
pdu::{finished::FinishedPduCreator, metadata::MetadataPduReader},
|
||||
ChecksumType, CrcFlag,
|
||||
},
|
||||
util::UnsignedByteFieldU16,
|
||||
};
|
||||
use tempfile::TempPath;
|
||||
@ -790,8 +792,8 @@ mod tests {
|
||||
|
||||
struct SourceHandlerTestbench {
|
||||
handler: TestSourceHandler,
|
||||
// src_path: PathBuf,
|
||||
// dest_path: PathBuf,
|
||||
srcfile: Option<String>,
|
||||
destfile: Option<String>,
|
||||
}
|
||||
|
||||
impl SourceHandlerTestbench {
|
||||
@ -816,9 +818,22 @@ mod tests {
|
||||
basic_remote_cfg_table(REMOTE_ID, crc_on_transmission_by_default),
|
||||
SeqCountProviderSimple::default(),
|
||||
),
|
||||
srcfile: None,
|
||||
destfile: None,
|
||||
}
|
||||
}
|
||||
|
||||
fn put_request(
|
||||
&mut self,
|
||||
put_request: &impl ReadablePutRequest,
|
||||
) -> Result<(), PutRequestError> {
|
||||
if self.srcfile.is_some() || self.destfile.is_some() {
|
||||
self.srcfile = Some(put_request.source_file().unwrap().to_string());
|
||||
self.destfile = Some(put_request.dest_file().unwrap().to_string());
|
||||
}
|
||||
self.handler.put_request(put_request)
|
||||
}
|
||||
|
||||
fn all_fault_queues_empty(&self) -> bool {
|
||||
self.handler
|
||||
.local_cfg
|
||||
@ -834,6 +849,33 @@ mod tests {
|
||||
fn get_next_sent_pdu(&self) -> Option<SentPdu> {
|
||||
self.handler.pdu_sender.retrieve_next_pdu()
|
||||
}
|
||||
|
||||
fn common_pdu_check_for_file_transfer(&self, pdu_header: &PduHeader, crc_flag: CrcFlag) {
|
||||
assert_eq!(
|
||||
pdu_header.seg_ctrl(),
|
||||
SegmentationControl::NoRecordBoundaryPreservation
|
||||
);
|
||||
assert_eq!(
|
||||
pdu_header.seg_metadata_flag(),
|
||||
SegmentMetadataFlag::NotPresent
|
||||
);
|
||||
assert_eq!(pdu_header.common_pdu_conf().source_id(), LOCAL_ID.into());
|
||||
assert_eq!(pdu_header.common_pdu_conf().dest_id(), REMOTE_ID.into());
|
||||
assert_eq!(pdu_header.common_pdu_conf().crc_flag, crc_flag);
|
||||
assert_eq!(
|
||||
pdu_header.common_pdu_conf().trans_mode,
|
||||
TransmissionMode::Unacknowledged
|
||||
);
|
||||
assert_eq!(
|
||||
pdu_header.common_pdu_conf().direction,
|
||||
Direction::TowardsReceiver
|
||||
);
|
||||
assert_eq!(
|
||||
pdu_header.common_pdu_conf().file_flag,
|
||||
LargeFileFlag::Normal
|
||||
);
|
||||
assert_eq!(pdu_header.common_pdu_conf().transaction_seq_num.size(), 2);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -848,31 +890,21 @@ mod tests {
|
||||
assert_eq!(tb.handler.step(), TransactionStep::Idle);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_empty_file_transfer_not_acked_no_closure() {
|
||||
let fault_handler = TestFaultHandler::default();
|
||||
let test_sender = TestCfdpSender::default();
|
||||
let mut tb = SourceHandlerTestbench::new(false, fault_handler, test_sender);
|
||||
let (srcfile, destfile) = init_full_filepaths_textfile();
|
||||
let srcfile_str = String::from(srcfile.to_str().unwrap());
|
||||
let destfile_str = String::from(destfile.to_str().unwrap());
|
||||
let put_request = PutRequestOwned::new_regular_request(
|
||||
REMOTE_ID.into(),
|
||||
&srcfile_str,
|
||||
&destfile_str,
|
||||
Some(TransmissionMode::Unacknowledged),
|
||||
Some(false),
|
||||
)
|
||||
.expect("creating put request failed");
|
||||
fn common_no_acked_file_transfer(
|
||||
tb: &mut SourceHandlerTestbench,
|
||||
cfdp_user: &mut TestCfdpUser,
|
||||
put_request: PutRequestOwned,
|
||||
srcfile_str: String,
|
||||
destfile_str: String,
|
||||
) -> PduHeader {
|
||||
tb.handler
|
||||
.put_request(&put_request)
|
||||
.expect("put_request call failed");
|
||||
assert_eq!(tb.handler.state(), State::Busy);
|
||||
assert_eq!(tb.handler.step(), TransactionStep::Idle);
|
||||
let mut cfdp_user = TestCfdpUser::new(0, srcfile_str.clone(), destfile_str.clone(), 0);
|
||||
let sent_packets = tb
|
||||
.handler
|
||||
.state_machine(&mut cfdp_user, None)
|
||||
.state_machine(cfdp_user, None)
|
||||
.expect("source handler FSM failure");
|
||||
assert_eq!(sent_packets, 2);
|
||||
assert!(!tb.pdu_queue_empty());
|
||||
@ -885,6 +917,8 @@ mod tests {
|
||||
);
|
||||
let metadata_pdu =
|
||||
MetadataPduReader::new(&next_pdu.raw_pdu).expect("invalid metadata PDU format");
|
||||
let pdu_header = metadata_pdu.pdu_header();
|
||||
tb.common_pdu_check_for_file_transfer(metadata_pdu.pdu_header(), CrcFlag::NoCrc);
|
||||
assert_eq!(
|
||||
metadata_pdu
|
||||
.src_file_name()
|
||||
@ -906,7 +940,16 @@ mod tests {
|
||||
metadata_pdu.metadata_params().checksum_type,
|
||||
ChecksumType::Crc32
|
||||
);
|
||||
assert!(!metadata_pdu.metadata_params().closure_requested);
|
||||
let closure_requested = if let Some(closure_requested) = put_request.closure_requested {
|
||||
assert_eq!(
|
||||
metadata_pdu.metadata_params().closure_requested,
|
||||
closure_requested
|
||||
);
|
||||
closure_requested
|
||||
} else {
|
||||
assert!(metadata_pdu.metadata_params().closure_requested);
|
||||
metadata_pdu.metadata_params().closure_requested
|
||||
};
|
||||
assert_eq!(metadata_pdu.options(), &[]);
|
||||
|
||||
let next_pdu = tb.get_next_sent_pdu().unwrap();
|
||||
@ -916,33 +959,10 @@ mod tests {
|
||||
Some(FileDirectiveType::EofPdu)
|
||||
);
|
||||
let eof_pdu = EofPdu::from_bytes(&next_pdu.raw_pdu).expect("invalid metadata PDU format");
|
||||
tb.common_pdu_check_for_file_transfer(eof_pdu.pdu_header(), CrcFlag::NoCrc);
|
||||
assert_eq!(eof_pdu.condition_code(), ConditionCode::NoError);
|
||||
assert_eq!(eof_pdu.file_size(), 0);
|
||||
assert_eq!(eof_pdu.file_checksum(), CRC_32.digest().finalize());
|
||||
assert_eq!(
|
||||
eof_pdu.pdu_header().common_pdu_conf().source_id(),
|
||||
LOCAL_ID.into()
|
||||
);
|
||||
assert_eq!(
|
||||
eof_pdu.pdu_header().common_pdu_conf().dest_id(),
|
||||
REMOTE_ID.into()
|
||||
);
|
||||
assert_eq!(
|
||||
eof_pdu.pdu_header().common_pdu_conf().crc_flag,
|
||||
CrcFlag::NoCrc
|
||||
);
|
||||
assert_eq!(
|
||||
eof_pdu.pdu_header().common_pdu_conf().direction,
|
||||
Direction::TowardsReceiver
|
||||
);
|
||||
assert_eq!(
|
||||
eof_pdu.pdu_header().common_pdu_conf().file_flag,
|
||||
LargeFileFlag::Normal
|
||||
);
|
||||
assert_eq!(
|
||||
eof_pdu.pdu_header().common_pdu_conf().trans_mode,
|
||||
TransmissionMode::Unacknowledged
|
||||
);
|
||||
assert_eq!(
|
||||
eof_pdu
|
||||
.pdu_header()
|
||||
@ -951,14 +971,76 @@ mod tests {
|
||||
.value_const(),
|
||||
0
|
||||
);
|
||||
assert_eq!(
|
||||
eof_pdu
|
||||
.pdu_header()
|
||||
.common_pdu_conf()
|
||||
.transaction_seq_num
|
||||
.size(),
|
||||
2
|
||||
if !closure_requested {
|
||||
assert_eq!(tb.handler.state(), State::Idle);
|
||||
assert_eq!(tb.handler.step(), TransactionStep::Idle);
|
||||
} else {
|
||||
assert_eq!(tb.handler.state(), State::Busy);
|
||||
assert_eq!(tb.handler.step(), TransactionStep::WaitingForFinished);
|
||||
}
|
||||
*pdu_header
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_empty_file_transfer_not_acked_no_closure() {
|
||||
let fault_handler = TestFaultHandler::default();
|
||||
let test_sender = TestCfdpSender::default();
|
||||
let mut tb = SourceHandlerTestbench::new(false, fault_handler, test_sender);
|
||||
let (srcfile, destfile) = init_full_filepaths_textfile();
|
||||
let srcfile_str = String::from(srcfile.to_str().unwrap());
|
||||
let destfile_str = String::from(destfile.to_str().unwrap());
|
||||
let put_request = PutRequestOwned::new_regular_request(
|
||||
REMOTE_ID.into(),
|
||||
&srcfile_str,
|
||||
&destfile_str,
|
||||
Some(TransmissionMode::Unacknowledged),
|
||||
Some(false),
|
||||
)
|
||||
.expect("creating put request failed");
|
||||
let mut cfdp_user = TestCfdpUser::new(0, srcfile_str.clone(), destfile_str.clone(), 0);
|
||||
common_no_acked_file_transfer(
|
||||
&mut tb,
|
||||
&mut cfdp_user,
|
||||
put_request,
|
||||
srcfile_str,
|
||||
destfile_str,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_empty_file_transfer_not_acked_with_closure() {
|
||||
let fault_handler = TestFaultHandler::default();
|
||||
let test_sender = TestCfdpSender::default();
|
||||
let mut tb = SourceHandlerTestbench::new(false, fault_handler, test_sender);
|
||||
let (srcfile, destfile) = init_full_filepaths_textfile();
|
||||
let srcfile_str = String::from(srcfile.to_str().unwrap());
|
||||
let destfile_str = String::from(destfile.to_str().unwrap());
|
||||
let put_request = PutRequestOwned::new_regular_request(
|
||||
REMOTE_ID.into(),
|
||||
&srcfile_str,
|
||||
&destfile_str,
|
||||
Some(TransmissionMode::Unacknowledged),
|
||||
Some(true),
|
||||
)
|
||||
.expect("creating put request failed");
|
||||
let mut cfdp_user = TestCfdpUser::new(0, srcfile_str.clone(), destfile_str.clone(), 0);
|
||||
let pdu_header = common_no_acked_file_transfer(
|
||||
&mut tb,
|
||||
&mut cfdp_user,
|
||||
put_request,
|
||||
srcfile_str,
|
||||
destfile_str,
|
||||
);
|
||||
let finished_pdu = FinishedPduCreator::new_default(
|
||||
pdu_header,
|
||||
DeliveryCode::Complete,
|
||||
FileStatus::Retained,
|
||||
);
|
||||
let finished_pdu_vec = finished_pdu.to_vec().unwrap();
|
||||
let packet_info = PacketInfo::new(&finished_pdu_vec).unwrap();
|
||||
tb.handler
|
||||
.state_machine(&mut cfdp_user, Some(&packet_info))
|
||||
.unwrap();
|
||||
assert_eq!(tb.handler.state(), State::Idle);
|
||||
assert_eq!(tb.handler.step(), TransactionStep::Idle);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user