diff options
author | Alan Somers <asomers@gmail.com> | 2019-05-26 18:20:04 -0600 |
---|---|---|
committer | Alan Somers <asomers@gmail.com> | 2019-06-06 08:54:18 -0600 |
commit | 129485cfa3455b7eda3217e36ee89d4ca75d38b2 (patch) | |
tree | dc0595bc5fc596539f21a0f3ab6528d2da3d003f | |
parent | d39bdbdd9cbe6bb5c782c8ea14932ec62c272764 (diff) | |
download | nix-129485cfa3455b7eda3217e36ee89d4ca75d38b2.zip |
Fix multiple problems with the test_acct test
* On Linux, it requires the CAP_SYS_PACCT capability.
* Reenable the test on FreeBSD, because our FreeBSD CI environment is no
longer jailed (since we switched from BuildBot to CirrusCI), but check
at runtime whether the process is jailed.
* test_acct needs the FORK_MTX because it uses Command::new .
* Fix a race condition. acct(2) isn't synchronous. It starts a kernel
thread but does not wait for it to become ready. Fix it by running
the test command within the polling loop.
-rw-r--r-- | test/test.rs | 25 | ||||
-rw-r--r-- | test/test_unistd.rs | 34 |
2 files changed, 50 insertions, 9 deletions
diff --git a/test/test.rs b/test/test.rs index 0a3d3b74..c8b8717f 100644 --- a/test/test.rs +++ b/test/test.rs @@ -9,6 +9,8 @@ extern crate nix; extern crate lazy_static; extern crate libc; extern crate rand; +#[cfg(target_os = "freebsd")] +extern crate sysctl; extern crate tempfile; #[cfg(any(target_os = "android", target_os = "linux"))] @@ -27,14 +29,31 @@ macro_rules! require_capability { } } +#[cfg(target_os = "freebsd")] +macro_rules! skip_if_jailed { + ($name:expr) => { + use ::sysctl::CtlValue; + + if let CtlValue::Int(1) = ::sysctl::value("security.jail.jailed") + .unwrap() + { + use ::std::io::Write; + let stderr = ::std::io::stderr(); + let mut handle = stderr.lock(); + writeln!(handle, "{} cannot run in a jail. Skipping test.", $name) + .unwrap(); + return; + } + } +} + macro_rules! skip_if_not_root { ($name:expr) => { use nix::unistd::Uid; - use std; - use std::io::Write; if !Uid::current().is_root() { - let stderr = std::io::stderr(); + use ::std::io::Write; + let stderr = ::std::io::stderr(); let mut handle = stderr.lock(); writeln!(handle, "{} requires root privileges. Skipping test.", $name).unwrap(); return; diff --git a/test/test_unistd.rs b/test/test_unistd.rs index 3f13883c..73ed845e 100644 --- a/test/test_unistd.rs +++ b/test/test_unistd.rs @@ -387,28 +387,50 @@ fn test_lseek64() { close(tmpfd).unwrap(); } -// Skip on FreeBSD because FreeBSD's CI environment is jailed, and jails -// aren't allowed to use acct(2) -#[cfg(not(target_os = "freebsd"))] +cfg_if!{ + if #[cfg(any(target_os = "android", target_os = "linux"))] { + macro_rules! require_acct{ + () => { + require_capability!(CAP_SYS_PACCT); + } + } + } else if #[cfg(target_os = "freebsd")] { + macro_rules! require_acct{ + () => { + skip_if_not_root!("test_acct"); + skip_if_jailed!("test_acct"); + } + } + } else { + macro_rules! require_acct{ + () => { + skip_if_not_root!("test_acct"); + } + } + } +} + #[test] fn test_acct() { use tempfile::NamedTempFile; use std::process::Command; use std::{thread, time}; - skip_if_not_root!("test_acct"); + let _m = ::FORK_MTX.lock().expect("Mutex got poisoned by another test"); + require_acct!(); + let file = NamedTempFile::new().unwrap(); let path = file.path().to_str().unwrap(); acct::enable(path).unwrap(); - Command::new("echo").arg("Hello world"); - acct::disable().unwrap(); loop { + Command::new("echo").arg("Hello world"); let len = fs::metadata(path).unwrap().len(); if len > 0 { break; } thread::sleep(time::Duration::from_millis(10)); } + acct::disable().unwrap(); } #[test] |