#![cfg(unix)]
use assert_cmd::cargo::CommandCargoExt;
use std::os::unix::process::CommandExt;
use std::process::Command;
use std::sync::atomic::{AtomicUsize, Ordering};
static COUNTER: AtomicUsize = AtomicUsize::new(0);
fn unique_name() -> String {
let n = COUNTER.fetch_add(1, Ordering::SeqCst);
format!("pca{}n{n}x", std::process::id())
}
fn from_inside_a_shell(name: &str, dir: &std::path::Path, args: &[&str]) -> (String, i32) {
let proc_path = Command::cargo_bin("proc").unwrap();
let script = format!(
"'{}' {}; code=$?; exit $code",
proc_path.get_program().to_string_lossy(),
args.join(" ")
);
let output = Command::new("sh")
.arg0(name)
.arg("-c")
.arg(script)
.current_dir(dir)
.env("NO_COLOR", "1")
.output()
.unwrap();
(
String::from_utf8(output.stdout).unwrap(),
output.status.code().unwrap(),
)
}
#[test]
fn the_shell_that_ran_proc_is_never_listed() {
let dir = tempfile::tempdir().unwrap();
for cmd in [false, true] {
let name = unique_name();
let flag: &[&str] = if cmd { &["--cmd"] } else { &[] };
let with_flag = |args: &[&str]| -> Vec<String> {
args.iter()
.map(|a| a.to_string())
.chain(flag.iter().map(|a| a.to_string()))
.collect()
};
let run = |args: &[&str]| {
let args = with_flag(args);
let args: Vec<&str> = args.iter().map(String::as_str).collect();
from_inside_a_shell(&name, dir.path(), &args)
};
for args in [
vec!["by", &name, "--json"],
vec!["kill", &name, "--dry-run", "--json"],
vec!["in", ".", "--by", &name, "--json"],
] {
let (out, code) = run(&args);
assert_eq!(code, 2, "{args:?} (--cmd: {cmd}): {out}");
assert!(!out.contains("\"pid\""), "{args:?} (--cmd: {cmd}): {out}");
}
let (out, code) = run(&["watch", &name]);
assert_eq!(code, 0, "watch (--cmd: {cmd}): {out}");
assert!(
out.contains("No processes found"),
"watch (--cmd: {cmd}): {out}"
);
}
}