1use std::sync::atomic::{AtomicBool, Ordering};
23/// True if a test is in progress somewhere in the process, false otherwise.
4static TEST_ACTIVE_IN_PROCESS: AtomicBool = AtomicBool::new(false);
56const OTHER_TEST_IN_PROGRESS_ERROR: &str = "TEST ISOLATION ERROR:
78wgpu's test harness requires that no more than one test is running per process.
910The best way to facilitate this is by using cargo-nextest which runs each test in its own process
11and has a very good testing UI:
1213cargo install cargo-nextest
14cargo nextest run
1516Alternatively, you can run tests in single threaded mode (much slower).
1718cargo test -- --test-threads=1
1920Calling std::process::abort()...
21";
2223/// When this guard is active, enforces that there is only a single test running in the process
24/// at any one time. If there are multiple processes, creating the guard hard terminates the process.
25pub struct OneTestPerProcessGuard(());
2627impl OneTestPerProcessGuard {
28pub fn new() -> Self {
29let other_tests_in_flight = TEST_ACTIVE_IN_PROCESS.swap(true, Ordering::SeqCst);
3031// We never abort if we're on wasm. Wasm tests are inherently single threaded, and panics cannot
32 // unwind the stack and trigger all the guards, so we don't actually need to check.
33if other_tests_in_flight && !cfg!(target_arch = "wasm32") {
34log::error!("{OTHER_TEST_IN_PROGRESS_ERROR}");
35// Hard exit to call attention to the error
36std::process::abort();
37 }
38 OneTestPerProcessGuard(())
39 }
40}
4142impl Drop for OneTestPerProcessGuard {
43fn drop(&mut self) {
44 TEST_ACTIVE_IN_PROCESS.store(false, Ordering::SeqCst);
45 }
46}