From 56d8a6880547dd37e3d4a40d690806562de95a2c Mon Sep 17 00:00:00 2001 From: Andrew Clemons Date: Fri, 20 Jan 2017 14:55:24 +1300 Subject: [PATCH] Configure travis to test with multiple bash versions This currently calls a script `test-with-all-bashes.sh` which tests using bash 3.1, 3.2 and 4.0 through 4.4, once with the initial release and again using the latest patchset for each version. Make note in the README that bash versions from 3.1 are supported. --- .travis.yml | 3 ++- README.md | 1 + libexec/bats | 4 ++-- libexec/bats-exec-test | 4 ++-- libexec/bats-preprocess | 2 +- test-with-all-bashes.sh | 44 +++++++++++++++++++++++++++++++++++++++++ test/bats.bats | 8 +++++--- 7 files changed, 57 insertions(+), 9 deletions(-) create mode 100755 test-with-all-bashes.sh diff --git a/.travis.yml b/.travis.yml index db06d9d7..72c775c0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,6 @@ language: c -script: bin/bats --tap test +script: + ./test-with-all-bashes.sh notifications: email: on_success: never diff --git a/README.md b/README.md index 235bf1ee..fb709371 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,7 @@ Bash's `errexit` (`set -e`) option when running test cases. If every command in the test case exits with a `0` status code (success), the test passes. In this way, each line is an assertion of truth. +Bats supports Bash version 3.1 and later. ## Running tests diff --git a/libexec/bats b/libexec/bats index 71f392f7..3bf5a795 100755 --- a/libexec/bats +++ b/libexec/bats @@ -116,11 +116,11 @@ for filename in "${arguments[@]}"; do if [ -d "$filename" ]; then shopt -s nullglob for suite_filename in "$(expand_path "$filename")"/*.bats; do - filenames["${#filenames[@]}"]="$suite_filename" + filenames[${#filenames[@]}]="$suite_filename" done shopt -u nullglob else - filenames["${#filenames[@]}"]="$(expand_path "$filename")" + filenames[${#filenames[@]}]="$(expand_path "$filename")" fi done diff --git a/libexec/bats-exec-test b/libexec/bats-exec-test index 8f3bd510..473028b8 100755 --- a/libexec/bats-exec-test +++ b/libexec/bats-exec-test @@ -89,7 +89,7 @@ bats_test_begin() { bats_test_function() { local test_name="$1" - BATS_TEST_NAMES["${#BATS_TEST_NAMES[@]}"]="$test_name" + BATS_TEST_NAMES[${#BATS_TEST_NAMES[@]}]="$test_name" } bats_capture_stack_trace() { @@ -104,7 +104,7 @@ bats_capture_stack_trace() { local index=1 while frame="$(caller "$index")"; do - BATS_CURRENT_STACK_TRACE["${#BATS_CURRENT_STACK_TRACE[@]}"]="$frame" + BATS_CURRENT_STACK_TRACE[${#BATS_CURRENT_STACK_TRACE[@]}]="$frame" if [[ "$frame" = *"$test_pattern" || \ "$frame" = *"$setup_pattern" || \ "$frame" = *"$teardown_pattern" ]]; then diff --git a/libexec/bats-preprocess b/libexec/bats-preprocess index 04297ed0..0098bc51 100755 --- a/libexec/bats-preprocess +++ b/libexec/bats-preprocess @@ -40,7 +40,7 @@ while IFS= read -r line; do body="${BASH_REMATCH[2]}" name="$(eval echo "$quoted_name")" encoded_name="$(encode_name "$name")" - tests["${#tests[@]}"]="$encoded_name" + tests[${#tests[@]}]="$encoded_name" echo "${encoded_name}() { bats_test_begin ${quoted_name} ${index}; ${body}" else printf "%s\n" "$line" diff --git a/test-with-all-bashes.sh b/test-with-all-bashes.sh new file mode 100755 index 00000000..953c09f7 --- /dev/null +++ b/test-with-all-bashes.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env bash + +set -e + +run_with_bash() { + # shellcheck disable=SC2016 + printf 'Running tests with bash %s\n\n' "$("$1/bash" -c 'echo $BASH_VERSION')" + + ( + PATH="$1":$PATH bin/bats --tap test + PATH="$1":$PATH bin/bats --pretty test + ) + + printf '\n' +} + +for v in 3.1 3.2 4.0 4.1 4.2 4.3 4.4 ; do + printf 'Building bash %s\n\n' $v + + wget --quiet https://ftp.gnu.org/gnu/bash/bash-$v.tar.gz + tar -xf bash-$v.tar.gz + rm bash-$v.tar.gz + + ( + cd bash-$v + ./configure > /dev/null 2>&1 + make > /dev/null 2>&1 + ) + + run_with_bash bash-$v + + printf 'Rebuilding bash %s with latest patch level\n\n' $v + ( + cd bash-$v + wget -q --cut-dirs=100 -r --no-parent https://ftp.gnu.org/gnu/bash/bash-$v-patches/ + mv ftp.gnu.org bash-$v-patches/ + ( cd bash-$v-patches && cat bash??-??? ) | patch -s -p0 || exit 1 + make > /dev/null 2>&1 + ) + + run_with_bash bash-$v + + rm -rf bash-$v +done diff --git a/test/bats.bats b/test/bats.bats index f1aff293..ad04aff5 100755 --- a/test/bats.bats +++ b/test/bats.bats @@ -131,8 +131,9 @@ fixtures bats PASS=1 run bats "$FIXTURE_ROOT/failing_teardown.bats" [ $status -eq 1 ] [ "${lines[1]}" = 'not ok 1 truth' ] - [ "${lines[2]}" = "# (from function \`teardown' in test file $RELATIVE_FIXTURE_ROOT/failing_teardown.bats, line 2)" ] - [ "${lines[3]}" = "# \`eval \"( exit \${STATUS:-1} )\"' failed" ] + # some versions of bash 4.0.x format this error slightly differently + [ "${lines[2]}" = "# (from function \`teardown' in test file $RELATIVE_FIXTURE_ROOT/failing_teardown.bats, line 1)" ] || [ "${lines[2]}" = "# (from function \`teardown' in test file $RELATIVE_FIXTURE_ROOT/failing_teardown.bats, line 2)" ] + [ "${lines[3]}" = "# \`teardown() {' failed" ] || [ "${lines[3]}" = "# \`eval \"( exit \${STATUS:-1} )\"' failed" ] } @test "failing test with teardown failure" { @@ -146,7 +147,8 @@ fixtures bats @test "teardown failure with significant status" { PASS=1 STATUS=2 run bats "$FIXTURE_ROOT/failing_teardown.bats" [ $status -eq 1 ] - [ "${lines[3]}" = "# \`eval \"( exit \${STATUS:-1} )\"' failed with status 2" ] + # some versions of bash 4.0.x format this error slightly differently + [ "${lines[3]}" = "# \`eval \"( exit \${STATUS:-1} )\"' failed with status 2" ] || [ "${lines[3]}" = "# \`teardown() {' failed with status 2" ] } @test "failing test file outside of BATS_CWD" {