Fix install: invalid link at destination

also remove some FixMEs for FreeBsd
This commit is contained in:
Ulrich Hornung 2024-02-24 17:19:25 +01:00
parent b34d410ade
commit 7cd754eb1f
No known key found for this signature in database
GPG key ID: 64EA3BAAF1BC0603
3 changed files with 769 additions and 10 deletions

View file

@ -748,6 +748,18 @@ fn perform_backup(to: &Path, b: &Behavior) -> UResult<Option<PathBuf>> {
/// Returns an empty Result or an error in case of failure.
///
fn copy_file(from: &Path, to: &Path) -> UResult<()> {
// fs::copy fails if destination is a invalid symlink.
// so lets just remove all existing files at destination before copy.
if let Err(e) = fs::remove_file(to) {
if e.kind() != std::io::ErrorKind::NotFound {
show_error!(
"Failed to remove existing file {}. Error: {:?}",
to.display(),
e
);
}
}
if from.as_os_str() == "/dev/null" {
/* workaround a limitation of fs::copy
* https://github.com/rust-lang/rust/issues/79390

View file

@ -8,7 +8,7 @@ use crate::common::util::{is_ci, run_ucmd_as_root, TestScenario};
use filetime::FileTime;
use std::fs;
use std::os::unix::fs::{MetadataExt, PermissionsExt};
#[cfg(not(any(windows, target_os = "freebsd")))]
#[cfg(not(windows))]
use std::process::Command;
#[cfg(any(target_os = "linux", target_os = "android"))]
use std::thread::sleep;
@ -610,13 +610,17 @@ fn test_install_copy_then_compare_file_with_extra_mode() {
}
const STRIP_TARGET_FILE: &str = "helloworld_installed";
#[cfg(not(any(windows, target_os = "freebsd")))]
#[cfg(all(not(windows), not(target_os = "freebsd")))]
const SYMBOL_DUMP_PROGRAM: &str = "objdump";
#[cfg(not(any(windows, target_os = "freebsd")))]
#[cfg(target_os = "freebsd")]
const SYMBOL_DUMP_PROGRAM: &str = "llvm-objdump";
#[cfg(not(windows))]
const STRIP_SOURCE_FILE_SYMBOL: &str = "main";
fn strip_source_file() -> &'static str {
if cfg!(target_os = "macos") {
if cfg!(target_os = "freebsd") {
"helloworld_freebsd"
} else if cfg!(target_os = "macos") {
"helloworld_macos"
} else if cfg!(target_arch = "arm") || cfg!(target_arch = "aarch64") {
"helloworld_android"
@ -626,8 +630,7 @@ fn strip_source_file() -> &'static str {
}
#[test]
// FixME: Freebsd fails on 'No such file or directory'
#[cfg(not(any(windows, target_os = "freebsd")))]
#[cfg(not(windows))]
fn test_install_and_strip() {
let scene = TestScenario::new(util_name!());
let at = &scene.fixtures;
@ -650,8 +653,7 @@ fn test_install_and_strip() {
}
#[test]
// FixME: Freebsd fails on 'No such file or directory'
#[cfg(not(any(windows, target_os = "freebsd")))]
#[cfg(not(windows))]
fn test_install_and_strip_with_program() {
let scene = TestScenario::new(util_name!());
let at = &scene.fixtures;
@ -677,8 +679,6 @@ fn test_install_and_strip_with_program() {
#[cfg(all(unix, feature = "chmod"))]
#[test]
// FixME: Freebsd fails on 'No such file or directory'
#[cfg(not(target_os = "freebsd"))]
fn test_install_and_strip_with_program_hyphen() {
let scene = TestScenario::new(util_name!());
@ -715,6 +715,64 @@ fn test_install_and_strip_with_program_hyphen() {
.stdout_is("./-dest\n");
}
#[cfg(all(unix, feature = "chmod"))]
#[test]
fn test_install_on_invalid_link_at_destination() {
let scene = TestScenario::new(util_name!());
let at = &scene.fixtures;
at.mkdir("src");
at.mkdir("dest");
let src_dir = at.plus("src");
let dst_dir = at.plus("dest");
at.touch("test.sh");
at.symlink_file(
"/opt/FakeDestination",
&dst_dir.join("test.sh").to_string_lossy(),
);
scene.ccmd("chmod").arg("+x").arg("test.sh").succeeds();
at.symlink_file("test.sh", &src_dir.join("test.sh").to_string_lossy());
scene
.ucmd()
.current_dir(&src_dir)
.arg(src_dir.join("test.sh"))
.arg(dst_dir.join("test.sh"))
.succeeds()
.no_stderr()
.no_stdout();
}
#[cfg(all(unix, feature = "chmod"))]
#[test]
fn test_install_on_invalid_link_at_destination_and_dev_null_at_source() {
let scene = TestScenario::new(util_name!());
let at = &scene.fixtures;
at.mkdir("src");
at.mkdir("dest");
let src_dir = at.plus("src");
let dst_dir = at.plus("dest");
at.touch("test.sh");
at.symlink_file(
"/opt/FakeDestination",
&dst_dir.join("test.sh").to_string_lossy(),
);
scene.ccmd("chmod").arg("+x").arg("test.sh").succeeds();
at.symlink_file("test.sh", &src_dir.join("test.sh").to_string_lossy());
scene
.ucmd()
.current_dir(&src_dir)
.arg("/dev/null")
.arg(dst_dir.join("test.sh"))
.succeeds()
.no_stderr()
.no_stdout();
}
#[test]
#[cfg(not(windows))]
fn test_install_and_strip_with_invalid_program() {

689
tests/fixtures/install/helloworld_freebsd vendored Executable file

File diff suppressed because one or more lines are too long