CFDP extracted to library #201

Closed
muellerr wants to merge 18 commits from continue-cfsp-source-handler into main
Showing only changes of commit 1646aac004 - Show all commits

View File

@ -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);
}