#[cfg(unix)]
use start_command::user_manager::get_current_user_groups;
use start_command::user_manager::{generate_isolated_username, get_current_user, user_exists};
#[test]
fn get_current_user_returns_non_empty_string() {
let user = get_current_user();
assert!(!user.is_empty(), "Expected non-empty username");
}
#[test]
fn get_current_user_returns_known_user() {
let user = get_current_user();
assert!(!user.is_empty());
}
#[test]
#[cfg(unix)]
fn get_current_user_groups_returns_non_empty_vec() {
let groups = get_current_user_groups();
assert!(!groups.is_empty(), "Expected at least one group");
}
#[test]
#[cfg(unix)]
fn get_current_user_groups_returns_strings() {
let groups = get_current_user_groups();
for g in &groups {
assert!(!g.is_empty(), "Group names should not be empty");
}
}
#[test]
fn generate_isolated_username_with_no_prefix_starts_with_start_dash() {
let name = generate_isolated_username(None);
assert!(name.starts_with("start-"), "Expected a 'start-' prefix");
}
#[test]
fn generate_isolated_username_with_no_prefix_length_at_most_31() {
let name = generate_isolated_username(None);
assert!(
name.len() <= 31,
"Expected length <= 31, got: {}",
name.len()
);
}
#[test]
fn generate_isolated_username_with_custom_prefix() {
let name = generate_isolated_username(Some("test"));
assert!(name.starts_with("test-"), "Expected a 'test-' prefix");
}
#[test]
fn generate_isolated_username_returns_unique_names() {
let name1 = generate_isolated_username(None);
std::thread::sleep(std::time::Duration::from_millis(2));
let name2 = generate_isolated_username(None);
assert_ne!(name1, name2, "Expected unique names");
}
#[test]
fn generate_isolated_username_draws_the_suffix_from_a_csprng() {
use std::collections::HashSet;
let mut suffixes = HashSet::new();
for _ in 0..500 {
let name = generate_isolated_username(None);
assert!(
name.strip_prefix("start-")
.is_some_and(|rest| rest.chars().all(|c| c.is_ascii_alphanumeric())),
"expected a 'start-' prefix followed by alphanumerics"
);
suffixes.insert(name[name.len() - 4..].to_string());
}
assert!(
suffixes.len() > 100,
"expected a wide spread of suffixes, got {}",
suffixes.len()
);
let source = std::fs::read_to_string(
std::path::Path::new(env!("CARGO_MANIFEST_DIR")).join("src/lib/user_manager.rs"),
)
.expect("cannot read src/lib/user_manager.rs");
assert!(
!source.contains("fn simple_random"),
"the suffix must come from the OS CSPRNG, not a hand-rolled generator"
);
assert!(
source.contains("Uuid::new_v4"),
"random_base36 must draw from uuid::Uuid::new_v4 (getrandom)"
);
}
#[test]
fn user_exists_returns_false_for_nonexistent_user() {
assert!(!user_exists(
"this_user_definitely_does_not_exist_xyzzy_12345"
));
}
#[test]
#[cfg(unix)]
fn user_exists_returns_true_for_root() {
assert!(user_exists("root"), "Expected 'root' user to exist on Unix");
}