Skip to content

A malformed @timeout or @retry aborts the run without running tear_down_after_script #1329

Description

@Chemaclass
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_reject ends in exit 1
  • Reached from bashunit::helper::annotations_validate_or_exit (src/helper/annotations.sh:93)
  • Called from src/runner/exec.sh:134, inside call_test_functions, before any test runs

Acceptance criteria

  • An acceptance test for each of @timeout and @retry with a bad value, asserting the file's tear_down_after_script released its resource, under --no-parallel and --parallel.
  • The error message text and the non-zero exit code are unchanged. Existing annotation-validation coverage still passes.
  • CHANGELOG.md gets a Fixed entry.

Notes for the implementer

  • bashunit::runner::run_pending_file_teardown and mark_file_teardown_pending landed in src/runner/hooks.sh with --stop-on-failure skips tear_down_after_script in sequential runs #1321 and are the primitive for this. The test loop already marks the debt at src/runner/discovery.sh:215, so sequentially the abort path only has to settle it.
  • Under --parallel the 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/.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    • Status
      Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions