From e0158869b165c85e508318e2b6910fc3585ec5cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= Date: Mon, 19 Jan 2026 18:26:43 +0100 Subject: [PATCH] tests: Add common bats test runner function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add run_bats_tests() function to common.bash that provides consistent test execution and reporting across all test suites (k8s, nvidia, kata-deploy). This removes duplicated test runner code from run_kubernetes_tests.sh, run_kubernetes_nv_tests.sh, and run-kata-deploy-tests.sh. Signed-off-by: Fabiano FidĂȘncio --- .github/workflows/run-kata-deploy-tests.yaml | 2 +- tests/common.bash | 110 ++++++++++++++++++ tests/functional/kata-deploy/gha-run.sh | 5 + .../kata-deploy/run-kata-deploy-tests.sh | 10 +- tests/integration/kubernetes/gha-run.sh | 36 +----- .../kubernetes/run_kubernetes_nv_tests.sh | 28 +---- .../kubernetes/run_kubernetes_tests.sh | 28 +---- 7 files changed, 128 insertions(+), 91 deletions(-) diff --git a/.github/workflows/run-kata-deploy-tests.yaml b/.github/workflows/run-kata-deploy-tests.yaml index 6bdaed6e71..73b128d235 100644 --- a/.github/workflows/run-kata-deploy-tests.yaml +++ b/.github/workflows/run-kata-deploy-tests.yaml @@ -87,4 +87,4 @@ jobs: - name: Report tests if: always() - run: bash tests/integration/kubernetes/gha-run.sh report-tests + run: bash tests/functional/kata-deploy/gha-run.sh report-tests diff --git a/tests/common.bash b/tests/common.bash index e027bb59b6..3405910712 100644 --- a/tests/common.bash +++ b/tests/common.bash @@ -1022,3 +1022,113 @@ function version_greater_than_equal() { return 1 fi } + +# Run bats tests with proper reporting +# +# This function provides consistent test execution and reporting across +# all test suites (k8s, nvidia, kata-deploy, etc.) +# +# Parameters: +# $1 - Test directory (where tests are located and reports will be saved) +# $2 - Array name containing test files (passed by reference) +# +# Environment variables: +# BATS_TEST_FAIL_FAST - Set to "yes" to stop at first failure (default: "no") +# +# Example usage: +# tests=("test1.bats" "test2.bats") +# run_bats_tests "/path/to/tests" tests +# +function run_bats_tests() { + local test_dir="$1" + local -n test_array=$2 + local fail_fast="${BATS_TEST_FAIL_FAST:-no}" + + local report_dir="${test_dir}/reports/$(date +'%F-%T')" + mkdir -p "${report_dir}" + + info "Running tests with bats version: $(bats --version). Save outputs to ${report_dir}" + + local tests_fail=() + for test_entry in "${test_array[@]}"; do + test_entry=$(echo "${test_entry}" | tr -d '[:space:][:cntrl:]') + [ -z "${test_entry}" ] && continue + + info "Executing ${test_entry}" + + # Output file will be prefixed with "ok" or "not_ok" based on the result + local out_file="${report_dir}/${test_entry}.out" + + pushd "${test_dir}" > /dev/null + if ! bats --timing --show-output-of-passing-tests "${test_entry}" | tee "${out_file}"; then + tests_fail+=("${test_entry}") + mv "${out_file}" "$(dirname "${out_file}")/not_ok-$(basename "${out_file}")" + [[ "${fail_fast}" == "yes" ]] && break + else + mv "${out_file}" "$(dirname "${out_file}")/ok-$(basename "${out_file}")" + fi + popd > /dev/null + done + + if [[ ${#tests_fail[@]} -ne 0 ]]; then + die "Tests FAILED from suites: ${tests_fail[*]}" + fi + + info "All tests SUCCEEDED" +} + +# Report bats test results from the reports directory +# +# This function displays a summary of test results and outputs from +# the reports directory created by run_bats_tests(). +# +# Parameters: +# $1 - Test directory (where reports subdirectory is located) +# +# Example usage: +# report_bats_tests "/path/to/tests" +# +function report_bats_tests() { + local test_dir="$1" + local reports_dir="${test_dir}/reports" + + if [[ ! -d "${reports_dir}" ]]; then + warn "No reports directory found: ${reports_dir}" + return 1 + fi + + for report_dir in "${reports_dir}"/*; do + [[ ! -d "${report_dir}" ]] && continue + + local ok=() + local not_ok=() + mapfile -t ok < <(find "${report_dir}" -name "ok-*.out" 2>/dev/null) + mapfile -t not_ok < <(find "${report_dir}" -name "not_ok-*.out" 2>/dev/null) + + cat <<-EOF + SUMMARY ($(basename "${report_dir}")): + Pass: ${#ok[*]} + Fail: ${#not_ok[*]} + EOF + + echo -e "\nSTATUSES:" + for out in "${not_ok[@]}" "${ok[@]}"; do + [[ -z "${out}" ]] && continue + local status + local bats + status=$(basename "${out}" | cut -d '-' -f1) + bats=$(basename "${out}" | cut -d '-' -f2- | sed 's/.out$//') + echo " ${status} ${bats}" + done + + echo -e "\nOUTPUTS:" + for out in "${not_ok[@]}" "${ok[@]}"; do + [[ -z "${out}" ]] && continue + local bats + bats=$(basename "${out}" | cut -d '-' -f2- | sed 's/.out$//') + echo "::group::${bats}" + cat "${out}" + echo "::endgroup::" + done + done +} diff --git a/tests/functional/kata-deploy/gha-run.sh b/tests/functional/kata-deploy/gha-run.sh index ce116de111..07fa6310f4 100755 --- a/tests/functional/kata-deploy/gha-run.sh +++ b/tests/functional/kata-deploy/gha-run.sh @@ -20,6 +20,10 @@ function run_tests() { popd } +function report_tests() { + report_bats_tests "${kata_deploy_dir}" +} + function cleanup_runtimeclasses() { # Cleanup any runtime class that was left behind in the cluster, in # case of a test failure, apart from the default one that comes from @@ -59,6 +63,7 @@ function main() { install-kubectl) install_kubectl ;; get-cluster-credentials) get_cluster_credentials "kata-deploy" ;; run-tests) run_tests ;; + report-tests) report_tests ;; delete-cluster) cleanup "aks" "kata-deploy" ;; *) >&2 echo "Invalid argument"; exit 2 ;; esac diff --git a/tests/functional/kata-deploy/run-kata-deploy-tests.sh b/tests/functional/kata-deploy/run-kata-deploy-tests.sh index 2357e557f7..6a4ce72672 100644 --- a/tests/functional/kata-deploy/run-kata-deploy-tests.sh +++ b/tests/functional/kata-deploy/run-kata-deploy-tests.sh @@ -6,10 +6,14 @@ # set -e +set -o pipefail kata_deploy_dir=$(dirname "$(readlink -f "$0")") source "${kata_deploy_dir}/../../common.bash" +# Setting to "yes" enables fail fast, stopping execution at the first failed test. +export BATS_TEST_FAIL_FAST="${BATS_TEST_FAIL_FAST:-no}" + if [[ -n "${KATA_DEPLOY_TEST_UNION:-}" ]]; then KATA_DEPLOY_TEST_UNION=("${KATA_DEPLOY_TEST_UNION}") else @@ -18,8 +22,4 @@ else ) fi -info "Run tests" -for KATA_DEPLOY_TEST_ENTRY in "${KATA_DEPLOY_TEST_UNION[@]}" -do - bats --show-output-of-passing-tests "${KATA_DEPLOY_TEST_ENTRY}" -done +run_bats_tests "${kata_deploy_dir}" KATA_DEPLOY_TEST_UNION diff --git a/tests/integration/kubernetes/gha-run.sh b/tests/integration/kubernetes/gha-run.sh index 98cbac07a5..c55ad7d6c1 100755 --- a/tests/integration/kubernetes/gha-run.sh +++ b/tests/integration/kubernetes/gha-run.sh @@ -326,41 +326,7 @@ function run_tests() { # directory. # function report_tests() { - local reports_dir="${kubernetes_dir}/reports" - local ok - local not_ok - local status - - if [[ ! -d "${reports_dir}" ]]; then - info "no reports directory found: ${reports_dir}" - return - fi - - for report_dir in "${reports_dir}"/*; do - mapfile -t ok < <(find "${report_dir}" -name "ok-*.out") - mapfile -t not_ok < <(find "${report_dir}" -name "not_ok-*.out") - - cat <<-EOF - SUMMARY ($(basename "${report_dir}")): - Pass: ${#ok[*]} - Fail: ${#not_ok[*]} - EOF - - echo -e "\nSTATUSES:" - for out in "${not_ok[@]}" "${ok[@]}"; do - status=$(basename "${out}" | cut -d '-' -f1) - bats=$(basename "${out}" | cut -d '-' -f2- | sed 's/.out$//') - echo " ${status} ${bats}" - done - - echo -e "\nOUTPUTS:" - for out in "${not_ok[@]}" "${ok[@]}"; do - bats=$(basename "${out}" | cut -d '-' -f2- | sed 's/.out$//') - echo "::group::${bats}" - cat "${out}" - echo "::endgroup::" - done - done + report_bats_tests "${kubernetes_dir}" } function collect_artifacts() { diff --git a/tests/integration/kubernetes/run_kubernetes_nv_tests.sh b/tests/integration/kubernetes/run_kubernetes_nv_tests.sh index b75ca9d6de..3a6f3e4dbb 100644 --- a/tests/integration/kubernetes/run_kubernetes_nv_tests.sh +++ b/tests/integration/kubernetes/run_kubernetes_nv_tests.sh @@ -54,28 +54,6 @@ if [[ "${ENABLE_NVRC_TRACE:-true}" == "true" ]]; then enable_nvrc_trace fi -report_dir="${kubernetes_dir}/reports/$(date +'%F-%T')" -mkdir -p "${report_dir}" - -info "Running tests with bats version: $(bats --version). Save outputs to ${report_dir}" - -tests_fail=() -for K8S_TEST_ENTRY in "${K8S_TEST_NV[@]}" -do - K8S_TEST_ENTRY=$(echo "${K8S_TEST_ENTRY}" | tr -d '[:space:][:cntrl:]') - time info "$(kubectl get pods --all-namespaces 2>&1)" - info "Executing ${K8S_TEST_ENTRY}" - # Output file will be prefixed with "ok" or "not_ok" based on the result - out_file="${report_dir}/${K8S_TEST_ENTRY}.out" - if ! bats --timing --show-output-of-passing-tests "${K8S_TEST_ENTRY}" | tee "${out_file}"; then - tests_fail+=("${K8S_TEST_ENTRY}") - mv "${out_file}" "$(dirname "${out_file}")/not_ok-$(basename "${out_file}")" - [[ "${K8S_TEST_FAIL_FAST}" = "yes" ]] && break - else - mv "${out_file}" "$(dirname "${out_file}")/ok-$(basename "${out_file}")" - fi -done - -[[ ${#tests_fail[@]} -ne 0 ]] && die "Tests FAILED from suites: ${tests_fail[*]}" - -info "All tests SUCCEEDED" +# Use common bats test runner with proper reporting +export BATS_TEST_FAIL_FAST="${K8S_TEST_FAIL_FAST}" +run_bats_tests "${kubernetes_dir}" K8S_TEST_NV diff --git a/tests/integration/kubernetes/run_kubernetes_tests.sh b/tests/integration/kubernetes/run_kubernetes_tests.sh index 92097baeb8..a1c24c11d7 100755 --- a/tests/integration/kubernetes/run_kubernetes_tests.sh +++ b/tests/integration/kubernetes/run_kubernetes_tests.sh @@ -135,28 +135,6 @@ fi ensure_yq -report_dir="${kubernetes_dir}/reports/$(date +'%F-%T')" -mkdir -p "${report_dir}" - -info "Running tests with bats version: $(bats --version). Save outputs to ${report_dir}" - -tests_fail=() -for K8S_TEST_ENTRY in "${K8S_TEST_UNION[@]}" -do - K8S_TEST_ENTRY=$(echo "$K8S_TEST_ENTRY" | tr -d '[:space:][:cntrl:]') - time info "$(kubectl get pods --all-namespaces 2>&1)" - info "Executing ${K8S_TEST_ENTRY}" - # Output file will be prefixed with "ok" or "not_ok" based on the result - out_file="${report_dir}/${K8S_TEST_ENTRY}.out" - if ! bats --timing --show-output-of-passing-tests "${K8S_TEST_ENTRY}" | tee "${out_file}"; then - tests_fail+=("${K8S_TEST_ENTRY}") - mv "${out_file}" "$(dirname "${out_file}")/not_ok-$(basename "${out_file}")" - [ "${K8S_TEST_FAIL_FAST}" = "yes" ] && break - else - mv "${out_file}" "$(dirname "${out_file}")/ok-$(basename "${out_file}")" - fi -done - -[ ${#tests_fail[@]} -ne 0 ] && die "Tests FAILED from suites: ${tests_fail[*]}" - -info "All tests SUCCEEDED" +# Use common bats test runner with proper reporting +export BATS_TEST_FAIL_FAST="${K8S_TEST_FAIL_FAST}" +run_bats_tests "${kubernetes_dir}" K8S_TEST_UNION