#!/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 } readonly -f os::test::junit::declare_suite_start # 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 } readonly -f os::test::junit::declare_suite_end # 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 } readonly -f os::test::junit::declare_test_start # 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 } readonly -f os::test::junit::declare_test_end # 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 occurred. # # 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 } readonly -f os::test::junit::check_test_counters # 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 } readonly -f os::test::junit::reconcile_output