Skip to content

perf(runner): stat a marker instead of scanning the shared temp dir - #1270

Merged
Chemaclass merged 1 commit into
mainfrom
perf/1269-temp-dir-scan
Aug 15, 2026
Merged

perf(runner): stat a marker instead of scanning the shared temp dir#1270
Chemaclass merged 1 commit into
mainfrom
perf/1269-temp-dir-scan

Conversation

@Chemaclass

Copy link
Copy Markdown
Member

🤔 Background

Related #1269

Every test's EXIT trap expanded a glob over BASHUNIT_TEMP_DIR, which makes bash read the whole directory. That directory is shared, survives between runs and nothing reaps it — so every file an interrupted run left behind was re-examined by every test of every later run, and could never match, since the test id carries the run's own $$.

Profiling a 200-test run against a real 4,242-file directory, this one call was 3.16 ms of an 8.5 ms per-test total — larger than the test body, both hooks, mock teardown and result encoding combined.

💡 Changes

  • temp_file/temp_dir write a <id>_.mark marker (a redirect, not a fork); the trap stats it and returns early when absent, which is the common case since most tests create no temp file. The marker shares the <id>_ prefix, so the existing rm takes it along with the rest
  • A 100-test file against 5000 leftovers: 978ms → 542ms, and runtime no longer grows with the directory at all (520ms at 0 and at 2000)
  • Behaviour change, documented: a file a test writes there by hand, named with its own id, is no longer removed for it — finding one is exactly the scan being removed
  • Guard plants such a file and asserts it survives while a helper-provided one is still cleaned; deterministic, where a timing assertion could not be

Every test's EXIT trap expanded

    matches=("$BASHUNIT_TEMP_DIR/${BASHUNIT_CURRENT_TEST_ID}"_*)

which makes bash read all of BASHUNIT_TEMP_DIR. That directory is shared
(${TMPDIR:-/tmp}/bashunit/tmp), survives between runs and nothing reaps it, so
every file an interrupted run left there was re-examined by every test of every
later run. It could never match one: the id carries the run's own $$.

Profiling a 200-test run against a real 4242-file directory, this single call
was 3.16ms of an 8.5ms per-test total -- larger than the test body, both hooks,
mock teardown and result encoding combined. A 100-test file:

    leftovers      0     500    2000    5000
    before      498ms   513ms   635ms   978ms
    after       520ms     -     520ms   542ms

temp_file/temp_dir now write a <id>_.mark marker (a redirect, not a fork) and
the trap returns early when it is absent -- the common case, since most tests
create no temp file. The marker shares the <id>_ prefix, so the existing rm
takes it along with the rest.

Behaviour change: a file a test writes into BASHUNIT_TEMP_DIR by hand, named
with its own id, is no longer removed for it. Finding one is exactly the
directory scan being removed. The guard test plants such a file and asserts it
survives, which no timing assertion could pin deterministically.

Closes #1269
@Chemaclass Chemaclass added the enhancement New feature or request label Aug 15, 2026
@Chemaclass Chemaclass self-assigned this Aug 15, 2026
@Chemaclass
Chemaclass merged commit d858132 into main Aug 15, 2026
37 checks passed
@Chemaclass
Chemaclass deleted the perf/1269-temp-dir-scan branch August 15, 2026 11:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant