Skip to content

Test temp dirs have no lifecycle owner — 11,345 entries / 14 GB over 10 days #85

Description

@iceteaSA

Test-suite temp dirs have no lifecycle owner: 11,345 entries / 14 GB accumulated over 10 days on one box.

Line numbers below are against 20029b3d.

Creator

unique_project_rootcrates/subc-core/src/control.rs:4424-4435:

fn unique_project_root(label: &str) -> std::path::PathBuf {
    let path = std::env::temp_dir().join(format!(
        "subc-control-{label}-{}-{:?}",
        std::process::id(),
        SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_nanos()
    ));
    std::fs::create_dir_all(&path).unwrap();
    path
}

Per-call unique name (pid + nanos) in a shared location, returning a bare PathBuf. 11 call sites in that file. The same shape appears at 37 env::temp_dir() sites across the test tree (watchdog.rs:479, forwarding.rs:6308, catalog_update.rs:717, supervision.rs:384, …).

Absent cleanup

  • remove_dir_all occurrences in control.rs: 0 — none of the 11 callers remove what they created.
  • tempfile in any crate manifest: 0 — so there is no Drop-based guard anywhere.

The second point is the mechanism rather than a style note. Cleanup written at the end of a test body does not run when the test fails, because a panic unwinds past it. Only Drop survives unwinding. So the accumulation rate is highest exactly when the suite is red — which is when the suite gets run repeatedly.

Measured

subc-client-rs-*     5331
subc-control-*       3596
subc-core-*          2148
fake-aft-stub-copy*   254
                    ─────
                    11345 entries   (40% of /tmp on this box)

oldest  2026-08-20 14:02
newest  2026-08-30 01:09

du -shc /tmp/fake-aft-stub-copy-*   →  14G

The 14 GB is the part that matters: fake-aft-stub-copy-* are real binary copies, not empty marker dirs.

Scope — the daemon is clean

This is test-only. I checked the non-test temp_dir() users before filing, and the one that could have leaked does not: unix_uid_token (crates/subc-core/src/bootstrap.rs:918-938) creates .subc-uid-probe-{pid}-{nonce} and removes it at :933. Measured: 0 leaked probe files in /tmp. bootstrap.rs:325 / :1252 use a stable connection-file name, not a per-call one.

So nothing here affects a running daemon or a deployed module. It is CI and developer disk cost.

Attribution

Most of this is mine. The window matches my gate runs — I have run cargo test --workspace on this box many times over those ten days while iterating on #82. The suite has no artifact lifecycle, and the seat running the gates hardest is the one that finds out.

Suggested fix

Adopt tempfile::TempDir (dev-dependency) for the test helpers, so cleanup is a Drop and survives a failing test. unique_project_root and the fake_aft_stub_path copy sites are the two that pay for themselves immediately — 254 stub copies are the 14 GB.

Happy to do this as a PR if you want it; it is mechanical but touches a lot of test files, so I would rather have your preference on scope (all 37 sites vs the two that dominate) before writing it.

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