From 832408ea9b713bc699932222d53bda911ad2ca66 Mon Sep 17 00:00:00 2001 From: Sergio Benitez Date: Wed, 8 Jul 2020 18:36:28 -0700 Subject: [PATCH] Add example requiring async testing. --- core/lib/Cargo.toml | 2 +- examples/testing/src/async_required.rs | 40 ++++++++++++++++++++++++++ examples/testing/src/main.rs | 18 ++++-------- site/guide/8-testing.md | 15 +++++----- 4 files changed, 54 insertions(+), 21 deletions(-) create mode 100644 examples/testing/src/async_required.rs diff --git a/core/lib/Cargo.toml b/core/lib/Cargo.toml index 50e99012..56bdb50c 100644 --- a/core/lib/Cargo.toml +++ b/core/lib/Cargo.toml @@ -43,7 +43,7 @@ atomic = "0.4" [dependencies.tokio] version = "0.2.9" -features = ["fs", "io-std", "io-util", "rt-threaded", "sync", "signal"] +features = ["fs", "io-std", "io-util", "rt-threaded", "sync", "signal", "macros"] [build-dependencies] yansi = "0.5" diff --git a/examples/testing/src/async_required.rs b/examples/testing/src/async_required.rs new file mode 100644 index 00000000..fa46e2ee --- /dev/null +++ b/examples/testing/src/async_required.rs @@ -0,0 +1,40 @@ +use rocket::State; +use rocket::fairing::AdHoc; +use rocket::tokio::sync::Barrier; + +#[get("/barrier")] +async fn rendezvous(barrier: State<'_, Barrier>) -> &'static str { + println!("Waiting for second task..."); + barrier.wait().await; + "Rendezvous reached." +} + +pub fn rocket() -> rocket::Rocket { + rocket::ignite() + .mount("/", routes![rendezvous]) + .attach(AdHoc::on_attach("Add Channel", |rocket| async { + Ok(rocket.manage(Barrier::new(2))) + })) +} + +#[cfg(test)] +mod test { + use super::rocket; + use rocket::http::Status; + + #[rocket::async_test] + async fn test_rendezvous() { + use rocket::local::asynchronous::Client; + + let client = Client::new(rocket()).await.unwrap(); + let req = client.get("/barrier"); + + let (r1, r2) = rocket::tokio::join!(req.clone().dispatch(), req.dispatch()); + assert_eq!(r1.status(), r2.status()); + assert_eq!(r1.status(), Status::Ok); + + let (s1, s2) = (r1.into_string().await, r2.into_string().await); + assert_eq!(s1, s2); + assert_eq!(s1.unwrap(), "Rendezvous reached."); + } +} diff --git a/examples/testing/src/main.rs b/examples/testing/src/main.rs index c3d3eaa8..8ca403de 100644 --- a/examples/testing/src/main.rs +++ b/examples/testing/src/main.rs @@ -2,14 +2,16 @@ #[macro_use] extern crate rocket; +mod async_required; + #[get("/")] fn hello() -> &'static str { "Hello, world!" } -#[rocket::launch] +#[launch] fn rocket() -> rocket::Rocket { - rocket::ignite().mount("/", routes![hello]) + async_required::rocket().mount("/", routes![hello]) } #[cfg(test)] @@ -17,18 +19,8 @@ mod test { use super::rocket; use rocket::http::Status; - #[rocket::async_test] - async fn test_hello_async() { - use rocket::local::asynchronous::Client; - - let client = Client::new(rocket()).await.unwrap(); - let response = client.get("/").dispatch().await; - assert_eq!(response.status(), Status::Ok); - assert_eq!(response.into_string().await, Some("Hello, world!".into())); - } - #[test] - fn test_hello_blocking() { + fn test_hello() { use rocket::local::blocking::Client; let client = Client::new(rocket()).unwrap(); diff --git a/site/guide/8-testing.md b/site/guide/8-testing.md index 8801b03a..90024e40 100644 --- a/site/guide/8-testing.md +++ b/site/guide/8-testing.md @@ -258,16 +258,17 @@ The tests can be run with `cargo test`. You can find the full source code to You may have noticed the use of a "`blocking`" API in these examples, even though `Rocket` is an `async` web framework. In most situations, the `blocking` -testing API is easier to use. When concurrent execution of two or more requests -is required for the server to make progress, you will need the more flexible -`asynchronous` API; the `blocking` API is not capable of dispatching multiple -requests simultaneously. For more information, see the [`rocket::local`] and -[`rocket::local::asynchronous`] documentation as well as the asynchronous -version of [the `testing` example]. +testing API is easier to use and should be preferred. However, when concurrent +execution of two or more requests is required for the server to make progress, +you will need the more flexible `asynchronous` API; the `blocking` API is not +capable of dispatching multiple requests simultaneously. While synthetic, the +[`async_required` `testing` example] uses an `async` barrier to demonstrate such +a case. For more information, see the [`rocket::local`] and +[`rocket::local::asynchronous`] documentation. [`rocket::local`]: @api/rocket/local/index.html [`rocket::local::asynchronous`]: @api/rocket/local/asynchronous/index.html -[the `testing` example]: @example/testing/src/main.rs +[`async_required` `testing` example]: @example/testing/src/async_required.rs ## Codegen Debug