Skip to content

Commit

Permalink
cp: --preserve should keep xattr
Browse files Browse the repository at this point in the history
Should help with tests/cp/acl.sh
  • Loading branch information
sylvestre committed Jan 13, 2024
1 parent ac27b6c commit e8be4d9
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 1 deletion.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Expand Up @@ -492,6 +492,7 @@ uucore = { workspace = true, features = ["entries", "process", "signals"] }
walkdir = { workspace = true }
hex-literal = "0.4.1"
rstest = { workspace = true }
xattr = { workspace = true }

[target.'cfg(any(target_os = "linux", target_os = "android"))'.dev-dependencies]
procfs = { version = "0.16", default-features = false }
Expand Down
1 change: 1 addition & 0 deletions src/uu/cp/src/cp.rs
Expand Up @@ -825,6 +825,7 @@ impl Attributes {
ownership: Preserve::Yes { required: true },
mode: Preserve::Yes { required: true },
timestamps: Preserve::Yes { required: true },
xattr: Preserve::Yes { required: true },
..Self::NONE
};

Expand Down
58 changes: 57 additions & 1 deletion tests/by-util/test_cp.rs
Expand Up @@ -2,7 +2,7 @@
//
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.
// spell-checker:ignore (flags) reflink (fs) tmpfs (linux) rlimit Rlim NOFILE clob btrfs ROOTDIR USERDIR procfs outfile uufs
// spell-checker:ignore (flags) reflink (fs) tmpfs (linux) rlimit Rlim NOFILE clob btrfs ROOTDIR USERDIR procfs outfile uufs xattrs

use crate::common::util::TestScenario;
#[cfg(not(windows))]
Expand Down Expand Up @@ -56,6 +56,8 @@ static TEST_MOUNT_MOUNTPOINT: &str = "mount";
static TEST_MOUNT_OTHER_FILESYSTEM_FILE: &str = "mount/DO_NOT_copy_me.txt";
#[cfg(unix)]
static TEST_NONEXISTENT_FILE: &str = "nonexistent_file.txt";
#[cfg(all(unix, not(target_os = "macos")))]
use xattr;

/// Assert that mode, ownership, and permissions of two metadata objects match.
#[cfg(all(not(windows), not(target_os = "freebsd")))]
Expand Down Expand Up @@ -3701,3 +3703,57 @@ fn test_cp_no_such() {
.fails()
.stderr_is("cp: 'no-such/' is not a directory\n");
}

#[cfg(all(unix, not(target_os = "macos")))]
fn compare_xattrs<P: AsRef<Path>>(path1: P, path2: P) -> bool {
let get_sorted_xattrs = |path: P| {
xattr::list(path)
.map(|attrs| {
let mut attrs = attrs.collect::<Vec<_>>();
attrs.sort();
attrs
})
.unwrap_or_else(|_| Vec::new())
};

Check warning on line 3717 in tests/by-util/test_cp.rs

View check run for this annotation

Codecov / codecov/patch

tests/by-util/test_cp.rs#L3708-L3717

Added lines #L3708 - L3717 were not covered by tests

get_sorted_xattrs(path1) == get_sorted_xattrs(path2)
}

Check warning on line 3720 in tests/by-util/test_cp.rs

View check run for this annotation

Codecov / codecov/patch

tests/by-util/test_cp.rs#L3719-L3720

Added lines #L3719 - L3720 were not covered by tests

#[cfg(all(unix, not(target_os = "macos")))]
#[test]
fn test_acl_preserve() {
use std::process::Command;

let scene = TestScenario::new(util_name!());
let at = &scene.fixtures;
let path1 = "a";
let path2 = "b";
let file = "a/file";
let file_target = "b/file";
at.mkdir(path1);
at.mkdir(path2);
at.touch(file);

let path = at.plus_as_string(file);
// calling the command directly. xattr requires some dev packages to be installed
// and it adds a complex dependency just for a test
match Command::new("setfacl")
.args(["-m", "group::rwx", &file])
.status()
.map(|status| status.code())
{
Ok(Some(0)) => {}
Ok(_) => {
println!("test skipped: setfacl failed");
return;
}
Err(e) => {
println!("test skipped: setfacl failed with {}", e);

Check warning on line 3751 in tests/by-util/test_cp.rs

View check run for this annotation

Codecov / codecov/patch

tests/by-util/test_cp.rs#L3750-L3751

Added lines #L3750 - L3751 were not covered by tests
return;
}

Check warning on line 3753 in tests/by-util/test_cp.rs

View check run for this annotation

Codecov / codecov/patch

tests/by-util/test_cp.rs#L3753

Added line #L3753 was not covered by tests
}

scene.ucmd().args(&["-p", &path, path2]).succeeds();

Check warning on line 3756 in tests/by-util/test_cp.rs

View check run for this annotation

Codecov / codecov/patch

tests/by-util/test_cp.rs#L3756

Added line #L3756 was not covered by tests

assert!(compare_xattrs(&file, &file_target));

Check warning on line 3758 in tests/by-util/test_cp.rs

View check run for this annotation

Codecov / codecov/patch

tests/by-util/test_cp.rs#L3758

Added line #L3758 was not covered by tests
}

0 comments on commit e8be4d9

Please sign in to comment.