From 74f65243e4f587734eab14ff605fecdbb968a4fd Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 1 Nov 2022 19:24:09 +0100 Subject: [PATCH] basic test framework done --- fsrc-core/src/event_man.rs | 55 ++++++++++++++--- fsrc-core/src/pus/event_man.rs | 38 ++++++------ fsrc-core/tests/pus_events.rs | 107 ++++++++++++++++++++++++++------- 3 files changed, 150 insertions(+), 50 deletions(-) diff --git a/fsrc-core/src/event_man.rs b/fsrc-core/src/event_man.rs index 98fe9a8..fb43184 100644 --- a/fsrc-core/src/event_man.rs +++ b/fsrc-core/src/event_man.rs @@ -35,7 +35,7 @@ use alloc::vec::Vec; use hashbrown::HashMap; #[cfg(feature = "std")] -pub use stdmod::MpscEventReceiver; +pub use stdmod::*; #[derive(PartialEq, Eq, Hash, Copy, Clone)] enum ListenerType { @@ -96,6 +96,14 @@ pub struct EventManager>, } +/// Safety: It is safe to implement [Send] because all fields in the [EventManager] are [Send] +/// as well +#[cfg(feature = "std")] +unsafe impl Send + for EventManager +{ +} + pub enum HandlerResult { Empty, Handled(u32, Provider, Option), @@ -128,8 +136,11 @@ impl EventManager { /// /// For example, this can be useful for a handler component which sends every event as /// a telemetry packet. - pub fn subscribe_all(&mut self, dest: impl SendEventProvider + 'static) { - self.update_listeners(ListenerType::All, dest); + pub fn subscribe_all( + &mut self, + send_provider: impl SendEventProvider + 'static, + ) { + self.update_listeners(ListenerType::All, send_provider); } /// Helper function which removes single subscriptions for which a group subscription already @@ -226,23 +237,24 @@ impl #[cfg(feature = "std")] pub mod stdmod { + use super::*; use crate::event_man::{EventReceiver, EventWithAuxData}; use crate::events::{EventU16, EventU32, GenericEvent}; use crate::util::Params; - use std::sync::mpsc::Receiver; + use std::sync::mpsc::{Receiver, SendError, Sender}; - pub struct MpscEventReceiver { + pub struct MpscEventReceiver { mpsc_receiver: Receiver<(Event, Option)>, } - impl MpscEventReceiver { + impl MpscEventReceiver { pub fn new(receiver: Receiver<(Event, Option)>) -> Self { Self { mpsc_receiver: receiver, } } } - impl EventReceiver for MpscEventReceiver { + impl EventReceiver for MpscEventReceiver { fn receive(&mut self) -> Option> { if let Ok(event_and_data) = self.mpsc_receiver.try_recv() { return Some(event_and_data); @@ -253,6 +265,35 @@ pub mod stdmod { pub type MpscEventU32Receiver = MpscEventReceiver; pub type MpscEventU16Receiver = MpscEventReceiver; + + #[derive(Clone)] + pub struct MpscEventSendProvider { + id: u32, + sender: Sender<(Event, Option)>, + } + + /// Safety: Send is safe to implement because both the ID and the MPSC sender are Send + //unsafe impl Send for MpscEventSendProvider {} + + impl MpscEventSendProvider { + pub fn new(id: u32, sender: Sender<(Event, Option)>) -> Self { + Self { id, sender } + } + } + + impl SendEventProvider for MpscEventSendProvider { + type Error = SendError<(Event, Option)>; + + fn id(&self) -> u32 { + self.id + } + fn send(&mut self, event: Event, aux_data: Option) -> Result<(), Self::Error> { + self.sender.send((event, aux_data)) + } + } + + pub type MpscEventU32SendProvider = MpscEventSendProvider; + pub type MpscEventU16SendProvider = MpscEventSendProvider; } #[cfg(test)] diff --git a/fsrc-core/src/pus/event_man.rs b/fsrc-core/src/pus/event_man.rs index 11075d9..feef852 100644 --- a/fsrc-core/src/pus/event_man.rs +++ b/fsrc-core/src/pus/event_man.rs @@ -38,6 +38,9 @@ pub struct DefaultPusMgmtBackendProvider { disabled: HashSet, } +/// Safety: All contained field are [Send] as well +unsafe impl Send for DefaultPusMgmtBackendProvider {} + impl Default for DefaultPusMgmtBackendProvider { fn default() -> Self { Self { @@ -73,13 +76,19 @@ pub mod heapless_mod { // TODO: After a new version of heapless is released which uses hash32 version 0.3, try using // regular Event type again. #[derive(Default)] - pub struct HeaplessPusMgmtBckendProvider { + pub struct HeaplessPusMgmtBackendProvider { disabled: heapless::FnvIndexSet, phantom: PhantomData, } + /// Safety: All contained field are [Send] as well + unsafe impl Send + for HeaplessPusMgmtBackendProvider + { + } + impl PusEventMgmtBackendProvider - for HeaplessPusMgmtBckendProvider + for HeaplessPusMgmtBackendProvider { type Error = (); @@ -116,6 +125,9 @@ pub struct PusEventTmManager { backend: Box>, } +/// Safety: All contained fields are send as well. +unsafe impl Send for PusEventTmManager {} + impl PusEventTmManager { pub fn new( reporter: EventReporter, @@ -136,7 +148,6 @@ impl PusEventTmManager { pub fn generate_pus_event_tm_generic( &mut self, - severity: Severity, sender: &mut (impl EcssTmSender + ?Sized), time_stamp: &[u8], event: Event, @@ -145,10 +156,7 @@ impl PusEventTmManager { if !self.backend.event_enabled(&event) { return Ok(false); } - if event.severity() != severity { - return Err(EventManError::SeverityMissmatch(severity, event.severity())); - } - match severity { + match event.severity() { Severity::INFO => self .reporter .event_info(sender, time_stamp, event, aux_data) @@ -195,13 +203,7 @@ impl PusEventTmManager { event: EventU32TypedSev, aux_data: Option<&[u8]>, ) -> Result> { - self.generate_pus_event_tm_generic( - Severity::SEVERITY, - sender, - time_stamp, - event.into(), - aux_data, - ) + self.generate_pus_event_tm_generic(sender, time_stamp, event.into(), aux_data) } } @@ -261,13 +263,7 @@ mod tests { assert!(res.is_ok()); assert!(res.unwrap()); let mut event_sent = event_man - .generate_pus_event_tm_generic( - Severity::LOW, - &mut sender, - &EMPTY_STAMP, - LOW_SEV_EVENT, - None, - ) + .generate_pus_event_tm_generic(&mut sender, &EMPTY_STAMP, LOW_SEV_EVENT, None) .expect("Sending low severity event failed"); assert!(!event_sent); let res = event_rx.try_recv(); diff --git a/fsrc-core/tests/pus_events.rs b/fsrc-core/tests/pus_events.rs index 0534e96..058b0f6 100644 --- a/fsrc-core/tests/pus_events.rs +++ b/fsrc-core/tests/pus_events.rs @@ -1,8 +1,11 @@ +use fsrc_core::event_man::{EventManager, MpscEventReceiver, MpscEventU32SendProvider}; use fsrc_core::events::{EventU32, EventU32TypedSev, Severity, SeverityInfo}; use fsrc_core::pus::event_man::{DefaultPusMgmtBackendProvider, EventReporter, PusEventTmManager}; use fsrc_core::pus::{EcssTmError, EcssTmSender}; +use fsrc_core::util::Params; use spacepackets::tm::PusTm; use std::sync::mpsc::{channel, SendError, TryRecvError}; +use std::thread; const INFO_EVENT: EventU32TypedSev = EventU32TypedSev::::const_new(1, 0); @@ -24,27 +27,87 @@ impl EcssTmSender for EventTmSender { } #[test] -fn test_basic() { - let reporter = EventReporter::new(0x02, 128).expect("Creating event repoter failed"); - let backend = DefaultPusMgmtBackendProvider::::default(); - let mut event_man = PusEventTmManager::new(reporter, Box::new(backend)); - let (event_tx, event_rx) = channel(); - let mut sender = EventTmSender { sender: event_tx }; - let mut event_sent = event_man - .generate_pus_event_tm(&mut sender, &EMPTY_STAMP, INFO_EVENT, None) - .expect("Sending info event failed"); +fn test_threaded_usage() { + let (event_sender, event_man_receiver) = channel(); + let event_receiver = MpscEventReceiver::new(event_man_receiver); + let mut event_man = EventManager::new(Box::new(event_receiver)); - assert!(event_sent); - // Will not check packet here, correctness of packet was tested somewhere else - event_rx.recv().expect("Receiving event TM failed"); - let res = event_man.disable_tm_for_event_with_sev(&INFO_EVENT); - assert!(res.is_ok()); - assert!(res.unwrap()); - event_sent = event_man - .generate_pus_event_tm(&mut sender, &EMPTY_STAMP, INFO_EVENT, None) - .expect("Sending info event failed"); - assert!(!event_sent); - let res = event_rx.try_recv(); - assert!(res.is_err()); - assert!(matches!(res.unwrap_err(), TryRecvError::Empty)); + let (pus_event_man_tx, pus_event_man_rx) = channel(); + let pus_event_man_send_provider = MpscEventU32SendProvider::new(1, pus_event_man_tx); + event_man.subscribe_all(pus_event_man_send_provider); + let (event_tx, event_rx) = channel(); + let reporter = EventReporter::new(0x02, 128).expect("Creating event reporter failed"); + let backend = DefaultPusMgmtBackendProvider::::default(); + let mut pus_event_man = PusEventTmManager::new(reporter, Box::new(backend)); + // PUS + Generic event manager thread + let jh0 = thread::spawn(move || { + let mut sender = EventTmSender { sender: event_tx }; + loop { + let res = event_man.try_event_handling(); + assert!(res.is_ok()); + match pus_event_man_rx.try_recv() { + Ok((event, aux_data)) => { + // TODO: Convert auxiliary data into raw byte format + if let Some(aux_data) = aux_data { + match aux_data { + Params::Heapless(_) => {} + Params::Vec(_) => {} + Params::String(_) => {} + } + } + let res = pus_event_man.generate_pus_event_tm_generic( + &mut sender, + &EMPTY_STAMP, + event, + None, + ); + assert!(res.is_ok()); + assert!(res.unwrap()); + break; + } + Err(e) => { + if let TryRecvError::Disconnected = e { + panic!("Event receiver disconnected!") + } + } + } + } + }); + + // Event sender and TM checker thread + let jh1 = thread::spawn(move || { + event_sender + .send((INFO_EVENT.into(), None)) + .expect("Sending info event failed"); + loop { + match event_rx.try_recv() { + // Event TM received successfully + Ok(_) => break, + Err(e) => { + if let TryRecvError::Disconnected = e { + panic!("Event sender disconnected!") + } + } + } + } + event_sender + .send(( + LOW_SEV_EVENT.into(), + Some(Params::Heapless((2_u32, 3_u32).into())), + )) + .expect("Sending low severity event failed"); + loop { + match event_rx.try_recv() { + // Event TM received successfully + Ok(_) => break, + Err(e) => { + if let TryRecvError::Disconnected = e { + panic!("Event sender disconnected!") + } + } + } + } + }); + jh0.join().expect("Joining manager thread failed"); + jh1.join().expect("Joining creator thread failed"); }