Skip to content

Commit bac7f7e

Browse files
fix(tests): seed tempfile's name generator per process (#4693)
1 parent c60d061 commit bac7f7e

71 files changed

Lines changed: 429 additions & 377 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎Cargo.lock‎

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎Cargo.toml‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,9 @@ petname = { version = "=3.2.0", default-features = false, features = ["default-w
272272
petname-macros = "=3.2.0"
273273

274274
tempfile = "3.27"
275+
# The generator tempfile names come from; the test helpers seed it per
276+
# process (`testing::temp_builder`, #4692).
277+
fastrand = "2.1.1"
275278

276279
# Timed waits on child processes (`Cmd::timeout`, `Cmd::delayed_stream`, the
277280
# picker's pager). Replaced `wait-timeout`, whose SIGCHLD handler aborts the

‎clippy.toml‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# tempfile's own random names collide across concurrently started test
2+
# processes (#4692); the suite's helpers seed the name generator per process.
3+
# Production code keeps these constructors and opts out at the call site.
4+
disallowed-methods = [
5+
{ path = "tempfile::tempdir", reason = "use worktrunk::testing::tempdir (#4692)" },
6+
{ path = "tempfile::TempDir::new", reason = "use worktrunk::testing::tempdir (#4692)" },
7+
{ path = "tempfile::NamedTempFile::new", reason = "use worktrunk::testing::named_tempfile (#4692)" },
8+
]

‎src/cache.rs‎

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,6 @@ pub fn count_json_files(dir: &Path) -> usize {
218218
#[cfg(test)]
219219
mod tests {
220220
use super::*;
221-
use tempfile::TempDir;
222221

223222
#[derive(serde::Serialize, serde::Deserialize, PartialEq, Debug)]
224223
struct V {
@@ -227,7 +226,7 @@ mod tests {
227226

228227
#[test]
229228
fn test_read_write_roundtrip() {
230-
let tmp = TempDir::new().unwrap();
229+
let tmp = crate::testing::tempdir().unwrap();
231230
let path = tmp.path().join("sub/entry.json");
232231

233232
// Missing file is a miss.
@@ -240,22 +239,22 @@ mod tests {
240239

241240
#[test]
242241
fn test_read_corrupt_json_returns_none() {
243-
let tmp = TempDir::new().unwrap();
242+
let tmp = crate::testing::tempdir().unwrap();
244243
let path = tmp.path().join("bad.json");
245244
fs::write(&path, "not json {{").unwrap();
246245
assert!(read_json::<V>(&path).is_none());
247246
}
248247

249248
#[test]
250249
fn test_clear_one_missing_returns_false() {
251-
let tmp = TempDir::new().unwrap();
250+
let tmp = crate::testing::tempdir().unwrap();
252251
let path = tmp.path().join("nope.json");
253252
assert!(!clear_one(&path).unwrap());
254253
}
255254

256255
#[test]
257256
fn test_clear_one_propagates_non_not_found() {
258-
let tmp = TempDir::new().unwrap();
257+
let tmp = crate::testing::tempdir().unwrap();
259258
// Put a directory where a file is expected so remove_file returns
260259
// EISDIR (or similar), not NotFound.
261260
let path = tmp.path().join("dir.json");
@@ -266,7 +265,7 @@ mod tests {
266265

267266
#[test]
268267
fn test_clear_json_files_counts_and_skips() {
269-
let tmp = TempDir::new().unwrap();
268+
let tmp = crate::testing::tempdir().unwrap();
270269
let dir = tmp.path().join("c");
271270
fs::create_dir_all(&dir).unwrap();
272271
fs::write(dir.join("a.json"), "{}").unwrap();
@@ -284,13 +283,13 @@ mod tests {
284283

285284
#[test]
286285
fn test_clear_json_files_missing_dir_is_zero() {
287-
let tmp = TempDir::new().unwrap();
286+
let tmp = crate::testing::tempdir().unwrap();
288287
assert_eq!(clear_json_files(&tmp.path().join("nope")).unwrap(), 0);
289288
}
290289

291290
#[test]
292291
fn test_clear_json_files_propagates_read_dir_error() {
293-
let tmp = TempDir::new().unwrap();
292+
let tmp = crate::testing::tempdir().unwrap();
294293
// Put a file where a directory is expected — read_dir returns
295294
// NotADirectory (not NotFound).
296295
let path = tmp.path().join("not-a-dir");
@@ -301,7 +300,7 @@ mod tests {
301300

302301
#[test]
303302
fn test_count_json_files() {
304-
let tmp = TempDir::new().unwrap();
303+
let tmp = crate::testing::tempdir().unwrap();
305304
let dir = tmp.path().join("c");
306305
fs::create_dir_all(&dir).unwrap();
307306
fs::write(dir.join("a.json"), "{}").unwrap();
@@ -313,7 +312,7 @@ mod tests {
313312

314313
#[test]
315314
fn test_sweep_lru_trims_oldest_entries() {
316-
let tmp = TempDir::new().unwrap();
315+
let tmp = crate::testing::tempdir().unwrap();
317316
let dir = tmp.path().join("c");
318317
fs::create_dir_all(&dir).unwrap();
319318

@@ -335,7 +334,7 @@ mod tests {
335334

336335
#[test]
337336
fn test_sweep_lru_no_op_under_bound() {
338-
let tmp = TempDir::new().unwrap();
337+
let tmp = crate::testing::tempdir().unwrap();
339338
let dir = tmp.path().join("c");
340339
fs::create_dir_all(&dir).unwrap();
341340

‎src/command_log.rs‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ mod tests {
225225

226226
#[test]
227227
fn test_write_creates_file_lazily() {
228-
let dir = tempfile::tempdir().unwrap();
228+
let dir = crate::testing::tempdir().unwrap();
229229
let mut logger = CommandLog::new(dir.path(), "wt test");
230230

231231
assert!(!dir.path().join("commands.jsonl").exists());
@@ -242,7 +242,7 @@ mod tests {
242242

243243
#[test]
244244
fn test_write_tolerates_unavailable_log_directory() {
245-
let dir = tempfile::tempdir().unwrap();
245+
let dir = crate::testing::tempdir().unwrap();
246246
let blocked = dir.path().join("not-a-directory");
247247
fs::write(&blocked, "preserved contents").unwrap();
248248
let mut logger = CommandLog::new(&blocked, "wt test");
@@ -255,7 +255,7 @@ mod tests {
255255

256256
#[test]
257257
fn test_write_appends_multiple_entries() {
258-
let dir = tempfile::tempdir().unwrap();
258+
let dir = crate::testing::tempdir().unwrap();
259259
let mut logger = CommandLog::new(dir.path(), "wt test");
260260

261261
logger.write("a", "cmd-a", Some(0), Some(Duration::from_millis(1)));
@@ -273,7 +273,7 @@ mod tests {
273273

274274
#[test]
275275
fn test_rotation_at_size_limit() {
276-
let dir = tempfile::tempdir().unwrap();
276+
let dir = crate::testing::tempdir().unwrap();
277277
let log_path = dir.path().join("commands.jsonl");
278278

279279
// Write a file just over MAX_LOG_SIZE

‎src/commands/backup.rs‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ mod tests {
165165

166166
#[test]
167167
fn test_back_up_clobbered_path_moves_to_fresh_suffix() {
168-
let temp = tempfile::tempdir().unwrap();
168+
let temp = worktrunk::testing::tempdir().unwrap();
169169
let stale = temp.path().join("feature");
170170
std::fs::create_dir(&stale).unwrap();
171171
std::fs::write(stale.join("file"), "content").unwrap();
@@ -182,7 +182,7 @@ mod tests {
182182

183183
#[test]
184184
fn test_back_up_clobbered_path_falls_back_when_suffix_taken() {
185-
let temp = tempfile::tempdir().unwrap();
185+
let temp = worktrunk::testing::tempdir().unwrap();
186186
let stale = temp.path().join("feature");
187187
std::fs::create_dir(&stale).unwrap();
188188

@@ -208,7 +208,7 @@ mod tests {
208208
// A missing source fails the rename with a non-AlreadyExists error,
209209
// which surfaces (with the "Failed to move" context) rather than being
210210
// retried.
211-
let temp = tempfile::tempdir().unwrap();
211+
let temp = worktrunk::testing::tempdir().unwrap();
212212
let missing = temp.path().join("does-not-exist");
213213
let err = back_up_clobbered_path(&missing, "20250101-000000").unwrap_err();
214214
assert!(
@@ -221,7 +221,7 @@ mod tests {
221221
fn test_back_up_clobbered_path_keeps_incrementing_past_many_collisions() {
222222
// There is no attempt cap: the move keeps counting up until a free
223223
// name is found, however many backups already exist.
224-
let temp = tempfile::tempdir().unwrap();
224+
let temp = worktrunk::testing::tempdir().unwrap();
225225
let stale = temp.path().join("feature");
226226
std::fs::create_dir(&stale).unwrap();
227227

@@ -239,7 +239,7 @@ mod tests {
239239

240240
#[test]
241241
fn test_back_up_clobbered_path_now_uses_timestamped_suffix() {
242-
let temp = tempfile::tempdir().unwrap();
242+
let temp = worktrunk::testing::tempdir().unwrap();
243243
let stale = temp.path().join("feature");
244244
std::fs::create_dir(&stale).unwrap();
245245

‎src/commands/command_executor.rs‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -928,7 +928,10 @@ mod tests {
928928

929929
#[test]
930930
fn test_hook_spawn_failure_retains_io_error_and_has_no_child_exit_code() {
931-
let missing = tempfile::tempdir().unwrap().path().join("missing-cwd");
931+
let missing = worktrunk::testing::tempdir()
932+
.unwrap()
933+
.path()
934+
.join("missing-cwd");
932935
let shell = worktrunk::shell_exec::ShellConfig::get().unwrap();
933936
let error = worktrunk::shell_exec::Cmd::new(shell.executable.to_string_lossy())
934937
.current_dir(&missing)

0 commit comments

Comments
 (0)