From 09bddc36769b4be38b6ce567c3352e2934204771 Mon Sep 17 00:00:00 2001 From: Ryan Zoeller Date: Sat, 27 Nov 2021 13:50:29 -0600 Subject: Avoid lock poisoning by using parking_lot parking_lot provides synchronization primitives which aren't poisoned on panic. This makes it easier to determine which tests are failing, as a test failure no longer causes all subsequent tests using that mutex to fail. --- Cargo.toml | 1 + test/sys/test_aio.rs | 4 ++-- test/sys/test_ptrace.rs | 6 +++--- test/sys/test_select.rs | 4 +--- test/sys/test_signal.rs | 8 ++++---- test/sys/test_signalfd.rs | 2 +- test/sys/test_termios.rs | 6 +++--- test/sys/test_uio.rs | 2 +- test/sys/test_wait.rs | 8 ++++---- test/test.rs | 5 ++--- test/test_kmod/mod.rs | 32 +++++++++++++++----------------- test/test_pty.rs | 18 +++++++++--------- test/test_unistd.rs | 26 +++++++++++++------------- 13 files changed, 59 insertions(+), 63 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index fc960255..f5c7a565 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -38,6 +38,7 @@ cc = "1" [dev-dependencies] assert-impl = "0.1" lazy_static = "1.2" +parking_lot = "0.11.2" rand = "0.8" tempfile = "3.2.0" semver = "1.0.0" diff --git a/test/sys/test_aio.rs b/test/sys/test_aio.rs index b4eb3129..80cd053f 100644 --- a/test/sys/test_aio.rs +++ b/test/sys/test_aio.rs @@ -406,7 +406,7 @@ extern fn sigfunc(_: c_int) { #[test] #[cfg_attr(any(all(target_env = "musl", target_arch = "x86_64"), target_arch = "mips", target_arch = "mips64"), ignore)] fn test_write_sigev_signal() { - let _m = crate::SIGNAL_MTX.lock().expect("Mutex got poisoned by another test"); + let _m = crate::SIGNAL_MTX.lock(); let sa = SigAction::new(SigHandler::Handler(sigfunc), SaFlags::SA_RESETHAND, SigSet::empty()); @@ -544,7 +544,7 @@ fn test_liocb_listio_nowait() { #[cfg(not(any(target_os = "ios", target_os = "macos")))] #[cfg_attr(any(target_arch = "mips", target_arch = "mips64", target_env = "musl"), ignore)] fn test_liocb_listio_signal() { - let _m = crate::SIGNAL_MTX.lock().expect("Mutex got poisoned by another test"); + let _m = crate::SIGNAL_MTX.lock(); const INITIAL: &[u8] = b"abcdef123456"; const WBUF: &[u8] = b"CDEF"; let mut rbuf = vec![0; 4]; diff --git a/test/sys/test_ptrace.rs b/test/sys/test_ptrace.rs index 1c72e7c2..83fff9a5 100644 --- a/test/sys/test_ptrace.rs +++ b/test/sys/test_ptrace.rs @@ -69,7 +69,7 @@ fn test_ptrace_cont() { require_capability!("test_ptrace_cont", CAP_SYS_PTRACE); - let _m = crate::FORK_MTX.lock().expect("Mutex got poisoned by another test"); + let _m = crate::FORK_MTX.lock(); // FIXME: qemu-user doesn't implement ptrace on all architectures // and retunrs ENOSYS in this case. @@ -127,7 +127,7 @@ fn test_ptrace_interrupt() { require_capability!("test_ptrace_interrupt", CAP_SYS_PTRACE); - let _m = crate::FORK_MTX.lock().expect("Mutex got poisoned by another test"); + let _m = crate::FORK_MTX.lock(); match unsafe{fork()}.expect("Error: Fork Failed") { Child => { @@ -173,7 +173,7 @@ fn test_ptrace_syscall() { require_capability!("test_ptrace_syscall", CAP_SYS_PTRACE); - let _m = crate::FORK_MTX.lock().expect("Mutex got poisoned by another test"); + let _m = crate::FORK_MTX.lock(); match unsafe{fork()}.expect("Error: Fork Failed") { Child => { diff --git a/test/sys/test_select.rs b/test/sys/test_select.rs index db079456..2f7396b1 100644 --- a/test/sys/test_select.rs +++ b/test/sys/test_select.rs @@ -5,9 +5,7 @@ use nix::sys::time::{TimeSpec, TimeValLike}; #[test] pub fn test_pselect() { - let _mtx = crate::SIGNAL_MTX - .lock() - .expect("Mutex got poisoned by another test"); + let _mtx = crate::SIGNAL_MTX.lock(); let (r1, w1) = pipe().unwrap(); write(w1, b"hi!").unwrap(); diff --git a/test/sys/test_signal.rs b/test/sys/test_signal.rs index 1b89af57..fdd2568d 100644 --- a/test/sys/test_signal.rs +++ b/test/sys/test_signal.rs @@ -19,7 +19,7 @@ fn test_killpg_none() { #[test] fn test_old_sigaction_flags() { - let _m = crate::SIGNAL_MTX.lock().expect("Mutex got poisoned by another test"); + let _m = crate::SIGNAL_MTX.lock(); extern "C" fn handler(_: ::libc::c_int) {} let act = SigAction::new( @@ -41,7 +41,7 @@ fn test_sigprocmask_noop() { #[test] fn test_sigprocmask() { - let _m = crate::SIGNAL_MTX.lock().expect("Mutex got poisoned by another test"); + let _m = crate::SIGNAL_MTX.lock(); // This needs to be a signal that rust doesn't use in the test harness. const SIGNAL: Signal = Signal::SIGCHLD; @@ -89,7 +89,7 @@ extern fn test_sigaction_action(_: libc::c_int, _: *mut libc::siginfo_t, _: *mut #[test] #[cfg(not(target_os = "redox"))] fn test_signal_sigaction() { - let _m = crate::SIGNAL_MTX.lock().expect("Mutex got poisoned by another test"); + let _m = crate::SIGNAL_MTX.lock(); let action_handler = SigHandler::SigAction(test_sigaction_action); assert_eq!(unsafe { signal(Signal::SIGINT, action_handler) }.unwrap_err(), Errno::ENOTSUP); @@ -97,7 +97,7 @@ fn test_signal_sigaction() { #[test] fn test_signal() { - let _m = crate::SIGNAL_MTX.lock().expect("Mutex got poisoned by another test"); + let _m = crate::SIGNAL_MTX.lock(); unsafe { signal(Signal::SIGINT, SigHandler::SigIgn) }.unwrap(); raise(Signal::SIGINT).unwrap(); diff --git a/test/sys/test_signalfd.rs b/test/sys/test_signalfd.rs index af04c222..b6f748b4 100644 --- a/test/sys/test_signalfd.rs +++ b/test/sys/test_signalfd.rs @@ -6,7 +6,7 @@ fn test_signalfd() { use nix::sys::signal::{self, raise, Signal, SigSet}; // Grab the mutex for altering signals so we don't interfere with other tests. - let _m = crate::SIGNAL_MTX.lock().expect("Mutex got poisoned by another test"); + let _m = crate::SIGNAL_MTX.lock(); // Block the SIGUSR1 signal from automatic processing for this thread let mut mask = SigSet::empty(); diff --git a/test/sys/test_termios.rs b/test/sys/test_termios.rs index 63d6a51f..4a861543 100644 --- a/test/sys/test_termios.rs +++ b/test/sys/test_termios.rs @@ -19,7 +19,7 @@ fn write_all(f: RawFd, buf: &[u8]) { #[test] fn test_tcgetattr_pty() { // openpty uses ptname(3) internally - let _m = crate::PTSNAME_MTX.lock().expect("Mutex got poisoned by another test"); + let _m = crate::PTSNAME_MTX.lock(); let pty = openpty(None, None).expect("openpty failed"); assert!(termios::tcgetattr(pty.slave).is_ok()); @@ -46,7 +46,7 @@ fn test_tcgetattr_ebadf() { #[test] fn test_output_flags() { // openpty uses ptname(3) internally - let _m = crate::PTSNAME_MTX.lock().expect("Mutex got poisoned by another test"); + let _m = crate::PTSNAME_MTX.lock(); // Open one pty to get attributes for the second one let mut termios = { @@ -88,7 +88,7 @@ fn test_output_flags() { #[test] fn test_local_flags() { // openpty uses ptname(3) internally - let _m = crate::PTSNAME_MTX.lock().expect("Mutex got poisoned by another test"); + let _m = crate::PTSNAME_MTX.lock(); // Open one pty to get attributes for the second one let mut termios = { diff --git a/test/sys/test_uio.rs b/test/sys/test_uio.rs index 8f8ba5e4..408537c8 100644 --- a/test/sys/test_uio.rs +++ b/test/sys/test_uio.rs @@ -214,7 +214,7 @@ fn test_process_vm_readv() { use crate::*; require_capability!("test_process_vm_readv", CAP_SYS_PTRACE); - let _m = crate::FORK_MTX.lock().expect("Mutex got poisoned by another test"); + let _m = crate::FORK_MTX.lock(); // Pre-allocate memory in the child, since allocation isn't safe // post-fork (~= async-signal-safe) diff --git a/test/sys/test_wait.rs b/test/sys/test_wait.rs index 4a5b9661..afe4f42b 100644 --- a/test/sys/test_wait.rs +++ b/test/sys/test_wait.rs @@ -8,7 +8,7 @@ use libc::_exit; #[test] #[cfg(not(target_os = "redox"))] fn test_wait_signal() { - let _m = crate::FORK_MTX.lock().expect("Mutex got poisoned by another test"); + let _m = crate::FORK_MTX.lock(); // Safe: The child only calls `pause` and/or `_exit`, which are async-signal-safe. match unsafe{fork()}.expect("Error: Fork Failed") { @@ -25,7 +25,7 @@ fn test_wait_signal() { #[test] fn test_wait_exit() { - let _m = crate::FORK_MTX.lock().expect("Mutex got poisoned by another test"); + let _m = crate::FORK_MTX.lock(); // Safe: Child only calls `_exit`, which is async-signal-safe. match unsafe{fork()}.expect("Error: Fork Failed") { @@ -46,7 +46,7 @@ fn test_waitstatus_from_raw() { #[test] fn test_waitstatus_pid() { - let _m = crate::FORK_MTX.lock().expect("Mutex got poisoned by another test"); + let _m = crate::FORK_MTX.lock(); match unsafe{fork()}.unwrap() { Child => unsafe { _exit(0) }, @@ -97,7 +97,7 @@ mod ptrace { #[test] fn test_wait_ptrace() { require_capability!("test_wait_ptrace", CAP_SYS_PTRACE); - let _m = crate::FORK_MTX.lock().expect("Mutex got poisoned by another test"); + let _m = crate::FORK_MTX.lock(); match unsafe{fork()}.expect("Error: Fork Failed") { Child => ptrace_child(), diff --git a/test/test.rs b/test/test.rs index b882d174..aade937a 100644 --- a/test/test.rs +++ b/test/test.rs @@ -43,7 +43,7 @@ mod test_unistd; use std::os::unix::io::RawFd; use std::path::PathBuf; -use std::sync::{Mutex, RwLock, RwLockWriteGuard}; +use parking_lot::{Mutex, RwLock, RwLockWriteGuard}; use nix::unistd::{chdir, getcwd, read}; @@ -84,8 +84,7 @@ struct DirRestore<'a> { impl<'a> DirRestore<'a> { fn new() -> Self { - let guard = crate::CWD_LOCK.write() - .expect("Lock got poisoned by another test"); + let guard = crate::CWD_LOCK.write(); DirRestore{ _g: guard, d: getcwd().unwrap(), diff --git a/test/test_kmod/mod.rs b/test/test_kmod/mod.rs index 0f7fc48e..8eef5384 100644 --- a/test/test_kmod/mod.rs +++ b/test/test_kmod/mod.rs @@ -5,9 +5,7 @@ use tempfile::{tempdir, TempDir}; use crate::*; fn compile_kernel_module() -> (PathBuf, String, TempDir) { - let _m = crate::FORK_MTX - .lock() - .expect("Mutex got poisoned by another test"); + let _m = crate::FORK_MTX.lock(); let tmp_dir = tempdir().expect("unable to create temporary build directory"); @@ -41,8 +39,8 @@ use std::io::Read; #[test] fn test_finit_and_delete_module() { require_capability!("test_finit_and_delete_module", CAP_SYS_MODULE); - let _m0 = crate::KMOD_MTX.lock().expect("Mutex got poisoned by another test"); - let _m1 = crate::CWD_LOCK.read().expect("Mutex got poisoned by another test"); + let _m0 = crate::KMOD_MTX.lock(); + let _m1 = crate::CWD_LOCK.read(); let (kmod_path, kmod_name, _kmod_dir) = compile_kernel_module(); @@ -59,8 +57,8 @@ fn test_finit_and_delete_module() { #[test] fn test_finit_and_delete_module_with_params() { require_capability!("test_finit_and_delete_module_with_params", CAP_SYS_MODULE); - let _m0 = crate::KMOD_MTX.lock().expect("Mutex got poisoned by another test"); - let _m1 = crate::CWD_LOCK.read().expect("Mutex got poisoned by another test"); + let _m0 = crate::KMOD_MTX.lock(); + let _m1 = crate::CWD_LOCK.read(); let (kmod_path, kmod_name, _kmod_dir) = compile_kernel_module(); @@ -80,8 +78,8 @@ fn test_finit_and_delete_module_with_params() { #[test] fn test_init_and_delete_module() { require_capability!("test_init_and_delete_module", CAP_SYS_MODULE); - let _m0 = crate::KMOD_MTX.lock().expect("Mutex got poisoned by another test"); - let _m1 = crate::CWD_LOCK.read().expect("Mutex got poisoned by another test"); + let _m0 = crate::KMOD_MTX.lock(); + let _m1 = crate::CWD_LOCK.read(); let (kmod_path, kmod_name, _kmod_dir) = compile_kernel_module(); @@ -100,8 +98,8 @@ fn test_init_and_delete_module() { #[test] fn test_init_and_delete_module_with_params() { require_capability!("test_init_and_delete_module_with_params", CAP_SYS_MODULE); - let _m0 = crate::KMOD_MTX.lock().expect("Mutex got poisoned by another test"); - let _m1 = crate::CWD_LOCK.read().expect("Mutex got poisoned by another test"); + let _m0 = crate::KMOD_MTX.lock(); + let _m1 = crate::CWD_LOCK.read(); let (kmod_path, kmod_name, _kmod_dir) = compile_kernel_module(); @@ -121,8 +119,8 @@ fn test_init_and_delete_module_with_params() { #[test] fn test_finit_module_invalid() { require_capability!("test_finit_module_invalid", CAP_SYS_MODULE); - let _m0 = crate::KMOD_MTX.lock().expect("Mutex got poisoned by another test"); - let _m1 = crate::CWD_LOCK.read().expect("Mutex got poisoned by another test"); + let _m0 = crate::KMOD_MTX.lock(); + let _m1 = crate::CWD_LOCK.read(); let kmod_path = "/dev/zero"; @@ -135,8 +133,8 @@ fn test_finit_module_invalid() { #[test] fn test_finit_module_twice_and_delete_module() { require_capability!("test_finit_module_twice_and_delete_module", CAP_SYS_MODULE); - let _m0 = crate::KMOD_MTX.lock().expect("Mutex got poisoned by another test"); - let _m1 = crate::CWD_LOCK.read().expect("Mutex got poisoned by another test"); + let _m0 = crate::KMOD_MTX.lock(); + let _m1 = crate::CWD_LOCK.read(); let (kmod_path, kmod_name, _kmod_dir) = compile_kernel_module(); @@ -157,8 +155,8 @@ fn test_finit_module_twice_and_delete_module() { #[test] fn test_delete_module_not_loaded() { require_capability!("test_delete_module_not_loaded", CAP_SYS_MODULE); - let _m0 = crate::KMOD_MTX.lock().expect("Mutex got poisoned by another test"); - let _m1 = crate::CWD_LOCK.read().expect("Mutex got poisoned by another test"); + let _m0 = crate::KMOD_MTX.lock(); + let _m1 = crate::CWD_LOCK.read(); let result = delete_module(&CString::new("hello").unwrap(), DeleteModuleFlags::empty()); diff --git a/test/test_pty.rs b/test/test_pty.rs index 57874de3..71932f2d 100644 --- a/test/test_pty.rs +++ b/test/test_pty.rs @@ -29,7 +29,7 @@ fn test_explicit_close() { #[test] #[cfg(any(target_os = "android", target_os = "linux"))] fn test_ptsname_equivalence() { - let _m = crate::PTSNAME_MTX.lock().expect("Mutex got poisoned by another test"); + let _m = crate::PTSNAME_MTX.lock(); // Open a new PTTY master let master_fd = posix_openpt(OFlag::O_RDWR).unwrap(); @@ -46,7 +46,7 @@ fn test_ptsname_equivalence() { #[test] #[cfg(any(target_os = "android", target_os = "linux"))] fn test_ptsname_copy() { - let _m = crate::PTSNAME_MTX.lock().expect("Mutex got poisoned by another test"); + let _m = crate::PTSNAME_MTX.lock(); // Open a new PTTY master let master_fd = posix_openpt(OFlag::O_RDWR).unwrap(); @@ -80,7 +80,7 @@ fn test_ptsname_r_copy() { #[test] #[cfg(any(target_os = "android", target_os = "linux"))] fn test_ptsname_unique() { - let _m = crate::PTSNAME_MTX.lock().expect("Mutex got poisoned by another test"); + let _m = crate::PTSNAME_MTX.lock(); // Open a new PTTY master let master1_fd = posix_openpt(OFlag::O_RDWR).unwrap(); @@ -98,7 +98,7 @@ fn test_ptsname_unique() { /// Common setup for testing PTTY pairs fn open_ptty_pair() -> (PtyMaster, File) { - let _m = crate::PTSNAME_MTX.lock().expect("Mutex got poisoned by another test"); + let _m = crate::PTSNAME_MTX.lock(); // Open a new PTTY master let master = posix_openpt(OFlag::O_RDWR).expect("posix_openpt failed"); @@ -114,7 +114,7 @@ fn open_ptty_pair() -> (PtyMaster, File) { let slave_fd = open(Path::new(&slave_name), OFlag::O_RDWR, stat::Mode::empty()).unwrap(); #[cfg(target_os = "illumos")] - // TODO: rewrite using ioctl! + // TODO: rewrite using ioctl! #[allow(clippy::comparison_chain)] { use libc::{ioctl, I_FIND, I_PUSH}; @@ -187,7 +187,7 @@ fn test_write_ptty_pair() { #[test] fn test_openpty() { // openpty uses ptname(3) internally - let _m = crate::PTSNAME_MTX.lock().expect("Mutex got poisoned by another test"); + let _m = crate::PTSNAME_MTX.lock(); let pty = openpty(None, None).unwrap(); assert!(pty.master > 0); @@ -222,7 +222,7 @@ fn test_openpty() { #[test] fn test_openpty_with_termios() { // openpty uses ptname(3) internally - let _m = crate::PTSNAME_MTX.lock().expect("Mutex got poisoned by another test"); + let _m = crate::PTSNAME_MTX.lock(); // Open one pty to get attributes for the second one let mut termios = { @@ -273,9 +273,9 @@ fn test_forkpty() { use nix::sys::signal::*; use nix::sys::wait::wait; // forkpty calls openpty which uses ptname(3) internally. - let _m0 = crate::PTSNAME_MTX.lock().expect("Mutex got poisoned by another test"); + let _m0 = crate::PTSNAME_MTX.lock(); // forkpty spawns a child process - let _m1 = crate::FORK_MTX.lock().expect("Mutex got poisoned by another test"); + let _m1 = crate::FORK_MTX.lock(); let string = "naninani\n"; let echoed_string = "naninani\r\n"; diff --git a/test/test_unistd.rs b/test/test_unistd.rs index 3a3d49dd..3a1f9f10 100644 --- a/test/test_unistd.rs +++ b/test/test_unistd.rs @@ -28,7 +28,7 @@ use crate::*; #[test] #[cfg(not(any(target_os = "netbsd")))] fn test_fork_and_waitpid() { - let _m = crate::FORK_MTX.lock().expect("Mutex got poisoned by another test"); + let _m = crate::FORK_MTX.lock(); // Safe: Child only calls `_exit`, which is signal-safe match unsafe{fork()}.expect("Error: Fork Failed") { @@ -56,7 +56,7 @@ fn test_fork_and_waitpid() { #[test] fn test_wait() { // Grab FORK_MTX so wait doesn't reap a different test's child process - let _m = crate::FORK_MTX.lock().expect("Mutex got poisoned by another test"); + let _m = crate::FORK_MTX.lock(); // Safe: Child only calls `_exit`, which is signal-safe match unsafe{fork()}.expect("Error: Fork Failed") { @@ -116,7 +116,7 @@ fn test_mkfifo_directory() { target_os = "macos", target_os = "ios", target_os = "android", target_os = "redox")))] fn test_mkfifoat_none() { - let _m = crate::CWD_LOCK.read().expect("Mutex got poisoned by another test"); + let _m = crate::CWD_LOCK.read(); let tempdir = tempdir().unwrap(); let mkfifoat_fifo = tempdir.path().join("mkfifoat_fifo"); @@ -151,7 +151,7 @@ fn test_mkfifoat() { target_os = "macos", target_os = "ios", target_os = "android", target_os = "redox")))] fn test_mkfifoat_directory_none() { - let _m = crate::CWD_LOCK.read().expect("Mutex got poisoned by another test"); + let _m = crate::CWD_LOCK.read(); // mkfifoat should fail if a directory is given assert!(!mkfifoat(None, &env::temp_dir(), Mode::S_IRUSR).is_ok()); @@ -206,7 +206,7 @@ fn test_setgroups() { // Skip this test when not run as root as `setgroups()` requires root. skip_if_not_root!("test_setgroups"); - let _m = crate::GROUPS_MTX.lock().expect("Mutex got poisoned by another test"); + let _m = crate::GROUPS_MTX.lock(); // Save the existing groups let old_groups = getgroups().unwrap(); @@ -234,7 +234,7 @@ fn test_initgroups() { // require root. skip_if_not_root!("test_initgroups"); - let _m = crate::GROUPS_MTX.lock().expect("Mutex got poisoned by another test"); + let _m = crate::GROUPS_MTX.lock(); // Save the existing groups let old_groups = getgroups().unwrap(); @@ -304,7 +304,7 @@ macro_rules! execve_test_factory( skip_if_seccomp!($test_name); } - let m = crate::FORK_MTX.lock().expect("Mutex got poisoned by another test"); + let m = crate::FORK_MTX.lock(); // The `exec`d process will write to `writer`, and we'll read that // data from `reader`. let (reader, writer) = pipe().unwrap(); @@ -575,7 +575,7 @@ fn test_acct() { use std::process::Command; use std::{thread, time}; - let _m = crate::FORK_MTX.lock().expect("Mutex got poisoned by another test"); + let _m = crate::FORK_MTX.lock(); require_acct!(); let file = NamedTempFile::new().unwrap(); @@ -735,7 +735,7 @@ fn test_alarm() { }; // Maybe other tests that fork interfere with this one? - let _m = crate::SIGNAL_MTX.lock().expect("Mutex got poisoned by another test"); + let _m = crate::SIGNAL_MTX.lock(); let handler = SigHandler::Handler(alarm_signal_handler); let signal_action = SigAction::new(handler, SaFlags::SA_RESTART, SigSet::empty()); @@ -773,7 +773,7 @@ fn test_alarm() { #[test] #[cfg(not(target_os = "redox"))] fn test_canceling_alarm() { - let _m = crate::SIGNAL_MTX.lock().expect("Mutex got poisoned by another test"); + let _m = crate::SIGNAL_MTX.lock(); assert_eq!(alarm::cancel(), None); @@ -784,7 +784,7 @@ fn test_canceling_alarm() { #[test] #[cfg(not(target_os = "redox"))] fn test_symlinkat() { - let _m = crate::CWD_LOCK.read().expect("Mutex got poisoned by another test"); + let _m = crate::CWD_LOCK.read(); let tempdir = tempdir().unwrap(); @@ -883,7 +883,7 @@ fn test_linkat_newdirfd_none() { #[test] #[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "redox")))] fn test_linkat_no_follow_symlink() { - let _m = crate::CWD_LOCK.read().expect("Mutex got poisoned by another test"); + let _m = crate::CWD_LOCK.read(); let tempdir = tempdir().unwrap(); let oldfilename = "foo.txt"; @@ -920,7 +920,7 @@ fn test_linkat_no_follow_symlink() { #[test] #[cfg(not(target_os = "redox"))] fn test_linkat_follow_symlink() { - let _m = crate::CWD_LOCK.read().expect("Mutex got poisoned by another test"); + let _m = crate::CWD_LOCK.read(); let tempdir = tempdir().unwrap(); let oldfilename = "foo.txt"; -- cgit v1.2.3