Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 32 additions & 7 deletions crates/openshell-binary-identity/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,8 @@ fn cmdline_absolute_paths(cmdline: &[u8]) -> Vec<std::path::PathBuf> {
mod tests {
use super::*;

const IDENTITY_HELPER_READY: &str = "identity helper ready\n";

struct ChildGuard(std::process::Child);

impl Drop for ChildGuard {
Expand All @@ -474,20 +476,22 @@ mod tests {
#[cfg(target_os = "linux")]
#[test]
fn resolver_cache_is_owned_and_only_explicit_clones_share_it() {
let first = ProcfsIdentityResolver::for_pid_namespace();
let pid = std::process::id();
let first = ProcfsIdentityResolver::for_process_tree(pid);
let shared = first.clone();
let separate = ProcfsIdentityResolver::for_pid_namespace();
let separate = ProcfsIdentityResolver::for_process_tree(pid);
assert!(Arc::ptr_eq(&first.cache, &shared.cache));
assert!(!Arc::ptr_eq(&first.cache, &separate.cache));
first.resolve(std::process::id()).unwrap();
first.resolve(pid).unwrap();
assert!(!shared.cache.lock().unwrap().is_empty());
assert!(separate.cache.lock().unwrap().is_empty());
}

#[test]
fn resolves_current_process_from_live_executable() {
let identity = ProcfsIdentityResolver::for_pid_namespace()
.resolve(std::process::id())
let pid = std::process::id();
let identity = ProcfsIdentityResolver::for_process_tree(pid)
.resolve(pid)
.expect("resolve current process");

assert!(identity.executable.path.is_absolute());
Expand All @@ -497,16 +501,37 @@ mod tests {
#[test]
#[ignore = "subprocess fixture for executable identity tests"]
fn identity_helper_process() {
std::thread::sleep(std::time::Duration::from_secs(30));
let mut stdout = std::io::stdout();
std::io::Write::write_all(&mut stdout, IDENTITY_HELPER_READY.as_bytes())
.expect("signal helper readiness");
std::io::Write::flush(&mut stdout).expect("flush helper readiness");

// Stay alive until the parent closes stdin or ChildGuard terminates us.
let _ = std::io::Read::read(&mut std::io::stdin(), &mut [0_u8]);
}

#[test]
fn resolves_child_and_hashes_ancestor_chain() {
let parent_pid = std::process::id();
let child = std::process::Command::new(std::env::current_exe().unwrap())
let mut child = std::process::Command::new(std::env::current_exe().unwrap())
.args(["--ignored", "--exact", "tests::identity_helper_process"])
.stdin(std::process::Stdio::piped())
.stdout(std::process::Stdio::piped())
.spawn()
.expect("spawn child");
let mut child_stdout = std::io::BufReader::new(child.stdout.take().expect("child stdout"));
let mut line = String::new();
// Wait until the helper has entered the test before taking the
// fail-closed procfs snapshot of the newly spawned process.
loop {
line.clear();
let bytes_read = std::io::BufRead::read_line(&mut child_stdout, &mut line)
.expect("read child readiness");
assert_ne!(bytes_read, 0, "child exited before signaling readiness");
if line == IDENTITY_HELPER_READY {
break;
}
}
let child = ChildGuard(child);

let identity = ProcfsIdentityResolver::for_process_tree(parent_pid)
Expand Down
Loading