From fa2f9d0b4f4c26f028b7952b5dee4692a7f5b62b Mon Sep 17 00:00:00 2001 From: Connor Fitzgerald Date: Wed, 14 Dec 2022 18:51:29 -0500 Subject: [PATCH] Error when not using cargo-nextest --- CHANGELOG.md | 1 + wgpu/tests/common/isolation.rs | 43 ++++++++++++++++++++++++++++++++++ wgpu/tests/common/mod.rs | 4 ++++ 3 files changed, 48 insertions(+) create mode 100644 wgpu/tests/common/isolation.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index 9fc3e46b2d..bf53a3d2e9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -193,6 +193,7 @@ Additionally `Surface::get_default_config` now returns an Option and returns Non - Use cargo 1.64 workspace inheritance feature. By @jinleili in [#3107](https://github.com/gfx-rs/wgpu/pull/3107) - Move `ResourceMetadata` into its own module. By @jimblandy in [#3213](https://github.com/gfx-rs/wgpu/pull/3213) - Add WebAssembly testing infrastructure. By @haraldreingruber in [#3238](https://github.com/gfx-rs/wgpu/pull/3238) +- Error message when you forget to use cargo-nextest. By @cwfitzgerald in [#]() #### Vulkan diff --git a/wgpu/tests/common/isolation.rs b/wgpu/tests/common/isolation.rs new file mode 100644 index 0000000000..e4c7b6e560 --- /dev/null +++ b/wgpu/tests/common/isolation.rs @@ -0,0 +1,43 @@ +use std::sync::atomic::{AtomicBool, Ordering}; + +/// True if a test is in progress somewhere in the process, false otherwise. +static TEST_ACTIVE_IN_PROCESS: AtomicBool = AtomicBool::new(false); + +const OTHER_TEST_IN_PROGRESS_ERROR: &str = "TEST ISOLATION ERROR: + +wgpu's test harness requires that no more than one test is running per process. + +The best way to facilitate this is by using cargo-nextest which runs each test in its own process +and has a very good testing UI: + +cargo install cargo-nextest +cargo nextest run + +Alternatively, you can run tests in single threaded mode (much slower). + +cargo test -- --test-threads=1 + +Calling std::process::abort()... +"; + +/// When this guard is active, enforces that there is only a single test running in the process +/// at any one time. If there are multiple processes, creating the guard hard terminates the process. +pub struct OneTestPerProcessGuard(()); + +impl OneTestPerProcessGuard { + pub fn new() -> Self { + let other_tests_in_flight = TEST_ACTIVE_IN_PROCESS.swap(true, Ordering::SeqCst); + if other_tests_in_flight { + log::error!("{}", OTHER_TEST_IN_PROGRESS_ERROR); + // Hard exit to call attention to the error + std::process::abort(); + } + OneTestPerProcessGuard(()) + } +} + +impl Drop for OneTestPerProcessGuard { + fn drop(&mut self) { + TEST_ACTIVE_IN_PROCESS.store(false, Ordering::SeqCst); + } +} diff --git a/wgpu/tests/common/mod.rs b/wgpu/tests/common/mod.rs index e624fc7919..37fafed043 100644 --- a/wgpu/tests/common/mod.rs +++ b/wgpu/tests/common/mod.rs @@ -7,6 +7,7 @@ use wgpu::{Adapter, Device, DownlevelFlags, Instance, Queue, Surface}; use wgt::{Backends, DeviceDescriptor, DownlevelCapabilities, Features, Limits}; pub mod image; +mod isolation; const CANVAS_ID: &str = "test-canvas"; @@ -167,6 +168,7 @@ impl TestParameters { self } } + pub fn initialize_test(parameters: TestParameters, test_function: impl FnOnce(TestingContext)) { // We don't actually care if it fails #[cfg(not(target_arch = "wasm32"))] @@ -174,6 +176,8 @@ pub fn initialize_test(parameters: TestParameters, test_function: impl FnOnce(Te #[cfg(target_arch = "wasm32")] let _ = console_log::init_with_level(log::Level::Info); + let _test_guard = isolation::OneTestPerProcessGuard::new(); + let (adapter, _) = initialize_adapter(); let adapter_info = adapter.get_info();