Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/wasi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ jobs:
# caret diagnostics; the host test crate does have them, hence the
# not(wasi_runner) in the cfg guarding every `mod diagnostics`.
# TODO: add integration tests for these tools as WASI support is extended:
# cksum csplit dircolors fmt ls mv readlink
# cksum csplit dircolors fmt ls readlink
# realpath rm seq sort split tsort
# nproc is not part of the default feature set, so it needs to be
# requested explicitly for the host test crate to compile its tests.
Expand All @@ -74,7 +74,7 @@ jobs:
test_factor:: test_false:: test_fold:: test_head:: test_join:: test_link:: test_ln:: \
test_ls::test_ls_a_dotdot_no_error_on_wasi \
test_ls::test_ls_al_no_capabilities_insufficient_on_wasi \
test_md5sum:: test_mkdir:: test_mktemp:: test_nl:: test_nproc:: test_numfmt:: test_od:: \
test_md5sum:: test_mkdir:: test_mktemp:: test_mv:: test_nl:: test_nproc:: test_numfmt:: test_od:: \
test_paste:: test_pathchk:: test_pr:: test_printenv:: test_printf:: test_ptx:: \
test_pwd:: test_rmdir:: test_sha1sum:: test_sha224sum:: test_sha256sum:: \
test_sha384sum:: test_sha512sum:: test_shred:: test_shuf:: test_sleep:: \
Expand Down
54 changes: 53 additions & 1 deletion tests/by-util/test_mv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,10 @@ fn test_mv_file_to_broken_symlink_directory() {

#[test]
#[cfg(all(unix, not(target_os = "android")))]
#[cfg_attr(
wasi_runner,
ignore = "WASI sandbox: mv doesn't recognize a symlink-to-directory as a directory target, so it overwrites the symlink with a plain file instead of moving into the directory it points to"
)]
fn test_mv_file_to_symlink_directory() {
let (at, mut ucmd) = at_and_ucmd!();

Expand Down Expand Up @@ -560,6 +564,10 @@ fn test_mv_same_file() {

#[test]
#[cfg(all(unix, not(target_os = "android")))]
#[cfg_attr(
wasi_runner,
ignore = "WASI: rustix::fs::stat doesn't return stable inode identity, so same-file detection via a hard link fails"
)]
fn test_mv_same_hardlink() {
let (at, mut ucmd) = at_and_ucmd!();
let file_a = "test_mv_same_file_a";
Expand Down Expand Up @@ -590,6 +598,10 @@ fn test_mv_dangling_symlink_to_folder() {

#[test]
#[cfg(all(unix, not(target_os = "android")))]
#[cfg_attr(
wasi_runner,
ignore = "WASI: rustix::fs::stat doesn't return stable inode identity, so same-file detection via a symlink fails"
)]
fn test_mv_same_symlink() {
let (at, mut ucmd) = at_and_ucmd!();
let file_a = "test_mv_same_file_a";
Expand Down Expand Up @@ -662,6 +674,7 @@ fn test_mv_symlink_into_target() {

#[cfg(target_os = "linux")]
#[test]
#[cfg_attr(wasi_runner, ignore = "WASI sandbox: host paths not visible")]
fn test_mv_broken_symlink_to_another_fs() {
use tempfile::TempDir;

Expand All @@ -679,6 +692,10 @@ fn test_mv_broken_symlink_to_another_fs() {

#[test]
#[cfg(all(unix, not(target_os = "android")))]
#[cfg_attr(
wasi_runner,
ignore = "WASI: rustix::fs::stat doesn't return stable inode identity, so same-file detection via a symlink/hardlink pair fails"
)]
fn test_mv_hardlink_to_symlink() {
let (at, mut ucmd) = at_and_ucmd!();
let file = "file";
Expand Down Expand Up @@ -1698,6 +1715,10 @@ fn test_mv_verbose() {
#[test]
#[cfg(any(target_os = "linux", target_os = "android"))] // mkdir does not support -m on windows. Freebsd doesn't return a permission error either.
#[cfg(feature = "mkdir")]
#[cfg_attr(
wasi_runner,
ignore = "WASI: mkdir -m444 does not restrict write access under the WASI sandbox, so the subsequent mv succeeds instead of failing with a permission error"
)]
fn test_mv_permission_error() {
let scene = TestScenario::new("mkdir");
let folder1 = "bar";
Expand Down Expand Up @@ -1914,6 +1935,10 @@ fn test_mv_seen_multiple_files_to_directory() {
}

#[test]
#[cfg_attr(
wasi_runner,
ignore = "WASI: raw ENOTDIR (\"Not a directory\") surfaces instead of the translated cannot-stat message, because stat() doesn't enforce the trailing-slash-requires-directory rule for non-directory sources"
)]
fn test_mv_dir_into_file_where_both_are_files() {
let scene = TestScenario::new(util_name!());
let at = &scene.fixtures;
Expand Down Expand Up @@ -2080,6 +2105,7 @@ mod inter_partition_copying {
// bits are legitimate; only a failed chown justifies stripping them, and
// that needs a second uid, so it is exercised out of band rather than here.
#[test]
#[cfg_attr(wasi_runner, ignore = "WASI sandbox: /dev/shm not visible")]
pub(crate) fn test_mv_inter_partition_keeps_setuid_when_ownership_preserved() {
let scene = TestScenario::new(util_name!());
let at = &scene.fixtures;
Expand Down Expand Up @@ -2111,6 +2137,7 @@ mod inter_partition_copying {

// Ensure that the copying code used in an inter-partition move unlinks the destination symlink.
#[test]
#[cfg_attr(wasi_runner, ignore = "WASI sandbox: host paths not visible")]
pub(crate) fn test_mv_unlinks_dest_symlink() {
let scene = TestScenario::new(util_name!());
let at = &scene.fixtures;
Expand Down Expand Up @@ -2160,6 +2187,7 @@ mod inter_partition_copying {
// In an inter-partition move if unlinking the destination symlink fails, ensure
// that it would output the proper error message.
#[test]
#[cfg_attr(wasi_runner, ignore = "WASI sandbox: host paths not visible")]
pub(crate) fn test_mv_unlinks_dest_symlink_error_message() {
use uutests::util::TestScenario;
let scene = TestScenario::new(util_name!());
Expand Down Expand Up @@ -2192,6 +2220,7 @@ mod inter_partition_copying {
// Test that hardlinks are preserved when moving files across partitions
#[test]
#[cfg(unix)]
#[cfg_attr(wasi_runner, ignore = "WASI sandbox: host paths not visible")]
pub(crate) fn test_mv_preserves_hardlinks_across_partitions() {
use std::fs;
use std::os::unix::fs::MetadataExt;
Expand Down Expand Up @@ -2268,6 +2297,7 @@ mod inter_partition_copying {
#[cfg(unix)]
#[allow(clippy::too_many_lines)]
#[allow(clippy::similar_names)]
#[cfg_attr(wasi_runner, ignore = "WASI sandbox: host paths not visible")]
pub(crate) fn test_mv_preserves_multiple_hardlink_groups_across_partitions() {
use std::fs::metadata;
use std::os::unix::fs::MetadataExt;
Expand Down Expand Up @@ -2381,6 +2411,7 @@ mod inter_partition_copying {
// Test hardlinks within directories being moved
#[test]
#[cfg(unix)]
#[cfg_attr(wasi_runner, ignore = "WASI sandbox: host paths not visible")]
pub(crate) fn test_mv_preserves_hardlinks_in_directories_across_partitions() {
use std::fs::metadata;
use std::os::unix::fs::MetadataExt;
Expand Down Expand Up @@ -2483,6 +2514,7 @@ mod inter_partition_copying {
#[cfg(unix)]
#[allow(clippy::too_many_lines)]
#[allow(clippy::similar_names)]
#[cfg_attr(wasi_runner, ignore = "WASI sandbox: host paths not visible")]
pub(crate) fn test_mv_preserves_complex_hardlinks_across_nested_directories() {
use std::fs::metadata;
use std::os::unix::fs::MetadataExt;
Expand Down Expand Up @@ -2629,6 +2661,7 @@ mod inter_partition_copying {

#[test]
#[cfg(unix)]
#[cfg_attr(wasi_runner, ignore = "WASI sandbox: host paths not visible")]
pub(crate) fn test_mv_dir_with_fifo_across_partitions() {
use std::os::unix::fs::FileTypeExt;
use tempfile::TempDir;
Expand Down Expand Up @@ -2662,6 +2695,7 @@ mod inter_partition_copying {
// self-referential symlinks and destroying the content.
#[test]
#[cfg(unix)]
#[cfg_attr(wasi_runner, ignore = "WASI sandbox: /dev/shm not visible")]
pub(crate) fn test_mv_symlink_to_hardlinked_sibling_across_partitions() {
use std::os::unix::fs::MetadataExt;

Expand Down Expand Up @@ -2861,6 +2895,7 @@ fn test_special_file_different_filesystem() {
/// a cross-device move fails due to permission errors when removing the target file
#[test]
#[cfg(target_os = "linux")]
#[cfg_attr(wasi_runner, ignore = "WASI sandbox: host paths not visible")]
fn test_mv_cross_device_permission_denied() {
use std::fs::{set_permissions, write};
use std::os::unix::fs::PermissionsExt;
Expand Down Expand Up @@ -2909,6 +2944,7 @@ fn test_mv_cross_device_permission_denied() {
/// than truncate `victim`.
#[test]
#[cfg(target_os = "linux")]
#[cfg_attr(wasi_runner, ignore = "WASI sandbox: host paths not visible")]
fn test_mv_cross_device_refuses_planted_symlink_dest() {
use std::os::unix::fs::symlink;
use tempfile::TempDir;
Expand Down Expand Up @@ -3063,6 +3099,7 @@ fn test_mv_error_usage_display_too_few() {

#[test]
#[cfg(target_os = "linux")]
#[cfg_attr(wasi_runner, ignore = "WASI sandbox: host paths not visible")]
fn test_mv_verbose_directory_recursive() {
use tempfile::TempDir;

Expand Down Expand Up @@ -3118,6 +3155,7 @@ fn test_mv_verbose_directory_recursive() {

#[cfg(unix)]
#[test]
#[cfg_attr(wasi_runner, ignore = "WASI: st_mode has no real permission bits")]
fn test_mv_prompt_unwriteable_file_when_using_tty() {
let (at, mut ucmd) = at_and_ucmd!();

Expand Down Expand Up @@ -3271,6 +3309,7 @@ fn test_mv_cross_device_dir_xattr_preserved() {
/// block, so the large attributes fail there and the small ones must survive.
#[test]
#[cfg(target_os = "linux")]
#[cfg_attr(wasi_runner, ignore = "WASI sandbox: /dev/shm not visible")]
fn test_mv_cross_device_xattr_failure_keeps_the_rest() {
use rustc_hash::FxHashMap;
use std::ffi::{OsStr, OsString};
Expand Down Expand Up @@ -3337,6 +3376,7 @@ fn test_mv_cross_device_xattr_failure_keeps_the_rest() {
/// destination atomically, matching GNU.
#[test]
#[cfg(target_os = "linux")]
#[cfg_attr(wasi_runner, ignore = "WASI sandbox: host paths not visible")]
fn test_mv_cross_device_symlink_onto_existing() {
use std::fs;
use std::os::unix::fs::symlink;
Expand Down Expand Up @@ -3377,6 +3417,7 @@ fn test_mv_cross_device_symlink_onto_existing() {
/// fail without destroying the directory or its contents.
#[test]
#[cfg(target_os = "linux")]
#[cfg_attr(wasi_runner, ignore = "WASI sandbox: host paths not visible")]
fn test_mv_cross_device_symlink_onto_existing_dir() {
use std::fs;
use std::os::unix::fs::symlink;
Expand Down Expand Up @@ -3418,6 +3459,7 @@ fn test_mv_cross_device_symlink_onto_existing_dir() {
/// (not expanded into full copies of their targets)
#[test]
#[cfg(target_os = "linux")]
#[cfg_attr(wasi_runner, ignore = "WASI sandbox: host paths not visible")]
fn test_mv_cross_device_symlink_preserved() {
use std::fs;
use std::os::unix::fs::symlink;
Expand Down Expand Up @@ -3465,6 +3507,7 @@ fn test_mv_cross_device_symlink_preserved() {
/// Test that broken/dangling symlinks are preserved during cross-device moves
#[test]
#[cfg(target_os = "linux")]
#[cfg_attr(wasi_runner, ignore = "WASI sandbox: host paths not visible")]
fn test_mv_cross_device_broken_symlink_preserved() {
use std::fs;
use std::os::unix::fs::symlink;
Expand Down Expand Up @@ -3510,6 +3553,7 @@ fn test_mv_cross_device_broken_symlink_preserved() {
/// Test that symlinks to regular files are preserved during cross-device moves
#[test]
#[cfg(target_os = "linux")]
#[cfg_attr(wasi_runner, ignore = "WASI sandbox: host paths not visible")]
fn test_mv_cross_device_file_symlink_preserved() {
use std::fs;
use std::os::unix::fs::symlink;
Expand Down Expand Up @@ -3571,6 +3615,7 @@ fn find_other_group(current: u32) -> Option<u32> {
/// See https://github.com/uutils/coreutils/issues/9714
#[test]
#[cfg(target_os = "linux")]
#[cfg_attr(wasi_runner, ignore = "WASI sandbox: host paths not visible")]
fn test_mv_cross_device_preserves_ownership() {
use std::fs;
use std::os::unix::fs::MetadataExt;
Expand Down Expand Up @@ -3633,6 +3678,7 @@ fn test_mv_cross_device_preserves_ownership() {
/// See https://github.com/uutils/coreutils/issues/9714
#[test]
#[cfg(target_os = "linux")]
#[cfg_attr(wasi_runner, ignore = "WASI sandbox: host paths not visible")]
fn test_mv_cross_device_preserves_ownership_recursive() {
use std::fs;
use std::os::unix::fs::MetadataExt;
Expand Down Expand Up @@ -3760,6 +3806,7 @@ fn test_mv_backup_numbered_allows_source_named_like_backup() {

#[cfg(any(target_os = "linux", target_os = "android"))]
#[test]
#[cfg_attr(wasi_runner, ignore = "WASI: --exchange is not supported")]
Comment thread
eduardomourar marked this conversation as resolved.
fn test_mv_exchange_file_and_dir() {
let (at, mut ucmd) = at_and_ucmd!();
at.write("leaf", "payload");
Expand All @@ -3780,6 +3827,7 @@ fn test_mv_exchange_file_and_dir() {

#[cfg(any(target_os = "linux", target_os = "android"))]
#[test]
#[cfg_attr(wasi_runner, ignore = "WASI: --exchange is not supported")]
fn test_mv_exchange_verbose() {
let (at, mut ucmd) = at_and_ucmd!();
at.write("first", "1");
Expand All @@ -3798,6 +3846,7 @@ fn test_mv_exchange_verbose() {

#[cfg(any(target_os = "linux", target_os = "android"))]
#[test]
#[cfg_attr(wasi_runner, ignore = "WASI: --exchange is not supported")]
fn test_mv_exchange_wrong_operand_count() {
let scene = TestScenario::new(util_name!());
scene.fixtures.write("only", "x");
Expand Down Expand Up @@ -3828,6 +3877,7 @@ fn test_mv_exchange_wrong_operand_count() {

#[cfg(any(target_os = "linux", target_os = "android"))]
#[test]
#[cfg_attr(wasi_runner, ignore = "WASI: --exchange is not supported")]
fn test_mv_exchange_multiple_operands_into_directory() {
let (at, mut ucmd) = at_and_ucmd!();
at.write("a", "src-a");
Expand Down Expand Up @@ -3859,6 +3909,7 @@ fn test_mv_exchange_multiple_operands_into_directory() {

#[cfg(any(target_os = "linux", target_os = "android"))]
#[test]
#[cfg_attr(wasi_runner, ignore = "WASI: --exchange is not supported")]
fn test_mv_exchange_same_file() {
let (at, mut ucmd) = at_and_ucmd!();
at.write("only", "data");
Expand All @@ -3873,7 +3924,7 @@ fn test_mv_exchange_same_file() {
assert_eq!(at.read("only"), "data");
}

#[cfg(not(any(target_os = "linux", target_os = "android")))]
#[cfg(any(not(any(target_os = "linux", target_os = "android")), wasi_runner))]
#[test]
fn test_mv_exchange_not_supported() {
let (at, mut ucmd) = at_and_ucmd!();
Expand All @@ -3893,6 +3944,7 @@ fn test_mv_exchange_not_supported() {

#[cfg(any(target_os = "linux", target_os = "android"))]
#[test]
#[cfg_attr(wasi_runner, ignore = "WASI: --exchange is not supported")]
fn test_mv_exchange_missing_target() {
let (at, mut ucmd) = at_and_ucmd!();
at.write("present", "data");
Expand Down
Loading