Skip to content

Commit 38aacab

Browse files
CopilotKSXGitHub
andcommitted
test(hardlink): add test proving device number is used in deduplication key
Co-authored-by: KSXGitHub <11488886+KSXGitHub@users.noreply.github.com>
1 parent ed6162e commit 38aacab

1 file changed

Lines changed: 35 additions & 0 deletions

File tree

src/hardlink/hardlink_list/test.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,3 +148,38 @@ fn detect_number_of_links_change() {
148148
});
149149
assert_eq!(actual, expected);
150150
}
151+
152+
/// Files on different devices may share the same inode number, but they are
153+
/// unrelated — hardlinks cannot span filesystem boundaries. Verify that two
154+
/// files with the same inode number but different device numbers produce
155+
/// separate entries in the list (i.e. the device number is actually used in
156+
/// the deduplication key).
157+
#[test]
158+
fn same_ino_on_different_devices_are_treated_separately() {
159+
let list = HardlinkList::<Bytes>::new();
160+
161+
// dev=1, ino=100 — first filesystem
162+
list.add(100.into(), 1, 50.into(), 2, "dev1/file_a".as_ref())
163+
.expect("add dev1/file_a");
164+
list.add(100.into(), 1, 50.into(), 2, "dev1/file_b".as_ref())
165+
.expect("add dev1/file_b (same dev+ino → same inode group)");
166+
167+
// dev=2, ino=100 — second filesystem, coincidentally same inode number
168+
list.add(100.into(), 2, 80.into(), 2, "dev2/file_c".as_ref())
169+
.expect("add dev2/file_c (different dev → separate inode group)");
170+
list.add(100.into(), 2, 80.into(), 2, "dev2/file_d".as_ref())
171+
.expect("add dev2/file_d (same dev+ino → same inode group as file_c)");
172+
173+
// Each device should produce its own entry, so the list should have 2 entries.
174+
assert_eq!(list.len(), 2, "expected one entry per (dev, ino) pair");
175+
176+
let reflection = list.into_reflection();
177+
// Both entries expose ino=100 in the reflection (device is not part of the
178+
// public JSON format), so there are still 2 entries in the vector.
179+
assert_eq!(reflection.len(), 2);
180+
181+
// Paths are grouped per (dev, ino): each group has exactly 2 paths.
182+
for entry in reflection.iter() {
183+
assert_eq!(entry.paths.len(), 2);
184+
}
185+
}

0 commit comments

Comments
 (0)