Repository navigation
Description
| Q | A |
|---|---|
| OS | macOS 26.5.2 (arm64) |
| Shell & version | bash 3.2.57 |
| bashunit version | 0.50.0 (main @ 1abb624) |
Summary
A malformed # @timeout or # @retry annotation aborts the run with exit 1 from inside call_test_functions. set_up_before_script has already run, and tear_down_after_script never does.
Same defect as #1322, one code path over: that issue is the bench runner's @revs/@its validation, this is the test runner's @timeout/@retry validation. Found while fixing #1322, kept separate because the two runners abort from different frames.
Current behavior
The annotation error prints, the run exits 1, and the file's teardown hook is skipped. Both modes leak: sequentially call_test_functions runs in the main shell, and under --parallel the hook now runs inside the worker (#1320), which the same exit 1 kills.
How to reproduce
annot_test.sh:
function set_up_before_script() { : >"$ANNOT_MARKER.setup"; }
function tear_down_after_script() { : >"$ANNOT_MARKER.RAN_TEARDOWN"; }
# @timeout abc
function test_bad_annotation() { assert_true true; }$ ANNOT_MARKER=/tmp/bu-annot ./bashunit --no-parallel annot_test.sh
Error: @timeout 'abc' above test_bad_annotation in annot_test.sh is not a non-negative integer.
$ ls /tmp/bu-annot.*
/tmp/bu-annot.setup
RAN_TEARDOWN is absent. --parallel behaves the same. # @retry abc takes the same path.
Expected behavior
The annotation error still aborts the run with a non-zero status, and tear_down_after_script runs for the file whose setup already ran.
Where it happens
src/helper/annotations.sh:124:_annotations_rejectends inexit 1- Reached from
bashunit::helper::annotations_validate_or_exit(src/helper/annotations.sh:93) - Called from
src/runner/exec.sh:134, insidecall_test_functions, before any test runs
Acceptance criteria
- An acceptance test for each of
@timeoutand@retrywith a bad value, asserting the file'stear_down_after_scriptreleased its resource, under--no-paralleland--parallel. - The error message text and the non-zero exit code are unchanged. Existing annotation-validation coverage still passes.
-
CHANGELOG.mdgets aFixedentry.
Notes for the implementer
bashunit::runner::run_pending_file_teardownandmark_file_teardown_pendinglanded insrc/runner/hooks.shwith--stop-on-failureskipstear_down_after_scriptin sequential runs #1321 and are the primitive for this. The test loop already marks the debt atsrc/runner/discovery.sh:215, so sequentially the abort path only has to settle it.- Under
--parallelthe debt is cleared in the parent right after dispatch, so the worker cannot read it. The worker's own frame has to run the hook before it exits. - Prefer returning non-zero up to a frame that can finish the file over exiting from inside the validator. The reason the exit exists at all is Malformed benchmark annotations are silently ignored #884: a silently defaulted annotation runs a different test than the one asked for. Keep that.
- Bash 3.0+ only. See
.claude/rules/bash-style.md. make sa,make lint,./bashunit tests/,./bashunit --parallel tests/.
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsDone
Activity
Chemaclass commentedon Aug 21, 2026
Done in #1334 (merged).