Unit testing with #[wasm_bindgen_test]
I'm trying to use wasm-bindgen-rayon in unit tests by wasm-bindgen-test, here is an demo project:
src/lib.rs
use rayon::iter::{IntoParallelRefIterator, ParallelIterator};
use wasm_bindgen::prelude::*;
#[macro_export]
macro_rules! log {
($($arg:tt)*) => (
web_sys::console::log_1(&format_args!($($arg)*).to_string().into())
)
}
#[wasm_bindgen]
pub fn sum(numbers: &[i32]) -> i32 {
numbers.par_iter().sum()
}
mod test {
use super::*;
use wasm_bindgen_futures::JsFuture;
use wasm_bindgen_rayon::init_thread_pool;
use wasm_bindgen_test::*;
wasm_bindgen_test_configure!(run_in_browser);
#[wasm_bindgen_test]
async fn test() {
log!("init thread pool");
let _ = JsFuture::from(init_thread_pool(
web_sys::window()
.unwrap()
.navigator()
.hardware_concurrency() as usize,
)).await;
log!("after init thread pool");
let nums: Vec<i32> = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let sum = sum(&nums);
assert_eq!(sum, 55);
}
}
Cargo.toml:
[package]
name = "wasm-bindgen-rayon-test"
version = "0.1.0"
edition = "2021"
[lib]
crate-type = ["cdylib", "rlib"]
[dependencies]
wasm-bindgen = "0.2.81"
wasm-bindgen-test = "0.3.13"
rayon = "1.5"
wasm-bindgen-rayon = { version = "1.0" }
wasm-bindgen-futures = "0.4.30"
[dependencies.web-sys]
version = "*"
features = ["console", "Window", "Navigator"]
Then I ran the test with:
wasm-pack test --chrome --headless
and I got the following output:
log output:
init thread pool
after init thread pool
error output:
panicked at 'The global thread pool has not been initialized.: ThreadPoolBuildError { kind: IOError(Error { kind: Unsupported, message: "operation not supported on this platform" }) }', C:\SDK\rust\cargo\registry\src\github.com-1ecc6299db9ec823\rayon-core-1.9.3\src\registry.rs:170:10
I've add some logs in wasm-bindgen-rayon, it appears the callback in waitForMsgType was never called.
I'd like to know how can I fix this issue. Thank you.
Is this related to #31? If you're running tests on the main thread, it probably won't work.
Also - just to check - are you building with all the necessary flags as described in the docs?
Is this related to #31? If you're running tests on the main thread, it probably won't work.
They are related. I'm trying to run wasm-bindgen-rayon my rust unit tests and javascript pages, neither of them worked for me. And I've all the necessary build flags (or I would have compile errors).
Anyway, guess I'll have to figure out a way to init a worker thread in rust? Is it even possible?
And I've all the necessary build flags (or I would have compile errors).
Not really, I think without some of the flags you'd simply get runtime errors as that's what wasm32-unknown-unknown target does for unsupported APIs. So it fails at runtime if you try to access filesystem or try to create thread but built without atomic flags and so on.
Anyway, guess I'll have to figure out a way to init a worker thread in rust? Is it even possible?
I think it's something you need to do from JS side, as it needs to be done before your Rust is even instantiated (since Wasm itself has to already run in a worker). But you can try playing with either rayon::spawn or web_sys::Worker, there might be a way, just not one I can think of.
https://github.com/rustwasm/wasm-bindgen/issues/2892 needs to be addressed.
Linked issue was resolved, so this should work nowadays. If not, please open an issue on the new repo (https://github.com/RReverser/wasm-bindgen-rayon).