From 2fcf48c4b34d673a5de761aacb136fb9c70ad8d1 Mon Sep 17 00:00:00 2001 From: cerdelen Date: Tue, 30 Dec 2025 19:29:23 +0100 Subject: [PATCH 1/7] chgrp: verbose "retained as" prints gid for unmapped gid --- src/uucore/src/lib/features/perms.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uucore/src/lib/features/perms.rs b/src/uucore/src/lib/features/perms.rs index 2823b35b1a2..82df03ebd5b 100644 --- a/src/uucore/src/lib/features/perms.rs +++ b/src/uucore/src/lib/features/perms.rs @@ -163,7 +163,7 @@ pub fn wrap_chown>( format!( "group of {} retained as {}", path.quote(), - entries::gid2grp(dest_gid).unwrap_or_default() + entries::gid2grp(dest_gid).unwrap_or_else(|_| dest_gid.to_string()) ) } else { format!( From 6f68d587b42998efb537c12d616e10f1098d9294 Mon Sep 17 00:00:00 2001 From: cerdelen Date: Tue, 30 Dec 2025 19:38:10 +0100 Subject: [PATCH 2/7] chgrp: edit tests to new verbose output --- tests/by-util/test_chgrp.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/by-util/test_chgrp.rs b/tests/by-util/test_chgrp.rs index cc0727dd3eb..51af05547aa 100644 --- a/tests/by-util/test_chgrp.rs +++ b/tests/by-util/test_chgrp.rs @@ -231,8 +231,8 @@ fn test_reference_multi_no_equal() { .arg("file1") .arg("file2") .succeeds() - .stderr_contains("chgrp: group of 'file1' retained as ") - .stderr_contains("\nchgrp: group of 'file2' retained as "); + .stderr_contains("chgrp: group of 'file1' retained as {}", getegid()) + .stderr_contains("\nchgrp: group of 'file2' retained as {}", getegid()); } #[test] @@ -246,9 +246,9 @@ fn test_reference_last() { .arg("--reference") .arg("ref_file") .succeeds() - .stderr_contains("chgrp: group of 'file1' retained as ") - .stderr_contains("\nchgrp: group of 'file2' retained as ") - .stderr_contains("\nchgrp: group of 'file3' retained as "); + .stderr_contains("chgrp: group of 'file1' retained as {}", getegid()) + .stderr_contains("\nchgrp: group of 'file2' retained as {}", getegid()) + .stderr_contains("\nchgrp: group of 'file3' retained as {}", getegid()); } #[test] @@ -511,7 +511,7 @@ fn test_verbosity_messages() { .arg("--reference=ref_file") .arg("target_file") .succeeds() - .stderr_contains("group of 'target_file' retained as "); + .stderr_contains("group of 'target_file' retained as {}", getegid()); } #[test] From 83c0c4bb5b32c31dc97ac2b0fff22878855f1d90 Mon Sep 17 00:00:00 2001 From: cerdelen Date: Wed, 31 Dec 2025 14:47:57 +0100 Subject: [PATCH 3/7] chgrp: fix tests --- tests/by-util/test_chgrp.rs | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/tests/by-util/test_chgrp.rs b/tests/by-util/test_chgrp.rs index 51af05547aa..62134fcaf8e 100644 --- a/tests/by-util/test_chgrp.rs +++ b/tests/by-util/test_chgrp.rs @@ -231,8 +231,11 @@ fn test_reference_multi_no_equal() { .arg("file1") .arg("file2") .succeeds() - .stderr_contains("chgrp: group of 'file1' retained as {}", getegid()) - .stderr_contains("\nchgrp: group of 'file2' retained as {}", getegid()); + .stderr_contains(format!("chgrp: group of 'file1' retained as {}", getegid())) + .stderr_contains(format!( + "\nchgrp: group of 'file2' retained as {}", + getegid() + )); } #[test] @@ -246,9 +249,15 @@ fn test_reference_last() { .arg("--reference") .arg("ref_file") .succeeds() - .stderr_contains("chgrp: group of 'file1' retained as {}", getegid()) - .stderr_contains("\nchgrp: group of 'file2' retained as {}", getegid()) - .stderr_contains("\nchgrp: group of 'file3' retained as {}", getegid()); + .stderr_contains(format!("chgrp: group of 'file1' retained as {}", getegid())) + .stderr_contains(format!( + "\nchgrp: group of 'file2' retained as {}", + getegid() + )) + .stderr_contains(format!( + "\nchgrp: group of 'file3' retained as {}", + getegid() + )); } #[test] @@ -511,7 +520,7 @@ fn test_verbosity_messages() { .arg("--reference=ref_file") .arg("target_file") .succeeds() - .stderr_contains("group of 'target_file' retained as {}", getegid()); + .stderr_contains(format!("group of 'target_file' retained as {}", getegid())); } #[test] From 0ae267a6e3c902b0c835cafd3c6d9b7d4942d821 Mon Sep 17 00:00:00 2001 From: cerdelen Date: Wed, 31 Dec 2025 15:17:15 +0100 Subject: [PATCH 4/7] chgrp: Fix tests that sometimes have mapped gid --- tests/by-util/test_chgrp.rs | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/tests/by-util/test_chgrp.rs b/tests/by-util/test_chgrp.rs index 62134fcaf8e..fa34d83780c 100644 --- a/tests/by-util/test_chgrp.rs +++ b/tests/by-util/test_chgrp.rs @@ -224,6 +224,14 @@ fn test_reference() { #[test] #[cfg(any(target_os = "linux", target_os = "android", target_vendor = "apple"))] fn test_reference_multi_no_equal() { + use nix::unistd::{Gid, Group}; + let gid = getegid(); + let expected_print = Group::from_gid(Gid::from_raw(gid)) + .ok() + .flatten() + .map(|g| g.name) + .unwrap_or_else(|| gid.to_string()); + new_ucmd!() .arg("-v") .arg("--reference") @@ -231,16 +239,27 @@ fn test_reference_multi_no_equal() { .arg("file1") .arg("file2") .succeeds() - .stderr_contains(format!("chgrp: group of 'file1' retained as {}", getegid())) + .stderr_contains(format!( + "chgrp: group of 'file1' retained as {}", + expected_print + )) .stderr_contains(format!( "\nchgrp: group of 'file2' retained as {}", - getegid() + expected_print )); } #[test] #[cfg(any(target_os = "linux", target_os = "android", target_vendor = "apple"))] fn test_reference_last() { + use nix::unistd::{Gid, Group}; + let gid = getegid(); + let expected_print = Group::from_gid(Gid::from_raw(gid)) + .ok() + .flatten() + .map(|g| g.name) + .unwrap_or_else(|| gid.to_string()); + new_ucmd!() .arg("-v") .arg("file1") @@ -249,14 +268,17 @@ fn test_reference_last() { .arg("--reference") .arg("ref_file") .succeeds() - .stderr_contains(format!("chgrp: group of 'file1' retained as {}", getegid())) + .stderr_contains(format!( + "chgrp: group of 'file1' retained as {}", + expected_print + )) .stderr_contains(format!( "\nchgrp: group of 'file2' retained as {}", - getegid() + expected_print )) .stderr_contains(format!( "\nchgrp: group of 'file3' retained as {}", - getegid() + expected_print )); } From 5da4ca14fcdd1e9108e93030a6acdf2f5d637bf1 Mon Sep 17 00:00:00 2001 From: cerdelen Date: Wed, 31 Dec 2025 18:53:08 +0100 Subject: [PATCH 5/7] chgrp: Remove gid check from verbose tests --- tests/by-util/test_chgrp.rs | 43 ++++++------------------------------- 1 file changed, 6 insertions(+), 37 deletions(-) diff --git a/tests/by-util/test_chgrp.rs b/tests/by-util/test_chgrp.rs index fa34d83780c..00d9fe0b6fe 100644 --- a/tests/by-util/test_chgrp.rs +++ b/tests/by-util/test_chgrp.rs @@ -224,14 +224,6 @@ fn test_reference() { #[test] #[cfg(any(target_os = "linux", target_os = "android", target_vendor = "apple"))] fn test_reference_multi_no_equal() { - use nix::unistd::{Gid, Group}; - let gid = getegid(); - let expected_print = Group::from_gid(Gid::from_raw(gid)) - .ok() - .flatten() - .map(|g| g.name) - .unwrap_or_else(|| gid.to_string()); - new_ucmd!() .arg("-v") .arg("--reference") @@ -239,27 +231,13 @@ fn test_reference_multi_no_equal() { .arg("file1") .arg("file2") .succeeds() - .stderr_contains(format!( - "chgrp: group of 'file1' retained as {}", - expected_print - )) - .stderr_contains(format!( - "\nchgrp: group of 'file2' retained as {}", - expected_print - )); + .stderr_contains("chgrp: group of 'file1' retained as") + .stderr_contains("\nchgrp: group of 'file2' retained as"); } #[test] #[cfg(any(target_os = "linux", target_os = "android", target_vendor = "apple"))] fn test_reference_last() { - use nix::unistd::{Gid, Group}; - let gid = getegid(); - let expected_print = Group::from_gid(Gid::from_raw(gid)) - .ok() - .flatten() - .map(|g| g.name) - .unwrap_or_else(|| gid.to_string()); - new_ucmd!() .arg("-v") .arg("file1") @@ -268,18 +246,9 @@ fn test_reference_last() { .arg("--reference") .arg("ref_file") .succeeds() - .stderr_contains(format!( - "chgrp: group of 'file1' retained as {}", - expected_print - )) - .stderr_contains(format!( - "\nchgrp: group of 'file2' retained as {}", - expected_print - )) - .stderr_contains(format!( - "\nchgrp: group of 'file3' retained as {}", - expected_print - )); + .stderr_contains("chgrp: group of 'file1' retained as") + .stderr_contains("\nchgrp: group of 'file2' retained as") + .stderr_contains("\nchgrp: group of 'file3' retained as"); } #[test] @@ -542,7 +511,7 @@ fn test_verbosity_messages() { .arg("--reference=ref_file") .arg("target_file") .succeeds() - .stderr_contains(format!("group of 'target_file' retained as {}", getegid())); + .stderr_contains("group of 'target_file' retained as"); } #[test] From 534128e49607f054209c9dcb74c9481795ac90d3 Mon Sep 17 00:00:00 2001 From: cerdelen Date: Thu, 1 Jan 2026 21:56:59 +0100 Subject: [PATCH 6/7] chgrp: add regression test while reverting other tests --- tests/by-util/test_chgrp.rs | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/tests/by-util/test_chgrp.rs b/tests/by-util/test_chgrp.rs index 00d9fe0b6fe..841c3751aa0 100644 --- a/tests/by-util/test_chgrp.rs +++ b/tests/by-util/test_chgrp.rs @@ -231,8 +231,8 @@ fn test_reference_multi_no_equal() { .arg("file1") .arg("file2") .succeeds() - .stderr_contains("chgrp: group of 'file1' retained as") - .stderr_contains("\nchgrp: group of 'file2' retained as"); + .stderr_contains("chgrp: group of 'file1' retained as ") + .stderr_contains("\nchgrp: group of 'file2' retained as "); } #[test] @@ -246,9 +246,9 @@ fn test_reference_last() { .arg("--reference") .arg("ref_file") .succeeds() - .stderr_contains("chgrp: group of 'file1' retained as") - .stderr_contains("\nchgrp: group of 'file2' retained as") - .stderr_contains("\nchgrp: group of 'file3' retained as"); + .stderr_contains("chgrp: group of 'file1' retained as ") + .stderr_contains("\nchgrp: group of 'file2' retained as ") + .stderr_contains("\nchgrp: group of 'file3' retained as "); } #[test] @@ -511,7 +511,7 @@ fn test_verbosity_messages() { .arg("--reference=ref_file") .arg("target_file") .succeeds() - .stderr_contains("group of 'target_file' retained as"); + .stderr_contains("group of 'target_file' retained as "); } #[test] @@ -640,3 +640,21 @@ fn test_chgrp_recursive_on_file() { current_gid ); } + +#[test] +#[cfg(target_os = "linux")] +fn test_chgrp_verbose_for_unmapped_gid() { + let (at, mut ucmd) = at_and_ucmd!(); + at.touch("tmp"); + + ucmd.arg("1337") + .arg("tmp") + .succeeds() + .no_stderr(); + + ucmd.arg("-v") + .arg("1337") + .arg("tmp") + .succeeds() + .stderr_contains("chgrp: group of 'tmp' retained as 1337"); +} From 263929610877c3444b91ed09fdf2475ded40070d Mon Sep 17 00:00:00 2001 From: cerdelen Date: Thu, 1 Jan 2026 22:30:08 +0100 Subject: [PATCH 7/7] chgrp: guard regression test to only run as root --- tests/by-util/test_chgrp.rs | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/tests/by-util/test_chgrp.rs b/tests/by-util/test_chgrp.rs index 841c3751aa0..d6f671baea5 100644 --- a/tests/by-util/test_chgrp.rs +++ b/tests/by-util/test_chgrp.rs @@ -8,7 +8,6 @@ use std::os::unix::ffi::OsStringExt; use uucore::process::getegid; use uutests::{at_and_ucmd, new_ucmd}; -#[cfg(not(target_vendor = "apple"))] use uutests::{util::TestScenario, util_name}; #[test] @@ -642,19 +641,23 @@ fn test_chgrp_recursive_on_file() { } #[test] -#[cfg(target_os = "linux")] fn test_chgrp_verbose_for_unmapped_gid() { - let (at, mut ucmd) = at_and_ucmd!(); - at.touch("tmp"); + // To be able to change the gid we need root privileges so we skip if the user running the test + // suite does not have root privileges + if getegid() == 0 { + let scene = TestScenario::new(util_name!()); + let at = &scene.fixtures; - ucmd.arg("1337") - .arg("tmp") - .succeeds() - .no_stderr(); + at.touch("tmp"); - ucmd.arg("-v") - .arg("1337") - .arg("tmp") - .succeeds() - .stderr_contains("chgrp: group of 'tmp' retained as 1337"); + scene.ucmd().arg("1337").arg("tmp").succeeds().no_stderr(); + + scene + .ucmd() + .arg("-v") + .arg("1337") + .arg("tmp") + .succeeds() + .stderr_contains("chgrp: group of 'tmp' retained as 1337"); + } }