Repository navigation
Description
Part of #761.
Problem
Every test run encodes its subshell context once per test in bashunit::state::export_subshell_context (src/state.sh:231-259). It always forks three echo -n ... | base64 pipelines (src/state.sh:239-246) for _BASHUNIT_TEST_OUTPUT, _BASHUNIT_TEST_TITLE, and _BASHUNIT_TEST_HOOK_MESSAGE, even though title and hook message are empty for almost every test. On the decode side, bashunit::helper::decode_base64 (src/helpers.sh:149) already has a fast path for the _BASHUNIT_EMPTY_ marker, but a plain empty string still forks printf | base64 -d, and bashunit::runner::decode_subshell_output (src/runner.sh:1110) runs once per test.
Measured cost: each pipeline is ~1.6ms (2 forks) on macOS bash 3.2. That is ~4-5ms per test, ~5s across the ~1160-test suite, and it compounds inside the 258 nested ./bashunit runs in the acceptance suite.
Task
- In
export_subshell_context, only forkbase64when the source variable is non-empty; emit an empty string (or the existing_BASHUNIT_EMPTY_marker, whichever keeps the wire format consistent — check how##TEST_TITLE=/##TEST_HOOK_MESSAGE=are parsed downstream insrc/runner.shandsrc/parallel.sh) for empty values. Noteecho -n "" | base64already produces an empty string, so guarding with[ -n "$var" ]should be wire-compatible; verify against the parallel.resultfile path too (bashunit::runner::parse_result_parallel,src/runner.sh:1441). - In
decode_base64, add an early return for empty input so""never forks. - Audit callers of
decode_base64for other per-test empty decodes.
Tests first (TDD)
- Unit tests for encode/decode round-trip: empty string, plain string, multiline string, string with ANSI codes, UTF-8. Follow patterns in
tests/unit/helpers_test.sh/ existing state tests. - Regression: a test with a
# @test_titleannotation and a hook message still renders correctly (sequential AND--parallel), since those exercise the non-empty paths.
Constraints
- Bash 3.0+ only: no
declare -A, no[[ ]], no${var,,}, no negative array indexing, no&>>. - Wire format of
##ASSERTIONS_*##TEST_*context string must remain parseable by the existing extractors; do not change field order. - Keep the Alpine
base64 -w 0branch behavior (src/state.sh:237-241).
Acceptance criteria
-
./bashunit tests/and./bashunit --parallel tests/pass. -
make sa,make lintpass;shfmt -w .produces no diff. - Fork census (see tracking issue) shows
base64count drops from ~4/test to ~2/test for tests without title/hook message. - Before/after timing of the 100-noop benchmark reported in the PR.
Line references valid at commit 4d80e7c.
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsDone
Activity
Chemaclass commentedon Jul 12, 2026
Landed in PR #768 (902fcb3). Verified at 1ae3e82:
export_subshell_contextonly forks base64 for non-empty values anddecode_base64short-circuits empties. Follow-up per-assertion/per-test fork work continues in #772/#774.