From 61dc052d34f8613bfa4bfd916f7ac3ec679d2215 Mon Sep 17 00:00:00 2001 From: Chemaclass Date: Sun, 13 Oct 2024 08:05:32 +0200 Subject: [PATCH 1/7] feat: improve tests ci --- .github/workflows/tests.yml | 83 +++++++++++++++++++------------------ 1 file changed, 42 insertions(+), 41 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index b8b26afc..5870f7e4 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -7,8 +7,9 @@ on: - main jobs: - ubuntu-macos: - name: "On ${{ matrix.os }}" + + simple-output: + name: "On ${{ matrix.os }} - simple & sync" timeout-minutes: 10 runs-on: ${{ matrix.os }} strategy: @@ -23,30 +24,18 @@ jobs: fetch-depth: 1 - name: Run Tests - run: make test + run: | + ./bashunit --simple --no-parallel tests/ - windows: - name: "On windows (${{ matrix.test_chunk }})" + simple-output-parallel: + name: "On ${{ matrix.os }} - simple & parallel" timeout-minutes: 10 - runs-on: windows-latest + runs-on: ${{ matrix.os }} strategy: matrix: - test_chunk: [acceptance, functional, unit] - fail-fast: false - steps: - - name: Checkout code - uses: actions/checkout@v4 - with: - fetch-depth: 1 - - - name: Run tests - shell: bash - run: | - ./bashunit tests/${{ matrix.test_chunk }}/*_test.sh - - alpine: - name: "On alpine-latest" - runs-on: ubuntu-latest + os: + - ubuntu-latest + - macos-latest steps: - name: Checkout uses: actions/checkout@v4 @@ -55,16 +44,17 @@ jobs: - name: Run Tests run: | - docker run --rm -v "$(pwd)":/project alpine:latest /bin/sh -c " \ - apk update && \ - apk add --no-cache bash make git && \ - adduser -D builder && \ - chown -R builder /project && \ - su - builder -c 'cd /project; make test';" + ./bashunit --simple --parallel tests/ - simple-output: - name: "Simple output" - runs-on: ubuntu-latest + detailed-output-parallel: + name: "On ${{ matrix.os }} - detailed & parallel" + timeout-minutes: 10 + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: + - ubuntu-latest + - macos-latest steps: - name: Checkout uses: actions/checkout@v4 @@ -73,23 +63,29 @@ jobs: - name: Run Tests run: | - ./bashunit --simple tests/ + ./bashunit --detailed --parallel tests/ - simple-output-parallel: - name: "Simple output in parallel" - runs-on: ubuntu-latest + windows: + name: "On windows (${{ matrix.test_chunk }})" + timeout-minutes: 10 + runs-on: windows-latest + strategy: + matrix: + test_chunk: [acceptance, functional, unit] + fail-fast: false steps: - - name: Checkout + - name: Checkout code uses: actions/checkout@v4 with: fetch-depth: 1 - - name: Run Tests + - name: Run tests + shell: bash run: | - ./bashunit --parallel --simple tests/ + ./bashunit tests/${{ matrix.test_chunk }}/*_test.sh - extended-output-parallel: - name: "Extended output in parallel" + alpine: + name: "On alpine-latest" runs-on: ubuntu-latest steps: - name: Checkout @@ -99,4 +95,9 @@ jobs: - name: Run Tests run: | - ./bashunit --parallel tests/ + docker run --rm -v "$(pwd)":/project alpine:latest /bin/sh -c " \ + apk update && \ + apk add --no-cache bash make git && \ + adduser -D builder && \ + chown -R builder /project && \ + su - builder -c 'cd /project; make test';" From d35cbf78c2a724e04fd18e740d5fc88edbcbd44a Mon Sep 17 00:00:00 2001 From: Chemaclass Date: Sun, 13 Oct 2024 08:25:32 +0200 Subject: [PATCH 2/7] feat: feature flag enable parallel only macos and ubuntu --- .github/workflows/tests.yml | 10 +++++----- CHANGELOG.md | 1 + src/main.sh | 16 +++++++++------- src/parallel.sh | 5 +++++ src/runner.sh | 12 ++++++------ src/state.sh | 2 +- 6 files changed, 27 insertions(+), 19 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 5870f7e4..86697c27 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -9,7 +9,7 @@ on: jobs: simple-output: - name: "On ${{ matrix.os }} - simple & sync" + name: "${{ matrix.os }} - simple & sync" timeout-minutes: 10 runs-on: ${{ matrix.os }} strategy: @@ -28,7 +28,7 @@ jobs: ./bashunit --simple --no-parallel tests/ simple-output-parallel: - name: "On ${{ matrix.os }} - simple & parallel" + name: "${{ matrix.os }} - simple & parallel" timeout-minutes: 10 runs-on: ${{ matrix.os }} strategy: @@ -47,7 +47,7 @@ jobs: ./bashunit --simple --parallel tests/ detailed-output-parallel: - name: "On ${{ matrix.os }} - detailed & parallel" + name: "${{ matrix.os }} - detailed & parallel" timeout-minutes: 10 runs-on: ${{ matrix.os }} strategy: @@ -66,7 +66,7 @@ jobs: ./bashunit --detailed --parallel tests/ windows: - name: "On windows (${{ matrix.test_chunk }})" + name: "windows (${{ matrix.test_chunk }})" timeout-minutes: 10 runs-on: windows-latest strategy: @@ -85,7 +85,7 @@ jobs: ./bashunit tests/${{ matrix.test_chunk }}/*_test.sh alpine: - name: "On alpine-latest" + name: "alpine-latest" runs-on: ubuntu-latest steps: - name: Checkout diff --git a/CHANGELOG.md b/CHANGELOG.md index 5ff738e5..0054cf23 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## [Unreleased](https://github.com/TypedDevs/bashunit/compare/0.17.0...main) - Added `-p|--parallel` to enable running tests in parallel + - Enabled only in macOS and Ubuntu - Added `assert_file_contains` and `assert_file_not_contains` - Added `assert_true` and `assert_false` - Added `BASHUNIT_DEV_LOG` diff --git a/src/main.sh b/src/main.sh index f610b726..aa867a39 100644 --- a/src/main.sh +++ b/src/main.sh @@ -19,23 +19,25 @@ function main::exec_tests() { trap 'main::cleanup' SIGINT trap '[[ $? -eq $EXIT_CODE_STOP_ON_FAILURE ]] && main::handle_stop_on_failure_sync' EXIT - if env::is_parallel_run_enabled && check_os::is_alpine; then - printf "%sWarning: Parallel test execution on Alpine Linux is currently" "${_COLOR_INCOMPLETE}" - printf "in a beta stage.\nThis means there may be unresolved issues, " - printf "particularly involving race conditions.%s\n" "${_COLOR_DEFAULT}" + if env::is_parallel_run_enabled && ! parallel::is_enabled; then + printf "%sWarning: Parallel tests are working only for macOS and Ubuntu.\n" "${_COLOR_INCOMPLETE}" + printf "For other OS (Linux/Alpine, Windows), --parallel is not enabled due to inconsistent results,\n" + printf "particularly involving race conditions.%s " "${_COLOR_DEFAULT}" + printf "%sFallback using --no-parallel%s\n" "${_COLOR_SKIPPED}" "${_COLOR_DEFAULT}" fi - if env::is_parallel_run_enabled; then + if parallel::is_enabled; then parallel::reset fi console_header::print_version_with_env "$filter" "${test_files[@]}" runner::load_test_files "$filter" "${test_files[@]}" - if env::is_parallel_run_enabled; then + + if parallel::is_enabled; then wait fi - if env::is_parallel_run_enabled && parallel::must_stop_on_failure; then + if parallel::is_enabled && parallel::must_stop_on_failure; then printf "\r%sStop on failure enabled...%s\n" "${_COLOR_SKIPPED}" "${_COLOR_DEFAULT}" fi diff --git a/src/parallel.sh b/src/parallel.sh index e4a0163c..b130b331 100755 --- a/src/parallel.sh +++ b/src/parallel.sh @@ -83,3 +83,8 @@ function parallel::reset() { rm -rf "$TEMP_DIR_PARALLEL_TEST_SUITE" [ -f "$TEMP_FILE_PARALLEL_STOP_ON_FAILURE" ] && rm "$TEMP_FILE_PARALLEL_STOP_ON_FAILURE" } + +function parallel::is_enabled() { + [[ $(env::is_parallel_run_enabled) \ + && ($(check_os::is_macos) || $(check_os::is_ubuntu)) ]] +} diff --git a/src/runner.sh b/src/runner.sh index e46c3124..27b04d5a 100755 --- a/src/runner.sh +++ b/src/runner.sh @@ -13,7 +13,7 @@ function runner::load_test_files() { # shellcheck source=/dev/null source "$test_file" runner::run_set_up_before_script - if env::is_parallel_run_enabled; then + if parallel::is_enabled; then runner::call_test_functions "$test_file" "$filter" 2>/dev/null & else runner::call_test_functions "$test_file" "$filter" @@ -22,7 +22,7 @@ function runner::load_test_files() { runner::clean_set_up_and_tear_down_after_script done - if env::is_parallel_run_enabled; then + if parallel::is_enabled; then wait runner::spinner & local spinner_pid=$! @@ -74,14 +74,14 @@ function runner::call_test_functions() { return fi - if ! env::is_simple_output_enabled && ! env::is_parallel_run_enabled; then + if ! env::is_simple_output_enabled && ! parallel::is_enabled; then echo "Running $script" fi helper::check_duplicate_functions "$script" || true for function_name in "${functions_to_run[@]}"; do - if env::is_parallel_run_enabled && parallel::must_stop_on_failure; then + if parallel::is_enabled && parallel::must_stop_on_failure; then break fi @@ -193,7 +193,7 @@ function runner::run_test() { runner::write_failure_result_output "$test_file" "$subshell_output" if env::is_stop_on_failure_enabled; then - if env::is_parallel_run_enabled; then + if parallel::is_enabled; then parallel::mark_stop_on_failure else exit "$EXIT_CODE_STOP_ON_FAILURE" @@ -249,7 +249,7 @@ function runner::parse_result() { shift local args=("$@") - if env::is_parallel_run_enabled; then + if parallel::is_enabled; then runner::parse_result_parallel "$function_name" "$execution_result" "${args[@]}" else runner::parse_result_sync "$function_name" "$execution_result" diff --git a/src/state.sh b/src/state.sh index 03078121..6eea2dbf 100644 --- a/src/state.sh +++ b/src/state.sh @@ -205,7 +205,7 @@ function state::print_line() { *) char="?" && log "warning" "unknown test type '$type'" ;; esac - if env::is_parallel_run_enabled; then + if parallel::is_enabled; then printf "%s" "$char" else if (( _TOTAL_TESTS_COUNT % 50 == 0 )); then From a5800c5cd3d8ffd6007520525e581160a91e9d55 Mon Sep 17 00:00:00 2001 From: Chemaclass Date: Sun, 13 Oct 2024 08:49:38 +0200 Subject: [PATCH 3/7] rollback changes on tests CI --- .github/workflows/tests.yml | 83 ++++++++++++++++++------------------- 1 file changed, 41 insertions(+), 42 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 86697c27..b8b26afc 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -7,9 +7,8 @@ on: - main jobs: - - simple-output: - name: "${{ matrix.os }} - simple & sync" + ubuntu-macos: + name: "On ${{ matrix.os }}" timeout-minutes: 10 runs-on: ${{ matrix.os }} strategy: @@ -24,18 +23,30 @@ jobs: fetch-depth: 1 - name: Run Tests - run: | - ./bashunit --simple --no-parallel tests/ + run: make test - simple-output-parallel: - name: "${{ matrix.os }} - simple & parallel" + windows: + name: "On windows (${{ matrix.test_chunk }})" timeout-minutes: 10 - runs-on: ${{ matrix.os }} + runs-on: windows-latest strategy: matrix: - os: - - ubuntu-latest - - macos-latest + test_chunk: [acceptance, functional, unit] + fail-fast: false + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 1 + + - name: Run tests + shell: bash + run: | + ./bashunit tests/${{ matrix.test_chunk }}/*_test.sh + + alpine: + name: "On alpine-latest" + runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 @@ -44,17 +55,16 @@ jobs: - name: Run Tests run: | - ./bashunit --simple --parallel tests/ + docker run --rm -v "$(pwd)":/project alpine:latest /bin/sh -c " \ + apk update && \ + apk add --no-cache bash make git && \ + adduser -D builder && \ + chown -R builder /project && \ + su - builder -c 'cd /project; make test';" - detailed-output-parallel: - name: "${{ matrix.os }} - detailed & parallel" - timeout-minutes: 10 - runs-on: ${{ matrix.os }} - strategy: - matrix: - os: - - ubuntu-latest - - macos-latest + simple-output: + name: "Simple output" + runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 @@ -63,29 +73,23 @@ jobs: - name: Run Tests run: | - ./bashunit --detailed --parallel tests/ + ./bashunit --simple tests/ - windows: - name: "windows (${{ matrix.test_chunk }})" - timeout-minutes: 10 - runs-on: windows-latest - strategy: - matrix: - test_chunk: [acceptance, functional, unit] - fail-fast: false + simple-output-parallel: + name: "Simple output in parallel" + runs-on: ubuntu-latest steps: - - name: Checkout code + - name: Checkout uses: actions/checkout@v4 with: fetch-depth: 1 - - name: Run tests - shell: bash + - name: Run Tests run: | - ./bashunit tests/${{ matrix.test_chunk }}/*_test.sh + ./bashunit --parallel --simple tests/ - alpine: - name: "alpine-latest" + extended-output-parallel: + name: "Extended output in parallel" runs-on: ubuntu-latest steps: - name: Checkout @@ -95,9 +99,4 @@ jobs: - name: Run Tests run: | - docker run --rm -v "$(pwd)":/project alpine:latest /bin/sh -c " \ - apk update && \ - apk add --no-cache bash make git && \ - adduser -D builder && \ - chown -R builder /project && \ - su - builder -c 'cd /project; make test';" + ./bashunit --parallel tests/ From 1309f544519325f04ea0d26838721e81928d03b4 Mon Sep 17 00:00:00 2001 From: Chemaclass Date: Sun, 13 Oct 2024 08:50:41 +0200 Subject: [PATCH 4/7] feat: add docker/ubuntu to makefile --- Makefile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Makefile b/Makefile index a4605d0b..d26f1879 100644 --- a/Makefile +++ b/Makefile @@ -72,6 +72,10 @@ docker/alpine: @docker run --rm -it -v "$(shell pwd)":/project -w /project alpine:latest \ sh -c "apk add bash make shellcheck git && bash" +docker/ubuntu: + @docker run --rm -it -v "$(shell pwd)":/project -w /project ubuntu:latest \ + sh -c "apt update && apt install -y bash make shellcheck git && bash" + env/example: @echo "Copying variables without the values from .env into .env.example" @sed 's/=.*/=/' .env > .env.example From 219f4264aba4f8fdc9ef698c001267010f27bbb7 Mon Sep 17 00:00:00 2001 From: Chemaclass Date: Sun, 13 Oct 2024 08:56:46 +0200 Subject: [PATCH 5/7] fix: parallel::is_enabled --- src/parallel.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/parallel.sh b/src/parallel.sh index b130b331..4412e715 100755 --- a/src/parallel.sh +++ b/src/parallel.sh @@ -85,6 +85,8 @@ function parallel::reset() { } function parallel::is_enabled() { - [[ $(env::is_parallel_run_enabled) \ - && ($(check_os::is_macos) || $(check_os::is_ubuntu)) ]] + if env::is_parallel_run_enabled && (check_os::is_macos || check_os::is_ubuntu); then + return 0 + fi + return 1 } From 58a3407286db7a10be6f124db791faaa8f081e74 Mon Sep 17 00:00:00 2001 From: Chemaclass Date: Sun, 13 Oct 2024 09:03:18 +0200 Subject: [PATCH 6/7] feat: display test number only when not running in parallel --- src/runner.sh | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/runner.sh b/src/runner.sh index 27b04d5a..aa80890c 100755 --- a/src/runner.sh +++ b/src/runner.sh @@ -349,7 +349,12 @@ function runner::write_failure_result_output() { local test_file=$1 local error_msg=$2 - echo -e "$(state::get_tests_failed)) $test_file\n$error_msg" >> "$FAILURES_OUTPUT_PATH" + local test_nr="*" + if ! parallel::is_enabled; then + test_nr=$(state::get_tests_failed) + fi + + echo -e "$test_nr) $test_file\n$error_msg" >> "$FAILURES_OUTPUT_PATH" } function runner::run_set_up() { From f63ae3a1705b52ba395e67b9fd80212d454cd268 Mon Sep 17 00:00:00 2001 From: Chemaclass Date: Sun, 13 Oct 2024 09:27:42 +0200 Subject: [PATCH 7/7] feat: run log only on dev_mode --- src/globals.sh | 4 ++++ tests/unit/globals_test.sh | 8 ++++++++ 2 files changed, 12 insertions(+) diff --git a/src/globals.sh b/src/globals.sh index 4ff70e2c..748bf524 100644 --- a/src/globals.sh +++ b/src/globals.sh @@ -50,6 +50,10 @@ function cleanup_temp_files() { # shellcheck disable=SC2145 function log() { + if ! env::is_dev_mode_enabled; then + return + fi + local level="$1" shift diff --git a/tests/unit/globals_test.sh b/tests/unit/globals_test.sh index cf879169..e8d4aa28 100644 --- a/tests/unit/globals_test.sh +++ b/tests/unit/globals_test.sh @@ -10,6 +10,14 @@ function tear_down() { rm "$BASHUNIT_DEV_LOG" } +function set_up_before_script() { + export BASHUNIT_DEV_MODE=true +} + +function tear_down_after_script() { + export BASHUNIT_DEV_MODE=$_DEFAULT_DEV_MODE +} + function test_globals_current_dir() { assert_same "tests/unit" "$(current_dir)" }