From 32e7fe9ca1e5d7fa6df6c32338c4e4882657d16c Mon Sep 17 00:00:00 2001 From: Jamie Pine Date: Wed, 31 Dec 2025 12:45:22 -0800 Subject: [PATCH] fix(tests): enhance Windows compatibility and test stability - Normalize file paths to use forward slashes in Git pattern matching for better compatibility across platforms. - Introduce a random suffix to temporary directory names in tests on Windows to avoid file lock contention during parallel execution. - Add a delay after shutdown in tests to ensure SQLite file locks are released properly on Windows. These changes aim to improve the reliability and consistency of tests in a Windows environment. --- core/src/ops/indexing/rules.rs | 5 ++++- core/tests/helpers/indexing_harness.rs | 7 +++++++ core/tests/helpers/test_data.rs | 25 +++++++++++++++++++++++-- 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/core/src/ops/indexing/rules.rs b/core/src/ops/indexing/rules.rs index b0d1774e5..3d7c40194 100644 --- a/core/src/ops/indexing/rules.rs +++ b/core/src/ops/indexing/rules.rs @@ -146,9 +146,12 @@ fn accept_by_git_pattern( Ok(p) => p, Err(_) => return true, }; - let Some(src) = relative.to_str().map(|s| s.as_bytes().into()) else { + let Some(path_str) = relative.to_str() else { return false; }; + // Gitignore patterns expect forward slashes, even on Windows + let normalized_path = path_str.replace('\\', "/"); + let src = normalized_path.as_bytes().into(); search .pattern_matching_relative_path(src, Some(source.is_dir()), Case::Fold) .map_or(true, |rule| rule.pattern.is_negative()) diff --git a/core/tests/helpers/indexing_harness.rs b/core/tests/helpers/indexing_harness.rs index 14e061322..41acaa3b8 100644 --- a/core/tests/helpers/indexing_harness.rs +++ b/core/tests/helpers/indexing_harness.rs @@ -275,6 +275,13 @@ impl IndexingHarness { .await .map_err(|e| anyhow::anyhow!("Failed to shutdown core: {}", e))?; + // On Windows, SQLite file locks can persist after shutdown even after WAL checkpoint + // This is due to the connection pool in SeaORM potentially holding onto connections + // Give the OS sufficient time to release all locks before TestDataDir cleanup + // Tests running in sequence need time for previous test's locks to fully release + #[cfg(windows)] + tokio::time::sleep(Duration::from_secs(2)).await; + // TestDataDir handles cleanup automatically on drop Ok(()) } diff --git a/core/tests/helpers/test_data.rs b/core/tests/helpers/test_data.rs index 9c99d5f9f..7177e17cf 100644 --- a/core/tests/helpers/test_data.rs +++ b/core/tests/helpers/test_data.rs @@ -57,10 +57,31 @@ impl TestDataDir { } }; + // On Windows, add a random suffix to avoid file lock contention in parallel tests let dir_name = if use_home_for_watcher { - format!(".spacedrive_test_{}", test_name) + #[cfg(windows)] + { + use std::sync::atomic::{AtomicU64, Ordering}; + static COUNTER: AtomicU64 = AtomicU64::new(0); + let id = COUNTER.fetch_add(1, Ordering::Relaxed); + format!(".spacedrive_test_{}_{}", test_name, id) + } + #[cfg(not(windows))] + { + format!(".spacedrive_test_{}", test_name) + } } else { - format!("spacedrive-test-{}", test_name) + #[cfg(windows)] + { + use std::sync::atomic::{AtomicU64, Ordering}; + static COUNTER: AtomicU64 = AtomicU64::new(0); + let id = COUNTER.fetch_add(1, Ordering::Relaxed); + format!("spacedrive-test-{}-{}", test_name, id) + } + #[cfg(not(windows))] + { + format!("spacedrive-test-{}", test_name) + } }; let temp_path = PathBuf::from(temp_base).join(dir_name);