diff --git a/.github/skills/code-review/SKILL.md b/.github/skills/code-review/SKILL.md index 7aa3acff197..912821f6422 100644 --- a/.github/skills/code-review/SKILL.md +++ b/.github/skills/code-review/SKILL.md @@ -87,7 +87,10 @@ patches: assistants can reproduce GPL sources verbatim. - Tests must be original (see the provenance rule above) and pick values that are clearly distinct from GNU's fixtures. - Use `.no_output()` rather than `.no_stdout().no_stderr()`. -- Anything that can't run under WASI needs `#[cfg_attr(wasi_runner, ignore)]`. +- Anything that can't run under WASI needs `#[uutests::wasi_ignore(ReasonKey)]`, + reusing an existing key from `tests/uutests_procs/src/lib.rs` when one fits and + adding a new key only when no existing reason matches the root cause. Don't use + a raw `#[cfg_attr(wasi_runner, ignore = "...")]`. - If a GNU test was failing while the Rust suite passed, the PR should add a Rust test so the gap can't reopen. diff --git a/.github/workflows/wasi.yml b/.github/workflows/wasi.yml index 5678ea54874..73b7f37ab1a 100644 --- a/.github/workflows/wasi.yml +++ b/.github/workflows/wasi.yml @@ -56,7 +56,9 @@ jobs: cargo build --target ${{ matrix.job.target }} --no-default-features --features feat_wasm # Run host-compiled integration tests against the WASI binary. # Tests incompatible with WASI are annotated with - # #[cfg_attr(wasi_runner, ignore)] in the test source files. + # #[uutests::wasi_ignore(ReasonKey)] in the test source files, which + # expands to #[cfg_attr(wasi_runner, ignore = "...")]; the reason keys + # live in tests/uutests_procs/src/lib.rs. # The binary above is built without default features, so it has no # caret diagnostics; the host test crate does have them, hence the # not(wasi_runner) in the cfg guarding every `mod diagnostics`. diff --git a/AGENTS.md b/AGENTS.md index e4b654088c6..9099b125291 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -36,6 +36,19 @@ add a Rust test so it cannot silently regress. No tests, no merge. +### Tests that can't run under WASI + +A test that can't run under the WASI runner is skipped with +`#[uutests::wasi_ignore(ReasonKey)]`, not a raw +`#[cfg_attr(wasi_runner, ignore = "...")]`. Every reason is defined once in +`tests/uutests_procs/src/lib.rs`. + +Reuse an existing key when one fits the root cause. Add a new key only when no +existing reason matches, and keep the list small - prefer widening an existing +reason over introducing a near-duplicate. When a skip's real cause differs from +its key, switch the key rather than leaving it mislabeled. See +`docs/src/wasi-test-gaps.md`. + ## Keep the PR description short Describe the problem being solved and what changed. That is all. @@ -55,4 +68,5 @@ rules, this file is only a pointer: - `DEVELOPMENT.md` - build, test and environment setup - `README.md`, `SECURITY.md`, `CODE_OF_CONDUCT.md` - `docs/src/*.md` - platforms, performance, l10n, multicall, test coverage +- `docs/src/wasi-test-gaps.md` - WASI test skips and the `wasi_ignore` reason keys - the per-utility `README.md` / `locales/*.ftl` files when touching a utility diff --git a/Cargo.lock b/Cargo.lock index 19f1ac4e3fd..ad7955a756b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4491,9 +4491,19 @@ dependencies = [ "rustix", "tempfile", "uucore", + "uutests_procs", "xattr", ] +[[package]] +name = "uutests_procs" +version = "0.13.0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + [[package]] name = "uutils_term_grid" version = "0.8.0" diff --git a/Cargo.toml b/Cargo.toml index c37b217d0dd..cafd8ce1ff2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,6 +27,7 @@ members = [ "src/uucore", "src/uucore_procs", "tests/uutests", + "tests/uutests_procs", # "fuzz", # TODO ] @@ -119,6 +120,7 @@ rustc-hash = "2.1.1" rustix = { version = "1.1.4", default-features = false } self_cell = "1.0.4" selinux = "0.6" +syn = { version = "2.0", features = ["full"] } tempfile = "3.15.0" terminal_size = "0.4.0" textwrap = { version = "0.16.1", features = ["terminal_size"] } @@ -161,6 +163,7 @@ uu_ls = { version = "0.13.0", path = "src/uu/ls" } uu_base32 = { version = "0.13.0", path = "src/uu/base32" } uu_checksum_common = { version = "0.13.0", path = "src/uu/checksum_common" } uutests = { version = "0.13.0", path = "tests/uutests" } +uutests_procs = { version = "0.13.0", path = "tests/uutests_procs" } # This is the linting configuration for all crates. # In order to use these, all crates have `[lints] workspace = true` section. diff --git a/docs/src/wasi-test-gaps.md b/docs/src/wasi-test-gaps.md index 4789ef03dc9..90f32fe71b7 100644 --- a/docs/src/wasi-test-gaps.md +++ b/docs/src/wasi-test-gaps.md @@ -1,8 +1,10 @@ # WASI integration test gaps -Tests annotated with `#[cfg_attr(wasi_runner, ignore = "...")]` are skipped when running integration tests against a WASI binary via wasmtime. This document tracks the reasons so that gaps in WASI support are visible in one place. +Tests annotated with `#[uutests::wasi_ignore(ReasonKey)]` are skipped when running integration tests against a WASI binary via wasmtime. The macro expands to `#[cfg_attr(wasi_runner, ignore = "...")]`, resolving `ReasonKey` to its reason text. Every reason lives once, alphabetically, in `tests/uutests_procs/src/lib.rs`; this document gives the prose overview so that gaps in WASI support are visible in one place. -To find all annotated tests: `grep -rn 'wasi_runner, ignore' tests/` +When a test cannot run under WASI, annotate it with `#[uutests::wasi_ignore(ReasonKey)]` using the key that matches the root cause. Reuse an existing key whenever one fits rather than adding a near-duplicate; add a new key to `tests/uutests_procs/src/lib.rs` only when no existing reason describes the cause, and keep the key list and this document in sync. If the real cause of an existing skip turns out to differ from its key, switch the key (and refine the reason text) rather than leaving it mislabeled. + +To find all annotated tests: `grep -rn 'wasi_ignore' tests/`. For the full, authoritative list of reason keys and their text, see `tests/uutests_procs/src/lib.rs`. ## Tools not yet covered by integration tests diff --git a/tests/by-util/test_base64.rs b/tests/by-util/test_base64.rs index e9d7da79362..3fa3518722e 100644 --- a/tests/by-util/test_base64.rs +++ b/tests/by-util/test_base64.rs @@ -18,9 +18,9 @@ fn test_version() { .stdout_is(format!("base64 {}\n", uucore::crate_version!())); } +#[uutests::wasi_ignore(NonUtf8ArgsUnsupported)] #[test] #[cfg(target_os = "linux")] -#[cfg_attr(wasi_runner, ignore = "WASI: argv/filenames must be valid UTF-8")] fn test_base64_non_utf8_paths() { use std::os::unix::ffi::OsStringExt; let (at, mut ucmd) = at_and_ucmd!(); @@ -288,9 +288,9 @@ cyBvdmVyIHRoZSBsYXp5IGRvZy4= ); } +#[uutests::wasi_ignore(HostPathsNotVisible)] #[test] #[cfg(all(target_os = "linux", not(target_env = "musl")))] -#[cfg_attr(wasi_runner, ignore = "WASI sandbox: host paths not visible")] fn test_read_error() { new_ucmd!() .arg("/proc/self/mem") diff --git a/tests/by-util/test_basename.rs b/tests/by-util/test_basename.rs index 2b85116e064..54c2ff71780 100644 --- a/tests/by-util/test_basename.rs +++ b/tests/by-util/test_basename.rs @@ -163,8 +163,8 @@ fn test_too_many_args_output() { } #[cfg(unix)] +#[uutests::wasi_ignore(NonUtf8ArgsUnsupported)] #[test] -#[cfg_attr(wasi_runner, ignore = "WASI: argv/filenames must be valid UTF-8")] fn test_invalid_utf8_args() { let param = uucore::os_str_from_bytes(b"/tmp/some-\xc0-file.k\xf3") .expect("Only unix platforms can test non-unicode names"); diff --git a/tests/by-util/test_basenc.rs b/tests/by-util/test_basenc.rs index e4f2c3d3f84..c3f5b9d90f5 100644 --- a/tests/by-util/test_basenc.rs +++ b/tests/by-util/test_basenc.rs @@ -189,9 +189,9 @@ fn test_base16() { } // This test fails if the Base16 output buffer is not explicitly flushed. +#[uutests::wasi_ignore(HostPathsNotVisible)] #[test] #[cfg(target_os = "linux")] -#[cfg_attr(wasi_runner, ignore = "WASI sandbox: host paths not visible")] fn test_base16_write_error_is_reported() { new_ucmd!() .arg("--base16") @@ -407,9 +407,9 @@ fn test_file() { .stdout_is("Zm9v\n"); } +#[uutests::wasi_ignore(NonUtf8ArgsUnsupported)] #[test] #[cfg(target_os = "linux")] -#[cfg_attr(wasi_runner, ignore = "WASI: argv/filenames must be valid UTF-8")] fn test_file_with_non_utf8_name() { use std::os::unix::ffi::OsStringExt; let (at, mut ucmd) = at_and_ucmd!(); diff --git a/tests/by-util/test_cat.rs b/tests/by-util/test_cat.rs index ab18b515f70..e83e104af6e 100644 --- a/tests/by-util/test_cat.rs +++ b/tests/by-util/test_cat.rs @@ -86,9 +86,9 @@ fn test_no_options_big_input() { } } +#[uutests::wasi_ignore(NoFifo)] #[test] #[cfg(unix)] -#[cfg_attr(wasi_runner, ignore = "WASI: no FIFO/mkfifo support")] fn test_fifo_symlink() { use std::io::Write; use std::thread; @@ -119,11 +119,11 @@ fn test_fifo_symlink() { thread.join().unwrap(); } +#[uutests::wasi_ignore(NoRlimitSetrlimitSupport)] #[test] // TODO(#7542): Re-enable on Android once we figure out why setting limit is broken. // #[cfg(any(target_os = "linux", target_os = "android"))] #[cfg(target_os = "linux")] -#[cfg_attr(wasi_runner, ignore = "WASI: rlimit/setrlimit not supported")] fn test_closes_file_descriptors() { // Each file creates a pipe, which has two file descriptors. // If they are not closed then five is certainly too many. @@ -139,9 +139,9 @@ fn test_closes_file_descriptors() { .succeeds(); } +#[uutests::wasi_ignore(NoPipeSignalSupport)] #[test] #[cfg(unix)] -#[cfg_attr(wasi_runner, ignore = "WASI: no pipe/signal support")] fn test_broken_pipe() { let mut cmd = new_ucmd!(); let mut child = cmd @@ -516,9 +516,9 @@ fn test_squeeze_blank_before_numbering() { } /// This tests reading from Unix character devices +#[uutests::wasi_ignore(HostPathsNotVisible)] #[test] #[cfg(unix)] -#[cfg_attr(wasi_runner, ignore = "WASI sandbox: host paths not visible")] fn test_dev_random() { #[cfg(any(target_os = "linux", target_os = "android"))] const DEV_RANDOM: &str = "/dev/urandom"; @@ -547,9 +547,9 @@ fn test_dev_random() { /// Reading from /dev/full should return an infinite amount of zero bytes. /// Wikipedia says there is support on Linux, FreeBSD, and `NetBSD`. +#[uutests::wasi_ignore(HostPathsNotVisible)] #[test] #[cfg(any(target_os = "linux", target_os = "freebsd", target_os = "netbsd"))] -#[cfg_attr(wasi_runner, ignore = "WASI sandbox: host paths not visible")] fn test_dev_full() { let mut proc = new_ucmd!() .set_stdout(Stdio::piped()) @@ -563,9 +563,9 @@ fn test_dev_full() { proc.kill(); } +#[uutests::wasi_ignore(HostPathsNotVisible)] #[test] #[cfg(any(target_os = "linux", target_os = "freebsd", target_os = "netbsd"))] -#[cfg_attr(wasi_runner, ignore = "WASI sandbox: host paths not visible")] fn test_dev_full_show_all() { let buf_len = 2048; let mut proc = new_ucmd!() @@ -586,9 +586,9 @@ fn test_dev_full_show_all() { // For some reason splice() on first of those files fails, resulting in // fallback inside `write_fast`, the other splice succeeds, in effect // without additional flush output gets reversed. +#[uutests::wasi_ignore(HostPathsNotVisible)] #[test] #[cfg(target_os = "linux")] -#[cfg_attr(wasi_runner, ignore = "WASI sandbox: host paths not visible")] fn test_write_fast_fallthrough_uses_flush() { const PROC_INIT_CMDLINE: &str = "/proc/1/cmdline"; let cmdline = read_to_string(PROC_INIT_CMDLINE).unwrap(); @@ -599,9 +599,9 @@ fn test_write_fast_fallthrough_uses_flush() { .stdout_only(format!("{cmdline}abcde\nfghij\nklmno\npqrst\nuvwxyz\n")); // spell-checker:disable-line } +#[uutests::wasi_ignore(NoUnixDomainSockets)] #[test] #[cfg(unix)] -#[cfg_attr(wasi_runner, ignore = "WASI: no Unix domain socket support")] fn test_domain_socket() { use std::os::unix::net::UnixListener; @@ -630,8 +630,8 @@ fn test_write_to_self_empty() { s.ucmd().set_stdout(file).arg("file.txt").succeeds(); } +#[uutests::wasi_ignore(CannotDetectUnsafeOverwrite)] #[test] -#[cfg_attr(wasi_runner, ignore = "WASI: cannot detect unsafe overwrite")] fn test_write_to_self() { let s = TestScenario::new(util_name!()); let file_path = s.fixtures.plus("first_file"); @@ -689,8 +689,8 @@ fn test_cat_rw_self_succeeds() { /// Test that cat handles self-referential input gracefully. /// /// `cat fx fx3 1<>fx3` +#[uutests::wasi_ignore(CannotDetectUnsafeOverwrite)] #[test] -#[cfg_attr(wasi_runner, ignore = "WASI: cannot detect unsafe overwrite")] fn test_cat_rw_self_conflict_fails() { let (at, mut ucmd) = at_and_ucmd!(); at.write("source", "a"); @@ -713,13 +713,10 @@ fn test_cat_rw_self_conflict_fails() { assert_eq!(dest_contents, "acde"); } +#[uutests::wasi_ignore(SymlinkLoopNoEloop)] #[test] #[cfg(unix)] #[cfg(not(target_os = "openbsd"))] -#[cfg_attr( - wasi_runner, - ignore = "WASI: symlink loop traversal does not surface ELOOP ('Too many levels of symbolic links')" -)] fn test_error_loop() { let (at, mut ucmd) = at_and_ucmd!(); at.symlink_file("2", "1"); @@ -750,9 +747,9 @@ fn test_u_ignored() { } } +#[uutests::wasi_ignore(ErrnoMessageMismatch)] #[test] #[cfg(unix)] -#[cfg_attr(wasi_runner, ignore = "WASI: errno/error-message mismatches")] fn test_write_fast_read_error() { use std::os::unix::fs::PermissionsExt; @@ -771,9 +768,9 @@ fn test_write_fast_read_error() { ucmd.arg("foo").fails().stderr_contains("Permission denied"); } +#[uutests::wasi_ignore(NonUtf8ArgsUnsupported)] #[test] #[cfg(target_os = "linux")] -#[cfg_attr(wasi_runner, ignore = "WASI: argv/filenames must be valid UTF-8")] fn test_cat_non_utf8_paths() { use std::ffi::OsStr; use std::os::unix::ffi::OsStrExt; @@ -796,9 +793,9 @@ fn test_cat_non_utf8_paths() { assert_eq!(output, "Hello, non-UTF-8 world!\n"); } +#[uutests::wasi_ignore(CannotDetectUnsafeOverwrite)] #[test] #[cfg(unix)] -#[cfg_attr(wasi_runner, ignore = "WASI: cannot detect unsafe overwrite")] fn test_appending_same_input_output() { let (at, mut ucmd) = at_and_ucmd!(); diff --git a/tests/by-util/test_comm.rs b/tests/by-util/test_comm.rs index 88a01f21135..e06603889d7 100644 --- a/tests/by-util/test_comm.rs +++ b/tests/by-util/test_comm.rs @@ -677,8 +677,8 @@ fn test_comm_eintr_handling() { .stdout_contains("line3"); } +#[uutests::wasi_ignore(NonUtf8ArgsUnsupported)] #[test] -#[cfg_attr(wasi_runner, ignore = "WASI: argv/filenames must be valid UTF-8")] fn test_output_lossy_utf8() { let scene = TestScenario::new(util_name!()); let at = &scene.fixtures; @@ -702,9 +702,9 @@ fn test_output_lossy_utf8() { .stdout_is_bytes(b"\xfe\n\t\t\xff\n\t\xfe\n"); } +#[uutests::wasi_ignore(HostPathsNotVisible)] #[test] #[cfg(any(target_os = "linux", target_os = "android"))] -#[cfg_attr(wasi_runner, ignore = "WASI sandbox: host paths not visible")] fn test_comm_anonymous_pipes() { use std::fmt::Write as _; use std::{io::Write, os::fd::AsRawFd, process}; @@ -742,9 +742,9 @@ fn test_comm_anonymous_pipes() { .stdout_is("99999\n"); } +#[uutests::wasi_ignore(HostPathsNotVisible)] #[test] #[cfg(all(target_os = "linux", not(target_env = "musl")))] -#[cfg_attr(wasi_runner, ignore = "WASI sandbox: host paths not visible")] fn test_read_error() { new_ucmd!() .arg("/proc/self/mem") @@ -759,9 +759,9 @@ fn test_read_error() { .stderr_contains("comm: /proc/self/mem: Input/output error"); } +#[uutests::wasi_ignore(NoLocaleData)] #[test] #[cfg(unix)] -#[cfg_attr(wasi_runner, ignore = "WASI: the guest does not inherit LC_ALL")] fn test_locale_collation() { // In a UTF-8 locale the collation puts `a1` before `a-b` and the byte order // puts them the other way round. Reading a file `sort` produced with a byte diff --git a/tests/by-util/test_cp.rs b/tests/by-util/test_cp.rs index d3474eeb413..18e334e89b0 100644 --- a/tests/by-util/test_cp.rs +++ b/tests/by-util/test_cp.rs @@ -90,12 +90,9 @@ macro_rules! assert_metadata_eq { }}; } +#[uutests::wasi_ignore(HostPathsNotVisible)] #[test] #[cfg(target_os = "linux")] -#[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: host paths (/dev, /private) not visible" -)] fn test_cp_stream_to_full() { let (_, mut ucmd) = at_and_ucmd!(); ucmd.arg("/dev/zero") @@ -313,11 +310,8 @@ fn test_cp_multiple_files_with_nonexistent_file() { assert_eq!(at.read(TEST_HOW_ARE_YOU_DEST), "How are you?\n"); } +#[uutests::wasi_ignore(EmptyPathResolvesToDirectory)] #[test] -#[cfg_attr( - wasi_runner, - ignore = "WASI: an empty path argument resolves to a directory instead of ENOENT" -)] fn test_cp_multiple_files_with_empty_file_name() { #[cfg(windows)] let error_msg = "The system cannot find the path specified"; @@ -512,10 +506,7 @@ fn test_cp_arg_update_none() { #[rstest] #[case::no_clobber("-n", true)] #[case::update_none("--update=none", true)] -#[cfg_attr( - wasi_runner, - ignore = "WASI: no chmod syscall, so required mode/ownership preservation always fails" -)] +#[uutests::wasi_ignore(NoPermissionBits)] #[case::archive_no_clobber("-an", true)] #[case::declined_prompt("-i", false)] fn test_cp_recursive_continues_after_skipped_file(#[case] arg: &str, #[case] succeeds: bool) { @@ -855,12 +846,9 @@ fn test_cp_arg_interactive_verbose_clobber() { .stdout_contains("skipped 'b'"); } +#[uutests::wasi_ignore(NoPermissionBits)] #[test] #[cfg(unix)] -#[cfg_attr( - wasi_runner, - ignore = "WASI: no chmod syscall, so required mode/ownership preservation always fails" -)] fn test_cp_f_i_verbose_non_writeable_destination_y() { let (at, mut ucmd) = at_and_ucmd!(); @@ -877,12 +865,9 @@ fn test_cp_f_i_verbose_non_writeable_destination_y() { .stdout_is("removed 'b'\n'a' -> 'b'\n"); } +#[uutests::wasi_ignore(NoPermissionBits)] #[test] #[cfg(unix)] -#[cfg_attr( - wasi_runner, - ignore = "WASI: no chmod syscall, so required mode/ownership preservation always fails" -)] fn test_cp_f_i_verbose_non_writeable_destination_empty() { let (at, mut ucmd) = at_and_ucmd!(); @@ -912,12 +897,9 @@ fn test_cp_arg_link() { assert_eq!(at.metadata(TEST_HELLO_WORLD_SOURCE).st_nlink(), 2); } +#[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] #[cfg(target_os = "linux")] -#[cfg_attr( - wasi_runner, - ignore = "WASI: same-file hard link detection not supported" -)] fn test_cp_arg_link_with_dest_hardlink_to_source() { use std::os::linux::fs::MetadataExt; @@ -935,12 +917,9 @@ fn test_cp_arg_link_with_dest_hardlink_to_source() { assert!(at.file_exists(hardlink)); } +#[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] #[cfg(target_os = "linux")] -#[cfg_attr( - wasi_runner, - ignore = "WASI: same-file hard link detection not supported" -)] fn test_cp_arg_link_with_same_file() { use std::os::linux::fs::MetadataExt; @@ -1032,12 +1011,9 @@ fn test_cp_arg_symlink() { // the destination symlink cp just created. chmod() follows symlinks, so doing so // would change the mode of the link target, which can live outside the copied // tree. GNU cp leaves the target untouched. +#[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] #[cfg(unix)] -#[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: symlink/hardlink capability restrictions cause dangling-symlink/same-file detection to differ" -)] fn test_cp_recursive_symlink_preserves_target_mode() { let (at, mut ucmd) = at_and_ucmd!(); @@ -1111,9 +1087,9 @@ fn test_cp_umask_stripping_owner_write_bit() { // Same umask scenario without a clone attempt: on reflink-capable // filesystems the test above succeeds via FICLONE and never reaches the // fallback, so pin the plain and sparse copy paths explicitly. +#[uutests::wasi_ignore(SparseLinuxOnly)] #[test] #[cfg(any(target_os = "linux", target_os = "android"))] -#[cfg_attr(wasi_runner, ignore = "WASI: --sparse is only supported on linux")] fn test_cp_umask_stripping_owner_write_bit_reflink_never() { for sparse in ["--sparse=auto", "--sparse=always"] { let (at, mut ucmd) = at_and_ucmd!(); @@ -1152,12 +1128,9 @@ fn test_cp_recursive_dir_applies_umask() { // The umask alone never covers setuid/setgid, so a non-preserving `cp -r` // must clear them on the directories it creates. The sticky bit survives. +#[uutests::wasi_ignore(DirectoryModesUmaskNotFaithful)] #[test] #[cfg(unix)] -#[cfg_attr( - wasi_runner, - ignore = "WASI: directory modes/umask are not faithfully reproduced" -)] fn test_cp_recursive_dir_drops_setuid_setgid() { let scene = TestScenario::new(util_name!()); let at = &scene.fixtures; @@ -1212,12 +1185,9 @@ fn test_cp_recursive_dir_drops_setuid_setgid() { // itself but keeps a pre-existing (truncated) one. Only observable on // filesystems without clone support; when the clone succeeds there is // nothing to clean up. +#[uutests::wasi_ignore(ReflinkLinuxMacosOnly)] #[test] #[cfg(any(target_os = "linux", target_os = "android"))] -#[cfg_attr( - wasi_runner, - ignore = "WASI: --reflink is only supported on linux and macOS" -)] fn test_cp_reflink_always_failure_dest_cleanup() { let scene = TestScenario::new(util_name!()); let at = &scene.fixtures; @@ -1241,12 +1211,9 @@ fn test_cp_reflink_always_failure_dest_cleanup() { assert_eq!(at.read("kept.txt"), ""); } +#[uutests::wasi_ignore(HostPathsNotVisible)] #[test] #[cfg(target_os = "linux")] -#[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: host paths (/dev, /private) not visible" -)] fn test_cp_reflink_always_failure() { let scene = TestScenario::new(util_name!()); scene @@ -1385,11 +1352,8 @@ fn test_cp_arg_backup() { ); } +#[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] -#[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: symlink/hardlink capability restrictions cause dangling-symlink/same-file detection to differ" -)] fn test_cp_arg_backup_with_dest_a_symlink() { let (at, mut ucmd) = at_and_ucmd!(); let source = "source"; @@ -1410,11 +1374,8 @@ fn test_cp_arg_backup_with_dest_a_symlink() { assert_eq!(original, at.resolve_link(backup)); } +#[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] -#[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: symlink/hardlink capability restrictions cause dangling-symlink/same-file detection to differ" -)] fn test_cp_arg_backup_with_dest_a_symlink_to_source() { let (at, mut ucmd) = at_and_ucmd!(); let source = "source"; @@ -2028,12 +1989,9 @@ fn test_cp_parents_dest_not_directory() { .stderr_contains("with --parents, the destination must be a directory"); } +#[uutests::wasi_ignore(NoPermissionBits)] #[test] #[cfg(not(target_os = "openbsd"))] -#[cfg_attr( - wasi_runner, - ignore = "WASI: no chmod syscall, so required mode/ownership preservation always fails" -)] fn test_cp_parents_with_permissions_copy_file() { let (at, mut ucmd) = at_and_ucmd!(); @@ -2073,12 +2031,9 @@ fn test_cp_parents_with_permissions_copy_file() { } } +#[uutests::wasi_ignore(NoPermissionBits)] #[test] #[cfg(not(target_os = "openbsd"))] -#[cfg_attr( - wasi_runner, - ignore = "WASI: no chmod syscall, so required mode/ownership preservation always fails" -)] fn test_cp_parents_with_permissions_copy_dir() { let (at, mut ucmd) = at_and_ucmd!(); @@ -2120,12 +2075,9 @@ fn test_cp_parents_with_permissions_copy_dir() { } } +#[uutests::wasi_ignore(NoPermissionBits)] #[test] #[cfg(unix)] -#[cfg_attr( - wasi_runner, - ignore = "WASI: no chmod syscall, so source modes cannot be set up" -)] fn test_cp_parents_created_dirs_take_source_mode() { // Without -p, a directory that --parents creates gets the mode of the // source directory it stands for, filtered through the umask, whether @@ -2180,12 +2132,9 @@ fn test_cp_parents_created_dirs_take_source_mode() { assert!(at.file_exists("file/ro/f")); } +#[uutests::wasi_ignore(NoPermissionBits)] #[test] #[cfg(unix)] -#[cfg_attr( - wasi_runner, - ignore = "WASI: no chmod syscall, so source modes cannot be set up" -)] fn test_cp_parents_existing_dirs() { // Directories already in the destination keep their attributes when // --parents has nothing to create. Once it creates one, -a/-p refreshes @@ -2233,12 +2182,9 @@ fn test_cp_parents_existing_dirs() { } } +#[uutests::wasi_ignore(NoPermissionBits)] #[test] #[cfg(unix)] -#[cfg_attr( - wasi_runner, - ignore = "WASI: no chmod syscall, so source modes cannot be set up" -)] fn test_cp_parents_dirs_take_source_mode_when_copy_fails() { // The --parents directories still get the source's mode when the copy // stops part-way, and when a directory above the working directory is @@ -2301,22 +2247,16 @@ fn test_cp_parents_failed_source_creates_nothing() { assert!(!at.dir_exists("d/missing")); } +#[uutests::wasi_ignore(HostPathsNotVisible)] #[test] #[cfg(unix)] -#[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: host paths (/dev, /private) not visible" -)] fn test_cp_writable_special_file_permissions() { new_ucmd!().arg("/dev/null").arg("/dev/zero").succeeds(); } +#[uutests::wasi_ignore(HostPathsNotVisible)] #[test] #[cfg(unix)] -#[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: host paths (/dev, /private) not visible" -)] fn test_cp_issue_1665() { let (at, mut ucmd) = at_and_ucmd!(); ucmd.arg("/dev/null").arg("foo").succeeds(); @@ -2324,12 +2264,9 @@ fn test_cp_issue_1665() { assert_eq!(at.read("foo"), ""); } +#[uutests::wasi_ignore(NoPermissionBits)] #[test] #[cfg(not(target_os = "openbsd"))] -#[cfg_attr( - wasi_runner, - ignore = "WASI: no chmod syscall, so required mode/ownership preservation always fails" -)] fn test_cp_preserve_no_args() { let (at, mut ucmd) = at_and_ucmd!(); let src_file = "a"; @@ -2356,12 +2293,9 @@ fn test_cp_preserve_no_args() { } } +#[uutests::wasi_ignore(NoPermissionBits)] #[test] #[cfg(not(target_os = "openbsd"))] -#[cfg_attr( - wasi_runner, - ignore = "WASI: no chmod syscall, so required mode/ownership preservation always fails" -)] fn test_cp_preserve_no_args_before_opts() { let (at, mut ucmd) = at_and_ucmd!(); let src_file = "a"; @@ -2388,11 +2322,8 @@ fn test_cp_preserve_no_args_before_opts() { } } +#[uutests::wasi_ignore(NoPermissionBits)] #[test] -#[cfg_attr( - wasi_runner, - ignore = "WASI: no chmod syscall, so required mode/ownership preservation always fails" -)] fn test_cp_preserve_all() { for argument in ["--preserve=all", "--preserve=al"] { let (at, mut ucmd) = at_and_ucmd!(); @@ -2574,13 +2505,10 @@ fn test_cp_preserve_links_case_1() { } } +#[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] // android platform will causing stderr = cp: Permission denied (os error 13) #[cfg(not(target_os = "android"))] -#[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: symlink/hardlink capability restrictions cause dangling-symlink/same-file detection to differ" -)] fn test_cp_preserve_links_case_2() { let (at, mut ucmd) = at_and_ucmd!(); @@ -2609,13 +2537,10 @@ fn test_cp_preserve_links_case_2() { } } +#[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] // android platform will causing stderr = cp: Permission denied (os error 13) #[cfg(not(target_os = "android"))] -#[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: symlink/hardlink capability restrictions cause dangling-symlink/same-file detection to differ" -)] fn test_cp_preserve_links_case_3() { let (at, mut ucmd) = at_and_ucmd!(); @@ -2777,14 +2702,11 @@ fn test_cp_no_preserve_mode() { assert_eq!(permission_b, "rw-------".to_string()); } +#[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] // For now, disable the test on Windows. Symlinks aren't well support on Windows. // It works on Unix for now and it works locally when run from a powershell #[cfg(not(windows))] -#[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: symlink/hardlink capability restrictions cause dangling-symlink/same-file detection to differ" -)] fn test_cp_deref_folder_to_folder() { let scene = TestScenario::new(util_name!()); let at = &scene.fixtures; @@ -2879,14 +2801,11 @@ fn test_cp_deref_folder_to_folder() { assert_eq!(at.read(path_to_check), "Hello, World!\n"); } +#[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] // For now, disable the test on Windows. Symlinks aren't well support on Windows. // It works on Unix for now and it works locally when run from a powershell #[cfg(not(windows))] -#[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: symlink/hardlink capability restrictions cause dangling-symlink/same-file detection to differ" -)] fn test_cp_no_deref_folder_to_folder() { let scene = TestScenario::new(util_name!()); let at = &scene.fixtures; @@ -2981,12 +2900,9 @@ fn test_cp_no_deref_folder_to_folder() { assert_eq!(at.read(path_to_check), "Hello, World!\n"); } +#[uutests::wasi_ignore(AclXattrPreservationFails)] #[test] #[cfg(target_os = "linux")] -#[cfg_attr( - wasi_runner, - ignore = "WASI: ACL/xattr syscalls are not implemented, so --archive's attribute preservation fails" -)] fn test_cp_archive() { let (at, mut ucmd) = at_and_ucmd!(); let previous = std::time::SystemTime::now() - Duration::from_secs(3600); @@ -3021,12 +2937,9 @@ fn test_cp_archive() { assert_eq!(creation, creation2); } +#[uutests::wasi_ignore(NoPermissionBits)] #[test] #[cfg(all(unix, not(target_os = "android")))] -#[cfg_attr( - wasi_runner, - ignore = "WASI: no chmod syscall, so required mode/ownership preservation always fails" -)] fn test_cp_archive_recursive() { let (at, mut ucmd) = at_and_ucmd!(); @@ -3231,12 +3144,9 @@ fn test_cp_preserve_mode_optional_wasi() { assert!(at.file_exists("dst/file")); } +#[uutests::wasi_ignore(HostPathsNotVisible)] #[test] #[cfg(any(target_os = "linux", target_os = "android"))] -#[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: host paths (/dev, /private) not visible" -)] fn test_cp_target_file_dev_null() { let (at, mut ucmd) = at_and_ucmd!(); let file1 = "/dev/null"; @@ -3473,8 +3383,8 @@ fn test_closes_file_descriptors() { } #[cfg(any(target_os = "linux", target_os = "android"))] +#[uutests::wasi_ignore(SparseLinuxOnly)] #[test] -#[cfg_attr(wasi_runner, ignore = "WASI: --sparse is only supported on linux")] fn test_cp_sparse_never_empty() { const BUFFER_SIZE: usize = 4096 * 4; let (at, mut ucmd) = at_and_ucmd!(); @@ -3494,8 +3404,8 @@ fn test_cp_sparse_never_empty() { } #[cfg(any(target_os = "linux", target_os = "android"))] +#[uutests::wasi_ignore(SparseLinuxOnly)] #[test] -#[cfg_attr(wasi_runner, ignore = "WASI: --sparse is only supported on linux")] fn test_cp_sparse_always_empty() { const BUFFER_SIZE: usize = 4096 * 4; for argument in ["--sparse=always", "--sparse=alway", "--sparse=al"] { @@ -3515,8 +3425,8 @@ fn test_cp_sparse_always_empty() { } #[cfg(any(target_os = "linux", target_os = "android"))] +#[uutests::wasi_ignore(SparseLinuxOnly)] #[test] -#[cfg_attr(wasi_runner, ignore = "WASI: --sparse is only supported on linux")] fn test_cp_sparse_always_non_empty() { const BUFFER_SIZE: usize = 4096 * 16 + 3; let (at, mut ucmd) = at_and_ucmd!(); @@ -3774,11 +3684,8 @@ fn test_cp_debug_sparse_always_windows() { #[cfg(any(target_os = "linux", target_os = "android"))] #[cfg(feature = "truncate")] +#[uutests::wasi_ignore(ReflinkLinuxMacosOnly)] #[test] -#[cfg_attr( - wasi_runner, - ignore = "WASI: --reflink is only supported on linux and macOS" -)] fn test_cp_reflink_always_override() { const DISK: &str = "disk.img"; const ROOTDIR: &str = "disk_root/"; @@ -3857,11 +3764,8 @@ fn test_cp_reflink_always_override() { .succeeds(); } +#[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] -#[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: symlink/hardlink capability restrictions cause dangling-symlink/same-file detection to differ" -)] fn test_copy_dir_symlink() { let (at, mut ucmd) = at_and_ucmd!(); at.mkdir("dir"); @@ -3870,13 +3774,10 @@ fn test_copy_dir_symlink() { assert_eq!(at.resolve_link("copy"), "dir"); } +#[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] #[cfg(not(target_os = "freebsd"))] // FIXME: fix this test for FreeBSD #[cfg(feature = "ln")] -#[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: symlink/hardlink capability restrictions cause dangling-symlink/same-file detection to differ" -)] fn test_copy_dir_with_symlinks() { let (at, mut ucmd) = at_and_ucmd!(); at.mkdir("dir"); @@ -3893,12 +3794,9 @@ fn test_copy_dir_with_symlinks() { assert_eq!(at.resolve_link("copy/file-link"), "file"); } +#[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] #[cfg(not(windows))] -#[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: symlink/hardlink capability restrictions cause dangling-symlink/same-file detection to differ" -)] fn test_copy_symlink_force() { let (at, mut ucmd) = at_and_ucmd!(); at.touch("file"); @@ -3910,13 +3808,10 @@ fn test_copy_symlink_force() { assert_eq!(at.resolve_link("copy"), "file"); } +#[uutests::wasi_ignore(NoPermissionBits)] #[test] #[cfg(unix)] #[cfg(not(target_os = "openbsd"))] -#[cfg_attr( - wasi_runner, - ignore = "WASI: no chmod syscall, so required mode/ownership preservation always fails" -)] fn test_no_preserve_mode() { use std::os::unix::prelude::MetadataExt; @@ -3944,13 +3839,10 @@ fn test_no_preserve_mode() { ); } +#[uutests::wasi_ignore(NoPermissionBits)] #[test] #[cfg(unix)] #[cfg(not(target_os = "openbsd"))] -#[cfg_attr( - wasi_runner, - ignore = "WASI: no chmod syscall, so required mode/ownership preservation always fails" -)] fn test_preserve_mode() { use std::os::unix::prelude::MetadataExt; @@ -4023,11 +3915,8 @@ fn test_copy_through_dangling_symlink() { .stderr_only("cp: not writing through dangling symlink 'target'\n"); } +#[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] -#[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: symlink/hardlink capability restrictions cause dangling-symlink/same-file detection to differ" -)] fn test_copy_through_dangling_symlink_posixly_correct() { let (at, mut ucmd) = at_and_ucmd!(); at.touch("file"); @@ -4042,11 +3931,8 @@ fn test_copy_through_dangling_symlink_posixly_correct() { assert_eq!(contents, "content"); } +#[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] -#[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: symlink/hardlink capability restrictions cause dangling-symlink/same-file detection to differ" -)] fn test_copy_through_dangling_symlink_no_dereference() { let (at, mut ucmd) = at_and_ucmd!(); at.symlink_file("no-such-file", "dangle"); @@ -4057,11 +3943,8 @@ fn test_copy_through_dangling_symlink_no_dereference() { .no_output(); } +#[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] -#[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: symlink/hardlink capability restrictions cause dangling-symlink/same-file detection to differ" -)] fn test_cp_symlink_overwrite_detection() { let ts = TestScenario::new(util_name!()); let at = &ts.fixtures; @@ -4117,11 +4000,8 @@ fn test_cp_dangling_symlink_inside_directory() { /// Test for copying a dangling symbolic link and its permissions. #[cfg(not(any(target_os = "freebsd", target_os = "openbsd")))] // FIXME: fix this test for FreeBSD/OpenBSD +#[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] -#[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: symlink/hardlink capability restrictions cause dangling-symlink/same-file detection to differ" -)] fn test_copy_through_dangling_symlink_no_dereference_permissions() { let (at, mut ucmd) = at_and_ucmd!(); // target name link name @@ -4202,9 +4082,9 @@ fn test_cp_link_backup() { /// It used to create a regular file for any source, which both got the type /// wrong and made the later xattr copy `open()` the source FIFO -- blocking /// forever, since nothing ever writes to it. GNU creates the FIFO and returns. +#[uutests::wasi_ignore(NoFifo)] #[test] #[cfg(unix)] -#[cfg_attr(wasi_runner, ignore = "WASI: no FIFO/mkfifo support")] fn test_cp_attributes_only_fifo_keeps_type_and_returns() { for recursive in ["-a", "-R"] { let scene = TestScenario::new(util_name!()); @@ -4224,9 +4104,9 @@ fn test_cp_attributes_only_fifo_keeps_type_and_returns() { } } +#[uutests::wasi_ignore(NoFifo)] #[test] #[cfg(unix)] -#[cfg_attr(wasi_runner, ignore = "WASI: no FIFO/mkfifo support")] fn test_cp_fifo() { let (at, mut ucmd) = at_and_ucmd!(); at.mkfifo("fifo"); @@ -4245,9 +4125,9 @@ fn test_cp_fifo() { assert_eq!(permission, "prwx-wx--x".to_string()); } +#[uutests::wasi_ignore(NoFifo)] #[test] #[cfg(unix)] -#[cfg_attr(wasi_runner, ignore = "WASI: no FIFO/mkfifo support")] fn test_cp_fifo_preserve_timestamps() { // Preserving timestamps must not open the FIFO: opening a FIFO with no // writer blocks forever. If this regresses, the test hangs instead of @@ -4307,10 +4187,7 @@ fn test_cp_recursive_char_device(#[case] flag: &str) { #[case::recursive("-R")] #[case::archive("-a")] #[cfg(unix)] -#[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: host paths (/dev, /private) not visible" -)] +#[uutests::wasi_ignore(HostPathsNotVisible)] fn test_cp_recursive_char_device_no_permission(#[case] flag: &str) { new_ucmd!() .args(&[flag, "/dev/null", "null2"]) @@ -4318,12 +4195,9 @@ fn test_cp_recursive_char_device_no_permission(#[case] flag: &str) { .stderr_is("cp: cannot create special file 'null2': Operation not permitted\n"); } +#[uutests::wasi_ignore(HostPathsNotVisible)] #[test] #[cfg(unix)] -#[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: host paths (/dev, /private) not visible" -)] fn test_cp_recursive_char_device_copy_contents() { let (at, mut ucmd) = at_and_ucmd!(); ucmd.args(&["-R", "--copy-contents", "/dev/null", "null2"]) @@ -4333,12 +4207,9 @@ fn test_cp_recursive_char_device_copy_contents() { assert_eq!(at.read("null2"), ""); } +#[uutests::wasi_ignore(HostPathsNotVisible)] #[test] #[cfg(unix)] -#[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: host paths (/dev, /private) not visible" -)] fn test_cp_char_device() { let (at, mut ucmd) = at_and_ucmd!(); ucmd.args(&["/dev/null", "null2"]).succeeds().no_stderr(); @@ -4403,9 +4274,9 @@ fn test_cp_block_device_no_permission() { .stderr_is("cp: cannot create special file 'sda2': Operation not permitted\n"); } +#[uutests::wasi_ignore(NoUnixDomainSockets)] #[test] #[cfg(unix)] -#[cfg_attr(wasi_runner, ignore = "WASI: no Unix domain socket support")] fn test_cp_socket() { let (at, mut ucmd) = at_and_ucmd!(); at.mksocket("socket"); @@ -4438,12 +4309,9 @@ fn find_other_group(_current: u32) -> Option { None } +#[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] #[cfg(unix)] -#[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: symlink/hardlink capability restrictions cause dangling-symlink/same-file detection to differ" -)] fn test_cp_r_symlink() { let (at, mut ucmd) = at_and_ucmd!(); // Specifically test copying a link in a subdirectory, as the internal path @@ -4661,11 +4529,8 @@ fn test_copy_same_symlink_no_dereference_dangling() { // TODO: enable for Android, when #3477 solved #[cfg(not(any(windows, target_os = "android", target_os = "openbsd")))] +#[uutests::wasi_ignore(NoPermissionBits)] #[test] -#[cfg_attr( - wasi_runner, - ignore = "WASI: no chmod syscall, so required mode/ownership preservation always fails" -)] fn test_cp_parents_2_dirs() { let (at, mut ucmd) = at_and_ucmd!(); at.mkdir_all("a/b/c"); @@ -4821,11 +4686,8 @@ fn test_cp_mode_hardlink_no_dereference() { } #[cfg(not(any(windows, target_os = "android")))] +#[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] -#[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: symlink/hardlink capability restrictions cause dangling-symlink/same-file detection to differ" -)] fn test_remove_destination_with_destination_being_a_hardlink_to_source() { let (at, mut ucmd) = at_and_ucmd!(); let file = "file"; @@ -4885,12 +4747,9 @@ fn test_remove_destination_symbolic_link_loop() { assert!(at.file_exists("loop")); } +#[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] #[cfg(not(windows))] -#[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: symlink/hardlink capability restrictions cause dangling-symlink/same-file detection to differ" -)] fn test_cp_symbolic_link_loop() { let (at, mut ucmd) = at_and_ucmd!(); at.symlink_file("loop", "loop"); @@ -4930,11 +4789,8 @@ fn test_copy_nested_directory_to_itself_disallowed() { /// Test for preserving permissions when copying a directory. #[cfg(all(not(windows), not(target_os = "freebsd"), not(target_os = "openbsd")))] +#[uutests::wasi_ignore(NoPermissionBits)] #[test] -#[cfg_attr( - wasi_runner, - ignore = "WASI: no chmod syscall, so required mode/ownership preservation always fails" -)] fn test_copy_dir_preserve_permissions() { // Create a directory that has some non-default permissions. let (at, mut ucmd) = at_and_ucmd!(); @@ -4960,11 +4816,8 @@ fn test_copy_dir_preserve_permissions() { /// cp should preserve attributes of subdirectories when copying recursively. #[cfg(all(not(windows), not(target_os = "freebsd"), not(target_os = "openbsd")))] +#[uutests::wasi_ignore(NoPermissionBits)] #[test] -#[cfg_attr( - wasi_runner, - ignore = "WASI: no chmod syscall, so required mode/ownership preservation always fails" -)] fn test_copy_dir_preserve_subdir_permissions() { let (at, mut ucmd) = at_and_ucmd!(); at.mkdir("a1"); @@ -4986,11 +4839,8 @@ fn test_copy_dir_preserve_subdir_permissions() { /// Regression test: build_dir previously created the destination with the source's /// read-only mode, causing EPERM when copying files into it. #[cfg(all(not(windows), not(target_os = "freebsd"), not(target_os = "openbsd")))] +#[uutests::wasi_ignore(NoPermissionBits)] #[test] -#[cfg_attr( - wasi_runner, - ignore = "WASI: no chmod syscall, so required mode/ownership preservation always fails" -)] fn test_copy_dir_preserve_readonly_source_with_files() { let (at, mut ucmd) = at_and_ucmd!(); at.mkdir("src"); @@ -5009,11 +4859,8 @@ fn test_copy_dir_preserve_readonly_source_with_files() { /// Test for preserving permissions when copying a directory, even in /// the face of an inaccessible file in that directory. #[cfg(all(not(windows), not(target_os = "freebsd"), not(target_os = "openbsd")))] +#[uutests::wasi_ignore(NoPermissionBits)] #[test] -#[cfg_attr( - wasi_runner, - ignore = "WASI: no chmod syscall, so required mode/ownership preservation always fails" -)] fn test_copy_dir_preserve_permissions_inaccessible_file() { // Create a directory that has some non-default permissions and // contains an inaccessible file. @@ -5069,11 +4916,8 @@ fn test_same_file_force() { /// Test that copying file to itself with forced backup succeeds. #[cfg(not(windows))] +#[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] -#[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: symlink/hardlink capability restrictions cause dangling-symlink/same-file detection to differ" -)] fn test_same_file_force_backup() { let (at, mut ucmd) = at_and_ucmd!(); at.touch("f"); @@ -5085,8 +4929,8 @@ fn test_same_file_force_backup() { /// Test for copying the contents of a FIFO as opposed to the FIFO object itself. #[cfg(unix)] +#[uutests::wasi_ignore(NoFifo)] #[test] -#[cfg_attr(wasi_runner, ignore = "WASI: no FIFO/mkfifo support")] fn test_copy_contents_fifo() { let scenario = TestScenario::new(util_name!()); let at = &scenario.fixtures; @@ -5111,8 +4955,8 @@ fn test_copy_contents_fifo() { } #[cfg(target_os = "linux")] +#[uutests::wasi_ignore(SparseLinuxOnly)] #[test] -#[cfg_attr(wasi_runner, ignore = "WASI: --sparse is only supported on linux")] fn test_reflink_never_sparse_always() { let (at, mut ucmd) = at_and_ucmd!(); @@ -5138,12 +4982,9 @@ fn test_reflink_never_sparse_always() { } /// Test for preserving attributes of a hard link in a directory. +#[uutests::wasi_ignore(NoPermissionBits)] #[test] #[cfg(not(any(target_os = "android", target_os = "openbsd")))] -#[cfg_attr( - wasi_runner, - ignore = "WASI: no chmod syscall, so required mode/ownership preservation always fails" -)] fn test_preserve_hardlink_attributes_in_directory() { let (at, mut ucmd) = at_and_ucmd!(); @@ -5199,11 +5040,8 @@ fn test_symbolic_link_file() { ); } +#[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] -#[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: symlink/hardlink capability restrictions cause dangling-symlink/same-file detection to differ" -)] fn test_src_base_dot() { let ts = TestScenario::new(util_name!()); let at = &ts.fixtures; @@ -5226,11 +5064,8 @@ fn non_utf8_name(suffix: &str) -> OsString { } #[cfg(target_os = "linux")] +#[uutests::wasi_ignore(NonUtf8ArgsUnsupported)] #[test] -#[cfg_attr( - wasi_runner, - ignore = "WASI: requires valid UTF-8 paths, so the non-UTF-8 error is expected" -)] fn test_non_utf8_src() { let (at, mut ucmd) = at_and_ucmd!(); let src = non_utf8_name("src"); @@ -5240,11 +5075,8 @@ fn test_non_utf8_src() { } #[cfg(target_os = "linux")] +#[uutests::wasi_ignore(NonUtf8ArgsUnsupported)] #[test] -#[cfg_attr( - wasi_runner, - ignore = "WASI: requires valid UTF-8 paths, so the non-UTF-8 error is expected" -)] fn test_non_utf8_dest() { let (at, mut ucmd) = at_and_ucmd!(); let dest = non_utf8_name("dest"); @@ -5255,11 +5087,8 @@ fn test_non_utf8_dest() { } #[cfg(target_os = "linux")] +#[uutests::wasi_ignore(NonUtf8ArgsUnsupported)] #[test] -#[cfg_attr( - wasi_runner, - ignore = "WASI: requires valid UTF-8 paths, so the non-UTF-8 error is expected" -)] fn test_non_utf8_target() { let (at, mut ucmd) = at_and_ucmd!(); let dest = non_utf8_name("dest"); @@ -5272,12 +5101,9 @@ fn test_non_utf8_target() { assert!(at.file_exists(copied_file)); } +#[uutests::wasi_ignore(NoPermissionBits)] #[test] #[cfg(not(windows))] -#[cfg_attr( - wasi_runner, - ignore = "WASI: no chmod syscall, so required mode/ownership preservation always fails" -)] fn test_cp_archive_on_directory_ending_dot() { let (at, mut ucmd) = at_and_ucmd!(); at.mkdir("dir1"); @@ -5287,12 +5113,9 @@ fn test_cp_archive_on_directory_ending_dot() { assert!(at.file_exists("dir2/file")); } +#[uutests::wasi_ignore(DebugReportsUnsupported)] #[test] #[cfg(any(windows, target_vendor = "apple", target_os = "linux"))] -#[cfg_attr( - wasi_runner, - ignore = "WASI: --debug reports 'unsupported' instead of 'unknown' for this platform" -)] fn test_cp_debug_default() { #[cfg(target_vendor = "apple")] let expected = "copy offload: unknown, reflink: unsupported, sparse detection: unsupported"; @@ -5313,12 +5136,9 @@ fn test_cp_debug_default() { .stdout_contains(expected); } +#[uutests::wasi_ignore(DebugReportsUnsupported)] #[test] #[cfg(any(windows, target_vendor = "apple", target_os = "linux"))] -#[cfg_attr( - wasi_runner, - ignore = "WASI: --debug reports 'unsupported' instead of 'unknown' for this platform" -)] fn test_cp_debug_multiple_default() { let ts = TestScenario::new(util_name!()); let at = &ts.fixtures; @@ -5346,9 +5166,9 @@ fn test_cp_debug_multiple_default() { assert_eq!(result.stdout_str().matches(expected).count(), 2); } +#[uutests::wasi_ignore(SparseLinuxOnly)] #[test] #[cfg(target_os = "linux")] -#[cfg_attr(wasi_runner, ignore = "WASI: --sparse is only supported on linux")] fn test_cp_debug_sparse_reflink() { let ts = TestScenario::new(util_name!()); let at = &ts.fixtures; @@ -5379,9 +5199,9 @@ fn test_cp_debug_no_update() { .stdout_contains("skipped 'b'"); } +#[uutests::wasi_ignore(SparseLinuxOnly)] #[test] #[cfg(target_os = "linux")] -#[cfg_attr(wasi_runner, ignore = "WASI: --sparse is only supported on linux")] fn test_cp_debug_sparse_always() { let ts = TestScenario::new(util_name!()); let at = &ts.fixtures; @@ -5396,9 +5216,9 @@ fn test_cp_debug_sparse_always() { .stdout_contains("copy offload: avoided, reflink: unsupported, sparse detection: zeros"); } +#[uutests::wasi_ignore(SparseLinuxOnly)] #[test] #[cfg(target_os = "linux")] -#[cfg_attr(wasi_runner, ignore = "WASI: --sparse is only supported on linux")] fn test_cp_debug_sparse_never() { let ts = TestScenario::new(util_name!()); let at = &ts.fixtures; @@ -5413,11 +5233,8 @@ fn test_cp_debug_sparse_never() { .stdout_contains("copy offload: avoided, reflink: no, sparse detection: no"); } +#[uutests::wasi_ignore(DebugReportsUnsupported)] #[test] -#[cfg_attr( - wasi_runner, - ignore = "WASI: --debug reports 'unsupported' instead of 'unknown' for this platform" -)] fn test_cp_debug_sparse_auto() { let ts = TestScenario::new(util_name!()); let at = &ts.fixtures; @@ -5448,12 +5265,9 @@ fn test_cp_debug_sparse_auto() { } } +#[uutests::wasi_ignore(DebugReportsUnsupported)] #[test] #[cfg(any(target_vendor = "apple", target_os = "linux"))] -#[cfg_attr( - wasi_runner, - ignore = "WASI: --debug reports 'unsupported' instead of 'unknown' for this platform" -)] fn test_cp_debug_reflink_auto() { #[cfg(target_vendor = "apple")] let expected = "copy offload: unknown, reflink: unsupported, sparse detection: unsupported"; @@ -5473,9 +5287,9 @@ fn test_cp_debug_reflink_auto() { .stdout_contains(expected); } +#[uutests::wasi_ignore(SparseLinuxOnly)] #[test] #[cfg(target_os = "linux")] -#[cfg_attr(wasi_runner, ignore = "WASI: --sparse is only supported on linux")] fn test_cp_debug_sparse_always_reflink_auto() { let ts = TestScenario::new(util_name!()); let at = &ts.fixtures; @@ -5519,11 +5333,8 @@ fn test_cp_dest_no_permissions() { /// Test readonly destination behavior with reflink options #[cfg(any(target_vendor = "apple", target_os = "linux"))] +#[uutests::wasi_ignore(ReflinkLinuxMacosOnly)] #[test] -#[cfg_attr( - wasi_runner, - ignore = "WASI: --reflink is only supported on linux and macOS" -)] fn test_cp_readonly_dest_with_reflink() { let ts = TestScenario::new(util_name!()); let at = &ts.fixtures; @@ -5665,12 +5476,9 @@ fn test_cp_attributes_only_dest_open_error() { .stderr_contains("cp: cannot create regular file '/dev/null/n.txt'"); } +#[uutests::wasi_ignore(HostPathsNotVisible)] #[test] #[cfg(unix)] -#[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: host paths (/dev, /private) not visible" -)] fn test_cp_cannot_create_regular_file() { let (at, mut ucmd) = at_and_ucmd!(); at.write("source.txt", "hello"); @@ -5680,12 +5488,9 @@ fn test_cp_cannot_create_regular_file() { .stderr_contains("cp: cannot create regular file '/dev/null/n.txt'"); } +#[uutests::wasi_ignore(HostPathsNotVisible)] #[test] #[cfg(unix)] -#[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: host paths (/dev, /private) not visible" -)] fn test_cp_cannot_create_regular_file_attributes_only() { let (at, mut ucmd) = at_and_ucmd!(); at.write("source.txt", "hello"); @@ -5785,11 +5590,8 @@ fn test_cp_no_such() { target_os = "linux", target_os = "netbsd" ))] +#[uutests::wasi_ignore(AbsoluteHostTmpdirOutsideGuestRoot)] #[test] -#[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: absolute host tmpdir path is outside the mapped guest root, so cp cannot stat it" -)] fn test_acl_preserve() { use std::process::Command; @@ -5828,9 +5630,9 @@ fn test_acl_preserve() { assert!(compare_xattrs(&file, &file_target)); } +#[uutests::wasi_ignore(SparseLinuxOnly)] #[test] #[cfg(any(target_os = "linux", target_os = "android"))] -#[cfg_attr(wasi_runner, ignore = "WASI: --sparse is only supported on linux")] fn test_cp_debug_reflink_never_with_hole() { let ts = TestScenario::new(util_name!()); let at = &ts.fixtures; @@ -5855,9 +5657,9 @@ fn test_cp_debug_reflink_never_with_hole() { assert_eq!(src_file_metadata.blocks(), dst_file_metadata.blocks()); } +#[uutests::wasi_ignore(SparseLinuxOnly)] #[test] #[cfg(any(target_os = "linux", target_os = "android"))] -#[cfg_attr(wasi_runner, ignore = "WASI: --sparse is only supported on linux")] fn test_cp_debug_reflink_never_empty_file_with_hole() { let ts = TestScenario::new(util_name!()); let at = &ts.fixtures; @@ -5881,9 +5683,9 @@ fn test_cp_debug_reflink_never_empty_file_with_hole() { assert_eq!(src_file_metadata.blocks(), dst_file_metadata.blocks()); } +#[uutests::wasi_ignore(SparseLinuxOnly)] #[test] #[cfg(any(target_os = "linux", target_os = "android"))] -#[cfg_attr(wasi_runner, ignore = "WASI: --sparse is only supported on linux")] fn test_cp_debug_default_with_hole() { let ts = TestScenario::new(util_name!()); let at = &ts.fixtures; @@ -5909,9 +5711,9 @@ fn test_cp_debug_default_with_hole() { assert_eq!(src_file_metadata.blocks(), dst_file_metadata.blocks()); } +#[uutests::wasi_ignore(SparseLinuxOnly)] #[test] #[cfg(any(target_os = "linux", target_os = "android"))] -#[cfg_attr(wasi_runner, ignore = "WASI: --sparse is only supported on linux")] fn test_cp_debug_default_less_than_512_bytes() { let ts = TestScenario::new(util_name!()); @@ -5933,9 +5735,9 @@ fn test_cp_debug_default_less_than_512_bytes() { .stdout_contains("copy offload: yes, reflink: unsupported, sparse detection: no"); } +#[uutests::wasi_ignore(SparseLinuxOnly)] #[test] #[cfg(any(target_os = "linux", target_os = "android"))] -#[cfg_attr(wasi_runner, ignore = "WASI: --sparse is only supported on linux")] fn test_cp_debug_default_without_hole() { let ts = TestScenario::new(util_name!()); @@ -5954,9 +5756,9 @@ fn test_cp_debug_default_without_hole() { .stdout_contains("copy offload: yes, reflink: unsupported, sparse detection: no"); } +#[uutests::wasi_ignore(SparseLinuxOnly)] #[test] #[cfg(any(target_os = "linux", target_os = "android"))] -#[cfg_attr(wasi_runner, ignore = "WASI: --sparse is only supported on linux")] fn test_cp_debug_default_empty_file_with_hole() { let ts = TestScenario::new(util_name!()); let at = &ts.fixtures; @@ -5981,9 +5783,9 @@ fn test_cp_debug_default_empty_file_with_hole() { assert_eq!(src_file_metadata.blocks(), dst_file_metadata.blocks()); } +#[uutests::wasi_ignore(SparseLinuxOnly)] #[test] #[cfg(any(target_os = "linux", target_os = "android"))] -#[cfg_attr(wasi_runner, ignore = "WASI: --sparse is only supported on linux")] fn test_cp_debug_reflink_never_sparse_always_with_hole() { let ts = TestScenario::new(util_name!()); let at = &ts.fixtures; @@ -6009,9 +5811,9 @@ fn test_cp_debug_reflink_never_sparse_always_with_hole() { assert_eq!(src_file_metadata.blocks(), dst_file_metadata.blocks()); } +#[uutests::wasi_ignore(SparseLinuxOnly)] #[test] #[cfg(any(target_os = "linux", target_os = "android"))] -#[cfg_attr(wasi_runner, ignore = "WASI: --sparse is only supported on linux")] fn test_cp_debug_reflink_never_sparse_always_without_hole() { let ts = TestScenario::new(util_name!()); let empty_bytes = [0_u8; 10000]; @@ -6035,9 +5837,9 @@ fn test_cp_debug_reflink_never_sparse_always_without_hole() { ); } +#[uutests::wasi_ignore(SparseLinuxOnly)] #[test] #[cfg(any(target_os = "linux", target_os = "android"))] -#[cfg_attr(wasi_runner, ignore = "WASI: --sparse is only supported on linux")] fn test_cp_debug_reflink_never_sparse_always_empty_file_with_hole() { let ts = TestScenario::new(util_name!()); let at = &ts.fixtures; @@ -6058,12 +5860,9 @@ fn test_cp_debug_reflink_never_sparse_always_empty_file_with_hole() { .stdout_contains("copy offload: unknown, reflink: no, sparse detection: SEEK_HOLE"); } +#[uutests::wasi_ignore(HostPathsNotVisible)] #[test] #[cfg(target_os = "linux")] -#[cfg_attr( - wasi_runner, - ignore = "WASI: /sys and /proc virtual files are not exposed to the sandbox" -)] fn test_cp_default_virtual_file() { // This file has existed at least since 2008, so we assume that it is present on "all" Linux kernels. // https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-profiling @@ -6085,9 +5884,9 @@ fn test_cp_default_virtual_file() { .size(); assert!(dest_size > 0); } +#[uutests::wasi_ignore(SparseLinuxOnly)] #[test] #[cfg(any(target_os = "linux", target_os = "android"))] -#[cfg_attr(wasi_runner, ignore = "WASI: --sparse is only supported on linux")] fn test_cp_debug_reflink_auto_sparse_always_non_sparse_file_with_long_zero_sequence() { let ts = TestScenario::new(util_name!()); @@ -6112,9 +5911,9 @@ fn test_cp_debug_reflink_auto_sparse_always_non_sparse_file_with_long_zero_seque ); } +#[uutests::wasi_ignore(SparseLinuxOnly)] #[test] #[cfg(target_os = "linux")] -#[cfg_attr(wasi_runner, ignore = "WASI: --sparse is only supported on linux")] fn test_cp_debug_sparse_never_empty_sparse_file() { let ts = TestScenario::new(util_name!()); let at = &ts.fixtures; @@ -6129,9 +5928,9 @@ fn test_cp_debug_sparse_never_empty_sparse_file() { .stdout_contains("copy offload: avoided, reflink: no, sparse detection: no"); } +#[uutests::wasi_ignore(SparseLinuxOnly)] #[test] #[cfg(any(target_os = "linux", target_os = "android"))] -#[cfg_attr(wasi_runner, ignore = "WASI: --sparse is only supported on linux")] fn test_cp_debug_reflink_never_sparse_always_non_sparse_file_with_long_zero_sequence() { let ts = TestScenario::new(util_name!()); @@ -6157,12 +5956,9 @@ fn test_cp_debug_reflink_never_sparse_always_non_sparse_file_with_long_zero_sequ ); } +#[uutests::wasi_ignore(HostPathsNotVisible)] #[test] #[cfg(target_os = "linux")] -#[cfg_attr( - wasi_runner, - ignore = "WASI: /sys and /proc virtual files are not exposed to the sandbox" -)] fn test_cp_debug_sparse_always_sparse_virtual_file() { // This file has existed at least since 2008, so we assume that it is present on "all" Linux kernels. // https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-profiling @@ -6185,9 +5981,9 @@ fn test_cp_debug_sparse_always_sparse_virtual_file() { ); } +#[uutests::wasi_ignore(SparseLinuxOnly)] #[test] #[cfg(any(target_os = "linux", target_os = "android"))] -#[cfg_attr(wasi_runner, ignore = "WASI: --sparse is only supported on linux")] fn test_cp_debug_reflink_never_less_than_512_bytes() { let ts = TestScenario::new(util_name!()); @@ -6208,9 +6004,9 @@ fn test_cp_debug_reflink_never_less_than_512_bytes() { .stdout_contains("copy offload: avoided, reflink: no, sparse detection: no"); } +#[uutests::wasi_ignore(SparseLinuxOnly)] #[test] #[cfg(any(target_os = "linux", target_os = "android"))] -#[cfg_attr(wasi_runner, ignore = "WASI: --sparse is only supported on linux")] fn test_cp_debug_reflink_never_sparse_never_empty_file_with_hole() { let ts = TestScenario::new(util_name!()); let at = &ts.fixtures; @@ -6231,9 +6027,9 @@ fn test_cp_debug_reflink_never_sparse_never_empty_file_with_hole() { .stdout_contains("copy offload: unknown, reflink: no, sparse detection: SEEK_HOLE"); } +#[uutests::wasi_ignore(SparseLinuxOnly)] #[test] #[cfg(any(target_os = "linux", target_os = "android"))] -#[cfg_attr(wasi_runner, ignore = "WASI: --sparse is only supported on linux")] fn test_cp_debug_reflink_never_file_with_hole() { let ts = TestScenario::new(util_name!()); let at = &ts.fixtures; @@ -6256,9 +6052,9 @@ fn test_cp_debug_reflink_never_file_with_hole() { .stdout_contains("copy offload: avoided, reflink: no, sparse detection: SEEK_HOLE"); } +#[uutests::wasi_ignore(SparseLinuxOnly)] #[test] #[cfg(any(target_os = "linux", target_os = "android"))] -#[cfg_attr(wasi_runner, ignore = "WASI: --sparse is only supported on linux")] fn test_cp_debug_sparse_never_less_than_512_bytes() { let ts = TestScenario::new(util_name!()); @@ -6280,9 +6076,9 @@ fn test_cp_debug_sparse_never_less_than_512_bytes() { .stdout_contains("copy offload: avoided, reflink: no, sparse detection: no"); } +#[uutests::wasi_ignore(SparseLinuxOnly)] #[test] #[cfg(any(target_os = "linux", target_os = "android"))] -#[cfg_attr(wasi_runner, ignore = "WASI: --sparse is only supported on linux")] fn test_cp_debug_sparse_never_without_hole() { let ts = TestScenario::new(util_name!()); @@ -6303,9 +6099,9 @@ fn test_cp_debug_sparse_never_without_hole() { .stdout_contains("copy offload: avoided, reflink: no, sparse detection: no"); } +#[uutests::wasi_ignore(SparseLinuxOnly)] #[test] #[cfg(any(target_os = "linux", target_os = "android"))] -#[cfg_attr(wasi_runner, ignore = "WASI: --sparse is only supported on linux")] fn test_cp_debug_sparse_never_empty_file_with_hole() { let ts = TestScenario::new(util_name!()); let at = &ts.fixtures; @@ -6326,9 +6122,9 @@ fn test_cp_debug_sparse_never_empty_file_with_hole() { .stdout_contains("copy offload: unknown, reflink: no, sparse detection: SEEK_HOLE"); } +#[uutests::wasi_ignore(SparseLinuxOnly)] #[test] #[cfg(any(target_os = "linux", target_os = "android"))] -#[cfg_attr(wasi_runner, ignore = "WASI: --sparse is only supported on linux")] fn test_cp_debug_sparse_never_file_with_hole() { let ts = TestScenario::new(util_name!()); let at = &ts.fixtures; @@ -6351,12 +6147,9 @@ fn test_cp_debug_sparse_never_file_with_hole() { .stdout_contains("copy offload: avoided, reflink: no, sparse detection: SEEK_HOLE"); } +#[uutests::wasi_ignore(HostPathsNotVisible)] #[test] #[cfg(target_os = "linux")] -#[cfg_attr( - wasi_runner, - ignore = "WASI: /sys and /proc virtual files are not exposed to the sandbox" -)] fn test_cp_debug_default_sparse_virtual_file() { // This file has existed at least since 2008, so we assume that it is present on "all" Linux kernels. // https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-profiling @@ -6378,12 +6171,9 @@ fn test_cp_debug_default_sparse_virtual_file() { ); } +#[uutests::wasi_ignore(HostPathsNotVisible)] #[test] #[cfg(target_os = "linux")] -#[cfg_attr( - wasi_runner, - ignore = "WASI: /sys and /proc virtual files are not exposed to the sandbox" -)] fn test_cp_debug_sparse_never_zero_sized_virtual_file() { let ts = TestScenario::new(util_name!()); ts.ucmd() @@ -6400,12 +6190,9 @@ fn test_cp_debug_sparse_never_zero_sized_virtual_file() { // descriptor, so it has to start over at offset 0 -- otherwise everything // the probe consumed is dropped and the destination ends up empty. The // --debug tests above only look at the reported strategy, not the bytes. +#[uutests::wasi_ignore(HostPathsNotVisible)] #[test] #[cfg(target_os = "linux")] -#[cfg_attr( - wasi_runner, - ignore = "WASI: /sys and /proc virtual files are not exposed to the sandbox" -)] fn test_cp_zero_sized_virtual_file_contents() { let expected = std::fs::read_to_string("/proc/version").unwrap(); assert!(!expected.is_empty()); @@ -6427,12 +6214,9 @@ fn test_cp_zero_sized_virtual_file_contents() { } } +#[uutests::wasi_ignore(HostPathsNotVisible)] #[test] #[cfg(target_os = "linux")] -#[cfg_attr( - wasi_runner, - ignore = "WASI: /sys and /proc virtual files are not exposed to the sandbox" -)] fn test_cp_debug_default_zero_sized_virtual_file() { let ts = TestScenario::new(util_name!()); ts.ucmd() @@ -6443,9 +6227,9 @@ fn test_cp_debug_default_zero_sized_virtual_file() { .stdout_contains("copy offload: unsupported, reflink: unsupported, sparse detection: no"); } +#[uutests::wasi_ignore(SparseLinuxOnly)] #[test] #[cfg(any(target_os = "linux", target_os = "android"))] -#[cfg_attr(wasi_runner, ignore = "WASI: --sparse is only supported on linux")] fn test_cp_debug_reflink_never_without_hole() { let ts = TestScenario::new(util_name!()); let filler_bytes = [0_u8; 1000]; @@ -6462,11 +6246,8 @@ fn test_cp_debug_reflink_never_without_hole() { .stdout_contains("copy offload: avoided, reflink: no, sparse detection: no"); } +#[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] -#[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: symlink/hardlink capability restrictions cause dangling-symlink/same-file detection to differ" -)] fn test_cp_force_remove_destination_attributes_only_with_symlink() { let scene = TestScenario::new(util_name!()); let at = &scene.fixtures; @@ -6535,11 +6316,8 @@ mod same_file { // the following tests tries to copy a file to the symlink of the same file with // various options + #[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] - #[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: symlink/hardlink capability restrictions cause dangling-symlink/same-file detection to differ" - )] fn test_same_file_from_file_to_symlink() { for option in ["-d", "-f", "-df"] { let scene = TestScenario::new(util_name!()); @@ -6574,11 +6352,8 @@ mod same_file { assert_eq!(at.read(FILE_NAME), CONTENTS); } + #[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] - #[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: symlink/hardlink capability restrictions cause dangling-symlink/same-file detection to differ" - )] fn test_same_file_from_file_to_symlink_with_backup_option() { for option in ["-b", "-bd", "-bf", "-bdf"] { let scene = TestScenario::new(util_name!()); @@ -6599,11 +6374,8 @@ mod same_file { } } + #[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] - #[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: symlink/hardlink capability restrictions cause dangling-symlink/same-file detection to differ" - )] fn test_same_file_from_file_to_symlink_with_link_option() { for option in ["-l", "-dl"] { let scene = TestScenario::new(util_name!()); @@ -6622,11 +6394,8 @@ mod same_file { } } + #[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] - #[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: symlink/hardlink capability restrictions cause dangling-symlink/same-file detection to differ" - )] fn test_same_file_from_file_to_symlink_with_options_link_and_force() { for option in ["-fl", "-dfl"] { let scene = TestScenario::new(util_name!()); @@ -6643,11 +6412,8 @@ mod same_file { } } + #[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] - #[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: symlink/hardlink capability restrictions cause dangling-symlink/same-file detection to differ" - )] fn test_same_file_from_file_to_symlink_with_options_backup_and_link() { for option in ["-bl", "-bdl", "-bfl", "-bdfl"] { let scene = TestScenario::new(util_name!()); @@ -6667,11 +6433,8 @@ mod same_file { } } + #[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] - #[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: symlink/hardlink capability restrictions cause dangling-symlink/same-file detection to differ" - )] fn test_same_file_from_file_to_symlink_with_options_symlink() { let scene = TestScenario::new(util_name!()); let at = &scene.fixtures; @@ -6688,11 +6451,8 @@ mod same_file { assert_eq!(at.read(FILE_NAME), CONTENTS); } + #[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] - #[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: symlink/hardlink capability restrictions cause dangling-symlink/same-file detection to differ" - )] fn test_same_file_from_file_to_symlink_with_options_symlink_and_force() { let scene = TestScenario::new(util_name!()); let at = &scene.fixtures; @@ -6709,11 +6469,8 @@ mod same_file { } // the following tests tries to copy a symlink to the file that symlink points to with // various options + #[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] - #[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: symlink/hardlink capability restrictions cause dangling-symlink/same-file detection to differ" - )] fn test_same_file_from_symlink_to_file() { for option in ["-d", "-f", "-df", "--rem"] { let scene = TestScenario::new(util_name!()); @@ -6732,11 +6489,8 @@ mod same_file { } } + #[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] - #[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: symlink/hardlink capability restrictions cause dangling-symlink/same-file detection to differ" - )] fn test_same_file_from_symlink_to_file_with_option_backup() { for option in ["-b", "-bf"] { let scene = TestScenario::new(util_name!()); @@ -6754,11 +6508,8 @@ mod same_file { assert_eq!(at.read(FILE_NAME), CONTENTS); } } + #[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] - #[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: symlink/hardlink capability restrictions cause dangling-symlink/same-file detection to differ" - )] fn test_same_file_from_symlink_to_file_with_option_backup_without_deref() { for option in ["-bd", "-bdf"] { let scene = TestScenario::new(util_name!()); @@ -6779,11 +6530,8 @@ mod same_file { } } + #[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] - #[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: symlink/hardlink capability restrictions cause dangling-symlink/same-file detection to differ" - )] fn test_same_file_from_symlink_to_file_with_options_link() { for option in ["-l", "-dl", "-fl", "-bl", "-bfl"] { let scene = TestScenario::new(util_name!()); @@ -6801,11 +6549,8 @@ mod same_file { } } + #[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] - #[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: symlink/hardlink capability restrictions cause dangling-symlink/same-file detection to differ" - )] fn test_same_file_from_symlink_to_file_with_option_symlink() { for option in ["-s", "-sf"] { let scene = TestScenario::new(util_name!()); @@ -6856,11 +6601,8 @@ mod same_file { } } + #[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] - #[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: symlink/hardlink capability restrictions cause dangling-symlink/same-file detection to differ" - )] fn test_same_file_from_file_to_file_with_options_backup_and_no_deref() { for option in ["-bf", "-bdf"] { let scene = TestScenario::new(util_name!()); @@ -6878,11 +6620,8 @@ mod same_file { } } + #[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] - #[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: symlink/hardlink capability restrictions cause dangling-symlink/same-file detection to differ" - )] fn test_same_file_from_file_to_file_with_options_link() { for option in ["-l", "-dl", "-fl", "-dfl", "-bl", "-bdl"] { let scene = TestScenario::new(util_name!()); @@ -6899,11 +6638,8 @@ mod same_file { } } + #[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] - #[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: symlink/hardlink capability restrictions cause dangling-symlink/same-file detection to differ" - )] fn test_same_file_from_file_to_file_with_options_link_and_backup_and_force() { for option in ["-bfl", "-bdfl"] { let scene = TestScenario::new(util_name!()); @@ -6939,11 +6675,8 @@ mod same_file { // the following tests tries to copy a symlink that points to a file to a symlink // that points to the same file with various options + #[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] - #[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: symlink/hardlink capability restrictions cause dangling-symlink/same-file detection to differ" - )] fn test_same_file_from_symlink_to_symlink_with_option_no_deref() { for option in ["-d", "-df"] { let scene = TestScenario::new(util_name!()); @@ -6961,11 +6694,8 @@ mod same_file { } } + #[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] - #[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: symlink/hardlink capability restrictions cause dangling-symlink/same-file detection to differ" - )] fn test_same_file_from_symlink_to_symlink_with_option_force() { let scene = TestScenario::new(util_name!()); let at = &scene.fixtures; @@ -6985,11 +6715,8 @@ mod same_file { assert_eq!(FILE_NAME, at.resolve_link(symlink2)); } + #[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] - #[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: symlink/hardlink capability restrictions cause dangling-symlink/same-file detection to differ" - )] fn test_same_file_from_symlink_to_symlink_with_option_rem() { let scene = TestScenario::new(util_name!()); let at = &scene.fixtures; @@ -7006,11 +6733,8 @@ mod same_file { assert_eq!(at.read(symlink2), CONTENTS); } + #[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] - #[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: symlink/hardlink capability restrictions cause dangling-symlink/same-file detection to differ" - )] fn test_same_file_from_symlink_to_symlink_with_option_backup() { for option in ["-b", "-bf"] { let scene = TestScenario::new(util_name!()); @@ -7031,11 +6755,8 @@ mod same_file { } } + #[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] - #[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: symlink/hardlink capability restrictions cause dangling-symlink/same-file detection to differ" - )] fn test_same_file_from_symlink_to_symlink_with_option_backup_and_no_deref() { for option in ["-bd", "-bdf"] { let scene = TestScenario::new(util_name!()); @@ -7054,11 +6775,8 @@ mod same_file { assert_eq!(FILE_NAME, at.resolve_link(backup)); } } + #[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] - #[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: symlink/hardlink capability restrictions cause dangling-symlink/same-file detection to differ" - )] fn test_same_file_from_symlink_to_symlink_with_option_link() { let scene = TestScenario::new(util_name!()); let at = &scene.fixtures; @@ -7078,11 +6796,8 @@ mod same_file { assert_eq!(FILE_NAME, at.resolve_link(symlink2)); } + #[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] - #[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: symlink/hardlink capability restrictions cause dangling-symlink/same-file detection to differ" - )] fn test_same_file_from_symlink_to_symlink_with_option_force_link() { let scene = TestScenario::new(util_name!()); let at = &scene.fixtures; @@ -7099,11 +6814,8 @@ mod same_file { assert_eq!(at.read(symlink2), CONTENTS); } + #[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] - #[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: symlink/hardlink capability restrictions cause dangling-symlink/same-file detection to differ" - )] fn test_same_file_from_symlink_to_symlink_with_option_backup_and_link() { for option in ["-bl", "-bfl"] { let scene = TestScenario::new(util_name!()); @@ -7124,11 +6836,8 @@ mod same_file { } } + #[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] - #[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: symlink/hardlink capability restrictions cause dangling-symlink/same-file detection to differ" - )] fn test_same_file_from_symlink_to_symlink_with_option_symlink() { let scene = TestScenario::new(util_name!()); let at = &scene.fixtures; @@ -7148,11 +6857,8 @@ mod same_file { assert_eq!(FILE_NAME, at.resolve_link(symlink2)); } + #[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] - #[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: symlink/hardlink capability restrictions cause dangling-symlink/same-file detection to differ" - )] fn test_same_file_from_symlink_to_symlink_with_option_symlink_and_force() { let scene = TestScenario::new(util_name!()); let at = &scene.fixtures; @@ -7215,11 +6921,8 @@ mod same_file { } } + #[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] - #[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: symlink/hardlink capability restrictions cause dangling-symlink/same-file detection to differ" - )] fn test_same_file_from_file_to_hardlink_with_option_rem() { let scene = TestScenario::new(util_name!()); let at = &scene.fixtures; @@ -7235,11 +6938,8 @@ mod same_file { assert_eq!(at.read(FILE_NAME), CONTENTS); } + #[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] - #[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: symlink/hardlink capability restrictions cause dangling-symlink/same-file detection to differ" - )] fn test_same_file_from_file_to_hardlink_with_option_backup() { for option in ["-b", "-bd", "-bf", "-bdf"] { let scene = TestScenario::new(util_name!()); @@ -7256,11 +6956,8 @@ mod same_file { } } + #[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] - #[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: symlink/hardlink capability restrictions cause dangling-symlink/same-file detection to differ" - )] fn test_same_file_from_file_to_hardlink_with_option_link() { for option in ["-l", "-dl", "-fl", "-dfl", "-bl", "-bdl", "-bfl", "-bdfl"] { let scene = TestScenario::new(util_name!()); @@ -7296,11 +6993,8 @@ mod same_file { // the following tests tries to copy symlink to a hardlink of the same symlink with // various options + #[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] - #[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: symlink/hardlink capability restrictions cause dangling-symlink/same-file detection to differ" - )] fn test_same_file_from_hard_link_of_symlink_to_symlink() { let scene = TestScenario::new(util_name!()); let at = &scene.fixtures; @@ -7321,11 +7015,8 @@ mod same_file { assert_eq!(at.read(FILE_NAME), CONTENTS); } + #[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] - #[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: symlink/hardlink capability restrictions cause dangling-symlink/same-file detection to differ" - )] fn test_same_file_from_hard_link_of_symlink_to_symlink_with_option_force() { let scene = TestScenario::new(util_name!()); let at = &scene.fixtures; @@ -7346,11 +7037,8 @@ mod same_file { assert_eq!(at.read(FILE_NAME), CONTENTS); } + #[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] - #[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: symlink/hardlink capability restrictions cause dangling-symlink/same-file detection to differ" - )] fn test_same_file_from_hard_link_of_symlink_to_symlink_with_option_no_deref() { for option in ["-d", "-df"] { let scene = TestScenario::new(util_name!()); @@ -7372,11 +7060,8 @@ mod same_file { } } + #[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] - #[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: symlink/hardlink capability restrictions cause dangling-symlink/same-file detection to differ" - )] fn test_same_file_from_hard_link_of_symlink_to_symlink_with_option_rem() { let scene = TestScenario::new(util_name!()); let at = &scene.fixtures; @@ -7397,11 +7082,8 @@ mod same_file { assert_eq!(at.read(SYMLINK_NAME), CONTENTS); } + #[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] - #[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: symlink/hardlink capability restrictions cause dangling-symlink/same-file detection to differ" - )] fn test_same_file_from_hard_link_of_symlink_to_symlink_with_option_backup() { for option in ["-b", "-bf"] { let scene = TestScenario::new(util_name!()); @@ -7427,11 +7109,8 @@ mod same_file { } } + #[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] - #[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: symlink/hardlink capability restrictions cause dangling-symlink/same-file detection to differ" - )] fn test_same_file_from_hard_link_of_symlink_to_symlink_with_option_backup_and_no_deref() { for option in ["-bd", "-bdf"] { let scene = TestScenario::new(util_name!()); @@ -7456,11 +7135,8 @@ mod same_file { } } + #[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] - #[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: symlink/hardlink capability restrictions cause dangling-symlink/same-file detection to differ" - )] fn test_same_file_from_hard_link_of_symlink_to_symlink_with_option_link() { let scene = TestScenario::new(util_name!()); let at = &scene.fixtures; @@ -7481,11 +7157,8 @@ mod same_file { assert_eq!(at.read(FILE_NAME), CONTENTS); } + #[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] - #[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: symlink/hardlink capability restrictions cause dangling-symlink/same-file detection to differ" - )] fn test_same_file_from_hard_link_of_symlink_to_symlink_with_option_link_and_no_deref() { for option in ["-dl", "-dfl"] { let scene = TestScenario::new(util_name!()); @@ -7507,11 +7180,8 @@ mod same_file { } } + #[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] - #[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: symlink/hardlink capability restrictions cause dangling-symlink/same-file detection to differ" - )] fn test_same_file_from_hard_link_of_symlink_to_symlink_with_option_link_and_force() { let scene = TestScenario::new(util_name!()); let at = &scene.fixtures; @@ -7531,11 +7201,8 @@ mod same_file { assert_eq!(at.read(FILE_NAME), CONTENTS); } + #[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] - #[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: symlink/hardlink capability restrictions cause dangling-symlink/same-file detection to differ" - )] fn test_same_file_from_hard_link_of_symlink_to_symlink_with_option_link_and_backup() { for option in ["-bl", "-bfl"] { let scene = TestScenario::new(util_name!()); @@ -7582,11 +7249,8 @@ mod same_file { } } + #[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] - #[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: symlink/hardlink capability restrictions cause dangling-symlink/same-file detection to differ" - )] fn test_same_file_from_hard_link_of_symlink_to_symlink_with_option_symlink() { let scene = TestScenario::new(util_name!()); let at = &scene.fixtures; @@ -7607,11 +7271,8 @@ mod same_file { assert_eq!(at.read(FILE_NAME), CONTENTS); } + #[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] - #[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: symlink/hardlink capability restrictions cause dangling-symlink/same-file detection to differ" - )] fn test_same_file_from_hard_link_of_symlink_to_symlink_with_option_symlink_and_force() { let scene = TestScenario::new(util_name!()); let at = &scene.fixtures; @@ -7631,11 +7292,8 @@ mod same_file { assert_eq!(at.read(FILE_NAME), CONTENTS); } + #[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] - #[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: symlink/hardlink capability restrictions cause dangling-symlink/same-file detection to differ" - )] fn test_hardlink_of_symlink_to_hardlink_of_same_symlink_with_option_no_deref() { let scene = TestScenario::new(util_name!()); let at = &scene.fixtures; @@ -7709,11 +7367,8 @@ mod link_deref { } // Dereferencing should fail for dangling symlink. + #[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] - #[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: symlink/hardlink capability restrictions cause dangling-symlink/same-file detection to differ" - )] fn test_cp_dang_link_as_source_with_link() { for option in ["", "-L", "-H"] { for r in [false, true] { @@ -7737,11 +7392,8 @@ mod link_deref { } // Dereferencing should fail for the 'dir_link' without -R. + #[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] - #[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: symlink/hardlink capability restrictions cause dangling-symlink/same-file detection to differ" - )] fn test_cp_dir_link_as_source_with_link() { for option in ["", "-L", "-H"] { let scene = TestScenario::new(util_name!()); @@ -7760,11 +7412,8 @@ mod link_deref { } // cp --link -R 'dir_link' should create a new directory. + #[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] - #[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: symlink/hardlink capability restrictions cause dangling-symlink/same-file detection to differ" - )] fn test_cp_dir_link_as_source_with_link_and_r() { for option in ["", "-L", "-H"] { let scene = TestScenario::new(util_name!()); @@ -7780,11 +7429,8 @@ mod link_deref { } //cp --link 'file_link' should create a hard link to the target. + #[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] - #[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: symlink/hardlink capability restrictions cause dangling-symlink/same-file detection to differ" - )] fn test_cp_file_link_as_source_with_link() { for option in ["", "-L", "-H"] { for r in [false, true] { @@ -7814,13 +7460,10 @@ mod link_deref { // This temporary setgid status could grant access to other users who share the same group // ownership as the newly created directory. To mitigate this issue, when creating a directory we // disable these excessive permissions. +#[uutests::wasi_ignore(NoPermissionBits)] #[test] #[cfg(unix)] #[cfg(not(target_os = "openbsd"))] -#[cfg_attr( - wasi_runner, - ignore = "WASI: no chmod syscall, so required mode/ownership preservation always fails" -)] fn test_dir_perm_race_with_preserve_mode_and_ownership() { const SRC_DIR: &str = "src"; const DEST_DIR: &str = "dest"; @@ -7873,13 +7516,10 @@ fn test_dir_perm_race_with_preserve_mode_and_ownership() { } } +#[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] // when -d and -a are overridden with --preserve or --no-preserve make sure that it only // overrides attributes not other flags like -r or --no_deref implied in -a and -d. -#[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: symlink/hardlink capability restrictions cause dangling-symlink/same-file detection to differ" -)] fn test_preserve_attrs_overriding_1() { const FILE: &str = "file"; const SYMLINK: &str = "symlink"; @@ -7897,12 +7537,9 @@ fn test_preserve_attrs_overriding_1() { } } +#[uutests::wasi_ignore(NoPermissionBits)] #[test] #[cfg(all(unix, not(target_os = "android")))] -#[cfg_attr( - wasi_runner, - ignore = "WASI: no chmod syscall, so required mode/ownership preservation always fails" -)] fn test_preserve_attrs_overriding_2() { const FILE1: &str = "file1"; const FILE2: &str = "file2"; @@ -7949,12 +7586,9 @@ fn test_preserve_attrs_overriding_2() { } } +#[uutests::wasi_ignore(NoPermissionBits)] #[test] #[cfg(unix)] -#[cfg_attr( - wasi_runner, - ignore = "WASI: no chmod syscall, so required mode/ownership preservation always fails" -)] fn test_no_preserve_mode_with_later_preserve() { let scene = TestScenario::new(util_name!()); let at = &scene.fixtures; @@ -8003,12 +7637,9 @@ fn test_no_preserve_mode_with_later_preserve() { } /// Test the behavior of preserving permissions when copying through a symlink +#[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] #[cfg(unix)] -#[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: symlink/hardlink capability restrictions cause dangling-symlink/same-file detection to differ" -)] fn test_cp_symlink_permissions() { let scene = TestScenario::new(util_name!()); let at = &scene.fixtures; @@ -8029,12 +7660,9 @@ fn test_cp_symlink_permissions() { } /// Test the behavior of preserving permissions of parents when copying through a symlink +#[uutests::wasi_ignore(NoPermissionBits)] #[test] #[cfg(unix)] -#[cfg_attr( - wasi_runner, - ignore = "WASI: no chmod syscall, so required mode/ownership preservation always fails" -)] fn test_cp_parents_symlink_permissions_file() { let scene = TestScenario::new(util_name!()); let at = &scene.fixtures; @@ -8084,12 +7712,9 @@ fn test_cp_recursive_dest_subdir_symlink_not_followed() { /// A symlinked directory named as the *target* is still a legitimate /// destination -- only entries discovered inside the tree are refused. +#[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] #[cfg(unix)] -#[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: symlink/hardlink capability restrictions cause dangling-symlink/same-file detection to differ" -)] fn test_cp_recursive_target_dir_symlink_still_allowed() { let scene = TestScenario::new(util_name!()); let at = &scene.fixtures; @@ -8105,12 +7730,9 @@ fn test_cp_recursive_target_dir_symlink_still_allowed() { /// Test the behavior of preserving permissions of parents when copying through /// a symlink when source is a dir. +#[uutests::wasi_ignore(NoPermissionBits)] #[test] #[cfg(unix)] -#[cfg_attr( - wasi_runner, - ignore = "WASI: no chmod syscall, so required mode/ownership preservation always fails" -)] fn test_cp_parents_symlink_permissions_dir() { let scene = TestScenario::new(util_name!()); let at = &scene.fixtures; @@ -8132,11 +7754,8 @@ fn test_cp_parents_symlink_permissions_dir() { /// Test the behavior of copying a file to a destination with parents using absolute paths. #[cfg(unix)] +#[uutests::wasi_ignore(HostPathsNotVisible)] #[test] -#[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: host paths (/dev, /private) not visible" -)] fn test_cp_parents_absolute_path() { let scene = TestScenario::new(util_name!()); let at = &scene.fixtures; @@ -8325,12 +7944,9 @@ fn test_cp_preserve_xattr_readonly_source() { ); } +#[uutests::wasi_ignore(NoPermissionBits)] #[test] #[cfg(unix)] -#[cfg_attr( - wasi_runner, - ignore = "WASI: no chmod syscall, so required mode/ownership preservation always fails" -)] fn test_cp_archive_preserves_directory_permissions() { // Test for issue #8407 let (at, mut ucmd) = at_and_ucmd!(); @@ -8369,13 +7985,10 @@ fn test_cp_archive_preserves_directory_permissions() { } } +#[uutests::wasi_ignore(HostPathsNotVisible)] #[test] #[cfg(unix)] #[cfg_attr(target_vendor = "apple", ignore = "Flaky on MacOS, see #8453")] -#[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: host paths (/dev, /private) not visible" -)] fn test_cp_from_stdin() { let (at, mut ucmd) = at_and_ucmd!(); let target = "target"; @@ -8444,10 +8057,7 @@ fn test_cp_update_none_interactive_prompt_no() { /// only unix has `/dev/fd/0` #[cfg(unix)] #[cfg_attr(target_vendor = "apple", ignore = "Flaky on MacOS, see #8453")] -#[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: host paths (/dev, /private) not visible" -)] +#[uutests::wasi_ignore(HostPathsNotVisible)] #[test] fn test_cp_from_stream() { let target = "target"; @@ -8475,10 +8085,7 @@ fn test_cp_from_stream() { /// only unix has `/dev/fd/0` #[cfg(unix)] #[cfg_attr(target_vendor = "apple", ignore = "Flaky on MacOS, see #8453")] -#[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: host paths (/dev, /private) not visible" -)] +#[uutests::wasi_ignore(HostPathsNotVisible)] #[test] fn test_cp_from_stream_permission() { let target = "target"; @@ -8920,10 +8527,7 @@ fn test_cp_preserve_context_root() { #[rstest] #[case::existing_target(true)] #[case::new_target(false)] -#[cfg_attr( - wasi_runner, - ignore = "WASI: wasmtime cannot exec the binary via a raw shell from a deleted cwd" -)] +#[uutests::wasi_ignore(CannotExecShellFromDeletedCwd)] fn test_cp_absolute_paths_from_deleted_cwd(#[case] target_exists: bool) { use std::process::Command; @@ -8968,11 +8572,8 @@ fn test_cp_absolute_paths_from_deleted_cwd(#[case] target_exists: bool) { // This tests the special case where we copy the current directory // to an existing directory, ensuring the directory name is properly // stripped from the descendant path. +#[uutests::wasi_ignore(DotDotCanonicalizationDiffers)] #[test] -#[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: relative '..' path canonicalization differs, causing a false self-copy detection" -)] fn test_cp_current_directory_to_existing_directory() { let (at, mut ucmd) = at_and_ucmd!(); @@ -9004,11 +8605,8 @@ fn test_cp_current_directory_to_existing_directory() { // Test copying current directory (.) to a new directory. // This should create the new directory and copy contents. +#[uutests::wasi_ignore(DotDotCanonicalizationDiffers)] #[test] -#[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: relative '..' path canonicalization differs, causing a false self-copy detection" -)] fn test_cp_current_directory_to_new_directory() { let (at, mut ucmd) = at_and_ucmd!(); @@ -9037,11 +8635,8 @@ fn test_cp_current_directory_to_new_directory() { // Regression test for Launchpad #2167118: // When copying current directory (.), files or directories inside it that share // the same name as the current directory itself must not be stripped to empty paths. +#[uutests::wasi_ignore(DotDotCanonicalizationDiffers)] #[test] -#[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: relative '..' path canonicalization differs, causing a false self-copy detection" -)] fn test_cp_current_directory_with_entry_matching_parent_basename() { let (at, mut ucmd) = at_and_ucmd!(); @@ -9071,11 +8666,8 @@ fn test_cp_current_directory_with_entry_matching_parent_basename() { // Test copying current directory (.) with verbose output. // This ensures the verbose output shows the correct paths. +#[uutests::wasi_ignore(DotDotCanonicalizationDiffers)] #[test] -#[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: relative '..' path canonicalization differs, causing a false self-copy detection" -)] fn test_cp_current_directory_verbose() { let (at, mut ucmd) = at_and_ucmd!(); @@ -9109,12 +8701,9 @@ fn test_cp_current_directory_verbose() { // Test copying current directory (.) with preserve attributes. // This ensures attributes are preserved when copying the current directory. +#[uutests::wasi_ignore(DotDotCanonicalizationDiffers)] #[test] #[cfg(all(not(windows), not(target_os = "freebsd"), not(target_os = "openbsd")))] -#[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: relative '..' path canonicalization differs, causing a false self-copy detection" -)] fn test_cp_current_directory_preserve_attributes() { use std::os::unix::prelude::MetadataExt; @@ -9218,11 +8807,8 @@ fn test_cp_current_directory_to_itself_disallowed() { // Test copying current directory (.) with symlinks. // This ensures symlinks are handled correctly when copying the current directory. +#[uutests::wasi_ignore(DotDotCanonicalizationDiffers)] #[test] -#[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: relative '..' path canonicalization differs, causing a false self-copy detection" -)] fn test_cp_current_directory_with_symlinks() { let (at, mut ucmd) = at_and_ucmd!(); @@ -9250,12 +8836,9 @@ fn test_cp_current_directory_with_symlinks() { assert!(at.is_symlink("dest_dir/subdir/link2.txt")); } +#[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] #[cfg(not(windows))] -#[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: symlink/hardlink capability restrictions cause dangling-symlink/same-file detection to differ" -)] fn test_cp_no_dereference_symlink_with_parents() { let ts = TestScenario::new(util_name!()); let at = &ts.fixtures; @@ -9274,12 +8857,9 @@ fn test_cp_no_dereference_symlink_with_parents() { assert_eq!(at.resolve_link("x/symlink-to-directory"), "directory"); } +#[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] #[cfg(unix)] -#[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: symlink/hardlink capability restrictions cause dangling-symlink/same-file detection to differ" -)] fn test_cp_recursive_no_dereference_symlink_to_directory() { let ts = TestScenario::new(util_name!()); let at = &ts.fixtures; @@ -9381,11 +8961,8 @@ fn test_cp_recurse_verbose_output() { .stdout_is(output); } +#[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] -#[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: symlink/hardlink capability restrictions cause dangling-symlink/same-file detection to differ" -)] fn test_cp_recurse_verbose_output_with_symlink() { let source_dir = "source_dir"; let target_dir = "target_dir"; @@ -9414,11 +8991,8 @@ fn test_cp_recurse_verbose_output_with_symlink() { .stdout_is(output); } +#[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] -#[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: symlink/hardlink capability restrictions cause dangling-symlink/same-file detection to differ" -)] fn test_cp_recurse_verbose_output_with_symlink_already_exists() { let source_dir = "source_dir"; let target_dir = "target_dir"; @@ -9450,12 +9024,9 @@ fn test_cp_recurse_verbose_output_with_symlink_already_exists() { .stdout_is(output); } +#[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] #[cfg(unix)] -#[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: symlink/hardlink capability restrictions cause dangling-symlink/same-file detection to differ" -)] fn test_cp_hlp_flag_ordering() { // GNU cp: "If more than one of -H, -L, and -P is specified, only the final one takes effect" let (at, mut ucmd) = at_and_ucmd!(); @@ -9475,12 +9046,9 @@ fn test_cp_hlp_flag_ordering() { assert!(at.file_exists("dest_ph")); } +#[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] #[cfg(unix)] -#[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: symlink/hardlink capability restrictions cause dangling-symlink/same-file detection to differ" -)] fn test_cp_archive_deref_flag_ordering() { // (flags, expect_symlink): last flag wins; a/d imply -P, H/L dereference for (flags, expect_symlink) in [ @@ -9504,12 +9072,9 @@ fn test_cp_archive_deref_flag_ordering() { /// Regression test: -a keeps recursion when combined with -L/-H/-d. /// https://github.com/uutils/coreutils/issues/13207 +#[uutests::wasi_ignore(NoPermissionBits)] #[test] #[cfg(unix)] -#[cfg_attr( - wasi_runner, - ignore = "WASI: no chmod syscall, so required mode/ownership preservation always fails" -)] fn test_cp_archive_deref_preserves_recursive() { for flags in ["-afL", "-aLf", "-aHL", "-adL"] { let (at, mut ucmd) = at_and_ucmd!(); @@ -9525,12 +9090,9 @@ fn test_cp_archive_deref_preserves_recursive() { } /// -aL should preserve file permissions (--preserve=all from -a). +#[uutests::wasi_ignore(NoPermissionBits)] #[test] #[cfg(unix)] -#[cfg_attr( - wasi_runner, - ignore = "WASI: no chmod syscall, so required mode/ownership preservation always fails" -)] fn test_cp_archive_deref_preserves_mode() { let (at, mut ucmd) = at_and_ucmd!(); at.mkdir("srcdir"); @@ -9567,12 +9129,9 @@ fn test_cp_no_deref_preserve_with_deref_keeps_hardlinks() { /// -aL inside a directory: inner symlinks should be dereferenced, /// while -a preserves them (last-flag-wins for dereference). +#[uutests::wasi_ignore(NoPermissionBits)] #[test] #[cfg(unix)] -#[cfg_attr( - wasi_runner, - ignore = "WASI: no chmod syscall, so required mode/ownership preservation always fails" -)] fn test_cp_archive_deref_symlinks_inside_dir() { use std::os::unix::fs::symlink; let scene = TestScenario::new(util_name!()); @@ -9604,12 +9163,9 @@ fn test_cp_archive_deref_symlinks_inside_dir() { } /// -aH: inner symlinks preserved (a wins for recursive), CLI symlinks followed (H wins for CLI). +#[uutests::wasi_ignore(NoPermissionBits)] #[test] #[cfg(unix)] -#[cfg_attr( - wasi_runner, - ignore = "WASI: no chmod syscall, so required mode/ownership preservation always fails" -)] fn test_cp_archive_cli_deref_inner_preserved() { use std::os::unix::fs::symlink; let scene = TestScenario::new(util_name!()); @@ -9634,12 +9190,9 @@ fn test_cp_archive_cli_deref_inner_preserved() { } /// Precedence: repeating the same flag should take the last position. +#[uutests::wasi_ignore(NoPermissionBits)] #[test] #[cfg(unix)] -#[cfg_attr( - wasi_runner, - ignore = "WASI: no chmod syscall, so required mode/ownership preservation always fails" -)] fn test_cp_archive_deref_repeated_flag_last_wins() { use std::os::unix::fs::symlink; let scene = TestScenario::new(util_name!()); @@ -9857,12 +9410,9 @@ fn test_cp_xattr_failure_keeps_dest_contents() { /// copied. cp still reports the failure and exits 1. tmpfs takes large values /// while ext4 caps a value at one block, so the large attributes fail there /// and the small ones must survive. +#[uutests::wasi_ignore(HostPathsNotVisible)] #[test] #[cfg(target_os = "linux")] -#[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: host paths (/dev/shm) not visible" -)] fn test_cp_preserve_xattr_failure_keeps_the_rest() { use rustc_hash::FxHashMap; use std::ffi::OsStr; @@ -9923,12 +9473,9 @@ fn test_cp_preserve_xattr_failure_keeps_the_rest() { } } +#[uutests::wasi_ignore(NoPermissionBits)] #[test] #[cfg(not(windows))] -#[cfg_attr( - wasi_runner, - ignore = "WASI: no chmod syscall, so required mode/ownership preservation always fails" -)] fn test_cp_preserve_directory_permissions_by_default() { let scene = TestScenario::new(util_name!()); let at = &scene.fixtures; @@ -10084,12 +9631,9 @@ fn test_cp_preserve_context_with_z_fails() { // stripping setuid/setgid when chown cannot preserve ownership — requires a // multi-user setup (source owned by a different uid, cp run as non-root) and // is exercised by GNU's test suite; documenting here as future coverage. +#[uutests::wasi_ignore(NoPermissionBits)] #[test] #[cfg(unix)] -#[cfg_attr( - wasi_runner, - ignore = "WASI: no chmod syscall, so required mode/ownership preservation always fails" -)] fn test_cp_preserve_setuid_when_chown_succeeds() { let (at, mut ucmd) = at_and_ucmd!(); at.touch("src"); @@ -10105,12 +9649,9 @@ fn test_cp_preserve_setuid_when_chown_succeeds() { ); } +#[uutests::wasi_ignore(NonUtf8ArgsUnsupported)] #[test] #[cfg(all(unix, not(target_vendor = "apple")))] -#[cfg_attr( - wasi_runner, - ignore = "WASI: requires valid UTF-8 paths, so the non-UTF-8 error is expected" -)] fn test_cp_recursive_non_utf8_source() { use std::{ffi::OsStr, os::unix::ffi::OsStrExt}; let (at, mut ucmd) = at_and_ucmd!(); @@ -10156,12 +9697,9 @@ fn test_cp_final_mode_unchanged_after_restrictive_create() { // raced deterministically from a unit test; that is locked in by the // strace check in util/check-safe-traversal.sh, which fails if a future // change drops `O_NOFOLLOW` from the source open under `-P`. +#[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] #[cfg(unix)] -#[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: symlink/hardlink capability restrictions cause dangling-symlink/same-file detection to differ" -)] fn test_cp_no_dereference_copies_symlink_as_symlink() { let (at, mut ucmd) = at_and_ucmd!(); at.write("target", "secret target contents"); @@ -10177,12 +9715,9 @@ fn test_cp_no_dereference_copies_symlink_as_symlink() { // still follow the destination symlink and overwrite the link's target. // `-P`/`-d` only forbids dereferencing on the source side; applying // O_NOFOLLOW to the dest open broke this and surfaced as ELOOP. +#[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] #[cfg(unix)] -#[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: symlink/hardlink capability restrictions cause dangling-symlink/same-file detection to differ" -)] fn test_cp_d_overwrites_existing_symlink_dest() { let (at, mut ucmd) = at_and_ucmd!(); at.touch("f"); @@ -10202,12 +9737,9 @@ fn test_cp_d_overwrites_existing_symlink_dest() { // preservation, so the default-no-xattr change in #9704 must not strip // them. Only runs when `setfacl` is available so non-ACL filesystems and // non-Linux CI do not flag spurious failures. +#[uutests::wasi_ignore(AclXattrPreservationFails)] #[test] #[cfg(target_os = "linux")] -#[cfg_attr( - wasi_runner, - ignore = "WASI: ACL/xattr syscalls are not implemented, so -p's attribute preservation fails" -)] fn test_cp_p_preserves_posix_acls() { use std::process::Command; diff --git a/tests/by-util/test_csplit.rs b/tests/by-util/test_csplit.rs index 9f1ae574556..ca0d0708613 100644 --- a/tests/by-util/test_csplit.rs +++ b/tests/by-util/test_csplit.rs @@ -1796,8 +1796,9 @@ fn test_create_error_reports_filename() { .stderr_is("csplit: xx00: Permission denied\n"); } +#[uutests::wasi_ignore(HostPathsNotVisible)] #[test] -#[cfg(all(target_os = "linux", not(wasi_runner)))] +#[cfg(target_os = "linux")] fn test_csplit_dev_full_stdout() { use std::fs::OpenOptions; diff --git a/tests/by-util/test_cut.rs b/tests/by-util/test_cut.rs index 7d27692380f..ebae4c0760e 100644 --- a/tests/by-util/test_cut.rs +++ b/tests/by-util/test_cut.rs @@ -207,8 +207,8 @@ fn test_delimiter_with_byte_and_char() { } } +#[uutests::wasi_ignore(HostPathsNotVisible)] #[test] -#[cfg_attr(wasi_runner, ignore = "WASI sandbox: host paths not visible")] fn test_too_large() { new_ucmd!() .args(&["-b1-18446744073709551615", "/dev/null"]) @@ -643,9 +643,9 @@ fn test_multiple_mode_args() { } } +#[uutests::wasi_ignore(NonUtf8ArgsUnsupported)] #[test] #[cfg(unix)] -#[cfg_attr(wasi_runner, ignore = "WASI: argv/filenames must be valid UTF-8")] fn test_8bit_non_utf8_delimiter() { use std::ffi::OsStr; use std::os::unix::ffi::OsStrExt; @@ -773,8 +773,8 @@ fn test_whitespace_delimited_trimmed_zero_terminated() { .stdout_only_bytes(&b"amber\0"[..]); } +#[uutests::wasi_ignore(NoLocaleData)] #[test] -#[cfg_attr(wasi_runner, ignore = "WASI: the guest does not inherit LC_ALL")] #[cfg(target_os = "linux")] fn test_byte_no_split_partially_selected_char() { // -b -n: the selected bytes of a character must reach its end without a @@ -849,8 +849,8 @@ fn test_newline_delim_suppress_missing_field() { .stdout_only(""); } +#[uutests::wasi_ignore(NoLocaleData)] #[test] -#[cfg_attr(wasi_runner, ignore = "WASI: the guest does not inherit LC_ALL")] #[cfg(target_os = "linux")] fn test_byte_no_split_with_output_delimiter() { // -b -n with an output delimiter: a range covering only part of a @@ -864,8 +864,8 @@ fn test_byte_no_split_with_output_delimiter() { .stdout_only_bytes(b"Z\n"); } +#[uutests::wasi_ignore(NoLocaleData)] #[test] -#[cfg_attr(wasi_runner, ignore = "WASI: the guest does not inherit LC_ALL")] #[cfg(target_os = "linux")] fn test_field_delimiter_not_split_inside_multibyte_char() { use std::os::unix::ffi::OsStrExt; @@ -890,8 +890,8 @@ fn test_field_delimiter_not_split_inside_multibyte_char() { .stdout_only_bytes(b"1\xe2\x82\xac2\n"); } +#[uutests::wasi_ignore(NoLocaleData)] #[test] -#[cfg_attr(wasi_runner, ignore = "WASI: the guest does not inherit LC_ALL")] #[cfg(target_os = "linux")] fn test_whitespace_delimiter_unicode_blank() { // U+2002 (EN SPACE) is a Unicode blank and splits fields under -w. @@ -922,8 +922,8 @@ fn test_delimiter_multibyte_rejected_in_c_locale() { .stderr_contains("cut: the delimiter must be a single character"); } +#[uutests::wasi_ignore(NoLocaleData)] #[test] -#[cfg_attr(wasi_runner, ignore = "WASI: the guest does not inherit LC_ALL")] fn test_emoji_delim() { // A multibyte delimiter is only a single character in a UTF-8 locale. new_ucmd!() @@ -952,9 +952,9 @@ fn test_failed_write_is_reported() { .stderr_is("cut: write error: No space left on device\n"); } +#[uutests::wasi_ignore(NonUtf8ArgsUnsupported)] #[test] #[cfg(target_os = "linux")] -#[cfg_attr(wasi_runner, ignore = "WASI: argv/filenames must be valid UTF-8")] fn test_cut_non_utf8_paths() { use std::fs::File; use std::io::Write; @@ -986,9 +986,9 @@ const GB_LOCALE: &str = "zh_CN.gb18030"; #[cfg(target_os = "linux")] const A: &[u8] = b"\xB0\xA1"; // 啊 +#[uutests::wasi_ignore(NonUtf8ArgsUnsupported)] #[test] #[cfg(target_os = "linux")] -#[cfg_attr(wasi_runner, ignore = "WASI: argv must be valid UTF-8")] fn test_cut_fields_gb18030_delimiter() { use std::ffi::OsString; use std::os::unix::ffi::OsStringExt; @@ -1019,9 +1019,9 @@ fn test_cut_fields_gb18030_delimiter() { .stdout_only_bytes(b"red\xB0\xA1blue\n"); } +#[uutests::wasi_ignore(NonUtf8ArgsUnsupported)] #[test] #[cfg(target_os = "linux")] -#[cfg_attr(wasi_runner, ignore = "WASI: argv must be valid UTF-8")] fn test_cut_fields_gb18030_complement_and_gaps() { use std::ffi::OsString; use std::os::unix::ffi::OsStringExt; @@ -1050,12 +1050,9 @@ fn test_cut_fields_gb18030_complement_and_gaps() { .stdout_only("||z\n"); } +#[uutests::wasi_ignore(NonUtf8ArgsUnsupported)] #[test] #[cfg(target_os = "linux")] -#[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: non-UTF-8 arguments can't be passed through wasmtime" -)] fn test_cut_fields_single_byte_delimiter_in_mb_locale() { use std::ffi::OsString; use std::os::unix::ffi::OsStringExt; @@ -1072,9 +1069,9 @@ fn test_cut_fields_single_byte_delimiter_in_mb_locale() { .stdout_only("a-c\n"); } +#[uutests::wasi_ignore(NonUtf8ArgsUnsupported)] #[test] #[cfg(target_os = "linux")] -#[cfg_attr(wasi_runner, ignore = "WASI: argv must be valid UTF-8")] fn test_cut_chars_gb18030() { // "啊w中": -c counts characters, so the second one is the ASCII 'w'. let line = b"\xB0\xA1w\xD6\xD0\n"; @@ -1103,9 +1100,9 @@ fn test_cut_chars_gb18030() { .stdout_only_bytes(b"\xB0\xA1w\n"); } +#[uutests::wasi_ignore(NonUtf8ArgsUnsupported)] #[test] #[cfg(target_os = "linux")] -#[cfg_attr(wasi_runner, ignore = "WASI: argv must be valid UTF-8")] fn test_cut_chars_gb18030_ranges_and_complement() { // "啊w中": list of two single-char ranges joined by a custom delimiter. new_ucmd!() @@ -1124,9 +1121,9 @@ fn test_cut_chars_gb18030_ranges_and_complement() { .stdout_only_bytes(b"\xB0\xA1\xD6\xD0\n"); } +#[uutests::wasi_ignore(NonUtf8ArgsUnsupported)] #[test] #[cfg(target_os = "linux")] -#[cfg_attr(wasi_runner, ignore = "WASI: argv must be valid UTF-8")] fn test_cut_bytes_no_split_gb18030() { // -n forbids splitting a multibyte character: a byte index landing inside // 啊 only produces output once its final byte is included. @@ -1151,9 +1148,9 @@ fn test_cut_bytes_no_split_gb18030() { // `-c` also operates on whole characters in a UTF-8 locale. The harness runs // under `LC_ALL=C`, so the locale is forced here. "naïve" is n a ï(2 bytes) v e. +#[uutests::wasi_ignore(NonUtf8ArgsUnsupported)] #[test] #[cfg(target_os = "linux")] -#[cfg_attr(wasi_runner, ignore = "WASI: argv must be valid UTF-8")] fn test_cut_chars_utf8() { // The third character is the accented 'ï', returned in full. new_ucmd!() @@ -1182,9 +1179,9 @@ fn test_cut_chars_utf8() { // Lines with no byte above 0x7F take a byte-wise shortcut in a multi-byte // locale; mixing them with multi-byte ones checks both paths agree on offsets. +#[uutests::wasi_ignore(NonUtf8ArgsUnsupported)] #[test] #[cfg(target_os = "linux")] -#[cfg_attr(wasi_runner, ignore = "WASI: argv must be valid UTF-8")] fn test_cut_chars_utf8_mixed_ascii_lines() { let input = "quokka\nfjärd\nwombat\ntøys\n"; @@ -1205,9 +1202,9 @@ fn test_cut_chars_utf8_mixed_ascii_lines() { .stdout_only("okk\när\nmba\nøys\n"); } +#[uutests::wasi_ignore(HostPathsNotVisible)] #[test] #[cfg(all(target_os = "linux", target_env = "gnu"))] -#[cfg_attr(wasi_runner, ignore = "WASI sandbox: host paths (/proc) not visible")] fn test_read_error() { new_ucmd!() .args(&["-c1", "/proc/self/mem"]) diff --git a/tests/by-util/test_date.rs b/tests/by-util/test_date.rs index 5c477dadde6..42f0466cab2 100644 --- a/tests/by-util/test_date.rs +++ b/tests/by-util/test_date.rs @@ -815,9 +815,9 @@ fn test_date_for_empty_file() { ucmd.arg("--file").arg(file).succeeds().no_output(); } +#[uutests::wasi_ignore(NonUtf8ArgsUnsupported)] #[test] #[cfg(target_os = "linux")] -#[cfg_attr(wasi_runner, ignore = "WASI: argv/filenames must be valid UTF-8")] fn test_date_for_file_with_non_utf8_path() { use std::os::unix::ffi::OsStrExt; @@ -918,9 +918,9 @@ fn test_date_for_file_mtime() { .stdout_only("1234\n"); } +#[uutests::wasi_ignore(NonUtf8ArgsUnsupported)] #[test] #[cfg(target_os = "linux")] -#[cfg_attr(wasi_runner, ignore = "WASI: argv/filenames must be valid UTF-8")] fn test_date_reference_is_non_utf8_path() { use std::os::unix::ffi::OsStrExt; use std::time::{Duration, UNIX_EPOCH}; @@ -3162,9 +3162,9 @@ fn test_date_embedded_timezone_conversion() { } // Tests for invalid UTF-8 in date string +#[uutests::wasi_ignore(NonUtf8ArgsUnsupported)] #[test] #[cfg(unix)] -#[cfg_attr(wasi_runner, ignore = "WASI: argv must be valid UTF-8")] fn test_date_invalid_utf8_byte_rejected() { use std::os::unix::ffi::OsStrExt; @@ -3783,9 +3783,9 @@ fn test_nanoseconds_width_prefix_ignored_issue12001() { assert_eq!(result.stdout().len(), 4); } +#[uutests::wasi_ignore(HostPathsNotVisible)] #[test] #[cfg(target_os = "linux")] -#[cfg_attr(wasi_runner, ignore)] fn test_write_error() { use std::fs::OpenOptions; @@ -3810,9 +3810,9 @@ fn test_date_allow_spaces_after_month() { .succeeds(); } +#[uutests::wasi_ignore(NonUtf8ArgsUnsupported)] #[test] #[cfg(unix)] -#[cfg_attr(wasi_runner, ignore = "WASI: argv must be valid UTF-8")] fn test_format_with_non_utf8_bytes() { use std::ffi::OsString; use std::os::unix::ffi::OsStringExt; @@ -3829,9 +3829,9 @@ fn test_format_with_non_utf8_bytes() { .stdout_only_bytes(b"\xc5[2031]\xa7%\xe4\n"); } +#[uutests::wasi_ignore(NonUtf8ArgsUnsupported)] #[test] #[cfg(unix)] -#[cfg_attr(wasi_runner, ignore = "WASI: argv must be valid UTF-8")] fn test_format_percent_before_non_utf8_byte() { use std::ffi::OsString; use std::os::unix::ffi::OsStringExt; @@ -3847,9 +3847,9 @@ fn test_format_percent_before_non_utf8_byte() { .stdout_only_bytes(b"w%\xd0z\n"); } +#[uutests::wasi_ignore(NonUtf8ArgsUnsupported)] #[test] #[cfg(unix)] -#[cfg_attr(wasi_runner, ignore = "WASI: argv must be valid UTF-8")] fn test_format_with_gb18030_bytes() { use std::ffi::OsString; use std::os::unix::ffi::OsStringExt; @@ -3866,9 +3866,9 @@ fn test_format_with_gb18030_bytes() { .stdout_only_bytes(b"2031\xc4\xea7\xd4\xc223\xc8\xd5\n"); } +#[uutests::wasi_ignore(NonUtf8ArgsUnsupported)] #[test] #[cfg(unix)] -#[cfg_attr(wasi_runner, ignore = "WASI: argv must be valid UTF-8")] fn test_non_utf8_operands_are_octal_escaped() { use std::ffi::OsString; use std::os::unix::ffi::OsStringExt; diff --git a/tests/by-util/test_dirname.rs b/tests/by-util/test_dirname.rs index 3ed660877ef..b8a67b522ad 100644 --- a/tests/by-util/test_dirname.rs +++ b/tests/by-util/test_dirname.rs @@ -71,9 +71,9 @@ fn test_empty() { new_ucmd!().arg("").succeeds().stdout_is(".\n"); } +#[uutests::wasi_ignore(NonUtf8ArgsUnsupported)] #[test] #[cfg(unix)] -#[cfg_attr(wasi_runner, ignore = "WASI: argv/filenames must be valid UTF-8")] fn test_dirname_non_utf8_paths() { use std::ffi::OsStr; use std::os::unix::ffi::OsStrExt; @@ -177,9 +177,9 @@ fn test_trailing_dot_emoji() { new_ucmd!().arg("/🎉/🚀/.").succeeds().stdout_is("/🎉/🚀\n"); } +#[uutests::wasi_ignore(NonUtf8ArgsUnsupported)] #[test] #[cfg(unix)] -#[cfg_attr(wasi_runner, ignore = "WASI: argv/filenames must be valid UTF-8")] fn test_trailing_dot_non_utf8() { use std::ffi::OsStr; use std::os::unix::ffi::OsStrExt; diff --git a/tests/by-util/test_du.rs b/tests/by-util/test_du.rs index 39cc4626997..f5787fa1c3f 100644 --- a/tests/by-util/test_du.rs +++ b/tests/by-util/test_du.rs @@ -955,8 +955,8 @@ fn test_du_h_precision() { } } +#[uutests::wasi_ignore(NoLocaleData)] #[test] -#[cfg_attr(wasi_runner, ignore = "WASI: locale env vars not propagated")] fn test_du_h_locale_decimal_separator() { for (locale, expected) in [("fr_FR.UTF-8", "8,4K"), ("C", "8.4K")] { let (at, mut ucmd) = at_and_ucmd!(); diff --git a/tests/by-util/test_echo.rs b/tests/by-util/test_echo.rs index 827005ba278..6767bd88f04 100644 --- a/tests/by-util/test_echo.rs +++ b/tests/by-util/test_echo.rs @@ -657,8 +657,8 @@ fn multibyte_escape_unicode() { .stdout_only_bytes(b"A\xF0"); } +#[uutests::wasi_ignore(NonUtf8ArgsUnsupported)] #[test] -#[cfg_attr(wasi_runner, ignore = "WASI: argv/filenames must be valid UTF-8")] fn non_utf_8_hex_round_trip() { new_ucmd!() .args(&["-e", r"\xFF"]) @@ -681,9 +681,9 @@ fn nine_bit_octal() { .stdout_only_bytes(RESULT); } +#[uutests::wasi_ignore(NonUtf8ArgsUnsupported)] #[test] #[cfg(unix)] -#[cfg_attr(wasi_runner, ignore = "WASI: argv/filenames must be valid UTF-8")] fn non_utf_8() { use std::ffi::OsStr; use std::os::unix::ffi::OsStrExt; @@ -737,8 +737,8 @@ fn test_cmd_result_stdout_check_and_stdout_str_check() { result.no_stderr(); } +#[uutests::wasi_ignore(NoSubprocessSpawning)] #[test] -#[cfg_attr(wasi_runner, ignore = "WASI: no subprocess spawning")] fn test_cmd_result_stderr_check_and_stderr_str_check() { let ts = TestScenario::new("echo"); diff --git a/tests/by-util/test_expand.rs b/tests/by-util/test_expand.rs index 49d19bbe90e..69d1fad171e 100644 --- a/tests/by-util/test_expand.rs +++ b/tests/by-util/test_expand.rs @@ -270,10 +270,7 @@ fn test_tabs_with_too_large_size() { } #[cfg(all(target_os = "linux", target_pointer_width = "64"))] -#[cfg_attr( - wasi_runner, - ignore = "WASI runner target is not suitable for this address-space-limit regression test" -)] +#[uutests::wasi_ignore(AddressSpaceLimitUnsuitable)] #[test] fn test_large_tab_stop_without_tabs_does_not_allocate() { use rustix::process::Resource; @@ -442,9 +439,9 @@ fn test_nonexisting_file() { .stdout_contains_line("// !note: file contains significant whitespace"); } +#[uutests::wasi_ignore(HostPathsNotVisible)] #[test] #[cfg(all(target_os = "linux", not(target_env = "musl")))] -#[cfg_attr(wasi_runner, ignore = "WASI sandbox: host paths not visible")] fn test_read_error() { new_ucmd!() .arg("/proc/self/mem") @@ -452,9 +449,9 @@ fn test_read_error() { .stderr_contains("expand: /proc/self/mem: Input/output error"); } +#[uutests::wasi_ignore(NonUtf8ArgsUnsupported)] #[test] #[cfg(target_os = "linux")] -#[cfg_attr(wasi_runner, ignore = "WASI: argv/filenames must be valid UTF-8")] fn test_expand_non_utf8_paths() { use std::os::unix::ffi::OsStringExt; use uutests::at_and_ucmd; diff --git a/tests/by-util/test_expr.rs b/tests/by-util/test_expr.rs index 9cb2a118d9c..4ca60b8caa2 100644 --- a/tests/by-util/test_expr.rs +++ b/tests/by-util/test_expr.rs @@ -581,11 +581,8 @@ fn test_invalid_substr() { .stdout_only("\n"); } +#[uutests::wasi_ignore(Usize32BitOverflow)] #[test] -#[cfg_attr( - wasi_runner, - ignore = "WASI: usize is 32-bit, the host usize::MAX does not parse" -)] fn test_substr_large_length_capacity_overflow() { new_ucmd!() .args(&["substr", "abc", "1", &usize::MAX.to_string()]) @@ -1574,8 +1571,8 @@ mod expr_arithmetic { mod locale_aware { use uutests::new_ucmd; + #[uutests::wasi_ignore(NoLocaleData)] #[test] - #[cfg_attr(wasi_runner, ignore = "WASI: no locale data, every locale is C")] fn test_expr_collating() { for (loc, code, output) in [ ("C", 0, "1\n"), @@ -2042,8 +2039,8 @@ mod expr_multibyte_arithmetic { } } +#[uutests::wasi_ignore(NoLocaleData)] #[test] -#[cfg_attr(wasi_runner, ignore = "WASI: no locale data, every locale is C")] fn test_emoji_operations() { new_ucmd!() .args(&["🚀", "=", "🚀"]) diff --git a/tests/by-util/test_factor.rs b/tests/by-util/test_factor.rs index cbd1d312132..81fcf218799 100644 --- a/tests/by-util/test_factor.rs +++ b/tests/by-util/test_factor.rs @@ -67,10 +67,10 @@ fn test_trim_null_chars() { .no_stderr(); } +#[uutests::wasi_ignore(HostPathsNotVisible)] #[test] #[cfg(feature = "sort")] #[cfg(not(target_os = "android"))] -#[cfg_attr(wasi_runner, ignore = "WASI sandbox: host paths not visible")] fn test_parallel() { use hex_literal::hex; use sha1::{Digest, Sha1}; diff --git a/tests/by-util/test_fold.rs b/tests/by-util/test_fold.rs index 0849bdda60f..d1c3702028a 100644 --- a/tests/by-util/test_fold.rs +++ b/tests/by-util/test_fold.rs @@ -17,9 +17,9 @@ fn test_invalid_arg() { new_ucmd!().arg("--definitely-invalid").fails_with_code(1); } +#[uutests::wasi_ignore(NonUtf8ArgsUnsupported)] #[test] #[cfg(target_os = "linux")] -#[cfg_attr(wasi_runner, ignore = "WASI: argv/filenames must be valid UTF-8")] fn test_non_utf8_filename() { use std::os::unix::ffi::OsStringExt; @@ -31,9 +31,9 @@ fn test_non_utf8_filename() { ucmd.arg(&filename).succeeds().stdout_only("foo"); } +#[uutests::wasi_ignore(NonUtf8ArgsUnsupported)] #[test] #[cfg(target_os = "linux")] -#[cfg_attr(wasi_runner, ignore = "WASI: argv/filenames must be valid UTF-8")] fn test_non_utf8_filename_of_nonexisting_file() { use std::os::unix::ffi::OsStringExt; @@ -951,10 +951,7 @@ fn test_bytewise_carriage_return_is_not_word_boundary() { } #[cfg(any(target_os = "linux", target_os = "freebsd", target_os = "netbsd"))] -#[cfg_attr( - wasi_runner, - ignore = "WASI: killing the wasmtime process discards the unflushed output buffer, so the streamed bytes never reach stdout" -)] +#[uutests::wasi_ignore(KillDiscardsUnflushedOutput)] #[test] fn test_bytewise_read_from_pseudo_device() { let mut child = new_ucmd!().arg("-b").arg("/dev/zero").run_no_wait(); diff --git a/tests/by-util/test_head.rs b/tests/by-util/test_head.rs index ca4eaae35d9..2a98c611df8 100644 --- a/tests/by-util/test_head.rs +++ b/tests/by-util/test_head.rs @@ -440,8 +440,8 @@ fn test_presume_input_pipe_5_chars() { .stdout_is_fixture("lorem_ipsum_5_chars.expected"); } +#[uutests::wasi_ignore(NoSubprocessSpawning)] #[test] -#[cfg_attr(wasi_runner, ignore = "WASI: no subprocess spawning")] fn test_all_but_last_bytes_large_file_piped() { // Validate print-all-but-last-n-bytes with a large piped-in (i.e. non-seekable) file. let scene = TestScenario::new(util_name!()); @@ -509,8 +509,8 @@ fn test_all_but_last_lines_large_file_presume_input_pipe() { .stdout_only_fixture(expected_output_file_name); } +#[uutests::wasi_ignore(NoSubprocessSpawning)] #[test] -#[cfg_attr(wasi_runner, ignore = "WASI: no subprocess spawning")] fn test_all_but_last_lines_large_file() { // Create our fixtures on the fly. We need the input file to be at least double // the size of BUF_SIZE as specified in head.rs. Go for something a bit bigger @@ -583,11 +583,8 @@ fn test_all_but_last_lines_large_file() { not(target_os = "openbsd"), not(windows) ))] +#[uutests::wasi_ignore(StdinPositionNotPreserved)] #[test] -#[cfg_attr( - wasi_runner, - ignore = "WASI: stdin file position not preserved through wasmtime" -)] fn test_validate_stdin_offset_lines() { // A handful of unix-only tests to validate behavior when reading from stdin on a seekable // file. GNU-compatibility requires that the stdin file be left such that if another @@ -687,11 +684,8 @@ fn test_validate_stdin_offset_lines() { not(target_os = "openbsd"), not(windows) ))] +#[uutests::wasi_ignore(StdinPositionNotPreserved)] #[test] -#[cfg_attr( - wasi_runner, - ignore = "WASI: stdin file position not preserved through wasmtime" -)] fn test_validate_stdin_offset_bytes() { // A handful of unix-only tests to validate behavior when reading from stdin on a seekable // file. GNU-compatibility requires that the stdin file be left such that if another @@ -816,8 +810,8 @@ fn test_validate_stdin_offset_bytes() { not(target_os = "openbsd"), not(windows) ))] +#[uutests::wasi_ignore(HostPathsNotVisible)] #[test] -#[cfg_attr(wasi_runner, ignore = "WASI sandbox: host paths (/proc) not visible")] fn test_read_backwards_bytes_proc_fs_version() { let ts = TestScenario::new(util_name!()); @@ -833,8 +827,8 @@ fn test_read_backwards_bytes_proc_fs_version() { not(target_os = "openbsd"), not(windows) ))] +#[uutests::wasi_ignore(HostPathsNotVisible)] #[test] -#[cfg_attr(wasi_runner, ignore = "WASI sandbox: host paths (/proc) not visible")] fn test_read_backwards_bytes_proc_fs_modules() { let ts = TestScenario::new(util_name!()); @@ -854,8 +848,8 @@ fn test_read_backwards_bytes_proc_fs_modules() { not(target_os = "openbsd"), not(windows) ))] +#[uutests::wasi_ignore(HostPathsNotVisible)] #[test] -#[cfg_attr(wasi_runner, ignore = "WASI sandbox: host paths (/proc) not visible")] fn test_read_backwards_lines_proc_fs_modules() { let ts = TestScenario::new(util_name!()); @@ -875,8 +869,8 @@ fn test_read_backwards_lines_proc_fs_modules() { not(target_os = "openbsd"), not(windows) ))] +#[uutests::wasi_ignore(HostPathsNotVisible)] #[test] -#[cfg_attr(wasi_runner, ignore = "WASI sandbox: host paths (/sys) not visible")] fn test_read_backwards_bytes_sys_kernel_profiling() { let ts = TestScenario::new(util_name!()); // in case the kernel was not built with profiling support, e.g. WSL @@ -948,9 +942,9 @@ fn test_write_to_dev_full() { } } +#[uutests::wasi_ignore(NonUtf8ArgsUnsupported)] #[test] #[cfg(target_os = "linux")] -#[cfg_attr(wasi_runner, ignore = "WASI: argv/filenames must be valid UTF-8")] fn test_head_non_utf8_paths() { use std::ffi::OsStr; use std::os::unix::ffi::OsStrExt; @@ -1058,9 +1052,9 @@ fn test_unreadable_file_prints_no_header() { /// `print_verbatim(...).unwrap()`. A filename longer than the stdout buffer /// forces the header write to flush mid-write so the failure surfaces inside /// the filename write rather than at the next checked one. +#[uutests::wasi_ignore(HostPathsNotVisible)] #[test] #[cfg(target_os = "linux")] -#[cfg_attr(wasi_runner, ignore = "WASI sandbox: host paths (/dev) not visible")] fn test_verbose_header_write_error_long_filename() { use std::fs::File; diff --git a/tests/by-util/test_ln.rs b/tests/by-util/test_ln.rs index e7273f6ac73..871b6acfef7 100644 --- a/tests/by-util/test_ln.rs +++ b/tests/by-util/test_ln.rs @@ -118,10 +118,10 @@ fn test_symlink_overwrite_force() { /// A forced replace must be atomic, so a concurrent creator always loses. /// Fails reliably if unlink-then-create ever comes back. +#[uutests::wasi_ignore(RenameNotAtomicReplace)] #[test] // Android's app-private filesystem refuses hard links. #[cfg(all(unix, not(any(target_os = "redox", target_os = "android"))))] -#[cfg_attr(wasi_runner, ignore)] fn test_force_replace_never_leaves_the_destination_name_free() { use std::sync::Arc; use std::sync::atomic::{AtomicBool, Ordering}; @@ -198,12 +198,9 @@ fn test_force_replace_same_inode_leaves_no_temp_file() { /// The destination can sit inside a directory reached through a symlink, as /// when the target argument is a symlink to a directory. The replace must /// follow it the same way the first create attempt does. +#[uutests::wasi_ignore(LinkInSymlinkedDirectoryDenied)] #[test] #[cfg(unix)] -#[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: creating a link inside a symlinked directory is denied" -)] fn test_force_replace_in_symlinked_directory() { let (at, mut ucmd) = at_and_ucmd!(); at.mkdir("real"); @@ -216,13 +213,10 @@ fn test_force_replace_in_symlinked_directory() { } /// Same as above for a hard link, which goes through the same replace path. +#[uutests::wasi_ignore(LinkInSymlinkedDirectoryDenied)] #[test] // Android's app-private filesystem refuses hard links. #[cfg(all(unix, not(any(target_os = "redox", target_os = "android"))))] -#[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: creating a link inside a symlinked directory is denied" -)] fn test_force_replace_hard_link_in_symlinked_directory() { use std::os::unix::fs::MetadataExt; @@ -504,12 +498,9 @@ fn test_symlink_target_dir() { assert_eq!(at.resolve_link(file_b_link), file_b); } +#[uutests::wasi_ignore(NonUtf8ArgsUnsupported)] #[test] #[cfg(target_os = "linux")] -#[cfg_attr( - wasi_runner, - ignore = "WASI: non-utf8 arguments cannot be passed through the spawned test harness" -)] fn test_symlink_target_dir_non_utf8_source_name() { use std::ffi::OsStr; use std::fs; @@ -675,8 +666,8 @@ fn test_symlink_implicit_target_dir() { assert_eq!(at.resolve_link(filename), *file); } +#[uutests::wasi_ignore(HostPathsNotVisible)] #[test] -#[cfg_attr(wasi_runner, ignore = "WASI sandbox: host paths not visible")] fn test_symlink_to_dir_2args() { let (at, mut ucmd) = at_and_ucmd!(); let filename = "test_symlink_to_dir_2args_file"; @@ -949,11 +940,8 @@ fn test_relative_dst_already_symlink() { at.is_symlink("file2"); } +#[uutests::wasi_ignore(ReadLinkAbsoluteFailsViaHarness)] #[test] -#[cfg_attr( - wasi_runner, - ignore = "WASI: read_link on absolute paths fails under wasmtime via spawned test harness" -)] fn test_relative_src_already_symlink() { let (at, mut ucmd) = at_and_ucmd!(); at.touch("file1"); @@ -1197,9 +1185,9 @@ fn test_ln_seen_file() { } } +#[uutests::wasi_ignore(NonUtf8ArgsUnsupported)] #[test] #[cfg(target_os = "linux")] -#[cfg_attr(wasi_runner, ignore = "WASI: argv/filenames must be valid UTF-8")] fn test_ln_non_utf8_paths() { use std::ffi::OsStr; use std::os::unix::ffi::OsStrExt; diff --git a/tests/by-util/test_mkdir.rs b/tests/by-util/test_mkdir.rs index b12e90c280e..79d7f40e0ca 100644 --- a/tests/by-util/test_mkdir.rs +++ b/tests/by-util/test_mkdir.rs @@ -248,9 +248,9 @@ fn test_mkdir_dup_file() { scene.ucmd().arg("-p").arg(test_file).fails(); } +#[uutests::wasi_ignore(NoPermissionBits)] #[test] #[cfg(not(windows))] -#[cfg_attr(wasi_runner, ignore = "WASI: st_mode has no real permission bits")] fn test_symbolic_mode() { let (at, mut ucmd) = at_and_ucmd!(); let test_dir = "test_dir"; @@ -260,9 +260,9 @@ fn test_symbolic_mode() { assert_eq!(perms, 0o40777); } +#[uutests::wasi_ignore(NoPermissionBits)] #[test] #[cfg(not(windows))] -#[cfg_attr(wasi_runner, ignore = "WASI: st_mode has no real permission bits")] fn test_symbolic_alteration() { let (at, mut ucmd) = at_and_ucmd!(); let test_dir = "test_dir"; @@ -278,9 +278,9 @@ fn test_symbolic_alteration() { assert_eq!(perms, 0o40577); } +#[uutests::wasi_ignore(NoPermissionBits)] #[test] #[cfg(not(windows))] -#[cfg_attr(wasi_runner, ignore = "WASI: st_mode has no real permission bits")] fn test_multi_symbolic() { let (at, mut ucmd) = at_and_ucmd!(); let test_dir = "test_dir"; @@ -436,9 +436,9 @@ fn test_mkdir_p_respects_umask_without_acl() { assert_eq!(perms & 0o777, 0o755); } +#[uutests::wasi_ignore(NoPermissionBits)] #[test] #[cfg(unix)] -#[cfg_attr(wasi_runner, ignore = "WASI: st_mode has no real permission bits")] fn test_mkdir_explicit_mode_zero() { use std::os::unix::fs::PermissionsExt; let (at, mut ucmd) = at_and_ucmd!(); diff --git a/tests/by-util/test_mktemp.rs b/tests/by-util/test_mktemp.rs index 7187b5bf4c5..25cc277fc7d 100644 --- a/tests/by-util/test_mktemp.rs +++ b/tests/by-util/test_mktemp.rs @@ -118,8 +118,8 @@ fn test_mktemp_mktemp() { .fails(); } +#[uutests::wasi_ignore(HostPathsNotVisible)] #[test] -#[cfg_attr(wasi_runner, ignore = "WASI sandbox: host paths not visible")] fn test_mktemp_mktemp_t() { let scene = TestScenario::new(util_name!()); @@ -400,8 +400,8 @@ fn test_mktemp_suffix() { .fails(); } +#[uutests::wasi_ignore(HostPathsNotVisible)] #[test] -#[cfg_attr(wasi_runner, ignore = "WASI sandbox: host paths not visible")] fn test_mktemp_tmpdir() { let scene = TestScenario::new(util_name!()); let dir = tempdir().unwrap(); @@ -464,8 +464,8 @@ fn test_mktemp_tmpdir() { .fails(); } +#[uutests::wasi_ignore(HostPathsNotVisible)] #[test] -#[cfg_attr(wasi_runner, ignore = "WASI sandbox: host paths not visible")] fn test_mktemp_empty_tmpdir() { let scene = TestScenario::new(util_name!()); let pathname = scene.fixtures.as_string(); @@ -485,8 +485,8 @@ fn test_mktemp_empty_tmpdir() { assert!(result.stdout_str().trim().starts_with(&pathname)); } +#[uutests::wasi_ignore(HostPathsNotVisible)] #[test] -#[cfg_attr(wasi_runner, ignore = "WASI sandbox: host paths not visible")] fn test_mktemp_tmpdir_one_arg() { let scene = TestScenario::new(util_name!()); @@ -499,8 +499,8 @@ fn test_mktemp_tmpdir_one_arg() { assert!(PathBuf::from(result.stdout_str().trim()).is_file()); } +#[uutests::wasi_ignore(HostPathsNotVisible)] #[test] -#[cfg_attr(wasi_runner, ignore = "WASI sandbox: host paths not visible")] fn test_mktemp_directory_tmpdir() { let scene = TestScenario::new(util_name!()); @@ -604,12 +604,8 @@ fn test_respect_template_directory() { } #[cfg(unix)] +#[uutests::wasi_ignore(PathCreateDirectoryNoModeParam)] #[test] -#[cfg_attr( - wasi_runner, - ignore = "WASI: path_create_directory has no mode parameter and chmod returns ENOSYS, \ - so directories can't be created with restricted permissions" -)] fn test_directory_permissions() { let (at, mut ucmd) = at_and_ucmd!(); let result = ucmd.args(&["-d", "XXX"]).succeeds(); @@ -879,8 +875,8 @@ fn test_nonexistent_tmpdir_env_var() { } } +#[uutests::wasi_ignore(HostPathsNotVisible)] #[test] -#[cfg_attr(wasi_runner, ignore = "WASI sandbox: host paths not visible")] fn test_empty_tmpdir_env_var() { #[cfg(not(any(windows, target_os = "android")))] { @@ -978,14 +974,14 @@ fn test_nonexistent_dir_prefix() { } } +#[uutests::wasi_ignore(HostPathsNotVisible)] #[test] -#[cfg_attr(wasi_runner, ignore = "WASI sandbox: host paths not visible")] fn test_default_missing_value() { new_ucmd!().arg("-d").arg("--tmpdir").succeeds(); } +#[uutests::wasi_ignore(HostPathsNotVisible)] #[test] -#[cfg_attr(wasi_runner, ignore = "WASI sandbox: host paths not visible")] fn test_default_issue_4821_t_tmpdir() { let scene = TestScenario::new(util_name!()); let pathname = scene.fixtures.as_string(); @@ -1000,8 +996,8 @@ fn test_default_issue_4821_t_tmpdir() { assert!(stdout.contains(&pathname)); } +#[uutests::wasi_ignore(HostPathsNotVisible)] #[test] -#[cfg_attr(wasi_runner, ignore = "WASI sandbox: host paths not visible")] fn test_default_issue_4821_t_tmpdir_p() { let scene = TestScenario::new(util_name!()); let pathname = scene.fixtures.as_string(); @@ -1017,8 +1013,8 @@ fn test_default_issue_4821_t_tmpdir_p() { assert!(stdout.contains(&pathname)); } +#[uutests::wasi_ignore(HostPathsNotVisible)] #[test] -#[cfg_attr(wasi_runner, ignore = "WASI sandbox: host paths not visible")] fn test_t_ensure_tmpdir_has_higher_priority_than_p() { let scene = TestScenario::new(util_name!()); let pathname = scene.fixtures.as_string(); @@ -1114,9 +1110,9 @@ fn test_missing_short_tmpdir_flag() { .stderr_contains("a value is required for '-p ' but none was supplied"); } +#[uutests::wasi_ignore(NonUtf8ArgsUnsupported)] #[test] #[cfg(unix)] -#[cfg_attr(wasi_runner, ignore = "WASI: wasmtime rejects non-UTF-8 arguments")] fn test_non_utf8_template() { use std::ffi::OsStr; use std::os::unix::ffi::OsStrExt; @@ -1129,9 +1125,9 @@ fn test_non_utf8_template() { ts.ucmd().arg(template).fails().stderr_contains("invalid"); } +#[uutests::wasi_ignore(NonUtf8ArgsUnsupported)] #[test] #[cfg(target_os = "linux")] -#[cfg_attr(wasi_runner, ignore = "WASI: wasmtime rejects non-UTF-8 arguments")] fn test_non_utf8_tmpdir_path() { use std::os::unix::ffi::OsStrExt; let (at, mut ucmd) = at_and_ucmd!(); @@ -1144,9 +1140,9 @@ fn test_non_utf8_tmpdir_path() { ucmd.arg("-p").arg(at.plus(dir_name)).succeeds(); } +#[uutests::wasi_ignore(NonUtf8ArgsUnsupported)] #[test] #[cfg(target_os = "linux")] -#[cfg_attr(wasi_runner, ignore = "WASI: wasmtime rejects non-UTF-8 arguments")] fn test_non_utf8_tmpdir_long_option() { use std::os::unix::ffi::OsStrExt; let (at, mut ucmd) = at_and_ucmd!(); @@ -1164,9 +1160,9 @@ fn test_non_utf8_tmpdir_long_option() { .succeeds(); } +#[uutests::wasi_ignore(NonUtf8ArgsUnsupported)] #[test] #[cfg(unix)] -#[cfg_attr(wasi_runner, ignore = "WASI: wasmtime rejects non-UTF-8 arguments")] fn test_invalid_utf8_suffix() { use std::os::unix::ffi::OsStrExt; let (at, mut ucmd) = at_and_ucmd!(); @@ -1185,9 +1181,9 @@ fn test_invalid_utf8_suffix() { .succeeds(); } +#[uutests::wasi_ignore(NonUtf8ArgsUnsupported)] #[test] #[cfg(target_os = "linux")] -#[cfg_attr(wasi_runner, ignore = "WASI: wasmtime rejects non-UTF-8 arguments")] fn test_non_utf8_tmpdir_directory_creation() { use std::os::unix::ffi::OsStrExt; let (at, mut ucmd) = at_and_ucmd!(); @@ -1202,9 +1198,9 @@ fn test_non_utf8_tmpdir_directory_creation() { ucmd.arg("-d").arg("-p").arg(at.plus(dir_name)).succeeds(); } +#[uutests::wasi_ignore(HostPathsNotVisible)] #[test] #[cfg(unix)] -#[cfg_attr(wasi_runner, ignore = "WASI sandbox: host paths not visible")] fn test_mktemp_hidden_file_single_dot() { let scene = TestScenario::new(util_name!()); let dir = tempdir().unwrap(); diff --git a/tests/by-util/test_nl.rs b/tests/by-util/test_nl.rs index ad4fd2b1ff6..31e73bf8fb3 100644 --- a/tests/by-util/test_nl.rs +++ b/tests/by-util/test_nl.rs @@ -7,9 +7,9 @@ use uutests::{at_and_ucmd, new_ucmd, util::TestScenario, util_name}; +#[uutests::wasi_ignore(NonUtf8ArgsUnsupported)] #[test] #[cfg(target_os = "linux")] -#[cfg_attr(wasi_runner, ignore = "WASI: argv/filenames must be valid UTF-8")] fn test_non_utf8_paths() { use std::os::unix::ffi::OsStringExt; let (at, mut ucmd) = at_and_ucmd!(); @@ -230,9 +230,9 @@ fn test_number_separator() { } } +#[uutests::wasi_ignore(NonUtf8ArgsUnsupported)] #[test] #[cfg(unix)] -#[cfg_attr(wasi_runner, ignore = "WASI: argv/filenames must be valid UTF-8")] fn test_number_separator_non_utf8() { use std::{ffi::OsString, os::unix::ffi::OsStringExt}; @@ -665,9 +665,9 @@ fn test_section_delimiter() { } } +#[uutests::wasi_ignore(NonUtf8ArgsUnsupported)] #[test] #[cfg(unix)] -#[cfg_attr(wasi_runner, ignore = "WASI: argv/filenames must be valid UTF-8")] fn test_section_delimiter_non_utf8() { use std::{ffi::OsString, os::unix::ffi::OsStringExt}; @@ -732,9 +732,9 @@ fn test_one_char_section_delimiter() { } } +#[uutests::wasi_ignore(NonUtf8ArgsUnsupported)] #[test] #[cfg(unix)] -#[cfg_attr(wasi_runner, ignore = "WASI: argv/filenames must be valid UTF-8")] fn test_one_byte_section_delimiter() { use std::{ffi::OsString, os::unix::ffi::OsStringExt}; diff --git a/tests/by-util/test_numfmt.rs b/tests/by-util/test_numfmt.rs index 7262f9732be..f502551294b 100644 --- a/tests/by-util/test_numfmt.rs +++ b/tests/by-util/test_numfmt.rs @@ -1389,8 +1389,8 @@ fn test_zero_terminated_embedded_newline() { } #[cfg(unix)] +#[uutests::wasi_ignore(NonUtf8ArgsUnsupported)] #[test] -#[cfg_attr(wasi_runner, ignore = "WASI: argv/filenames must be valid UTF-8")] fn test_non_utf8_delimiter() { use std::ffi::OsStr; use std::os::unix::ffi::OsStrExt; @@ -1768,8 +1768,8 @@ fn test_format_value_below_large_threshold_ok() { .stdout_is("999999999999999999.0\n"); } +#[uutests::wasi_ignore(NoLocaleData)] #[test] -#[cfg_attr(wasi_runner, ignore = "WASI: locale env vars not propagated")] fn test_locale_fr_output() { // Output uses the locale separator new_ucmd!() @@ -1779,8 +1779,8 @@ fn test_locale_fr_output() { .stdout_is("1,5K\n"); } +#[uutests::wasi_ignore(NoLocaleData)] #[test] -#[cfg_attr(wasi_runner, ignore = "WASI: locale env vars not propagated")] fn test_locale_fr_input_comma() { // fr_FR should take '1,5' as a number new_ucmd!() @@ -1790,8 +1790,8 @@ fn test_locale_fr_input_comma() { .stdout_is("1,500\n"); } +#[uutests::wasi_ignore(NoLocaleData)] #[test] -#[cfg_attr(wasi_runner, ignore = "WASI: locale env vars not propagated")] fn test_locale_fr_rejects_period() { // '.' isn't valid in fr_FR, should bail new_ucmd!() diff --git a/tests/by-util/test_od.rs b/tests/by-util/test_od.rs index 8868bca7caa..a88bba34eb8 100644 --- a/tests/by-util/test_od.rs +++ b/tests/by-util/test_od.rs @@ -928,8 +928,8 @@ fn test_skip_bytes_prints_after_consuming_multiple_inputs() { } #[cfg(target_os = "linux")] +#[uutests::wasi_ignore(HostPathsNotVisible)] #[test] -#[cfg_attr(wasi_runner, ignore = "WASI sandbox: host paths (/proc) not visible")] fn test_skip_bytes_proc_file_without_seeking() { let proc_path = Path::new("/proc/version"); if !proc_path.exists() { @@ -984,11 +984,8 @@ fn test_skip_bytes_past_end_message() { // A seekable special file such as /dev/null can be skipped past its (empty) // end without error, matching GNU od. #[cfg(unix)] +#[uutests::wasi_ignore(DevNullNotSeekable)] #[test] -#[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: /dev/null is not a seekable device" -)] fn test_skip_bytes_past_end_of_seekable_device() { new_ucmd!() .arg("-j1") @@ -1006,11 +1003,8 @@ fn test_skip_bytes_past_end_no_offset() { ucmd.arg("-j10").arg("f").fails().no_stdout(); } +#[uutests::wasi_ignore(StdinPositionNotPreserved)] #[test] -#[cfg_attr( - wasi_runner, - ignore = "WASI: stdin file position not preserved through wasmtime" -)] fn test_read_bytes() { let scene = TestScenario::new(util_name!()); let fixtures = &scene.fixtures; @@ -1434,9 +1428,9 @@ fn test_hex_lowercase() { )); } +#[uutests::wasi_ignore(ErrnoMessageMismatch)] #[test] #[cfg(not(windows))] -#[cfg_attr(wasi_runner, ignore)] fn test_is_a_directory() { let scene = TestScenario::new(util_name!()); let fixtures = &scene.fixtures; diff --git a/tests/by-util/test_paste.rs b/tests/by-util/test_paste.rs index 020fceb80aa..582d70e5ab3 100644 --- a/tests/by-util/test_paste.rs +++ b/tests/by-util/test_paste.rs @@ -406,8 +406,8 @@ fn test_paste_delimiter_escape_sequences() { // As of 2024-10-09, only bsdutils (https://github.com/dcantrell/bsdutils, derived from FreeBSD) and toybox handle // multibyte delimiter characters in the way a user would likely expect. BusyBox and GNU Core Utilities do not. +#[uutests::wasi_ignore(NoLocaleData)] #[test] -#[cfg_attr(wasi_runner, ignore = "WASI: the guest does not inherit LC_ALL")] fn test_multi_byte_delimiter() { for option_style in ["-d", "--delimiters"] { new_ucmd!() @@ -433,8 +433,8 @@ fn test_multi_byte_delimiter() { } } +#[uutests::wasi_ignore(NoLocaleData)] #[test] -#[cfg_attr(wasi_runner, ignore = "WASI: the guest does not inherit LC_ALL")] fn test_data() { for example in EXAMPLE_DATA { let (at, mut ucmd) = at_and_ucmd!(); @@ -454,9 +454,9 @@ fn test_data() { } } +#[uutests::wasi_ignore(NonUtf8ArgsUnsupported)] #[test] #[cfg(target_os = "linux")] -#[cfg_attr(wasi_runner, ignore = "WASI: argv/filenames must be valid UTF-8")] fn test_non_utf8_delimiter() { let (at, mut ucmd) = at_and_ucmd!(); at.write("f1", "1\n2\n"); @@ -470,9 +470,9 @@ fn test_non_utf8_delimiter() { .stdout_only_bytes(b"1\xA2\xE3a\n2\xA2\xE3b\n"); } +#[uutests::wasi_ignore(NonUtf8ArgsUnsupported)] #[test] #[cfg(target_os = "linux")] -#[cfg_attr(wasi_runner, ignore = "WASI: argv/filenames must be valid UTF-8")] fn test_paste_non_utf8_paths() { let (at, mut ucmd) = at_and_ucmd!(); @@ -497,9 +497,9 @@ fn make_broken_pipe() -> std::io::PipeWriter { write } +#[uutests::wasi_ignore(HostPathsNotVisible)] #[test] #[cfg(target_os = "linux")] -#[cfg_attr(wasi_runner, ignore = "WASI sandbox: host paths (/dev) not visible")] fn test_dev_zero_write_error_dev_full() { use std::fs::File; @@ -514,9 +514,9 @@ fn test_dev_zero_write_error_dev_full() { .stderr_contains("No space left on device"); } +#[uutests::wasi_ignore(HostPathsNotVisible)] #[test] #[cfg(target_os = "linux")] -#[cfg_attr(wasi_runner, ignore = "WASI sandbox: host paths (/dev) not visible")] fn test_dev_zero_closed_pipe() { new_ucmd!() .arg("/dev/zero") diff --git a/tests/by-util/test_pathchk.rs b/tests/by-util/test_pathchk.rs index ceae18d87d8..ef8af6cbe57 100644 --- a/tests/by-util/test_pathchk.rs +++ b/tests/by-util/test_pathchk.rs @@ -196,9 +196,9 @@ fn test_empty_path_portability_message() { } } +#[uutests::wasi_ignore(NonUtf8ArgsUnsupported)] #[test] #[cfg(target_os = "linux")] -#[cfg_attr(wasi_runner, ignore = "WASI: argv/filenames must be valid UTF-8")] fn test_pathchk_non_utf8_paths() { let filename = std::ffi::OsString::from_vec(vec![0xFF, 0xFE]); new_ucmd!().arg(&filename).succeeds(); diff --git a/tests/by-util/test_pr.rs b/tests/by-util/test_pr.rs index e626f0cc55c..69f7dcd041a 100644 --- a/tests/by-util/test_pr.rs +++ b/tests/by-util/test_pr.rs @@ -628,8 +628,8 @@ fn test_with_date_format() { .stdout_only(format!("\n\nHello!{whitespace}Page 1\n\n\na{blank_lines}")); } +#[uutests::wasi_ignore(NoLocaleData)] #[test] -#[cfg_attr(wasi_runner, ignore = "WASI sandbox: locale database not visible")] fn test_with_date_format_env() { // POSIXLY_CORRECT + LC_ALL/TIME=POSIX uses "%b %e %H:%M %Y" date format let whitespace = " ".repeat(49); diff --git a/tests/by-util/test_printenv.rs b/tests/by-util/test_printenv.rs index 89b9140fc21..c27e7080275 100644 --- a/tests/by-util/test_printenv.rs +++ b/tests/by-util/test_printenv.rs @@ -92,10 +92,10 @@ fn test_null_separator() { } } +#[uutests::wasi_ignore(NonUtf8ArgsUnsupported)] #[test] #[cfg(unix)] #[cfg(not(any(target_os = "freebsd", target_os = "android", target_os = "openbsd")))] -#[cfg_attr(wasi_runner, ignore = "WASI: env values must be valid UTF-8")] fn test_non_utf8_value() { use std::ffi::OsStr; use std::os::unix::ffi::OsStrExt; @@ -120,9 +120,9 @@ fn test_non_utf8_value() { result.stdout_is_bytes(b"/tmp/lib.so\xff\n"); } +#[uutests::wasi_ignore(NonUtf8ArgsUnsupported)] #[test] #[cfg(unix)] -#[cfg_attr(wasi_runner, ignore = "WASI: env values must be valid UTF-8")] fn test_non_utf8_env_vars() { use std::ffi::OsString; use std::os::unix::ffi::OsStringExt; diff --git a/tests/by-util/test_printf.rs b/tests/by-util/test_printf.rs index 32c51d7a418..f174863bdb5 100644 --- a/tests/by-util/test_printf.rs +++ b/tests/by-util/test_printf.rs @@ -1451,9 +1451,9 @@ fn mb_input() { } } +#[uutests::wasi_ignore(NonUtf8ArgsUnsupported)] #[test] #[cfg(unix)] -#[cfg_attr(wasi_runner, ignore = "WASI: argv/filenames must be valid UTF-8")] fn mb_invalid_unicode() { use std::ffi::OsStr; use std::os::unix::ffi::OsStrExt; @@ -1540,9 +1540,9 @@ fn positional_format_specifiers() { .stdout_only("Octal: 115, Int: 42, Float: 3.141590, String: hello, Hex: ff, Scientific: 1.000000e-05, Char: A, Unsigned: 100, Integer: 123"); } +#[uutests::wasi_ignore(NonUtf8ArgsUnsupported)] #[test] #[cfg(unix)] -#[cfg_attr(wasi_runner, ignore = "WASI: argv/filenames must be valid UTF-8")] fn non_utf_8_input() { use std::ffi::OsStr; use std::os::unix::ffi::OsStrExt; diff --git a/tests/by-util/test_rmdir.rs b/tests/by-util/test_rmdir.rs index 16f1cb25443..6a2fd2bac04 100644 --- a/tests/by-util/test_rmdir.rs +++ b/tests/by-util/test_rmdir.rs @@ -207,8 +207,8 @@ fn test_rmdir_ignore_nonempty_no_permissions() { at.set_mode("dir/ect", 0o755); } +#[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] -#[cfg_attr(wasi_runner, ignore = "WASI: read_link() not supported for symlinks")] fn test_rmdir_remove_symlink_file() { let (at, mut ucmd) = at_and_ucmd!(); @@ -222,8 +222,8 @@ fn test_rmdir_remove_symlink_file() { // This behavior is known to happen on Linux but not all Unixes #[cfg(any(target_os = "linux", target_os = "android"))] +#[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] -#[cfg_attr(wasi_runner, ignore = "WASI: read_link() not supported for symlinks")] fn test_rmdir_remove_symlink_dir() { let (at, mut ucmd) = at_and_ucmd!(); @@ -236,8 +236,8 @@ fn test_rmdir_remove_symlink_dir() { } #[cfg(any(target_os = "linux", target_os = "android"))] +#[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] -#[cfg_attr(wasi_runner, ignore = "WASI: read_link() not supported for symlinks")] fn test_rmdir_remove_symlink_dangling() { let (at, mut ucmd) = at_and_ucmd!(); @@ -249,8 +249,8 @@ fn test_rmdir_remove_symlink_dangling() { } #[cfg(any(target_os = "linux", target_os = "android"))] +#[uutests::wasi_ignore(SymlinkHardlinkCaps)] #[test] -#[cfg_attr(wasi_runner, ignore = "WASI: read_link() not supported for symlinks")] fn test_rmdir_remove_symlink_dir_with_trailing_slashes() { // a symlink with trailing slashes should still be printing the 'Symbolic link not followed' // message diff --git a/tests/by-util/test_shred.rs b/tests/by-util/test_shred.rs index c3a57ab3cb9..772578f1c7a 100644 --- a/tests/by-util/test_shred.rs +++ b/tests/by-util/test_shred.rs @@ -559,9 +559,9 @@ shred: invalid file size: '4vv' } } +#[uutests::wasi_ignore(HostPathsNotVisible)] #[test] #[cfg(target_os = "linux")] -#[cfg_attr(wasi_runner, ignore = "WASI sandbox: host paths (/proc) not visible")] fn test_couldnt_rename() { new_ucmd!() .args(&["-u", "/proc/self/mem"]) diff --git a/tests/by-util/test_shuf.rs b/tests/by-util/test_shuf.rs index 98fcfd7673e..9cc8ba302c3 100644 --- a/tests/by-util/test_shuf.rs +++ b/tests/by-util/test_shuf.rs @@ -15,9 +15,9 @@ fn test_invalid_arg() { new_ucmd!().arg("--definitely-invalid").fails_with_code(1); } +#[uutests::wasi_ignore(NoSubprocessSpawning)] #[test] #[cfg(target_os = "linux")] -#[cfg(not(wasi_runner))] fn test_getrandom_fail() { // getrandom is missing from legacy kernel use std::process::Command; @@ -434,8 +434,8 @@ fn test_echo_separators_in_arguments() { } #[cfg(unix)] +#[uutests::wasi_ignore(NonUtf8ArgsUnsupported)] #[test] -#[cfg_attr(wasi_runner, ignore = "WASI: argv/filenames must be valid UTF-8")] fn test_echo_invalid_unicode_in_arguments() { use std::{ffi::OsStr, os::unix::ffi::OsStrExt}; @@ -450,8 +450,8 @@ fn test_echo_invalid_unicode_in_arguments() { #[cfg(unix)] #[cfg(not(target_vendor = "apple"))] +#[uutests::wasi_ignore(NonUtf8ArgsUnsupported)] #[test] -#[cfg_attr(wasi_runner, ignore = "WASI: argv/filenames must be valid UTF-8")] fn test_invalid_unicode_in_filename() { use std::{ffi::OsStr, os::unix::ffi::OsStrExt}; @@ -928,9 +928,9 @@ fn test_range_repeat_empty_minus_one() { } // This test fails if we forget to flush the `BufWriter`. +#[uutests::wasi_ignore(HostPathsNotVisible)] #[test] #[cfg(target_os = "linux")] -#[cfg_attr(wasi_runner, ignore = "WASI sandbox: host paths not visible")] fn write_errors_are_reported() { new_ucmd!() .arg("-i1-10") diff --git a/tests/by-util/test_sleep.rs b/tests/by-util/test_sleep.rs index b7e676a6c5a..08ab33ebc2c 100644 --- a/tests/by-util/test_sleep.rs +++ b/tests/by-util/test_sleep.rs @@ -143,9 +143,9 @@ fn test_sleep_wrong_time() { new_ucmd!().args(&["0.1s", "abc"]).fails(); } +#[uutests::wasi_ignore(NoPipeSignalSupport)] #[test] #[cfg(unix)] -#[cfg_attr(wasi_runner, ignore = "WASI: no signal support")] fn test_sleep_stops_after_sigsegv() { let mut child = new_ucmd!() .arg("100") @@ -161,9 +161,9 @@ fn test_sleep_stops_after_sigsegv() { .no_output(); } +#[uutests::wasi_ignore(NoPipeSignalSupport)] #[test] #[cfg(unix)] -#[cfg_attr(wasi_runner, ignore = "WASI: no signal support")] fn test_sleep_stops_after_sigbus() { let mut child = new_ucmd!() .arg("100") diff --git a/tests/by-util/test_sort.rs b/tests/by-util/test_sort.rs index 6aeccf0e70b..aa473ba52e3 100644 --- a/tests/by-util/test_sort.rs +++ b/tests/by-util/test_sort.rs @@ -1420,9 +1420,9 @@ fn test_spill_write_error_does_not_panic() { // A read error must be reported with context and without the raw io::Error suffix. // It used to print `sort: Input/output error (os error 5)`. +#[uutests::wasi_ignore(HostPathsNotVisible)] #[test] #[cfg(target_os = "linux")] -#[cfg_attr(wasi_runner, ignore)] fn test_read_error_message() { // Reading /proc/self/mem from offset 0 fails with EIO. let result = new_ucmd!().arg("/proc/self/mem").fails_with_code(2); diff --git a/tests/by-util/test_sum.rs b/tests/by-util/test_sum.rs index c75af526c68..af60e92591a 100644 --- a/tests/by-util/test_sum.rs +++ b/tests/by-util/test_sum.rs @@ -98,9 +98,9 @@ fn test_invalid_metadata() { .stderr_is("sum: b: No such file or directory\n"); } +#[uutests::wasi_ignore(NonUtf8ArgsUnsupported)] #[test] #[cfg(target_os = "linux")] -#[cfg_attr(wasi_runner, ignore = "WASI: argv/filenames must be valid UTF-8")] fn test_sum_non_utf8_paths() { let (at, mut ucmd) = at_and_ucmd!(); @@ -122,7 +122,7 @@ fn test_filename_ends_with_slash() { } #[cfg(all(unix, not(target_vendor = "apple"), not(target_os = "openbsd")))] -#[cfg_attr(wasi_runner, ignore)] +#[uutests::wasi_ignore(HostPathsNotVisible)] #[test] fn test_filename_proc_self_mem() { // https://github.com/uutils/coreutils/issues/12949 diff --git a/tests/by-util/test_tail.rs b/tests/by-util/test_tail.rs index 9758f5cf7ca..75b89936ee1 100644 --- a/tests/by-util/test_tail.rs +++ b/tests/by-util/test_tail.rs @@ -241,8 +241,8 @@ fn test_nc_0_wo_follow2() { .no_output(); } +#[uutests::wasi_ignore(TailFollowDisabled)] #[test] -#[cfg_attr(wasi_runner, ignore = "WASI: tail follow mode disabled")] fn test_n0_with_follow() { let (at, mut ucmd) = at_and_ucmd!(); let test_file = "test.txt"; @@ -530,8 +530,8 @@ fn test_null_default() { .stdout_is_fixture("foobar_with_null_default.expected"); } +#[uutests::wasi_ignore(TailFollowDisabled)] #[test] -#[cfg_attr(wasi_runner, ignore = "WASI: tail follow mode disabled")] fn test_follow_single() { let (at, mut ucmd) = at_and_ucmd!(); @@ -571,9 +571,9 @@ fn test_follow_file_unsupported() { } /// Test for following when bytes are written that are not valid UTF-8. +#[uutests::wasi_ignore(TailFollowDisabled)] #[test] #[cfg(not(windows))] // FIXME: test times out -#[cfg_attr(wasi_runner, ignore = "WASI: tail follow mode disabled")] fn test_follow_non_utf8_bytes() { // Tail the test file and start following it. let (at, mut ucmd) = at_and_ucmd!(); @@ -630,8 +630,8 @@ fn test_permission_denied_is_not_reported_as_not_found() { fs::set_permissions(&dir, fs::Permissions::from_mode(0o700)).unwrap(); } +#[uutests::wasi_ignore(TailFollowDisabled)] #[test] -#[cfg_attr(wasi_runner, ignore = "WASI: tail follow mode disabled")] fn test_follow_multiple() { let (at, mut ucmd) = at_and_ucmd!(); let mut child = ucmd @@ -666,8 +666,8 @@ fn test_follow_multiple() { child.kill(); } +#[uutests::wasi_ignore(TailFollowDisabled)] #[test] -#[cfg_attr(wasi_runner, ignore = "WASI: tail follow mode disabled")] fn test_follow_name_multiple() { // spell-checker:disable-next-line for argument in ["--follow=name", "--follo=nam", "--f=n"] { @@ -712,8 +712,8 @@ fn test_follow_name_multiple() { } } +#[uutests::wasi_ignore(TailFollowDisabled)] #[test] -#[cfg_attr(wasi_runner, ignore = "WASI: tail follow mode disabled")] fn test_follow_multiple_untailable() { // $ tail -f DIR1 DIR2 // ==> DIR1 <== @@ -791,6 +791,7 @@ fn test_follow_invalid_pid() { // FixME: test PASSES for usual windows builds, but fails for coverage testing builds (likely related to the specific RUSTFLAGS '-Zpanic_abort_tests -Cpanic=abort') // spell-checker:disable-line // FIXME: FreeBSD: See issue https://github.com/uutils/coreutils/issues/4306 // Fails intermittently in the CI, but couldn't reproduce the failure locally. +#[uutests::wasi_ignore(TailFollowDisabled)] #[test] #[cfg(all( not(target_vendor = "apple"), @@ -798,7 +799,6 @@ fn test_follow_invalid_pid() { not(target_os = "freebsd"), not(windows) ))] // FIXME: for currently not working platforms -#[cfg_attr(wasi_runner, ignore = "WASI: tail follow mode disabled")] fn test_follow_with_pid() { use std::process::Command; @@ -1021,8 +1021,8 @@ fn test_multiple_input_files_missing() { ); } +#[uutests::wasi_ignore(TailFollowDisabled)] #[test] -#[cfg_attr(wasi_runner, ignore = "WASI: tail follow mode disabled")] fn test_follow_missing() { // Ensure that --follow=name does not imply --retry. // Ensure that --follow={descriptor,name} (without --retry) does *not wait* for the @@ -1090,8 +1090,8 @@ fn test_dir() { .stderr_is("tail: error reading 'DIR': Is a directory\n"); } +#[uutests::wasi_ignore(TailFollowDisabled)] #[test] -#[cfg_attr(wasi_runner, ignore = "WASI: tail follow mode disabled")] fn test_dir_follow() { let ts = TestScenario::new(util_name!()); let at = &ts.fixtures; @@ -1110,8 +1110,8 @@ fn test_dir_follow() { } } +#[uutests::wasi_ignore(TailFollowDisabled)] #[test] -#[cfg_attr(wasi_runner, ignore = "WASI: tail follow mode disabled")] fn test_dir_follow_retry() { let ts = TestScenario::new(util_name!()); let at = &ts.fixtures; @@ -1453,9 +1453,9 @@ fn test_num_with_undocumented_sign_bytes() { .stdout_is("efghijklmnopqrstuvwxyz"); } +#[uutests::wasi_ignore(HostPathsNotVisible)] #[test] #[cfg(unix)] -#[cfg_attr(wasi_runner, ignore = "WASI sandbox: host paths not visible")] fn test_bytes_for_funny_unix_files() { // Test tail with byte count let ts = TestScenario::new(util_name!()); @@ -1509,6 +1509,7 @@ fn test_retry_missing_file_error() { ); } +#[uutests::wasi_ignore(TailFollowDisabled)] #[test] #[cfg(all( not(target_vendor = "apple"), @@ -1517,7 +1518,6 @@ fn test_retry_missing_file_error() { not(target_os = "openbsd"), not(windows) ))] // FIXME: for currently not working platforms -#[cfg_attr(wasi_runner, ignore = "WASI: tail follow mode disabled")] fn test_retry_follow_name_waits_for_creation() { // Test tail --retry behavior // Ensure that `tail --retry --follow=name` waits for the file to appear. @@ -1555,6 +1555,7 @@ fn test_retry_follow_name_waits_for_creation() { } } +#[uutests::wasi_ignore(TailFollowDisabled)] #[test] #[cfg(all( not(target_vendor = "apple"), @@ -1563,7 +1564,6 @@ fn test_retry_follow_name_waits_for_creation() { not(target_os = "openbsd"), not(windows) ))] // FIXME: for currently not working platforms -#[cfg_attr(wasi_runner, ignore = "WASI: tail follow mode disabled")] fn test_retry_descriptor_detects_truncation() { // Test tail --retry behavior // Ensure that `tail --retry --follow=descriptor` waits for the file to appear. @@ -1615,6 +1615,7 @@ fn test_retry_descriptor_detects_truncation() { } } +#[uutests::wasi_ignore(TailFollowDisabled)] #[test] #[cfg(all( not(target_vendor = "apple"), @@ -1623,7 +1624,6 @@ fn test_retry_descriptor_detects_truncation() { not(target_os = "openbsd"), not(windows) ))] // FIXME: for currently not working platforms -#[cfg_attr(wasi_runner, ignore = "WASI: tail follow mode disabled")] fn test_retry_descriptor_gives_up_on_untailable() { // Test tail --retry behavior // Ensure that `tail --follow=descriptor --retry` exits when the file appears untailable. @@ -1663,9 +1663,9 @@ fn test_retry_descriptor_gives_up_on_untailable() { // Diff < left / right > : // ==> existing <== // >X +#[uutests::wasi_ignore(TailFollowDisabled)] #[test] #[cfg(all(not(windows), not(target_os = "android")))] // FIXME: for currently not working platforms -#[cfg_attr(wasi_runner, ignore = "WASI: tail follow mode disabled")] fn test_descriptor_no_retry_skips_late_file() { // Test tail --retry behavior // Ensure that --follow=descriptor (without --retry) does *not* try @@ -1707,6 +1707,7 @@ fn test_descriptor_no_retry_skips_late_file() { .stderr_is(expected_stderr); } +#[uutests::wasi_ignore(TailFollowDisabled)] #[test] #[cfg(all( not(target_vendor = "apple"), @@ -1715,7 +1716,6 @@ fn test_descriptor_no_retry_skips_late_file() { not(target_os = "openbsd"), not(windows) ))] // FIXME: for currently not working platforms -#[cfg_attr(wasi_runner, ignore = "WASI: tail follow mode disabled")] fn test_capital_f_recovers_after_dir_swap() { // Test tail --retry behavior // Ensure that `tail -F` retries when the file is initially untailable. @@ -1786,10 +1786,10 @@ fn test_capital_f_recovers_after_dir_swap() { /// Under `--follow=name`, a watched file replaced by a symlink must be reported /// as untailable, not silently followed to the link target (which would /// exfiltrate its contents). +#[uutests::wasi_ignore(TailFollowDisabled)] #[test] #[cfg(unix)] #[cfg(not(target_os = "android"))] -#[cfg_attr(wasi_runner, ignore = "WASI: tail follow mode disabled")] fn test_follow_name_replaced_by_symlink_is_untailable() { let ts = TestScenario::new(util_name!()); let at = &ts.fixtures; @@ -1840,6 +1840,7 @@ fn test_follow_name_replaced_by_symlink_is_untailable() { .stderr_contains("has been replaced with an untailable symbolic link"); } +#[uutests::wasi_ignore(TailFollowDisabled)] #[test] #[cfg(all( not(target_vendor = "apple"), @@ -1848,7 +1849,6 @@ fn test_follow_name_replaced_by_symlink_is_untailable() { not(target_os = "openbsd"), not(windows) ))] // FIXME: for currently not working platforms -#[cfg_attr(wasi_runner, ignore = "WASI: tail follow mode disabled")] fn test_retry8() { // Ensure that inotify will switch to polling mode if directory // of the watched file was initially missing and later created. @@ -1910,6 +1910,7 @@ fn test_retry8() { .stdout_is(expected_stdout); } +#[uutests::wasi_ignore(TailFollowDisabled)] #[test] #[cfg(all( not(target_vendor = "apple"), @@ -1918,7 +1919,6 @@ fn test_retry8() { not(target_os = "openbsd"), not(windows) ))] // FIXME: for currently not working platforms -#[cfg_attr(wasi_runner, ignore = "WASI: tail follow mode disabled")] fn test_retry9() { // Test inotify behavior when directory is recreated // Ensure that inotify will switch to polling mode if directory @@ -1993,6 +1993,7 @@ fn test_retry9() { .stdout_is(expected_stdout); } +#[uutests::wasi_ignore(TailFollowDisabled)] #[test] #[cfg(all( not(target_vendor = "apple"), @@ -2001,7 +2002,6 @@ fn test_retry9() { not(target_os = "openbsd"), not(windows) ))] // FIXME: for currently not working platforms -#[cfg_attr(wasi_runner, ignore = "WASI: tail follow mode disabled")] fn test_follow_descriptor_vs_rename1() { // Test file descriptor behavior vs rename // $ ((rm -f A && touch A && sleep 1 && echo -n "A\n" >> A && sleep 1 && \ @@ -2058,6 +2058,7 @@ fn test_follow_descriptor_vs_rename1() { } } +#[uutests::wasi_ignore(TailFollowDisabled)] #[test] #[cfg(all( not(target_vendor = "apple"), @@ -2066,7 +2067,6 @@ fn test_follow_descriptor_vs_rename1() { not(target_os = "openbsd"), not(windows) ))] // FIXME: for currently not working platforms -#[cfg_attr(wasi_runner, ignore = "WASI: tail follow mode disabled")] fn test_follow_descriptor_vs_rename2() { // Ensure the headers are correct for --verbose. // NOTE: GNU's tail does not update the header from FILE_A to FILE_C after `mv FILE_A FILE_C` @@ -2112,6 +2112,7 @@ fn test_follow_descriptor_vs_rename2() { } } +#[uutests::wasi_ignore(TailFollowDisabled)] #[test] #[cfg(all( not(target_vendor = "apple"), @@ -2120,7 +2121,6 @@ fn test_follow_descriptor_vs_rename2() { not(target_os = "openbsd"), not(windows) ))] // FIXME: for currently not working platforms -#[cfg_attr(wasi_runner, ignore = "WASI: tail follow mode disabled")] fn test_follow_name_shows_headers_on_creation() { // Test -F flag with file headers // Ensure tail -F distinguishes output with the @@ -2185,9 +2185,9 @@ fn test_follow_name_shows_headers_on_creation() { } } +#[uutests::wasi_ignore(TailFollowDisabled)] #[test] #[cfg(all(not(windows), not(target_os = "android")))] // FIXME: for currently not working platforms -#[cfg_attr(wasi_runner, ignore = "WASI: tail follow mode disabled")] fn test_follow_name_remove() { // This test triggers a remove event while `tail --follow=name file` is running. // ((sleep 2 && rm file &)>/dev/null 2>&1 &) ; tail --follow=name file @@ -2246,9 +2246,9 @@ fn test_follow_name_remove() { } } +#[uutests::wasi_ignore(TailFollowDisabled)] #[test] #[cfg(all(not(target_os = "android"), not(target_os = "freebsd")))] // FIXME: for currently not working platforms -#[cfg_attr(wasi_runner, ignore = "WASI: tail follow mode disabled")] fn test_follow_name_truncate1() { // This test triggers a truncate event while `tail --follow=name file` is running. // $ cp file backup && head file > file && sleep 1 && cp backup file @@ -2299,9 +2299,9 @@ fn test_follow_name_truncate1() { .stdout_is(expected_stdout); } +#[uutests::wasi_ignore(TailFollowDisabled)] #[test] #[cfg(all(not(target_os = "android"), not(target_os = "freebsd")))] // FIXME: for currently not working platforms -#[cfg_attr(wasi_runner, ignore = "WASI: tail follow mode disabled")] fn test_follow_name_truncate2() { fn wait_for_output( child: &mut uutests::util::UChild, @@ -2360,8 +2360,8 @@ fn test_follow_name_truncate2() { .stdout_is(expected_stdout); } +#[uutests::wasi_ignore(TailFollowDisabled)] #[test] -#[cfg_attr(wasi_runner, ignore = "WASI: tail follow mode disabled")] fn test_follow_name_truncate3() { // Opening an empty file in truncate mode should not trigger a truncate event while // `tail --follow=name file` is running. @@ -2392,13 +2392,13 @@ fn test_follow_name_truncate3() { .stdout_only(expected_stdout); } +#[uutests::wasi_ignore(TailFollowDisabled)] #[test] #[cfg(all( not(target_vendor = "apple"), not(windows), not(feature = "selinux") // flaky ))] // FIXME: for currently not working platforms -#[cfg_attr(wasi_runner, ignore = "WASI: tail follow mode disabled")] fn test_follow_name_truncate4() { // Truncating a file with the same content it already has should not trigger a truncate event @@ -2432,9 +2432,9 @@ fn test_follow_name_truncate4() { } } +#[uutests::wasi_ignore(TailFollowDisabled)] #[test] #[cfg(not(windows))] // FIXME: for currently not working platforms -#[cfg_attr(wasi_runner, ignore = "WASI: tail follow mode disabled")] fn test_follow_detects_file_truncation() { // Test tail behavior on file truncation // Ensure all logs are output upon file truncation @@ -2486,6 +2486,7 @@ fn test_follow_detects_file_truncation() { } } +#[uutests::wasi_ignore(TailFollowDisabled)] #[test] #[cfg(all( not(target_vendor = "apple"), @@ -2494,7 +2495,6 @@ fn test_follow_detects_file_truncation() { not(target_os = "openbsd"), not(windows) ))] // FIXME: for currently not working platforms -#[cfg_attr(wasi_runner, ignore = "WASI: tail follow mode disabled")] fn test_follow_name_move_create1() { // This test triggers a move/create event while `tail --follow=name file` is running. // ((sleep 2 && mv file backup && sleep 2 && cp backup file &)>/dev/null 2>&1 &) ; tail --follow=name file @@ -2543,6 +2543,7 @@ fn test_follow_name_move_create1() { .stdout_is(expected_stdout); } +#[uutests::wasi_ignore(TailFollowDisabled)] #[test] #[cfg(all( not(target_vendor = "apple"), @@ -2551,7 +2552,6 @@ fn test_follow_name_move_create1() { not(target_os = "openbsd"), not(windows) ))] // FIXME: for currently not working platforms -#[cfg_attr(wasi_runner, ignore = "WASI: tail follow mode disabled")] fn test_follow_name_hash_table_stress() { // Test inotify hash table under heavy file churn by watching 9 files simultaneously. // Exercises an abort-inducing flaw in inotify-enabled tail -F @@ -2624,6 +2624,7 @@ fn test_follow_name_hash_table_stress() { } } +#[uutests::wasi_ignore(TailFollowDisabled)] #[test] #[cfg(all( not(target_vendor = "apple"), @@ -2632,7 +2633,6 @@ fn test_follow_name_hash_table_stress() { not(target_os = "openbsd"), not(windows) ))] // FIXME: for currently not working platforms -#[cfg_attr(wasi_runner, ignore = "WASI: tail follow mode disabled")] fn test_follow_name_move1() { // This test triggers a move event while `tail --follow=name file` is running. // ((sleep 2 && mv file backup &)>/dev/null 2>&1 &) ; tail --follow=name file @@ -2687,6 +2687,7 @@ fn test_follow_name_move1() { } } +#[uutests::wasi_ignore(TailFollowDisabled)] #[test] #[cfg(all( not(target_vendor = "apple"), @@ -2695,7 +2696,6 @@ fn test_follow_name_move1() { not(target_os = "openbsd"), not(windows) ))] // FIXME: for currently not working platforms -#[cfg_attr(wasi_runner, ignore = "WASI: tail follow mode disabled")] fn test_follow_name_move2() { // Like test_follow_name_move1, but move to a name that's already monitored. @@ -2776,6 +2776,7 @@ fn test_follow_name_move2() { } } +#[uutests::wasi_ignore(TailFollowDisabled)] #[test] #[cfg(all( not(target_vendor = "apple"), @@ -2784,7 +2785,6 @@ fn test_follow_name_move2() { not(target_os = "openbsd"), not(windows) ))] // FIXME: for currently not working platforms -#[cfg_attr(wasi_runner, ignore = "WASI: tail follow mode disabled")] fn test_follow_name_move_retry1() { // Similar to test_follow_name_move1 but with `--retry` (`-F`) // This test triggers two move/rename events while `tail --follow=name --retry file` is running. @@ -2837,6 +2837,7 @@ fn test_follow_name_move_retry1() { } } +#[uutests::wasi_ignore(TailFollowDisabled)] #[test] #[cfg(all( not(target_vendor = "apple"), @@ -2845,7 +2846,6 @@ fn test_follow_name_move_retry1() { not(target_os = "openbsd"), not(windows) ))] // FIXME: for currently not working platforms -#[cfg_attr(wasi_runner, ignore = "WASI: tail follow mode disabled")] fn test_follow_name_rename_chain() { // Test -F flag behavior across file renames // Similar to test_follow_name_move2 (move to a name that's already monitored) @@ -2944,9 +2944,9 @@ fn test_follow_name_rename_chain() { } } +#[uutests::wasi_ignore(TailFollowDisabled)] #[test] #[cfg(not(windows))] // FIXME: for currently not working platforms -#[cfg_attr(wasi_runner, ignore = "WASI: tail follow mode disabled")] fn test_follow_inotify_only_regular() { // The GNU test inotify-only-regular.sh uses strace to ensure that `tail -f` // doesn't make inotify syscalls and only uses inotify for regular files or fifos. @@ -3018,6 +3018,7 @@ fn test_fifo() { /// Test that tail with --pid exits when the monitored process dies, even with a FIFO. /// Without non-blocking FIFO open, tail would block forever waiting for a writer. +#[uutests::wasi_ignore(NoFifo)] #[test] #[cfg(all( not(target_os = "android"), @@ -3025,7 +3026,6 @@ fn test_fifo() { not(target_os = "openbsd"), not(windows) ))] -#[cfg_attr(wasi_runner, ignore = "WASI: no FIFO/mkfifo support")] fn test_fifo_with_pid() { use std::process::{Command, Stdio}; @@ -4344,9 +4344,9 @@ fn test_args_when_settings_check_warnings_follow_retry() { } /// TODO: Write similar tests for windows +#[uutests::wasi_ignore(TailFollowDisabled)] #[test] #[cfg(target_os = "linux")] -#[cfg_attr(wasi_runner, ignore = "WASI: tail follow mode disabled")] fn test_args_when_settings_check_warnings_follow_indefinitely_then_warning() { let scene = TestScenario::new(util_name!()); @@ -4469,9 +4469,9 @@ fn test_args_when_settings_check_warnings_follow_indefinitely_then_warning() { .stdout_only(expected_stdout); } +#[uutests::wasi_ignore(TailFollowDisabled)] #[test] #[cfg(unix)] -#[cfg_attr(wasi_runner, ignore = "WASI: tail follow mode disabled")] fn test_args_when_settings_check_warnings_follow_indefinitely_then_no_warning() { let scene = TestScenario::new(util_name!()); let at = &scene.fixtures; @@ -4785,8 +4785,8 @@ fn test_follow_when_file_and_symlink_are_pointing_to_same_file_and_append_data() .stdout_only(expected_stdout); } +#[uutests::wasi_ignore(TailFollowDisabled)] #[test] -#[cfg_attr(wasi_runner, ignore = "WASI: tail follow mode disabled")] fn test_args_when_directory_given_shorthand_big_f_together_with_retry() { let scene = TestScenario::new(util_name!()); let at = &scene.fixtures; @@ -4839,6 +4839,7 @@ fn test_args_when_directory_given_shorthand_big_f_together_with_retry() { // ==> /tmp/.tmpZPXPlS/data <== // >file data // < +#[uutests::wasi_ignore(TailFollowDisabled)] #[test] #[cfg(all( not(target_vendor = "apple"), @@ -4847,7 +4848,6 @@ fn test_args_when_directory_given_shorthand_big_f_together_with_retry() { not(target_os = "openbsd"), not(feature = "selinux") // flaky ))] -#[cfg_attr(wasi_runner, ignore = "WASI: tail follow mode disabled")] fn test_follow_when_files_are_pointing_to_same_relative_file_and_file_stays_same_size() { let scene = TestScenario::new(util_name!()); let at = &scene.fixtures; @@ -5120,8 +5120,8 @@ fn test_tail_obsolete_error_cases() { .stdout_is("x"); } +#[uutests::wasi_ignore(TailFollowDisabled)] #[test] -#[cfg_attr(wasi_runner, ignore = "WASI: tail follow mode disabled")] fn test_tail_obsolete_f_flag() { let scene = TestScenario::new(util_name!()); let at = &scene.fixtures; @@ -5141,9 +5141,9 @@ fn test_tail_obsolete_f_flag() { p.kill().make_assertion().with_all_output().no_output(); } +#[uutests::wasi_ignore(NonUtf8ArgsUnsupported)] #[test] #[cfg(unix)] -#[cfg_attr(wasi_runner, ignore = "WASI: argv/filenames must be valid UTF-8")] fn test_obsolete_encoding_unix() { use std::ffi::OsStr; use std::os::unix::ffi::OsStrExt; @@ -5176,8 +5176,8 @@ fn test_obsolete_encoding_windows() { .stderr_is("tail: bad argument encoding: \"-`u{D800}b\"\n"); } +#[uutests::wasi_ignore(TailFollowDisabled)] #[test] -#[cfg_attr(wasi_runner, ignore = "WASI: tail follow mode disabled")] fn test_following_with_pid() { use std::process::Command; @@ -5252,12 +5252,9 @@ fn test_when_piped_input_then_no_broken_pipe() { } } +#[uutests::wasi_ignore(ClosedStdoutGenericIoError)] #[test] #[cfg(unix)] -#[cfg_attr( - wasi_runner, - ignore = "WASI: closed stdout reports a generic I/O error rather than BrokenPipe" -)] fn test_when_output_closed_then_no_broken_pipe() { let (at, mut cmd) = at_and_ucmd!(); at.make_file("input").set_len(10_000_000).unwrap(); @@ -5323,9 +5320,9 @@ fn test_failed_write_is_reported_on_seekable_input() { .stderr_is("tail: No space left on device\n"); } +#[uutests::wasi_ignore(HostPathsNotVisible)] #[test] #[cfg(unix)] -#[cfg_attr(wasi_runner, ignore = "WASI sandbox: host paths not visible")] fn test_dev_zero() { new_ucmd!() .args(&["-c", "1", "/dev/zero"]) @@ -5368,9 +5365,9 @@ fn test_follow_pipe_f() { .stdout_only("oo\n"); } +#[uutests::wasi_ignore(TailFollowDisabled)] #[test] #[cfg(target_os = "linux")] -#[cfg_attr(wasi_runner, ignore = "WASI: tail follow mode disabled")] fn test_follow_stdout_pipe_close() { let (at, mut ucmd) = at_and_ucmd!(); at.write("f", "line1\nline2\n"); @@ -5385,8 +5382,8 @@ fn test_follow_stdout_pipe_close() { child.delay(2000).make_assertion().is_not_alive(); } +#[uutests::wasi_ignore(TailFollowDisabled)] #[test] -#[cfg_attr(wasi_runner, ignore = "WASI: tail follow mode disabled")] fn test_debug_flag_with_polling() { let ts = TestScenario::new(util_name!()); let at = &ts.fixtures; @@ -5405,9 +5402,9 @@ fn test_debug_flag_with_polling() { .stderr_contains("tail: using polling mode"); } +#[uutests::wasi_ignore(TailFollowDisabled)] #[test] #[cfg(target_os = "linux")] -#[cfg_attr(wasi_runner, ignore = "WASI: tail follow mode disabled")] fn test_debug_flag_with_inotify() { let ts = TestScenario::new(util_name!()); let at = &ts.fixtures; @@ -5423,9 +5420,9 @@ fn test_debug_flag_with_inotify() { .stderr_contains("tail: using notification mode"); } +#[uutests::wasi_ignore(TailFollowDisabled)] #[test] #[cfg(target_os = "linux")] -#[cfg_attr(wasi_runner, ignore = "WASI: tail follow mode disabled")] fn test_follow_dangling_symlink() { let (at, mut ucmd) = at_and_ucmd!(); at.symlink_file("target", "link"); @@ -5438,9 +5435,9 @@ fn test_follow_dangling_symlink() { p.kill().make_assertion().with_all_output().stdout_is("X\n"); } +#[uutests::wasi_ignore(TailFollowDisabled)] #[test] #[cfg(target_os = "linux")] -#[cfg_attr(wasi_runner, ignore = "WASI: tail follow mode disabled")] fn test_follow_symlink_target_change() { let (at, mut ucmd) = at_and_ucmd!(); at.write("t1", "A\n"); diff --git a/tests/by-util/test_tee.rs b/tests/by-util/test_tee.rs index 00e30eada05..1384a735647 100644 --- a/tests/by-util/test_tee.rs +++ b/tests/by-util/test_tee.rs @@ -125,8 +125,8 @@ fn test_tee_multiple_append_flags() { assert_eq!(at.read(file2), format!("existing2\n{content}")); } +#[uutests::wasi_ignore(HostPathsNotVisible)] #[test] -#[cfg_attr(wasi_runner, ignore = "WASI sandbox: host paths not visible")] fn test_readonly() { let (at, mut ucmd) = at_and_ucmd!(); let content_tee = "hello"; @@ -147,8 +147,8 @@ fn test_readonly() { assert_eq!(at.read(writable_file), content_tee); } +#[uutests::wasi_ignore(NoPipeSignalSupport)] #[test] -#[cfg_attr(wasi_runner, ignore = "WASI: no pipe/signal support")] fn test_tee_output_not_buffered() { // POSIX says: The tee utility shall not buffer output @@ -252,7 +252,8 @@ fn test_tee_continues_after_short_read() { handle.join().unwrap(); } -#[cfg(all(target_os = "linux", not(wasi_runner)))] +#[uutests::wasi_ignore(NoPipeSignalSupport)] +#[cfg(target_os = "linux")] mod linux_only { use uutests::util::{AtPath, CmdResult, UCommand}; diff --git a/tests/by-util/test_test.rs b/tests/by-util/test_test.rs index d12eaadd40c..ff66dccdee6 100644 --- a/tests/by-util/test_test.rs +++ b/tests/by-util/test_test.rs @@ -448,9 +448,9 @@ fn test_float_inequality_is_error() { .stderr_is("test: invalid integer '123.45'\n"); } +#[uutests::wasi_ignore(NonUtf8ArgsUnsupported)] #[test] #[cfg(not(windows))] -#[cfg_attr(wasi_runner, ignore = "WASI: argv/filenames must be valid UTF-8")] fn test_invalid_utf8_integer_compare() { use std::ffi::OsStr; use std::os::unix::ffi::OsStrExt; @@ -510,8 +510,8 @@ fn test_file_is_itself() { .succeeds(); } +#[uutests::wasi_ignore(HostPathsNotVisible)] #[test] -#[cfg_attr(wasi_runner, ignore = "WASI sandbox: host paths not visible")] // Disabled for android, since the temp dir doesn't allow creating hard links #[cfg(not(target_os = "android"))] fn test_hard_link_is_same_file() { @@ -555,8 +555,8 @@ fn test_file_is_newer_than_non_existing_file() { .no_output(); } +#[uutests::wasi_ignore(HostPathsNotVisible)] #[test] -#[cfg_attr(wasi_runner, ignore = "WASI sandbox: host paths not visible")] fn test_same_device_inode() { let scenario = TestScenario::new(util_name!()); let at = &scenario.fixtures; @@ -634,9 +634,9 @@ fn test_file_is_readable() { new_ucmd!().args(&["-r", "regular_file"]).succeeds(); } +#[uutests::wasi_ignore(NoPermissionBits)] #[test] #[cfg(not(windows))] -#[cfg_attr(wasi_runner, ignore = "WASI: no permission bits")] fn test_file_is_not_readable() { let scenario = TestScenario::new(util_name!()); let mut ucmd = scenario.ucmd(); @@ -648,8 +648,8 @@ fn test_file_is_not_readable() { ucmd.args(&["!", "-r", "crypto_file"]).succeeds(); } +#[uutests::wasi_ignore(NoPermissionBits)] #[test] -#[cfg_attr(wasi_runner, ignore = "WASI: no permission bits")] fn test_file_is_writable() { new_ucmd!().args(&["-w", "regular_file"]).succeeds(); } @@ -689,9 +689,9 @@ fn test_file_is_not_executable() { ucmd.args(&["!", "-x", "regular_file"]).succeeds(); } +#[uutests::wasi_ignore(NoPermissionBits)] #[test] #[cfg(not(windows))] -#[cfg_attr(wasi_runner, ignore = "WASI: no permission bits")] fn test_file_is_executable() { let scenario = TestScenario::new(util_name!()); let mut chmod = scenario.cmd("chmod"); @@ -752,8 +752,8 @@ fn test_file_is_executable_from_pathext_windows() { .succeeds(); } +#[uutests::wasi_ignore(NoPermissionBits)] #[test] -#[cfg_attr(wasi_runner, ignore = "WASI: no permission bits")] fn test_directory_is_executable() { let (at, mut ucmd) = at_and_ucmd!(); at.mkdir("dir"); @@ -877,11 +877,11 @@ fn test_nonexistent_file_is_not_symlink() { .succeeds(); } +#[uutests::wasi_ignore(NoPermissionBits)] #[test] // Only the superuser is allowed to set the sticky bit on files on FreeBSD/OpenBSD. // Windows has no concept of sticky bit #[cfg(not(any(windows, target_os = "freebsd", target_os = "openbsd")))] -#[cfg_attr(wasi_runner, ignore = "WASI: no permission bits")] fn test_file_is_sticky() { let scenario = TestScenario::new(util_name!()); let mut ucmd = scenario.ucmd(); @@ -976,8 +976,8 @@ fn test_parenthesized_right_parenthesis_as_literal() { new_ucmd!().args(&["(", "-f", ")", ")"]).fails_with_code(1); } +#[uutests::wasi_ignore(NoUidGid)] #[test] -#[cfg_attr(wasi_runner, ignore = "WASI: no uid/gid")] fn test_file_owned_by_euid() { new_ucmd!().args(&["-O", "regular_file"]).succeeds(); } @@ -989,18 +989,18 @@ fn test_nonexistent_file_not_owned_by_euid() { .fails_with_code(1); } +#[uutests::wasi_ignore(NoUidGid)] #[test] #[cfg(not(windows))] -#[cfg_attr(wasi_runner, ignore = "WASI: no uid/gid")] fn test_file_not_owned_by_euid() { new_ucmd!() .args(&["-f", "/bin/sh", "-a", "!", "-O", "/bin/sh"]) .succeeds(); } +#[uutests::wasi_ignore(NoUidGid)] #[test] #[cfg(not(windows))] -#[cfg_attr(wasi_runner, ignore = "WASI: no uid/gid")] fn test_file_owned_by_egid() { // On some platforms (mostly the BSDs) the test fixture files copied to the // /tmp directory will have a different gid than the current egid (due to @@ -1030,9 +1030,9 @@ fn test_nonexistent_file_not_owned_by_egid() { .fails_with_code(1); } +#[uutests::wasi_ignore(NoUidGid)] #[test] #[cfg(not(windows))] -#[cfg_attr(wasi_runner, ignore = "WASI: no uid/gid")] fn test_file_not_owned_by_egid() { let target_file = if cfg!(target_os = "freebsd") { // The coreutils test runner user has a primary group id of "wheel", diff --git a/tests/by-util/test_touch.rs b/tests/by-util/test_touch.rs index bac66196b31..259ad6ca2b2 100644 --- a/tests/by-util/test_touch.rs +++ b/tests/by-util/test_touch.rs @@ -166,11 +166,8 @@ fn test_touch_2_digit_years_2038() { assert_eq!(mtime, expected); } +#[uutests::wasi_ignore(PreEpochTimestampsUnrepresentable)] #[test] -#[cfg_attr( - wasi_runner, - ignore = "WASI: pre-epoch timestamps not representable by path_filestat_set_times" -)] fn test_touch_2_digit_years_69() { // 69 and after are 19xx let (at, mut ucmd) = at_and_ucmd!(); @@ -648,11 +645,8 @@ fn test_touch_set_date7() { assert_eq!(mtime, expected); } +#[uutests::wasi_ignore(NoTzdb)] #[test] -#[cfg_attr( - wasi_runner, - ignore = "WASI: no tzdb; TZ env var is not honoured so timezone-dependent timestamps differ" -)] fn test_touch_set_date_without_leading_zeroes() { let (at, mut ucmd) = at_and_ucmd!(); let file = "test_touch_set_date_without_leading_zeroes"; @@ -674,12 +668,9 @@ fn test_touch_set_date_without_leading_zeroes() { /// because the i64 Unix timestamp (~-62 billion) overflowed the i32 `tv_sec` /// expected by the old nix-based implementation. After switching to rustix /// (which uses i64 `tv_sec` natively), this should succeed on all targets. +#[uutests::wasi_ignore(PreEpochTimestampsUnrepresentable)] #[test] #[cfg(unix)] -#[cfg_attr( - wasi_runner, - ignore = "WASI: pre-epoch timestamps not representable by path_filestat_set_times" -)] fn test_touch_set_date_year_zero() { let (at, mut ucmd) = at_and_ucmd!(); let file = "test_touch_year_zero"; @@ -812,12 +803,9 @@ fn test_touch_mtime_dst_succeeds() { assert_eq!(target_time, mtime); } +#[uutests::wasi_ignore(NoTzdb)] #[test] #[cfg(unix)] -#[cfg_attr( - wasi_runner, - ignore = "WASI: no tzdb; TZ env var is not honoured so DST validation is skipped" -)] fn test_touch_mtime_dst_fails() { let file = "test_touch_set_mtime_dst_fails"; @@ -833,12 +821,9 @@ fn test_touch_mtime_dst_fails() { .fails(); } +#[uutests::wasi_ignore(GuestRootWritablePreopen)] #[test] #[cfg(unix)] -#[cfg_attr( - wasi_runner, - ignore = "WASI: guest root is a writable preopen, not the protected system root" -)] fn test_touch_system_fails() { let file = "/"; new_ucmd!() @@ -847,12 +832,9 @@ fn test_touch_system_fails() { .stderr_contains("setting times of '/'"); } +#[uutests::wasi_ignore(GuestRootWritablePreopen)] #[test] #[cfg(target_os = "linux")] -#[cfg_attr( - wasi_runner, - ignore = "WASI: guest root is a writable preopen, not the protected system root" -)] fn test_touch_explicit_time_on_root_owned_file_eperm() { // Setting explicit timestamps on a file we do not own fails with EPERM // (not EACCES), which GNU reports as "Operation not permitted" (#15020). @@ -866,9 +848,9 @@ fn test_touch_explicit_time_on_root_owned_file_eperm() { .stderr_only("touch: setting times of '/': Operation not permitted\n"); } +#[uutests::wasi_ignore(HostPathsNotVisible)] #[test] #[cfg(target_os = "linux")] -#[cfg_attr(wasi_runner, ignore = "WASI sandbox: host paths not visible")] fn test_touch_date_now_on_writable_file_owned_by_other() { // /dev/null is root-owned but writable, so `-d now` needs only write permission (#15019). if rustix::process::geteuid().is_root() { @@ -880,9 +862,9 @@ fn test_touch_date_now_on_writable_file_owned_by_other() { .no_output(); } +#[uutests::wasi_ignore(NoFifo)] #[test] #[cfg(unix)] -#[cfg_attr(wasi_runner, ignore = "WASI: no FIFO support")] fn test_touch_fifo() { // touch must not hang on a reader-less FIFO and must update its times. let (at, mut ucmd) = at_and_ucmd!(); @@ -893,9 +875,9 @@ fn test_touch_fifo() { assert!(at.is_fifo("fifo")); } +#[uutests::wasi_ignore(NoStdoutFileRedirection)] #[test] #[cfg(unix)] -#[cfg_attr(wasi_runner, ignore = "WASI: no stdout-to-file redirection")] fn test_touch_dash_updates_stdout_file() { // `touch -` must update the times of the file open as stdout (fd 1), even // when it is read-only, and set them to "now" rather than a 1970 sentinel. @@ -947,9 +929,9 @@ fn test_touch_no_such_file_error_msg() { )); } +#[uutests::wasi_ignore(StdoutDashUnsupported)] #[test] #[cfg(not(any(target_os = "freebsd", target_os = "openbsd")))] -#[cfg_attr(wasi_runner, ignore = "WASI: touch - (stdout) is unsupported")] fn test_touch_changes_time_of_file_in_stdout() { // command like: `touch - 1< ./c` // should change the timestamp of c @@ -970,12 +952,9 @@ fn test_touch_changes_time_of_file_in_stdout() { assert_ne!(mtime_after, mtime); } +#[uutests::wasi_ignore(PermissionErrorsSurfaceAsEnoent)] #[test] #[cfg(unix)] -#[cfg_attr( - wasi_runner, - ignore = "WASI: filesystem permission errors surface as ENOENT rather than EACCES" -)] fn test_touch_permission_denied_error_msg() { let (at, mut ucmd) = at_and_ucmd!(); @@ -994,9 +973,9 @@ fn test_touch_permission_denied_error_msg() { )); } +#[uutests::wasi_ignore(HostPathsNotVisible)] #[test] #[cfg(unix)] -#[cfg_attr(wasi_runner, ignore = "WASI: host system file is not visible")] fn test_touch_existing_unwritable_file_error_msg() { use std::fs::OpenOptions; use std::path::Path; @@ -1028,9 +1007,9 @@ fn test_touch_existing_unwritable_file_error_msg() { )); } +#[uutests::wasi_ignore(NoPermissionBits)] #[test] #[cfg(unix)] -#[cfg_attr(wasi_runner, ignore = "WASI: filesystem permissions differ")] fn test_touch_inaccessible_parent_error_msg() { use std::fs::{Permissions, set_permissions}; use std::os::unix::fs::PermissionsExt; @@ -1170,9 +1149,9 @@ fn test_touch_no_dereference_dangling() { ucmd.args(&["-h", "dangling"]).succeeds(); } +#[uutests::wasi_ignore(StdoutDashUnsupported)] #[test] #[cfg(not(target_os = "openbsd"))] -#[cfg_attr(wasi_runner, ignore = "WASI: touch - (stdout) is unsupported")] fn test_touch_dash() { new_ucmd!().args(&["-h", "-"]).succeeds().no_output(); } @@ -1295,9 +1274,9 @@ fn test_touch_f_option() { at.remove(file); } +#[uutests::wasi_ignore(NonUtf8ArgsUnsupported)] #[test] #[cfg(target_os = "linux")] -#[cfg_attr(wasi_runner, ignore = "WASI: argv/filenames must be valid UTF-8")] fn test_touch_non_utf8_paths() { use std::ffi::OsStr; use std::os::unix::ffi::OsStrExt; @@ -1312,9 +1291,9 @@ fn test_touch_non_utf8_paths() { assert!(std::fs::metadata(at.plus(non_utf8_name)).is_ok()); } +#[uutests::wasi_ignore(HostPathsNotVisible)] #[test] #[cfg(target_os = "linux")] -#[cfg_attr(wasi_runner, ignore = "WASI sandbox: host paths not visible")] fn test_touch_device_files() { let (_, mut ucmd) = at_and_ucmd!(); ucmd.args(&["/dev/null", "/dev/zero", "/dev/full", "/dev/random"]) @@ -1328,12 +1307,9 @@ fn test_touch_device_files() { // truncates" contract. The create-path fix itself is covered by the // create_without_truncate unit tests in src/touch.rs and the syscall-flag // check in util/check-safe-traversal.sh. +#[uutests::wasi_ignore(AbsoluteSymlinkTargetsUnfollowable)] #[test] #[cfg(unix)] -#[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: absolute symlink targets cannot be followed" -)] fn test_touch_does_not_truncate_symlink_target() { use std::os::unix::fs::symlink; @@ -1347,12 +1323,9 @@ fn test_touch_does_not_truncate_symlink_target() { } // Touching a dangling symlink creates its target as an empty file, like GNU. +#[uutests::wasi_ignore(AbsoluteSymlinkTargetsUnfollowable)] #[test] #[cfg(unix)] -#[cfg_attr( - wasi_runner, - ignore = "WASI sandbox: absolute symlink targets cannot be followed" -)] fn test_touch_through_dangling_symlink_creates_target() { use std::os::unix::fs::symlink; diff --git a/tests/by-util/test_tr.rs b/tests/by-util/test_tr.rs index 2262f89879e..76f1ec74107 100644 --- a/tests/by-util/test_tr.rs +++ b/tests/by-util/test_tr.rs @@ -1544,9 +1544,9 @@ fn check_complement_set2_too_big() { .stderr_contains("when translating with complemented character classes,\nstring2 must map all characters in the domain to one"); } +#[uutests::wasi_ignore(NonUtf8ArgsUnsupported)] #[test] #[cfg(unix)] -#[cfg_attr(wasi_runner, ignore = "WASI: argv/filenames must be valid UTF-8")] fn test_truncate_non_utf8_set() { let stdin = b"\x01amp\xfe\xff"; let set1 = OsStr::from_bytes(b"a\xfe\xffz"); // spell-checker:disable-line @@ -1644,10 +1644,7 @@ fn test_backwards_range() { } #[cfg(target_pointer_width = "64")] -#[cfg_attr( - wasi_runner, - ignore = "WASI: usize is 32-bit, so these repeat counts do not parse" -)] +#[uutests::wasi_ignore(Usize32BitOverflow)] #[test] fn test_huge_repeat_count_in_set1() { // A repeat count this large used to be expanded character by character, @@ -1675,10 +1672,7 @@ fn test_huge_repeat_count_in_set1() { } #[cfg(target_pointer_width = "64")] -#[cfg_attr( - wasi_runner, - ignore = "WASI: usize is 32-bit, so these repeat counts do not parse" -)] +#[uutests::wasi_ignore(Usize32BitOverflow)] #[test] fn test_huge_repeat_count_in_set2() { new_ucmd!() @@ -1699,10 +1693,7 @@ fn test_huge_repeat_count_in_set2() { } #[cfg(target_pointer_width = "64")] -#[cfg_attr( - wasi_runner, - ignore = "WASI: usize is 32-bit, so these repeat counts do not parse" -)] +#[uutests::wasi_ignore(Usize32BitOverflow)] #[test] fn test_repeat_lengths_beyond_usize() { // Set lengths are kept exact when repeat counts add up past usize::MAX, @@ -1762,9 +1753,9 @@ fn test_non_digit_repeat() { .stderr_only("tr: invalid repeat count 'c' in [c*n] construct\n"); } +#[uutests::wasi_ignore(NonUtf8ArgsUnsupported)] #[test] #[cfg(unix)] -#[cfg_attr(wasi_runner, ignore = "WASI: argv/filenames must be valid UTF-8")] fn test_octal_escape_ambiguous_followed_by_non_utf8() { // This case does not trigger the panic let set1 = OsStr::from_bytes(b"\\501a"); @@ -1807,8 +1798,8 @@ fn test_unbuffered_flag() { .stdout_only("HELLO\n"); } +#[uutests::wasi_ignore(NoPipeSignalSupport)] #[test] -#[cfg_attr(wasi_runner, ignore = "WASI: no pipe support")] fn test_unbuffered_partial_line() { // With -u, a chunk without a trailing newline must come out before more // input arrives, as in `tail -f log | tr -u a-z A-Z | consumer`. @@ -1845,8 +1836,8 @@ fn test_unbuffered_partial_line() { handle.join().unwrap(); } +#[uutests::wasi_ignore(NoPipeSignalSupport)] #[test] -#[cfg_attr(wasi_runner, ignore = "WASI: no pipe/signal support")] fn test_broken_pipe_no_error() { // More than a pipe buffer, so that the output blocks until the reader is gone. new_ucmd!() diff --git a/tests/by-util/test_truncate.rs b/tests/by-util/test_truncate.rs index 841fd53a9fe..714fd9b1785 100644 --- a/tests/by-util/test_truncate.rs +++ b/tests/by-util/test_truncate.rs @@ -70,9 +70,9 @@ fn test_reference() { assert_eq!(expected, actual, "expected '{expected}' got '{actual}'"); } +#[uutests::wasi_ignore(NonUtf8ArgsUnsupported)] #[test] #[cfg(target_os = "linux")] -#[cfg_attr(wasi_runner, ignore = "WASI: argv/filenames must be valid UTF-8")] fn test_reference_non_utf8_path() { use std::os::unix::ffi::OsStrExt; @@ -334,8 +334,8 @@ fn test_relative_size_overflow_preserves_file() { } #[cfg(unix)] +#[uutests::wasi_ignore(NoBlockSizeSupport)] #[test] -#[cfg_attr(wasi_runner, ignore = "WASI: no block size support")] fn test_io_blocks_uses_file_block_size() { let (at, mut ucmd) = at_and_ucmd!(); at.write(FILE1, "x"); @@ -349,8 +349,8 @@ fn test_io_blocks_uses_file_block_size() { } #[cfg(unix)] +#[uutests::wasi_ignore(NoBlockSizeSupport)] #[test] -#[cfg_attr(wasi_runner, ignore = "WASI: no block size support")] fn test_io_blocks_uses_parent_block_size_for_new_file() { let (at, mut ucmd) = at_and_ucmd!(); let block_size = at.metadata(".").blksize(); @@ -505,9 +505,9 @@ fn test_negative_size_with_space() { assert!(at.read_bytes(FILE1).is_empty()); } +#[uutests::wasi_ignore(NonUtf8ArgsUnsupported)] #[test] #[cfg(target_os = "linux")] -#[cfg_attr(wasi_runner, ignore = "WASI: argv/filenames must be valid UTF-8")] fn test_truncate_non_utf8_paths() { use std::os::unix::ffi::OsStrExt; let ts = TestScenario::new(util_name!()); @@ -577,8 +577,8 @@ mod diagnostics { } } +#[uutests::wasi_ignore(NoFifo)] #[cfg(not(windows))] -#[cfg(not(wasi_runner))] // WASI: no FIFO/mkfifo support mod fifo { use super::*; diff --git a/tests/by-util/test_unexpand.rs b/tests/by-util/test_unexpand.rs index 675b83f3556..28480e33cfa 100644 --- a/tests/by-util/test_unexpand.rs +++ b/tests/by-util/test_unexpand.rs @@ -359,9 +359,9 @@ fn test_one_nonexisting_file() { .stderr_contains("asdf.txt: No such file or directory"); } +#[uutests::wasi_ignore(HostPathsNotVisible)] #[test] #[cfg(all(target_os = "linux", not(target_env = "musl")))] -#[cfg_attr(wasi_runner, ignore = "WASI sandbox: host paths not visible")] fn test_read_error() { new_ucmd!() .arg("/proc/self/mem") @@ -369,9 +369,9 @@ fn test_read_error() { .stderr_contains("unexpand: /proc/self/mem: Input/output error"); } +#[uutests::wasi_ignore(NonUtf8ArgsUnsupported)] #[test] #[cfg(target_os = "linux")] -#[cfg_attr(wasi_runner, ignore = "WASI: argv/filenames must be valid UTF-8")] fn test_non_utf8_filename() { use std::os::unix::ffi::OsStringExt; diff --git a/tests/by-util/test_uniq.rs b/tests/by-util/test_uniq.rs index 67b83b5ba2b..7033d9813e9 100644 --- a/tests/by-util/test_uniq.rs +++ b/tests/by-util/test_uniq.rs @@ -1189,8 +1189,8 @@ fn uniq_basic_dedup_cases() { } } +#[uutests::wasi_ignore(NoLocaleData)] #[test] -#[cfg_attr(wasi_runner, ignore = "WASI sandbox: locale database not visible")] fn test_stdin_w1_multibyte() { let input = "à\ná\n"; new_ucmd!() diff --git a/tests/by-util/test_unlink.rs b/tests/by-util/test_unlink.rs index 5b12d7205a2..bcfb3672ebb 100644 --- a/tests/by-util/test_unlink.rs +++ b/tests/by-util/test_unlink.rs @@ -81,9 +81,9 @@ fn test_unlink_symlink() { assert!(!at.file_exists("bar")); } +#[uutests::wasi_ignore(NonUtf8ArgsUnsupported)] #[test] #[cfg(target_os = "linux")] -#[cfg_attr(wasi_runner, ignore = "WASI: argv/filenames must be valid UTF-8")] fn test_unlink_non_utf8_paths() { use std::ffi::OsStr; use std::os::unix::ffi::OsStrExt; diff --git a/tests/by-util/test_wc.rs b/tests/by-util/test_wc.rs index 16fd79293f5..d0fb0bca900 100644 --- a/tests/by-util/test_wc.rs +++ b/tests/by-util/test_wc.rs @@ -473,9 +473,9 @@ fn test_read_from_nonexistent_file() { .stderr_only("wc: bogusfile: No such file or directory\n"); } +#[uutests::wasi_ignore(HostPathsNotVisible)] #[test] #[cfg(any(target_os = "linux", target_os = "android"))] -#[cfg_attr(wasi_runner, ignore = "WASI sandbox: host paths (/proc) not visible")] fn test_files_from_pseudo_filesystem() { use pretty_assertions::assert_ne; let result = new_ucmd!().arg("-c").arg("/proc/cpuinfo").succeeds(); @@ -769,8 +769,8 @@ fn test_files0_progressive_stream() { } #[cfg(target_os = "linux")] +#[uutests::wasi_ignore(HostPathsNotVisible)] #[test] -#[cfg_attr(wasi_runner, ignore = "WASI sandbox: host paths not visible")] fn test_files0_stops_after_stdout_write_error() { use std::fs::OpenOptions; @@ -873,8 +873,8 @@ fn test_invalid_byte_sequence_word_count() { } #[cfg(unix)] +#[uutests::wasi_ignore(HostPathsNotVisible)] #[test] -#[cfg_attr(wasi_runner, ignore = "WASI sandbox: host paths not visible")] fn test_simd_respects_glibc_tunables() { use std::fmt::Write as _; diff --git a/tests/by-util/test_yes.rs b/tests/by-util/test_yes.rs index ee6f41a2c00..66286013669 100644 --- a/tests/by-util/test_yes.rs +++ b/tests/by-util/test_yes.rs @@ -32,34 +32,34 @@ fn test_version() { new_ucmd!().arg("--version").succeeds(); } +#[uutests::wasi_ignore(NoPipeSignalSupport)] #[test] -#[cfg_attr(wasi_runner, ignore)] fn test_simple() { run(NO_ARGS, b"y\ny\ny\ny\n"); } +#[uutests::wasi_ignore(NoPipeSignalSupport)] #[test] -#[cfg_attr(wasi_runner, ignore)] fn test_args() { run(&["a", "bar", "c"], b"a bar c\na bar c\na ba"); } +#[uutests::wasi_ignore(NoPipeSignalSupport)] #[test] -#[cfg_attr(wasi_runner, ignore)] fn test_long_output() { run(NO_ARGS, "y\n".repeat(512 * 1024).as_bytes()); } /// Test with an output that seems likely to get mangled in case of incomplete writes. +#[uutests::wasi_ignore(NoPipeSignalSupport)] #[test] -#[cfg_attr(wasi_runner, ignore)] fn test_long_odd_output() { run(&["abcdef"], "abcdef\n".repeat(1024 * 1024).as_bytes()); } /// Test with an input that doesn't fit in the standard buffer. +#[uutests::wasi_ignore(NoPipeSignalSupport)] #[test] -#[cfg_attr(wasi_runner, ignore)] fn test_long_input() { #[cfg(not(windows))] const TIMES: usize = 14000; @@ -75,9 +75,9 @@ fn test_long_input() { /// A joined line larger than the internal broker pipe's capacity (1 MiB) /// can cause a deadlock +#[uutests::wasi_ignore(NoPipeSignalSupport)] #[test] #[cfg(any(target_os = "linux", target_os = "android"))] -#[cfg_attr(wasi_runner, ignore)] fn test_long_line_exceeds_pipe_capacity() { // A single argv string is capped at ~128 KiB by the kernel, so use many // args joined by spaces to build a >1 MiB line instead of one huge arg. @@ -87,9 +87,9 @@ fn test_long_line_exceeds_pipe_capacity() { run(&args, format!("{line}\n{line}\n").as_bytes()); } +#[uutests::wasi_ignore(NoPipeSignalSupport)] #[test] #[cfg(any(target_os = "linux", target_os = "freebsd", target_os = "netbsd"))] -#[cfg_attr(wasi_runner, ignore)] fn test_piped_to_dev_full() { use std::fs::OpenOptions; @@ -109,10 +109,10 @@ fn test_piped_to_dev_full() { } } +#[uutests::wasi_ignore(NonUtf8ArgsUnsupported)] #[test] #[cfg(unix)] // WASI runners (wasmtime) require UTF-8 arguments, so skip this test when testing WASI binaries -#[cfg_attr(wasi_runner, ignore = "WASI: argv must be valid UTF-8")] fn test_non_utf8() { use std::os::unix::ffi::OsStrExt; diff --git a/tests/uutests/Cargo.toml b/tests/uutests/Cargo.toml index ee810110c32..5d001bd68ab 100644 --- a/tests/uutests/Cargo.toml +++ b/tests/uutests/Cargo.toml @@ -32,6 +32,7 @@ uucore = { workspace = true, features = [ "signals", "utmpx", ] } +uutests_procs = { workspace = true } [target.'cfg(any(target_os = "linux", target_os = "android"))'.dependencies] diff --git a/tests/uutests/src/lib/lib.rs b/tests/uutests/src/lib/lib.rs index afd8f1a3939..693bc389875 100644 --- a/tests/uutests/src/lib/lib.rs +++ b/tests/uutests/src/lib/lib.rs @@ -7,3 +7,5 @@ pub mod macros; pub mod random; pub mod util; + +pub use uutests_procs::*; diff --git a/tests/uutests_procs/Cargo.toml b/tests/uutests_procs/Cargo.toml new file mode 100644 index 00000000000..a80d304da6f --- /dev/null +++ b/tests/uutests_procs/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "uutests_procs" +description = "uutils ~ 'uutests' proc-macros" +repository = "https://github.com/uutils/coreutils/tree/main/tests/uutests_procs" +keywords = ["cross-platform", "proc-macros", "uutests", "uutils"] +edition.workspace = true +rust-version.workspace = true +homepage.workspace = true +license.workspace = true +version.workspace = true + +[lib] +proc-macro = true +test = false +doctest = false + +[dependencies] +proc-macro2.workspace = true +quote.workspace = true +syn.workspace = true + +[lints] +workspace = true diff --git a/tests/uutests_procs/src/lib.rs b/tests/uutests_procs/src/lib.rs new file mode 100644 index 00000000000..d2544a0b5c2 --- /dev/null +++ b/tests/uutests_procs/src/lib.rs @@ -0,0 +1,176 @@ +// This file is part of the uutils coreutils package. +// +// For the full copyright and license information, please view the LICENSE +// file that was distributed with this source code. + +//! A collection of procedural macros for the uutests integration test harness. + +#![deny(missing_docs)] + +use proc_macro::TokenStream; +use quote::{quote, quote_spanned}; +use syn::Item; + +/// Marks an integration test as `#[ignore]` under the WASI test runner, for one of a fixed +/// set of named, de-duplicated reasons. +/// +/// This expands to `#[cfg_attr(wasi_runner, ignore = "...")]`, where `wasi_runner` is the +/// `--cfg` set only by the WASI CI job (see `.github/workflows/wasi.yml`) when host-compiled +/// integration tests drive a `wasm32-wasip1`/`wasm32-wasip2` binary through `wasmtime`. Every +/// test ignored under WASI names its reason here, even reasons currently used only once, so +/// the set of known WASI limitations stays in one place instead of scattered as ad hoc string +/// literals across the test suite. +/// +/// Can be applied to a single `#[test]` function, or to a `mod { ... }` block, in which case +/// the reason is attached to every function in that module and in any nested modules. +#[proc_macro_attribute] +pub fn wasi_ignore(args: TokenStream, item: TokenStream) -> TokenStream { + let args = proc_macro2::TokenStream::from(args); + let key = args.to_string(); + let reason = match key.as_str() { + "AbsoluteHostTmpdirOutsideGuestRoot" => { + "WASI sandbox: absolute host tmpdir path is outside the mapped guest root, so cp cannot stat it" + } + "AbsoluteSymlinkTargetsUnfollowable" => { + "WASI sandbox: absolute symlink targets cannot be followed" + } + "AclXattrPreservationFails" => { + "WASI: ACL/xattr syscalls are not implemented, so attribute preservation (--archive, -p) always fails" + } + "AddressSpaceLimitUnsuitable" => { + "WASI runner target is not suitable for this address-space-limit regression test" + } + "CannotDetectUnsafeOverwrite" => "WASI: cannot detect unsafe overwrite", + "CannotExecShellFromDeletedCwd" => { + "WASI: wasmtime cannot exec the binary via a raw shell from a deleted cwd" + } + "ClosedStdoutGenericIoError" => { + "WASI: closed stdout reports a generic I/O error rather than BrokenPipe" + } + "DebugReportsUnsupported" => { + "WASI: --debug reports 'unsupported' instead of 'unknown' for this platform" + } + "DevNullNotSeekable" => "WASI sandbox: /dev/null is not a seekable device", + "DirectoryModesUmaskNotFaithful" => { + "WASI: directory modes/umask are not faithfully reproduced" + } + "DotDotCanonicalizationDiffers" => { + "WASI sandbox: relative '..' path canonicalization differs, causing a false self-copy detection" + } + "EmptyPathResolvesToDirectory" => { + "WASI: an empty path argument resolves to a directory instead of ENOENT" + } + "ErrnoMessageMismatch" => "WASI: errno/error-message mismatches", + "GuestRootWritablePreopen" => { + "WASI: guest root is a writable preopen, not the protected system root" + } + "HostPathsNotVisible" => { + "WASI sandbox: host paths (/dev, /private, /proc, /sys, etc.) not visible" + } + "KillDiscardsUnflushedOutput" => { + "WASI: killing the wasmtime process discards the unflushed output buffer, so the streamed bytes never reach stdout" + } + "LinkInSymlinkedDirectoryDenied" => { + "WASI sandbox: creating a link inside a symlinked directory is denied" + } + "NoBlockSizeSupport" => "WASI: no block size support", + "NoFifo" => "WASI: no FIFO/mkfifo support", + "NoLocaleData" => { + "WASI: no locale data; every locale (even one requested via LC_ALL or other locale env vars) behaves as C" + } + "NoPermissionBits" => { + "WASI: no permission bits/chmod syscall, so file mode cannot be restricted or observed, and explicit mode/ownership preservation always fails" + } + "NoPipeSignalSupport" => "WASI: no pipe/signal support", + "NoRlimitSetrlimitSupport" => "WASI: rlimit/setrlimit not supported", + "NoStdoutFileRedirection" => "WASI: no stdout-to-file redirection", + "NoSubprocessSpawning" => "WASI: no subprocess spawning", + "NoTzdb" => { + "WASI: no tzdb; TZ env var is not honoured, so timezone-dependent behaviour (DST validation, timestamps) differs from the host" + } + "NoUidGid" => "WASI: no uid/gid", + "NoUnixDomainSockets" => "WASI: no Unix domain socket support", + "NonUtf8ArgsUnsupported" => { + "WASI: argv, env values, and paths must be valid UTF-8; wasmtime cannot pass non-UTF-8 data through the sandboxed binary or the spawned test harness" + } + "PathCreateDirectoryNoModeParam" => { + "WASI: path_create_directory has no mode parameter and chmod returns ENOSYS, so directories can't be created with restricted permissions" + } + "PermissionErrorsSurfaceAsEnoent" => { + "WASI: filesystem permission errors surface as ENOENT rather than EACCES" + } + "PreEpochTimestampsUnrepresentable" => { + "WASI: pre-epoch timestamps not representable by path_filestat_set_times" + } + "ReadLinkAbsoluteFailsViaHarness" => { + "WASI: read_link on absolute paths fails under wasmtime via spawned test harness" + } + "ReflinkLinuxMacosOnly" => "WASI: --reflink is only supported on linux and macOS", + "RenameNotAtomicReplace" => { + "WASI: path rename is not guaranteed to be an atomic replace, so a concurrent creator can win the race during a forced relink" + } + "SparseLinuxOnly" => "WASI: --sparse is only supported on linux", + "StdinPositionNotPreserved" => "WASI: stdin file position not preserved through wasmtime", + "StdoutDashUnsupported" => "WASI: touch - (stdout) is unsupported", + "SymlinkHardlinkCaps" => { + "WASI sandbox: symlink/hardlink capability restrictions cause dangling-symlink/same-file detection to differ" + } + "SymlinkLoopNoEloop" => { + "WASI: symlink loop traversal does not surface ELOOP ('Too many levels of symbolic links')" + } + "TailFollowDisabled" => "WASI: tail follow mode disabled", + "Usize32BitOverflow" => "WASI: usize is 32-bit, the host usize::MAX does not parse", + other => { + let span = args + .into_iter() + .next() + .map_or_else(proc_macro2::Span::call_site, |token| token.span()); + let message = format!( + "wasi_ignore: unknown reason key `{other}` (add it to tests/uutests_procs/src/lib.rs)" + ); + let item = proc_macro2::TokenStream::from(item); + return TokenStream::from(quote_spanned! { span => + compile_error!(#message); + #item + }); + } + }; + + let input = syn::parse_macro_input!(item as Item); + let output = match input { + Item::Fn(_) | Item::Mod(_) => apply_to_tests(input, reason), + other => { + let message = "wasi_ignore can only be applied to a #[test] function or a module containing tests"; + return TokenStream::from(quote_spanned! { proc_macro2::Span::call_site() => + compile_error!(#message); + #other + }); + } + }; + TokenStream::from(quote! { #output }) +} + +/// Attaches the ignore reason to every function in `item`, recursing into nested modules. +/// Non-function, non-module items (`use`, `const`, ...) pass through unchanged. +fn apply_to_tests(item: Item, reason: &str) -> Item { + match item { + Item::Fn(mut func) => { + func.attrs.insert( + 0, + syn::parse_quote! { #[cfg_attr(wasi_runner, ignore = #reason)] }, + ); + Item::Fn(func) + } + Item::Mod(mut module) => { + if let Some((brace, items)) = module.content.take() { + let items = items + .into_iter() + .map(|it| apply_to_tests(it, reason)) + .collect(); + module.content = Some((brace, items)); + } + Item::Mod(module) + } + other => other, + } +} diff --git a/util/publish.sh b/util/publish.sh index f892e638c99..58b7ee380d4 100755 --- a/util/publish.sh +++ b/util/publish.sh @@ -58,7 +58,7 @@ TOTAL_ORDER=${TOTAL_ORDER#ROOT} CRATE_VERSION=$(grep '^version =' Cargo.toml | head -n1 | cut -d '"' -f2) set -e -CORE_DIRS="src/uucore_procs/ src/uucore/ src/uu/stdbuf/src/libstdbuf/ tests/uutests/ fuzz/uufuzz/" +CORE_DIRS="src/uucore_procs/ src/uucore/ src/uu/stdbuf/src/libstdbuf/ tests/uutests_procs/ tests/uutests/ fuzz/uufuzz/" CORE_COUNT=$(echo $CORE_DIRS | wc -w) UTIL_COUNT=$(echo $TOTAL_ORDER | wc -w) TOTAL_COUNT=$((CORE_COUNT + UTIL_COUNT + 1)) diff --git a/util/update-version.sh b/util/update-version.sh index d810bb636d3..1c59537fe21 100755 --- a/util/update-version.sh +++ b/util/update-version.sh @@ -20,7 +20,7 @@ FROM="0.12.0" TO="0.13.0" -MANIFESTS=$(ls -1d Cargo.toml src/uu/*/Cargo.toml src/uu/stdbuf/src/libstdbuf/Cargo.toml src/uucore/Cargo.toml src/uucore_procs/Cargo.toml tests/uutests/Cargo.toml fuzz/uufuzz/Cargo.toml) +MANIFESTS=$(ls -1d Cargo.toml src/uu/*/Cargo.toml src/uu/stdbuf/src/libstdbuf/Cargo.toml src/uucore/Cargo.toml src/uucore_procs/Cargo.toml tests/uutests_procs/Cargo.toml tests/uutests/Cargo.toml fuzz/uufuzz/Cargo.toml) # Only two kinds of lines are rewritten, so that third party crates which # happen to share our version number (md-5, sha1, sha2, sha3, ...) are left