From 434fc29ab867d630185b632a43e82513ac918fe5 Mon Sep 17 00:00:00 2001 From: Hermes Agent Date: Wed, 12 Aug 2026 03:27:18 +0000 Subject: Preserve hardlinks in native tar archives --- tests/archive.rs | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) (limited to 'tests') diff --git a/tests/archive.rs b/tests/archive.rs index 3956849..e31b65a 100644 --- a/tests/archive.rs +++ b/tests/archive.rs @@ -47,6 +47,56 @@ fn writes_deterministic_tar_with_files_directories_and_symlinks() { ); } +#[test] +fn preserves_hardlinks_in_the_archive() { + use std::os::unix::fs::MetadataExt; + + let fixture = tempdir().expect("fixture directory"); + let rootfs = fixture.path().join("rootfs"); + fs::create_dir_all(rootfs.join("usr/bin")).expect("create rootfs tree"); + let original = rootfs.join("usr/bin/controller"); + let alias = rootfs.join("usr/bin/controller-link"); + fs::write(&original, "controller\n").expect("write controller"); + fs::hard_link(&original, &alias).expect("create hardlink"); + assert_eq!( + fs::metadata(&original).expect("stat original").ino(), + fs::metadata(&alias).expect("stat alias").ino() + ); + + let artifact = fixture.path().join("controller.tar"); + NativeTarWriter::new() + .write(&rootfs, &artifact) + .expect("write archive"); + + let mut archive = Archive::new(fs::File::open(artifact).expect("open archive")); + let entries = archive + .entries() + .expect("read archive entries") + .map(|entry| { + let entry = entry.expect("read entry"); + ( + entry.path().expect("entry path").into_owned(), + entry.header().entry_type(), + entry.link_name().expect("entry link name").map(|path| path.into_owned()), + ) + }) + .collect::>(); + + assert_eq!( + entries, + vec![ + ("usr".into(), tar::EntryType::Directory, None), + ("usr/bin".into(), tar::EntryType::Directory, None), + ("usr/bin/controller".into(), tar::EntryType::Regular, None), + ( + "usr/bin/controller-link".into(), + tar::EntryType::Link, + Some("usr/bin/controller".into()) + ), + ] + ); +} + #[test] fn rejects_a_missing_rootfs() { let fixture = tempdir().expect("fixture directory"); -- cgit v1.2.3