#!/bin/bash
# This utility file contains functions that format test output to be parsed into jUnit XML
# os::test::junit::declare_suite_start prints a message declaring the start of a test suite
# Any number of suites can be in flight at any time, so there is no failure condition for this
# script based on the number of suites in flight.
#
# Globals:
# - JUNIT_REPORT_OUTPUT
# - NUM_OS_JUNIT_SUITES_IN_FLIGHT
# Arguments:
# - 1: the suite name that is starting
# Returns:
# - increment NUM_OS_JUNIT_SUITES_IN_FLIGHT
function os::test::junit::declare_suite_start() {
local suite_name=$1
local num_suites=${NUM_OS_JUNIT_SUITES_IN_FLIGHT:-0}
echo "=== BEGIN TEST SUITE github.com/openshift/origin/test/${suite_name} ===" >> "${JUNIT_REPORT_OUTPUT:-/dev/null}"
NUM_OS_JUNIT_SUITES_IN_FLIGHT=$(( ${num_suites} + 1 ))
export NUM_OS_JUNIT_SUITES_IN_FLIGHT
}
# os::test::junit::declare_suite_end prints a message declaring the end of a test suite
# If there aren't any suites in flight, this function will fail.
#
# Globals:
# - JUNIT_REPORT_OUTPUT
# - NUM_OS_JUNIT_SUITES_IN_FLIGHT
# Arguments:
# - 1: the suite name that is starting
# Returns:
# - export/decrement NUM_OS_JUNIT_SUITES_IN_FLIGHT
function os::test::junit::declare_suite_end() {
local num_suites=${NUM_OS_JUNIT_SUITES_IN_FLIGHT:-0}
if [[ "${num_suites}" -lt "1" ]]; then
# we can't end a suite if none have been started yet
echo "[ERROR] jUnit suite marker could not be placed, expected suites in flight, got ${num_suites}"
return 1
fi
echo "=== END TEST SUITE ===" >> "${JUNIT_REPORT_OUTPUT:-/dev/null}"
NUM_OS_JUNIT_SUITES_IN_FLIGHT=$(( ${num_suites} - 1 ))
export NUM_OS_JUNIT_SUITES_IN_FLIGHT
}
# os::test::junit::declare_test_start prints a message declaring the start of a test case
# If there is already a test marked as being in flight, this function will fail.
#
# Globals:
# - JUNIT_REPORT_OUTPUT
# - NUM_OS_JUNIT_TESTS_IN_FLIGHT
# Arguments:
# None
# Returns:
# - increment NUM_OS_JUNIT_TESTS_IN_FLIGHT
function os::test::junit::declare_test_start() {
local num_tests=${NUM_OS_JUNIT_TESTS_IN_FLIGHT:-0}
if [[ "${num_tests}" -ne "0" ]]; then
# someone's declaring the starting of a test when a test is already in flight
echo "[ERROR] jUnit test marker could not be placed, expected no tests in flight, got ${num_tests}"
return 1
fi
local num_suites=${NUM_OS_JUNIT_SUITES_IN_FLIGHT:-0}
if [[ "${num_suites}" -lt "1" ]]; then
# we can't end a test if no suites are in flight
echo "[ERROR] jUnit test marker could not be placed, expected suites in flight, got ${num_suites}"
return 1
fi
echo "=== BEGIN TEST CASE ===" >> "${JUNIT_REPORT_OUTPUT:-/dev/null}"
NUM_OS_JUNIT_TESTS_IN_FLIGHT=$(( ${num_tests} + 1 ))
export NUM_OS_JUNIT_TESTS_IN_FLIGHT
}
# os::test::junit::declare_test_end prints a message declaring the end of a test case
# If there is no test marked as being in flight, this function will fail.
#
# Globals:
# - JUNIT_REPORT_OUTPUT
# - NUM_OS_JUNIT_TESTS_IN_FLIGHT
# Arguments:
# None
# Returns:
# - decrement NUM_OS_JUNIT_TESTS_IN_FLIGHT
function os::test::junit::declare_test_end() {
local num_tests=${NUM_OS_JUNIT_TESTS_IN_FLIGHT:-0}
if [[ "${num_tests}" -ne "1" ]]; then
# someone's declaring the end of a test when a test is not in flight
echo "[ERROR] jUnit test marker could not be placed, expected one test in flight, got ${num_tests}"
return 1
fi
echo "=== END TEST CASE ===" >> "${JUNIT_REPORT_OUTPUT:-/dev/null}"
NUM_OS_JUNIT_TESTS_IN_FLIGHT=$(( ${num_tests} - 1 ))
export NUM_OS_JUNIT_TESTS_IN_FLIGHT
}
# os::test::junit::check_test_counters checks that we do not have any test suites or test cases in flight
# This function should be called at the very end of any test script using jUnit markers to make sure no error in
# marking has occured.
#
# Globals:
# - NUM_OS_JUNIT_SUITES_IN_FLIGHT
# - NUM_OS_JUNIT_TESTS_IN_FLIGHT
# Arguments:
# None
# Returns:
# None
function os::test::junit::check_test_counters() {
if [[ "${NUM_OS_JUNIT_SUITES_IN_FLIGHT-}" -ne "0" ]]; then
echo "[ERROR] Expected no test suites to be marked as in-flight at the end of testing, got ${NUM_OS_JUNIT_SUITES_IN_FLIGHT-}"
return 1
elif [[ "${NUM_OS_JUNIT_TESTS_IN_FLIGHT-}" -ne "0" ]]; then
echo "[ERROR] Expected no test cases to be marked as in-flight at the end of testing, got ${NUM_OS_JUNIT_TESTS_IN_FLIGHT-}"
return 1
fi
}
# os::test::junit::reconcile_output appends the necessary suite and test end statements to the jUnit output file
# in order to ensure that the file is in a consistent state to allow for parsing
#
# Globals:
# - NUM_OS_JUNIT_SUITES_IN_FLIGHT
# - NUM_OS_JUNIT_TESTS_IN_FLIGHT
# Arguments:
# None
# Returns:
# None
function os::test::junit::reconcile_output() {
if [[ "${NUM_OS_JUNIT_TESTS_IN_FLIGHT:-0}" = "1" ]]; then
os::test::junit::declare_test_end
fi
for (( i = 0; i < ${NUM_OS_JUNIT_SUITES_IN_FLIGHT:-0}; i++ )); do
os::test::junit::declare_suite_end
done
}