From 060cc4e46aedc40b0a44dcbc31deb0df39abdb4e Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Sat, 5 Sep 2026 01:35:22 -0700 Subject: [PATCH] wasm: support the wasm32-unknown-emscripten target (#8281) --- .github/workflows/ci.yml | 55 +++++++++++++++++ spellcheck.dic | 6 +- tokio/Cargo.toml | 14 +++-- tokio/src/blocking.rs | 30 ++++++++++ tokio/src/io/stdio_common.rs | 1 + tokio/src/lib.rs | 72 +++++++++++++++++------ tokio/src/macros/cfg.rs | 42 ++++++++----- tokio/src/runtime/blocking/pool.rs | 14 ++++- tokio/src/runtime/driver.rs | 2 +- tokio/src/runtime/mod.rs | 5 ++ tokio/src/runtime/time/tests/mod.rs | 2 +- tokio/src/sync/tests/atomic_waker.rs | 2 +- tokio/src/sync/tests/notify.rs | 2 +- tokio/src/sync/tests/semaphore_batch.rs | 2 +- tokio/src/task/coop/mod.rs | 2 +- tokio/src/task/local.rs | 2 +- tokio/src/util/idle_notified_set.rs | 2 +- tokio/tests/fs.rs | 14 ++++- tokio/tests/fs_canonicalize_dir.rs | 14 ++++- tokio/tests/fs_copy.rs | 14 ++++- tokio/tests/fs_dir.rs | 14 ++++- tokio/tests/fs_file.rs | 22 ++++++- tokio/tests/fs_link.rs | 18 +++++- tokio/tests/fs_open_options.rs | 14 ++++- tokio/tests/fs_remove_dir_all.rs | 14 ++++- tokio/tests/fs_remove_file.rs | 14 ++++- tokio/tests/fs_rename.rs | 14 ++++- tokio/tests/fs_try_exists.rs | 14 ++++- tokio/tests/fs_write.rs | 14 ++++- tokio/tests/io_async_read.rs | 10 +++- tokio/tests/io_buf_reader.rs | 10 +++- tokio/tests/io_buf_writer.rs | 10 +++- tokio/tests/io_chain.rs | 10 +++- tokio/tests/io_copy.rs | 10 +++- tokio/tests/io_emscripten.rs | 59 +++++++++++++++++++ tokio/tests/io_fill_buf.rs | 11 +++- tokio/tests/io_join.rs | 10 +++- tokio/tests/io_lines.rs | 10 +++- tokio/tests/io_mem_stream.rs | 10 +++- tokio/tests/io_panic.rs | 15 +++-- tokio/tests/io_read.rs | 10 +++- tokio/tests/io_read_buf.rs | 10 +++- tokio/tests/io_read_exact.rs | 10 +++- tokio/tests/io_read_line.rs | 10 +++- tokio/tests/io_read_to_end.rs | 10 +++- tokio/tests/io_read_to_string.rs | 10 +++- tokio/tests/io_read_until.rs | 10 +++- tokio/tests/io_repeat.rs | 10 +++- tokio/tests/io_sink.rs | 10 +++- tokio/tests/io_split.rs | 10 +++- tokio/tests/io_take.rs | 10 +++- tokio/tests/io_util_empty.rs | 10 +++- tokio/tests/io_write.rs | 10 +++- tokio/tests/io_write_all.rs | 10 +++- tokio/tests/io_write_all_buf.rs | 10 +++- tokio/tests/io_write_buf.rs | 10 +++- tokio/tests/io_write_int.rs | 10 +++- tokio/tests/join_handle_panic.rs | 5 +- tokio/tests/macros_join.rs | 6 +- tokio/tests/macros_pin.rs | 4 +- tokio/tests/macros_select.rs | 4 +- tokio/tests/macros_try_join.rs | 4 +- tokio/tests/rt_basic.rs | 20 +++++-- tokio/tests/rt_handle.rs | 5 +- tokio/tests/rt_multi_thread_emscripten.rs | 72 +++++++++++++++++++++++ tokio/tests/rt_panic.rs | 14 ++++- tokio/tests/rt_shutdown_err.rs | 4 +- tokio/tests/rt_time_start_paused.rs | 10 +++- tokio/tests/sync_barrier.rs | 2 +- tokio/tests/sync_broadcast.rs | 4 +- tokio/tests/sync_broadcast_weak.rs | 2 +- tokio/tests/sync_errors.rs | 2 +- tokio/tests/sync_mpsc.rs | 6 +- tokio/tests/sync_mpsc_weak.rs | 2 +- tokio/tests/sync_mutex.rs | 6 +- tokio/tests/sync_mutex_owned.rs | 6 +- tokio/tests/sync_notify.rs | 2 +- tokio/tests/sync_notify_owned.rs | 2 +- tokio/tests/sync_once_cell.rs | 10 +++- tokio/tests/sync_oneshot.rs | 6 +- tokio/tests/sync_panic.rs | 5 +- tokio/tests/sync_rwlock.rs | 6 +- tokio/tests/sync_semaphore.rs | 2 +- tokio/tests/sync_semaphore_owned.rs | 2 +- tokio/tests/sync_set_once.rs | 10 +++- tokio/tests/sync_watch.rs | 2 +- tokio/tests/task_abort.rs | 20 +++++-- tokio/tests/task_emscripten.rs | 12 ++++ tokio/tests/task_id.rs | 28 ++++++--- tokio/tests/task_join_set.rs | 12 +++- tokio/tests/task_local.rs | 8 ++- tokio/tests/task_panic.rs | 10 +++- tokio/tests/task_yield_now.rs | 10 +++- tokio/tests/test_clock.rs | 10 +++- tokio/tests/time_interval.rs | 10 +++- tokio/tests/time_panic.rs | 34 ++++++----- tokio/tests/time_pause.rs | 12 +++- tokio/tests/time_sleep.rs | 10 +++- tokio/tests/time_timeout.rs | 10 +++- tokio/tests/time_wasm.rs | 6 +- tokio/tests/unwindsafe.rs | 8 ++- 101 files changed, 1013 insertions(+), 182 deletions(-) create mode 100644 tokio/tests/io_emscripten.rs create mode 100644 tokio/tests/rt_multi_thread_emscripten.rs create mode 100644 tokio/tests/task_emscripten.rs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3cbe22076..1a4f347ae 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,6 +19,8 @@ env: rust_nightly: nightly-2025-10-12 # Pin a specific miri version rust_miri_nightly: nightly-2026-06-29 + rust_emscripten_nightly: nightly-2026-08-17 + emsdk_version: '6.0.8' rust_clippy: '1.88' # When updating this, also update: # - README.md @@ -1193,6 +1195,59 @@ jobs: RUSTFLAGS: --cfg tokio_unstable CARGO_TARGET_WASM32_WASIP2_RUNNER: wasmtime run -Sinherit-network + wasm32-unknown-emscripten: + name: test tokio for wasm32-unknown-emscripten + needs: basics + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v7 + - name: Install Rust ${{ env.rust_stable }} + uses: dtolnay/rust-toolchain@stable + with: + toolchain: ${{ env.rust_stable }} + targets: wasm32-unknown-emscripten + + - name: Install Emscripten + uses: mymindstorm/setup-emsdk@v14 + with: + version: ${{ env.emsdk_version }} + + - uses: actions/setup-node@v4 + with: + node-version: 26 + + - uses: Swatinem/rust-cache@v2 + + - name: Install cargo-hack + uses: taiki-e/install-action@v2 + with: + tool: cargo-hack + + - name: Check tokio feature matrix for emscripten + run: cargo hack check -p tokio --each-feature --exclude-features full,net,process,signal,rt-multi-thread,io-uring,taskdump,schedule-latency --target wasm32-unknown-emscripten + working-directory: tokio + + - name: Test tokio for emscripten + run: cargo test -p tokio --target wasm32-unknown-emscripten --features "rt,time,sync,macros,fs,io-util,io-std,test-util" --tests + working-directory: tokio + env: + CARGO_TARGET_WASM32_UNKNOWN_EMSCRIPTEN_RUNNER: node + RUSTFLAGS: "-Dwarnings -Clink-args=-sALLOW_MEMORY_GROWTH=1 -Clink-args=-sEXIT_RUNTIME=1 -Clink-args=-sSTACK_SIZE=1048576" + + - name: Install Rust ${{ env.rust_emscripten_nightly }} + uses: dtolnay/rust-toolchain@nightly + with: + toolchain: ${{ env.rust_emscripten_nightly }} + targets: wasm32-unknown-emscripten + components: rust-src + + - name: Test tokio multi-thread runtime for emscripten (pthreads) + run: cargo +${{ env.rust_emscripten_nightly }} test -Zbuild-std=std,panic_abort -p tokio --target wasm32-unknown-emscripten --features "rt,rt-multi-thread,time,sync,macros" --test rt_multi_thread_emscripten + working-directory: tokio + env: + CARGO_TARGET_WASM32_UNKNOWN_EMSCRIPTEN_RUNNER: node + RUSTFLAGS: "-Dwarnings -Ctarget-feature=+atomics,+bulk-memory,+mutable-globals -Clink-args=-pthread -Clink-args=-sPTHREAD_POOL_SIZE=8 -Clink-args=-sINITIAL_MEMORY=134217728 -Clink-args=-sEXIT_RUNTIME=1 -Clink-args=-sSTACK_SIZE=1048576" + check-external-types: name: check-external-types (${{ matrix.os }}) needs: basics diff --git a/spellcheck.dic b/spellcheck.dic index 9d4479334..b0d4535ca 100644 --- a/spellcheck.dic +++ b/spellcheck.dic @@ -1,4 +1,4 @@ -327 +331 & + < @@ -106,6 +106,8 @@ dns DNS DoS dwOpenMode +Emscripten +Emscripten's endian enqueue enqueued @@ -213,6 +215,7 @@ plaintext poller POSIX proxied +pthreads qos RAII RCU @@ -323,6 +326,7 @@ Wakers wakeup wakeups WASI +Wasm watchOS workstealing ZST diff --git a/tokio/Cargo.toml b/tokio/Cargo.toml index e260bbc5b..0cd6fa059 100644 --- a/tokio/Cargo.toml +++ b/tokio/Cargo.toml @@ -101,7 +101,7 @@ bytes = { version = "1.2.1", optional = true } mio = { version = "1.2.0", optional = true, default-features = false } parking_lot = { version = "0.12.0", optional = true } -[target.'cfg(any(not(target_family = "wasm"), all(target_os = "wasi", not(target_env = "p1"))))'.dependencies] +[target.'cfg(any(not(target_family = "wasm"), target_os = "emscripten", all(target_os = "wasi", not(target_env = "p1"))))'.dependencies] socket2 = { version = "0.6.3", optional = true, features = ["all"] } # Currently unstable. The API exposed by these features may be broken at any time. @@ -130,6 +130,8 @@ libc = { version = "0.2.168", optional = true } [target.'cfg(unix)'.dev-dependencies] libc = { version = "0.2.168" } + +[target.'cfg(all(unix, not(target_os = "emscripten")))'.dev-dependencies] nix = { version = "0.31.0", default-features = false, features = ["aio", "fs", "socket"] } [target.'cfg(windows)'.dependencies.windows-sys] @@ -146,22 +148,26 @@ features = [ [dev-dependencies] tokio-test = "0.4.0" tokio-stream = "0.1" -tokio-util = { version = "0.7", features = ["rt"] } futures = { version = "0.3.0", features = ["async-await"] } futures-test = "0.3.31" mockall = "0.13.0" async-stream = "0.3" futures-concurrency = "7.6.3" +[target.'cfg(not(target_os = "emscripten"))'.dev-dependencies] +tokio-util = { version = "0.7", features = ["rt"] } + [target.'cfg(not(target_family = "wasm"))'.dev-dependencies] socket2 = "0.6.0" -tempfile = "3.1.0" proptest = "1" +[target.'cfg(any(not(target_family = "wasm"), target_os = "emscripten"))'.dev-dependencies] +tempfile = "3.1.0" + [target.'cfg(not(all(target_family = "wasm", target_os = "unknown")))'.dev-dependencies] rand = "0.9" -[target.'cfg(all(target_family = "wasm", not(target_os = "wasi")))'.dev-dependencies] +[target.'cfg(all(target_family = "wasm", target_os = "unknown"))'.dev-dependencies] wasm-bindgen-test = "0.3.0" [target.'cfg(target_os = "freebsd")'.dev-dependencies] diff --git a/tokio/src/blocking.rs b/tokio/src/blocking.rs index f172399d5..c02c9363f 100644 --- a/tokio/src/blocking.rs +++ b/tokio/src/blocking.rs @@ -1,12 +1,42 @@ cfg_rt! { + #[cfg(any(not(target_os = "emscripten"), target_feature = "atomics"))] pub(crate) use crate::runtime::spawn_blocking; cfg_fs! { + #[cfg(any(not(target_os = "emscripten"), target_feature = "atomics"))] #[allow(unused_imports)] pub(crate) use crate::runtime::spawn_mandatory_blocking; } + #[cfg(any(not(target_os = "emscripten"), target_feature = "atomics"))] pub(crate) use crate::task::JoinHandle; + + // Non-pthread emscripten has no blocking pool, and the `std` calls behind + // `fs` and `io-std` complete synchronously there, so this internal shim + // runs the closure inline and hands back an already-completed future. The + // public `task::spawn_blocking` is not routed through here and keeps its + // native semantics. Pthread builds (`+atomics`) use the native pool. + #[cfg(all(target_os = "emscripten", not(target_feature = "atomics")))] + pub(crate) type JoinHandle = std::future::Ready>; + + #[cfg(all(target_os = "emscripten", not(target_feature = "atomics")))] + pub(crate) fn spawn_blocking(f: F) -> JoinHandle + where + F: FnOnce() -> R + Send + 'static, + R: Send + 'static, + { + std::future::ready(Ok(f())) + } + + #[cfg(all(target_os = "emscripten", not(target_feature = "atomics"), feature = "fs"))] + #[allow(dead_code)] // unit tests replace this with the `fs::mocks` version + pub(crate) fn spawn_mandatory_blocking(f: F) -> Option> + where + F: FnOnce() -> R + Send + 'static, + R: Send + 'static, + { + Some(spawn_blocking(f)) + } } cfg_not_rt! { diff --git a/tokio/src/io/stdio_common.rs b/tokio/src/io/stdio_common.rs index 72fd97d91..902bf619c 100644 --- a/tokio/src/io/stdio_common.rs +++ b/tokio/src/io/stdio_common.rs @@ -108,6 +108,7 @@ where #[cfg(test)] #[cfg(not(loom))] +#[cfg(not(target_os = "emscripten"))] mod tests { use crate::io::blocking::DEFAULT_MAX_BUF_SIZE; use crate::io::AsyncWriteExt; diff --git a/tokio/src/lib.rs b/tokio/src/lib.rs index e62aab506..1dcffd2e1 100644 --- a/tokio/src/lib.rs +++ b/tokio/src/lib.rs @@ -424,8 +424,11 @@ //! //! ## `WASM` support //! -//! Tokio has some limited support for the `WASM` platform. Without the -//! `tokio_unstable` flag, the following features are supported: +//! Tokio has some limited support for Wasm platforms. +//! +//! Many of Tokio's feature flags are restricted on Wasm, and unsupported +//! combinations of feature flags will fail to build. However, all Wasm targets +//! can be built with the following features: //! //! * `sync` //! * `macros` @@ -434,26 +437,45 @@ //! * `time` //! //! Enabling any other feature (including `full`) will cause a compilation -//! failure. +//! failure. Furthermore, some operations available under these feature flags +//! may panic if they are unsupported. For example: //! -//! The `time` module will only work on `WASM` platforms that have support for -//! timers (e.g. wasm32-wasi). The timing functions will panic if used on a `WASM` -//! platform that does not support timers. +//! * Using timers will panic on Wasm targets that do not support blocking the +//! thread. +//! * If the runtime becomes indefinitely idle (e.g., the program triggers a +//! deadlock), then this will panic on most Wasm targets. +//! * Operations such as `spawn_blocking` that involve spawning threads will +//! panic on Wasm targets that do not support threads. //! -//! Note also that if the runtime becomes indefinitely idle, it will panic -//! immediately instead of blocking forever. On platforms that don't support -//! time, this means that the runtime can never be idle in any way. +//! All Wasm targets are still experimental, and breaking behavior changes can +//! occur in an effort to make Tokio use native Wasm operations. For instance, +//! the behavior of timers could be changed from panicking or blocking the +//! thread to starting a JavaScript timer. As another example, the +//! `spawn_blocking` method could be changed from starting a new thread to +//! creating a new cooperatively scheduled context of execution, if the Wasm +//! target supports such contexts. As a third example, the `#[tokio::main]` or +//! `#[tokio::test]` macros could be changed to work better with the Wasm +//! environment. //! -//! ## Unstable `WASM` support +//! ### `WASI` support //! -//! Tokio also has unstable support for some additional `WASM` features. This -//! requires the use of the `tokio_unstable` flag. +//! The `wasm32-wasip1` and `wasm32-wasip2` targets support the above features. +//! Timers work correctly as blocking the thread is supported. //! -//! Using this flag enables the use of `tokio::net` on the wasm32-wasi target. -//! However, not all methods are available on the networking types as `WASI` -//! currently does not support the creation of new sockets from within `WASM`. -//! Because of this, sockets must currently be created via the `FromRawFd` -//! trait. +//! Under the `tokio_unstable` flag, these targets support the use +//! of `tokio::net`. On `wasm32-wasip1`, not all methods are available on the +//! networking types as this target does not support the creation of new +//! sockets from within `WASM`. Because of this, sockets must currently be +//! created via the `FromRawFd` trait on `wasm32-wasip1`. The `wasm32-wasip2` +//! target does not have this limitation. +//! +//! ### Emscripten support +//! +//! The `wasm32-unknown-emscripten` target supports the single-threaded runtime +//! with the `rt`, `time`, `sync`, `macros`, `fs`, `io-util`, `io-std`, and +//! `test-util` features. The `rt-multi-thread` feature is additionally +//! supported when building with Emscripten pthreads (`-pthread`). The `net`, +//! `process`, and `signal` features are not supported. // Test that pointer width is compatible. This asserts that e.g. usize is at // least 32 bits, which a lot of components in Tokio currently assumes. @@ -467,6 +489,7 @@ compile_error! { #[cfg(all( not(tokio_unstable), target_family = "wasm", + not(target_os = "emscripten"), any( feature = "fs", feature = "io-std", @@ -478,6 +501,21 @@ compile_error! { ))] compile_error!("Only features sync,macros,io-util,rt,time are supported on wasm."); +#[cfg(all( + target_os = "emscripten", + any(feature = "net", feature = "process", feature = "signal") +))] +compile_error!("Features net,process,signal are not supported on wasm32-unknown-emscripten."); + +#[cfg(all( + target_os = "emscripten", + feature = "rt-multi-thread", + not(target_feature = "atomics") +))] +compile_error!( + "The `rt-multi-thread` feature on wasm32-unknown-emscripten requires pthreads support (build with `-pthread`)." +); + #[cfg(all( tokio_unstable, feature = "taskdump", diff --git a/tokio/src/macros/cfg.rs b/tokio/src/macros/cfg.rs index 76165a508..8c6ec4ea6 100644 --- a/tokio/src/macros/cfg.rs +++ b/tokio/src/macros/cfg.rs @@ -398,6 +398,7 @@ macro_rules! cfg_process { #[cfg_attr(docsrs, doc(cfg(feature = "process")))] #[cfg(not(loom))] #[cfg(not(target_os = "wasi"))] + #[cfg(not(target_os = "emscripten"))] $item )* } @@ -405,16 +406,29 @@ macro_rules! cfg_process { macro_rules! cfg_process_driver { ($($item:item)*) => { - #[cfg(unix)] - #[cfg(not(loom))] - cfg_process! { $($item)* } + $( + #[cfg(all( + unix, + not(loom), + feature = "process", + not(target_os = "wasi"), + not(target_os = "emscripten"), + ))] + $item + )* } } macro_rules! cfg_not_process_driver { ($($item:item)*) => { $( - #[cfg(not(all(unix, not(loom), feature = "process")))] + #[cfg(not(all( + unix, + not(loom), + feature = "process", + not(target_os = "wasi"), + not(target_os = "emscripten"), + )))] $item )* } @@ -427,6 +441,7 @@ macro_rules! cfg_signal { #[cfg_attr(docsrs, doc(cfg(feature = "signal")))] #[cfg(not(loom))] #[cfg(not(target_os = "wasi"))] + #[cfg(not(target_os = "emscripten"))] $item )* } @@ -437,6 +452,7 @@ macro_rules! cfg_signal_internal { $( #[cfg(any(feature = "signal", all(unix, feature = "process")))] #[cfg(not(loom))] + #[cfg(not(target_os = "emscripten"))] $item )* } @@ -449,10 +465,15 @@ macro_rules! cfg_signal_internal_and_unix { } } -macro_rules! cfg_not_signal_internal { +macro_rules! cfg_not_signal_internal_and_unix { ($($item:item)*) => { $( - #[cfg(any(loom, not(unix), not(any(feature = "signal", all(unix, feature = "process")))))] + #[cfg(not(all( + unix, + any(feature = "signal", all(unix, feature = "process")), + not(loom), + not(target_os = "emscripten"), + )))] $item )* } @@ -712,15 +733,6 @@ macro_rules! cfg_not_wasip1 { } } -macro_rules! cfg_is_wasm_not_wasi { - ($($item:item)*) => { - $( - #[cfg(all(target_family = "wasm", not(target_os = "wasi")))] - $item - )* - } -} - /// Use this macro to provide two different implementations of the same API — one for stable /// builds and one for unstable builds. macro_rules! cfg_metrics_variant { diff --git a/tokio/src/runtime/blocking/pool.rs b/tokio/src/runtime/blocking/pool.rs index 5507bf136..eb18dc6e5 100644 --- a/tokio/src/runtime/blocking/pool.rs +++ b/tokio/src/runtime/blocking/pool.rs @@ -182,7 +182,13 @@ pub(crate) struct Task { #[derive(PartialEq, Eq)] pub(crate) enum Mandatory { - #[cfg_attr(not(feature = "fs"), allow(dead_code))] + #[cfg_attr( + any( + not(feature = "fs"), + all(target_os = "emscripten", not(target_feature = "atomics")) + ), + allow(dead_code) + )] Mandatory, NonMandatory, } @@ -246,7 +252,8 @@ where cfg_fs! { #[cfg_attr(any( all(loom, not(test)), // the function is covered by loom tests - test + test, + all(target_os = "emscripten", not(target_feature = "atomics")), // fs uses the inline shim ), allow(dead_code))] /// Runs the provided function on an executor dedicated to blocking /// operations. Tasks will be scheduled as mandatory, meaning they are @@ -385,7 +392,8 @@ impl Spawner { #[track_caller] #[cfg_attr(any( all(loom, not(test)), // the function is covered by loom tests - test + test, + all(target_os = "emscripten", not(target_feature = "atomics")), // fs uses the inline shim ), allow(dead_code))] pub(crate) fn spawn_mandatory_blocking(&self, rt: &Handle, func: F) -> Option> where diff --git a/tokio/src/runtime/driver.rs b/tokio/src/runtime/driver.rs index 92b2350db..35bfe0262 100644 --- a/tokio/src/runtime/driver.rs +++ b/tokio/src/runtime/driver.rs @@ -251,7 +251,7 @@ cfg_signal_internal_and_unix! { } } -cfg_not_signal_internal! { +cfg_not_signal_internal_and_unix! { pub(crate) type SignalHandle = (); cfg_io_driver! { diff --git a/tokio/src/runtime/mod.rs b/tokio/src/runtime/mod.rs index 05bb5fa6e..ab99219cc 100644 --- a/tokio/src/runtime/mod.rs +++ b/tokio/src/runtime/mod.rs @@ -550,6 +550,11 @@ cfg_rt! { } cfg_fs! { + // Non-pthread emscripten uses the inline shim in `crate::blocking`. + #[cfg_attr( + all(target_os = "emscripten", not(target_feature = "atomics")), + allow(unused_imports) + )] pub(crate) use blocking::spawn_mandatory_blocking; } diff --git a/tokio/src/runtime/time/tests/mod.rs b/tokio/src/runtime/time/tests/mod.rs index 84c765af6..0773f91c1 100644 --- a/tokio/src/runtime/time/tests/mod.rs +++ b/tokio/src/runtime/time/tests/mod.rs @@ -1,4 +1,4 @@ -#![cfg(not(target_os = "wasi"))] +#![cfg(all(not(target_os = "wasi"), not(target_os = "emscripten")))] use std::{task::Context, time::Duration}; diff --git a/tokio/src/sync/tests/atomic_waker.rs b/tokio/src/sync/tests/atomic_waker.rs index b182574f3..8c5e1a113 100644 --- a/tokio/src/sync/tests/atomic_waker.rs +++ b/tokio/src/sync/tests/atomic_waker.rs @@ -15,7 +15,7 @@ impl AssertSync for AtomicWaker {} impl AssertSend for Waker {} impl AssertSync for Waker {} -#[cfg(all(target_family = "wasm", not(target_os = "wasi")))] +#[cfg(all(target_family = "wasm", target_os = "unknown"))] use wasm_bindgen_test::wasm_bindgen_test as test; #[test] diff --git a/tokio/src/sync/tests/notify.rs b/tokio/src/sync/tests/notify.rs index 540aa2244..bfbc6f486 100644 --- a/tokio/src/sync/tests/notify.rs +++ b/tokio/src/sync/tests/notify.rs @@ -3,7 +3,7 @@ use std::future::Future; use std::sync::Arc; use std::task::{Context, RawWaker, RawWakerVTable, Waker}; -#[cfg(all(target_family = "wasm", not(target_os = "wasi")))] +#[cfg(all(target_family = "wasm", target_os = "unknown"))] use wasm_bindgen_test::wasm_bindgen_test as test; #[test] diff --git a/tokio/src/sync/tests/semaphore_batch.rs b/tokio/src/sync/tests/semaphore_batch.rs index fb5e8fdd6..84f062d8f 100644 --- a/tokio/src/sync/tests/semaphore_batch.rs +++ b/tokio/src/sync/tests/semaphore_batch.rs @@ -3,7 +3,7 @@ use tokio_test::*; const MAX_PERMITS: usize = crate::sync::Semaphore::MAX_PERMITS; -#[cfg(all(target_family = "wasm", not(target_os = "wasi")))] +#[cfg(all(target_family = "wasm", target_os = "unknown"))] use wasm_bindgen_test::wasm_bindgen_test as test; #[test] diff --git a/tokio/src/task/coop/mod.rs b/tokio/src/task/coop/mod.rs index 4a520e6f5..5b9ebbd9e 100644 --- a/tokio/src/task/coop/mod.rs +++ b/tokio/src/task/coop/mod.rs @@ -496,7 +496,7 @@ cfg_coop! { mod test { use super::*; - #[cfg(all(target_family = "wasm", not(target_os = "wasi")))] + #[cfg(all(target_family = "wasm", target_os = "unknown"))] use wasm_bindgen_test::wasm_bindgen_test as test; fn get() -> Budget { diff --git a/tokio/src/task/local.rs b/tokio/src/task/local.rs index 4d467d0fb..a447a1849 100644 --- a/tokio/src/task/local.rs +++ b/tokio/src/task/local.rs @@ -1276,7 +1276,7 @@ impl LocalState { // ensure they are on the same thread that owns the `LocalSet`. unsafe impl Send for LocalState {} -#[cfg(all(test, not(loom)))] +#[cfg(all(test, not(loom), not(target_os = "emscripten")))] mod tests { use super::*; diff --git a/tokio/src/util/idle_notified_set.rs b/tokio/src/util/idle_notified_set.rs index 4c5177c56..3d9e7dd2b 100644 --- a/tokio/src/util/idle_notified_set.rs +++ b/tokio/src/util/idle_notified_set.rs @@ -492,7 +492,7 @@ unsafe impl linked_list::Link for ListEntry { } } -#[cfg(all(test, not(loom)))] +#[cfg(all(test, not(loom), not(target_os = "emscripten")))] mod tests { use crate::runtime::Builder; use crate::task::JoinSet; diff --git a/tokio/tests/fs.rs b/tokio/tests/fs.rs index f5fb193f4..30d8690a5 100644 --- a/tokio/tests/fs.rs +++ b/tokio/tests/fs.rs @@ -1,5 +1,13 @@ #![warn(rust_2018_idioms)] -#![cfg(all(feature = "full", not(target_os = "wasi")))] // Wasi does not support file operations +#![cfg(any( + all(feature = "full", not(target_os = "wasi")), // Wasi does not support file operations + all( + target_os = "emscripten", + feature = "rt", + feature = "macros", + feature = "fs" + ) +))] use tokio::fs; use tokio_test::assert_ok; @@ -16,6 +24,10 @@ async fn path_read_write() { } #[tokio::test] +#[cfg_attr( + target_os = "emscripten", + ignore = "emscripten libc does not implement dup()/try_clone()" +)] async fn try_clone_should_preserve_max_buf_size() { let buf_size = 128; let temp = tempdir(); diff --git a/tokio/tests/fs_canonicalize_dir.rs b/tokio/tests/fs_canonicalize_dir.rs index e7f6c68ea..9f4d6d94a 100644 --- a/tokio/tests/fs_canonicalize_dir.rs +++ b/tokio/tests/fs_canonicalize_dir.rs @@ -1,5 +1,17 @@ #![warn(rust_2018_idioms)] -#![cfg(all(feature = "full", not(target_os = "wasi")))] // WASI does not support all fs operations +#![cfg(all( + any( + feature = "full", + all( + target_os = "emscripten", + feature = "fs", + feature = "macros", + feature = "rt", + feature = "io-util" + ) + ), + not(target_os = "wasi") +))] // WASI does not support all fs operations use tokio::fs; diff --git a/tokio/tests/fs_copy.rs b/tokio/tests/fs_copy.rs index fac64dccd..ddf4c2bc5 100644 --- a/tokio/tests/fs_copy.rs +++ b/tokio/tests/fs_copy.rs @@ -1,5 +1,17 @@ #![warn(rust_2018_idioms)] -#![cfg(all(feature = "full", not(target_os = "wasi")))] // WASI does not support all fs operations +#![cfg(all( + any( + feature = "full", + all( + target_os = "emscripten", + feature = "fs", + feature = "macros", + feature = "rt", + feature = "io-util" + ) + ), + not(target_os = "wasi") +))] // WASI does not support all fs operations use tempfile::tempdir; use tokio::fs; diff --git a/tokio/tests/fs_dir.rs b/tokio/tests/fs_dir.rs index 3f28c1a07..f11ef0364 100644 --- a/tokio/tests/fs_dir.rs +++ b/tokio/tests/fs_dir.rs @@ -1,5 +1,17 @@ #![warn(rust_2018_idioms)] -#![cfg(all(feature = "full", not(target_os = "wasi")))] // WASI does not support all fs operations +#![cfg(all( + any( + feature = "full", + all( + target_os = "emscripten", + feature = "fs", + feature = "macros", + feature = "rt", + feature = "io-util" + ) + ), + not(target_os = "wasi") +))] // WASI does not support all fs operations use tokio::fs; use tokio_test::{assert_err, assert_ok}; diff --git a/tokio/tests/fs_file.rs b/tokio/tests/fs_file.rs index e5bc0bd87..ea4b104a5 100644 --- a/tokio/tests/fs_file.rs +++ b/tokio/tests/fs_file.rs @@ -1,5 +1,17 @@ #![warn(rust_2018_idioms)] -#![cfg(all(feature = "full", not(target_os = "wasi")))] // WASI does not support all fs operations +#![cfg(all( + any( + feature = "full", + all( + target_os = "emscripten", + feature = "fs", + feature = "macros", + feature = "rt", + feature = "io-util" + ) + ), + not(target_os = "wasi") +))] // WASI does not support all fs operations use futures::future::FutureExt; use std::io::prelude::*; @@ -99,6 +111,10 @@ async fn rewind_seek_position() { } #[tokio::test] +#[cfg_attr( + target_os = "emscripten", + ignore = "inline-fs shim does not insert cooperative yield points" +)] async fn coop() { let mut tempfile = tempfile(); tempfile.write_all(HELLO).unwrap(); @@ -124,6 +140,10 @@ async fn coop() { } #[tokio::test] +#[cfg_attr( + target_os = "emscripten", + ignore = "emscripten libc does not implement dup()/try_clone()" +)] async fn write_to_clone() { let tempfile = tempfile(); diff --git a/tokio/tests/fs_link.rs b/tokio/tests/fs_link.rs index ef143678b..7bb854175 100644 --- a/tokio/tests/fs_link.rs +++ b/tokio/tests/fs_link.rs @@ -1,5 +1,17 @@ #![warn(rust_2018_idioms)] -#![cfg(all(feature = "full", not(target_os = "wasi")))] // WASI does not support all fs operations +#![cfg(all( + any( + feature = "full", + all( + target_os = "emscripten", + feature = "fs", + feature = "macros", + feature = "rt", + feature = "io-util" + ) + ), + not(target_os = "wasi") +))] // WASI does not support all fs operations use tokio::fs; @@ -8,6 +20,7 @@ use tempfile::tempdir; #[tokio::test] #[cfg_attr(miri, ignore)] // No `linkat` in miri. +#[cfg_attr(target_os = "emscripten", ignore = "MEMFS rejects link() with EMLINK")] async fn test_hard_link() { let dir = tempdir().unwrap(); let src = dir.path().join("src.txt"); @@ -63,6 +76,7 @@ async fn test_symlink() { #[tokio::test] #[cfg_attr(miri, ignore)] // No `linkat` in miri. +#[cfg_attr(target_os = "emscripten", ignore = "MEMFS rejects link() with EMLINK")] async fn test_hard_link_error_source_not_found() { let dir = tempdir().unwrap(); let src = dir.path().join("nonexistent.txt"); @@ -72,6 +86,7 @@ async fn test_hard_link_error_source_not_found() { assert_eq!(err.kind(), std::io::ErrorKind::NotFound); } +// On emscripten MEMFS reports EEXIST before its unconditional link() EMLINK. #[tokio::test] #[cfg_attr(miri, ignore)] // No `linkat` in miri. async fn test_hard_link_error_destination_already_exists() { @@ -92,6 +107,7 @@ async fn test_hard_link_error_destination_already_exists() { #[tokio::test] #[cfg_attr(miri, ignore)] // No `linkat` in miri. +#[cfg_attr(target_os = "emscripten", ignore = "MEMFS rejects link() with EMLINK")] async fn test_hard_link_error_source_is_directory() { let dir = tempdir().unwrap(); let src_dir = dir.path().join("src_directory"); diff --git a/tokio/tests/fs_open_options.rs b/tokio/tests/fs_open_options.rs index 58982d679..957cdd333 100644 --- a/tokio/tests/fs_open_options.rs +++ b/tokio/tests/fs_open_options.rs @@ -1,5 +1,17 @@ #![warn(rust_2018_idioms)] -#![cfg(all(feature = "full", not(target_os = "wasi")))] // WASI does not support all fs operations +#![cfg(all( + any( + feature = "full", + all( + target_os = "emscripten", + feature = "fs", + feature = "macros", + feature = "rt", + feature = "io-util" + ) + ), + not(target_os = "wasi") +))] // WASI does not support all fs operations use std::io::Write; use tempfile::NamedTempFile; diff --git a/tokio/tests/fs_remove_dir_all.rs b/tokio/tests/fs_remove_dir_all.rs index 5c71bdfda..996b6ee5e 100644 --- a/tokio/tests/fs_remove_dir_all.rs +++ b/tokio/tests/fs_remove_dir_all.rs @@ -1,5 +1,17 @@ #![warn(rust_2018_idioms)] -#![cfg(all(feature = "full", not(target_os = "wasi")))] // WASI does not support all fs operations +#![cfg(all( + any( + feature = "full", + all( + target_os = "emscripten", + feature = "fs", + feature = "macros", + feature = "rt", + feature = "io-util" + ) + ), + not(target_os = "wasi") +))] // WASI does not support all fs operations use tempfile::tempdir; use tokio::fs; diff --git a/tokio/tests/fs_remove_file.rs b/tokio/tests/fs_remove_file.rs index ea4772139..9d584532e 100644 --- a/tokio/tests/fs_remove_file.rs +++ b/tokio/tests/fs_remove_file.rs @@ -1,5 +1,17 @@ #![warn(rust_2018_idioms)] -#![cfg(all(feature = "full", not(target_os = "wasi")))] // WASI does not support all fs operations +#![cfg(all( + any( + feature = "full", + all( + target_os = "emscripten", + feature = "fs", + feature = "macros", + feature = "rt", + feature = "io-util" + ) + ), + not(target_os = "wasi") +))] // WASI does not support all fs operations use tempfile::tempdir; use tokio::fs; diff --git a/tokio/tests/fs_rename.rs b/tokio/tests/fs_rename.rs index 91bb39ee3..01041c191 100644 --- a/tokio/tests/fs_rename.rs +++ b/tokio/tests/fs_rename.rs @@ -1,5 +1,17 @@ #![warn(rust_2018_idioms)] -#![cfg(all(feature = "full", not(target_os = "wasi")))] // WASI does not support all fs operations +#![cfg(all( + any( + feature = "full", + all( + target_os = "emscripten", + feature = "fs", + feature = "macros", + feature = "rt", + feature = "io-util" + ) + ), + not(target_os = "wasi") +))] // WASI does not support all fs operations use tempfile::tempdir; use tokio::fs; diff --git a/tokio/tests/fs_try_exists.rs b/tokio/tests/fs_try_exists.rs index 5e698cf18..9e11bb963 100644 --- a/tokio/tests/fs_try_exists.rs +++ b/tokio/tests/fs_try_exists.rs @@ -1,5 +1,17 @@ #![warn(rust_2018_idioms)] -#![cfg(all(feature = "full", not(target_os = "wasi")))] // WASI does not support all fs operations +#![cfg(all( + any( + feature = "full", + all( + target_os = "emscripten", + feature = "fs", + feature = "macros", + feature = "rt", + feature = "io-util" + ) + ), + not(target_os = "wasi") +))] // WASI does not support all fs operations use tempfile::tempdir; use tokio::fs; diff --git a/tokio/tests/fs_write.rs b/tokio/tests/fs_write.rs index a125e0408..dae2d7ba8 100644 --- a/tokio/tests/fs_write.rs +++ b/tokio/tests/fs_write.rs @@ -1,5 +1,17 @@ #![warn(rust_2018_idioms)] -#![cfg(all(feature = "full", not(target_os = "wasi")))] // WASI does not support all fs operations +#![cfg(all( + any( + feature = "full", + all( + target_os = "emscripten", + feature = "fs", + feature = "macros", + feature = "rt", + feature = "io-util" + ) + ), + not(target_os = "wasi") +))] // WASI does not support all fs operations use tempfile::tempdir; use tokio::fs; diff --git a/tokio/tests/io_async_read.rs b/tokio/tests/io_async_read.rs index aaeadfa4c..8fe8ca013 100644 --- a/tokio/tests/io_async_read.rs +++ b/tokio/tests/io_async_read.rs @@ -1,5 +1,13 @@ #![warn(rust_2018_idioms)] -#![cfg(feature = "full")] +#![cfg(any( + feature = "full", + all( + target_os = "emscripten", + feature = "rt", + feature = "macros", + feature = "io-util" + ) +))] use tokio::io::AsyncRead; diff --git a/tokio/tests/io_buf_reader.rs b/tokio/tests/io_buf_reader.rs index 0d3f6bafc..2e69b1ce2 100644 --- a/tokio/tests/io_buf_reader.rs +++ b/tokio/tests/io_buf_reader.rs @@ -1,5 +1,13 @@ #![warn(rust_2018_idioms)] -#![cfg(feature = "full")] +#![cfg(any( + feature = "full", + all( + target_os = "emscripten", + feature = "rt", + feature = "macros", + feature = "io-util" + ) +))] // https://github.com/rust-lang/futures-rs/blob/1803948ff091b4eabf7f3bf39e16bbbdefca5cc8/futures/tests/io_buf_reader.rs diff --git a/tokio/tests/io_buf_writer.rs b/tokio/tests/io_buf_writer.rs index d3acf62c7..8b4491ac0 100644 --- a/tokio/tests/io_buf_writer.rs +++ b/tokio/tests/io_buf_writer.rs @@ -1,5 +1,13 @@ #![warn(rust_2018_idioms)] -#![cfg(feature = "full")] +#![cfg(any( + feature = "full", + all( + target_os = "emscripten", + feature = "rt", + feature = "macros", + feature = "io-util" + ) +))] // https://github.com/rust-lang/futures-rs/blob/1803948ff091b4eabf7f3bf39e16bbbdefca5cc8/futures/tests/io_buf_writer.rs diff --git a/tokio/tests/io_chain.rs b/tokio/tests/io_chain.rs index 70398295b..23574fb00 100644 --- a/tokio/tests/io_chain.rs +++ b/tokio/tests/io_chain.rs @@ -1,5 +1,13 @@ #![warn(rust_2018_idioms)] -#![cfg(feature = "full")] +#![cfg(any( + feature = "full", + all( + target_os = "emscripten", + feature = "rt", + feature = "macros", + feature = "io-util" + ) +))] use tokio::io::AsyncReadExt; use tokio_test::assert_ok; diff --git a/tokio/tests/io_copy.rs b/tokio/tests/io_copy.rs index 3bde8e7fa..931d7edfa 100644 --- a/tokio/tests/io_copy.rs +++ b/tokio/tests/io_copy.rs @@ -1,5 +1,13 @@ #![warn(rust_2018_idioms)] -#![cfg(feature = "full")] +#![cfg(any( + feature = "full", + all( + target_os = "emscripten", + feature = "rt", + feature = "macros", + feature = "io-util" + ) +))] use bytes::BytesMut; use tokio::io::{self, AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt, ReadBuf}; diff --git a/tokio/tests/io_emscripten.rs b/tokio/tests/io_emscripten.rs new file mode 100644 index 000000000..a4971d418 --- /dev/null +++ b/tokio/tests/io_emscripten.rs @@ -0,0 +1,59 @@ +//! Standard I/O tests for emscripten. +//! +//! `tokio::io::{stdout, stderr}` round through emscripten's libc to the JS +//! `print`/`printErr` hooks; these tests mostly check that writes don't fail — +//! observable output verification is left to manual `--nocapture` runs. +//! +//! `tokio::io::stdin` reads fd 0 synchronously in emscripten, so this only +//! completes when stdin is non-interactive (EOF), as under CI where +//! the runner's stdin is `/dev/null`. The contract worth pinning is "a stdin +//! read returns rather than deadlocking", not a specific errno. + +#![cfg(all(target_os = "emscripten", feature = "io-std"))] + +use tokio::io::{AsyncReadExt, AsyncWriteExt}; + +#[tokio::test] +async fn stdout_write_completes() { + let mut out = tokio::io::stdout(); + out.write_all(b"hello from stdout\n").await.unwrap(); + out.flush().await.unwrap(); +} + +#[tokio::test] +async fn stderr_write_completes() { + let mut err = tokio::io::stderr(); + err.write_all(b"hello from stderr\n").await.unwrap(); + err.flush().await.unwrap(); +} + +#[tokio::test] +async fn stdout_large_multichunk_write_completes() { + // Exercises the BufWriter chunking inside `Stdout` (writes larger than + // the internal buffer force multiple underlying writes). + let mut out = tokio::io::stdout(); + let data = vec![b'x'; 64 * 1024]; + out.write_all(&data).await.unwrap(); + out.flush().await.unwrap(); +} + +#[tokio::test] +async fn stdout_interleaved_writes_complete() { + let mut out = tokio::io::stdout(); + for i in 0..16 { + out.write_all(format!("line {i}\n").as_bytes()) + .await + .unwrap(); + } + out.flush().await.unwrap(); +} + +#[tokio::test] +async fn stdin_read_does_not_hang() { + // The runner detaches stdin onto the null device, so a read must return + // promptly (Ok(0) EOF or an I/O error) rather than blocking the host + // loop. The runner's watchdog fails the test if this ever deadlocks. + let mut stdin = tokio::io::stdin(); + let mut buf = [0u8; 32]; + let _ = stdin.read(&mut buf).await; +} diff --git a/tokio/tests/io_fill_buf.rs b/tokio/tests/io_fill_buf.rs index 534417c85..7cf44cdcc 100644 --- a/tokio/tests/io_fill_buf.rs +++ b/tokio/tests/io_fill_buf.rs @@ -1,5 +1,14 @@ #![warn(rust_2018_idioms)] -#![cfg(all(feature = "full", not(target_os = "wasi")))] // Wasi does not support file operations +#![cfg(any( + all(feature = "full", not(target_os = "wasi")), + all( + target_os = "emscripten", + feature = "rt", + feature = "macros", + feature = "io-util", + feature = "fs" + ) +))] use tempfile::NamedTempFile; use tokio::fs::File; diff --git a/tokio/tests/io_join.rs b/tokio/tests/io_join.rs index 9b9f1e5ae..7f7539863 100644 --- a/tokio/tests/io_join.rs +++ b/tokio/tests/io_join.rs @@ -1,5 +1,13 @@ #![warn(rust_2018_idioms)] -#![cfg(feature = "full")] +#![cfg(any( + feature = "full", + all( + target_os = "emscripten", + feature = "rt", + feature = "macros", + feature = "io-util" + ) +))] use tokio::io::{join, AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt, Join, ReadBuf}; diff --git a/tokio/tests/io_lines.rs b/tokio/tests/io_lines.rs index 56fd27bea..20a441a2a 100644 --- a/tokio/tests/io_lines.rs +++ b/tokio/tests/io_lines.rs @@ -1,5 +1,13 @@ #![warn(rust_2018_idioms)] -#![cfg(feature = "full")] +#![cfg(any( + feature = "full", + all( + target_os = "emscripten", + feature = "rt", + feature = "macros", + feature = "io-util" + ) +))] use std::io::{Error, ErrorKind}; use std::string::FromUtf8Error; diff --git a/tokio/tests/io_mem_stream.rs b/tokio/tests/io_mem_stream.rs index 9c4304203..b5965697c 100644 --- a/tokio/tests/io_mem_stream.rs +++ b/tokio/tests/io_mem_stream.rs @@ -1,5 +1,13 @@ #![warn(rust_2018_idioms)] -#![cfg(feature = "full")] +#![cfg(any( + feature = "full", + all( + target_os = "emscripten", + feature = "rt", + feature = "macros", + feature = "io-util" + ) +))] use futures::FutureExt; use std::io::IoSlice; diff --git a/tokio/tests/io_panic.rs b/tokio/tests/io_panic.rs index 6189ecf9a..d64f14f52 100644 --- a/tokio/tests/io_panic.rs +++ b/tokio/tests/io_panic.rs @@ -1,5 +1,8 @@ #![warn(rust_2018_idioms)] -#![cfg(all(feature = "full", not(target_os = "wasi")))] // Wasi does not support panic recovery +#![cfg(any( + all(feature = "full", not(target_os = "wasi")), // Wasi does not support panic recovery + all(target_os = "emscripten", feature = "io-util") +))] #![cfg(panic = "unwind")] use std::task::{Context, Poll}; @@ -42,7 +45,7 @@ impl AsyncWrite for RW { } } -#[cfg(unix)] +#[cfg(all(unix, not(target_os = "emscripten")))] mod unix { use std::os::unix::prelude::{AsRawFd, RawFd}; @@ -168,7 +171,7 @@ fn new_unsplit_zero_capacity_panic_caller() -> Result<(), Box> { } #[test] -#[cfg(unix)] +#[cfg(all(unix, not(target_os = "emscripten")))] fn async_fd_new_panic_caller() -> Result<(), Box> { use tokio::io::unix::AsyncFd; use tokio::runtime::Builder; @@ -190,7 +193,7 @@ fn async_fd_new_panic_caller() -> Result<(), Box> { } #[test] -#[cfg(unix)] +#[cfg(all(unix, not(target_os = "emscripten")))] fn async_fd_with_interest_panic_caller() -> Result<(), Box> { use tokio::io::unix::AsyncFd; use tokio::io::Interest; @@ -213,7 +216,7 @@ fn async_fd_with_interest_panic_caller() -> Result<(), Box> { } #[test] -#[cfg(unix)] +#[cfg(all(unix, not(target_os = "emscripten")))] fn async_fd_try_new_panic_caller() -> Result<(), Box> { use tokio::io::unix::AsyncFd; use tokio::runtime::Builder; @@ -235,7 +238,7 @@ fn async_fd_try_new_panic_caller() -> Result<(), Box> { } #[test] -#[cfg(unix)] +#[cfg(all(unix, not(target_os = "emscripten")))] fn async_fd_try_with_interest_panic_caller() -> Result<(), Box> { use tokio::io::unix::AsyncFd; use tokio::io::Interest; diff --git a/tokio/tests/io_read.rs b/tokio/tests/io_read.rs index 6bea0ac86..f15d88458 100644 --- a/tokio/tests/io_read.rs +++ b/tokio/tests/io_read.rs @@ -1,5 +1,13 @@ #![warn(rust_2018_idioms)] -#![cfg(all(feature = "full", not(target_os = "wasi")))] // Wasi does not support panic recovery +#![cfg(any( + all(feature = "full", not(target_os = "wasi")), // Wasi does not support panic recovery + all( + target_os = "emscripten", + feature = "rt", + feature = "macros", + feature = "io-util" + ) +))] use tokio::io::{AsyncRead, AsyncReadExt, ReadBuf}; use tokio_test::assert_ok; diff --git a/tokio/tests/io_read_buf.rs b/tokio/tests/io_read_buf.rs index 49a4f86f8..33db33060 100644 --- a/tokio/tests/io_read_buf.rs +++ b/tokio/tests/io_read_buf.rs @@ -1,5 +1,13 @@ #![warn(rust_2018_idioms)] -#![cfg(feature = "full")] +#![cfg(any( + feature = "full", + all( + target_os = "emscripten", + feature = "rt", + feature = "macros", + feature = "io-util" + ) +))] use tokio::io::{AsyncRead, AsyncReadExt, ReadBuf}; use tokio_test::assert_ok; diff --git a/tokio/tests/io_read_exact.rs b/tokio/tests/io_read_exact.rs index d0e659bd3..670fa33be 100644 --- a/tokio/tests/io_read_exact.rs +++ b/tokio/tests/io_read_exact.rs @@ -1,5 +1,13 @@ #![warn(rust_2018_idioms)] -#![cfg(feature = "full")] +#![cfg(any( + feature = "full", + all( + target_os = "emscripten", + feature = "rt", + feature = "macros", + feature = "io-util" + ) +))] use tokio::io::AsyncReadExt; use tokio_test::assert_ok; diff --git a/tokio/tests/io_read_line.rs b/tokio/tests/io_read_line.rs index bbc984b45..ef3436cd2 100644 --- a/tokio/tests/io_read_line.rs +++ b/tokio/tests/io_read_line.rs @@ -1,5 +1,13 @@ #![warn(rust_2018_idioms)] -#![cfg(feature = "full")] +#![cfg(any( + feature = "full", + all( + target_os = "emscripten", + feature = "rt", + feature = "macros", + feature = "io-util" + ) +))] use std::io::ErrorKind; use std::str::Utf8Error; diff --git a/tokio/tests/io_read_to_end.rs b/tokio/tests/io_read_to_end.rs index 6573f8b68..08e5c23ed 100644 --- a/tokio/tests/io_read_to_end.rs +++ b/tokio/tests/io_read_to_end.rs @@ -1,5 +1,13 @@ #![warn(rust_2018_idioms)] -#![cfg(feature = "full")] +#![cfg(any( + feature = "full", + all( + target_os = "emscripten", + feature = "rt", + feature = "macros", + feature = "io-util" + ) +))] use std::pin::Pin; use std::task::{Context, Poll}; diff --git a/tokio/tests/io_read_to_string.rs b/tokio/tests/io_read_to_string.rs index 040f72692..3fa10c3af 100644 --- a/tokio/tests/io_read_to_string.rs +++ b/tokio/tests/io_read_to_string.rs @@ -1,5 +1,13 @@ #![warn(rust_2018_idioms)] -#![cfg(feature = "full")] +#![cfg(any( + feature = "full", + all( + target_os = "emscripten", + feature = "rt", + feature = "macros", + feature = "io-util" + ) +))] use std::io; use std::str::Utf8Error; diff --git a/tokio/tests/io_read_until.rs b/tokio/tests/io_read_until.rs index 61800a0d9..f8b73eff6 100644 --- a/tokio/tests/io_read_until.rs +++ b/tokio/tests/io_read_until.rs @@ -1,5 +1,13 @@ #![warn(rust_2018_idioms)] -#![cfg(feature = "full")] +#![cfg(any( + feature = "full", + all( + target_os = "emscripten", + feature = "rt", + feature = "macros", + feature = "io-util" + ) +))] use std::io::ErrorKind; use tokio::io::{AsyncBufReadExt, BufReader, Error}; diff --git a/tokio/tests/io_repeat.rs b/tokio/tests/io_repeat.rs index 5a48817b1..f9ad4db4a 100644 --- a/tokio/tests/io_repeat.rs +++ b/tokio/tests/io_repeat.rs @@ -1,5 +1,13 @@ #![warn(rust_2018_idioms)] -#![cfg(all(feature = "full", not(miri)))] +#![cfg(any( + all(feature = "full", not(miri)), + all( + target_os = "emscripten", + feature = "rt", + feature = "macros", + feature = "io-util" + ) +))] use tokio::io::AsyncReadExt; diff --git a/tokio/tests/io_sink.rs b/tokio/tests/io_sink.rs index fb085c515..749a7b260 100644 --- a/tokio/tests/io_sink.rs +++ b/tokio/tests/io_sink.rs @@ -1,5 +1,13 @@ #![warn(rust_2018_idioms)] -#![cfg(feature = "full")] +#![cfg(any( + feature = "full", + all( + target_os = "emscripten", + feature = "rt", + feature = "macros", + feature = "io-util" + ) +))] use tokio::io::AsyncWriteExt; diff --git a/tokio/tests/io_split.rs b/tokio/tests/io_split.rs index 983982cca..45891484b 100644 --- a/tokio/tests/io_split.rs +++ b/tokio/tests/io_split.rs @@ -1,5 +1,13 @@ #![warn(rust_2018_idioms)] -#![cfg(all(feature = "full", not(target_os = "wasi")))] // Wasi does not support panic recovery +#![cfg(any( + all(feature = "full", not(target_os = "wasi")), // Wasi does not support panic recovery + all( + target_os = "emscripten", + feature = "rt", + feature = "macros", + feature = "io-util" + ) +))] use tokio::io::{ split, AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt, ReadBuf, ReadHalf, WriteHalf, diff --git a/tokio/tests/io_take.rs b/tokio/tests/io_take.rs index 1ae5f6908..dd735146a 100644 --- a/tokio/tests/io_take.rs +++ b/tokio/tests/io_take.rs @@ -1,5 +1,13 @@ #![warn(rust_2018_idioms)] -#![cfg(all(feature = "full", not(target_os = "wasi")))] // Wasi does not support panic recovery +#![cfg(any( + all(feature = "full", not(target_os = "wasi")), // Wasi does not support panic recovery + all( + target_os = "emscripten", + feature = "rt", + feature = "macros", + feature = "io-util" + ) +))] use std::pin::Pin; use std::task::{Context, Poll}; diff --git a/tokio/tests/io_util_empty.rs b/tokio/tests/io_util_empty.rs index 7a4b8c6a5..72fac1b14 100644 --- a/tokio/tests/io_util_empty.rs +++ b/tokio/tests/io_util_empty.rs @@ -1,4 +1,12 @@ -#![cfg(feature = "full")] +#![cfg(any( + feature = "full", + all( + target_os = "emscripten", + feature = "rt", + feature = "macros", + feature = "io-util" + ) +))] use tokio::io::{AsyncBufReadExt, AsyncReadExt, AsyncSeekExt}; #[tokio::test] diff --git a/tokio/tests/io_write.rs b/tokio/tests/io_write.rs index 96cebc331..21bdcbe6e 100644 --- a/tokio/tests/io_write.rs +++ b/tokio/tests/io_write.rs @@ -1,5 +1,13 @@ #![warn(rust_2018_idioms)] -#![cfg(feature = "full")] +#![cfg(any( + feature = "full", + all( + target_os = "emscripten", + feature = "rt", + feature = "macros", + feature = "io-util" + ) +))] use tokio::io::{AsyncWrite, AsyncWriteExt}; use tokio_test::assert_ok; diff --git a/tokio/tests/io_write_all.rs b/tokio/tests/io_write_all.rs index 7ca02228a..1ac9b61f3 100644 --- a/tokio/tests/io_write_all.rs +++ b/tokio/tests/io_write_all.rs @@ -1,5 +1,13 @@ #![warn(rust_2018_idioms)] -#![cfg(feature = "full")] +#![cfg(any( + feature = "full", + all( + target_os = "emscripten", + feature = "rt", + feature = "macros", + feature = "io-util" + ) +))] use tokio::io::{AsyncWrite, AsyncWriteExt}; use tokio_test::assert_ok; diff --git a/tokio/tests/io_write_all_buf.rs b/tokio/tests/io_write_all_buf.rs index 52ad5965c..c5e736255 100644 --- a/tokio/tests/io_write_all_buf.rs +++ b/tokio/tests/io_write_all_buf.rs @@ -1,5 +1,13 @@ #![warn(rust_2018_idioms)] -#![cfg(feature = "full")] +#![cfg(any( + feature = "full", + all( + target_os = "emscripten", + feature = "rt", + feature = "macros", + feature = "io-util" + ) +))] use tokio::io::{AsyncWrite, AsyncWriteExt}; use tokio_test::{assert_err, assert_ok}; diff --git a/tokio/tests/io_write_buf.rs b/tokio/tests/io_write_buf.rs index 8bd09ad62..dd74c7313 100644 --- a/tokio/tests/io_write_buf.rs +++ b/tokio/tests/io_write_buf.rs @@ -1,5 +1,13 @@ #![warn(rust_2018_idioms)] -#![cfg(feature = "full")] +#![cfg(any( + feature = "full", + all( + target_os = "emscripten", + feature = "rt", + feature = "macros", + feature = "io-util" + ) +))] use tokio::io::{AsyncWrite, AsyncWriteExt}; use tokio_test::assert_ok; diff --git a/tokio/tests/io_write_int.rs b/tokio/tests/io_write_int.rs index 48a583d8c..c9c58fa88 100644 --- a/tokio/tests/io_write_int.rs +++ b/tokio/tests/io_write_int.rs @@ -1,5 +1,13 @@ #![warn(rust_2018_idioms)] -#![cfg(feature = "full")] +#![cfg(any( + feature = "full", + all( + target_os = "emscripten", + feature = "rt", + feature = "macros", + feature = "io-util" + ) +))] use tokio::io::{AsyncWrite, AsyncWriteExt}; diff --git a/tokio/tests/join_handle_panic.rs b/tokio/tests/join_handle_panic.rs index 248d5702f..de505c36f 100644 --- a/tokio/tests/join_handle_panic.rs +++ b/tokio/tests/join_handle_panic.rs @@ -1,5 +1,8 @@ #![warn(rust_2018_idioms)] -#![cfg(all(feature = "full", not(target_os = "wasi")))] // Wasi doesn't support panic recovery +#![cfg(any( + all(feature = "full", not(target_os = "wasi")), // Wasi doesn't support panic recovery + all(target_os = "emscripten", feature = "rt", feature = "macros", feature = "time") +))] #![cfg(panic = "unwind")] struct PanicsOnDrop; diff --git a/tokio/tests/macros_join.rs b/tokio/tests/macros_join.rs index 4c6db26d8..8b304be8d 100644 --- a/tokio/tests/macros_join.rs +++ b/tokio/tests/macros_join.rs @@ -2,13 +2,13 @@ #![allow(clippy::disallowed_names)] use std::sync::Arc; -#[cfg(all(target_family = "wasm", not(target_os = "wasi")))] +#[cfg(all(target_family = "wasm", target_os = "unknown"))] #[cfg(target_pointer_width = "64")] use wasm_bindgen_test::wasm_bindgen_test as test; -#[cfg(all(target_family = "wasm", not(target_os = "wasi")))] +#[cfg(all(target_family = "wasm", target_os = "unknown"))] use wasm_bindgen_test::wasm_bindgen_test as maybe_tokio_test; -#[cfg(not(all(target_family = "wasm", not(target_os = "wasi"))))] +#[cfg(not(all(target_family = "wasm", target_os = "unknown")))] use tokio::test as maybe_tokio_test; use tokio::sync::{oneshot, Semaphore}; diff --git a/tokio/tests/macros_pin.rs b/tokio/tests/macros_pin.rs index 2de68ad03..19c29d56f 100644 --- a/tokio/tests/macros_pin.rs +++ b/tokio/tests/macros_pin.rs @@ -1,9 +1,9 @@ #![cfg(feature = "macros")] -#[cfg(all(target_family = "wasm", not(target_os = "wasi")))] +#[cfg(all(target_family = "wasm", target_os = "unknown"))] use wasm_bindgen_test::wasm_bindgen_test as maybe_tokio_test; -#[cfg(not(all(target_family = "wasm", not(target_os = "wasi"))))] +#[cfg(not(all(target_family = "wasm", target_os = "unknown")))] use tokio::test as maybe_tokio_test; async fn one() {} diff --git a/tokio/tests/macros_select.rs b/tokio/tests/macros_select.rs index 3b403e4ce..662645c07 100644 --- a/tokio/tests/macros_select.rs +++ b/tokio/tests/macros_select.rs @@ -1,10 +1,10 @@ #![cfg(feature = "macros")] #![allow(clippy::disallowed_names)] -#[cfg(all(target_family = "wasm", not(target_os = "wasi")))] +#[cfg(all(target_family = "wasm", target_os = "unknown"))] use wasm_bindgen_test::wasm_bindgen_test as maybe_tokio_test; -#[cfg(not(all(target_family = "wasm", not(target_os = "wasi"))))] +#[cfg(not(all(target_family = "wasm", target_os = "unknown")))] use tokio::test as maybe_tokio_test; use tokio::sync::oneshot; diff --git a/tokio/tests/macros_try_join.rs b/tokio/tests/macros_try_join.rs index 03172ca2a..25f811c8e 100644 --- a/tokio/tests/macros_try_join.rs +++ b/tokio/tests/macros_try_join.rs @@ -6,10 +6,10 @@ use std::{convert::Infallible, sync::Arc}; use tokio::sync::{oneshot, Semaphore}; use tokio_test::{assert_pending, assert_ready, task}; -#[cfg(all(target_family = "wasm", not(target_os = "wasi")))] +#[cfg(all(target_family = "wasm", target_os = "unknown"))] use wasm_bindgen_test::wasm_bindgen_test as maybe_tokio_test; -#[cfg(not(all(target_family = "wasm", not(target_os = "wasi"))))] +#[cfg(not(all(target_family = "wasm", target_os = "unknown")))] use tokio::test as maybe_tokio_test; #[maybe_tokio_test] diff --git a/tokio/tests/rt_basic.rs b/tokio/tests/rt_basic.rs index 3fab2649a..3adf7d48c 100644 --- a/tokio/tests/rt_basic.rs +++ b/tokio/tests/rt_basic.rs @@ -1,5 +1,8 @@ #![warn(rust_2018_idioms)] -#![cfg(feature = "full")] +#![cfg(any( + feature = "full", + all(target_os = "emscripten", feature = "rt", feature = "macros") +))] use tokio::runtime::{self, Runtime}; use tokio::sync::oneshot; @@ -249,7 +252,10 @@ fn spawn_two() { } } -#[cfg_attr(target_os = "wasi", ignore = "WASI: std::thread::spawn not supported")] +#[cfg_attr( + target_family = "wasm", + ignore = "wasm targets do not support std::thread::spawn" +)] #[test] fn spawn_remote() { let rt = rt(); @@ -346,7 +352,10 @@ mod unstable { } #[test] - #[cfg_attr(target_os = "wasi", ignore = "Wasi does not support panic recovery")] + #[cfg_attr( + target_family = "wasm", + ignore = "wasm targets do not support std::thread::spawn" + )] fn spawns_do_nothing() { use std::sync::Arc; @@ -375,7 +384,10 @@ mod unstable { } #[test] - #[cfg_attr(target_os = "wasi", ignore = "Wasi does not support panic recovery")] + #[cfg_attr( + target_family = "wasm", + ignore = "wasm targets do not support std::thread::spawn" + )] fn shutdown_all_concurrent_block_on() { const N: usize = 2; use std::sync::{mpsc, Arc}; diff --git a/tokio/tests/rt_handle.rs b/tokio/tests/rt_handle.rs index 8feb7207d..db1ee6f71 100644 --- a/tokio/tests/rt_handle.rs +++ b/tokio/tests/rt_handle.rs @@ -1,5 +1,8 @@ #![warn(rust_2018_idioms)] -#![cfg(feature = "full")] +#![cfg(any( + feature = "full", + all(target_os = "emscripten", feature = "rt", feature = "macros") +))] use std::sync::Arc; use tokio::runtime::Runtime; diff --git a/tokio/tests/rt_multi_thread_emscripten.rs b/tokio/tests/rt_multi_thread_emscripten.rs new file mode 100644 index 000000000..49e41731c --- /dev/null +++ b/tokio/tests/rt_multi_thread_emscripten.rs @@ -0,0 +1,72 @@ +#![warn(rust_2018_idioms)] +#![cfg(all( + target_os = "emscripten", + feature = "rt-multi-thread", + feature = "macros" +))] + +//! Multi-thread runtime tests for `wasm32-unknown-emscripten` built with +//! pthreads (`-pthread`). + +use std::sync::atomic::{AtomicUsize, Ordering}; +use std::sync::{Arc, Barrier}; +use std::time::Duration; + +#[test] +fn block_on_multi_thread() { + let rt = tokio::runtime::Builder::new_multi_thread() + .worker_threads(2) + .enable_time() + .build() + .unwrap(); + + let out = rt.block_on(async { + let jh = tokio::spawn(async { + tokio::time::sleep(Duration::from_millis(10)).await; + "hello" + }); + jh.await.unwrap() + }); + assert_eq!(out, "hello"); +} + +#[test] +fn spawn_blocking_runs_in_parallel() { + let rt = tokio::runtime::Builder::new_multi_thread() + .worker_threads(2) + .build() + .unwrap(); + + // Both closures must be running concurrently for the barrier to release. + let barrier = Arc::new(Barrier::new(2)); + rt.block_on(async { + let a = tokio::task::spawn_blocking({ + let barrier = barrier.clone(); + move || { + barrier.wait(); + } + }); + let b = tokio::task::spawn_blocking(move || { + barrier.wait(); + }); + a.await.unwrap(); + b.await.unwrap(); + }); +} + +#[tokio::test(flavor = "multi_thread", worker_threads = 2)] +async fn macro_multi_thread() { + static COUNT: AtomicUsize = AtomicUsize::new(0); + + let mut handles = Vec::new(); + for _ in 0..8 { + handles.push(tokio::spawn(async { + tokio::task::yield_now().await; + COUNT.fetch_add(1, Ordering::Relaxed); + })); + } + for handle in handles { + handle.await.unwrap(); + } + assert_eq!(COUNT.load(Ordering::Relaxed), 8); +} diff --git a/tokio/tests/rt_panic.rs b/tokio/tests/rt_panic.rs index 1bf05580a..f9c122ae2 100644 --- a/tokio/tests/rt_panic.rs +++ b/tokio/tests/rt_panic.rs @@ -1,11 +1,16 @@ #![warn(rust_2018_idioms)] -#![cfg(feature = "full")] +#![cfg(any( + feature = "full", + all(target_os = "emscripten", feature = "rt", feature = "macros") +))] #![cfg(not(target_os = "wasi"))] // Wasi doesn't support panic recovery #![cfg(panic = "unwind")] use futures::future; use std::error::Error; -use tokio::runtime::{Builder, Handle, Runtime}; +#[cfg(feature = "rt-multi-thread")] +use tokio::runtime::Builder; +use tokio::runtime::{Handle, Runtime}; mod support { pub mod panic; @@ -47,6 +52,7 @@ fn into_panic_panic_caller() -> Result<(), Box> { } #[test] +#[cfg(feature = "rt-multi-thread")] fn builder_worker_threads_panic_caller() -> Result<(), Box> { let panic_location_file = test_panic(|| { let _ = Builder::new_multi_thread().worker_threads(0).build(); @@ -59,6 +65,7 @@ fn builder_worker_threads_panic_caller() -> Result<(), Box> { } #[test] +#[cfg(feature = "rt-multi-thread")] fn builder_max_blocking_threads_panic_caller() -> Result<(), Box> { let panic_location_file = test_panic(|| { let _ = Builder::new_multi_thread().max_blocking_threads(0).build(); @@ -71,6 +78,7 @@ fn builder_max_blocking_threads_panic_caller() -> Result<(), Box> { } #[test] +#[cfg(feature = "rt-multi-thread")] fn builder_global_queue_interval_panic_caller() -> Result<(), Box> { let panic_location_file = test_panic(|| { let _ = Builder::new_multi_thread().global_queue_interval(0).build(); @@ -83,6 +91,7 @@ fn builder_global_queue_interval_panic_caller() -> Result<(), Box> { } #[test] +#[cfg(feature = "rt-multi-thread")] fn builder_event_interval_interval_panic_caller() -> Result<(), Box> { let panic_location_file = test_panic(|| { let _ = Builder::new_multi_thread().event_interval(0).build(); @@ -95,6 +104,7 @@ fn builder_event_interval_interval_panic_caller() -> Result<(), Box> } #[test] +#[cfg(feature = "rt-multi-thread")] fn builder_name_panic_caller() -> Result<(), Box> { let panic_location_file = test_panic(|| { let _ = Builder::new_multi_thread().name(" ").build(); diff --git a/tokio/tests/rt_shutdown_err.rs b/tokio/tests/rt_shutdown_err.rs index b92d8eb24..cf03debed 100644 --- a/tokio/tests/rt_shutdown_err.rs +++ b/tokio/tests/rt_shutdown_err.rs @@ -1,8 +1,9 @@ #![warn(rust_2018_idioms)] -#![cfg(feature = "full")] +#![cfg(any(feature = "full", all(target_os = "emscripten", feature = "rt")))] #![cfg(not(miri))] // No socket in miri. use std::io; +#[cfg(not(target_family = "wasm"))] use tokio::net::TcpListener; use tokio::runtime::Builder; @@ -10,6 +11,7 @@ fn rt() -> tokio::runtime::Runtime { Builder::new_current_thread().enable_all().build().unwrap() } +#[cfg(not(target_family = "wasm"))] // needs net (TcpListener) #[test] fn test_is_rt_shutdown_err() { let rt1 = rt(); diff --git a/tokio/tests/rt_time_start_paused.rs b/tokio/tests/rt_time_start_paused.rs index 1765d625e..6ec020f79 100644 --- a/tokio/tests/rt_time_start_paused.rs +++ b/tokio/tests/rt_time_start_paused.rs @@ -1,4 +1,12 @@ -#![cfg(feature = "full")] +#![cfg(any( + feature = "full", + all( + target_os = "emscripten", + feature = "rt", + feature = "macros", + feature = "test-util" + ) +))] use tokio::time::{Duration, Instant}; diff --git a/tokio/tests/sync_barrier.rs b/tokio/tests/sync_barrier.rs index ac5977f24..a8f8e9790 100644 --- a/tokio/tests/sync_barrier.rs +++ b/tokio/tests/sync_barrier.rs @@ -2,7 +2,7 @@ #![warn(rust_2018_idioms)] #![cfg(feature = "sync")] -#[cfg(all(target_family = "wasm", not(target_os = "wasi")))] +#[cfg(all(target_family = "wasm", target_os = "unknown"))] use wasm_bindgen_test::wasm_bindgen_test as test; use tokio::sync::Barrier; diff --git a/tokio/tests/sync_broadcast.rs b/tokio/tests/sync_broadcast.rs index 2bfe235e5..94bfde6bb 100644 --- a/tokio/tests/sync_broadcast.rs +++ b/tokio/tests/sync_broadcast.rs @@ -2,7 +2,7 @@ #![warn(rust_2018_idioms)] #![cfg(feature = "sync")] -#[cfg(all(target_family = "wasm", not(target_os = "wasi")))] +#[cfg(all(target_family = "wasm", target_os = "unknown"))] use wasm_bindgen_test::wasm_bindgen_test as test; use tokio::sync::broadcast; @@ -563,7 +563,7 @@ fn sender_len() { } #[test] -#[cfg(not(all(target_family = "wasm", not(target_os = "wasi"))))] +#[cfg(not(all(target_family = "wasm", target_os = "unknown")))] fn sender_len_random() { let (tx, mut rx1) = broadcast::channel(16); let mut rx2 = tx.subscribe(); diff --git a/tokio/tests/sync_broadcast_weak.rs b/tokio/tests/sync_broadcast_weak.rs index 1e7fd6f2d..ccca130e5 100644 --- a/tokio/tests/sync_broadcast_weak.rs +++ b/tokio/tests/sync_broadcast_weak.rs @@ -2,7 +2,7 @@ #![warn(rust_2018_idioms)] #![cfg(feature = "sync")] -#[cfg(all(target_family = "wasm", not(target_os = "wasi")))] +#[cfg(all(target_family = "wasm", target_os = "unknown"))] use wasm_bindgen_test::wasm_bindgen_test as test; use tokio::sync::broadcast::{self, channel}; diff --git a/tokio/tests/sync_errors.rs b/tokio/tests/sync_errors.rs index 4e43c8f31..2bc9b8781 100644 --- a/tokio/tests/sync_errors.rs +++ b/tokio/tests/sync_errors.rs @@ -1,7 +1,7 @@ #![warn(rust_2018_idioms)] #![cfg(feature = "sync")] -#[cfg(all(target_family = "wasm", not(target_os = "wasi")))] +#[cfg(all(target_family = "wasm", target_os = "unknown"))] use wasm_bindgen_test::wasm_bindgen_test as test; fn is_error() {} diff --git a/tokio/tests/sync_mpsc.rs b/tokio/tests/sync_mpsc.rs index 398ab6339..207bef40d 100644 --- a/tokio/tests/sync_mpsc.rs +++ b/tokio/tests/sync_mpsc.rs @@ -2,12 +2,12 @@ #![warn(rust_2018_idioms)] #![cfg(feature = "sync")] -#[cfg(all(target_family = "wasm", not(target_os = "wasi")))] +#[cfg(all(target_family = "wasm", target_os = "unknown"))] use wasm_bindgen_test::wasm_bindgen_test as test; -#[cfg(all(target_family = "wasm", not(target_os = "wasi")))] +#[cfg(all(target_family = "wasm", target_os = "unknown"))] use wasm_bindgen_test::wasm_bindgen_test as maybe_tokio_test; -#[cfg(not(all(target_family = "wasm", not(target_os = "wasi"))))] +#[cfg(not(all(target_family = "wasm", target_os = "unknown")))] use tokio::test as maybe_tokio_test; use std::fmt; diff --git a/tokio/tests/sync_mpsc_weak.rs b/tokio/tests/sync_mpsc_weak.rs index fba0fe4e3..f09e79dab 100644 --- a/tokio/tests/sync_mpsc_weak.rs +++ b/tokio/tests/sync_mpsc_weak.rs @@ -2,7 +2,7 @@ #![warn(rust_2018_idioms)] #![cfg(feature = "sync")] -#[cfg(all(target_family = "wasm", not(target_os = "wasi")))] +#[cfg(all(target_family = "wasm", target_os = "unknown"))] use wasm_bindgen_test::wasm_bindgen_test as test; use std::sync::atomic::AtomicUsize; diff --git a/tokio/tests/sync_mutex.rs b/tokio/tests/sync_mutex.rs index 8d74addad..37ecf7a2e 100644 --- a/tokio/tests/sync_mutex.rs +++ b/tokio/tests/sync_mutex.rs @@ -1,12 +1,12 @@ #![warn(rust_2018_idioms)] #![cfg(feature = "sync")] -#[cfg(all(target_family = "wasm", not(target_os = "wasi")))] +#[cfg(all(target_family = "wasm", target_os = "unknown"))] use wasm_bindgen_test::wasm_bindgen_test as test; -#[cfg(all(target_family = "wasm", not(target_os = "wasi")))] +#[cfg(all(target_family = "wasm", target_os = "unknown"))] use wasm_bindgen_test::wasm_bindgen_test as maybe_tokio_test; -#[cfg(not(all(target_family = "wasm", not(target_os = "wasi"))))] +#[cfg(not(all(target_family = "wasm", target_os = "unknown")))] use tokio::test as maybe_tokio_test; use tokio::sync::Mutex; diff --git a/tokio/tests/sync_mutex_owned.rs b/tokio/tests/sync_mutex_owned.rs index 28b2afbf3..95f7ba82e 100644 --- a/tokio/tests/sync_mutex_owned.rs +++ b/tokio/tests/sync_mutex_owned.rs @@ -1,12 +1,12 @@ #![warn(rust_2018_idioms)] #![cfg(feature = "sync")] -#[cfg(all(target_family = "wasm", not(target_os = "wasi")))] +#[cfg(all(target_family = "wasm", target_os = "unknown"))] use wasm_bindgen_test::wasm_bindgen_test as test; -#[cfg(all(target_family = "wasm", not(target_os = "wasi")))] +#[cfg(all(target_family = "wasm", target_os = "unknown"))] use wasm_bindgen_test::wasm_bindgen_test as maybe_tokio_test; -#[cfg(not(all(target_family = "wasm", not(target_os = "wasi"))))] +#[cfg(not(all(target_family = "wasm", target_os = "unknown")))] use tokio::test as maybe_tokio_test; use tokio::sync::Mutex; diff --git a/tokio/tests/sync_notify.rs b/tokio/tests/sync_notify.rs index ee7a9ecf0..3eb927160 100644 --- a/tokio/tests/sync_notify.rs +++ b/tokio/tests/sync_notify.rs @@ -1,7 +1,7 @@ #![warn(rust_2018_idioms)] #![cfg(feature = "sync")] -#[cfg(all(target_family = "wasm", not(target_os = "wasi")))] +#[cfg(all(target_family = "wasm", target_os = "unknown"))] use wasm_bindgen_test::wasm_bindgen_test as test; use tokio::sync::Notify; diff --git a/tokio/tests/sync_notify_owned.rs b/tokio/tests/sync_notify_owned.rs index 06a0f6ade..cef574a68 100644 --- a/tokio/tests/sync_notify_owned.rs +++ b/tokio/tests/sync_notify_owned.rs @@ -1,7 +1,7 @@ #![warn(rust_2018_idioms)] #![cfg(feature = "sync")] -#[cfg(all(target_family = "wasm", not(target_os = "wasi")))] +#[cfg(all(target_family = "wasm", target_os = "unknown"))] use wasm_bindgen_test::wasm_bindgen_test as test; use std::sync::Arc; diff --git a/tokio/tests/sync_once_cell.rs b/tokio/tests/sync_once_cell.rs index a05438f24..acc2a1f42 100644 --- a/tokio/tests/sync_once_cell.rs +++ b/tokio/tests/sync_once_cell.rs @@ -1,5 +1,13 @@ #![warn(rust_2018_idioms)] -#![cfg(feature = "full")] +#![cfg(any( + feature = "full", + all( + target_os = "emscripten", + feature = "rt", + feature = "macros", + feature = "test-util" + ) +))] use std::mem; use std::sync::atomic::{AtomicU32, Ordering}; diff --git a/tokio/tests/sync_oneshot.rs b/tokio/tests/sync_oneshot.rs index 08206ea1d..8aaddbdb3 100644 --- a/tokio/tests/sync_oneshot.rs +++ b/tokio/tests/sync_oneshot.rs @@ -1,12 +1,12 @@ #![warn(rust_2018_idioms)] #![cfg(feature = "sync")] -#[cfg(all(target_family = "wasm", not(target_os = "wasi")))] +#[cfg(all(target_family = "wasm", target_os = "unknown"))] use wasm_bindgen_test::wasm_bindgen_test as test; -#[cfg(all(target_family = "wasm", not(target_os = "wasi")))] +#[cfg(all(target_family = "wasm", target_os = "unknown"))] use wasm_bindgen_test::wasm_bindgen_test as maybe_tokio_test; -#[cfg(not(all(target_family = "wasm", not(target_os = "wasi"))))] +#[cfg(not(all(target_family = "wasm", target_os = "unknown")))] use tokio::test as maybe_tokio_test; use tokio::sync::oneshot; diff --git a/tokio/tests/sync_panic.rs b/tokio/tests/sync_panic.rs index c781c846b..f2f79e0f3 100644 --- a/tokio/tests/sync_panic.rs +++ b/tokio/tests/sync_panic.rs @@ -1,5 +1,8 @@ #![warn(rust_2018_idioms)] -#![cfg(all(feature = "full", not(target_os = "wasi")))] +#![cfg(any( + all(feature = "full", not(target_os = "wasi")), + all(target_os = "emscripten", feature = "rt", feature = "sync") +))] #![cfg(panic = "unwind")] use std::{error::Error, sync::Arc}; diff --git a/tokio/tests/sync_rwlock.rs b/tokio/tests/sync_rwlock.rs index 2dc7b0a62..c51f9616c 100644 --- a/tokio/tests/sync_rwlock.rs +++ b/tokio/tests/sync_rwlock.rs @@ -1,12 +1,12 @@ #![warn(rust_2018_idioms)] #![cfg(feature = "sync")] -#[cfg(all(target_family = "wasm", not(target_os = "wasi")))] +#[cfg(all(target_family = "wasm", target_os = "unknown"))] use wasm_bindgen_test::wasm_bindgen_test as test; -#[cfg(all(target_family = "wasm", not(target_os = "wasi")))] +#[cfg(all(target_family = "wasm", target_os = "unknown"))] use wasm_bindgen_test::wasm_bindgen_test as maybe_tokio_test; -#[cfg(not(all(target_family = "wasm", not(target_os = "wasi"))))] +#[cfg(not(all(target_family = "wasm", target_os = "unknown")))] use tokio::test as maybe_tokio_test; use std::task::Poll; diff --git a/tokio/tests/sync_semaphore.rs b/tokio/tests/sync_semaphore.rs index 113dee064..695c35bb6 100644 --- a/tokio/tests/sync_semaphore.rs +++ b/tokio/tests/sync_semaphore.rs @@ -1,6 +1,6 @@ #![cfg(feature = "sync")] -#[cfg(all(target_family = "wasm", not(target_os = "wasi")))] +#[cfg(all(target_family = "wasm", target_os = "unknown"))] use wasm_bindgen_test::wasm_bindgen_test as test; use std::sync::Arc; diff --git a/tokio/tests/sync_semaphore_owned.rs b/tokio/tests/sync_semaphore_owned.rs index 1bae1e9e0..031d297c5 100644 --- a/tokio/tests/sync_semaphore_owned.rs +++ b/tokio/tests/sync_semaphore_owned.rs @@ -1,6 +1,6 @@ #![cfg(feature = "sync")] -#[cfg(all(target_family = "wasm", not(target_os = "wasi")))] +#[cfg(all(target_family = "wasm", target_os = "unknown"))] use wasm_bindgen_test::wasm_bindgen_test as test; use std::sync::Arc; diff --git a/tokio/tests/sync_set_once.rs b/tokio/tests/sync_set_once.rs index 5b6d88a9f..99c0e6255 100644 --- a/tokio/tests/sync_set_once.rs +++ b/tokio/tests/sync_set_once.rs @@ -1,5 +1,13 @@ #![warn(rust_2018_idioms)] -#![cfg(feature = "full")] +#![cfg(any( + feature = "full", + all( + target_os = "emscripten", + feature = "rt", + feature = "sync", + feature = "macros" + ) +))] use std::sync::{ atomic::{AtomicU32, Ordering}, diff --git a/tokio/tests/sync_watch.rs b/tokio/tests/sync_watch.rs index 48e410684..df366f4a8 100644 --- a/tokio/tests/sync_watch.rs +++ b/tokio/tests/sync_watch.rs @@ -2,7 +2,7 @@ #![warn(rust_2018_idioms)] #![cfg(feature = "sync")] -#[cfg(all(target_family = "wasm", not(target_os = "wasi")))] +#[cfg(all(target_family = "wasm", target_os = "unknown"))] use wasm_bindgen_test::wasm_bindgen_test as test; use tokio::sync::watch; diff --git a/tokio/tests/task_abort.rs b/tokio/tests/task_abort.rs index 8de366454..101daad58 100644 --- a/tokio/tests/task_abort.rs +++ b/tokio/tests/task_abort.rs @@ -1,16 +1,22 @@ #![warn(rust_2018_idioms)] -#![cfg(all(feature = "full", not(target_os = "wasi")))] // Wasi doesn't support panic recovery +#![cfg(any( + all(feature = "full", not(target_os = "wasi")), // Wasi doesn't support panic recovery + all(target_os = "emscripten", feature = "rt", feature = "time") +))] +#[cfg(not(target_family = "wasm"))] use std::sync::Arc; +#[cfg(not(target_family = "wasm"))] use std::thread::sleep; +#[cfg(not(target_family = "wasm"))] use tokio::time::Duration; use tokio::runtime::Builder; -#[cfg(panic = "unwind")] +#[cfg(all(panic = "unwind", not(target_family = "wasm")))] struct PanicOnDrop; -#[cfg(panic = "unwind")] +#[cfg(all(panic = "unwind", not(target_family = "wasm")))] impl Drop for PanicOnDrop { fn drop(&mut self) { panic!("Well what did you expect would happen..."); @@ -19,6 +25,7 @@ impl Drop for PanicOnDrop { /// Checks that a suspended task can be aborted without panicking as reported in /// issue #3157: . +#[cfg(not(target_family = "wasm"))] #[test] fn test_abort_without_panic_3157() { let rt = Builder::new_multi_thread() @@ -41,6 +48,7 @@ fn test_abort_without_panic_3157() { /// Checks that a suspended task can be aborted inside of a current_thread /// executor without panicking as reported in issue #3662: /// . +#[cfg(not(target_family = "wasm"))] #[test] fn test_abort_without_panic_3662() { use std::sync::atomic::{AtomicBool, Ordering}; @@ -104,6 +112,7 @@ fn test_abort_without_panic_3662() { /// Checks that a suspended LocalSet task can be aborted from a remote thread /// without panicking and without running the tasks destructor on the wrong thread. /// +#[cfg(not(target_family = "wasm"))] #[test] fn remote_abort_local_set_3929() { struct DropCheck { @@ -147,6 +156,7 @@ fn remote_abort_local_set_3929() { /// Checks that a suspended task can be aborted even if the `JoinHandle` is immediately dropped. /// issue #3964: . +#[cfg(not(target_family = "wasm"))] #[test] fn test_abort_wakes_task_3964() { let rt = Builder::new_current_thread().enable_time().build().unwrap(); @@ -177,8 +187,8 @@ fn test_abort_wakes_task_3964() { /// Checks that aborting a task whose destructor panics does not allow the /// panic to escape the task. +#[cfg(all(panic = "unwind", not(target_family = "wasm")))] #[test] -#[cfg(panic = "unwind")] fn test_abort_task_that_panics_on_drop_contained() { let rt = Builder::new_current_thread().enable_time().build().unwrap(); @@ -201,8 +211,8 @@ fn test_abort_task_that_panics_on_drop_contained() { } /// Checks that aborting a task whose destructor panics has the expected result. +#[cfg(all(panic = "unwind", not(target_family = "wasm")))] #[test] -#[cfg(panic = "unwind")] fn test_abort_task_that_panics_on_drop_returned() { let rt = Builder::new_current_thread().enable_time().build().unwrap(); diff --git a/tokio/tests/task_emscripten.rs b/tokio/tests/task_emscripten.rs new file mode 100644 index 000000000..cb72517dd --- /dev/null +++ b/tokio/tests/task_emscripten.rs @@ -0,0 +1,12 @@ +#![cfg(all(target_os = "emscripten", not(target_feature = "atomics")))] + +/// There is no threadpool on a single-threaded JS worker: the public +/// `spawn_blocking` is unsupported on non-pthread emscripten, as on the other +/// single-threaded wasm targets. `tokio::fs` and +/// `tokio::io::{stdin, stdout, stderr}` do not rely on it there — their +/// syscalls complete synchronously. +#[tokio::test] +#[should_panic = "OS can't spawn worker thread"] +async fn spawn_blocking_is_unsupported() { + let _ = tokio::task::spawn_blocking(|| 42).await; +} diff --git a/tokio/tests/task_id.rs b/tokio/tests/task_id.rs index 0cbf80d5a..1c54773af 100644 --- a/tokio/tests/task_id.rs +++ b/tokio/tests/task_id.rs @@ -1,10 +1,19 @@ #![warn(rust_2018_idioms)] -#![cfg(feature = "full")] +#![cfg(any( + feature = "full", + all( + target_os = "emscripten", + feature = "rt", + feature = "sync", + feature = "macros" + ) +))] use std::error::Error; use std::future::Future; use std::pin::Pin; use std::task::{Context, Poll}; +#[cfg(not(target_family = "wasm"))] use tokio::runtime::Runtime; use tokio::sync::oneshot; use tokio::task::{self, Id, LocalSet}; @@ -21,7 +30,7 @@ async fn task_id_spawn() { .unwrap(); } -#[cfg(not(target_os = "wasi"))] +#[cfg(not(any(target_os = "wasi", target_os = "emscripten")))] #[tokio::test(flavor = "current_thread")] async fn task_id_spawn_blocking() { task::spawn_blocking(|| println!("task id: {}", task::id())) @@ -38,7 +47,7 @@ async fn task_id_collision_current_thread() { assert_ne!(id1.unwrap(), id2.unwrap()); } -#[cfg(not(target_os = "wasi"))] +#[cfg(not(target_family = "wasm"))] #[tokio::test(flavor = "multi_thread")] async fn task_id_collision_multi_thread() { let handle1 = tokio::spawn(async { task::id() }); @@ -59,7 +68,7 @@ async fn task_ids_match_current_thread() { handle.await.unwrap(); } -#[cfg(not(target_os = "wasi"))] +#[cfg(not(target_family = "wasm"))] #[tokio::test(flavor = "multi_thread")] async fn task_ids_match_multi_thread() { let (tx, rx) = oneshot::channel(); @@ -72,7 +81,8 @@ async fn task_ids_match_multi_thread() { } #[cfg(not(target_os = "wasi"))] -#[tokio::test(flavor = "multi_thread")] +#[cfg_attr(target_os = "emscripten", tokio::test(flavor = "current_thread"))] +#[cfg_attr(not(target_os = "emscripten"), tokio::test(flavor = "multi_thread"))] async fn task_id_future_destructor_completion() { struct MyFuture { tx: Option>, @@ -100,7 +110,8 @@ async fn task_id_future_destructor_completion() { } #[cfg(not(target_os = "wasi"))] -#[tokio::test(flavor = "multi_thread")] +#[cfg_attr(target_os = "emscripten", tokio::test(flavor = "current_thread"))] +#[cfg_attr(not(target_os = "emscripten"), tokio::test(flavor = "multi_thread"))] async fn task_id_future_destructor_abort() { struct MyFuture { tx: Option>, @@ -205,7 +216,7 @@ fn task_try_id_outside_task() { assert_eq!(None, task::try_id()); } -#[cfg(not(target_os = "wasi"))] +#[cfg(not(target_family = "wasm"))] #[test] fn task_try_id_inside_block_on() { let rt = Runtime::new().unwrap(); @@ -248,7 +259,7 @@ async fn task_id_nested_spawn_local() { .await; } -#[cfg(not(target_os = "wasi"))] +#[cfg(not(target_family = "wasm"))] #[tokio::test(flavor = "multi_thread")] async fn task_id_block_in_place_block_on_spawn() { use tokio::runtime::Builder; @@ -283,6 +294,7 @@ fn task_id_outside_task_panic_caller() -> Result<(), Box> { Ok(()) } +#[cfg(not(target_family = "wasm"))] #[test] #[cfg_attr(not(panic = "unwind"), ignore)] fn task_id_inside_block_on_panic_caller() -> Result<(), Box> { diff --git a/tokio/tests/task_join_set.rs b/tokio/tests/task_join_set.rs index 38534d1b7..6d6f2b315 100644 --- a/tokio/tests/task_join_set.rs +++ b/tokio/tests/task_join_set.rs @@ -1,5 +1,14 @@ #![warn(rust_2018_idioms)] -#![cfg(feature = "full")] +#![cfg(any( + feature = "full", + all( + target_os = "emscripten", + feature = "rt", + feature = "sync", + feature = "macros", + feature = "time" + ) +))] use futures::future::{pending, FutureExt}; use std::panic; @@ -433,6 +442,7 @@ mod spawn_local { set.spawn_local(async {}); } + #[cfg(not(target_family = "wasm"))] #[tokio::test(flavor = "multi_thread")] #[should_panic( expected = "`spawn_local` called from outside of a `task::LocalSet` or `runtime::LocalRuntime`" diff --git a/tokio/tests/task_local.rs b/tokio/tests/task_local.rs index be9de7241..0341c7df5 100644 --- a/tokio/tests/task_local.rs +++ b/tokio/tests/task_local.rs @@ -1,11 +1,15 @@ -#![cfg(all(feature = "full", not(target_os = "wasi")))] // Wasi doesn't support threads +#![cfg(any( + all(feature = "full", not(target_os = "wasi")), // Wasi doesn't support threads + all(target_os = "emscripten", feature = "rt", feature = "macros") +))] use std::future::Future; use std::pin::Pin; use std::task::{Context, Poll}; use tokio::sync::oneshot; -#[tokio::test(flavor = "multi_thread")] +#[cfg_attr(not(target_family = "wasm"), tokio::test(flavor = "multi_thread"))] +#[cfg_attr(target_family = "wasm", tokio::test)] async fn local() { tokio::task_local! { static REQ_ID: u32; diff --git a/tokio/tests/task_panic.rs b/tokio/tests/task_panic.rs index 8b4de2ada..2221f6343 100644 --- a/tokio/tests/task_panic.rs +++ b/tokio/tests/task_panic.rs @@ -1,11 +1,16 @@ #![warn(rust_2018_idioms)] -#![cfg(all(feature = "full", not(target_os = "wasi")))] +#![cfg(any( + all(feature = "full", not(target_os = "wasi")), + all(target_os = "emscripten", feature = "rt", feature = "macros") +))] #![cfg(panic = "unwind")] use futures::future; use std::error::Error; use tokio::runtime::Builder; -use tokio::task::{self, block_in_place}; +use tokio::task; +#[cfg(feature = "rt-multi-thread")] +use tokio::task::block_in_place; mod support { pub mod panic; @@ -13,6 +18,7 @@ mod support { use support::panic::test_panic; #[test] +#[cfg(feature = "rt-multi-thread")] fn block_in_place_panic_caller() -> Result<(), Box> { let panic_location_file = test_panic(|| { let rt = Builder::new_current_thread().enable_all().build().unwrap(); diff --git a/tokio/tests/task_yield_now.rs b/tokio/tests/task_yield_now.rs index e6fe5d200..343b94181 100644 --- a/tokio/tests/task_yield_now.rs +++ b/tokio/tests/task_yield_now.rs @@ -1,4 +1,11 @@ -#![cfg(all(feature = "full", not(target_os = "wasi"), tokio_unstable))] +#![cfg(all( + any( + feature = "full", + all(target_os = "emscripten", feature = "rt", feature = "macros") + ), + not(target_os = "wasi"), + tokio_unstable +))] use tokio::task; use tokio_test::task::spawn; @@ -15,6 +22,7 @@ fn yield_now_outside_of_runtime() { assert!(task.poll().is_ready()); } +#[cfg(not(target_family = "wasm"))] #[tokio::test(flavor = "multi_thread")] async fn yield_now_external_executor_and_block_in_place() { let j = tokio::spawn(async { diff --git a/tokio/tests/test_clock.rs b/tokio/tests/test_clock.rs index 891636fdb..f5f643a7b 100644 --- a/tokio/tests/test_clock.rs +++ b/tokio/tests/test_clock.rs @@ -1,5 +1,13 @@ #![warn(rust_2018_idioms)] -#![cfg(feature = "full")] +#![cfg(any( + feature = "full", + all( + target_os = "emscripten", + feature = "rt", + feature = "macros", + feature = "test-util" + ) +))] use tokio::time::{self, Duration, Instant}; diff --git a/tokio/tests/time_interval.rs b/tokio/tests/time_interval.rs index 7472a3712..c33ca177c 100644 --- a/tokio/tests/time_interval.rs +++ b/tokio/tests/time_interval.rs @@ -1,5 +1,13 @@ #![warn(rust_2018_idioms)] -#![cfg(feature = "full")] +#![cfg(any( + feature = "full", + all( + target_os = "emscripten", + feature = "rt", + feature = "macros", + feature = "test-util" + ) +))] use std::pin::Pin; use std::task::{Context, Poll}; diff --git a/tokio/tests/time_panic.rs b/tokio/tests/time_panic.rs index 918d02a41..5aa651f35 100644 --- a/tokio/tests/time_panic.rs +++ b/tokio/tests/time_panic.rs @@ -1,5 +1,8 @@ #![warn(rust_2018_idioms)] -#![cfg(all(feature = "full", not(target_os = "wasi")))] // Wasi doesn't support panic recovery +#![cfg(any( + all(feature = "full", not(target_os = "wasi")), // Wasi doesn't support panic recovery + all(target_os = "emscripten", feature = "rt", feature = "time") +))] #![cfg(panic = "unwind")] use futures::future; @@ -22,21 +25,24 @@ fn rt_combinations() -> Vec { .unwrap(); rts.push(rt); - let rt = tokio::runtime::Builder::new_multi_thread() - .worker_threads(1) - .enable_all() - .build() - .unwrap(); - rts.push(rt); + #[cfg(not(target_os = "emscripten"))] + { + let rt = tokio::runtime::Builder::new_multi_thread() + .worker_threads(1) + .enable_all() + .build() + .unwrap(); + rts.push(rt); - let rt = tokio::runtime::Builder::new_multi_thread() - .worker_threads(4) - .enable_all() - .build() - .unwrap(); - rts.push(rt); + let rt = tokio::runtime::Builder::new_multi_thread() + .worker_threads(4) + .enable_all() + .build() + .unwrap(); + rts.push(rt); + } - #[cfg(tokio_unstable)] + #[cfg(all(tokio_unstable, not(target_os = "emscripten")))] { let rt = tokio::runtime::Builder::new_multi_thread() .worker_threads(1) diff --git a/tokio/tests/time_pause.rs b/tokio/tests/time_pause.rs index be993b4c8..aed0037f2 100644 --- a/tokio/tests/time_pause.rs +++ b/tokio/tests/time_pause.rs @@ -1,5 +1,13 @@ #![warn(rust_2018_idioms)] -#![cfg(feature = "full")] +#![cfg(any( + feature = "full", + all( + target_os = "emscripten", + feature = "rt", + feature = "macros", + feature = "test-util" + ) +))] #![cfg(not(miri))] // Too slow on miri. use rand::SeedableRng; @@ -7,7 +15,7 @@ use rand::{rngs::StdRng, Rng}; use tokio::time::{self, Duration, Instant, Sleep}; use tokio_test::{assert_elapsed, assert_pending, assert_ready, assert_ready_eq, task}; -#[cfg(not(target_os = "wasi"))] +#[cfg(all(feature = "full", not(target_os = "wasi")))] use tokio_test::assert_err; use std::{ diff --git a/tokio/tests/time_sleep.rs b/tokio/tests/time_sleep.rs index b82b1cc6a..ff3517079 100644 --- a/tokio/tests/time_sleep.rs +++ b/tokio/tests/time_sleep.rs @@ -1,5 +1,13 @@ #![warn(rust_2018_idioms)] -#![cfg(feature = "full")] +#![cfg(any( + feature = "full", + all( + target_os = "emscripten", + feature = "rt", + feature = "macros", + feature = "test-util" + ) +))] #![cfg(not(miri))] // Too slow on Miri. use std::future::Future; diff --git a/tokio/tests/time_timeout.rs b/tokio/tests/time_timeout.rs index ec871cf62..e54e470d5 100644 --- a/tokio/tests/time_timeout.rs +++ b/tokio/tests/time_timeout.rs @@ -1,5 +1,13 @@ #![warn(rust_2018_idioms)] -#![cfg(feature = "full")] +#![cfg(any( + feature = "full", + all( + target_os = "emscripten", + feature = "rt", + feature = "macros", + feature = "test-util" + ) +))] use tokio::sync::oneshot; use tokio::time::{self, timeout, timeout_at, Instant}; diff --git a/tokio/tests/time_wasm.rs b/tokio/tests/time_wasm.rs index 8e0483f20..073df353d 100644 --- a/tokio/tests/time_wasm.rs +++ b/tokio/tests/time_wasm.rs @@ -1,5 +1,9 @@ #![warn(rust_2018_idioms)] -#![cfg(all(target_arch = "wasm32", not(target_os = "wasi")))] +#![cfg(all( + target_arch = "wasm32", + not(target_os = "wasi"), + not(target_os = "emscripten") +))] use wasm_bindgen_test::wasm_bindgen_test; diff --git a/tokio/tests/unwindsafe.rs b/tokio/tests/unwindsafe.rs index 8ab665429..161055058 100644 --- a/tokio/tests/unwindsafe.rs +++ b/tokio/tests/unwindsafe.rs @@ -1,5 +1,8 @@ #![warn(rust_2018_idioms)] -#![cfg(all(feature = "full", not(target_os = "wasi")))] // Wasi does not support panic recovery +#![cfg(any( + all(feature = "full", not(target_os = "wasi")), // Wasi does not support panic recovery + all(target_os = "emscripten", feature = "rt", feature = "sync") +))] use std::panic::{RefUnwindSafe, UnwindSafe}; @@ -14,6 +17,7 @@ fn join_handle_is_unwind_safe() { } #[test] +#[cfg(feature = "net")] fn net_types_are_unwind_safe() { is_unwind_safe::(); is_unwind_safe::(); @@ -22,7 +26,7 @@ fn net_types_are_unwind_safe() { } #[test] -#[cfg(unix)] +#[cfg(all(unix, feature = "net"))] fn unix_net_types_are_unwind_safe() { is_unwind_safe::(); is_unwind_safe::();