From 5d7e64bdea52c1487e32efbbc335d0c7d5b979d5 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 7 Feb 2024 17:10:42 +0100 Subject: [PATCH] add first unittest for UDP server --- satrs-example/src/udp.rs | 109 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) diff --git a/satrs-example/src/udp.rs b/satrs-example/src/udp.rs index 023f8cf..11f84b2 100644 --- a/satrs-example/src/udp.rs +++ b/satrs-example/src/udp.rs @@ -111,3 +111,112 @@ impl } } } + +#[cfg(test)] +mod tests { + use std::{ + collections::VecDeque, + net::IpAddr, + sync::{Arc, Mutex}, + }; + + use satrs_core::{ + spacepackets::{ + ecss::{tc::PusTcCreator, WritablePusPacket}, + SpHeader, + }, + tmtc::ReceivesTcCore, + }; + use satrs_example::config::{OBSW_SERVER_ADDR, PUS_APID}; + + use super::*; + + #[derive(Default, Debug, Clone)] + pub struct TestReceiver { + tc_vec: Arc>>>, + } + + impl ReceivesTcCore for TestReceiver { + type Error = CcsdsError<()>; + fn pass_tc(&mut self, tc_raw: &[u8]) -> Result<(), Self::Error> { + self.tc_vec.lock().unwrap().push_back(tc_raw.to_vec()); + Ok(()) + } + } + + #[derive(Default, Debug, Clone)] + pub struct TestTmHandler { + addrs_to_send_to: Arc>>, + } + + impl UdpTmHandler for TestTmHandler { + fn send_tm_to_udp_client(&mut self, _socket: &UdpSocket, recv_addr: &SocketAddr) { + self.addrs_to_send_to.lock().unwrap().push_back(*recv_addr); + } + } + + #[test] + fn test_basic() { + let sock_addr = SocketAddr::new(IpAddr::V4(OBSW_SERVER_ADDR), 0); + let test_receiver = TestReceiver::default(); + let tc_queue = test_receiver.tc_vec.clone(); + let udp_tc_server = UdpTcServer::new(sock_addr, 2048, Box::new(test_receiver)).unwrap(); + let tm_handler = TestTmHandler::default(); + let tm_handler_calls = tm_handler.addrs_to_send_to.clone(); + let mut udp_dyn_server = UdpTmtcServer { + udp_tc_server, + tm_handler, + }; + udp_dyn_server.periodic_operation(); + assert!(tc_queue.lock().unwrap().is_empty()); + assert!(tm_handler_calls.lock().unwrap().is_empty()); + } + + #[test] + fn test_transactions() { + let sock_addr = SocketAddr::new(IpAddr::V4(OBSW_SERVER_ADDR), 0); + let test_receiver = TestReceiver::default(); + let tc_queue = test_receiver.tc_vec.clone(); + let udp_tc_server = UdpTcServer::new(sock_addr, 2048, Box::new(test_receiver)).unwrap(); + let server_addr = udp_tc_server.socket.local_addr().unwrap(); + let tm_handler = TestTmHandler::default(); + let tm_handler_calls = tm_handler.addrs_to_send_to.clone(); + let mut udp_dyn_server = UdpTmtcServer { + udp_tc_server, + tm_handler, + }; + let mut sph = SpHeader::tc_unseg(PUS_APID, 0, 0).unwrap(); + let ping_tc = PusTcCreator::new_simple(&mut sph, 17, 1, None, true) + .to_vec() + .unwrap(); + let client = UdpSocket::bind("127.0.0.1:0").expect("Connecting to UDP server failed"); + let client_addr = client.local_addr().unwrap(); + client.connect(server_addr).unwrap(); + client.send(&ping_tc).unwrap(); + udp_dyn_server.periodic_operation(); + { + let mut tc_queue = tc_queue.lock().unwrap(); + assert!(!tc_queue.is_empty()); + let received_tc = tc_queue.pop_front().unwrap(); + assert_eq!(received_tc, ping_tc); + } + + { + let mut tm_handler_calls = tm_handler_calls.lock().unwrap(); + assert!(!tm_handler_calls.is_empty()); + assert_eq!(tm_handler_calls.len(), 1); + let received_addr = tm_handler_calls.pop_front().unwrap(); + assert_eq!(received_addr, client_addr); + } + udp_dyn_server.periodic_operation(); + assert!(tc_queue.lock().unwrap().is_empty()); + // Still tries to send to the same client. + { + let mut tm_handler_calls = tm_handler_calls.lock().unwrap(); + assert!(!tm_handler_calls.is_empty()); + assert_eq!(tm_handler_calls.len(), 1); + let received_addr = tm_handler_calls.pop_front().unwrap(); + assert_eq!(received_addr, client_addr); + } + } +}