From a347ca8ef9109315b92ee44e85762c0e32db274f Mon Sep 17 00:00:00 2001 From: Thomas Bertschinger Date: Mon, 8 Sep 2025 21:09:52 -0600 Subject: [PATCH] tests: make xattr test more robust Currently the xattr test asserts that listxattr() on Cargo.toml returns a length of 0. This causes a spurious failure when Cargo.toml does have xattrs, and this can happen in fairly normal situations like when a Linux distribution enables selinux (as it does on an AlmaLinux 10 test system, for example): $ cat /etc/almalinux-release AlmaLinux release 10.0 (Purple Lion) $ getfattr -d -m - Cargo.toml security.selinux=[...] $ cargo test --features=fs,stdio xattr [...] thread 'xattr::xattr_basic' panicked at tests/fs/xattr.rs:88:5: assertion `left == right` failed left: 17 right: 0 This change fixes the failure by comparing the output of rustix *listxattr() with an external implementation, the libc crate's implementation of listxattr(). Rather than asserting a specific value for rustix *listxattr(), it should match the value produced by libc listxattr(). --- tests/fs/xattr.rs | 37 ++++++++++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/tests/fs/xattr.rs b/tests/fs/xattr.rs index 936ec7437..ba2ff17aa 100644 --- a/tests/fs/xattr.rs +++ b/tests/fs/xattr.rs @@ -85,8 +85,14 @@ fn xattr_basic() { .raw_os_error(), enodata ); - assert_eq!(rustix::fs::listxattr("Cargo.toml", &mut empty).unwrap(), 0); - assert_eq!(rustix::fs::llistxattr("Cargo.toml", &mut empty).unwrap(), 0); + assert_eq!( + rustix::fs::listxattr("Cargo.toml", &mut empty).unwrap(), + libc_listxattr("Cargo.toml") + ); + assert_eq!( + rustix::fs::llistxattr("Cargo.toml", &mut empty).unwrap(), + libc_listxattr("Cargo.toml") + ); assert_eq!( rustix::fs::removexattr("Cargo.toml", "user.test") .unwrap_err() @@ -113,7 +119,10 @@ fn xattr_basic() { .raw_os_error(), enodata ); - assert_eq!(rustix::fs::flistxattr(&file, &mut empty).unwrap(), 0); + assert_eq!( + rustix::fs::flistxattr(&file, &mut empty).unwrap(), + libc_listxattr("Cargo.toml") + ); assert_eq!( rustix::fs::fremovexattr(&file, "user.test") .unwrap_err() @@ -121,3 +130,25 @@ fn xattr_basic() { enodata ); } + +/// To check the correctness of the tested implementations of *listxattr(), their output can be +/// compared to an external implementation, in this case listxattr() from the libc crate. +fn libc_listxattr(path: &str) -> usize { + let path = std::ffi::CString::new(path).unwrap(); + let path: *const _ = path.as_ptr(); + + let list = std::ffi::CString::new("").unwrap(); + let list = list.as_ptr() as *mut _; + + ({ + #[cfg(not(apple))] + unsafe { + libc::listxattr(path, list, 0) + } + + #[cfg(apple)] + unsafe { + libc::listxattr(path, list, 0, 0) + } + }) as usize +}