diff --git a/satrs-example/src/acs/mgm.rs b/satrs-example/src/acs/mgm.rs index 1b0f3b5..b102225 100644 --- a/satrs-example/src/acs/mgm.rs +++ b/satrs-example/src/acs/mgm.rs @@ -532,7 +532,7 @@ mod tests { hk_reply_rx, handler: MgmHandlerLis3Mdl::new( UniqueApidTargetId::new(Apid::Acs as u16, 1), - "test-mgm", + "TEST_MGM", mode_interface, composite_request_rx, hk_reply_tx, diff --git a/satrs-example/src/eps/pcdu.rs b/satrs-example/src/eps/pcdu.rs index d51ca55..875b398 100644 --- a/satrs-example/src/eps/pcdu.rs +++ b/satrs-example/src/eps/pcdu.rs @@ -130,15 +130,13 @@ impl SerialInterface for SerialInterfaceDummy { &self, mut f: ReplyHandler, ) -> Result<(), Self::Error> { - if self.reply_deque.borrow().is_empty() { + if self.reply_queue_empty() { return Ok(()); } loop { - let mut reply_deque_mut = self.reply_deque.borrow_mut(); - let next_reply = reply_deque_mut.pop_front().unwrap(); - let reply = serde_json::to_string(&next_reply).unwrap(); + let reply = self.get_next_reply_as_string(); f(reply.as_bytes()); - if reply_deque_mut.is_empty() { + if self.reply_queue_empty() { break; } } @@ -146,6 +144,18 @@ impl SerialInterface for SerialInterfaceDummy { } } +impl SerialInterfaceDummy { + fn get_next_reply_as_string(&self) -> String { + let mut reply_deque_mut = self.reply_deque.borrow_mut(); + let next_reply = reply_deque_mut.pop_front().unwrap(); + serde_json::to_string(&next_reply).unwrap() + } + + fn reply_queue_empty(&self) -> bool { + self.reply_deque.borrow().is_empty() + } +} + pub enum SerialSimInterfaceWrapper { Dummy(SerialInterfaceDummy), Sim(SerialInterfaceToSim), @@ -465,3 +475,127 @@ impl ModeRequestHandler Ok(()) } } + +#[cfg(test)] +mod tests { + use std::sync::mpsc; + + use satrs::{mode::ModeRequest, request::GenericMessage, tmtc::PacketAsVec}; + use satrs_example::config::components::Apid; + + use super::*; + + #[derive(Default)] + pub struct SerialInterfaceTest { + pub inner: SerialInterfaceDummy, + pub send_queue: RefCell>>, + pub reply_queue: RefCell>, + } + + impl SerialInterface for SerialInterfaceTest { + type Error = (); + + fn send(&self, data: &[u8]) -> Result<(), Self::Error> { + let mut send_queue_mut = self.send_queue.borrow_mut(); + send_queue_mut.push_back(data.to_vec()); + self.inner.send(data) + } + + fn try_recv_replies( + &self, + mut f: ReplyHandler, + ) -> Result<(), Self::Error> { + if self.inner.reply_queue_empty() { + return Ok(()); + } + loop { + let reply = self.inner.get_next_reply_as_string(); + self.reply_queue.borrow_mut().push_back(reply.clone()); + f(reply.as_bytes()); + if self.inner.reply_queue_empty() { + break; + } + } + Ok(()) + } + } + + pub struct PcduTestbench { + pub mode_request_tx: mpsc::Sender>, + pub mode_reply_rx_to_pus: mpsc::Receiver>, + pub mode_reply_rx_to_parent: mpsc::Receiver>, + pub composite_request_tx: mpsc::Sender>, + pub hk_reply_rx: mpsc::Receiver>, + pub tm_rx: mpsc::Receiver, + pub switch_request_tx: mpsc::Sender>, + pub handler: PcduHandler>, + } + + impl PcduTestbench { + pub fn new() -> Self { + let (mode_request_tx, mode_request_rx) = mpsc::channel(); + let (mode_reply_tx_to_pus, mode_reply_rx_to_pus) = mpsc::channel(); + let (mode_reply_tx_to_parent, mode_reply_rx_to_parent) = mpsc::sync_channel(5); + let mode_interface = MpscModeLeafInterface { + request_rx: mode_request_rx, + reply_to_pus_tx: mode_reply_tx_to_pus, + reply_to_parent_tx: mode_reply_tx_to_parent, + }; + let (composite_request_tx, composite_request_rx) = mpsc::channel(); + let (hk_reply_tx, hk_reply_rx) = mpsc::channel(); + let (tm_tx, tm_rx) = mpsc::channel::(); + let (switch_request_tx, switch_reqest_rx) = mpsc::channel(); + let shared_switch_map = Arc::new(Mutex::new(SwitchSet::default())); + Self { + mode_request_tx, + mode_reply_rx_to_pus, + mode_reply_rx_to_parent, + composite_request_tx, + hk_reply_rx, + tm_rx, + switch_request_tx, + handler: PcduHandler::new( + UniqueApidTargetId::new(Apid::Eps as u16, 0), + "TEST_PCDU", + mode_interface, + composite_request_rx, + hk_reply_tx, + switch_reqest_rx, + tm_tx, + SerialInterfaceTest::default(), + shared_switch_map, + ), + } + } + } + + #[test] + fn test_basic_handler() { + let mut testbench = PcduTestbench::new(); + assert_eq!(testbench.handler.com_interface.send_queue.borrow().len(), 0); + assert_eq!( + testbench.handler.com_interface.reply_queue.borrow().len(), + 0 + ); + assert_eq!( + testbench.handler.mode_and_submode().mode(), + DeviceMode::Off as u32 + ); + assert_eq!(testbench.handler.mode_and_submode().submode(), 0_u16); + testbench.handler.periodic_operation(OpCode::RegularOp); + testbench + .handler + .periodic_operation(OpCode::PollAndRecvReplies); + // Handler is OFF, no changes expected. + assert_eq!(testbench.handler.com_interface.send_queue.borrow().len(), 0); + assert_eq!( + testbench.handler.com_interface.reply_queue.borrow().len(), + 0 + ); + assert_eq!( + testbench.handler.mode_and_submode().mode(), + DeviceMode::Off as u32 + ); + assert_eq!(testbench.handler.mode_and_submode().submode(), 0_u16); + } +}