Skip to content
Open
Show file tree
Hide file tree
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
25 changes: 13 additions & 12 deletions tests/by-util/test_chroot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use uutests::at_and_ucmd;
use uutests::new_ucmd;
#[cfg(not(target_os = "android"))]
use uutests::util::is_ci;
use uutests::util::{TestScenario, run_ucmd_as_root};
use uutests::util::{TestScenario, run_ucmd_as_root, run_ucmd_as_root_to_migrate};
use uutests::util_name;

#[test]
Expand Down Expand Up @@ -57,12 +57,13 @@ fn test_no_such_directory() {
}

#[test]
#[cfg(not(target_os = "macos"))]
fn test_multiple_group_args() {
let ts = TestScenario::new(util_name!());
let at = &ts.fixtures;
at.mkdir("id");

if let Ok(result) = run_ucmd_as_root(
if let Ok(result) = run_ucmd_as_root_to_migrate(
&ts,
&["--groups='invalid ignored'", "--groups=''", "/", "id", "-G"],
) {
Expand All @@ -80,7 +81,7 @@ fn test_invalid_user_spec() {
result
.failure()
.code_is(125)
.stderr_is("chroot: invalid user");
.stderr_is("chroot: invalid user\n");
} else {
print!("Test skipped; requires root user");
}
Expand All @@ -89,7 +90,7 @@ fn test_invalid_user_spec() {
result
.failure()
.code_is(125)
.stderr_is("chroot: invalid user");
.stderr_is("chroot: invalid user\n");
} else {
print!("Test skipped; requires root user");
}
Expand All @@ -98,7 +99,7 @@ fn test_invalid_user_spec() {
result
.failure()
.code_is(125)
.stderr_is("chroot: invalid group");
.stderr_is("chroot: invalid group\n");
} else {
print!("Test skipped; requires root user");
}
Expand All @@ -111,14 +112,14 @@ fn test_invalid_user() {

let dir = "CHROOT_DIR";
at.mkdir(dir);
if let Ok(result) = run_ucmd_as_root(&ts, &[dir, "whoami"]) {
if let Ok(result) = run_ucmd_as_root_to_migrate(&ts, &[dir, "whoami"]) {
result.success().no_stderr().stdout_is("root");
} else {
print!("Test skipped; requires root user");
}

// `--user` is an abbreviation of `--userspec`.
if let Ok(result) = run_ucmd_as_root(&ts, &["--user=nobody:+65535", dir, "pwd"]) {
if let Ok(result) = run_ucmd_as_root_to_migrate(&ts, &["--user=nobody:+65535", dir, "pwd"]) {
result.failure().stderr_is("chroot: invalid user");
} else {
print!("Test skipped; requires root user");
Expand Down Expand Up @@ -181,7 +182,7 @@ fn test_default_shell() {
let shell = std::env::var("SHELL").unwrap_or_else(|_| "/bin/sh".to_string());
let expected = format!("chroot: failed to run command '{shell}': No such file or directory");

if let Ok(result) = run_ucmd_as_root(&ts, &[dir]) {
if let Ok(result) = run_ucmd_as_root_to_migrate(&ts, &[dir]) {
result.stderr_contains(expected);
} else {
print!("Test skipped; requires root user");
Expand All @@ -195,13 +196,13 @@ fn test_chroot() {

let dir = "CHROOT_DIR";
at.mkdir(dir);
if let Ok(result) = run_ucmd_as_root(&ts, &[dir, "whoami"]) {
if let Ok(result) = run_ucmd_as_root_to_migrate(&ts, &[dir, "whoami"]) {
result.success().no_stderr().stdout_is("root");
} else {
print!("Test skipped; requires root user");
}

if let Ok(result) = run_ucmd_as_root(&ts, &[dir, "pwd"]) {
if let Ok(result) = run_ucmd_as_root_to_migrate(&ts, &[dir, "pwd"]) {
result.success().no_stderr().stdout_is("/");
} else {
print!("Test skipped; requires root user");
Expand Down Expand Up @@ -229,7 +230,7 @@ fn test_chroot_skip_chdir() {
at.symlink_file("/", "isroot");
for dir in dirs {
let env_cd = std::env::current_dir().unwrap();
if let Ok(result) = run_ucmd_as_root(&ts, &[dir, "--skip-chdir"]) {
if let Ok(result) = run_ucmd_as_root_to_migrate(&ts, &[dir, "--skip-chdir"]) {
// Should return the same path
assert_eq!(
result.success().no_stderr().stdout_str(),
Expand All @@ -250,7 +251,7 @@ fn test_chroot_extra_arg() {
at.mkdir(dir);
let env_cd = std::env::current_dir().unwrap();
// Verify that -P is pwd's and not chroot
if let Ok(result) = run_ucmd_as_root(&ts, &[dir, "pwd", "-P"]) {
if let Ok(result) = run_ucmd_as_root_to_migrate(&ts, &[dir, "pwd", "-P"]) {
assert_eq!(
result.success().no_stderr().stdout_str(),
env_cd.to_str().unwrap()
Expand Down
10 changes: 7 additions & 3 deletions tests/by-util/test_install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,9 @@

#[cfg(not(target_os = "openbsd"))]
use filetime::FileTime;
use std::fs;
#[cfg(target_os = "linux")]
use std::os::unix::ffi::OsStringExt;
use std::os::unix::fs::{MetadataExt, PermissionsExt};
use std::os::unix::fs::PermissionsExt;
#[cfg(not(windows))]
use std::process::Command;
#[cfg(any(target_os = "linux", target_os = "android"))]
Expand All @@ -19,7 +18,7 @@ use uucore::process::{getegid, geteuid};
use uucore::selinux::get_getfattr_output;
use uutests::at_and_ucmd;
use uutests::new_ucmd;
use uutests::util::{TestScenario, is_ci, run_ucmd_as_root};
use uutests::util::{TestScenario, is_ci};
use uutests::util_name;

#[test]
Expand Down Expand Up @@ -2017,7 +2016,12 @@ fn test_target_file_ends_with_slash() {
}

#[test]
#[cfg(not(target_os = "macos"))]
fn test_install_root_combined() {
use std::fs;
use std::os::unix::fs::MetadataExt;
use uutests::util::run_ucmd_as_root;

let ts = TestScenario::new(util_name!());
let at = &ts.fixtures;
at.touch("a");
Expand Down
79 changes: 45 additions & 34 deletions tests/uutests/src/lib/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3143,50 +3143,61 @@ pub fn run_ucmd_as_root(
run_ucmd_as_root_with_stdin_stdout(ts, args, None, None)
}

// Using this function as a temporary measure to keep the tests that are not passing
// either locally or on the build fleet to be able to allow all of the tests that require root
// to pass. This will be removed one all of the tests that use this are fixed.
#[cfg(unix)]
pub fn run_ucmd_as_root_with_stdin_stdout(
pub fn run_ucmd_as_root_to_migrate(
ts: &TestScenario,
args: &[&str],
stdin: Option<&str>,
stdout: Option<&str>,
) -> std::result::Result<CmdResult, String> {
if is_ci() {
Err(format!("{UUTILS_INFO}: {}", "cannot run inside CI"))
} else {
// check if we can run 'sudo'
log_info("run", "sudo -E --non-interactive whoami");
match Command::new("sudo")
.envs(DEFAULT_ENV)
.args(["-E", "--non-interactive", "whoami"])
.output()
{
Ok(output) if String::from_utf8_lossy(&output.stdout).eq("root\n") => {
// we can run sudo and we're root
// run ucmd as root:
let mut cmd = ts.cmd("sudo");
cmd.env("PATH", PATH)
.envs(DEFAULT_ENV)
.arg("-E")
.arg("--non-interactive")
.arg(&ts.bin_path)
.arg(&ts.util_name)
.args(args);
if let Some(stdin) = stdin {
cmd.set_stdin(File::open(stdin).unwrap());
}
if let Some(stdout) = stdout {
cmd.set_stdout(File::open(stdout).unwrap());
}
Ok(cmd.run())
run_ucmd_as_root_with_stdin_stdout(ts, args, None, None)
}
}

#[cfg(unix)]
pub fn run_ucmd_as_root_with_stdin_stdout(
ts: &TestScenario,
args: &[&str],
stdin: Option<&str>,
stdout: Option<&str>,
) -> std::result::Result<CmdResult, String> {
// check if we can run 'sudo'
log_info("run", "sudo -E --non-interactive whoami");
match Command::new("sudo")
.envs(DEFAULT_ENV)
.args(["-E", "--non-interactive", "whoami"])
.output()
{
Ok(output) if String::from_utf8_lossy(&output.stdout).eq("root\n") => {
// we can run sudo and we're root
// run ucmd as root:
let mut cmd = ts.cmd("sudo");
cmd.env("PATH", PATH)
.envs(DEFAULT_ENV)
.arg("-E")
.arg("--non-interactive")
.arg(&ts.bin_path)
.arg(&ts.util_name)
.args(args);
if let Some(stdin) = stdin {
cmd.set_stdin(File::open(stdin).unwrap());
}
Ok(output)
if String::from_utf8_lossy(&output.stderr).eq("sudo: a password is required\n") =>
{
Err("Cannot run non-interactive sudo".to_string())
if let Some(stdout) = stdout {
cmd.set_stdout(File::open(stdout).unwrap());
}
Ok(_output) => Err("\"sudo whoami\" didn't return \"root\"".to_string()),
Err(e) => Err(format!("{UUTILS_WARNING}: {e}")),
Ok(cmd.run())
}
Ok(output)
if String::from_utf8_lossy(&output.stderr).eq("sudo: a password is required\n") =>
{
Err("Cannot run non-interactive sudo".to_string())
}
Ok(_output) => Err("\"sudo whoami\" didn't return \"root\"".to_string()),
Err(e) => Err(format!("{UUTILS_WARNING}: {e}")),
}
}

Expand Down
Loading