#![allow(clippy::expect_used)]
mod common;
use common::{ELF_HEADER, create_data_file, path_str, rmagic_cmd, symlink_or_skip};
use predicates::prelude::*;
use std::fs;
use tempfile::TempDir;
#[test]
fn test_directory_is_classified_not_reported_as_an_error() {
let temp_dir = TempDir::new().expect("Failed to create temp dir");
let dir = temp_dir.path().join("realdir");
fs::create_dir_all(&dir).expect("Failed to create dir");
rmagic_cmd()
.args(["--use-builtin", path_str(&dir)])
.assert()
.success()
.stdout(predicate::str::contains("directory"))
.stderr(predicate::str::is_empty());
}
#[test]
fn test_directory_with_strict_exits_zero() {
let temp_dir = TempDir::new().expect("Failed to create temp dir");
let dir = temp_dir.path().join("realdir");
fs::create_dir_all(&dir).expect("Failed to create dir");
rmagic_cmd()
.args(["--use-builtin", "--strict", path_str(&dir)])
.assert()
.success()
.stdout(predicate::str::contains("directory"));
}
#[test]
fn test_symlink_to_directory_classifies_as_directory_by_default() {
let temp_dir = TempDir::new().expect("Failed to create temp dir");
let dir = temp_dir.path().join("realdir");
fs::create_dir_all(&dir).expect("Failed to create dir");
let link = temp_dir.path().join("dir.link");
if !symlink_or_skip(
&dir,
&link,
"test_symlink_to_directory_classifies_as_directory_by_default",
) {
return;
}
rmagic_cmd()
.args(["--use-builtin", path_str(&link)])
.assert()
.success()
.stdout(predicate::str::contains("directory"))
.stdout(predicate::str::contains("symbolic link").not());
}
#[test]
fn test_directory_and_regular_file_in_one_invocation() {
let temp_dir = TempDir::new().expect("Failed to create temp dir");
let dir = temp_dir.path().join("realdir");
fs::create_dir_all(&dir).expect("Failed to create dir");
let regular = create_data_file(&temp_dir, "real.elf", ELF_HEADER);
rmagic_cmd()
.args(["--use-builtin", path_str(&dir), path_str(®ular)])
.assert()
.success()
.stdout(predicate::str::contains("directory"))
.stdout(predicate::str::contains("ELF"))
.stdout(predicate::str::contains("realdir:"));
}
#[test]
fn test_directory_json_output_is_coherent() {
let temp_dir = TempDir::new().expect("Failed to create temp dir");
let dir = temp_dir.path().join("realdir");
fs::create_dir_all(&dir).expect("Failed to create dir");
rmagic_cmd()
.args(["--use-builtin", "--json", path_str(&dir)])
.assert()
.success()
.stdout(predicate::str::contains("\"matches\""))
.stdout(predicate::str::contains("directory"));
}
fn relative_elf_link_paths(temp_dir: &TempDir) -> (std::path::PathBuf, std::path::PathBuf) {
create_data_file(temp_dir, "real.elf", ELF_HEADER);
(
std::path::PathBuf::from("real.elf"),
temp_dir.path().join("valid.link"),
)
}
#[test]
fn test_no_dereference_reports_the_link_itself() {
let temp_dir = TempDir::new().expect("Failed to create temp dir");
let (target, link) = relative_elf_link_paths(&temp_dir);
if !symlink_or_skip(
&target,
&link,
"test_no_dereference_reports_the_link_itself",
) {
return;
}
rmagic_cmd()
.args(["--use-builtin", "--no-dereference", path_str(&link)])
.assert()
.success()
.stdout(predicate::str::contains("symbolic link to real.elf"))
.stdout(predicate::str::contains("ELF").not());
}
#[test]
fn test_no_dereference_keeps_the_broken_prefix() {
let temp_dir = TempDir::new().expect("Failed to create temp dir");
let link = temp_dir.path().join("dangling.link");
if !symlink_or_skip(
std::path::Path::new("missing.txt"),
&link,
"test_no_dereference_keeps_the_broken_prefix",
) {
return;
}
rmagic_cmd()
.args(["--use-builtin", "--no-dereference", path_str(&link)])
.assert()
.success()
.stdout(predicate::str::contains(
"broken symbolic link to missing.txt",
));
}
#[test]
fn test_no_dereference_on_symlink_to_directory_reports_the_link() {
let temp_dir = TempDir::new().expect("Failed to create temp dir");
let dir = temp_dir.path().join("realdir");
fs::create_dir_all(&dir).expect("Failed to create dir");
let link = temp_dir.path().join("dir.link");
if !symlink_or_skip(
&dir,
&link,
"test_no_dereference_on_symlink_to_directory_reports_the_link",
) {
return;
}
rmagic_cmd()
.args(["--use-builtin", "--no-dereference", path_str(&link)])
.assert()
.success()
.stdout(predicate::str::contains("symbolic link to"))
.stdout(predicate::str::contains("realdir"));
}
#[test]
fn test_dereference_flag_is_a_no_op_matching_the_default() {
let temp_dir = TempDir::new().expect("Failed to create temp dir");
let target = create_data_file(&temp_dir, "real.elf", ELF_HEADER);
let link = temp_dir.path().join("valid.link");
if !symlink_or_skip(
&target,
&link,
"test_dereference_flag_is_a_no_op_matching_the_default",
) {
return;
}
for args in [
vec!["--use-builtin", path_str(&link)],
vec!["--use-builtin", "-L", path_str(&link)],
] {
rmagic_cmd()
.args(&args)
.assert()
.success()
.stdout(predicate::str::contains("ELF"));
}
}
#[test]
fn test_dereference_flags_are_last_one_wins() {
let temp_dir = TempDir::new().expect("Failed to create temp dir");
let (target, link) = relative_elf_link_paths(&temp_dir);
if !symlink_or_skip(&target, &link, "test_dereference_flags_are_last_one_wins") {
return;
}
rmagic_cmd()
.args(["--use-builtin", "--no-dereference", "-L", path_str(&link)])
.assert()
.success()
.stdout(predicate::str::contains("ELF"));
rmagic_cmd()
.args(["--use-builtin", "-L", "--no-dereference", path_str(&link)])
.assert()
.success()
.stdout(predicate::str::contains("symbolic link to real.elf"));
}
#[test]
fn test_no_dereference_leaves_non_symlink_paths_alone() {
let temp_dir = TempDir::new().expect("Failed to create temp dir");
let regular = create_data_file(&temp_dir, "real.elf", ELF_HEADER);
let dir = temp_dir.path().join("realdir");
fs::create_dir_all(&dir).expect("Failed to create dir");
rmagic_cmd()
.args(["--use-builtin", "--no-dereference", path_str(®ular)])
.assert()
.success()
.stdout(predicate::str::contains("ELF"));
rmagic_cmd()
.args(["--use-builtin", "--no-dereference", path_str(&dir)])
.assert()
.success()
.stdout(predicate::str::contains("directory"));
}
#[test]
fn test_no_dereference_renders_an_absolute_target_verbatim() {
let temp_dir = TempDir::new().expect("Failed to create temp dir");
let target = create_data_file(&temp_dir, "real.elf", ELF_HEADER);
let link = temp_dir.path().join("abs.link");
if !symlink_or_skip(
&target,
&link,
"test_no_dereference_renders_an_absolute_target_verbatim",
) {
return;
}
rmagic_cmd()
.args(["--use-builtin", "--no-dereference", path_str(&link)])
.assert()
.success()
.stdout(predicate::str::contains(format!(
"symbolic link to {}",
path_str(&target)
)));
}
#[test]
fn test_no_dereference_on_a_valid_link_with_strict_exits_zero() {
let temp_dir = TempDir::new().expect("Failed to create temp dir");
let (target, link) = relative_elf_link_paths(&temp_dir);
if !symlink_or_skip(
&target,
&link,
"test_no_dereference_on_a_valid_link_with_strict_exits_zero",
) {
return;
}
rmagic_cmd()
.args([
"--use-builtin",
"--no-dereference",
"--strict",
path_str(&link),
])
.assert()
.success()
.stdout(predicate::str::contains("symbolic link to real.elf"));
}
#[test]
fn test_help_flags_are_unchanged() {
for flag in ["-h", "--help"] {
rmagic_cmd()
.arg(flag)
.assert()
.success()
.stdout(predicate::str::contains("Usage"))
.stdout(predicate::str::contains("--no-dereference"));
}
}