Skip to content

Improve parallel runner#588

Merged
Chemaclass merged 14 commits intomainfrom
feat/improve-parallel-runner
Feb 13, 2026
Merged

Improve parallel runner#588
Chemaclass merged 14 commits intomainfrom
feat/improve-parallel-runner

Conversation

@Chemaclass
Copy link
Member

@Chemaclass Chemaclass commented Feb 13, 2026

📚 Description

Improve parallel test execution by implementing test-level parallelism — individual test functions within a file now run concurrently when --parallel is enabled. Previously, only file-level parallelism was supported. Also splits large test files for better parallel distribution and optimizes sandbox creation in the release script.

🔖 Changes

  • Test-level parallelism: Individual test functions (with and without data providers) run in parallel within each file via background processes (& + wait)
  • Opt-out mechanism: Test files can disable test-level parallelism with a # bashunit: no-parallel-tests header comment
  • Optimized result aggregation: Replace tail with pure Bash parameter expansion and use (( )) arithmetic for counting
  • Split large test files: Break assert_test.sh, coverage_test.sh, release_test.sh, and acceptance test files into smaller, focused files for better parallel distribution
  • Optimized sandbox creation: Replace cp -r + rm -rf with a tar pipe that excludes directories upfront, avoiding unnecessary copying

✅ To-do list

  • I updated the CHANGELOG.md to reflect the new feature or fix
  • I updated the documentation to reflect the changes

🖼️ Demo

BEFORE

  • parallel: 38.3s
  • regular: 2m 9s
Screenshot 2026-02-13 at 16 12 52

AFTER

  • parallel: 24.3s
  • regular: 2m 2s
Screenshot 2026-02-13 at 15 46 39

Split assert_test.sh (79 tests) into 4 focused files
Split release_test.sh (71 tests) into 5 domain files
Split coverage_test.sh (65 tests) into 4 functional files

Improves parallel execution by distributing 215 tests across more workers.
Remove assert_test.sh, release_test.sh, and coverage_test.sh after splitting.
Tests are now distributed across 13 focused files for better parallel load balancing.
Replace tail subprocess with parameter expansion.
Eliminates 750+ process spawns during aggregation.

Use (( )) arithmetic for counter updates (Bash 3.0 compatible).
…ribution

Split bashunit_assert_subcommand_test.sh (20 tests) into 3 files:
- bashunit_assert_basic_test.sh (8 tests): basic assertions and help
- bashunit_assert_errors_test.sh (6 tests): error cases and deprecation
- bashunit_assert_multi_test.sh (6 tests): multi-assertion mode

Split bashunit_direct_fn_call_test.sh (19 tests) into 2 files:
- bashunit_direct_fn_call_basic_test.sh (11 tests): basic assertions
- bashunit_direct_fn_call_advanced_test.sh (8 tests): exit codes and failures

Split bashunit_lifecycle_output_test.sh (12 tests) into 2 files:
- bashunit_lifecycle_verbose_test.sh (2 tests): verbose output behavior
- bashunit_lifecycle_visibility_test.sh (4 tests): hook visibility modes

Improves parallel execution by distributing 51 acceptance tests across more workers.
…ance

Enable parallel execution of individual test functions within files,
not just parallel file execution. This significantly improves CPU
utilization and reduces test execution time.

Implementation:
- Modified call_test_functions to run test functions in parallel
- Added opt-out mechanism via `# bashunit: no-parallel-tests` marker
- Tests within a file now execute concurrently using background jobs
- Result aggregation already supports per-test result files

Opt-out marker added to tests with shared state:
- install_test.sh (shares ./lib and ./deps directories)
- bashunit_report_html_test.sh (shares HTML output files)
- bashunit_upgrade_test.sh (shares tmp/ directory)

Performance improvement:
- Parallel execution: 31.71s (down from ~40s, ~21% faster)
- CPU utilization: 702% (up from ~480%)
- Better parallelization across all available cores

All 750 tests passing, all 1136 assertions correct.
Replace cp + rm with tar pipe for sandbox directory copying.
This provides significant performance improvements by:
- Excluding directories during copy (not after)
- Using tar's optimized bulk operations
- Eliminating separate rm -rf cleanup

Performance impact:
- Sandbox tests: 50s+ → 2.45s (~20x faster)
- Full parallel suite: 31.71s → 26.56s (16% faster)
- Overall from baseline: 42.94s → 26.56s (38% faster)

