From da9136e17ba51d3acf7f002e1f9a27fc4a8b3aff Mon Sep 17 00:00:00 2001 From: leynos Date: Fri, 12 Jun 2026 17:41:16 +0200 Subject: [PATCH] Restore EnvLock synchronisation unit tests (#321) PR #273 removed the `#[cfg(test)]` block in `tests/bdd/fixtures/mod.rs` that validated `ensure_env_lock()` and the `Drop`-based working directory restoration, leaving these synchronisation properties untested at the unit level. Restore the four tests (first-call acquisition, idempotency, CWD capture, and Drop restoration), adapted to the current semantics. The two CWD-asserting tests now hold an outer re-entrant `EnvLock` for their full duration so parallel test threads cannot move the process CWD between the world's drop and the assertion. --- tests/bdd/fixtures/mod.rs | 74 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/tests/bdd/fixtures/mod.rs b/tests/bdd/fixtures/mod.rs index ff761e5e..051019f8 100644 --- a/tests/bdd/fixtures/mod.rs +++ b/tests/bdd/fixtures/mod.rs @@ -294,3 +294,77 @@ impl RefCellOptionExt for RefCell> { self.borrow_mut().take() } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn ensure_env_lock_acquires_lock_on_first_call() { + let world = TestWorld::default(); + assert!( + world.env_lock.borrow().is_none(), + "env_lock should be None before ensure_env_lock is called" + ); + world.ensure_env_lock(); + assert!( + world.env_lock.borrow().is_some(), + "env_lock should be Some after ensure_env_lock is called" + ); + } + + #[test] + fn ensure_env_lock_is_idempotent() { + let world = TestWorld::default(); + world.ensure_env_lock(); + world.ensure_env_lock(); + assert!( + world.env_lock.borrow().is_some(), + "repeated ensure_env_lock calls should keep the lock held" + ); + } + + #[test] + fn ensure_env_lock_captures_cwd() { + // EnvLock is re-entrant per thread, so holding an outer lock keeps + // other tests from moving the CWD while this one asserts on it. + let _outer = EnvLock::acquire(); + let world = TestWorld::default(); + assert!( + world.original_cwd.borrow().is_none(), + "original_cwd should be None before ensure_env_lock is called" + ); + world.ensure_env_lock(); + let captured = world + .original_cwd + .borrow() + .clone() + .expect("original_cwd should be captured when the lock is first acquired"); + let actual = std::env::current_dir().expect("current_dir"); + assert_eq!( + captured, actual, + "captured CWD should match the actual CWD at lock acquisition time" + ); + } + + #[test] + fn drop_restores_cwd_after_ensure_env_lock() { + // Hold the (re-entrant) lock across the world's lifetime so the CWD + // cannot be moved by another test between drop and the assertion. + let _outer = EnvLock::acquire(); + let original = std::env::current_dir().expect("current_dir"); + let temp = tempfile::tempdir().expect("tempdir"); + + { + let world = TestWorld::default(); + world.ensure_env_lock(); + std::env::set_current_dir(temp.path()).expect("chdir"); + } + + assert_eq!( + std::env::current_dir().expect("current_dir"), + original, + "Drop should restore the CWD captured at ensure_env_lock time" + ); + } +}