mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-09-16 03:36:18 +00:00
Merge branch 'main' into 2884-time-0.3
This commit is contained in:
commit
56264ebece
25 changed files with 673 additions and 341 deletions
|
@ -1506,6 +1506,18 @@ fn test_copy_through_dangling_symlink() {
|
|||
.stderr_only("cp: not writing through dangling symlink 'target'");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_copy_through_dangling_symlink_no_dereference() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
at.symlink_file("no-such-file", "dangle");
|
||||
ucmd.arg("-P")
|
||||
.arg("dangle")
|
||||
.arg("d2")
|
||||
.succeeds()
|
||||
.no_stderr()
|
||||
.no_stdout();
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(unix)]
|
||||
fn test_cp_archive_on_nonexistent_file() {
|
||||
|
|
|
@ -392,6 +392,11 @@ fn test_block_size_1024() {
|
|||
assert_eq!(get_header(2 * 1024 * 1024), "2M-blocks");
|
||||
assert_eq!(get_header(1024 * 1024 * 1024), "1G-blocks");
|
||||
assert_eq!(get_header(34 * 1024 * 1024 * 1024), "34G-blocks");
|
||||
|
||||
// multiples of both 1024 and 1000
|
||||
assert_eq!(get_header(128_000), "128kB-blocks");
|
||||
assert_eq!(get_header(1000 * 1024), "1.1MB-blocks");
|
||||
assert_eq!(get_header(1_000_000_000_000), "1TB-blocks");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -413,10 +418,33 @@ fn test_block_size_with_suffix() {
|
|||
assert_eq!(get_header("1KiB"), "1K-blocks");
|
||||
assert_eq!(get_header("1MiB"), "1M-blocks");
|
||||
assert_eq!(get_header("1GiB"), "1G-blocks");
|
||||
// TODO enable the following asserts when #3193 is resolved
|
||||
//assert_eq!(get_header("1KB"), "1kB-blocks");
|
||||
//assert_eq!(get_header("1MB"), "1MB-blocks");
|
||||
//assert_eq!(get_header("1GB"), "1GB-blocks");
|
||||
assert_eq!(get_header("1KB"), "1kB-blocks");
|
||||
assert_eq!(get_header("1MB"), "1MB-blocks");
|
||||
assert_eq!(get_header("1GB"), "1GB-blocks");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_too_large_block_size() {
|
||||
fn run_command(size: &str) {
|
||||
new_ucmd!()
|
||||
.arg(format!("--block-size={}", size))
|
||||
.fails()
|
||||
.stderr_contains(format!("--block-size argument '{}' too large", size));
|
||||
}
|
||||
|
||||
let too_large_sizes = vec!["1Y", "1Z"];
|
||||
|
||||
for size in too_large_sizes {
|
||||
run_command(size);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_invalid_block_size() {
|
||||
new_ucmd!()
|
||||
.arg("--block-size=x")
|
||||
.fails()
|
||||
.stderr_contains("invalid --block-size argument 'x'");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -435,9 +435,7 @@ fn test_du_no_permission() {
|
|||
ts.ccmd("chmod").arg("-r").arg(SUB_DIR_LINKS).succeeds();
|
||||
|
||||
let result = ts.ucmd().arg(SUB_DIR_LINKS).fails();
|
||||
result.stderr_contains(
|
||||
"du: cannot read directory 'subdir/links': Permission denied (os error 13)",
|
||||
);
|
||||
result.stderr_contains("du: cannot read directory 'subdir/links': Permission denied");
|
||||
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
{
|
||||
|
|
|
@ -58,3 +58,8 @@ fn test_command_where_command_takes_n_flag() {
|
|||
.run()
|
||||
.stdout_is("a");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_invalid_argument() {
|
||||
new_ucmd!().arg("--invalid").fails().code_is(125);
|
||||
}
|
||||
|
|
|
@ -345,3 +345,58 @@ fn test_printf() {
|
|||
let expected_stdout = unwrap_or_return!(expected_result(&ts, &args)).stdout_move_str();
|
||||
ts.ucmd().args(&args).succeeds().stdout_is(expected_stdout);
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
#[test]
|
||||
#[cfg(disable_until_fixed)]
|
||||
fn test_stdin_pipe_fifo1() {
|
||||
// $ echo | stat -
|
||||
// File: -
|
||||
// Size: 0 Blocks: 0 IO Block: 4096 fifo
|
||||
// use std::process::{Command, Stdio};
|
||||
new_ucmd!()
|
||||
.arg("-")
|
||||
.set_stdin(std::process::Stdio::piped())
|
||||
.run()
|
||||
.no_stderr()
|
||||
.stdout_contains("fifo")
|
||||
.stdout_contains("File: -")
|
||||
.succeeded();
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
#[test]
|
||||
#[cfg(disable_until_fixed)]
|
||||
fn test_stdin_pipe_fifo2() {
|
||||
// $ stat -
|
||||
// File: -
|
||||
// Size: 0 Blocks: 0 IO Block: 1024 character special file
|
||||
new_ucmd!()
|
||||
.arg("-")
|
||||
.run()
|
||||
.no_stderr()
|
||||
.stdout_contains("character special file")
|
||||
.stdout_contains("File: -")
|
||||
.succeeded();
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
#[test]
|
||||
#[cfg(disable_until_fixed)]
|
||||
fn test_stdin_redirect() {
|
||||
// $ touch f && stat - < f
|
||||
// File: -
|
||||
// Size: 0 Blocks: 0 IO Block: 4096 regular empty file
|
||||
|
||||
let ts = TestScenario::new(util_name!());
|
||||
let at = &ts.fixtures;
|
||||
at.touch("f");
|
||||
new_ucmd!()
|
||||
.arg("-")
|
||||
.set_stdin(std::fs::File::open("f").unwrap())
|
||||
.run()
|
||||
.no_stderr()
|
||||
.stdout_contains("regular empty file")
|
||||
.stdout_contains("File: -")
|
||||
.succeeded();
|
||||
}
|
||||
|
|
|
@ -1362,6 +1362,60 @@ pub fn expected_result(ts: &TestScenario, args: &[&str]) -> std::result::Result<
|
|||
))
|
||||
}
|
||||
|
||||
/// This is a convenience wrapper to run a ucmd with root permissions.
|
||||
/// It can be used to test programs when being root is needed
|
||||
/// This runs 'sudo -E --non-interactive target/debug/coreutils util_name args`
|
||||
/// This is primarily designed to run in an environment where whoami is in $path
|
||||
/// and where non-interactive sudo is possible.
|
||||
/// To check if i) non-interactive sudo is possible and ii) if sudo works, this runs:
|
||||
/// 'sudo -E --non-interactive whoami' first.
|
||||
///
|
||||
/// Example:
|
||||
///
|
||||
/// ```no_run
|
||||
/// use crate::common::util::*;
|
||||
/// #[test]
|
||||
/// fn test_xyz() {
|
||||
/// let ts = TestScenario::new("whoami");
|
||||
/// let expected = "root\n".to_string();
|
||||
/// if let Ok(result) = run_ucmd_as_root(&ts, &[]) {
|
||||
/// result.stdout_is(expected);
|
||||
/// } else {
|
||||
/// print!("TEST SKIPPED");
|
||||
/// }
|
||||
/// }
|
||||
///```
|
||||
#[cfg(unix)]
|
||||
pub fn run_ucmd_as_root(
|
||||
ts: &TestScenario,
|
||||
args: &[&str],
|
||||
) -> std::result::Result<CmdResult, String> {
|
||||
// Apparently CICD environment has no `sudo`?
|
||||
if ts
|
||||
.cmd_keepenv("sudo")
|
||||
.env("LC_ALL", "C")
|
||||
.arg("-E")
|
||||
.arg("--non-interactive")
|
||||
.arg("whoami")
|
||||
.run()
|
||||
.stdout_str()
|
||||
.trim()
|
||||
!= "root"
|
||||
{
|
||||
Err("\"sudo whoami\" didn't return \"root\"".to_string())
|
||||
} else {
|
||||
Ok(ts
|
||||
.cmd_keepenv("sudo")
|
||||
.env("LC_ALL", "C")
|
||||
.arg("-E")
|
||||
.arg("--non-interactive")
|
||||
.arg(&ts.bin_path)
|
||||
.arg(&ts.util_name)
|
||||
.args(args)
|
||||
.run())
|
||||
}
|
||||
}
|
||||
|
||||
/// Sanity checks for test utils
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
@ -1712,4 +1766,23 @@ mod tests {
|
|||
std::assert_eq!(host_name_for("gwho"), "gwho");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(unix)]
|
||||
#[cfg(feature = "whoami")]
|
||||
fn test_run_ucmd_as_root() {
|
||||
// Skip test if we can't guarantee non-interactive `sudo`.
|
||||
if let Ok(_status) = Command::new("sudo")
|
||||
.args(&["-E", "-v", "--non-interactive"])
|
||||
.status()
|
||||
{
|
||||
let ts = TestScenario::new("whoami");
|
||||
std::assert_eq!(
|
||||
run_ucmd_as_root(&ts, &[]).unwrap().stdout_str().trim(),
|
||||
"root"
|
||||
);
|
||||
} else {
|
||||
print!("TEST SKIPPED");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue