diff options
Diffstat (limited to 'third_party/rust/tokio-timer/tests/delay.rs')
-rw-r--r-- | third_party/rust/tokio-timer/tests/delay.rs | 499 |
1 files changed, 499 insertions, 0 deletions
diff --git a/third_party/rust/tokio-timer/tests/delay.rs b/third_party/rust/tokio-timer/tests/delay.rs new file mode 100644 index 0000000000..d21106c630 --- /dev/null +++ b/third_party/rust/tokio-timer/tests/delay.rs @@ -0,0 +1,499 @@ +extern crate futures; +extern crate tokio_executor; +extern crate tokio_timer; + +#[macro_use] +mod support; +use support::*; + +use tokio_timer::timer::Handle; +use tokio_timer::*; + +use futures::Future; + +use std::time::{Duration, Instant}; + +#[test] +fn immediate_delay() { + mocked(|timer, time| { + // Create `Delay` that elapsed immediately. + let mut delay = Delay::new(time.now()); + + // Ready! + assert_ready!(delay); + + // Turn the timer, it runs for the elapsed time + turn(timer, ms(1000)); + + // The time has not advanced. The `turn` completed immediately. + assert_eq!(time.advanced(), ms(1000)); + }); +} + +#[test] +fn delayed_delay_level_0() { + for &i in &[1, 10, 60] { + mocked(|timer, time| { + // Create a `Delay` that elapses in the future + let mut delay = Delay::new(time.now() + ms(i)); + + // The delay has not elapsed. + assert_not_ready!(delay); + + turn(timer, ms(1000)); + assert_eq!(time.advanced(), ms(i)); + + assert_ready!(delay); + }); + } +} + +#[test] +fn sub_ms_delayed_delay() { + mocked(|timer, time| { + for _ in 0..5 { + let deadline = time.now() + Duration::from_millis(1) + Duration::new(0, 1); + + let mut delay = Delay::new(deadline); + + assert_not_ready!(delay); + + turn(timer, None); + assert_ready!(delay); + + assert!(time.now() >= deadline); + + time.advance(Duration::new(0, 1)); + } + }); +} + +#[test] +fn delayed_delay_wrapping_level_0() { + mocked(|timer, time| { + turn(timer, ms(5)); + assert_eq!(time.advanced(), ms(5)); + + let mut delay = Delay::new(time.now() + ms(60)); + + assert_not_ready!(delay); + + turn(timer, None); + assert_eq!(time.advanced(), ms(64)); + assert_not_ready!(delay); + + turn(timer, None); + assert_eq!(time.advanced(), ms(65)); + + assert_ready!(delay); + }); +} + +#[test] +fn timer_wrapping_with_higher_levels() { + mocked(|timer, time| { + // Set delay to hit level 1 + let mut s1 = Delay::new(time.now() + ms(64)); + assert_not_ready!(s1); + + // Turn a bit + turn(timer, ms(5)); + + // Set timeout such that it will hit level 0, but wrap + let mut s2 = Delay::new(time.now() + ms(60)); + assert_not_ready!(s2); + + // This should result in s1 firing + turn(timer, None); + assert_eq!(time.advanced(), ms(64)); + + assert_ready!(s1); + assert_not_ready!(s2); + + turn(timer, None); + assert_eq!(time.advanced(), ms(65)); + + assert_ready!(s2); + }); +} + +#[test] +fn delay_with_deadline_in_past() { + mocked(|timer, time| { + // Create `Delay` that elapsed immediately. + let mut delay = Delay::new(time.now() - ms(100)); + + // Even though the delay expires in the past, it is not ready yet + // because the timer must observe it. + assert_ready!(delay); + + // Turn the timer, it runs for the elapsed time + turn(timer, ms(1000)); + + // The time has not advanced. The `turn` completed immediately. + assert_eq!(time.advanced(), ms(1000)); + }); +} + +#[test] +fn delayed_delay_level_1() { + mocked(|timer, time| { + // Create a `Delay` that elapses in the future + let mut delay = Delay::new(time.now() + ms(234)); + + // The delay has not elapsed. + assert_not_ready!(delay); + + // Turn the timer, this will wake up to cascade the timer down. + turn(timer, ms(1000)); + assert_eq!(time.advanced(), ms(192)); + + // The delay has not elapsed. + assert_not_ready!(delay); + + // Turn the timer again + turn(timer, ms(1000)); + assert_eq!(time.advanced(), ms(234)); + + // The delay has elapsed. + assert_ready!(delay); + }); + + mocked(|timer, time| { + // Create a `Delay` that elapses in the future + let mut delay = Delay::new(time.now() + ms(234)); + + // The delay has not elapsed. + assert_not_ready!(delay); + + // Turn the timer with a smaller timeout than the cascade. + turn(timer, ms(100)); + assert_eq!(time.advanced(), ms(100)); + + assert_not_ready!(delay); + + // Turn the timer, this will wake up to cascade the timer down. + turn(timer, ms(1000)); + assert_eq!(time.advanced(), ms(192)); + + // The delay has not elapsed. + assert_not_ready!(delay); + + // Turn the timer again + turn(timer, ms(1000)); + assert_eq!(time.advanced(), ms(234)); + + // The delay has elapsed. + assert_ready!(delay); + }); +} + +#[test] +fn creating_delay_outside_of_context() { + let now = Instant::now(); + + // This creates a delay outside of the context of a mock timer. This tests + // that it will still expire. + let mut delay = Delay::new(now + ms(500)); + + mocked_with_now(now, |timer, time| { + // This registers the delay with the timer + assert_not_ready!(delay); + + // Wait some time... the timer is cascading + turn(timer, ms(1000)); + assert_eq!(time.advanced(), ms(448)); + + assert_not_ready!(delay); + + turn(timer, ms(1000)); + assert_eq!(time.advanced(), ms(500)); + + // The delay has elapsed + assert_ready!(delay); + }); +} + +#[test] +fn concurrently_set_two_timers_second_one_shorter() { + mocked(|timer, time| { + let mut delay1 = Delay::new(time.now() + ms(500)); + let mut delay2 = Delay::new(time.now() + ms(200)); + + // The delay has not elapsed + assert_not_ready!(delay1); + assert_not_ready!(delay2); + + // Delay until a cascade + turn(timer, None); + assert_eq!(time.advanced(), ms(192)); + + // Delay until the second timer. + turn(timer, None); + assert_eq!(time.advanced(), ms(200)); + + // The shorter delay fires + assert_ready!(delay2); + assert_not_ready!(delay1); + + turn(timer, None); + assert_eq!(time.advanced(), ms(448)); + + assert_not_ready!(delay1); + + // Turn again, this time the time will advance to the second delay + turn(timer, None); + assert_eq!(time.advanced(), ms(500)); + + assert_ready!(delay1); + }) +} + +#[test] +fn short_delay() { + mocked(|timer, time| { + // Create a `Delay` that elapses in the future + let mut delay = Delay::new(time.now() + ms(1)); + + // The delay has not elapsed. + assert_not_ready!(delay); + + // Turn the timer, but not enough time will go by. + turn(timer, None); + + // The delay has elapsed. + assert_ready!(delay); + + // The time has advanced to the point of the delay elapsing. + assert_eq!(time.advanced(), ms(1)); + }) +} + +#[test] +fn sorta_long_delay() { + const MIN_5: u64 = 5 * 60 * 1000; + + mocked(|timer, time| { + // Create a `Delay` that elapses in the future + let mut delay = Delay::new(time.now() + ms(MIN_5)); + + // The delay has not elapsed. + assert_not_ready!(delay); + + let cascades = &[262_144, 262_144 + 9 * 4096, 262_144 + 9 * 4096 + 15 * 64]; + + for &elapsed in cascades { + turn(timer, None); + assert_eq!(time.advanced(), ms(elapsed)); + + assert_not_ready!(delay); + } + + turn(timer, None); + assert_eq!(time.advanced(), ms(MIN_5)); + + // The delay has elapsed. + assert_ready!(delay); + }) +} + +#[test] +fn very_long_delay() { + const MO_5: u64 = 5 * 30 * 24 * 60 * 60 * 1000; + + mocked(|timer, time| { + // Create a `Delay` that elapses in the future + let mut delay = Delay::new(time.now() + ms(MO_5)); + + // The delay has not elapsed. + assert_not_ready!(delay); + + let cascades = &[ + 12_884_901_888, + 12_952_010_752, + 12_959_875_072, + 12_959_997_952, + ]; + + for &elapsed in cascades { + turn(timer, None); + assert_eq!(time.advanced(), ms(elapsed)); + + assert_not_ready!(delay); + } + + // Turn the timer, but not enough time will go by. + turn(timer, None); + + // The time has advanced to the point of the delay elapsing. + assert_eq!(time.advanced(), ms(MO_5)); + + // The delay has elapsed. + assert_ready!(delay); + }) +} + +#[test] +fn greater_than_max() { + const YR_5: u64 = 5 * 365 * 24 * 60 * 60 * 1000; + + mocked(|timer, time| { + // Create a `Delay` that elapses in the future + let mut delay = Delay::new(time.now() + ms(YR_5)); + + assert_not_ready!(delay); + + turn(timer, ms(0)); + + assert!(delay.poll().is_err()); + }) +} + +#[test] +fn unpark_is_delayed() { + mocked(|timer, time| { + let mut delay1 = Delay::new(time.now() + ms(100)); + let mut delay2 = Delay::new(time.now() + ms(101)); + let mut delay3 = Delay::new(time.now() + ms(200)); + + assert_not_ready!(delay1); + assert_not_ready!(delay2); + assert_not_ready!(delay3); + + time.park_for(ms(500)); + + turn(timer, None); + + assert_eq!(time.advanced(), ms(500)); + + assert_ready!(delay1); + assert_ready!(delay2); + assert_ready!(delay3); + }) +} + +#[test] +fn set_timeout_at_deadline_greater_than_max_timer() { + const YR_1: u64 = 365 * 24 * 60 * 60 * 1000; + const YR_5: u64 = 5 * YR_1; + + mocked(|timer, time| { + for _ in 0..5 { + turn(timer, ms(YR_1)); + } + + let mut delay = Delay::new(time.now() + ms(1)); + assert_not_ready!(delay); + + turn(timer, ms(1000)); + assert_eq!(time.advanced(), Duration::from_millis(YR_5) + ms(1)); + + assert_ready!(delay); + }); +} + +#[test] +fn reset_future_delay_before_fire() { + mocked(|timer, time| { + let mut delay = Delay::new(time.now() + ms(100)); + + assert_not_ready!(delay); + + delay.reset(time.now() + ms(200)); + + turn(timer, None); + assert_eq!(time.advanced(), ms(192)); + + assert_not_ready!(delay); + + turn(timer, None); + assert_eq!(time.advanced(), ms(200)); + + assert_ready!(delay); + }); +} + +#[test] +fn reset_past_delay_before_turn() { + mocked(|timer, time| { + let mut delay = Delay::new(time.now() + ms(100)); + + assert_not_ready!(delay); + + delay.reset(time.now() + ms(80)); + + turn(timer, None); + assert_eq!(time.advanced(), ms(64)); + + assert_not_ready!(delay); + + turn(timer, None); + assert_eq!(time.advanced(), ms(80)); + + assert_ready!(delay); + }); +} + +#[test] +fn reset_past_delay_before_fire() { + mocked(|timer, time| { + let mut delay = Delay::new(time.now() + ms(100)); + + assert_not_ready!(delay); + turn(timer, ms(10)); + + assert_not_ready!(delay); + delay.reset(time.now() + ms(80)); + + turn(timer, None); + assert_eq!(time.advanced(), ms(64)); + + assert_not_ready!(delay); + + turn(timer, None); + assert_eq!(time.advanced(), ms(90)); + + assert_ready!(delay); + }); +} + +#[test] +fn reset_future_delay_after_fire() { + mocked(|timer, time| { + let mut delay = Delay::new(time.now() + ms(100)); + + assert_not_ready!(delay); + + turn(timer, ms(1000)); + assert_eq!(time.advanced(), ms(64)); + + turn(timer, None); + assert_eq!(time.advanced(), ms(100)); + + assert_ready!(delay); + + delay.reset(time.now() + ms(10)); + assert_not_ready!(delay); + + turn(timer, ms(1000)); + assert_eq!(time.advanced(), ms(110)); + + assert_ready!(delay); + }); +} + +#[test] +fn delay_with_default_handle() { + let handle = Handle::default(); + let now = Instant::now(); + + let mut delay = handle.delay(now + ms(1)); + + mocked_with_now(now, |timer, _time| { + assert_not_ready!(delay); + + turn(timer, ms(1)); + + assert_ready!(delay); + }); +} |