tests: enable running wasm32-unknown-unknown tests (#4421)

* Several of tokio's features (e.g. the channel implementation) do not
  need a runtime to work, and can be compiled and used for
  wasm32-unknown-unknown targets
* This change enables running tests for the `sync` and `macros` features
  so that we can note any regressions there
This commit is contained in:
Ivan Petkov 2022-01-27 14:07:52 +00:00 committed by GitHub
parent 2a5071fc2d
commit 2747043f6f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
30 changed files with 301 additions and 109 deletions

View File

@ -36,6 +36,7 @@ jobs:
- loom-compile
- check-readme
- test-hyper
- wasm32-unknown-unknown
steps:
- run: exit 0
@ -391,3 +392,17 @@ jobs:
echo 'tokio-test = { path = "../tokio-test" }' >>Cargo.toml
git diff
cargo test --features full
wasm32-unknown-unknown:
name: test tokio for wasm32-unknown-unknown
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install Rust
run: rustup update stable
- uses: Swatinem/rust-cache@v1
- name: Install wasm-pack
run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
- name: test tokio
run: wasm-pack test --node -- --features "macros sync"
working-directory: tokio

View File

@ -128,12 +128,17 @@ tokio-test = { version = "0.4.0", path = "../tokio-test" }
tokio-stream = { version = "0.1", path = "../tokio-stream" }
futures = { version = "0.3.0", features = ["async-await"] }
mockall = "0.10.2"
proptest = "1"
rand = "0.8.0"
tempfile = "3.1.0"
async-stream = "0.3"
[target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies]
proptest = "1"
rand = "0.8.0"
socket2 = "0.4"
[target.'cfg(target_arch = "wasm32")'.dev-dependencies]
wasm-bindgen-test = "0.3.0"
[target.'cfg(target_os = "freebsd")'.dev-dependencies]
mio-aio = { version = "0.6.0", features = ["tokio"] }

View File

@ -207,6 +207,9 @@ cfg_coop! {
mod test {
use super::*;
#[cfg(target_arch = "wasm32")]
use wasm_bindgen_test::wasm_bindgen_test as test;
fn get() -> Budget {
CURRENT.with(|cell| cell.get())
}

View File

@ -174,6 +174,7 @@
// At the top due to macros
#[cfg(test)]
#[cfg(not(target_arch = "wasm32"))]
#[macro_use]
mod tests;

View File

@ -347,6 +347,7 @@ impl<S: Schedule> LocalNotified<S> {
impl<S: Schedule> UnownedTask<S> {
// Used in test of the inject queue.
#[cfg(test)]
#[cfg_attr(target_arch = "wasm32", allow(dead_code))]
pub(super) fn into_notified(self) -> Notified<S> {
Notified(self.into_task())
}

View File

@ -12,6 +12,9 @@ impl AssertSync for AtomicWaker {}
impl AssertSend for Waker {}
impl AssertSync for Waker {}
#[cfg(target_arch = "wasm32")]
use wasm_bindgen_test::wasm_bindgen_test as test;
#[test]
fn basic_usage() {
let mut waker = task::spawn(AtomicWaker::new());
@ -34,6 +37,7 @@ fn wake_without_register() {
}
#[test]
#[cfg(not(target_arch = "wasm32"))] // wasm currently doesn't support unwinding
fn atomic_waker_panic_safe() {
use std::panic;
use std::ptr;

View File

@ -4,6 +4,9 @@ use std::mem::ManuallyDrop;
use std::sync::Arc;
use std::task::{Context, RawWaker, RawWakerVTable, Waker};
#[cfg(target_arch = "wasm32")]
use wasm_bindgen_test::wasm_bindgen_test as test;
#[test]
fn notify_clones_waker_before_lock() {
const VTABLE: &RawWakerVTable = &RawWakerVTable::new(clone_w, wake, wake_by_ref, drop_w);

View File

@ -1,6 +1,9 @@
use crate::sync::batch_semaphore::Semaphore;
use tokio_test::*;
#[cfg(target_arch = "wasm32")]
use wasm_bindgen_test::wasm_bindgen_test as test;
#[test]
fn poll_acquire_one_available() {
let s = Semaphore::new(100);
@ -167,6 +170,7 @@ fn poll_acquire_one_zero_permits() {
#[test]
#[should_panic]
#[cfg(not(target_arch = "wasm32"))] // wasm currently doesn't support unwinding
fn validates_max_permits() {
use std::usize;
Semaphore::new((usize::MAX >> 2) + 1);

View File

@ -614,6 +614,7 @@ mod tests {
}
}
#[cfg(not(target_arch = "wasm32"))]
proptest::proptest! {
#[test]
fn fuzz_linked_list(ops: Vec<usize>) {

View File

@ -1,2 +1,2 @@
#![cfg(not(feature = "full"))]
#![cfg(not(any(feature = "full", target_arch = "wasm32")))]
compile_error!("run main Tokio tests with `--features full`");

View File

@ -1,36 +1,46 @@
#![cfg(feature = "macros")]
#![allow(clippy::blacklisted_name)]
#[cfg(target_arch = "wasm32")]
use wasm_bindgen_test::wasm_bindgen_test as test;
#[cfg(target_arch = "wasm32")]
use wasm_bindgen_test::wasm_bindgen_test as maybe_tokio_test;
#[cfg(not(target_arch = "wasm32"))]
use tokio::test as maybe_tokio_test;
use tokio::sync::oneshot;
use tokio_test::{assert_pending, assert_ready, task};
#[tokio::test]
#[maybe_tokio_test]
async fn sync_one_lit_expr_comma() {
let foo = tokio::join!(async { 1 },);
assert_eq!(foo, (1,));
}
#[tokio::test]
#[maybe_tokio_test]
async fn sync_one_lit_expr_no_comma() {
let foo = tokio::join!(async { 1 });
assert_eq!(foo, (1,));
}
#[tokio::test]
#[maybe_tokio_test]
async fn sync_two_lit_expr_comma() {
let foo = tokio::join!(async { 1 }, async { 2 },);
assert_eq!(foo, (1, 2));
}
#[tokio::test]
#[maybe_tokio_test]
async fn sync_two_lit_expr_no_comma() {
let foo = tokio::join!(async { 1 }, async { 2 });
assert_eq!(foo, (1, 2));
}
#[tokio::test]
#[maybe_tokio_test]
async fn two_await() {
let (tx1, rx1) = oneshot::channel::<&str>();
let (tx2, rx2) = oneshot::channel::<u32>();

View File

@ -1,7 +1,15 @@
#![cfg(feature = "macros")]
#[cfg(target_arch = "wasm32")]
use wasm_bindgen_test::wasm_bindgen_test as maybe_tokio_test;
#[cfg(not(target_arch = "wasm32"))]
use tokio::test as maybe_tokio_test;
async fn one() {}
async fn two() {}
#[tokio::test]
#[maybe_tokio_test]
async fn multi_pin() {
tokio::pin! {
let f1 = one();

View File

@ -1,12 +1,19 @@
#![cfg(feature = "macros")]
#![allow(clippy::blacklisted_name)]
use tokio::sync::{mpsc, oneshot};
use tokio::task;
#[cfg(target_arch = "wasm32")]
use wasm_bindgen_test::wasm_bindgen_test as maybe_tokio_test;
#[cfg(not(target_arch = "wasm32"))]
use tokio::test as maybe_tokio_test;
use tokio::sync::oneshot;
use tokio_test::{assert_ok, assert_pending, assert_ready};
use futures::future::poll_fn;
use std::task::Poll::Ready;
#[tokio::test]
#[maybe_tokio_test]
async fn sync_one_lit_expr_comma() {
let foo = tokio::select! {
foo = async { 1 } => foo,
@ -15,7 +22,7 @@ async fn sync_one_lit_expr_comma() {
assert_eq!(foo, 1);
}
#[tokio::test]
#[maybe_tokio_test]
async fn nested_one() {
let foo = tokio::select! {
foo = async { 1 } => tokio::select! {
@ -26,7 +33,7 @@ async fn nested_one() {
assert_eq!(foo, 1);
}
#[tokio::test]
#[maybe_tokio_test]
async fn sync_one_lit_expr_no_comma() {
let foo = tokio::select! {
foo = async { 1 } => foo
@ -35,7 +42,7 @@ async fn sync_one_lit_expr_no_comma() {
assert_eq!(foo, 1);
}
#[tokio::test]
#[maybe_tokio_test]
async fn sync_one_lit_expr_block() {
let foo = tokio::select! {
foo = async { 1 } => { foo }
@ -44,7 +51,7 @@ async fn sync_one_lit_expr_block() {
assert_eq!(foo, 1);
}
#[tokio::test]
#[maybe_tokio_test]
async fn sync_one_await() {
let foo = tokio::select! {
foo = one() => foo,
@ -53,7 +60,7 @@ async fn sync_one_await() {
assert_eq!(foo, 1);
}
#[tokio::test]
#[maybe_tokio_test]
async fn sync_one_ident() {
let one = one();
@ -64,7 +71,7 @@ async fn sync_one_ident() {
assert_eq!(foo, 1);
}
#[tokio::test]
#[maybe_tokio_test]
async fn sync_two() {
use std::cell::Cell;
@ -85,7 +92,7 @@ async fn sync_two() {
assert!(res == 1 || res == 2);
}
#[tokio::test]
#[maybe_tokio_test]
async fn drop_in_fut() {
let s = "hello".to_string();
@ -100,7 +107,8 @@ async fn drop_in_fut() {
assert_eq!(res, 1);
}
#[tokio::test]
#[maybe_tokio_test]
#[cfg(feature = "full")]
async fn one_ready() {
let (tx1, rx1) = oneshot::channel::<i32>();
let (_tx2, rx2) = oneshot::channel::<i32>();
@ -117,20 +125,23 @@ async fn one_ready() {
assert_eq!(1, v);
}
#[tokio::test]
#[maybe_tokio_test]
#[cfg(feature = "full")]
async fn select_streams() {
use tokio::sync::mpsc;
let (tx1, mut rx1) = mpsc::unbounded_channel::<i32>();
let (tx2, mut rx2) = mpsc::unbounded_channel::<i32>();
tokio::spawn(async move {
assert_ok!(tx2.send(1));
task::yield_now().await;
tokio::task::yield_now().await;
assert_ok!(tx1.send(2));
task::yield_now().await;
tokio::task::yield_now().await;
assert_ok!(tx2.send(3));
task::yield_now().await;
tokio::task::yield_now().await;
drop((tx1, tx2));
});
@ -156,7 +167,7 @@ async fn select_streams() {
assert_eq!(&msgs[..], &[1, 2, 3]);
}
#[tokio::test]
#[maybe_tokio_test]
async fn move_uncompleted_futures() {
let (tx1, mut rx1) = oneshot::channel::<i32>();
let (tx2, mut rx2) = oneshot::channel::<i32>();
@ -182,7 +193,7 @@ async fn move_uncompleted_futures() {
assert!(ran);
}
#[tokio::test]
#[maybe_tokio_test]
async fn nested() {
let res = tokio::select! {
x = async { 1 } => {
@ -195,7 +206,7 @@ async fn nested() {
assert_eq!(res, 3);
}
#[tokio::test]
#[maybe_tokio_test]
async fn struct_size() {
use futures::future;
use std::mem;
@ -237,7 +248,7 @@ async fn struct_size() {
assert!(mem::size_of_val(&fut) <= 48);
}
#[tokio::test]
#[maybe_tokio_test]
async fn mutable_borrowing_future_with_same_borrow_in_block() {
let mut value = 234;
@ -251,7 +262,7 @@ async fn mutable_borrowing_future_with_same_borrow_in_block() {
assert!(value >= 234);
}
#[tokio::test]
#[maybe_tokio_test]
async fn mutable_borrowing_future_with_same_borrow_in_block_and_else() {
let mut value = 234;
@ -268,7 +279,7 @@ async fn mutable_borrowing_future_with_same_borrow_in_block_and_else() {
assert!(value >= 234);
}
#[tokio::test]
#[maybe_tokio_test]
async fn future_panics_after_poll() {
use tokio_test::task;
@ -298,7 +309,7 @@ async fn future_panics_after_poll() {
assert_eq!(1, res);
}
#[tokio::test]
#[maybe_tokio_test]
async fn disable_with_if() {
use tokio_test::task;
@ -320,7 +331,7 @@ async fn disable_with_if() {
assert_ready!(f.poll());
}
#[tokio::test]
#[maybe_tokio_test]
async fn join_with_select() {
use tokio_test::task;
@ -356,6 +367,7 @@ async fn join_with_select() {
}
#[tokio::test]
#[cfg(feature = "full")]
async fn use_future_in_if_condition() {
use tokio::time::{self, Duration};
@ -369,6 +381,7 @@ async fn use_future_in_if_condition() {
}
#[tokio::test]
#[cfg(feature = "full")]
async fn use_future_in_if_condition_biased() {
use tokio::time::{self, Duration};
@ -382,7 +395,7 @@ async fn use_future_in_if_condition_biased() {
}
}
#[tokio::test]
#[maybe_tokio_test]
async fn many_branches() {
let num = tokio::select! {
x = async { 1 } => x,
@ -453,7 +466,7 @@ async fn many_branches() {
assert_eq!(1, num);
}
#[tokio::test]
#[maybe_tokio_test]
async fn never_branch_no_warnings() {
let t = tokio::select! {
_ = async_never() => 0,
@ -474,7 +487,7 @@ async fn async_never() -> ! {
}
// From https://github.com/tokio-rs/tokio/issues/2857
#[tokio::test]
#[maybe_tokio_test]
async fn mut_on_left_hand_side() {
let v = async move {
let ok = async { 1 };
@ -490,7 +503,7 @@ async fn mut_on_left_hand_side() {
assert_eq!(v, 2);
}
#[tokio::test]
#[maybe_tokio_test]
async fn biased_one_not_ready() {
let (_tx1, rx1) = oneshot::channel::<i32>();
let (tx2, rx2) = oneshot::channel::<i32>();
@ -514,7 +527,8 @@ async fn biased_one_not_ready() {
assert_eq!(2, v);
}
#[tokio::test]
#[maybe_tokio_test]
#[cfg(feature = "full")]
async fn biased_eventually_ready() {
use tokio::task::yield_now;
@ -560,7 +574,7 @@ pub async fn default_numeric_fallback() {
}
// https://github.com/tokio-rs/tokio/issues/4182
#[tokio::test]
#[maybe_tokio_test]
async fn mut_ref_patterns() {
tokio::select! {
Some(mut foo) = async { Some("1".to_string()) } => {

View File

@ -1,3 +1,5 @@
#![cfg(feature = "full")]
use tokio::test;
#[test]

View File

@ -1,36 +1,44 @@
#![cfg(feature = "macros")]
#![allow(clippy::blacklisted_name)]
use tokio::sync::oneshot;
use tokio_test::{assert_pending, assert_ready, task};
#[tokio::test]
#[cfg(target_arch = "wasm32")]
use wasm_bindgen_test::wasm_bindgen_test as maybe_tokio_test;
#[cfg(not(target_arch = "wasm32"))]
use tokio::test as maybe_tokio_test;
#[maybe_tokio_test]
async fn sync_one_lit_expr_comma() {
let foo = tokio::try_join!(async { ok(1) },);
assert_eq!(foo, Ok((1,)));
}
#[tokio::test]
#[maybe_tokio_test]
async fn sync_one_lit_expr_no_comma() {
let foo = tokio::try_join!(async { ok(1) });
assert_eq!(foo, Ok((1,)));
}
#[tokio::test]
#[maybe_tokio_test]
async fn sync_two_lit_expr_comma() {
let foo = tokio::try_join!(async { ok(1) }, async { ok(2) },);
assert_eq!(foo, Ok((1, 2)));
}
#[tokio::test]
#[maybe_tokio_test]
async fn sync_two_lit_expr_no_comma() {
let foo = tokio::try_join!(async { ok(1) }, async { ok(2) });
assert_eq!(foo, Ok((1, 2)));
}
#[tokio::test]
#[maybe_tokio_test]
async fn two_await() {
let (tx1, rx1) = oneshot::channel::<&str>();
let (tx2, rx2) = oneshot::channel::<u32>();
@ -51,7 +59,7 @@ async fn two_await() {
assert_eq!(Ok(("hello", 123)), res);
}
#[tokio::test]
#[maybe_tokio_test]
async fn err_abort_early() {
let (tx1, rx1) = oneshot::channel::<&str>();
let (tx2, rx2) = oneshot::channel::<u32>();

View File

@ -1,3 +1,5 @@
#![cfg(feature = "full")]
use tokio::net;
use tokio_test::assert_ok;

View File

@ -1,3 +1,5 @@
#![cfg(feature = "full")]
use tokio::net::TcpStream;
use tokio::sync::oneshot;
use tokio::time::{timeout, Duration};

View File

@ -1,6 +1,9 @@
#![allow(clippy::unnecessary_operation)]
#![warn(rust_2018_idioms)]
#![cfg(feature = "full")]
#![cfg(feature = "sync")]
#[cfg(target_arch = "wasm32")]
use wasm_bindgen_test::wasm_bindgen_test as test;
use tokio::sync::Barrier;

View File

@ -2,6 +2,9 @@
#![warn(rust_2018_idioms)]
#![cfg(feature = "sync")]
#[cfg(target_arch = "wasm32")]
use wasm_bindgen_test::wasm_bindgen_test as test;
use tokio::sync::broadcast;
use tokio_test::task;
use tokio_test::{
@ -273,12 +276,14 @@ fn send_no_rx() {
#[test]
#[should_panic]
#[cfg(not(target_arch = "wasm32"))] // wasm currently doesn't support unwinding
fn zero_capacity() {
broadcast::channel::<()>(0);
}
#[test]
#[should_panic]
#[cfg(not(target_arch = "wasm32"))] // wasm currently doesn't support unwinding
fn capacity_too_big() {
use std::usize;
@ -286,6 +291,7 @@ fn capacity_too_big() {
}
#[test]
#[cfg(not(target_arch = "wasm32"))] // wasm currently doesn't support unwinding
fn panic_in_clone() {
use std::panic::{self, AssertUnwindSafe};

View File

@ -1,5 +1,8 @@
#![warn(rust_2018_idioms)]
#![cfg(feature = "full")]
#![cfg(feature = "sync")]
#[cfg(target_arch = "wasm32")]
use wasm_bindgen_test::wasm_bindgen_test as test;
fn is_error<T: std::error::Error + Send + Sync>() {}

View File

@ -1,18 +1,22 @@
#![allow(clippy::redundant_clone)]
#![warn(rust_2018_idioms)]
#![cfg(feature = "full")]
#![cfg(feature = "sync")]
#[cfg(target_arch = "wasm32")]
use wasm_bindgen_test::wasm_bindgen_test as test;
#[cfg(target_arch = "wasm32")]
use wasm_bindgen_test::wasm_bindgen_test as maybe_tokio_test;
#[cfg(not(target_arch = "wasm32"))]
use tokio::test as maybe_tokio_test;
use std::thread;
use tokio::runtime::Runtime;
use tokio::sync::mpsc;
use tokio::sync::mpsc::error::{TryRecvError, TrySendError};
use tokio_test::task;
use tokio_test::{
assert_err, assert_ok, assert_pending, assert_ready, assert_ready_err, assert_ready_ok,
};
use tokio_test::*;
use std::sync::Arc;
#[cfg(not(target_arch = "wasm32"))]
mod support {
pub(crate) mod mpsc_stream;
}
@ -21,7 +25,7 @@ trait AssertSend: Send {}
impl AssertSend for mpsc::Sender<i32> {}
impl AssertSend for mpsc::Receiver<i32> {}
#[tokio::test]
#[maybe_tokio_test]
async fn send_recv_with_buffer() {
let (tx, mut rx) = mpsc::channel::<i32>(16);
@ -46,6 +50,7 @@ async fn send_recv_with_buffer() {
}
#[tokio::test]
#[cfg(feature = "full")]
async fn reserve_disarm() {
let (tx, mut rx) = mpsc::channel::<i32>(2);
let tx1 = tx.clone();
@ -58,10 +63,10 @@ async fn reserve_disarm() {
let permit2 = assert_ok!(tx2.reserve().await);
// But a third should not be ready
let mut r3 = task::spawn(tx3.reserve());
let mut r3 = tokio_test::task::spawn(tx3.reserve());
assert_pending!(r3.poll());
let mut r4 = task::spawn(tx4.reserve());
let mut r4 = tokio_test::task::spawn(tx4.reserve());
assert_pending!(r4.poll());
// Using one of the reserved slots should allow a new handle to become ready
@ -78,11 +83,12 @@ async fn reserve_disarm() {
drop(permit2);
assert!(r4.is_woken());
let mut r1 = task::spawn(tx1.reserve());
let mut r1 = tokio_test::task::spawn(tx1.reserve());
assert_pending!(r1.poll());
}
#[tokio::test]
#[cfg(feature = "full")]
async fn send_recv_stream_with_buffer() {
use tokio_stream::StreamExt;
@ -100,6 +106,7 @@ async fn send_recv_stream_with_buffer() {
}
#[tokio::test]
#[cfg(feature = "full")]
async fn async_send_recv_with_buffer() {
let (tx, mut rx) = mpsc::channel(16);
@ -114,10 +121,11 @@ async fn async_send_recv_with_buffer() {
}
#[tokio::test]
#[cfg(feature = "full")]
async fn start_send_past_cap() {
use std::future::Future;
let mut t1 = task::spawn(());
let mut t1 = tokio_test::task::spawn(());
let (tx1, mut rx) = mpsc::channel(1);
let tx2 = tx1.clone();
@ -128,7 +136,7 @@ async fn start_send_past_cap() {
t1.enter(|cx, _| assert_pending!(r1.as_mut().poll(cx)));
{
let mut r2 = task::spawn(tx2.reserve());
let mut r2 = tokio_test::task::spawn(tx2.reserve());
assert_pending!(r2.poll());
drop(r1);
@ -147,11 +155,12 @@ async fn start_send_past_cap() {
#[test]
#[should_panic]
#[cfg(not(target_arch = "wasm32"))] // wasm currently doesn't support unwinding
fn buffer_gteq_one() {
mpsc::channel::<i32>(0);
}
#[tokio::test]
#[maybe_tokio_test]
async fn send_recv_unbounded() {
let (tx, mut rx) = mpsc::unbounded_channel::<i32>();
@ -168,6 +177,7 @@ async fn send_recv_unbounded() {
}
#[tokio::test]
#[cfg(feature = "full")]
async fn async_send_recv_unbounded() {
let (tx, mut rx) = mpsc::unbounded_channel();
@ -182,6 +192,7 @@ async fn async_send_recv_unbounded() {
}
#[tokio::test]
#[cfg(feature = "full")]
async fn send_recv_stream_unbounded() {
use tokio_stream::StreamExt;
@ -199,7 +210,7 @@ async fn send_recv_stream_unbounded() {
assert_eq!(None, rx.next().await);
}
#[tokio::test]
#[maybe_tokio_test]
async fn no_t_bounds_buffer() {
struct NoImpls;
@ -215,7 +226,7 @@ async fn no_t_bounds_buffer() {
assert!(rx.recv().await.is_some());
}
#[tokio::test]
#[maybe_tokio_test]
async fn no_t_bounds_unbounded() {
struct NoImpls;
@ -232,6 +243,7 @@ async fn no_t_bounds_unbounded() {
}
#[tokio::test]
#[cfg(feature = "full")]
async fn send_recv_buffer_limited() {
let (tx, mut rx) = mpsc::channel::<i32>(1);
@ -242,7 +254,7 @@ async fn send_recv_buffer_limited() {
p1.send(1);
// Not ready
let mut p2 = task::spawn(tx.reserve());
let mut p2 = tokio_test::task::spawn(tx.reserve());
assert_pending!(p2.poll());
// Take the value
@ -261,7 +273,7 @@ async fn send_recv_buffer_limited() {
assert!(rx.recv().await.is_some());
}
#[tokio::test]
#[maybe_tokio_test]
async fn recv_close_gets_none_idle() {
let (tx, mut rx) = mpsc::channel::<i32>(10);
@ -273,12 +285,13 @@ async fn recv_close_gets_none_idle() {
}
#[tokio::test]
#[cfg(feature = "full")]
async fn recv_close_gets_none_reserved() {
let (tx1, mut rx) = mpsc::channel::<i32>(1);
let tx2 = tx1.clone();
let permit1 = assert_ok!(tx1.reserve().await);
let mut permit2 = task::spawn(tx2.reserve());
let mut permit2 = tokio_test::task::spawn(tx2.reserve());
assert_pending!(permit2.poll());
rx.close();
@ -287,7 +300,7 @@ async fn recv_close_gets_none_reserved() {
assert_ready_err!(permit2.poll());
{
let mut recv = task::spawn(rx.recv());
let mut recv = tokio_test::task::spawn(rx.recv());
assert_pending!(recv.poll());
permit1.send(123);
@ -300,13 +313,13 @@ async fn recv_close_gets_none_reserved() {
assert!(rx.recv().await.is_none());
}
#[tokio::test]
#[maybe_tokio_test]
async fn tx_close_gets_none() {
let (_, mut rx) = mpsc::channel::<i32>(10);
assert!(rx.recv().await.is_none());
}
#[tokio::test]
#[maybe_tokio_test]
async fn try_send_fail() {
let (tx, mut rx) = mpsc::channel(1);
@ -327,7 +340,7 @@ async fn try_send_fail() {
assert!(rx.recv().await.is_none());
}
#[tokio::test]
#[maybe_tokio_test]
async fn try_send_fail_with_try_recv() {
let (tx, mut rx) = mpsc::channel(1);
@ -348,7 +361,7 @@ async fn try_send_fail_with_try_recv() {
assert_eq!(rx.try_recv(), Err(TryRecvError::Disconnected));
}
#[tokio::test]
#[maybe_tokio_test]
async fn try_reserve_fails() {
let (tx, mut rx) = mpsc::channel(1);
@ -372,6 +385,7 @@ async fn try_reserve_fails() {
}
#[tokio::test]
#[cfg(feature = "full")]
async fn drop_permit_releases_permit() {
// poll_ready reserves capacity, ensure that the capacity is released if tx
// is dropped w/o sending a value.
@ -380,7 +394,7 @@ async fn drop_permit_releases_permit() {
let permit = assert_ok!(tx1.reserve().await);
let mut reserve2 = task::spawn(tx2.reserve());
let mut reserve2 = tokio_test::task::spawn(tx2.reserve());
assert_pending!(reserve2.poll());
drop(permit);
@ -389,7 +403,7 @@ async fn drop_permit_releases_permit() {
assert_ready_ok!(reserve2.poll());
}
#[tokio::test]
#[maybe_tokio_test]
async fn dropping_rx_closes_channel() {
let (tx, rx) = mpsc::channel(100);
@ -439,48 +453,57 @@ fn unconsumed_messages_are_dropped() {
}
#[test]
#[cfg(feature = "full")]
fn blocking_recv() {
let (tx, mut rx) = mpsc::channel::<u8>(1);
let sync_code = thread::spawn(move || {
let sync_code = std::thread::spawn(move || {
assert_eq!(Some(10), rx.blocking_recv());
});
Runtime::new().unwrap().block_on(async move {
let _ = tx.send(10).await;
});
tokio::runtime::Runtime::new()
.unwrap()
.block_on(async move {
let _ = tx.send(10).await;
});
sync_code.join().unwrap()
}
#[tokio::test]
#[should_panic]
#[cfg(not(target_arch = "wasm32"))] // wasm currently doesn't support unwinding
async fn blocking_recv_async() {
let (_tx, mut rx) = mpsc::channel::<()>(1);
let _ = rx.blocking_recv();
}
#[test]
#[cfg(feature = "full")]
fn blocking_send() {
let (tx, mut rx) = mpsc::channel::<u8>(1);
let sync_code = thread::spawn(move || {
let sync_code = std::thread::spawn(move || {
tx.blocking_send(10).unwrap();
});
Runtime::new().unwrap().block_on(async move {
assert_eq!(Some(10), rx.recv().await);
});
tokio::runtime::Runtime::new()
.unwrap()
.block_on(async move {
assert_eq!(Some(10), rx.recv().await);
});
sync_code.join().unwrap()
}
#[tokio::test]
#[should_panic]
#[cfg(not(target_arch = "wasm32"))] // wasm currently doesn't support unwinding
async fn blocking_send_async() {
let (tx, _rx) = mpsc::channel::<()>(1);
let _ = tx.blocking_send(());
}
#[tokio::test]
#[cfg(feature = "full")]
async fn ready_close_cancel_bounded() {
let (tx, mut rx) = mpsc::channel::<()>(100);
let _tx2 = tx.clone();
@ -489,7 +512,7 @@ async fn ready_close_cancel_bounded() {
rx.close();
let mut recv = task::spawn(rx.recv());
let mut recv = tokio_test::task::spawn(rx.recv());
assert_pending!(recv.poll());
drop(permit);
@ -500,13 +523,14 @@ async fn ready_close_cancel_bounded() {
}
#[tokio::test]
#[cfg(feature = "full")]
async fn permit_available_not_acquired_close() {
let (tx1, mut rx) = mpsc::channel::<()>(1);
let tx2 = tx1.clone();
let permit1 = assert_ok!(tx1.reserve().await);
let mut permit2 = task::spawn(tx2.reserve());
let mut permit2 = tokio_test::task::spawn(tx2.reserve());
assert_pending!(permit2.poll());
rx.close();
@ -599,6 +623,7 @@ fn try_recv_close_while_empty_unbounded() {
}
#[tokio::test(start_paused = true)]
#[cfg(feature = "full")]
async fn recv_timeout() {
use tokio::sync::mpsc::error::SendTimeoutError::{Closed, Timeout};
use tokio::time::Duration;
@ -624,6 +649,7 @@ async fn recv_timeout() {
#[test]
#[should_panic = "there is no reactor running, must be called from the context of a Tokio 1.x runtime"]
#[cfg(not(target_arch = "wasm32"))] // wasm currently doesn't support unwinding
fn recv_timeout_panic() {
use futures::future::FutureExt;
use tokio::time::Duration;

View File

@ -1,13 +1,19 @@
#![warn(rust_2018_idioms)]
#![cfg(feature = "full")]
#![cfg(feature = "sync")]
#[cfg(target_arch = "wasm32")]
use wasm_bindgen_test::wasm_bindgen_test as test;
#[cfg(target_arch = "wasm32")]
use wasm_bindgen_test::wasm_bindgen_test as maybe_tokio_test;
#[cfg(not(target_arch = "wasm32"))]
use tokio::test as maybe_tokio_test;
use tokio::sync::Mutex;
use tokio::time::{interval, timeout};
use tokio_test::task::spawn;
use tokio_test::{assert_pending, assert_ready};
use std::sync::Arc;
use std::time::Duration;
#[test]
fn straight_execution() {
@ -82,10 +88,14 @@ fn lock() {
}
*/
#[tokio::test]
/// Ensure a mutex is unlocked if a future holding the lock
/// is aborted prematurely.
#[tokio::test]
#[cfg(feature = "full")]
async fn aborted_future_1() {
use std::time::Duration;
use tokio::time::{interval, timeout};
let m1: Arc<Mutex<usize>> = Arc::new(Mutex::new(0));
{
let m2 = m1.clone();
@ -108,10 +118,14 @@ async fn aborted_future_1() {
.expect("Mutex is locked");
}
#[tokio::test]
/// This test is similar to `aborted_future_1` but this time the
/// aborted future is waiting for the lock.
#[tokio::test]
#[cfg(feature = "full")]
async fn aborted_future_2() {
use std::time::Duration;
use tokio::time::timeout;
let m1: Arc<Mutex<usize>> = Arc::new(Mutex::new(0));
{
// Lock mutex
@ -147,14 +161,14 @@ fn try_lock() {
assert!(g3.is_ok());
}
#[tokio::test]
#[maybe_tokio_test]
async fn debug_format() {
let s = "debug";
let m = Mutex::new(s.to_string());
assert_eq!(format!("{:?}", s), format!("{:?}", m.lock().await));
}
#[tokio::test]
#[maybe_tokio_test]
async fn mutex_debug() {
let s = "data";
let m = Mutex::new(s.to_string());

View File

@ -1,13 +1,19 @@
#![warn(rust_2018_idioms)]
#![cfg(feature = "full")]
#![cfg(feature = "sync")]
#[cfg(target_arch = "wasm32")]
use wasm_bindgen_test::wasm_bindgen_test as test;
#[cfg(target_arch = "wasm32")]
use wasm_bindgen_test::wasm_bindgen_test as maybe_tokio_test;
#[cfg(not(target_arch = "wasm32"))]
use tokio::test as maybe_tokio_test;
use tokio::sync::Mutex;
use tokio::time::{interval, timeout};
use tokio_test::task::spawn;
use tokio_test::{assert_pending, assert_ready};
use std::sync::Arc;
use std::time::Duration;
#[test]
fn straight_execution() {
@ -49,10 +55,14 @@ fn readiness() {
assert_ready!(t2.poll());
}
#[tokio::test]
/// Ensure a mutex is unlocked if a future holding the lock
/// is aborted prematurely.
#[tokio::test]
#[cfg(feature = "full")]
async fn aborted_future_1() {
use std::time::Duration;
use tokio::time::{interval, timeout};
let m1: Arc<Mutex<usize>> = Arc::new(Mutex::new(0));
{
let m2 = m1.clone();
@ -75,10 +85,14 @@ async fn aborted_future_1() {
.expect("Mutex is locked");
}
#[tokio::test]
/// This test is similar to `aborted_future_1` but this time the
/// aborted future is waiting for the lock.
#[tokio::test]
#[cfg(feature = "full")]
async fn aborted_future_2() {
use std::time::Duration;
use tokio::time::timeout;
let m1: Arc<Mutex<usize>> = Arc::new(Mutex::new(0));
{
// Lock mutex
@ -114,7 +128,7 @@ fn try_lock_owned() {
assert!(g3.is_ok());
}
#[tokio::test]
#[maybe_tokio_test]
async fn debug_format() {
let s = "debug";
let m = Arc::new(Mutex::new(s.to_string()));

View File

@ -1,5 +1,8 @@
#![warn(rust_2018_idioms)]
#![cfg(feature = "full")]
#![cfg(feature = "sync")]
#[cfg(target_arch = "wasm32")]
use wasm_bindgen_test::wasm_bindgen_test as test;
use tokio::sync::Notify;
use tokio_test::task::spawn;

View File

@ -1,5 +1,13 @@
#![warn(rust_2018_idioms)]
#![cfg(feature = "full")]
#![cfg(feature = "sync")]
#[cfg(target_arch = "wasm32")]
use wasm_bindgen_test::wasm_bindgen_test as test;
#[cfg(target_arch = "wasm32")]
use wasm_bindgen_test::wasm_bindgen_test as maybe_tokio_test;
#[cfg(not(target_arch = "wasm32"))]
use tokio::test as maybe_tokio_test;
use tokio::sync::oneshot;
use tokio::sync::oneshot::error::TryRecvError;
@ -40,7 +48,7 @@ fn send_recv() {
assert_eq!(val, 1);
}
#[tokio::test]
#[maybe_tokio_test]
async fn async_send_recv() {
let (tx, rx) = oneshot::channel();
@ -86,6 +94,7 @@ fn close_rx() {
}
#[tokio::test]
#[cfg(feature = "full")]
async fn async_rx_closed() {
let (mut tx, rx) = oneshot::channel::<()>();
@ -170,6 +179,7 @@ fn explicit_close_try_recv() {
#[test]
#[should_panic]
#[cfg(not(target_arch = "wasm32"))] // wasm currently doesn't support unwinding
fn close_try_recv_poll() {
let (_tx, rx) = oneshot::channel::<i32>();
let mut rx = task::spawn(rx);

View File

@ -1,13 +1,19 @@
#![warn(rust_2018_idioms)]
#![cfg(feature = "sync")]
#[cfg(target_arch = "wasm32")]
use wasm_bindgen_test::wasm_bindgen_test as test;
#[cfg(target_arch = "wasm32")]
use wasm_bindgen_test::wasm_bindgen_test as maybe_tokio_test;
#[cfg(not(target_arch = "wasm32"))]
use tokio::test as maybe_tokio_test;
use std::sync::Arc;
use std::task::Poll;
use futures::future::FutureExt;
use futures::stream;
use futures::stream::StreamExt;
use tokio::sync::{Barrier, RwLock};
use tokio::sync::RwLock;
use tokio_test::task::spawn;
use tokio_test::{assert_pending, assert_ready};
@ -135,7 +141,7 @@ fn write_read_shared_drop_pending() {
}
// Acquire an RwLock nonexclusively by a single task
#[tokio::test]
#[maybe_tokio_test]
async fn read_uncontested() {
let rwlock = RwLock::new(100);
let result = *rwlock.read().await;
@ -144,7 +150,7 @@ async fn read_uncontested() {
}
// Acquire an uncontested RwLock in exclusive mode
#[tokio::test]
#[maybe_tokio_test]
async fn write_uncontested() {
let rwlock = RwLock::new(100);
let mut result = rwlock.write().await;
@ -153,7 +159,7 @@ async fn write_uncontested() {
}
// RwLocks should be acquired in the order that their Futures are waited upon.
#[tokio::test]
#[maybe_tokio_test]
async fn write_order() {
let rwlock = RwLock::<Vec<u32>>::new(vec![]);
let fut2 = rwlock.write().map(|mut guard| guard.push(2));
@ -166,8 +172,13 @@ async fn write_order() {
}
// A single RwLock is contested by tasks in multiple threads
#[cfg(feature = "full")]
#[tokio::test(flavor = "multi_thread", worker_threads = 8)]
async fn multithreaded() {
use futures::stream::{self, StreamExt};
use std::sync::Arc;
use tokio::sync::Barrier;
let barrier = Arc::new(Barrier::new(5));
let rwlock = Arc::new(RwLock::<u32>::new(0));
let rwclone1 = rwlock.clone();
@ -236,7 +247,7 @@ async fn multithreaded() {
assert_eq!(*g, 17_000);
}
#[tokio::test]
#[maybe_tokio_test]
async fn try_write() {
let lock = RwLock::new(0);
let read_guard = lock.read().await;

View File

@ -1,4 +1,7 @@
#![cfg(feature = "full")]
#![cfg(feature = "sync")]
#[cfg(target_arch = "wasm32")]
use wasm_bindgen_test::wasm_bindgen_test as test;
use std::sync::Arc;
use tokio::sync::Semaphore;
@ -23,6 +26,7 @@ fn try_acquire() {
}
#[tokio::test]
#[cfg(feature = "full")]
async fn acquire() {
let sem = Arc::new(Semaphore::new(1));
let p1 = sem.try_acquire().unwrap();
@ -35,6 +39,7 @@ async fn acquire() {
}
#[tokio::test]
#[cfg(feature = "full")]
async fn add_permits() {
let sem = Arc::new(Semaphore::new(0));
let sem_clone = sem.clone();
@ -59,6 +64,7 @@ fn forget() {
}
#[tokio::test]
#[cfg(feature = "full")]
async fn stresstest() {
let sem = Arc::new(Semaphore::new(5));
let mut join_handles = Vec::new();
@ -87,6 +93,7 @@ fn add_max_amount_permits() {
assert_eq!(s.available_permits(), usize::MAX >> 3);
}
#[cfg(not(target_arch = "wasm32"))] // wasm currently doesn't support unwinding
#[test]
#[should_panic]
fn add_more_than_max_amount_permits() {

View File

@ -1,4 +1,7 @@
#![cfg(feature = "full")]
#![cfg(feature = "sync")]
#[cfg(target_arch = "wasm32")]
use wasm_bindgen_test::wasm_bindgen_test as test;
use std::sync::Arc;
use tokio::sync::Semaphore;
@ -33,6 +36,7 @@ fn try_acquire_many() {
}
#[tokio::test]
#[cfg(feature = "full")]
async fn acquire() {
let sem = Arc::new(Semaphore::new(1));
let p1 = sem.clone().try_acquire_owned().unwrap();
@ -45,6 +49,7 @@ async fn acquire() {
}
#[tokio::test]
#[cfg(feature = "full")]
async fn acquire_many() {
let semaphore = Arc::new(Semaphore::new(42));
let permit32 = semaphore.clone().try_acquire_many_owned(32).unwrap();
@ -60,6 +65,7 @@ async fn acquire_many() {
}
#[tokio::test]
#[cfg(feature = "full")]
async fn add_permits() {
let sem = Arc::new(Semaphore::new(0));
let sem_clone = sem.clone();
@ -84,6 +90,7 @@ fn forget() {
}
#[tokio::test]
#[cfg(feature = "full")]
async fn stresstest() {
let sem = Arc::new(Semaphore::new(5));
let mut join_handles = Vec::new();

View File

@ -1,6 +1,9 @@
#![allow(clippy::cognitive_complexity)]
#![warn(rust_2018_idioms)]
#![cfg(feature = "full")]
#![cfg(feature = "sync")]
#[cfg(target_arch = "wasm32")]
use wasm_bindgen_test::wasm_bindgen_test as test;
use tokio::sync::watch;
use tokio_test::task::spawn;

View File

@ -1,3 +1,5 @@
#![cfg(feature = "full")]
tokio::task_local! {
static REQ_ID: u32;
pub static FOO: bool;