Skip to content

Tests std::mem::forget tempdirs — leaks per test run #273

Description

@lovebear2008

In crates/forkd-controller/src/http.rs:1480-1494, test_state does:

let td = tempfile::TempDir::new().unwrap();
let path = td.path().join("state.json");
let snapshot_root = td.path().join("snapshots");
// Leak the TempDir so it survives the test (Drop deletes the dir).
std::mem::forget(td);

The same pattern is repeated in branch_slot_global_cap_blocks (1630-1641) and branch_slot_capacity_recovers_on_drop (1652-1662).

The comment explains the motivation ("survive the test") but the result is that every cargo test run leaves N orphan directories in $TMPDIR per worker. tempfile::TempDir's default location is /tmp on Linux, which is usually tmpfs — so the leak is bounded by reboot, but on CI the cargo test cache can accumulate hundreds of these between runs.

Better shapes

  • Bind the TempDir to a 'static location via tempfile::tempdir_in() plus a one-shot OnceCell, so all tests in the file share one cleanup root that's reaped on process exit.
  • Or move the leak to a Drop impl on a wrapper that calls remove_dir_all on the leaked path. axum-test patterns usually use this approach.
  • Cheapest: keep the TempDir alive by binding it to the returned SharedState (add a field). Drop of AppState then triggers Drop of the TempDir, no leak.

This came up while running the test suite locally — ls /tmp/.tmp* | wc -l jumped by ~10 per cargo test -p forkd-controller.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions