#![cfg(feature = "_containerized-integration-test")]
use std::collections::HashMap;
use std::path::Path;
use change_user_run::{create_users, run_command_as_user};
use log::{LevelFilter, debug};
use nix::unistd::User;
use rstest::rstest;
use simplelog::{ColorChoice, Config, TermLogger, TerminalMode};
use testresult::TestResult;
fn init_logger() {
if TermLogger::init(
LevelFilter::Trace,
Config::default(),
TerminalMode::Stderr,
ColorChoice::Auto,
)
.is_err()
{
debug!("Not initializing another logger, as one is initialized already.");
}
}
mod user {
use super::*;
struct TestInput<'a> {
pub users: &'a [&'a str],
pub home_base_dir: Option<&'a Path>,
pub shell: Option<&'a Path>,
}
#[rstest]
#[case(TestInput{
users: &["testuser1", "testuser2"],
home_base_dir: None,
shell: None,
})]
#[case(TestInput{
users: &["testuser1", "testuser2"],
home_base_dir: Some(Path::new("/usr/share/test")),
shell: Some(Path::new("/bin/bash")),
})]
fn create_users_succeeds(#[case] input: TestInput) -> TestResult {
init_logger();
create_users(input.users, input.home_base_dir, input.shell)?;
for user in input.users {
let home_dir = input.home_base_dir.unwrap_or(Path::new("/home")).join(user);
if !home_dir.is_dir() {
panic!("The directory {home_dir:?} should exist as home for user {user}");
}
let Some(user) = User::from_name(user)? else {
panic!("The user {user} should exist!");
};
assert_eq!(
user.shell.as_path(),
if let Some(shell) = input.shell {
shell
} else {
Path::new("/usr/bin/bash")
}
)
}
Ok(())
}
}
mod command {
use super::*;
struct TestInput<'a> {
pub command: &'a str,
pub command_args: &'a [&'a str],
pub command_input: Option<&'a [u8]>,
pub env_list: &'a [&'a str],
pub user: &'a str,
pub envs: Option<HashMap<String, String>>,
}
#[cfg(target_os = "linux")]
#[rstest]
#[case::whoami(
TestInput{
command: "whoami",
command_args: &[],
command_input: None,
env_list: &[],
user: "testuser",
envs: None,
},
"testuser\n",
)]
#[case::cut_with_input(
TestInput{
command: "cut",
command_args: &["-f", "1", "-d", " "],
command_input: Some("foo bar".as_bytes()),
env_list: &[],
user: "testuser",
envs: None,
},
"foo\n",
)]
#[case::echo_env_var(
TestInput{
command: "bash",
command_args: &["-c", "echo $FOO"],
command_input: None,
env_list: &[
"LLVM_PROFILE_FILE",
"CARGO_LLVM_COV",
"CARGO_LLVM_COV_SHOW_ENV",
"CARGO_LLVM_COV_TARGET_DIR",
"RUSTFLAGS",
"RUSTDOCFLAGS",
],
user: "testuser",
envs: Some(HashMap::from([("FOO".to_string(), "BAR".to_string())])),
},
"BAR\n",
)]
fn run_command_as_user_succeeds(#[case] input: TestInput, #[case] output: &str) -> TestResult {
init_logger();
create_users(&[input.user], None, None)?;
let cmd_output = run_command_as_user(
input.command,
input.command_args,
input.command_input,
input.env_list,
input.envs,
input.user,
)?;
debug!("{output}");
assert_eq!(output, cmd_output.stdout);
Ok(())
}
}