GoogleChromeLabs / wasm-bindgen-rayon

An adapter for enabling Rayon-based concurrency on the Web with WebAssembly.
https://github.com/RReverser/wasm-bindgen-rayon
Apache License 2.0
404 stars 35 forks source link

Unit testing with #[wasm_bindgen_test] #30

Closed ZhaoXiangXML closed 10 months ago

ZhaoXiangXML commented 2 years ago

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.

RReverser commented 2 years ago

Is this related to #31? If you're running tests on the main thread, it probably won't work.

RReverser commented 2 years ago

Also - just to check - are you building with all the necessary flags as described in the docs?

ZhaoXiangXML commented 2 years ago

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?

RReverser commented 2 years ago

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.

codeart1st commented 2 years ago

https://github.com/rustwasm/wasm-bindgen/issues/2892 needs to be addressed.

RReverser commented 10 months ago

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).