diff --git a/satrs/src/mode_tree.rs b/satrs/src/mode_tree.rs index 1fb4c6f..1c1bfa6 100644 --- a/satrs/src/mode_tree.rs +++ b/satrs/src/mode_tree.rs @@ -366,292 +366,4 @@ pub trait ModeRequestHandler: ModeProvider { #[cfg(test)] mod tests { - use std::{println, sync::mpsc}; - - use alloc::string::{String, ToString}; - - use super::*; - use crate::{ - mode::{ModeAndSubmode, ModeReply, ModeRequest}, - mode_tree::ModeRequestSender, - ChannelId, - }; - - pub enum TestChannelId { - Device1 = 1, - Device2 = 2, - Assembly = 3, - PusModeService = 4, - } - - struct PusModeService { - pub mode_node: MpscBoundedModeRequestorConnector, - } - - impl PusModeService { - pub fn send_announce_mode_cmd_to_assy(&self) { - self.mode_node - .send_mode_request( - TestChannelId::Assembly as u32, - ModeRequest::AnnounceModeRecursive, - ) - .unwrap(); - } - } - - struct TestDevice { - pub name: String, - pub mode_node: MpscBoundedModeRequestHandlerConnector, - pub mode_and_submode: ModeAndSubmode, - pub mode_req_commander: Option, - } - - impl TestDevice { - pub fn run(&mut self) { - self.check_mode_requests().expect("mode messaging error"); - } - - pub fn check_mode_requests(&mut self) -> Result<(), GenericTargetedMessagingError> { - if let Some(request_and_id) = self.mode_node.try_recv_mode_request()? { - match request_and_id.message { - ModeRequest::SetMode(mode_and_submode) => { - self.start_transition(mode_and_submode).unwrap(); - self.mode_req_commander = Some(request_and_id.sender_id); - } - ModeRequest::ReadMode => self - .mode_node - .send_mode_reply( - request_and_id.sender_id, - ModeReply::ModeReply(self.mode_and_submode), - ) - .unwrap(), - ModeRequest::AnnounceMode => self.announce_mode(false), - ModeRequest::AnnounceModeRecursive => self.announce_mode(true), - } - } - Ok(()) - } - } - - impl ModeProvider for TestDevice { - fn mode_and_submode(&self) -> ModeAndSubmode { - self.mode_and_submode - } - } - impl ModeRequestHandler for TestDevice { - fn start_transition(&mut self, mode_and_submode: ModeAndSubmode) -> Result<(), ModeError> { - self.mode_and_submode = mode_and_submode; - self.handle_mode_reached()?; - Ok(()) - } - - fn announce_mode(&self, _recursive: bool) { - println!( - "{}: announcing mode: {:?}", - self.name, self.mode_and_submode - ); - } - - fn handle_mode_reached(&mut self) -> Result<(), GenericTargetedMessagingError> { - self.mode_node.send_mode_reply( - self.mode_req_commander.unwrap(), - ModeReply::ModeReply(self.mode_and_submode), - )?; - Ok(()) - } - } - - struct TestAssembly { - pub mode_node: MpscBoundedModeConnector, - pub mode_req_commander: Option, - pub mode_and_submode: ModeAndSubmode, - pub target_mode_and_submode: Option, - } - - impl ModeProvider for TestAssembly { - fn mode_and_submode(&self) -> ModeAndSubmode { - self.mode_and_submode - } - } - - impl TestAssembly { - pub fn run(&mut self) { - self.check_mode_requests().expect("mode messaging error"); - self.check_mode_replies().expect("mode messaging error"); - } - - pub fn check_mode_requests(&mut self) -> Result<(), GenericTargetedMessagingError> { - if let Some(request_and_id) = self.mode_node.try_recv_mode_request()? { - match request_and_id.message { - ModeRequest::SetMode(mode_and_submode) => { - self.start_transition(mode_and_submode).unwrap(); - self.mode_req_commander = Some(request_and_id.sender_id); - } - ModeRequest::ReadMode => { - // self.handle_read_mode_request(0, self.mode_and_submode, &mut self.mode_reply_sender).unwrap() - self.mode_node - .send_mode_reply( - request_and_id.sender_id, - ModeReply::ModeReply(self.mode_and_submode), - ) - .unwrap() - } - ModeRequest::AnnounceMode => self.announce_mode(false), - ModeRequest::AnnounceModeRecursive => self.announce_mode(true), - } - } - Ok(()) - } - pub fn check_mode_replies(&mut self) -> Result<(), GenericTargetedMessagingError> { - if let Some(reply_and_id) = self.mode_node.try_recv_mode_reply()? { - match reply_and_id.message { - ModeReply::ModeInfo(_) => todo!(), - ModeReply::ModeReply(reply) => { - println!( - "TestAssembly: Received mode reply from {:?}, reached: {:?}", - reply_and_id.sender_id, reply - ); - } - ModeReply::CantReachMode(_) => todo!(), - ModeReply::WrongMode { expected, reached } => { - println!( - "TestAssembly: Wrong mode reply from {:?}, reached {:?}, expected {:?}", - reply_and_id.sender_id, reached, expected - ); - } - } - } - Ok(()) - } - } - - impl ModeRequestHandler for TestAssembly { - fn start_transition( - &mut self, - mode_and_submode: ModeAndSubmode, - ) -> Result<(), super::ModeError> { - self.target_mode_and_submode = Some(mode_and_submode); - Ok(()) - } - - fn announce_mode(&self, recursive: bool) { - println!( - "TestAssembly: Announcing mode (recursively: {}): {:?}", - recursive, self.mode_and_submode - ); - let mut mode_request = ModeRequest::AnnounceMode; - if recursive { - mode_request = ModeRequest::AnnounceModeRecursive; - } - self.mode_node - .request_sender_map - .0 - .iter() - .for_each(|(_, sender)| { - sender - .send(MessageWithSenderId::new( - self.mode_node.local_channel_id_generic(), - mode_request, - )) - .expect("sending mode request failed"); - }); - } - - fn handle_mode_reached(&mut self) -> Result<(), GenericTargetedMessagingError> { - self.mode_node.send_mode_reply( - self.mode_req_commander.unwrap(), - ModeReply::ModeReply(self.mode_and_submode), - )?; - Ok(()) - } - } - - #[test] - fn basic_test() { - // All request channel handles. - let (request_sender_to_dev1, request_receiver_dev1) = mpsc::sync_channel(10); - let (request_sender_to_dev2, request_receiver_dev2) = mpsc::sync_channel(10); - let (request_sender_to_assy, request_receiver_assy) = mpsc::sync_channel(10); - - // All reply channel handles. - let (reply_sender_to_assy, reply_receiver_assy) = mpsc::sync_channel(10); - let (reply_sender_to_pus, reply_receiver_pus) = mpsc::sync_channel(10); - - // Mode requestors and handlers. - let mut mode_node_assy = MpscBoundedModeConnector::new( - TestChannelId::Assembly as u32, - request_receiver_assy, - reply_receiver_assy, - ); - // Mode requestors only. - let mut mode_node_pus = MpscBoundedModeRequestorConnector::new( - TestChannelId::PusModeService as u32, - reply_receiver_pus, - ); - - // Request handlers only. - let mut mode_node_dev1 = MpscBoundedModeRequestHandlerConnector::new( - TestChannelId::Device1 as u32, - request_receiver_dev1, - ); - let mut mode_node_dev2 = MpscBoundedModeRequestHandlerConnector::new( - TestChannelId::Device2 as u32, - request_receiver_dev2, - ); - - // Set up mode request senders first. - mode_node_pus.add_message_target(TestChannelId::Assembly as u32, request_sender_to_assy); - mode_node_pus.add_message_target( - TestChannelId::Device1 as u32, - request_sender_to_dev1.clone(), - ); - mode_node_pus.add_message_target( - TestChannelId::Device2 as u32, - request_sender_to_dev2.clone(), - ); - mode_node_assy.add_request_target(TestChannelId::Device1 as u32, request_sender_to_dev1); - mode_node_assy.add_request_target(TestChannelId::Device2 as u32, request_sender_to_dev2); - - // Set up mode reply senders. - mode_node_dev1 - .add_message_target(TestChannelId::Assembly as u32, reply_sender_to_assy.clone()); - mode_node_dev1.add_message_target( - TestChannelId::PusModeService as u32, - reply_sender_to_pus.clone(), - ); - mode_node_dev2.add_message_target(TestChannelId::Assembly as u32, reply_sender_to_assy); - mode_node_dev2.add_message_target( - TestChannelId::PusModeService as u32, - reply_sender_to_pus.clone(), - ); - mode_node_assy.add_reply_target(TestChannelId::PusModeService as u32, reply_sender_to_pus); - - let mut device1 = TestDevice { - name: "Test Device 1".to_string(), - mode_node: mode_node_dev1, - mode_req_commander: None, - mode_and_submode: ModeAndSubmode::new(0, 0), - }; - let mut device2 = TestDevice { - name: "Test Device 2".to_string(), - mode_node: mode_node_dev2, - mode_req_commander: None, - mode_and_submode: ModeAndSubmode::new(0, 0), - }; - let mut assy = TestAssembly { - mode_node: mode_node_assy, - mode_req_commander: None, - mode_and_submode: ModeAndSubmode::new(0, 0), - target_mode_and_submode: None, - }; - let pus_service = PusModeService { - mode_node: mode_node_pus, - }; - - pus_service.send_announce_mode_cmd_to_assy(); - assy.run(); - device1.run(); - device2.run(); - assy.run(); - } } diff --git a/satrs/tests/mode_tree.rs b/satrs/tests/mode_tree.rs new file mode 100644 index 0000000..d0c986f --- /dev/null +++ b/satrs/tests/mode_tree.rs @@ -0,0 +1,288 @@ +use std::{println, sync::mpsc}; + +use satrs::mode_tree::ModeRequestSender; +use satrs::{ + mode::{ModeAndSubmode, ModeReply, ModeRequest}, + mode_tree::{ + ModeError, ModeProvider, ModeReplyReceiver, ModeReplySender, ModeRequestHandler, + ModeRequestReceiver, MpscBoundedModeConnector, MpscBoundedModeRequestHandlerConnector, + MpscBoundedModeRequestorConnector, + }, + queue::GenericTargetedMessagingError, + request::MessageWithSenderId, + ChannelId, +}; +use std::string::{String, ToString}; + +pub enum TestChannelId { + Device1 = 1, + Device2 = 2, + Assembly = 3, + PusModeService = 4, +} + +struct PusModeService { + pub mode_node: MpscBoundedModeRequestorConnector, +} + +impl PusModeService { + pub fn send_announce_mode_cmd_to_assy(&self) { + self.mode_node + .send_mode_request( + TestChannelId::Assembly as u32, + ModeRequest::AnnounceModeRecursive, + ) + .unwrap(); + } +} + +struct TestDevice { + pub name: String, + pub mode_node: MpscBoundedModeRequestHandlerConnector, + pub mode_and_submode: ModeAndSubmode, + pub mode_req_commander: Option, +} + +impl TestDevice { + pub fn run(&mut self) { + self.check_mode_requests().expect("mode messaging error"); + } + + pub fn check_mode_requests(&mut self) -> Result<(), GenericTargetedMessagingError> { + if let Some(request_and_id) = self.mode_node.try_recv_mode_request()? { + match request_and_id.message { + ModeRequest::SetMode(mode_and_submode) => { + self.start_transition(mode_and_submode).unwrap(); + self.mode_req_commander = Some(request_and_id.sender_id); + } + ModeRequest::ReadMode => self + .mode_node + .send_mode_reply( + request_and_id.sender_id, + ModeReply::ModeReply(self.mode_and_submode), + ) + .unwrap(), + ModeRequest::AnnounceMode => self.announce_mode(false), + ModeRequest::AnnounceModeRecursive => self.announce_mode(true), + } + } + Ok(()) + } +} + +impl ModeProvider for TestDevice { + fn mode_and_submode(&self) -> ModeAndSubmode { + self.mode_and_submode + } +} +impl ModeRequestHandler for TestDevice { + fn start_transition(&mut self, mode_and_submode: ModeAndSubmode) -> Result<(), ModeError> { + self.mode_and_submode = mode_and_submode; + self.handle_mode_reached()?; + Ok(()) + } + + fn announce_mode(&self, _recursive: bool) { + println!( + "{}: announcing mode: {:?}", + self.name, self.mode_and_submode + ); + } + + fn handle_mode_reached(&mut self) -> Result<(), GenericTargetedMessagingError> { + self.mode_node.send_mode_reply( + self.mode_req_commander.unwrap(), + ModeReply::ModeReply(self.mode_and_submode), + )?; + Ok(()) + } +} + +struct TestAssembly { + pub mode_node: MpscBoundedModeConnector, + pub mode_req_commander: Option, + pub mode_and_submode: ModeAndSubmode, + pub target_mode_and_submode: Option, +} + +impl ModeProvider for TestAssembly { + fn mode_and_submode(&self) -> ModeAndSubmode { + self.mode_and_submode + } +} + +impl TestAssembly { + pub fn run(&mut self) { + self.check_mode_requests().expect("mode messaging error"); + self.check_mode_replies().expect("mode messaging error"); + } + + pub fn check_mode_requests(&mut self) -> Result<(), GenericTargetedMessagingError> { + if let Some(request_and_id) = self.mode_node.try_recv_mode_request()? { + match request_and_id.message { + ModeRequest::SetMode(mode_and_submode) => { + self.start_transition(mode_and_submode).unwrap(); + self.mode_req_commander = Some(request_and_id.sender_id); + } + ModeRequest::ReadMode => { + // self.handle_read_mode_request(0, self.mode_and_submode, &mut self.mode_reply_sender).unwrap() + self.mode_node + .send_mode_reply( + request_and_id.sender_id, + ModeReply::ModeReply(self.mode_and_submode), + ) + .unwrap() + } + ModeRequest::AnnounceMode => self.announce_mode(false), + ModeRequest::AnnounceModeRecursive => self.announce_mode(true), + } + } + Ok(()) + } + pub fn check_mode_replies(&mut self) -> Result<(), GenericTargetedMessagingError> { + if let Some(reply_and_id) = self.mode_node.try_recv_mode_reply()? { + match reply_and_id.message { + ModeReply::ModeInfo(_) => todo!(), + ModeReply::ModeReply(reply) => { + println!( + "TestAssembly: Received mode reply from {:?}, reached: {:?}", + reply_and_id.sender_id, reply + ); + } + ModeReply::CantReachMode(_) => todo!(), + ModeReply::WrongMode { expected, reached } => { + println!( + "TestAssembly: Wrong mode reply from {:?}, reached {:?}, expected {:?}", + reply_and_id.sender_id, reached, expected + ); + } + } + } + Ok(()) + } +} + +impl ModeRequestHandler for TestAssembly { + fn start_transition(&mut self, mode_and_submode: ModeAndSubmode) -> Result<(), ModeError> { + self.target_mode_and_submode = Some(mode_and_submode); + Ok(()) + } + + fn announce_mode(&self, recursive: bool) { + println!( + "TestAssembly: Announcing mode (recursively: {}): {:?}", + recursive, self.mode_and_submode + ); + let mut mode_request = ModeRequest::AnnounceMode; + if recursive { + mode_request = ModeRequest::AnnounceModeRecursive; + } + self.mode_node + .request_sender_map + .0 + .iter() + .for_each(|(_, sender)| { + sender + .send(MessageWithSenderId::new( + self.mode_node.local_channel_id_generic(), + mode_request, + )) + .expect("sending mode request failed"); + }); + } + + fn handle_mode_reached(&mut self) -> Result<(), GenericTargetedMessagingError> { + self.mode_node.send_mode_reply( + self.mode_req_commander.unwrap(), + ModeReply::ModeReply(self.mode_and_submode), + )?; + Ok(()) + } +} + +fn main() { + // All request channel handles. + let (request_sender_to_dev1, request_receiver_dev1) = mpsc::sync_channel(10); + let (request_sender_to_dev2, request_receiver_dev2) = mpsc::sync_channel(10); + let (request_sender_to_assy, request_receiver_assy) = mpsc::sync_channel(10); + + // All reply channel handles. + let (reply_sender_to_assy, reply_receiver_assy) = mpsc::sync_channel(10); + let (reply_sender_to_pus, reply_receiver_pus) = mpsc::sync_channel(10); + + // Mode requestors and handlers. + let mut mode_node_assy = MpscBoundedModeConnector::new( + TestChannelId::Assembly as u32, + request_receiver_assy, + reply_receiver_assy, + ); + // Mode requestors only. + let mut mode_node_pus = MpscBoundedModeRequestorConnector::new( + TestChannelId::PusModeService as u32, + reply_receiver_pus, + ); + + // Request handlers only. + let mut mode_node_dev1 = MpscBoundedModeRequestHandlerConnector::new( + TestChannelId::Device1 as u32, + request_receiver_dev1, + ); + let mut mode_node_dev2 = MpscBoundedModeRequestHandlerConnector::new( + TestChannelId::Device2 as u32, + request_receiver_dev2, + ); + + // Set up mode request senders first. + mode_node_pus.add_message_target(TestChannelId::Assembly as u32, request_sender_to_assy); + mode_node_pus.add_message_target( + TestChannelId::Device1 as u32, + request_sender_to_dev1.clone(), + ); + mode_node_pus.add_message_target( + TestChannelId::Device2 as u32, + request_sender_to_dev2.clone(), + ); + mode_node_assy.add_request_target(TestChannelId::Device1 as u32, request_sender_to_dev1); + mode_node_assy.add_request_target(TestChannelId::Device2 as u32, request_sender_to_dev2); + + // Set up mode reply senders. + mode_node_dev1.add_message_target(TestChannelId::Assembly as u32, reply_sender_to_assy.clone()); + mode_node_dev1.add_message_target( + TestChannelId::PusModeService as u32, + reply_sender_to_pus.clone(), + ); + mode_node_dev2.add_message_target(TestChannelId::Assembly as u32, reply_sender_to_assy); + mode_node_dev2.add_message_target( + TestChannelId::PusModeService as u32, + reply_sender_to_pus.clone(), + ); + mode_node_assy.add_reply_target(TestChannelId::PusModeService as u32, reply_sender_to_pus); + + let mut device1 = TestDevice { + name: "Test Device 1".to_string(), + mode_node: mode_node_dev1, + mode_req_commander: None, + mode_and_submode: ModeAndSubmode::new(0, 0), + }; + let mut device2 = TestDevice { + name: "Test Device 2".to_string(), + mode_node: mode_node_dev2, + mode_req_commander: None, + mode_and_submode: ModeAndSubmode::new(0, 0), + }; + let mut assy = TestAssembly { + mode_node: mode_node_assy, + mode_req_commander: None, + mode_and_submode: ModeAndSubmode::new(0, 0), + target_mode_and_submode: None, + }; + let pus_service = PusModeService { + mode_node: mode_node_pus, + }; + + pus_service.send_announce_mode_cmd_to_assy(); + assy.run(); + device1.run(); + device2.run(); + assy.run(); +}