From 1b11ebb95cec9923d0e0814696074c02c8ccb191 Mon Sep 17 00:00:00 2001 From: Chemaclass Date: Thu, 16 Jul 2026 00:08:46 +0200 Subject: [PATCH] perf(runner): create cold-start scratch dirs in one mkdir fork The run-output scratch directory and the shared temp directory were each created by a separate 'mkdir -p' fork at load. Create both in one call (2 -> 1 mkdir fork per cold start); matters across the acceptance suite's ~258 nested runs. No behaviour change. --- CHANGELOG.md | 1 + src/env.sh | 7 ++++--- .../acceptance/bashunit_coldstart_forks_test.sh | 17 +++++++++++++++++ 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ecdbe1ba..183a8e41 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ - `--jobs auto` / `-j auto` caps parallel concurrency at the CPU core count (portable across Linux/macOS/BSD); the default stays unlimited (#766) ### Changed +- Faster cold start: the run-output scratch directory and the shared temp directory are created with a single `mkdir -p` call instead of one fork each (2 -> 1 `mkdir` forks per cold start). No behaviour change - Faster test runs: the runner detects a failed source (syntax error / unexpected EOF) and discovery detects the `.bash` pattern variant with shell `case` matches instead of `grep` forks (2 -> 0 `grep` forks per sourced test file). No behaviour change - Faster cold start: the base64 `-w` capability is detected with a shell `case` on `base64 --help` instead of piping into a `grep` fork (1 -> 0 `grep` forks per cold start). Same detection, no behaviour change - Faster cold start: selecting the `perl` clock reads the time once instead of an empty `Time::HiRes` probe followed by a separate first read (2 -> 1 `perl` fork per cold start on bash 3.2 / macOS). No behaviour change diff --git a/src/env.sh b/src/env.sh index a1a9c22a..3c5f4c17 100644 --- a/src/env.sh +++ b/src/env.sh @@ -494,7 +494,6 @@ MKTEMP="$(command -v mktemp)" # not be pre-created. The random suffix keeps the directory unique across # recursive and parallel invocations, matching TEMP_DIR_PARALLEL_TEST_SUITE. _BASHUNIT_RUN_OUTPUT_DIR="${TMPDIR:-/tmp}/bashunit/run/${_BASHUNIT_OS:-Unknown}/$(bashunit::random_str 8)" -mkdir -p "$_BASHUNIT_RUN_OUTPUT_DIR" 2>/dev/null || true FAILURES_OUTPUT_PATH="$_BASHUNIT_RUN_OUTPUT_DIR/failures" SKIPPED_OUTPUT_PATH="$_BASHUNIT_RUN_OUTPUT_DIR/skipped" INCOMPLETE_OUTPUT_PATH="$_BASHUNIT_RUN_OUTPUT_DIR/incomplete" @@ -504,9 +503,11 @@ PROFILE_OUTPUT_PATH="$_BASHUNIT_RUN_OUTPUT_DIR/profile" # next --rerun-failed can replay just those. Shared across parallel subshells. RERUN_FAILED_OUTPUT_PATH="$_BASHUNIT_RUN_OUTPUT_DIR/rerun-failed" -# Initialize temp directory once at startup for performance +# Shared temp directory, initialized once at startup for performance. BASHUNIT_TEMP_DIR="${TMPDIR:-/tmp}/bashunit/tmp" -mkdir -p "$BASHUNIT_TEMP_DIR" 2>/dev/null || true + +# Create both scratch directories in a single `mkdir -p` fork. +mkdir -p "$_BASHUNIT_RUN_OUTPUT_DIR" "$BASHUNIT_TEMP_DIR" 2>/dev/null || true if bashunit::env::is_dev_mode_enabled; then bashunit::internal_log "info" "Dev log enabled" "file:$BASHUNIT_DEV_LOG" diff --git a/tests/acceptance/bashunit_coldstart_forks_test.sh b/tests/acceptance/bashunit_coldstart_forks_test.sh index d202f778..1b670793 100644 --- a/tests/acceptance/bashunit_coldstart_forks_test.sh +++ b/tests/acceptance/bashunit_coldstart_forks_test.sh @@ -65,3 +65,20 @@ function test_coldstart_does_not_fork_grep_to_detect_base64_wrap() { assert_equals 0 "$grep_forks" } + +# Regression guard: cold start creates its two scratch directories (the run +# output dir and the shared temp dir) with a single `mkdir -p` call instead of +# one fork each. +function test_coldstart_creates_scratch_dirs_with_one_mkdir() { + if bashunit::check_os::is_windows; then + bashunit::skip "process tracing is unreliable under Git Bash" && return + fi + + local trace + trace="$(PS4='+ ' bash -x ./bashunit --version 2>&1 >/dev/null)" + + local mkdir_forks + mkdir_forks="$(printf '%s\n' "$trace" | grep -cE '^\++ +/?[a-z/]*mkdir ' || true)" + + assert_less_or_equal_than 1 "$mkdir_forks" +}