summaryrefslogtreecommitdiffstats
path: root/third_party/rust/tokio-timer/tests/delay.rs
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/tokio-timer/tests/delay.rs')
-rw-r--r--third_party/rust/tokio-timer/tests/delay.rs499
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);
+ });
+}