Skip to content

Commit 1402afb

Browse files
committed
test: complex tree
1 parent 0f9ea89 commit 1402afb

1 file changed

Lines changed: 62 additions & 0 deletions

File tree

tests/deduplicate_hardlinks.rs

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,3 +109,65 @@ fn multiple_hardlinks_to_a_single_file_without_deduplication() {
109109

110110
assert_eq!(actual_size, expected_size);
111111
}
112+
113+
#[test]
114+
fn complex_tree_with_shared_and_unique_files_with_deduplication() {
115+
let files_per_branch = 255;
116+
let workspace =
117+
SampleWorkspace::complex_tree_with_shared_and_unique_files(files_per_branch, 100_000);
118+
119+
let tree = Command::new(PDU)
120+
.with_current_dir(&workspace)
121+
.with_arg("--min-ratio=0")
122+
.with_arg("--quantity=apparent-size")
123+
.with_arg("--deduplicate-hardlinks")
124+
.with_arg("--json-output")
125+
.pipe(stdio)
126+
.output()
127+
.expect("spawn command")
128+
.pipe(stdout_text)
129+
.pipe_as_ref(serde_json::from_str::<JsonData>)
130+
.expect("parse stdout as JsonData")
131+
.body
132+
.pipe(JsonTree::<Bytes>::try_from)
133+
.expect("get tree of bytes");
134+
135+
let actual_size = tree.size;
136+
137+
let file_size = workspace
138+
.join("no-hardlinks/file-0.txt")
139+
.pipe_as_ref(read_apparent_size)
140+
.pipe(Bytes::new);
141+
142+
let inode_size = |path: &str| {
143+
workspace
144+
.join(path)
145+
.pipe_as_ref(read_apparent_size)
146+
.pipe(Bytes::new)
147+
};
148+
149+
// The following formula treat the first file as "real" and
150+
// the non-first file with the same inode as "fake" for ease
151+
// of reasoning.
152+
// It should still produce the same result as the proper
153+
// deduplication formula however.
154+
#[expect(clippy::erasing_op)]
155+
let expected_size: Bytes = [
156+
inode_size("."),
157+
inode_size("no-hardlinks"),
158+
inode_size("some-hardlinks"),
159+
inode_size("only-hardlinks"),
160+
inode_size("only-hardlinks/exclusive"),
161+
inode_size("only-hardlinks/mixed"),
162+
inode_size("only-hardlinks/external"),
163+
file_size * files_per_branch, // no-hardlinks/*
164+
file_size * files_per_branch, // some-hardlinks/*
165+
file_size * files_per_branch, // only-hardlinks/exclusive/*
166+
file_size * files_per_branch, // only-hardlinks/mixed/*
167+
file_size * 0usize, // only-hardlinks/external/*
168+
]
169+
.into_iter()
170+
.sum();
171+
172+
assert_eq!(actual_size, expected_size);
173+
}

0 commit comments

Comments
 (0)