coreutils/tests/test_cp.rs

330 lines
8.8 KiB
Rust

use crate::common::util::*;
#[cfg(not(windows))]
use std::fs::set_permissions;
static TEST_EXISTING_FILE: &str = "existing_file.txt";
static TEST_HELLO_WORLD_SOURCE: &str = "hello_world.txt";
static TEST_HELLO_WORLD_DEST: &str = "copy_of_hello_world.txt";
static TEST_HOW_ARE_YOU_SOURCE: &str = "how_are_you.txt";
static TEST_HOW_ARE_YOU_DEST: &str = "hello_dir/how_are_you.txt";
static TEST_COPY_TO_FOLDER: &str = "hello_dir/";
static TEST_COPY_TO_FOLDER_FILE: &str = "hello_dir/hello_world.txt";
static TEST_COPY_FROM_FOLDER: &str = "hello_dir_with_file/";
static TEST_COPY_FROM_FOLDER_FILE: &str = "hello_dir_with_file/hello_world.txt";
static TEST_COPY_TO_FOLDER_NEW: &str = "hello_dir_new/";
static TEST_COPY_TO_FOLDER_NEW_FILE: &str = "hello_dir_new/hello_world.txt";
#[test]
fn test_cp_cp() {
let (at, mut ucmd) = at_and_ucmd!();
// Invoke our binary to make the copy.
let result = ucmd
.arg(TEST_HELLO_WORLD_SOURCE)
.arg(TEST_HELLO_WORLD_DEST)
.run();
// Check that the exit code represents a successful copy.
let exit_success = result.success;
assert!(exit_success);
// Check the content of the destination file that was copied.
assert_eq!(at.read(TEST_HELLO_WORLD_DEST), "Hello, World!\n");
}
#[test]
fn test_cp_existing_target() {
let (at, mut ucmd) = at_and_ucmd!();
let result = ucmd
.arg(TEST_HELLO_WORLD_SOURCE)
.arg(TEST_EXISTING_FILE)
.run();
assert!(result.success);
// Check the content of the destination file
assert_eq!(at.read(TEST_EXISTING_FILE), "Hello, World!\n");
// No backup should have been created
assert!(!at.file_exists(&*format!("{}~", TEST_EXISTING_FILE)));
}
#[test]
fn test_cp_duplicate_files() {
let (at, mut ucmd) = at_and_ucmd!();
let result = ucmd
.arg(TEST_HELLO_WORLD_SOURCE)
.arg(TEST_HELLO_WORLD_SOURCE)
.arg(TEST_COPY_TO_FOLDER)
.run();
assert!(result.success);
assert!(result.stderr.contains("specified more than once"));
assert_eq!(at.read(TEST_COPY_TO_FOLDER_FILE), "Hello, World!\n");
}
#[test]
fn test_cp_multiple_files_target_is_file() {
let (_, mut ucmd) = at_and_ucmd!();
let result = ucmd
.arg(TEST_HELLO_WORLD_SOURCE)
.arg(TEST_HELLO_WORLD_SOURCE)
.arg(TEST_EXISTING_FILE)
.run();
assert!(!result.success);
assert!(result.stderr.contains("not a directory"));
}
#[test]
fn test_cp_directory_not_recursive() {
let (_, mut ucmd) = at_and_ucmd!();
let result = ucmd
.arg(TEST_COPY_TO_FOLDER)
.arg(TEST_HELLO_WORLD_DEST)
.run();
assert!(!result.success);
assert!(result.stderr.contains("omitting directory"));
}
#[test]
fn test_cp_multiple_files() {
let (at, mut ucmd) = at_and_ucmd!();
let result = ucmd
.arg(TEST_HELLO_WORLD_SOURCE)
.arg(TEST_HOW_ARE_YOU_SOURCE)
.arg(TEST_COPY_TO_FOLDER)
.run();
assert!(result.success);
assert_eq!(at.read(TEST_COPY_TO_FOLDER_FILE), "Hello, World!\n");
assert_eq!(at.read(TEST_HOW_ARE_YOU_DEST), "How are you?\n");
}
#[test]
fn test_cp_recurse() {
let (at, mut ucmd) = at_and_ucmd!();
let result = ucmd
.arg("-r")
.arg(TEST_COPY_FROM_FOLDER)
.arg(TEST_COPY_TO_FOLDER_NEW)
.run();
assert!(result.success);
// Check the content of the destination file that was copied.
assert_eq!(at.read(TEST_COPY_TO_FOLDER_NEW_FILE), "Hello, World!\n");
}
#[test]
fn test_cp_with_dirs_t() {
let (at, mut ucmd) = at_and_ucmd!();
//using -t option
let result_to_dir_t = ucmd
.arg("-t")
.arg(TEST_COPY_TO_FOLDER)
.arg(TEST_HELLO_WORLD_SOURCE)
.run();
assert!(result_to_dir_t.success);
assert_eq!(at.read(TEST_COPY_TO_FOLDER_FILE), "Hello, World!\n");
}
#[test]
fn test_cp_with_dirs() {
let scene = TestScenario::new(util_name!());
let at = &scene.fixtures;
//using -t option
let result_to_dir = scene
.ucmd()
.arg(TEST_HELLO_WORLD_SOURCE)
.arg(TEST_COPY_TO_FOLDER)
.run();
assert!(result_to_dir.success);
assert_eq!(at.read(TEST_COPY_TO_FOLDER_FILE), "Hello, World!\n");
let result_from_dir = scene
.ucmd()
.arg(TEST_COPY_FROM_FOLDER_FILE)
.arg(TEST_HELLO_WORLD_DEST)
.run();
assert!(result_from_dir.success);
assert_eq!(at.read(TEST_HELLO_WORLD_DEST), "Hello, World!\n");
}
#[test]
fn test_cp_arg_target_directory() {
let (at, mut ucmd) = at_and_ucmd!();
let result = ucmd
.arg(TEST_HELLO_WORLD_SOURCE)
.arg("-t")
.arg(TEST_COPY_TO_FOLDER)
.run();
assert!(result.success);
assert_eq!(at.read(TEST_COPY_TO_FOLDER_FILE), "Hello, World!\n");
}
#[test]
fn test_cp_arg_no_target_directory() {
let (_, mut ucmd) = at_and_ucmd!();
let result = ucmd
.arg(TEST_HELLO_WORLD_SOURCE)
.arg("-v")
.arg("-T")
.arg(TEST_COPY_TO_FOLDER)
.run();
assert!(!result.success);
assert!(result.stderr.contains("cannot overwrite directory"));
}
#[test]
fn test_cp_arg_interactive() {
let (_, mut ucmd) = at_and_ucmd!();
let result = ucmd
.arg(TEST_HELLO_WORLD_SOURCE)
.arg(TEST_HOW_ARE_YOU_SOURCE)
.arg("-i")
.pipe_in("N\n")
.run();
assert!(result.success);
assert!(result.stderr.contains("Not overwriting"));
}
#[test]
#[cfg(target_os = "unix")]
fn test_cp_arg_link() {
use std::os::linux::fs::MetadataExt;
let (at, mut ucmd) = at_and_ucmd!();
let result = ucmd
.arg(TEST_HELLO_WORLD_SOURCE)
.arg("--link")
.arg(TEST_HELLO_WORLD_DEST)
.run();
assert!(result.success);
assert_eq!(at.metadata(TEST_HELLO_WORLD_SOURCE).st_nlink(), 2);
}
#[test]
fn test_cp_arg_symlink() {
let (at, mut ucmd) = at_and_ucmd!();
let result = ucmd
.arg(TEST_HELLO_WORLD_SOURCE)
.arg("--symbolic-link")
.arg(TEST_HELLO_WORLD_DEST)
.run();
assert!(result.success);
assert!(at.is_symlink(TEST_HELLO_WORLD_DEST));
}
#[test]
fn test_cp_arg_no_clobber() {
let (at, mut ucmd) = at_and_ucmd!();
let result = ucmd
.arg(TEST_HELLO_WORLD_SOURCE)
.arg("--no-clobber")
.arg(TEST_HOW_ARE_YOU_SOURCE)
.run();
assert!(result.success);
assert_eq!(at.read(TEST_HOW_ARE_YOU_SOURCE), "How are you?\n");
assert!(result.stderr.contains("Not overwriting"));
}
#[test]
#[cfg(not(windows))]
fn test_cp_arg_force() {
let (at, mut ucmd) = at_and_ucmd!();
// create dest without write permissions
let mut permissions = at
.make_file(TEST_HELLO_WORLD_DEST)
.metadata()
.unwrap()
.permissions();
permissions.set_readonly(true);
set_permissions(at.plus(TEST_HELLO_WORLD_DEST), permissions).unwrap();
let result = ucmd
.arg(TEST_HELLO_WORLD_SOURCE)
.arg("--force")
.arg(TEST_HELLO_WORLD_DEST)
.run();
println!("{:?}", result.stderr);
println!("{:?}", result.stdout);
assert!(result.success);
assert_eq!(at.read(TEST_HELLO_WORLD_DEST), "Hello, World!\n");
}
/// TODO: write a better test that differentiates --remove-destination
/// from --force. Also this test currently doesn't work on
/// Windows. This test originally checked file timestamps, which
/// proved to be unreliable per target / CI platform
#[test]
#[cfg(not(windows))]
fn test_cp_arg_remove_destination() {
let (at, mut ucmd) = at_and_ucmd!();
// create dest without write permissions
let mut permissions = at
.make_file(TEST_HELLO_WORLD_DEST)
.metadata()
.unwrap()
.permissions();
permissions.set_readonly(true);
set_permissions(at.plus(TEST_HELLO_WORLD_DEST), permissions).unwrap();
let result = ucmd
.arg(TEST_HELLO_WORLD_SOURCE)
.arg("--remove-destination")
.arg(TEST_HELLO_WORLD_DEST)
.run();
assert!(result.success);
assert_eq!(at.read(TEST_HELLO_WORLD_DEST), "Hello, World!\n");
}
#[test]
fn test_cp_arg_backup() {
let (at, mut ucmd) = at_and_ucmd!();
let result = ucmd
.arg(TEST_HELLO_WORLD_SOURCE)
.arg("--backup")
.arg(TEST_HOW_ARE_YOU_SOURCE)
.run();
assert!(result.success);
assert_eq!(at.read(TEST_HOW_ARE_YOU_SOURCE), "Hello, World!\n");
assert_eq!(
at.read(&*format!("{}~", TEST_HOW_ARE_YOU_SOURCE)),
"How are you?\n"
);
}
#[test]
fn test_cp_arg_suffix() {
let (at, mut ucmd) = at_and_ucmd!();
let result = ucmd
.arg(TEST_HELLO_WORLD_SOURCE)
.arg("--suffix")
.arg(".bak")
.arg(TEST_HOW_ARE_YOU_SOURCE)
.run();
assert!(result.success);
assert_eq!(at.read(TEST_HOW_ARE_YOU_SOURCE), "Hello, World!\n");
assert_eq!(
at.read(&*format!("{}.bak", TEST_HOW_ARE_YOU_SOURCE)),
"How are you?\n"
);
}