diff --git a/satrs-core/src/pus/scheduling.rs b/satrs-core/src/pus/scheduling.rs index d996600..3205a59 100644 --- a/satrs-core/src/pus/scheduling.rs +++ b/satrs-core/src/pus/scheduling.rs @@ -59,16 +59,16 @@ 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) { Entry::Vacant(e) => { e.insert(vec![addr]); - }, + } Entry::Occupied(mut v) => { v.get_mut().push(addr); - }, + } } true } @@ -99,8 +99,13 @@ impl PusScheduler { mod tests { use crate::pool::StoreAddr; use crate::pus::scheduling::PusScheduler; + 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() { @@ -115,31 +120,207 @@ 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, }, ); - scheduler.insert_tc( + + 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)); + + let worked = scheduler.insert_tc( + UnixTimestamp::new_only_seconds(100), + StoreAddr { + pool_idx: 0, + packet_idx: 1, + }, + ); + + assert!(worked); + + let worked = scheduler.insert_tc( + UnixTimestamp::new_only_seconds(100), + 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); + } + + #[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); + } }