diff --git a/tests/by-util/test_install.rs b/tests/by-util/test_install.rs index fb360533f..3db25c81f 100644 --- a/tests/by-util/test_install.rs +++ b/tests/by-util/test_install.rs @@ -4,9 +4,10 @@ // file that was distributed with this source code. // spell-checker:ignore (words) helloworld nodir objdump n'source -use crate::common::util::{is_ci, TestScenario}; +use crate::common::util::{is_ci, run_ucmd_as_root, TestScenario}; use filetime::FileTime; -use std::os::unix::fs::PermissionsExt; +use std::fs; +use std::os::unix::fs::{MetadataExt, PermissionsExt}; #[cfg(not(any(windows, target_os = "freebsd")))] use std::process::Command; #[cfg(any(target_os = "linux", target_os = "android"))] @@ -1613,3 +1614,32 @@ fn test_target_file_ends_with_slash() { .fails() .stderr_contains("failed to access 'dir/target_file/': Not a directory"); } + +#[test] +fn test_install_root_combined() { + let ts = TestScenario::new(util_name!()); + let at = ts.fixtures.clone(); + at.touch("a"); + at.touch("c"); + + let run_and_check = |args: &[&str], target: &str, expected_uid: u32, expected_gid: u32| { + if let Ok(result) = run_ucmd_as_root(&ts, args) { + result.success(); + assert!(at.file_exists(target)); + + let metadata = fs::metadata(at.plus(target)).unwrap(); + assert_eq!(metadata.uid(), expected_uid); + assert_eq!(metadata.gid(), expected_gid); + } else { + print!("Test skipped; requires root user"); + } + }; + + run_and_check(&["-Cv", "-o1", "-g1", "a", "b"], "b", 1, 1); + run_and_check(&["-Cv", "-o2", "-g1", "a", "b"], "b", 2, 1); + run_and_check(&["-Cv", "-o2", "-g2", "a", "b"], "b", 2, 2); + + run_and_check(&["-Cv", "-o2", "c", "d"], "d", 2, 0); + run_and_check(&["-Cv", "c", "d"], "d", 0, 0); + run_and_check(&["-Cv", "c", "d"], "d", 0, 0); +}