testbench for reply handlers
Some checks failed
Rust/sat-rs/pipeline/pr-main There was a failure building this commit

This commit is contained in:
Robin Müller 2024-03-25 19:18:15 +01:00
parent 1e93bded04
commit 47b9bb1fb9
Signed by: muellerr
GPG Key ID: A649FB78196E3849
6 changed files with 132 additions and 12 deletions

View File

@ -560,4 +560,6 @@ mod tests {
assert!(result.is_err());
// Verify the correct result and completion failure.
}
// TODO: Add more dedicated tests using the dedicated converter and reply handler testbenches.
}

View File

@ -371,7 +371,7 @@ mod tests {
use satrs::{
hk::HkRequest,
pus::{test_util::TEST_APID, ActiveRequestProvider},
request::TargetAndApidId,
request::{GenericMessage, TargetAndApidId},
spacepackets::{
ecss::{
hk::Subservice,
@ -382,15 +382,14 @@ mod tests {
},
};
use crate::pus::tests::ConverterTestbench;
use crate::pus::tests::{PusConverterTestbench, ReplyHandlerTestbench};
use super::ExampleHkRequestConverter;
use super::{ExampleHkRequestConverter, HkReply, HkReplyHandler};
#[test]
fn test_hk_converter_one_shot_req() {
let mut hk_bench = ConverterTestbench::new(ExampleHkRequestConverter::default());
let mut hk_bench = PusConverterTestbench::new(ExampleHkRequestConverter::default());
let mut sp_header = SpHeader::tc_unseg(TEST_APID, 0, 0).unwrap();
let target_id = 2_u32;
let unique_id = 5_u32;
let mut app_data: [u8; 8] = [0; 8];
@ -420,4 +419,17 @@ mod tests {
panic!("unexpected HK request")
}
}
#[test]
fn test_hk_reply_handler() {
let mut reply_testbench = ReplyHandlerTestbench::new(HkReplyHandler::default());
let sender_id = 2_u64;
let target_id = 3_u64;
let (req_id, active_req) = reply_testbench.add_tc(TEST_APID, target_id, &[]);
let reply = GenericMessage::new(req_id.into(), sender_id, HkReply::Ack);
let result = reply_testbench.handle_reply(&reply, &active_req, &[]);
assert!(result.is_ok());
}
// TODO: Add more tests.
}

View File

@ -466,6 +466,7 @@ impl<VerificationReporter: VerificationReportingProvider> PusReceiver<Verificati
#[cfg(test)]
pub(crate) mod tests {
use std::time::Duration;
use satrs::{
pus::{
@ -473,10 +474,14 @@ pub(crate) mod tests {
test_util::{SharedVerificationMap, TestVerificationReporter},
VerificationReporterWithVecMpscSender,
},
ActiveRequestMapProvider, EcssTcInVecConverter, MpscTcReceiver, TmAsVecSenderWithMpsc,
ActivePusRequestStd, ActiveRequestMapProvider, EcssTcInVecConverter, MpscTcReceiver,
TmAsVecSenderWithMpsc,
},
request::TargetAndApidId,
spacepackets::ecss::tc::PusTcCreator,
spacepackets::{
ecss::tc::{PusTcCreator, PusTcSecondaryHeader},
SpHeader,
},
};
use crate::requests::CompositeRequest;
@ -487,7 +492,86 @@ pub(crate) mod tests {
pub const TEST_APID_TARGET_ID: u32 = 5;
pub const TARGET_ID: TargetAndApidId = TargetAndApidId::new(TEST_APID, TEST_APID_TARGET_ID);
pub struct ConverterTestbench<
// Testbench dedicated to the testing of [PusReplyHandler]s
pub struct ReplyHandlerTestbench<
ReplyHandler: PusReplyHandler<ActiveRequestInfo, Reply, Error = EcssTmtcError>,
ActiveRequestInfo: ActiveRequestProvider,
Reply,
> {
pub shared_verif_map: SharedVerificationMap,
pub verif_reporter: TestVerificationReporter,
pub reply_handler: ReplyHandler,
pub tm_receiver: mpsc::Receiver<Vec<u8>>,
tm_sender: TmAsVecSenderWithMpsc,
phantom: std::marker::PhantomData<(ActiveRequestInfo, Reply)>,
}
impl<
ReplyHandler: PusReplyHandler<ActiveRequestInfo, Reply, Error = EcssTmtcError>,
ActiveRequestInfo: ActiveRequestProvider,
Reply,
> ReplyHandlerTestbench<ReplyHandler, ActiveRequestInfo, Reply>
{
pub fn new(reply_handler: ReplyHandler) -> Self {
let shared_verif_map = SharedVerificationMap::default();
let test_verif_reporter = TestVerificationReporter::new(shared_verif_map.clone());
let (tm_sender, tm_receiver) = mpsc::channel();
Self {
shared_verif_map,
verif_reporter: test_verif_reporter,
reply_handler,
tm_sender: TmAsVecSenderWithMpsc::new(0, "TEST_SENDER", tm_sender),
tm_receiver,
phantom: std::marker::PhantomData,
}
}
pub fn add_tc(
&mut self,
apid: u16,
target_id: ComponentId,
time_stamp: &[u8],
) -> (verification::RequestId, ActivePusRequestStd) {
let mut sp_header = SpHeader::tc_unseg(apid, 0, 0).unwrap();
let sec_header_dummy = PusTcSecondaryHeader::new_simple(0, 0);
let init = self.verif_reporter.add_tc(&PusTcCreator::new(
&mut sp_header,
sec_header_dummy,
&[],
true,
));
let accepted = self
.verif_reporter
.acceptance_success(init, time_stamp)
.expect("acceptance failed");
let started = self
.verif_reporter
.start_success(accepted, time_stamp)
.expect("start failed");
(
started.req_id(),
ActivePusRequestStd::new(target_id, started, Duration::from_secs(30)),
)
}
pub fn handle_reply(
&mut self,
reply: &GenericMessage<Reply>,
active_request: &ActiveRequestInfo,
time_stamp: &[u8],
) -> Result<bool, ReplyHandler::Error> {
self.reply_handler.handle_reply(
reply,
active_request,
&self.verif_reporter,
time_stamp,
&self.tm_sender,
)
}
}
// Testbench dedicated to the testing of [PusTcToRequestConverter]s
pub struct PusConverterTestbench<
Converter: PusTcToRequestConverter<ActiveRequestInfo, Request, Error = GenericConversionError>,
ActiveRequestInfo: ActiveRequestProvider,
Request,
@ -502,7 +586,7 @@ pub(crate) mod tests {
Converter: PusTcToRequestConverter<ActiveRequestInfo, Request, Error = GenericConversionError>,
ActiveRequestInfo: ActiveRequestProvider,
Request,
> ConverterTestbench<Converter, ActiveRequestInfo, Request>
> PusConverterTestbench<Converter, ActiveRequestInfo, Request>
{
pub fn new(converter: Converter) -> Self {
let shared_verif_map = SharedVerificationMap::default();

View File

@ -195,3 +195,6 @@ impl PusTcToRequestConverter<ActivePusRequestStd, ModeRequest> for ExampleModeRe
}
}
}
#[cfg(test)]
mod tests {}

View File

@ -1080,6 +1080,7 @@ pub mod std_mod {
fn target_id(&self) -> ComponentId {
self.target_id
}
fn token(&self) -> TcStateToken {
self.token
}

View File

@ -141,6 +141,11 @@ impl RequestId {
/// This allows extracting the request ID from a given PUS telecommand.
pub fn new(tc: &(impl CcsdsPacket + IsPusTelecommand)) -> Self {
Self::new_from_ccsds_tc(tc)
}
/// Extract the request ID from a CCSDS TC packet.
pub fn new_from_ccsds_tc(tc: &impl CcsdsPacket) -> Self {
RequestId {
version_number: tc.ccsds_version(),
packet_id: tc.packet_id(),
@ -226,7 +231,13 @@ impl<STATE> VerificationToken<STATE> {
}
}
/// Create a verification token with a state. This can be useful for test purposes.
pub fn req_id(&self) -> RequestId {
self.req_id
}
}
impl VerificationToken<TcStateAccepted> {
/// Create a verification token with the accepted state. This can be useful for test purposes.
/// For general purposes, it is recommended to use the API exposed by verification handlers.
pub fn new_accepted_state(req_id: RequestId) -> VerificationToken<TcStateAccepted> {
VerificationToken {
@ -234,9 +245,16 @@ impl<STATE> VerificationToken<STATE> {
req_id,
}
}
}
pub fn req_id(&self) -> RequestId {
self.req_id
impl VerificationToken<TcStateStarted> {
/// Create a verification token with the started state. This can be useful for test purposes.
/// For general purposes, it is recommended to use the API exposed by verification handlers.
pub fn new_started_state(req_id: RequestId) -> VerificationToken<TcStateStarted> {
VerificationToken {
state: PhantomData,
req_id,
}
}
}