going towards unittest completion
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-29 16:20:06 +01:00
parent 9144a9f9a3
commit 5c1acfe912
Signed by: muellerr
GPG Key ID: A649FB78196E3849
8 changed files with 170 additions and 106 deletions

View File

@ -3,8 +3,7 @@ use satrs::action::{ActionRequest, ActionRequestVariant};
use satrs::params::WritableToBeBytes; use satrs::params::WritableToBeBytes;
use satrs::pool::{SharedStaticMemoryPool, StoreAddr}; use satrs::pool::{SharedStaticMemoryPool, StoreAddr};
use satrs::pus::action::{ use satrs::pus::action::{
ActionReplyPus, ActionReplyPusWithActionId, ActivePusActionRequestStd, ActionReplyVariant, ActivePusActionRequestStd, DefaultActiveActionRequestMap, PusActionReply,
DefaultActiveActionRequestMap,
}; };
use satrs::pus::verification::{ use satrs::pus::verification::{
FailParams, FailParamsWithStep, TcStateAccepted, TcStateStarted, FailParams, FailParamsWithStep, TcStateAccepted, TcStateStarted,
@ -43,12 +42,12 @@ impl Default for ActionReplyHandler {
} }
} }
impl PusReplyHandler<ActivePusActionRequestStd, ActionReplyPusWithActionId> for ActionReplyHandler { impl PusReplyHandler<ActivePusActionRequestStd, PusActionReply> for ActionReplyHandler {
type Error = EcssTmtcError; type Error = EcssTmtcError;
fn handle_unexpected_reply( fn handle_unrequested_reply(
&mut self, &mut self,
reply: &GenericMessage<ActionReplyPusWithActionId>, reply: &GenericMessage<PusActionReply>,
_tm_sender: &impl EcssTmSenderCore, _tm_sender: &impl EcssTmSenderCore,
) -> Result<(), Self::Error> { ) -> Result<(), Self::Error> {
log::warn!("received unexpected reply for service 8: {reply:?}"); log::warn!("received unexpected reply for service 8: {reply:?}");
@ -57,7 +56,7 @@ impl PusReplyHandler<ActivePusActionRequestStd, ActionReplyPusWithActionId> for
fn handle_reply( fn handle_reply(
&mut self, &mut self,
reply: &satrs::request::GenericMessage<ActionReplyPusWithActionId>, reply: &satrs::request::GenericMessage<PusActionReply>,
active_request: &ActivePusActionRequestStd, active_request: &ActivePusActionRequestStd,
verification_handler: &impl VerificationReportingProvider, verification_handler: &impl VerificationReportingProvider,
time_stamp: &[u8], time_stamp: &[u8],
@ -68,7 +67,7 @@ impl PusReplyHandler<ActivePusActionRequestStd, ActionReplyPusWithActionId> for
.try_into() .try_into()
.expect("invalid token state"); .expect("invalid token state");
let remove_entry = match &reply.message.variant { let remove_entry = match &reply.message.variant {
ActionReplyPus::CompletionFailed { error_code, params } => { ActionReplyVariant::CompletionFailed { error_code, params } => {
let mut fail_data_len = 0; let mut fail_data_len = 0;
if let Some(params) = params { if let Some(params) = params {
fail_data_len = params.write_to_be_bytes(&mut self.fail_data_buf)?; fail_data_len = params.write_to_be_bytes(&mut self.fail_data_buf)?;
@ -85,7 +84,7 @@ impl PusReplyHandler<ActivePusActionRequestStd, ActionReplyPusWithActionId> for
.map_err(|e| e.0)?; .map_err(|e| e.0)?;
true true
} }
ActionReplyPus::StepFailed { ActionReplyVariant::StepFailed {
error_code, error_code,
step, step,
params, params,
@ -107,13 +106,13 @@ impl PusReplyHandler<ActivePusActionRequestStd, ActionReplyPusWithActionId> for
.map_err(|e| e.0)?; .map_err(|e| e.0)?;
true true
} }
ActionReplyPus::Completed => { ActionReplyVariant::Completed => {
verification_handler verification_handler
.completion_success(verif_token, time_stamp) .completion_success(verif_token, time_stamp)
.map_err(|e| e.0)?; .map_err(|e| e.0)?;
true true
} }
ActionReplyPus::StepSuccess { step } => { ActionReplyVariant::StepSuccess { step } => {
verification_handler.step_success( verification_handler.step_success(
&verif_token, &verif_token,
time_stamp, time_stamp,
@ -205,7 +204,7 @@ pub fn create_action_service_static(
tc_pool: SharedStaticMemoryPool, tc_pool: SharedStaticMemoryPool,
pus_action_rx: mpsc::Receiver<EcssTcAndToken>, pus_action_rx: mpsc::Receiver<EcssTcAndToken>,
action_router: GenericRequestRouter, action_router: GenericRequestRouter,
reply_receiver: mpsc::Receiver<GenericMessage<ActionReplyPusWithActionId>>, reply_receiver: mpsc::Receiver<GenericMessage<PusActionReply>>,
) -> Pus8Wrapper< ) -> Pus8Wrapper<
MpscTcReceiver, MpscTcReceiver,
TmInSharedPoolSenderWithBoundedMpsc, TmInSharedPoolSenderWithBoundedMpsc,
@ -250,7 +249,7 @@ pub fn create_action_service_dynamic(
verif_reporter: VerificationReporterWithVecMpscSender, verif_reporter: VerificationReporterWithVecMpscSender,
pus_action_rx: mpsc::Receiver<EcssTcAndToken>, pus_action_rx: mpsc::Receiver<EcssTcAndToken>,
action_router: GenericRequestRouter, action_router: GenericRequestRouter,
reply_receiver: mpsc::Receiver<GenericMessage<ActionReplyPusWithActionId>>, reply_receiver: mpsc::Receiver<GenericMessage<PusActionReply>>,
) -> Pus8Wrapper< ) -> Pus8Wrapper<
MpscTcReceiver, MpscTcReceiver,
TmAsVecSenderWithMpsc, TmAsVecSenderWithMpsc,
@ -303,7 +302,7 @@ pub struct Pus8Wrapper<
DefaultActiveActionRequestMap, DefaultActiveActionRequestMap,
ActivePusActionRequestStd, ActivePusActionRequestStd,
ActionRequest, ActionRequest,
ActionReplyPusWithActionId, PusActionReply,
>, >,
} }
@ -387,7 +386,7 @@ mod tests {
DefaultActiveActionRequestMap, DefaultActiveActionRequestMap,
ActivePusActionRequestStd, ActivePusActionRequestStd,
ActionRequest, ActionRequest,
ActionReplyPusWithActionId, PusActionReply,
> >
{ {
pub fn new_for_action() -> Self { pub fn new_for_action() -> Self {
@ -529,8 +528,7 @@ mod tests {
if let CompositeRequest::Action(action_req) = req.message { if let CompositeRequest::Action(action_req) = req.message {
assert_eq!(action_req.action_id, action_id); assert_eq!(action_req.action_id, action_id);
assert_eq!(action_req.variant, ActionRequestVariant::NoData); assert_eq!(action_req.variant, ActionRequestVariant::NoData);
let action_reply = let action_reply = PusActionReply::new(action_id, ActionReplyVariant::Completed);
ActionReplyPusWithActionId::new(action_id, ActionReplyPus::Completed);
testbench testbench
.reply_tx .reply_tx
.send(GenericMessage::new( .send(GenericMessage::new(
@ -634,7 +632,7 @@ mod tests {
let (req_id, active_req) = testbench.add_tc(TEST_APID, TEST_APID_TARGET_ID, &[]); let (req_id, active_req) = testbench.add_tc(TEST_APID, TEST_APID_TARGET_ID, &[]);
let active_action_req = let active_action_req =
ActivePusActionRequestStd::new_from_common_req(action_id, active_req); ActivePusActionRequestStd::new_from_common_req(action_id, active_req);
let reply = ActionReplyPusWithActionId::new(action_id, ActionReplyPus::Completed); let reply = PusActionReply::new(action_id, ActionReplyVariant::Completed);
let generic_reply = GenericMessage::new(req_id.into(), 0, reply); let generic_reply = GenericMessage::new(req_id.into(), 0, reply);
let result = testbench.handle_reply(&generic_reply, &active_action_req, &[]); let result = testbench.handle_reply(&generic_reply, &active_action_req, &[]);
assert!(result.is_ok()); assert!(result.is_ok());
@ -652,9 +650,9 @@ mod tests {
let active_action_req = let active_action_req =
ActivePusActionRequestStd::new_from_common_req(action_id, active_req); ActivePusActionRequestStd::new_from_common_req(action_id, active_req);
let error_code = ResultU16::new(2, 3); let error_code = ResultU16::new(2, 3);
let reply = ActionReplyPusWithActionId::new( let reply = PusActionReply::new(
action_id, action_id,
ActionReplyPus::CompletionFailed { ActionReplyVariant::CompletionFailed {
error_code, error_code,
params: None, params: None,
}, },
@ -675,8 +673,7 @@ mod tests {
let (req_id, active_req) = testbench.add_tc(TEST_APID, TEST_APID_TARGET_ID, &[]); let (req_id, active_req) = testbench.add_tc(TEST_APID, TEST_APID_TARGET_ID, &[]);
let active_action_req = let active_action_req =
ActivePusActionRequestStd::new_from_common_req(action_id, active_req); ActivePusActionRequestStd::new_from_common_req(action_id, active_req);
let reply = let reply = PusActionReply::new(action_id, ActionReplyVariant::StepSuccess { step: 1 });
ActionReplyPusWithActionId::new(action_id, ActionReplyPus::StepSuccess { step: 1 });
let generic_reply = GenericMessage::new(req_id.into(), 0, reply); let generic_reply = GenericMessage::new(req_id.into(), 0, reply);
let result = testbench.handle_reply(&generic_reply, &active_action_req, &[]); let result = testbench.handle_reply(&generic_reply, &active_action_req, &[]);
assert!(result.is_ok()); assert!(result.is_ok());
@ -697,9 +694,9 @@ mod tests {
let active_action_req = let active_action_req =
ActivePusActionRequestStd::new_from_common_req(action_id, active_req); ActivePusActionRequestStd::new_from_common_req(action_id, active_req);
let error_code = ResultU16::new(2, 3); let error_code = ResultU16::new(2, 3);
let reply = ActionReplyPusWithActionId::new( let reply = PusActionReply::new(
action_id, action_id,
ActionReplyPus::StepFailed { ActionReplyVariant::StepFailed {
error_code, error_code,
step: 1, step: 1,
params: None, params: None,
@ -718,11 +715,21 @@ mod tests {
#[test] #[test]
fn reply_handling_unrequested_reply() { fn reply_handling_unrequested_reply() {
// TODO: Implement let mut testbench = ReplyHandlerTestbench::new(ActionReplyHandler::default());
let action_reply = PusActionReply::new(5_u32, ActionReplyVariant::Completed);
let unrequested_reply = GenericMessage::new(10_u32, 15_u64, action_reply);
// Right now this function does not do a lot. We simply check that it does not panic or do
// weird stuff.
let result = testbench.handle_unrequested_reply(&unrequested_reply);
assert!(result.is_ok());
} }
#[test] #[test]
fn reply_handling_reply_timeout() { fn reply_handling_reply_timeout() {
// TODO: Implement let mut testbench = ReplyHandlerTestbench::new(ActionReplyHandler::default());
// TODO: Start a request, then time it out with the API and check verification completion
// failure.
// testbench.reply_handler.handle_request_timeout(active_request, verification_handler, time_stamp, tm_sender)
// testbench.default_timeout = Duration::from_millis(50);
} }
} }

View File

@ -1,5 +1,6 @@
use derive_new::new;
use log::{error, warn}; use log::{error, warn};
use satrs::hk::{CollectionIntervalFactor, HkRequest}; use satrs::hk::{CollectionIntervalFactor, HkRequest, HkRequestVariant, UniqueId};
use satrs::pool::{SharedStaticMemoryPool, StoreAddr}; use satrs::pool::{SharedStaticMemoryPool, StoreAddr};
use satrs::pus::verification::{ use satrs::pus::verification::{
FailParams, TcStateAccepted, TcStateStarted, FailParams, TcStateAccepted, TcStateStarted,
@ -28,8 +29,14 @@ use crate::requests::GenericRequestRouter;
use super::PusTargetedRequestService; use super::PusTargetedRequestService;
#[derive(Clone, PartialEq, Debug, new)]
pub struct HkReply {
pub unique_id: UniqueId,
pub variant: HkReplyVariant,
}
#[derive(Clone, PartialEq, Debug)] #[derive(Clone, PartialEq, Debug)]
pub enum HkReply { pub enum HkReplyVariant {
Ack, Ack,
} }
@ -39,7 +46,7 @@ pub struct HkReplyHandler {}
impl PusReplyHandler<ActivePusRequestStd, HkReply> for HkReplyHandler { impl PusReplyHandler<ActivePusRequestStd, HkReply> for HkReplyHandler {
type Error = EcssTmtcError; type Error = EcssTmtcError;
fn handle_unexpected_reply( fn handle_unrequested_reply(
&mut self, &mut self,
reply: &satrs::request::GenericMessage<HkReply>, reply: &satrs::request::GenericMessage<HkReply>,
_tm_sender: &impl EcssTmSenderCore, _tm_sender: &impl EcssTmSenderCore,
@ -60,8 +67,8 @@ impl PusReplyHandler<ActivePusRequestStd, HkReply> for HkReplyHandler {
.token() .token()
.try_into() .try_into()
.expect("invalid token state"); .expect("invalid token state");
match reply.message { match reply.message.variant {
HkReply::Ack => { HkReplyVariant::Ack => {
verification_handler verification_handler
.completion_success(started_token, time_stamp) .completion_success(started_token, time_stamp)
.expect("sending completio success verification failed"); .expect("sending completio success verification failed");
@ -160,15 +167,15 @@ impl PusTcToRequestConverter<ActivePusRequestStd, HkRequest> for HkRequestConver
} }
let request = match standard_subservice.unwrap() { let request = match standard_subservice.unwrap() {
hk::Subservice::TcEnableHkGeneration | hk::Subservice::TcEnableDiagGeneration => { hk::Subservice::TcEnableHkGeneration | hk::Subservice::TcEnableDiagGeneration => {
HkRequest::Enable(unique_id) HkRequest::new(unique_id, HkRequestVariant::Enable)
} }
hk::Subservice::TcDisableHkGeneration | hk::Subservice::TcDisableDiagGeneration => { hk::Subservice::TcDisableHkGeneration | hk::Subservice::TcDisableDiagGeneration => {
HkRequest::Disable(unique_id) HkRequest::new(unique_id, HkRequestVariant::Disable)
} }
hk::Subservice::TcReportHkReportStructures => todo!(), hk::Subservice::TcReportHkReportStructures => todo!(),
hk::Subservice::TmHkPacket => todo!(), hk::Subservice::TmHkPacket => todo!(),
hk::Subservice::TcGenerateOneShotHk | hk::Subservice::TcGenerateOneShotDiag => { hk::Subservice::TcGenerateOneShotHk | hk::Subservice::TcGenerateOneShotDiag => {
HkRequest::OneShot(unique_id) HkRequest::new(unique_id, HkRequestVariant::OneShot)
} }
hk::Subservice::TcModifyDiagCollectionInterval hk::Subservice::TcModifyDiagCollectionInterval
| hk::Subservice::TcModifyHkCollectionInterval => { | hk::Subservice::TcModifyHkCollectionInterval => {
@ -187,9 +194,13 @@ impl PusTcToRequestConverter<ActivePusRequestStd, HkRequest> for HkRequestConver
found: user_data.len(), found: user_data.len(),
}); });
} }
HkRequest::ModifyCollectionInterval( HkRequest::new(
unique_id, unique_id,
CollectionIntervalFactor::from_be_bytes(user_data[8..12].try_into().unwrap()), HkRequestVariant::ModifyCollectionInterval(
CollectionIntervalFactor::from_be_bytes(
user_data[8..12].try_into().unwrap(),
),
),
) )
} }
_ => { _ => {
@ -369,7 +380,7 @@ impl<
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use satrs::{ use satrs::{
hk::HkRequest, hk::HkRequestVariant,
pus::test_util::TEST_APID, pus::test_util::TEST_APID,
request::GenericMessage, request::GenericMessage,
spacepackets::{ spacepackets::{
@ -378,7 +389,10 @@ mod tests {
}, },
}; };
use crate::pus::tests::{PusConverterTestbench, ReplyHandlerTestbench, TEST_APID_TARGET_ID}; use crate::pus::{
hk::HkReplyVariant,
tests::{PusConverterTestbench, ReplyHandlerTestbench, TEST_APID_TARGET_ID},
};
use super::{HkReply, HkReplyHandler, HkRequestConverter}; use super::{HkReply, HkReplyHandler, HkRequestConverter};
@ -403,8 +417,9 @@ mod tests {
let (_active_req, req) = hk_bench let (_active_req, req) = hk_bench
.convert(accepted_token, &[], TEST_APID, TEST_APID_TARGET_ID) .convert(accepted_token, &[], TEST_APID, TEST_APID_TARGET_ID)
.expect("conversion failed"); .expect("conversion failed");
if let HkRequest::OneShot(id) = req {
assert_eq!(id, unique_id); assert_eq!(req.unique_id, unique_id);
if let HkRequestVariant::OneShot = req.variant {
} else { } else {
panic!("unexpected HK request") panic!("unexpected HK request")
} }
@ -424,8 +439,8 @@ mod tests {
let (_active_req, req) = hk_bench let (_active_req, req) = hk_bench
.convert(accepted_token, &[], TEST_APID, TEST_APID_TARGET_ID) .convert(accepted_token, &[], TEST_APID, TEST_APID_TARGET_ID)
.expect("conversion failed"); .expect("conversion failed");
if let HkRequest::Enable(id) = req { assert_eq!(req.unique_id, unique_id);
assert_eq!(id, unique_id); if let HkRequestVariant::Enable = req.variant {
} else { } else {
panic!("unexpected HK request") panic!("unexpected HK request")
} }
@ -462,8 +477,8 @@ mod tests {
let (_active_req, req) = hk_bench let (_active_req, req) = hk_bench
.convert(accepted_token, &[], TEST_APID, TEST_APID_TARGET_ID) .convert(accepted_token, &[], TEST_APID, TEST_APID_TARGET_ID)
.expect("conversion failed"); .expect("conversion failed");
if let HkRequest::Disable(id) = req { assert_eq!(req.unique_id, unique_id);
assert_eq!(id, unique_id); if let HkRequestVariant::Disable = req.variant {
} else { } else {
panic!("unexpected HK request") panic!("unexpected HK request")
} }
@ -503,8 +518,8 @@ mod tests {
let (_active_req, req) = hk_bench let (_active_req, req) = hk_bench
.convert(accepted_token, &[], TEST_APID, TEST_APID_TARGET_ID) .convert(accepted_token, &[], TEST_APID, TEST_APID_TARGET_ID)
.expect("conversion failed"); .expect("conversion failed");
if let HkRequest::ModifyCollectionInterval(id, interval_factor) = req { assert_eq!(req.unique_id, unique_id);
assert_eq!(id, unique_id); if let HkRequestVariant::ModifyCollectionInterval(interval_factor) = req.variant {
assert_eq!(interval_factor, collection_interval_factor); assert_eq!(interval_factor, collection_interval_factor);
} else { } else {
panic!("unexpected HK request") panic!("unexpected HK request")
@ -533,8 +548,13 @@ mod tests {
let mut reply_testbench = ReplyHandlerTestbench::new(HkReplyHandler::default()); let mut reply_testbench = ReplyHandlerTestbench::new(HkReplyHandler::default());
let sender_id = 2_u64; let sender_id = 2_u64;
let apid_target_id = 3_u32; let apid_target_id = 3_u32;
let unique_id = 5_u32;
let (req_id, active_req) = reply_testbench.add_tc(TEST_APID, apid_target_id, &[]); let (req_id, active_req) = reply_testbench.add_tc(TEST_APID, apid_target_id, &[]);
let reply = GenericMessage::new(req_id.into(), sender_id, HkReply::Ack); let reply = GenericMessage::new(
req_id.into(),
sender_id,
HkReply::new(unique_id, HkReplyVariant::Ack),
);
let result = reply_testbench.handle_reply(&reply, &active_req, &[]); let result = reply_testbench.handle_reply(&reply, &active_req, &[]);
assert!(result.is_ok()); assert!(result.is_ok());
assert!(result.unwrap()); assert!(result.unwrap());
@ -544,5 +564,23 @@ mod tests {
.unwrap()); .unwrap());
} }
// TODO: Add more tests for reply handler: Request timeout and unrequested reply. #[test]
fn reply_handling_unrequested_reply() {
let mut testbench = ReplyHandlerTestbench::new(HkReplyHandler::default());
let action_reply = HkReply::new(5_u32, HkReplyVariant::Ack);
let unrequested_reply = GenericMessage::new(10_u32, 15_u64, action_reply);
// Right now this function does not do a lot. We simply check that it does not panic or do
// weird stuff.
let result = testbench.handle_unrequested_reply(&unrequested_reply);
assert!(result.is_ok());
}
#[test]
fn reply_handling_reply_timeout() {
let mut testbench = ReplyHandlerTestbench::new(HkReplyHandler::default());
// TODO: Start a request, then time it out with the API and check verification completion
// failure.
// testbench.reply_handler.handle_request_timeout(active_request, verification_handler, time_stamp, tm_sender)
// testbench.default_timeout = Duration::from_millis(50);
}
} }

View File

@ -317,7 +317,7 @@ where
let active_req_opt = self.active_request_map.get(reply.request_id); let active_req_opt = self.active_request_map.get(reply.request_id);
if active_req_opt.is_none() { if active_req_opt.is_none() {
self.reply_handler self.reply_handler
.handle_unexpected_reply(reply, &self.service_helper.common.tm_sender)?; .handle_unrequested_reply(reply, &self.service_helper.common.tm_sender)?;
return Ok(()); return Ok(());
} }
let active_request = active_req_opt.unwrap(); let active_request = active_req_opt.unwrap();
@ -505,6 +505,7 @@ pub(crate) mod tests {
pub verif_reporter: TestVerificationReporter, pub verif_reporter: TestVerificationReporter,
pub reply_handler: ReplyHandler, pub reply_handler: ReplyHandler,
pub tm_receiver: mpsc::Receiver<Vec<u8>>, pub tm_receiver: mpsc::Receiver<Vec<u8>>,
pub default_timeout: Duration,
tm_sender: TmAsVecSenderWithMpsc, tm_sender: TmAsVecSenderWithMpsc,
phantom: std::marker::PhantomData<(ActiveRequestInfo, Reply)>, phantom: std::marker::PhantomData<(ActiveRequestInfo, Reply)>,
} }
@ -523,6 +524,7 @@ pub(crate) mod tests {
shared_verif_map, shared_verif_map,
verif_reporter: test_verif_reporter, verif_reporter: test_verif_reporter,
reply_handler, reply_handler,
default_timeout: Duration::from_secs(30),
tm_sender: TmAsVecSenderWithMpsc::new(0, "TEST_SENDER", tm_sender), tm_sender: TmAsVecSenderWithMpsc::new(0, "TEST_SENDER", tm_sender),
tm_receiver, tm_receiver,
phantom: std::marker::PhantomData, phantom: std::marker::PhantomData,
@ -556,7 +558,7 @@ pub(crate) mod tests {
ActivePusRequestStd::new( ActivePusRequestStd::new(
TargetAndApidId::new(apid, apid_target).raw(), TargetAndApidId::new(apid, apid_target).raw(),
started, started,
Duration::from_secs(30), self.default_timeout,
), ),
) )
} }
@ -575,6 +577,14 @@ pub(crate) mod tests {
&self.tm_sender, &self.tm_sender,
) )
} }
pub fn handle_unrequested_reply(
&mut self,
reply: &GenericMessage<Reply>,
) -> Result<(), ReplyHandler::Error> {
self.reply_handler
.handle_unrequested_reply(reply, &self.tm_sender)
}
} }
// Testbench dedicated to the testing of [PusTcToRequestConverter]s // Testbench dedicated to the testing of [PusTcToRequestConverter]s

View File

@ -31,7 +31,7 @@ pub struct ModeReplyHandler {}
impl PusReplyHandler<ActivePusRequestStd, ModeReply> for ModeReplyHandler { impl PusReplyHandler<ActivePusRequestStd, ModeReply> for ModeReplyHandler {
type Error = EcssTmtcError; type Error = EcssTmtcError;
fn handle_unexpected_reply( fn handle_unrequested_reply(
&mut self, &mut self,
reply: &satrs::request::GenericMessage<ModeReply>, reply: &satrs::request::GenericMessage<ModeReply>,
_tm_sender: &impl EcssTmSenderCore, _tm_sender: &impl EcssTmSenderCore,
@ -199,15 +199,19 @@ impl PusTcToRequestConverter<ActivePusRequestStd, ModeRequest> for ModeRequestCo
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use satrs::{ use satrs::{
mode::{ModeAndSubmode, ModeRequest}, mode::{ModeAndSubmode, ModeReply, ModeRequest},
pus::mode::Subservice, pus::mode::Subservice,
request::GenericMessage,
spacepackets::{ spacepackets::{
ecss::tc::{PusTcCreator, PusTcSecondaryHeader}, ecss::tc::{PusTcCreator, PusTcSecondaryHeader},
SpHeader, SpHeader,
}, },
}; };
use crate::pus::tests::{PusConverterTestbench, TEST_APID, TEST_APID_TARGET_ID}; use crate::pus::{
mode::ModeReplyHandler,
tests::{PusConverterTestbench, ReplyHandlerTestbench, TEST_APID, TEST_APID_TARGET_ID},
};
use super::ModeRequestConverter; use super::ModeRequestConverter;
@ -276,5 +280,23 @@ mod tests {
assert_eq!(req, ModeRequest::AnnounceModeRecursive); assert_eq!(req, ModeRequest::AnnounceModeRecursive);
} }
// TODO: Add reply handler tests. #[test]
fn reply_handling_unrequested_reply() {
let mut testbench = ReplyHandlerTestbench::new(ModeReplyHandler::default());
let mode_reply = ModeReply::ModeInfo(ModeAndSubmode::new(5, 1));
let unrequested_reply = GenericMessage::new(10_u32, 15_u64, mode_reply);
// Right now this function does not do a lot. We simply check that it does not panic or do
// weird stuff.
let result = testbench.handle_unrequested_reply(&unrequested_reply);
assert!(result.is_ok());
}
#[test]
fn reply_handling_reply_timeout() {
let mut testbench = ReplyHandlerTestbench::new(ModeReplyHandler::default());
// TODO: Start a request, then time it out with the API and check verification completion
// failure.
// testbench.reply_handler.handle_request_timeout(active_request, verification_handler, time_stamp, tm_sender)
// testbench.default_timeout = Duration::from_millis(50);
}
} }

View File

@ -22,27 +22,6 @@ pub enum CompositeRequest {
Action(ActionRequest), Action(ActionRequest),
} }
//#[derive(Clone, Debug)]
// pub struct CompositeRequestWithToken {
//pub(crate) targeted_request: GenericMessage<CompositeRequest>,
//}
/*
impl CompositeRequestWithToken {
pub fn new(
target_id: ComponentId,
request_id: RequestId,
request: CompositeRequest,
token: VerificationToken<TcStateStarted>,
) -> Self {
Self {
targeted_request: GenericMessage::new(request_id, target_id, request),
token,
}
}
}
*/
#[derive(Default, Clone)] #[derive(Default, Clone)]
pub struct GenericRequestRouter( pub struct GenericRequestRouter(
pub HashMap<ComponentId, mpsc::Sender<GenericMessage<CompositeRequest>>>, pub HashMap<ComponentId, mpsc::Sender<GenericMessage<CompositeRequest>>>,

View File

@ -1,24 +1,37 @@
use crate::ComponentId; use crate::ComponentId;
pub type CollectionIntervalFactor = u32; pub type CollectionIntervalFactor = u32;
/// Unique Identifier for a certain housekeeping dataset.
pub type UniqueId = u32; pub type UniqueId = u32;
#[derive(Debug, Copy, Clone, PartialEq, Eq)] #[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum HkRequest { pub struct HkRequest {
OneShot(UniqueId), pub unique_id: UniqueId,
Enable(UniqueId), pub variant: HkRequestVariant,
Disable(UniqueId), }
ModifyCollectionInterval(UniqueId, CollectionIntervalFactor),
impl HkRequest {
pub fn new(unique_id: UniqueId, variant: HkRequestVariant) -> Self {
Self { unique_id, variant }
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum HkRequestVariant {
OneShot,
Enable,
Disable,
ModifyCollectionInterval(CollectionIntervalFactor),
} }
#[derive(Debug, Copy, Clone, PartialEq, Eq)] #[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub struct TargetedHkRequest { pub struct TargetedHkRequest {
pub target_id: ComponentId, pub target_id: ComponentId,
pub hk_request: HkRequest, pub hk_request: HkRequestVariant,
} }
impl TargetedHkRequest { impl TargetedHkRequest {
pub fn new(target_id: ComponentId, hk_request: HkRequest) -> Self { pub fn new(target_id: ComponentId, hk_request: HkRequestVariant) -> Self {
Self { Self {
target_id, target_id,
hk_request, hk_request,

View File

@ -25,7 +25,7 @@ pub struct ActionRequestWithId {
/// A reply to an action request, but tailored to the PUS standard verification process. /// A reply to an action request, but tailored to the PUS standard verification process.
#[non_exhaustive] #[non_exhaustive]
#[derive(Clone, PartialEq, Debug)] #[derive(Clone, PartialEq, Debug)]
pub enum ActionReplyPus { pub enum ActionReplyVariant {
Completed, Completed,
StepSuccess { StepSuccess {
step: u16, step: u16,
@ -42,31 +42,27 @@ pub enum ActionReplyPus {
} }
#[derive(Debug, PartialEq, Clone)] #[derive(Debug, PartialEq, Clone)]
pub struct ActionReplyPusWithActionId { pub struct PusActionReply {
pub action_id: ActionId, pub action_id: ActionId,
pub variant: ActionReplyPus, pub variant: ActionReplyVariant,
} }
impl ActionReplyPusWithActionId { impl PusActionReply {
pub fn new(action_id: ActionId, variant: ActionReplyPus) -> Self { pub fn new(action_id: ActionId, variant: ActionReplyVariant) -> Self {
Self { action_id, variant } Self { action_id, variant }
} }
} }
pub type GenericActionReplyPus = GenericMessage<ActionReplyPusWithActionId>; pub type GenericActionReplyPus = GenericMessage<PusActionReply>;
impl GenericActionReplyPus { impl GenericActionReplyPus {
pub fn new_action_reply( pub fn new_action_reply(
request_id: RequestId, request_id: RequestId,
sender_id: ComponentId, sender_id: ComponentId,
action_id: ActionId, action_id: ActionId,
reply: ActionReplyPus, reply: ActionReplyVariant,
) -> Self { ) -> Self {
Self::new( Self::new(request_id, sender_id, PusActionReply::new(action_id, reply))
request_id,
sender_id,
ActionReplyPusWithActionId::new(action_id, reply),
)
} }
} }
@ -82,13 +78,13 @@ pub mod alloc_mod {
ComponentId, ComponentId,
}; };
use super::ActionReplyPusWithActionId; use super::PusActionReply;
/// Helper type definition for a mode handler which can handle mode requests. /// Helper type definition for a mode handler which can handle mode requests.
pub type ActionRequestHandlerInterface<S, R> = pub type ActionRequestHandlerInterface<S, R> =
MessageSenderAndReceiver<ActionReplyPusWithActionId, ActionRequest, S, R>; MessageSenderAndReceiver<PusActionReply, ActionRequest, S, R>;
impl<S: MessageSender<ActionReplyPusWithActionId>, R: MessageReceiver<ActionRequest>> impl<S: MessageSender<PusActionReply>, R: MessageReceiver<ActionRequest>>
ActionRequestHandlerInterface<S, R> ActionRequestHandlerInterface<S, R>
{ {
pub fn try_recv_action_request( pub fn try_recv_action_request(
@ -101,7 +97,7 @@ pub mod alloc_mod {
&self, &self,
request_id: RequestId, request_id: RequestId,
target_id: ComponentId, target_id: ComponentId,
reply: ActionReplyPusWithActionId, reply: PusActionReply,
) -> Result<(), GenericTargetedMessagingError> { ) -> Result<(), GenericTargetedMessagingError> {
self.send_message(request_id, target_id, reply) self.send_message(request_id, target_id, reply)
} }
@ -110,15 +106,14 @@ pub mod alloc_mod {
/// Helper type defintion for a mode handler object which can send mode requests and receive /// Helper type defintion for a mode handler object which can send mode requests and receive
/// mode replies. /// mode replies.
pub type ActionRequestorInterface<S, R> = pub type ActionRequestorInterface<S, R> =
MessageSenderAndReceiver<ActionRequest, ActionReplyPusWithActionId, S, R>; MessageSenderAndReceiver<ActionRequest, PusActionReply, S, R>;
impl<S: MessageSender<ActionRequest>, R: MessageReceiver<ActionReplyPusWithActionId>> impl<S: MessageSender<ActionRequest>, R: MessageReceiver<PusActionReply>>
ActionRequestorInterface<S, R> ActionRequestorInterface<S, R>
{ {
pub fn try_recv_action_reply( pub fn try_recv_action_reply(
&self, &self,
) -> Result<Option<GenericMessage<ActionReplyPusWithActionId>>, GenericTargetedMessagingError> ) -> Result<Option<GenericMessage<PusActionReply>>, GenericTargetedMessagingError> {
{
self.try_recv_message() self.try_recv_message()
} }
@ -186,21 +181,21 @@ pub mod std_mod {
pub type DefaultActiveActionRequestMap = DefaultActiveRequestMap<ActivePusActionRequestStd>; pub type DefaultActiveActionRequestMap = DefaultActiveRequestMap<ActivePusActionRequestStd>;
pub type ActionRequestHandlerMpsc = ActionRequestHandlerInterface< pub type ActionRequestHandlerMpsc = ActionRequestHandlerInterface<
mpsc::Sender<GenericMessage<ActionReplyPusWithActionId>>, mpsc::Sender<GenericMessage<PusActionReply>>,
mpsc::Receiver<GenericMessage<ActionRequest>>, mpsc::Receiver<GenericMessage<ActionRequest>>,
>; >;
pub type ActionRequestHandlerMpscBounded = ActionRequestHandlerInterface< pub type ActionRequestHandlerMpscBounded = ActionRequestHandlerInterface<
mpsc::SyncSender<GenericMessage<ActionReplyPusWithActionId>>, mpsc::SyncSender<GenericMessage<PusActionReply>>,
mpsc::Receiver<GenericMessage<ActionRequest>>, mpsc::Receiver<GenericMessage<ActionRequest>>,
>; >;
pub type ActionRequestorMpsc = ActionRequestorInterface< pub type ActionRequestorMpsc = ActionRequestorInterface<
mpsc::Sender<GenericMessage<ActionRequest>>, mpsc::Sender<GenericMessage<ActionRequest>>,
mpsc::Receiver<GenericMessage<ActionReplyPusWithActionId>>, mpsc::Receiver<GenericMessage<PusActionReply>>,
>; >;
pub type ActionRequestorBoundedMpsc = ActionRequestorInterface< pub type ActionRequestorBoundedMpsc = ActionRequestorInterface<
mpsc::SyncSender<GenericMessage<ActionRequest>>, mpsc::SyncSender<GenericMessage<ActionRequest>>,
mpsc::Receiver<GenericMessage<ActionReplyPusWithActionId>>, mpsc::Receiver<GenericMessage<PusActionReply>>,
>; >;
/* /*

View File

@ -322,7 +322,7 @@ pub trait PusReplyHandler<ActiveRequestInfo: ActiveRequestProvider, ReplyType> {
tm_sender: &impl EcssTmSenderCore, tm_sender: &impl EcssTmSenderCore,
) -> Result<bool, Self::Error>; ) -> Result<bool, Self::Error>;
fn handle_unexpected_reply( fn handle_unrequested_reply(
&mut self, &mut self,
reply: &GenericMessage<ReplyType>, reply: &GenericMessage<ReplyType>,
tm_sender: &impl EcssTmSenderCore, tm_sender: &impl EcssTmSenderCore,