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