#![cfg(unix)]
use super::*;
use crate::test_support::{fixture, remove};
use std::path::PathBuf;
fn add_process(table: &Path, outer: i64, status: Option<&str>) {
let process: PathBuf = table.join(outer.to_string());
std::fs::create_dir_all(process.as_path()).expect("fake process");
if let Some(text) = status {
std::fs::write(process.join("status"), text).expect("status");
}
}
#[test]
fn a_process_numbered_inside_a_nested_namespace_holds_that_number() {
let root: PathBuf = fixture("nested-numbers-holder");
add_process(root.as_path(), 9001, Some("Name:\tsh\nNSpid:\t9001\t7\n"));
assert_eq!(nested_holders_of(root.as_path(), 7), Ok(vec![9001]));
assert_eq!(nested_holders_of(root.as_path(), 8), Ok(Vec::new()));
remove(root.as_path());
}
#[test]
fn the_readers_own_number_is_not_a_nested_one() {
let root: PathBuf = fixture("nested-numbers-own");
add_process(root.as_path(), 9001, Some("Name:\tsh\nNSpid:\t9001\n"));
assert_eq!(nested_holders_of(root.as_path(), 9001), Ok(Vec::new()));
remove(root.as_path());
}
#[test]
fn a_process_that_ended_during_the_listing_holds_nothing() {
let root: PathBuf = fixture("nested-numbers-ended");
add_process(root.as_path(), 9001, None);
assert_eq!(nested_holders_of(root.as_path(), 7), Ok(Vec::new()));
remove(root.as_path());
}
#[test]
fn a_status_without_the_namespace_line_leaves_the_question_open() {
let root: PathBuf = fixture("nested-numbers-no-line");
add_process(root.as_path(), 9001, Some("Name:\tsh\n"));
assert!(nested_holders_of(root.as_path(), 7).is_err());
remove(root.as_path());
}
#[test]
fn a_table_that_cannot_be_listed_leaves_the_question_open() {
let root: PathBuf = fixture("nested-numbers-no-table");
assert!(nested_holders_of(root.join("absent").as_path(), 7).is_err());
remove(root.as_path());
}
#[test]
fn an_unreadable_status_leaves_the_question_open() {
use std::os::unix::fs::PermissionsExt as _;
let root: PathBuf = fixture("nested-numbers-unreadable");
add_process(root.as_path(), 9001, Some("Name:\tsh\nNSpid:\t9001\n"));
let status: PathBuf = root.join("9001").join("status");
std::fs::set_permissions(status.as_path(), std::fs::Permissions::from_mode(0o000)).expect("hide the status");
let answer = nested_holders_of(root.as_path(), 7);
std::fs::set_permissions(status.as_path(), std::fs::Permissions::from_mode(0o600)).expect("reveal the status");
if unsafe { libc::geteuid() } == 0 {
eprintln!("skipped: a superuser reads a file whose mode hides it");
} else {
assert!(answer.is_err(), "{answer:?}");
}
remove(root.as_path());
}