Skip to content

fix(test): the remaining hand-rolled temp dirs leak too — a named list of ~38,000 dirs across 8 prefixes #370

Description

@MichaelTaylor3d

Task

dig-node#361 fixed the temp-directory leak that took the dev machine to ENOSPC — the ~57 MB-per-node
dig-node-serve-test-* tree in crates/dig-node-service/tests/content_serve.rs. It deliberately did
not widen into the rest of the workspace.

This ticket closes the remainder, as a named finite list rather than a sweep.

Context — there is no shared helper, and that was the surprising part

#361 hypothesised a shared helper. There isn't one: every site is a hand-rolled
std::env::temp_dir().join(format!(..)), roughly 50 across the workspace, each independently
missing its cleanup. So the fix is per-site, and the list below is the whole of it.

One exception is worth knowing, because it collapses two of the ticket's rows into a single edit:
dig-node-auth* and dig-node-custody* are both produced by the same function
crates/dig-node-core/src/peer.rs's fresh_pool_handle_on(tag, ..), building
dig-node-{tag}-{pid}.

The list

prefix file note
dig-node-test-* crates/dig-node-service/tests/server.rs (4 sites) 0.77 GB / 6,701 dirs — the only remaining one with real bytes. base outlives the block that creates it (state is returned from it), so a guard needs a signature change on those helpers, not just a TempDir
dig-node-dual-*, dig-node-dualstack-* crates/dig-node-service/tests/server.rs pid-only, one dir per process
dig-node-{tag}-* (auth, custody, bootstrap, wuc, wuc-share) crates/dig-node-core/src/peer.rs ~12,500 dirs between them; the returned GossipHandle uses the cert files for its lifetime, so the guard has to be held by the caller
dig-tip-* (9,898 dirs) crates/dig-wallet/src/sage/tipping.rs
dig-wallet-sup-* (3,659) crates/dig-wallet/src/sage/sync_supervisor/tests.rs
dig-wallet-svc-* (1,354) crates/dig-wallet/src/sage/service.rs
dig-wallet-rpc-authgate-* (2,585) crates/dig-wallet/src/sage/rpc.rs
dig-watchlist-* crates/dig-wallet/src/sage/watchlist.rs

Roughly 38,000 directories in total. Bytes are near zero for everything except
dig-node-test-*
— these matter because ~50,000 entries make every Temp scan slow and make the
next real leak hard to see, which is exactly what delayed the #361 diagnosis (the first diagnosis
blamed worktree target/ dirs, which were not the cause).

Reference of "good"

content_serve.rs's NodeCache on
#368. Two properties are the point, and a fix that has
neither is not a fix:

  1. The guard owns the directory (tempfile::TempDir), so removal happens in Drop — including
    on an unwind. A cleanup line at the end of a test is skipped by every failing assertion, i.e. the
    runs a developer repeats; and a cleanup placed after an .await leaks on panic if anything
    catches it.
  2. Where a still-open handle prevents removal (Windows will not unlink an open file — the node's
    wallet.sqlite is held by the detached serve task), the residue is bounded and stated, not
    pretended away. fix(test): serve integration test leaks a ~57MB temp dir per run — 1,123 dirs / 62.5 GB took the machine to ENOSPC #361 uses a once-per-process sweep over trees idle longer than any live run.

The tests to copy are the_temp_tree_is_removed_on_drop_and_on_panic and
the_sweep_removes_an_abandoned_tree_and_spares_a_live_one. Note the second one's live-tree
control
: a sweep that deleted everything would pass a "the stale one is gone" assertion while
removing a concurrent lane's working directory.

Scope

The simplest per-site change that gives property 1. Do not introduce a workspace-wide temp-dir
abstraction as part of this — several of these sites have genuinely different lifetimes (a returned
GossipHandle, a returned state), and a shared type would have to model all of them before any
one leak is fixed.

dig-node-test-* first: it is the only one that costs disk.

Evidence

Per site: run its suite twice and show the Temp entry count for that prefix returns to its
pre-run value, or state the bound and why removal is impossible. A leak test bounded by its own
duration is not a test
— assert on the path after the guard is gone, and include the panic path.

Done condition

Every row above is either fixed or has a stated, checkable bound, and a test asserts its own cleanup.

Parent

https://github.com/DIG-Network/dig_ecosystem/issues/2790
Follows #361

Metadata

Metadata

Assignees

No one assigned

    Labels

    kind:maintenancereal work that changes nothing a user can perceive

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions