mirror of
https://github.com/tokio-rs/tokio.git
synced 2026-08-26 00:00:16 +02:00
tokio-test: add assert_elapsed macro (#3728)
This commit is contained in:
@@ -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
|
||||
);
|
||||
}};
|
||||
}
|
||||
|
||||
@@ -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
@@ -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]
|
||||
|
||||
Reference in New Issue
Block a user