Skip to content

Commit 470a325

Browse files
committed
test: prepare some functions
1 parent 2d0e08e commit 470a325

1 file changed

Lines changed: 124 additions & 0 deletions

File tree

tests/_utils.rs

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,130 @@ impl SampleWorkspace {
116116

117117
SampleWorkspace(temp)
118118
}
119+
120+
/// Set up a temporary directory for tests.
121+
///
122+
/// The tree in this tests have a diverse types of files, both shared (hardlinks)
123+
/// and unique (non-hardlinks).
124+
pub fn complex_tree_with_shared_and_unique_files(
125+
files_per_branch: usize,
126+
bytes_per_file: usize,
127+
) -> Self {
128+
use std::fs::{create_dir_all, hard_link, write as write_file};
129+
130+
let whole = files_per_branch;
131+
let half = files_per_branch / 2;
132+
let quarter = files_per_branch / 4;
133+
let half_quarter = files_per_branch / 8;
134+
let temp = Temp::new_dir().expect("create working directory for sample workspace");
135+
136+
temp.join("no-hardlinks")
137+
.pipe(create_dir_all)
138+
.expect("create no-hardlinks");
139+
temp.join("some-hardlinks")
140+
.pipe(create_dir_all)
141+
.expect("create some-hardlinks");
142+
temp.join("only-hardlinks/exclusive")
143+
.pipe(create_dir_all)
144+
.expect("create only-hardlinks/exclusive");
145+
temp.join("only-hardlinks/mixed")
146+
.pipe(create_dir_all)
147+
.expect("create only-hardlinks/mixed");
148+
temp.join("only-hardlinks/external")
149+
.pipe(create_dir_all)
150+
.expect("create only-hardlinks/external");
151+
152+
// Create files in no-hardlinks.
153+
// There will be no files with nlink > 1.
154+
(0..files_per_branch).par_bridge().for_each(|index| {
155+
let file_name = format!("file-{index}.txt");
156+
let file_path = temp.join("no-hardlinks").join(file_name);
157+
if let Err(error) = write_file(&file_path, "a".repeat(bytes_per_file)) {
158+
panic!("Failed to write {bytes_per_file} bytes into {file_path:?}: {error}");
159+
}
160+
});
161+
162+
// Create files in some-hardlinks.
163+
// Let's divide the files into 8 equal groups.
164+
// Each file in the first group will have 2 exclusive links.
165+
// Each file in the second group will have 1 exclusive link.
166+
// Each file in the third and fourth groups will have no links.
167+
// Each file in the remaining groups is PLANNED to have 1 external link from only-hardlinks/mixed.
168+
(0..whole).par_bridge().for_each(|file_index| {
169+
let file_name = format!("file-{file_index}.txt");
170+
let file_path = temp.join("some-hardlinks").join(file_name);
171+
if let Err(error) = write_file(&file_path, "a".repeat(bytes_per_file)) {
172+
panic!("Failed to write {bytes_per_file} bytes into {file_path:?}: {error}");
173+
}
174+
175+
let link_count =
176+
((file_index < quarter) as usize) + ((file_index < half_quarter) as usize);
177+
178+
for link_index in 0..link_count {
179+
let link_name = format!("link{link_index}-file{file_index}.txt");
180+
let link_path = temp.join("some-hardlinks").join(link_name);
181+
if let Err(error) = hard_link(&file_path, &link_path) {
182+
panic!("Failed to link {file_path:?} to {link_path:?}: {error}");
183+
}
184+
}
185+
});
186+
187+
// Create files in only-hardlinks/exclusive.
188+
// Each file in this directory will have 1 exclusive link.
189+
(0..whole).par_bridge().for_each(|index| {
190+
let file_name = format!("file-{index}.txt");
191+
let file_path = temp.join("only-hardlinks/exclusive").join(file_name);
192+
if let Err(error) = write_file(&file_path, "a".repeat(bytes_per_file)) {
193+
panic!("Failed to write {bytes_per_file} bytes into {file_path:?}: {error}");
194+
}
195+
let link_name = format!("link-{index}.txt");
196+
let link_path = temp.join("only-hardlinks/exclusive").join(link_name);
197+
if let Err(error) = hard_link(&file_path, &link_path) {
198+
panic!("Failed to link {file_path:?} to {link_path:?}: {error}");
199+
}
200+
});
201+
202+
// Create links in only-hardlinks/mixed.
203+
// Let's divide the PLANNED links into 2 equal groups.
204+
// Each link in the first group is PLANNED to shared with only-hardlinks/external.
205+
// Each link in the second group is exclusive.
206+
(half..whole).par_bridge().for_each(|index| {
207+
let file_name = format!("link0-{index}.txt");
208+
let file_path = temp.join("only-hardlinks/mixed").join(file_name);
209+
if let Err(error) = write_file(&file_path, "a".repeat(bytes_per_file)) {
210+
panic!("Failed to write {bytes_per_file} bytes to {file_path:?}: {error}");
211+
}
212+
213+
let link_name = format!("link1-{index}.txt");
214+
let link_path = temp.join("only-hardlinks/mixed").join(link_name);
215+
if let Err(error) = hard_link(&file_path, &link_path) {
216+
panic!("Failed to link {file_path:?} to {link_path:?}: {error}");
217+
}
218+
});
219+
220+
// Create links in only-hardlinks/external
221+
// Let's divide the links into 2 equal groups.
222+
// The first group will share with only-hardlinks/mixed.
223+
// The second group will share with some-hardlinks.
224+
(0..whole).par_bridge().for_each(|index| {
225+
let link_name = format!("linkX-{index}.txt");
226+
let link_path = temp.join("only-hardlinks/external").join(link_name);
227+
228+
let file_path = if index <= half {
229+
let file_name = format!("link0-{index}.txt"); // file name from only-hardlinks/mixed
230+
temp.join("only-hardlinks/mixed").join(file_name)
231+
} else {
232+
let file_name = format!("file-{index}.txt"); // file name from some-hardlinks
233+
temp.join("some-hardlinks").join(file_name)
234+
};
235+
236+
if let Err(error) = hard_link(&file_path, &link_path) {
237+
panic!("Failed to link {file_path:?} to {link_path:?}: {error}");
238+
}
239+
});
240+
241+
SampleWorkspace(temp)
242+
}
119243
}
120244

121245
/// Make the snapshot of a [`TreeReflection`] testable.

0 commit comments

Comments
 (0)