From 5a202bc11974c17edfce72acde2b0c3b116cc8fb Mon Sep 17 00:00:00 2001 From: Peter Taylor Date: Mon, 29 Jun 2020 17:08:21 -0600 Subject: [PATCH] test(Timer): Stabilize tests Switch from using system clock for delays to manually advancing clock ticks using multiple threads --- src/timer.rs | 105 +++++++++++++++++++++++++++------------------------ 1 file changed, 55 insertions(+), 50 deletions(-) diff --git a/src/timer.rs b/src/timer.rs index 5a90d36..ab19d89 100644 --- a/src/timer.rs +++ b/src/timer.rs @@ -223,93 +223,85 @@ impl Timer = None; + static TICKS: AtomicI64 = AtomicI64::new(0); impl crate::Clock for Clock { type Rep = i64; - const PERIOD: Period = Period::new(1, 64_000_000); + const PERIOD: Period = Period::new(1, 1_000); fn now() -> Instant { - let since_start = unsafe { START.unwrap() }.elapsed(); - let ticks = Nanoseconds::::try_from(since_start) - .unwrap() - .into_ticks(Self::PERIOD) - .unwrap(); - Instant::new(ticks) - } - } - - fn init_start_time() { - unsafe { - START = Some(std::time::Instant::now()); + Instant::new(TICKS.load(Ordering::Acquire)) } } #[test] fn oneshot_wait() { - init_start_time(); + init_ticks(); - // WHEN blocking on a timer - let timer = Clock::new_timer().set_duration(1.seconds()).start().wait(); + let timer = Clock::new_timer().set_duration(1.seconds()).start(); + let timer_handle = thread::spawn(move || timer.wait()); - // THEN the block occurs for _at least_ the given duration - unsafe { - assert!(Seconds::::try_from(START.unwrap().elapsed()).unwrap() >= 1.seconds()); - } + add_to_ticks(1.seconds()); - // WHEN blocking on a timer - timer.start().wait(); + let result = timer_handle.join(); - // THEN the block occurs for _at least_ the given duration - unsafe { - assert!(Seconds::::try_from(START.unwrap().elapsed()).unwrap() >= 2.seconds()); - } + assert!(result.is_ok()); + + let timer = result.unwrap().start(); + let timer_handle = thread::spawn(move || timer.wait()); + + add_to_ticks(1.seconds()); + + assert!(timer_handle.join().is_ok()); } #[test] fn periodic_wait() { - init_start_time(); + init_ticks(); let timer = Clock::new_timer() .into_periodic() .set_duration(1.seconds()) - .start() - .wait(); + .start(); + let timer_handle = thread::spawn(move || timer.wait()); - unsafe { - assert!(Seconds::::try_from(START.unwrap().elapsed()).unwrap() == 1.seconds()); - } + add_to_ticks(1.seconds()); - let timer = timer.wait(); - unsafe { - assert!(Seconds::::try_from(START.unwrap().elapsed()).unwrap() == 2.seconds()); - } + let result = timer_handle.join(); - timer.wait(); - unsafe { - assert!(Seconds::::try_from(START.unwrap().elapsed()).unwrap() == 3.seconds()); - } + assert!(result.is_ok()); + + let timer = result.unwrap(); + + // WHEN blocking on a timer + let timer_handle = thread::spawn(move || timer.wait()); + + add_to_ticks(1.seconds()); + + assert!(timer_handle.join().is_ok()); } #[test] fn periodic_expiration() { - init_start_time(); + init_ticks(); let mut timer = Clock::new_timer() .into_periodic() .set_duration(1.seconds()) .start(); - std::thread::sleep(std::time::Duration::from_secs(2)); + add_to_ticks(2.seconds()); assert!(timer.period_complete()); assert!(timer.period_complete()); @@ -317,24 +309,26 @@ mod test { #[test] fn read_timer() { - init_start_time(); + init_ticks(); let timer = Clock::new_timer().set_duration(2.seconds()).start(); + add_to_ticks(1.milliseconds()); + assert_eq!(timer.elapsed(), 0.seconds()); assert_eq!(timer.remaining(), 1.seconds()); - std::thread::sleep(std::time::Duration::from_secs(1)); + add_to_ticks(1.seconds()); assert_eq!(timer.elapsed(), 1.seconds()); assert_eq!(timer.remaining(), 0.seconds()); - std::thread::sleep(std::time::Duration::from_secs(1)); + add_to_ticks(1.seconds()); assert_eq!(timer.elapsed(), 2.seconds()); assert_eq!(timer.remaining(), (0).seconds()); - std::thread::sleep(std::time::Duration::from_secs(1)); + add_to_ticks(1.seconds()); assert_eq!(timer.elapsed(), 3.seconds()); assert_eq!(timer.remaining(), (-1).seconds()); @@ -342,7 +336,7 @@ mod test { #[test] fn expiration_task() { - init_start_time(); + init_ticks(); let mut x = 1; @@ -353,4 +347,15 @@ mod test { assert_eq!(x, 2); } + + fn init_ticks() {} + + fn add_to_ticks(duration: Dur) { + let ticks = TICKS.load(Ordering::Acquire); + let ticks = ticks + + duration + .into_ticks::<::Rep>(Clock::PERIOD) + .unwrap(); + TICKS.store(ticks, Ordering::Release); + } }