You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Ctrl-C runs bashunit::main::cleanup, which kills the children, sweeps the temp directories and exits. It never runs tear_down_after_script for the file in flight, so a file-scoped resource acquired in set_up_before_script is left behind.
Same class as #1318. The per-test half of the pair already survives this: pkill sends SIGTERM to the test subshell, its EXIT trap fires, and tear_down runs. The file-scoped half does not.
Current behavior
● set_up_before_script 11ms
Caught Ctrl-C, killing all child processes...
tear_down ran. tear_down_after_script did not. The resource survives.
A shell that backgrounds a job sets SIGINT to SIG_IGN in the child, and bash refuses to trap a signal that was ignored on entry. So the repro has to reset the disposition before exec, or the signal is swallowed and the run finishes normally:
--watch is the same path: src/main/watch.sh:38 traps INT in the parent and exec_tests runs in a ( ) subshell, so fixing cleanup covers both
Acceptance criteria
bashunit::main::cleanup runs tear_down_after_script for the current file when one is defined and its set_up_before_script already ran.
It runs before bashunit::cleanup_script_temp_files, so a hook that reads a bashunit::temp_file still finds it.
It runs after pkill -P $$, matching the normal order: per-test tear_down first, then the file hook.
Nothing runs for a file whose setup never ran, and nothing runs twice.
Ctrl-C still prints "Caught Ctrl-C, killing all child processes..." and still exits 1.
A hook that blocks does not hang the interrupt. Bound it, or write down in a comment why it is safe not to.
A test covering it. The SIG_IGN inheritance above has to be handled inside the test, and the reason belongs in a comment so the next reader does not delete the workaround.
CHANGELOG.md gets a Fixed entry.
Notes for the implementer
The trap cannot see the loop variable in bashunit::runner::load_test_files. Record the current file in a global when the loop starts one, and clear it after the file's teardown, so the trap knows both which file and whether the hook is still owed.
Summary
Ctrl-C runs
bashunit::main::cleanup, which kills the children, sweeps the temp directories and exits. It never runstear_down_after_scriptfor the file in flight, so a file-scoped resource acquired inset_up_before_scriptis left behind.Same class as #1318. The per-test half of the pair already survives this:
pkillsendsSIGTERMto the test subshell, itsEXITtrap fires, andtear_downruns. The file-scoped half does not.Current behavior
tear_downran.tear_down_after_scriptdid not. The resource survives.How to reproduce
sigint_test.sh:A shell that backgrounds a job sets
SIGINTtoSIG_IGNin the child, and bash refuses to trap a signal that was ignored on entry. So the repro has to reset the disposition before exec, or the signal is swallowed and the run finishes normally:RAN_FILE_TEARDOWNis absent.Expected behavior
Ctrl-C runs
tear_down_after_scriptfor the file whoseset_up_before_scriptalready ran, then exits 1 as it does today.Where it happens
src/main/run.sh:82:trap 'bashunit::main::cleanup' SIGINTsrc/main/run.sh:382:bashunit::main::cleanuprunspkill -P $$,bashunit::cleanup_script_temp_files,bashunit::parallel::cleanup,bashunit::env::cleanup_run_output_dir,exit 1--watchis the same path:src/main/watch.sh:38trapsINTin the parent andexec_testsruns in a( )subshell, so fixingcleanupcovers bothAcceptance criteria
bashunit::main::cleanuprunstear_down_after_scriptfor the current file when one is defined and itsset_up_before_scriptalready ran.bashunit::cleanup_script_temp_files, so a hook that reads abashunit::temp_filestill finds it.pkill -P $$, matching the normal order: per-testtear_downfirst, then the file hook.SIG_IGNinheritance above has to be handled inside the test, and the reason belongs in a comment so the next reader does not delete the workaround.CHANGELOG.mdgets aFixedentry.Notes for the implementer
bashunit::runner::load_test_files. Record the current file in a global when the loop starts one, and clear it after the file's teardown, so the trap knows both which file and whether the hook is still owed.--stop-on-failurequestion in--stop-on-failureskipstear_down_after_scriptin sequential runs #1321. Worth building once..claude/rules/bash-style.md.make sa,make lint,./bashunit tests/,./bashunit --parallel tests/.