Skip to content

tear_down_after_script runs before the file's tests under --parallel #1320

Description

@Chemaclass
Q A
OS macOS 26.5.2 (arm64)
Shell & version bash 3.2.57
bashunit version 0.50.0

Summary

Under --parallel the runner dispatches a file's tests as a background worker, then runs tear_down_after_script in the parent on the very next line. The hook releases the file's resources while the tests that need them are still running.

Same class as #1318: a file-scoped hook that does not line up with the work it is supposed to wrap. There the hook never ran. Here it runs too early.

The same file passes under --no-parallel and fails under --parallel, which is exactly the sequential/parallel divergence #1150 set out to stop.

Current behavior

tear_down_after_script runs immediately after the fork, before the worker has executed a single test. Tests that read a resource created in set_up_before_script fail against whatever the hook left behind. The failure is reported against the test, so nothing points at the hook.

How to reproduce

race_test.sh:

RESOURCE=""

function set_up_before_script() {
  RESOURCE="$CLEANUP_MARKER"
  : >"$RESOURCE"
}

function tear_down_after_script() {
  rm -f "$RESOURCE"
}

function test_needs_resource() {
  sleep 0.5
  assert_file_exists "$CLEANUP_MARKER"
}

Sequential passes:

$ CLEANUP_MARKER=/tmp/bu-race.marker ./bashunit --no-parallel race_test.sh
Tests:      1 passed, 1 total

Parallel fails:

$ CLEANUP_MARKER=/tmp/bu-race.marker ./bashunit --parallel race_test.sh
✗ Failed: Needs resource
    Expected '/tmp/bu-race.marker'
    to exist but 'do not exist'
Tests:      1 failed, 1 total

Expected behavior

tear_down_after_script runs after the file's tests have finished, in both modes. A file that passes sequentially passes in parallel.

Where it happens

src/runner/discovery.sh:

  • line 231: bashunit::runner::call_test_functions "$test_file" "$_cached_fns" 2>"$_worker_stderr" &
  • line 235: bashunit::runner::run_tear_down_after_script "$test_file" runs in the parent
  • line 249: wait runs only after the whole file loop

Acceptance criteria

  • An acceptance test with a file whose test sleeps, then asserts a resource created in set_up_before_script. It passes under --no-parallel and --parallel.
  • A tear_down_after_script that fails is still counted, and still reported against the hook, under --parallel.
  • ./bashunit tests/ and ./bashunit --parallel tests/ green.
  • The caveat at docs/ai-agents.md:144 ("Do not delete a shared fixture in tear_down_after_script") is removed or rewritten, since it exists only to work around this.
  • CHANGELOG.md gets a Fixed entry.

Notes for the implementer

  • Moving the hook into call_test_functions is the obvious shape, but that runs in a subshell. State written there dies with it, which is the trap Duplicate test functions go undetected under --parallel #1147 documents and the comment at discovery.sh:216 restates. A hook failure has to reach the parent through the result payload, the same channel the worker already uses for test results.
  • Waiting on the file's own worker before running the hook is correct and simple, and it serialises the run one file at a time. Measure the suite before choosing it.
  • set_up_before_script runs in the parent before the fork, so the worker inherits its state. Only the teardown side is misplaced.
  • 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

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