Excluded directories: .git, .release-state, node_modules, .tasks, tmp
@Chemaclass Chemaclass added the enhancement New feature or request label Feb 13, 2026
@Chemaclass Chemaclass self-assigned this Feb 13, 2026
@github-actions
Copy link
Contributor

✅ Contributor Report

User: @Chemaclass
Status: Passed (13/13 metrics passed)

Metric Description Value Threshold Status
PR Merge Rate PRs merged vs closed 94% >= 30%
Repo Quality Repos with ≥100 stars 6 >= 0
Positive Reactions Positive reactions received 157 >= 1
Negative Reactions Negative reactions received 0 <= 5
Account Age GitHub account age 4561 days >= 30 days
Activity Consistency Regular activity over time 108% >= 0%
Issue Engagement Issues with community engagement 0 >= 0
Code Reviews Code reviews given to others 175 >= 0
Merger Diversity Unique maintainers who merged PRs 8 >= 2
Repo History Merge Rate Merge rate in this repo 88% >= 0%
Repo History Min PRs Previous PRs in this repo 123 >= 0
Profile Completeness Profile richness (bio, followers) 100 >= 0
Suspicious Patterns Spam-like activity detection 0 N/A

Contributor Report evaluates based on public GitHub activity. Analysis period: 2025-02-13 to 2026-02-13

    Changes for Bash 3.0+ compliance:
    - Replace [[ ]] with [ ] test operators in runner.sh
    - Replace == with = for string comparisons
    - Add fallback from tar to cp+rm for portability
    - Fix indentation to pass EditorConfig linting

    The tar pipe optimization now gracefully falls back to the traditional
    cp + rm approach on systems without tar or with limited tar support,
    ensuring maximum portability while maintaining performance gains on
    systems with modern tar implementations.
Add no-parallel-tests marker to tests that have race conditions when
run with test-level parallelism in strict mode:

- parallel_test.sh: Tests parallel functionality, needs sequential execution
  to avoid interference with its own parallel temp directory management

- bashunit_script_temp_file_cleanup_test.sh: Has data provider that runs
  bashunit internally, parallel execution causes tests to interfere with
  each other's temp file cleanup checks

These tests were causing intermittent failures in strict parallel mode
due to shared state and global temp directory access.

Fixes race conditions while maintaining performance for other tests.
Replace [[ -d ]] && rm with if [ -d ]; then rm; fi pattern in tear_down
function to ensure proper behavior in strict mode (set -euo pipefail).

The [[ ]] && pattern can cause issues in strict mode when the test
returns false, potentially causing the tear_down to exit early and
prevent proper cleanup and variable restoration.

This ensures Bash 3.0+ compatibility and stable behavior in all modes:
- Normal mode: ✓
- Parallel mode: ✓
- Strict mode: ✓
- Parallel + Strict mode: ✓
Disable errexit temporarily around tar pipe to allow proper fallback
to cp+rm when tar fails. In strict mode (set -euo pipefail), pipe
failures would exit the function before the fallback could execute.

Changes:
- Wrap tar command with set +e / set -e
- Capture tar exit status explicitly
- Check status and fallback to cp if needed

This fixes intermittent sandbox test failures in strict parallel mode
while maintaining the performance benefit of tar on systems where it works.
Replace process substitution with command substitution and positional parameters.
@Chemaclass Chemaclass force-pushed the feat/improve-parallel-runner branch from 4acc337 to cda6633 Compare February 13, 2026 14:13
The disown && kill command could fail if the spinner process
already finished, causing non-zero exit code in strict mode.

Split into separate commands with || true to ensure they never fail.
The (( var += val )) syntax returns exit code 1 when result is 0,
causing script to exit in strict mode with -e flag.

Use var=$((var + val)) instead which never fails.
Add CHANGELOG entries for:
- 30-40% performance improvement in parallel mode
- Test-level parallelism feature
- Opt-out directive for files with shared state
- Strict mode compatibility fixes

Add documentation for the no-parallel-tests directive in command-line guide.
@Chemaclass Chemaclass merged commit d6f8c59 into main Feb 13, 2026
21 checks passed
@Chemaclass Chemaclass deleted the feat/improve-parallel-runner branch February 13, 2026 15:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant