tokio-test: add assert_elapsed macro (#3728)

This commit is contained in:
Russell Cohen
2021-05-05 12:09:28 +02:00
committed by GitHub
parent 541b0c3af2
commit 8ef39dfb22
3 changed files with 54 additions and 49 deletions
+34
View File
@@ -259,3 +259,37 @@ macro_rules! assert_err {
}
}};
}
/// Asserts that an exact duration has elapsed since since the start instant ±1ms.
///
/// ```rust
/// use tokio::time::{self, Instant};
/// use std::time::Duration;
/// use tokio_test::assert_elapsed;
/// # async fn test_time_passed() {
///
/// let start = Instant::now();
/// let dur = Duration::from_millis(50);
/// time::sleep(dur).await;
/// assert_elapsed!(start, dur);
/// # }
/// ```
///
/// This 1ms buffer is required because Tokio's hashed-wheel timer has finite time resolution and
/// will not always sleep for the exact interval.
#[macro_export]
macro_rules! assert_elapsed {
($start:expr, $dur:expr) => {{
let elapsed = $start.elapsed();
// type ascription improves compiler error when wrong type is passed
let lower: std::time::Duration = $dur;
// Handles ms rounding
assert!(
elapsed >= lower && elapsed <= lower + std::time::Duration::from_millis(1),
"actual = {:?}, expected = {:?}",
elapsed,
lower
);
}};
}
+8 -23
View File
@@ -4,7 +4,7 @@
use rand::SeedableRng;
use rand::{rngs::StdRng, Rng};
use tokio::time::{self, Duration, Instant, Sleep};
use tokio_test::{assert_err, assert_pending, assert_ready_eq, task};
use tokio_test::{assert_elapsed, assert_err, assert_pending, assert_ready_eq, task};
use std::{
future::Future,
@@ -12,21 +12,6 @@ use std::{
task::{Context, Poll},
};
macro_rules! assert_elapsed {
($now:expr, $ms:expr) => {{
let elapsed = $now.elapsed();
let lower = ms($ms);
// Handles ms rounding
assert!(
elapsed >= lower && elapsed <= lower + ms(1),
"actual = {:?}, expected = {:?}",
elapsed,
lower
);
}};
}
#[tokio::test]
async fn pause_time_in_main() {
tokio::time::pause();
@@ -91,7 +76,7 @@ async fn advance_after_poll() {
let before = Instant::now();
time::advance(ms(100)).await;
assert_elapsed!(before, 100);
assert_elapsed!(before, ms(100));
assert_pending!(sleep.poll());
}
@@ -107,7 +92,7 @@ async fn sleep_no_poll() {
let before = Instant::now();
time::advance(ms(100)).await;
assert_elapsed!(before, 100);
assert_elapsed!(before, ms(100));
assert_pending!(sleep.poll());
}
@@ -147,7 +132,7 @@ impl Future for Tester {
}
},
State::AfterAdvance => {
assert_elapsed!(self.before.unwrap(), 100);
assert_elapsed!(self.before.unwrap(), ms(100));
assert_pending!(self.sleep.as_mut().poll(cx));
@@ -207,24 +192,24 @@ async fn interval() {
let before = Instant::now();
time::advance(ms(100)).await;
assert_elapsed!(before, 100);
assert_elapsed!(before, ms(100));
assert_pending!(poll_next(&mut i));
let before = Instant::now();
time::advance(ms(200)).await;
assert_elapsed!(before, 200);
assert_elapsed!(before, ms(200));
assert_ready_eq!(poll_next(&mut i), start + ms(300));
assert_pending!(poll_next(&mut i));
let before = Instant::now();
time::advance(ms(400)).await;
assert_elapsed!(before, 400);
assert_elapsed!(before, ms(400));
assert_ready_eq!(poll_next(&mut i), start + ms(600));
assert_pending!(poll_next(&mut i));
let before = Instant::now();
time::advance(ms(500)).await;
assert_elapsed!(before, 500);
assert_elapsed!(before, ms(500));
assert_ready_eq!(poll_next(&mut i), start + ms(900));
assert_ready_eq!(poll_next(&mut i), start + ms(1200));
assert_pending!(poll_next(&mut i));
+12 -26
View File
@@ -7,22 +7,7 @@ use std::task::Context;
use futures::task::noop_waker_ref;
use tokio::time::{self, Duration, Instant};
use tokio_test::{assert_pending, assert_ready, task};
macro_rules! assert_elapsed {
($now:expr, $ms:expr) => {{
let elapsed = $now.elapsed();
let lower = ms($ms);
// Handles ms rounding
assert!(
elapsed >= lower && elapsed <= lower + ms(1),
"actual = {:?}, expected = {:?}",
elapsed,
lower
);
}};
}
use tokio_test::{assert_elapsed, assert_pending, assert_ready, task};
#[tokio::test]
async fn immediate_sleep() {
@@ -32,7 +17,7 @@ async fn immediate_sleep() {
// Ready!
time::sleep_until(now).await;
assert_elapsed!(now, 0);
assert_elapsed!(now, ms(1));
}
#[tokio::test]
@@ -60,10 +45,11 @@ async fn delayed_sleep_level_0() {
for &i in &[1, 10, 60] {
let now = Instant::now();
let dur = ms(i);
time::sleep_until(now + ms(i)).await;
time::sleep_until(now + dur).await;
assert_elapsed!(now, i);
assert_elapsed!(now, dur);
}
}
@@ -77,7 +63,7 @@ async fn sub_ms_delayed_sleep() {
time::sleep_until(deadline).await;
assert_elapsed!(now, 1);
assert_elapsed!(now, ms(1));
}
}
@@ -90,7 +76,7 @@ async fn delayed_sleep_wrapping_level_0() {
let now = Instant::now();
time::sleep_until(now + ms(60)).await;
assert_elapsed!(now, 60);
assert_elapsed!(now, ms(60));
}
#[tokio::test]
@@ -107,7 +93,7 @@ async fn reset_future_sleep_before_fire() {
sleep.as_mut().reset(Instant::now() + ms(200));
sleep.await;
assert_elapsed!(now, 200);
assert_elapsed!(now, ms(200));
}
#[tokio::test]
@@ -124,7 +110,7 @@ async fn reset_past_sleep_before_turn() {
sleep.as_mut().reset(now + ms(80));
sleep.await;
assert_elapsed!(now, 80);
assert_elapsed!(now, ms(80));
}
#[tokio::test]
@@ -143,7 +129,7 @@ async fn reset_past_sleep_before_fire() {
sleep.as_mut().reset(now + ms(80));
sleep.await;
assert_elapsed!(now, 80);
assert_elapsed!(now, ms(80));
}
#[tokio::test]
@@ -154,11 +140,11 @@ async fn reset_future_sleep_after_fire() {
let mut sleep = Box::pin(time::sleep_until(now + ms(100)));
sleep.as_mut().await;
assert_elapsed!(now, 100);
assert_elapsed!(now, ms(100));
sleep.as_mut().reset(now + ms(110));
sleep.await;
assert_elapsed!(now, 110);
assert_elapsed!(now, ms(110));
}
#[tokio::test]