From 90373f87f78baaec2f3d2825b171896d500dac0e Mon Sep 17 00:00:00 2001 From: michele Date: Sun, 24 Apr 2022 18:49:37 +0200 Subject: [PATCH] #135 add utilities --- rstest/Cargo.toml | 5 +- rstest/src/lib.rs | 2 + rstest/src/timeout.rs | 120 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 126 insertions(+), 1 deletion(-) create mode 100644 rstest/src/timeout.rs diff --git a/rstest/Cargo.toml b/rstest/Cargo.toml index cd5d103..663b75f 100644 --- a/rstest/Cargo.toml +++ b/rstest/Cargo.toml @@ -17,17 +17,20 @@ version = "0.13.0" [lib] [dependencies] +futures = "0.3.15" +futures-timer = "3.0.2" rstest_macros = {version = "0.13.0", path = "../rstest_macros"} [dev-dependencies] actix-rt = "2.2.0" async-std = {version = "1.9.0", features = ["attributes"]} lazy_static = "1.4.0" -mytest = { package = "rstest", version = "0.12.0" } +mytest = {package = "rstest", version = "0.12.0"} pretty_assertions = "1.0.0" rstest_reuse = {version = "0.3", path = "../rstest_reuse"} rstest_test = {version = "0.6", path = "../rstest_test"} temp_testdir = "0.2.3" +tokio = {version = "1.6.1", features = ["rt", "macros"]} unindent = "0.1.7" [build-dependencies] diff --git a/rstest/src/lib.rs b/rstest/src/lib.rs index 9badc2c..e11e300 100644 --- a/rstest/src/lib.rs +++ b/rstest/src/lib.rs @@ -229,5 +229,7 @@ #[doc(hidden)] pub mod magic_conversion; +#[doc(hidden)] +pub mod timeout; pub use rstest_macros::{fixture, rstest}; diff --git a/rstest/src/timeout.rs b/rstest/src/timeout.rs new file mode 100644 index 0000000..65e90ec --- /dev/null +++ b/rstest/src/timeout.rs @@ -0,0 +1,120 @@ +use std::{sync::mpsc, time::Duration}; + +use futures::{select, Future, FutureExt}; +use futures_timer::Delay; + +pub fn execute_with_timeout_sync T + Send + 'static>( + code: F, + timeout: Duration, +) -> T { + let (sender, receiver) = mpsc::channel(); + std::thread::spawn(move || sender.send(code())); + receiver + .recv_timeout(timeout) + .unwrap_or_else(|_| panic!("Timeout {:?} Expired", timeout)) +} + +pub async fn execute_with_timeout_async, F: Fn() -> Fut>( + code: F, + timeout: Duration, +) -> T { + select! { + () = async { + Delay::new(timeout).await; + }.fuse() => panic!("Timeout {:?} expired", timeout), + out = code().fuse() => out, + } +} + +#[cfg(test)] +mod tests { + use super::*; + mod async_version { + + use super::*; + use std::time::Duration; + + async fn delayed_sum(a: u32, b: u32, delay: Duration) -> u32 { + async_std::task::sleep(delay).await; + a + b + } + + async fn test(delay: Duration) { + let result = delayed_sum(2, 2, delay).await; + assert_eq!(result, 4); + } + + mod use_async_std_runtime { + use super::*; + + #[async_std::test] + #[should_panic] + async fn should_fail() { + execute_with_timeout_async( + || test(Duration::from_millis(20)), + Duration::from_millis(10) + ).await + } + + #[async_std::test] + async fn should_pass() { + execute_with_timeout_async( + || test(Duration::from_millis(10)), + Duration::from_millis(20) + ).await + } + } + + mod use_tokio_runtime { + use super::*; + + #[tokio::test] + #[should_panic] + async fn should_fail() { + execute_with_timeout_async( + || test(Duration::from_millis(20)), + Duration::from_millis(10) + ).await + } + + #[tokio::test] + async fn should_pass() { + execute_with_timeout_async( + || test(Duration::from_millis(10)), + Duration::from_millis(20) + ).await + } + } + } + + mod thread_version { + use super::*; + + pub fn delayed_sum(a: u32, b: u32, delay: Duration) -> u32 { + std::thread::sleep(delay); + a + b + } + + fn test(delay: Duration) { + let result = delayed_sum(2, 2, delay); + assert_eq!(result, 4); + } + + #[test] + fn should_pass() { + execute_with_timeout_sync( + || test(Duration::from_millis(30)), + Duration::from_millis(70), + ) + } + + #[test] + #[should_panic] + fn should_fail() { + execute_with_timeout_sync( + || test(Duration::from_millis(70)), + Duration::from_millis(30), + ) + } + } +}