From 82f44ed0cc93938319c654779f78b8c73e2e491f Mon Sep 17 00:00:00 2001 From: lkoester Date: Tue, 24 Jan 2023 14:44:28 +0100 Subject: [PATCH 1/2] fixed tc insertion, added unit tests for releasing single tcs as well as inserting and releasing multiple tcs with same timestamp --- satrs-core/src/pus/scheduling.rs | 184 +++++++++++++++++++++++++++++-- 1 file changed, 176 insertions(+), 8 deletions(-) diff --git a/satrs-core/src/pus/scheduling.rs b/satrs-core/src/pus/scheduling.rs index d996600..b7deeeb 100644 --- a/satrs-core/src/pus/scheduling.rs +++ b/satrs-core/src/pus/scheduling.rs @@ -6,6 +6,7 @@ use std::collections::BTreeMap; use std::time::SystemTimeError; use std::vec; use std::vec::Vec; +use std::sync::{mpsc, Arc, RwLock}; #[derive(Debug)] pub struct PusScheduler { @@ -59,7 +60,7 @@ impl PusScheduler { } pub fn insert_tc(&mut self, time_stamp: UnixTimestamp, addr: StoreAddr) -> bool { - if time_stamp > self.current_time + self.time_margin { + if time_stamp < self.current_time + self.time_margin { return false; } match self.tc_map.entry(time_stamp) { @@ -97,10 +98,15 @@ impl PusScheduler { #[cfg(test)] mod tests { + use std::{println, vec}; + use std::sync::mpsc; + use std::sync::mpsc::{channel, Receiver, TryRecvError}; use crate::pool::StoreAddr; use crate::pus::scheduling::PusScheduler; use spacepackets::time::UnixTimestamp; use std::time::Duration; + use spacepackets::ecss::PacketTypeCodes::UnsignedInt; + use std::vec::Vec; #[test] fn basic() { @@ -115,20 +121,65 @@ mod tests { fn reset() { let mut scheduler = PusScheduler::new(UnixTimestamp::new_only_seconds(0), Duration::from_secs(5)); - scheduler.insert_tc( - UnixTimestamp::new_only_seconds(200), + + let worked = scheduler.insert_tc( + UnixTimestamp::new_only_seconds(100), StoreAddr { pool_idx: 0, packet_idx: 1, }, ); - scheduler.insert_tc( + + assert!(worked); + + let worked = scheduler.insert_tc( UnixTimestamp::new_only_seconds(200), StoreAddr { pool_idx: 0, packet_idx: 2, }, ); + + assert!(worked); + + let worked = scheduler.insert_tc( + UnixTimestamp::new_only_seconds(300), + StoreAddr { + pool_idx: 0, + packet_idx: 2, + }, + ); + + assert!(worked); + + assert_eq!(scheduler.num_scheduled_telecommands(), 3); + assert!(scheduler.is_enabled()); + scheduler.reset(); + assert!(!scheduler.is_enabled()); + assert_eq!(scheduler.num_scheduled_telecommands(), 0); + } + + #[test] + fn insert_multi_with_same_time() { + let mut scheduler = + PusScheduler::new(UnixTimestamp::new_only_seconds(0), Duration::from_secs(5)); + + scheduler.insert_tc( + UnixTimestamp::new_only_seconds(100), + StoreAddr { + pool_idx: 0, + packet_idx: 1, + }, + ); + + let worked = scheduler.insert_tc( + UnixTimestamp::new_only_seconds(100), + StoreAddr { + pool_idx: 0, + packet_idx: 2, + }, + ); + scheduler.insert_tc( UnixTimestamp::new_only_seconds(300), StoreAddr { @@ -136,10 +187,127 @@ mod tests { packet_idx: 2, }, ); + assert_eq!(scheduler.num_scheduled_telecommands(), 3); - assert!(scheduler.is_enabled()); - scheduler.reset(); - assert!(!scheduler.is_enabled()); - assert_eq!(scheduler.num_scheduled_telecommands(), 0); + } + + + #[test] + fn time() { + let mut scheduler = + PusScheduler::new(UnixTimestamp::new_only_seconds(0), Duration::from_secs(5)); + let time = UnixTimestamp::new(1,2).unwrap(); + scheduler.update_time(time); + assert_eq!(scheduler.current_time(), &time); + } + + #[test] + fn release_basic() { + let mut scheduler = + PusScheduler::new(UnixTimestamp::new_only_seconds(0), Duration::from_secs(5)); + + scheduler.insert_tc( + UnixTimestamp::new_only_seconds(100), + StoreAddr { + pool_idx: 0, + packet_idx: 1, + }, + ); + + scheduler.insert_tc( + UnixTimestamp::new_only_seconds(200), + StoreAddr { + pool_idx: 0, + packet_idx: 2, + }, + ); + + let mut i = 0; + let mut test_closure_1 = |boolvar: bool, store_addr: &StoreAddr| { + assert_eq!(boolvar, true); + assert_eq!(store_addr, &StoreAddr { + pool_idx: 0, + packet_idx: 1, + }); + i += 1; + }; + + // test 1: too early, no tcs + scheduler.update_time(UnixTimestamp::new_only_seconds(99)); + + scheduler.release_telecommands( &mut test_closure_1); + + // test 2: exact time stamp of tc, releases 1 tc + scheduler.update_time(UnixTimestamp::new_only_seconds(100)); + + scheduler.release_telecommands(&mut test_closure_1); + + // test 3, late timestamp, release 1 overdue tc + let mut test_closure_2 = |boolvar: bool, store_addr: &StoreAddr| { + assert_eq!(boolvar, true); + assert_eq!(store_addr, &StoreAddr { + pool_idx: 0, + packet_idx: 2, + }); + i += 1; + }; + + scheduler.update_time(UnixTimestamp::new_only_seconds(206)); + + scheduler.release_telecommands(&mut test_closure_2); + + //test 4: no tcs left + scheduler.release_telecommands(&mut test_closure_2); + + // check that 2 total tcs have been released + assert_eq!(i, 2); + } + + #[test] + fn release_multi_with_same_time() { + let mut scheduler = + PusScheduler::new(UnixTimestamp::new_only_seconds(0), Duration::from_secs(5)); + + scheduler.insert_tc( + UnixTimestamp::new_only_seconds(100), + StoreAddr { + pool_idx: 0, + packet_idx: 1, + }, + ); + + scheduler.insert_tc( + UnixTimestamp::new_only_seconds(100), + StoreAddr { + pool_idx: 0, + packet_idx: 1, + }, + ); + + let mut i = 0; + let mut test_closure = |boolvar: bool, store_addr: &StoreAddr| { + assert_eq!(boolvar, true); + assert_eq!(store_addr, &StoreAddr { + pool_idx: 0, + packet_idx: 1, + }); + i += 1; + }; + + // test 1: too early, no tcs + scheduler.update_time(UnixTimestamp::new_only_seconds(99)); + + scheduler.release_telecommands( &mut test_closure); + + // test 2: exact time stamp of tc, releases 2 tc + scheduler.update_time(UnixTimestamp::new_only_seconds(100)); + + scheduler.release_telecommands(&mut test_closure); + + //test 3: no tcs left + scheduler.release_telecommands(&mut test_closure); + + // check that 2 total tcs have been released + assert_eq!(i, 2); } } -- 2.43.0 From 299135a4c48aa61b01cd6fcaab8e472bce084be8 Mon Sep 17 00:00:00 2001 From: lkoester Date: Tue, 24 Jan 2023 18:57:19 +0100 Subject: [PATCH 2/2] ran clippy and fmt, added insert checks to insert_multi test --- satrs-core/src/pus/scheduling.rs | 67 +++++++++++++++++++------------- 1 file changed, 40 insertions(+), 27 deletions(-) diff --git a/satrs-core/src/pus/scheduling.rs b/satrs-core/src/pus/scheduling.rs index b7deeeb..3205a59 100644 --- a/satrs-core/src/pus/scheduling.rs +++ b/satrs-core/src/pus/scheduling.rs @@ -6,7 +6,6 @@ use std::collections::BTreeMap; use std::time::SystemTimeError; use std::vec; use std::vec::Vec; -use std::sync::{mpsc, Arc, RwLock}; #[derive(Debug)] pub struct PusScheduler { @@ -66,10 +65,10 @@ impl PusScheduler { match self.tc_map.entry(time_stamp) { Entry::Vacant(e) => { e.insert(vec![addr]); - }, + } Entry::Occupied(mut v) => { v.get_mut().push(addr); - }, + } } true } @@ -98,15 +97,15 @@ impl PusScheduler { #[cfg(test)] mod tests { - use std::{println, vec}; - use std::sync::mpsc; - use std::sync::mpsc::{channel, Receiver, TryRecvError}; use crate::pool::StoreAddr; use crate::pus::scheduling::PusScheduler; - use spacepackets::time::UnixTimestamp; - use std::time::Duration; use spacepackets::ecss::PacketTypeCodes::UnsignedInt; + use spacepackets::time::UnixTimestamp; + use std::sync::mpsc; + use std::sync::mpsc::{channel, Receiver, TryRecvError}; + use std::time::Duration; use std::vec::Vec; + use std::{println, vec}; #[test] fn basic() { @@ -142,7 +141,7 @@ mod tests { assert!(worked); - let worked = scheduler.insert_tc( + let worked = scheduler.insert_tc( UnixTimestamp::new_only_seconds(300), StoreAddr { pool_idx: 0, @@ -164,7 +163,7 @@ mod tests { let mut scheduler = PusScheduler::new(UnixTimestamp::new_only_seconds(0), Duration::from_secs(5)); - scheduler.insert_tc( + let worked = scheduler.insert_tc( UnixTimestamp::new_only_seconds(100), StoreAddr { pool_idx: 0, @@ -172,6 +171,8 @@ mod tests { }, ); + assert!(worked); + let worked = scheduler.insert_tc( UnixTimestamp::new_only_seconds(100), StoreAddr { @@ -180,7 +181,9 @@ mod tests { }, ); - scheduler.insert_tc( + assert!(worked); + + let worked = scheduler.insert_tc( UnixTimestamp::new_only_seconds(300), StoreAddr { pool_idx: 0, @@ -188,15 +191,16 @@ mod tests { }, ); + assert!(worked); + assert_eq!(scheduler.num_scheduled_telecommands(), 3); } - #[test] fn time() { let mut scheduler = PusScheduler::new(UnixTimestamp::new_only_seconds(0), Duration::from_secs(5)); - let time = UnixTimestamp::new(1,2).unwrap(); + let time = UnixTimestamp::new(1, 2).unwrap(); scheduler.update_time(time); assert_eq!(scheduler.current_time(), &time); } @@ -225,17 +229,20 @@ mod tests { let mut i = 0; let mut test_closure_1 = |boolvar: bool, store_addr: &StoreAddr| { assert_eq!(boolvar, true); - assert_eq!(store_addr, &StoreAddr { - pool_idx: 0, - packet_idx: 1, - }); + assert_eq!( + store_addr, + &StoreAddr { + pool_idx: 0, + packet_idx: 1, + } + ); i += 1; }; // test 1: too early, no tcs scheduler.update_time(UnixTimestamp::new_only_seconds(99)); - scheduler.release_telecommands( &mut test_closure_1); + scheduler.release_telecommands(&mut test_closure_1); // test 2: exact time stamp of tc, releases 1 tc scheduler.update_time(UnixTimestamp::new_only_seconds(100)); @@ -245,10 +252,13 @@ mod tests { // test 3, late timestamp, release 1 overdue tc let mut test_closure_2 = |boolvar: bool, store_addr: &StoreAddr| { assert_eq!(boolvar, true); - assert_eq!(store_addr, &StoreAddr { - pool_idx: 0, - packet_idx: 2, - }); + assert_eq!( + store_addr, + &StoreAddr { + pool_idx: 0, + packet_idx: 2, + } + ); i += 1; }; @@ -287,17 +297,20 @@ mod tests { let mut i = 0; let mut test_closure = |boolvar: bool, store_addr: &StoreAddr| { assert_eq!(boolvar, true); - assert_eq!(store_addr, &StoreAddr { - pool_idx: 0, - packet_idx: 1, - }); + assert_eq!( + store_addr, + &StoreAddr { + pool_idx: 0, + packet_idx: 1, + } + ); i += 1; }; // test 1: too early, no tcs scheduler.update_time(UnixTimestamp::new_only_seconds(99)); - scheduler.release_telecommands( &mut test_closure); + scheduler.release_telecommands(&mut test_closure); // test 2: exact time stamp of tc, releases 2 tc scheduler.update_time(UnixTimestamp::new_only_seconds(100)); -- 2.43.0