mirror of
https://github.com/storytold/lightcraft.git
synced 2026-11-01 05:57:09 -06:00
gpu: init-marker tests use their own scope counter so parallel device tests cannot join them (#1721)
This commit is contained in:
+30
-16
@@ -213,12 +213,12 @@ fn disarm(marker: &std::path::Path, active: &Mutex<u32>) {
|
||||
}
|
||||
|
||||
/// Removes the marker on the way out, a panic included (the process survived).
|
||||
struct Armed(Option<PathBuf>);
|
||||
struct Armed<'a>(Option<PathBuf>, &'a Mutex<u32>);
|
||||
|
||||
impl Drop for Armed {
|
||||
impl Drop for Armed<'_> {
|
||||
fn drop(&mut self) {
|
||||
if let Some(m) = &self.0 {
|
||||
disarm(m, &ACTIVE);
|
||||
disarm(m, self.1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -227,10 +227,16 @@ impl Drop for Armed {
|
||||
/// removing the init marker (if one is set).
|
||||
pub(crate) fn with_marker<T>(what: &str, f: impl FnOnce() -> T) -> T {
|
||||
let marker = MARKER.lock().unwrap_or_else(|e| e.into_inner()).clone();
|
||||
with_marker_on(marker, &ACTIVE, what, f)
|
||||
}
|
||||
|
||||
/// [`with_marker`] on an explicit marker path and scope counter (the tests use their own, so that
|
||||
/// device-creating tests running in parallel cannot join their scopes).
|
||||
fn with_marker_on<T>(marker: Option<PathBuf>, active: &Mutex<u32>, what: &str, f: impl FnOnce() -> T) -> T {
|
||||
if let Some(m) = &marker {
|
||||
arm(m, &ACTIVE, what);
|
||||
arm(m, active, what);
|
||||
}
|
||||
let _armed = Armed(marker);
|
||||
let _armed = Armed(marker, active);
|
||||
f()
|
||||
}
|
||||
|
||||
@@ -352,9 +358,6 @@ mod tests {
|
||||
}
|
||||
use super::*;
|
||||
|
||||
/// The tests that set the process-wide marker take turns.
|
||||
static GLOBAL: Mutex<()> = Mutex::new(());
|
||||
|
||||
#[test]
|
||||
fn parses_backend_names() {
|
||||
assert_eq!(parse_backends("dx12"), Some(BackendChoice::Use(Backends::DX12)));
|
||||
@@ -421,13 +424,12 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn init_marker_is_written_during_creation_and_removed_after() {
|
||||
let _turn = GLOBAL.lock().unwrap_or_else(|e| e.into_inner());
|
||||
let dir = std::env::temp_dir().join(format!("lc-gpu-marker-{}", std::process::id()));
|
||||
let m = dir.join("gpu-init.marker");
|
||||
let _ = std::fs::remove_dir_all(&dir);
|
||||
set_init_marker(Some(m.clone()));
|
||||
let seen = with_init_marker(Backends::DX12, || m.exists());
|
||||
set_init_marker(None);
|
||||
// a local scope counter: other tests create real devices through the process-wide one
|
||||
let active = Mutex::new(0);
|
||||
let seen = with_marker_on(Some(m.clone()), &active, "device creation", || m.exists());
|
||||
assert!(seen, "the marker exists while the device is created");
|
||||
assert!(!m.exists(), "and is removed afterwards");
|
||||
// a marker left behind by a crashed process is reported once; reading it leaves it in place
|
||||
@@ -440,6 +442,20 @@ mod tests {
|
||||
let _ = std::fs::remove_dir_all(&dir);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn with_init_marker_writes_the_process_wide_marker() {
|
||||
let dir = std::env::temp_dir().join(format!("lc-gpu-global-{}", std::process::id()));
|
||||
let m = dir.join("gpu-init.marker");
|
||||
let _ = std::fs::remove_dir_all(&dir);
|
||||
set_init_marker(Some(m.clone()));
|
||||
let seen = with_init_marker(Backends::DX12, || m.exists());
|
||||
set_init_marker(None);
|
||||
// not checked for removal: device-creating tests running in parallel may still hold the file
|
||||
// (the test above checks removal on its own scope counter)
|
||||
assert!(seen, "the marker set with set_init_marker exists while the device is created");
|
||||
let _ = std::fs::remove_dir_all(&dir);
|
||||
}
|
||||
|
||||
/// The window's renderer fallback: forced, remembered, the platform chain, the failed one last.
|
||||
#[test]
|
||||
fn window_renderer_fallback_order() {
|
||||
@@ -505,13 +521,11 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn a_panic_inside_the_scope_still_removes_the_marker() {
|
||||
let _turn = GLOBAL.lock().unwrap_or_else(|e| e.into_inner());
|
||||
let dir = std::env::temp_dir().join(format!("lc-gpu-panic-{}", std::process::id()));
|
||||
let m = dir.join("gpu-init.marker");
|
||||
let _ = std::fs::remove_dir_all(&dir);
|
||||
set_init_marker(Some(m.clone()));
|
||||
let r = std::panic::catch_unwind(|| with_marker("kernel compilation", || panic!("compile")));
|
||||
set_init_marker(None);
|
||||
let active = Mutex::new(0);
|
||||
let r = std::panic::catch_unwind(|| with_marker_on(Some(m.clone()), &active, "kernel compilation", || panic!("compile")));
|
||||
assert!(r.is_err());
|
||||
assert!(!m.exists(), "the process survived, so nothing is left to report");
|
||||
let _ = std::fs::remove_dir_all(&dir);
|
||||
|
||||
Reference in New Issue
Block a user