mirror of
https://github.com/tw93/Mole.git
synced 2026-03-22 16:45:07 +00:00
test: fix parallel test flakiness and bash 3.2 empty-array expansion
- Fix 'bats_opts[@]: unbound variable' under set -u + bash 3.2: empty
arrays must use ${arr[@]+"${arr[@]}"} idiom, not "${arr[@]}"
- Split core_performance.bats out of the parallel batch; run it after
all parallel workers finish so wall-clock timing assertions aren't
skewed by CPU contention from concurrent bats processes
- Raise MOLE_PERF_GET_INVOKING_USER_LIMIT_MS default 500→2000ms and
add MOLE_PERF_SECTION_LIMIT_MS (default 2000ms) to give sufficient
headroom without masking real regressions
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
101
scripts/test.sh
101
scripts/test.sh
@@ -112,51 +112,76 @@ if command -v bats > /dev/null 2>&1 && [ -d "tests" ]; then
|
||||
unset _ncpu _jobs
|
||||
fi
|
||||
|
||||
if bats --help 2>&1 | grep -q -- "--formatter"; then
|
||||
formatter="${BATS_FORMATTER:-pretty}"
|
||||
if [[ "$formatter" == "tap" ]]; then
|
||||
# core_performance.bats has wall-clock timing assertions that are skewed by
|
||||
# CPU contention from parallel test workers. When parallel mode is active,
|
||||
# split it out to run sequentially after the parallel batch completes.
|
||||
_perf_files=()
|
||||
if [[ ${#bats_opts[@]} -gt 0 ]]; then
|
||||
_all=("$@")
|
||||
_rest=()
|
||||
if [[ ${#_all[@]} -eq 1 && -d "${_all[0]}" ]]; then
|
||||
while IFS= read -r _f; do
|
||||
case "$_f" in
|
||||
*core_performance.bats) _perf_files+=("$_f") ;;
|
||||
*) _rest+=("$_f") ;;
|
||||
esac
|
||||
done < <(find "${_all[0]}" -type f -name '*.bats' | sort)
|
||||
else
|
||||
for _f in "${_all[@]}"; do
|
||||
case "$_f" in
|
||||
*core_performance.bats) _perf_files+=("$_f") ;;
|
||||
*) _rest+=("$_f") ;;
|
||||
esac
|
||||
done
|
||||
fi
|
||||
if [[ ${#_rest[@]} -gt 0 ]]; then
|
||||
set -- "${_rest[@]}"
|
||||
else
|
||||
set --
|
||||
fi
|
||||
unset _all _rest _f
|
||||
fi
|
||||
|
||||
# Accumulate pass/fail across all bats invocations.
|
||||
_unit_rc=0
|
||||
|
||||
# Main run (parallel when bats_opts has --jobs, skipped if no files remain).
|
||||
if [[ $# -gt 0 ]]; then
|
||||
if bats --help 2>&1 | grep -q -- "--formatter"; then
|
||||
formatter="${BATS_FORMATTER:-pretty}"
|
||||
if [[ "$formatter" == "tap" ]]; then
|
||||
if $use_color; then
|
||||
esc=$'\033'
|
||||
bats ${bats_opts[@]+"${bats_opts[@]}"} --formatter tap "$@" |
|
||||
sed -e "s/^ok /${esc}[32mok ${esc}[0m /" \
|
||||
-e "s/^not ok /${esc}[31mnot ok ${esc}[0m /" || _unit_rc=1
|
||||
else
|
||||
bats ${bats_opts[@]+"${bats_opts[@]}"} --formatter tap "$@" || _unit_rc=1
|
||||
fi
|
||||
else
|
||||
# Pretty format for local development
|
||||
bats ${bats_opts[@]+"${bats_opts[@]}"} --formatter "$formatter" "$@" || _unit_rc=1
|
||||
fi
|
||||
else
|
||||
if $use_color; then
|
||||
esc=$'\033'
|
||||
if bats "${bats_opts[@]}" --formatter tap "$@" |
|
||||
bats ${bats_opts[@]+"${bats_opts[@]}"} --tap "$@" |
|
||||
sed -e "s/^ok /${esc}[32mok ${esc}[0m /" \
|
||||
-e "s/^not ok /${esc}[31mnot ok ${esc}[0m /"; then
|
||||
report_unit_result 0
|
||||
else
|
||||
report_unit_result 1
|
||||
fi
|
||||
-e "s/^not ok /${esc}[31mnot ok ${esc}[0m /" || _unit_rc=1
|
||||
else
|
||||
if bats "${bats_opts[@]}" --formatter tap "$@"; then
|
||||
report_unit_result 0
|
||||
else
|
||||
report_unit_result 1
|
||||
fi
|
||||
fi
|
||||
else
|
||||
# Pretty format for local development
|
||||
if bats "${bats_opts[@]}" --formatter "$formatter" "$@"; then
|
||||
report_unit_result 0
|
||||
else
|
||||
report_unit_result 1
|
||||
fi
|
||||
fi
|
||||
else
|
||||
if $use_color; then
|
||||
esc=$'\033'
|
||||
if bats "${bats_opts[@]}" --tap "$@" |
|
||||
sed -e "s/^ok /${esc}[32mok ${esc}[0m /" \
|
||||
-e "s/^not ok /${esc}[31mnot ok ${esc}[0m /"; then
|
||||
report_unit_result 0
|
||||
else
|
||||
report_unit_result 1
|
||||
fi
|
||||
else
|
||||
if bats "${bats_opts[@]}" --tap "$@"; then
|
||||
report_unit_result 0
|
||||
else
|
||||
report_unit_result 1
|
||||
bats ${bats_opts[@]+"${bats_opts[@]}"} --tap "$@" || _unit_rc=1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# Post-run: timing-sensitive perf tests run after parallel workers have
|
||||
# finished so CPU contention does not skew wall-clock assertions.
|
||||
for _pf in ${_perf_files[@]+"${_perf_files[@]}"}; do
|
||||
bats "$_pf" || _unit_rc=1
|
||||
done
|
||||
unset _perf_files _pf
|
||||
|
||||
report_unit_result "$_unit_rc"
|
||||
else
|
||||
printf "${YELLOW}${ICON_WARNING} bats not installed or no tests found, skipping${NC}\n"
|
||||
fi
|
||||
|
||||
Reference in New Issue
Block a user