use processkit::Command;
pub(crate) fn skip_unless_enabled(scenario: &str) -> bool {
if std::env::var_os("PROCESSKIT_STRESS").is_some() {
return false;
}
eprintln!("[stress] skipping {scenario}: set PROCESSKIT_STRESS=1 to run");
true
}
pub(crate) fn quick_exit() -> Command {
if cfg!(windows) {
Command::new("cmd").args(["/c", "exit", "0"])
} else {
Command::new("true")
}
}
pub(crate) fn always_fail() -> Command {
if cfg!(windows) {
Command::new("cmd").args(["/c", "exit", "1"])
} else {
Command::new("sh").args(["-c", "exit 1"])
}
}
pub(crate) fn line_emitter(n: u32) -> Command {
if cfg!(windows) {
Command::new("powershell").args([
"-NoProfile",
"-Command",
&format!("for ($i = 1; $i -le {n}; $i++) {{ $i }}"),
])
} else {
Command::new("seq").arg(n.to_string())
}
}
pub(crate) fn long_sleeper() -> Command {
if cfg!(windows) {
Command::new("ping").args(["-n", "91", "127.0.0.1"])
} else {
Command::new("sleep").arg("90")
}
}
#[cfg(target_os = "linux")]
pub(crate) fn open_handle_count() -> Option<usize> {
std::fs::read_dir("/proc/self/fd")
.ok()
.map(|dir| dir.count())
}
#[cfg(target_os = "macos")]
pub(crate) fn open_handle_count() -> Option<usize> {
let pid = std::process::id().to_string();
let output = std::process::Command::new("lsof")
.args(["-p", &pid])
.output()
.ok()?;
if !output.status.success() {
return None;
}
Some(
String::from_utf8_lossy(&output.stdout)
.lines()
.count()
.saturating_sub(1),
)
}
#[cfg(windows)]
pub(crate) fn open_handle_count() -> Option<usize> {
use windows_sys::Win32::System::Threading::{GetCurrentProcess, GetProcessHandleCount};
let mut count: u32 = 0;
let ok = unsafe { GetProcessHandleCount(GetCurrentProcess(), &mut count) };
(ok != 0).then_some(count as usize)
}
#[cfg(not(any(target_os = "linux", target_os = "macos", windows)))]
pub(crate) fn open_handle_count() -> Option<usize> {
None
}
#[cfg(target_os = "linux")]
pub(crate) fn own_cgroup_v2_parent() -> Option<std::path::PathBuf> {
for candidate in ["/sys/fs/cgroup", "/sys/fs/cgroup/unified"] {
let root = std::path::Path::new(candidate);
if !root.join("cgroup.controllers").exists() {
continue;
}
let self_cgroup = std::fs::read_to_string("/proc/self/cgroup").ok()?;
let rel = self_cgroup
.lines()
.find_map(|line| line.strip_prefix("0::"))
.unwrap_or("/")
.trim();
return Some(root.join(rel.trim_start_matches('/')));
}
None
}
#[cfg(target_os = "linux")]
pub(crate) fn own_processkit_cgroup_dirs(parent: &std::path::Path) -> Vec<std::path::PathBuf> {
let prefix = format!("processkit-{}-", std::process::id());
std::fs::read_dir(parent)
.map(|entries| {
entries
.filter_map(|e| e.ok())
.map(|e| e.path())
.filter(|p| {
p.file_name()
.and_then(|n| n.to_str())
.is_some_and(|n| n.starts_with(&prefix))
})
.collect()
})
.unwrap_or_default()
}