Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mv: inter partition copying test code cleanup #6583

Merged
merged 3 commits into from
Jul 19, 2024
Merged
Changes from 1 commit
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
199 changes: 100 additions & 99 deletions tests/by-util/test_mv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1623,105 +1623,106 @@ fn test_acl() {
// mv: try to overwrite 'b', overriding mode 0444 (r--r--r--)? y
// 'a' -> 'b'

// Ensure that the copying code used in an inter-partition move unlinks the destination symlink.
#[cfg(target_os = "linux")]
#[test]
fn test_mv_unlinks_dest_symlink() {
let scene = TestScenario::new(util_name!());
let at = &scene.fixtures;

// create a file in the current partition.
at.write("src", "src contents");

// create a folder in another partition.
let other_fs_tempdir =
tempfile::TempDir::new_in("/dev/shm/").expect("Unable to create temp directory");

// create a file inside that folder.
let other_fs_file_path = other_fs_tempdir.path().join("other_fs_file");
let mut file =
std::fs::File::create(&other_fs_file_path).expect("Unable to create other_fs_file");
std::io::Write::write_all(&mut file, b"other fs file contents")
.expect("Unable to write to other_fs_file");

// create a symlink to the file inside the same directory.
let symlink_path = other_fs_tempdir.path().join("symlink_to_file");
std::os::unix::fs::symlink(&other_fs_file_path, &symlink_path)
.expect("Unable to create symlink_to_file");

// mv src to symlink in another partition
scene
.ucmd()
.arg("src")
.arg(symlink_path.to_str().unwrap())
.succeeds();

// make sure that src got removed.
assert!(!at.file_exists("src"));

// make sure symlink got unlinked
assert!(!symlink_path.is_symlink());

// make sure that file contents in other_fs_file didn't change.
let mut new_contents = String::new();
std::io::Read::read_to_string(
&mut std::fs::File::open(&other_fs_file_path).expect("Unable to open other_fs_file"),
&mut new_contents,
)
.expect("Unable to read other_fs_file");
assert_eq!(new_contents, "other fs file contents");

// make sure that src file contents got copied into new file created in symlink_path .
let mut new_contents = String::new();
std::io::Read::read_to_string(
&mut std::fs::File::open(&symlink_path).expect("Unable to open file"),
&mut new_contents,
)
.expect("Unable to read file");
assert_eq!(new_contents, "src contents");
}

// In an inter-partition move if unlinking the destination symlink fails, ensure
// that it would output the proper error message.
#[cfg(target_os = "linux")]
#[test]
fn test_mv_unlinks_dest_symlink_error_message() {
let scene = TestScenario::new(util_name!());
let at = &scene.fixtures;
mod inter_partition_copying {
use crate::common::util::TestScenario;

use std::fs::{set_permissions, File};
use std::io::{Read, Write};
use std::os::unix::fs::{symlink, PermissionsExt};
use tempfile::TempDir;

// Ensure that the copying code used in an inter-partition move unlinks the destination symlink.
#[test]
pub(crate) fn test_mv_unlinks_dest_symlink() {
let scene = TestScenario::new(util_name!());
let at = &scene.fixtures;

// create a file in the current partition.
at.write("src", "src contents");

// create a folder in another partition.
let other_fs_tempdir =
TempDir::new_in("/dev/shm/").expect("Unable to create temp directory");

// create a file inside that folder.
let other_fs_file_path = other_fs_tempdir.path().join("other_fs_file");
let mut file = File::create(&other_fs_file_path).expect("Unable to create other_fs_file");
Write::write_all(&mut file, b"other fs file contents")
.expect("Unable to write to other_fs_file");
matrixhead marked this conversation as resolved.
Show resolved Hide resolved

// create a symlink to the file inside the same directory.
let symlink_path = other_fs_tempdir.path().join("symlink_to_file");
symlink(&other_fs_file_path, &symlink_path).expect("Unable to create symlink_to_file");

// mv src to symlink in another partition
scene
.ucmd()
.arg("src")
.arg(symlink_path.to_str().unwrap())
.succeeds();

// make sure that src got removed.
assert!(!at.file_exists("src"));

// make sure symlink got unlinked
assert!(!symlink_path.is_symlink());

// make sure that file contents in other_fs_file didn't change.
let mut new_contents = String::new();
Read::read_to_string(
&mut File::open(&other_fs_file_path).expect("Unable to open other_fs_file"),
&mut new_contents,
)
matrixhead marked this conversation as resolved.
Show resolved Hide resolved
.expect("Unable to read other_fs_file");
assert_eq!(new_contents, "other fs file contents");

// make sure that src file contents got copied into new file created in symlink_path .
let mut new_contents = String::new();
Read::read_to_string(
&mut File::open(&symlink_path).expect("Unable to open file"),
&mut new_contents,
)
.expect("Unable to read file");
assert_eq!(new_contents, "src contents");
}

// create a file in the current partition.
at.write("src", "src contents");

// create a folder in another partition.
let other_fs_tempdir =
tempfile::TempDir::new_in("/dev/shm/").expect("Unable to create temp directory");

// create a file inside that folder.
let other_fs_file_path = other_fs_tempdir.path().join("other_fs_file");
let mut file =
std::fs::File::create(&other_fs_file_path).expect("Unable to create other_fs_file");
std::io::Write::write_all(&mut file, b"other fs file contents")
.expect("Unable to write to other_fs_file");

// create a symlink to the file inside the same directory.
let symlink_path = other_fs_tempdir.path().join("symlink_to_file");
std::os::unix::fs::symlink(&other_fs_file_path, &symlink_path)
.expect("Unable to create symlink_to_file");

// disable write for the target folder so that when mv tries to remove the
// the destination symlink inside the target directory it would fail.
std::fs::set_permissions(
other_fs_tempdir.path(),
std::os::unix::fs::PermissionsExt::from_mode(0o555),
)
.expect("Unable to set permissions for temp directory");

// mv src to symlink in another partition
scene
.ucmd()
.arg("src")
.arg(symlink_path.to_str().unwrap())
.fails()
.stderr_contains("inter-device move failed:")
.stderr_contains("Permission denied");
// In an inter-partition move if unlinking the destination symlink fails, ensure
// that it would output the proper error message.
#[test]
pub(crate) fn test_mv_unlinks_dest_symlink_error_message() {
let scene = TestScenario::new(util_name!());
let at = &scene.fixtures;

// create a file in the current partition.
at.write("src", "src contents");

// create a folder in another partition.
let other_fs_tempdir =
TempDir::new_in("/dev/shm/").expect("Unable to create temp directory");

// create a file inside that folder.
let other_fs_file_path = other_fs_tempdir.path().join("other_fs_file");
let mut file = File::create(&other_fs_file_path).expect("Unable to create other_fs_file");
Write::write_all(&mut file, b"other fs file contents")
.expect("Unable to write to other_fs_file");

// create a symlink to the file inside the same directory.
let symlink_path = other_fs_tempdir.path().join("symlink_to_file");
symlink(&other_fs_file_path, &symlink_path).expect("Unable to create symlink_to_file");

// disable write for the target folder so that when mv tries to remove the
// the destination symlink inside the target directory it would fail.
set_permissions(other_fs_tempdir.path(), PermissionsExt::from_mode(0o555))
.expect("Unable to set permissions for temp directory");

// mv src to symlink in another partition
scene
.ucmd()
.arg("src")
.arg(symlink_path.to_str().unwrap())
.fails()
.stderr_contains("inter-device move failed:")
.stderr_contains("Permission denied");
}
}
Loading