1# Copyright 2020 The Bazel Authors. All rights reserved. 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14 15# Support for unittest.bash 16 17#### Set up the test environment. 18 19set -euo pipefail 20 21cat_jvm_log () { 22 if [[ "$log_content" =~ \ 23 "(error code:".*", error message: '".*"', log file: '"(.*)"')" ]]; then 24 echo >&2 25 echo "Content of ${BASH_REMATCH[1]}:" >&2 26 cat "${BASH_REMATCH[1]}" >&2 27 fi 28} 29 30# Print message in "$1" then exit with status "$2" 31die () { 32 # second argument is optional, defaulting to 1 33 local status_code=${2:-1} 34 # Stop capturing stdout/stderr, and dump captured output 35 if [[ "$CAPTURED_STD_ERR" -ne 0 || "$CAPTURED_STD_OUT" -ne 0 ]]; then 36 restore_outputs 37 if [[ "$CAPTURED_STD_OUT" -ne 0 ]]; then 38 cat "${TEST_TMPDIR}/captured.out" 39 CAPTURED_STD_OUT=0 40 fi 41 if [[ "$CAPTURED_STD_ERR" -ne 0 ]]; then 42 cat "${TEST_TMPDIR}/captured.err" 1>&2 43 cat_jvm_log "$(cat "${TEST_TMPDIR}/captured.err")" 44 CAPTURED_STD_ERR=0 45 fi 46 fi 47 48 if [[ -n "${1-}" ]] ; then 49 echo "$1" 1>&2 50 fi 51 if [[ -n "${BASH-}" ]]; then 52 local caller_n=0 53 while [[ $caller_n -lt 4 ]] && \ 54 caller_out=$(caller $caller_n 2>/dev/null); do 55 test $caller_n -eq 0 && echo "CALLER stack (max 4):" 56 echo " $caller_out" 57 let caller_n=caller_n+1 58 done 1>&2 59 fi 60 if [[ -n "${status_code}" && "${status_code}" -ne 0 ]]; then 61 exit "$status_code" 62 else 63 exit 1 64 fi 65} 66 67# Print message in "$1" then record that a non-fatal error occurred in 68# ERROR_COUNT 69ERROR_COUNT="${ERROR_COUNT:-0}" 70error () { 71 if [[ -n "$1" ]] ; then 72 echo "$1" 1>&2 73 fi 74 ERROR_COUNT=$(($ERROR_COUNT + 1)) 75} 76 77# Die if "$1" != "$2", print $3 as death reason 78check_eq () { 79 [[ "$1" = "$2" ]] || die "Check failed: '$1' == '$2' ${3:+ ($3)}" 80} 81 82# Die if "$1" == "$2", print $3 as death reason 83check_ne () { 84 [[ "$1" != "$2" ]] || die "Check failed: '$1' != '$2' ${3:+ ($3)}" 85} 86 87# The structure of the following if statements is such that if '[[' fails 88# (e.g., a non-number was passed in) then the check will fail. 89 90# Die if "$1" > "$2", print $3 as death reason 91check_le () { 92 [[ "$1" -gt "$2" ]] || die "Check failed: '$1' <= '$2' ${3:+ ($3)}" 93} 94 95# Die if "$1" >= "$2", print $3 as death reason 96check_lt () { 97 [[ "$1" -lt "$2" ]] || die "Check failed: '$1' < '$2' ${3:+ ($3)}" 98} 99 100# Die if "$1" < "$2", print $3 as death reason 101check_ge () { 102 [[ "$1" -ge "$2" ]] || die "Check failed: '$1' >= '$2' ${3:+ ($3)}" 103} 104 105# Die if "$1" <= "$2", print $3 as death reason 106check_gt () { 107 [[ "$1" -gt "$2" ]] || die "Check failed: '$1' > '$2' ${3:+ ($3)}" 108} 109 110# Die if $2 !~ $1; print $3 as death reason 111check_match () 112{ 113 expr match "$2" "$1" >/dev/null || \ 114 die "Check failed: '$2' does not match regex '$1' ${3:+ ($3)}" 115} 116 117# Run command "$1" at exit. Like "trap" but multiple atexits don't 118# overwrite each other. Will break if someone does call trap 119# directly. So, don't do that. 120ATEXIT="${ATEXIT-}" 121atexit () { 122 if [[ -z "$ATEXIT" ]]; then 123 ATEXIT="$1" 124 else 125 ATEXIT="$1 ; $ATEXIT" 126 fi 127 trap "$ATEXIT" EXIT 128} 129 130## TEST_TMPDIR 131if [[ -z "${TEST_TMPDIR:-}" ]]; then 132 export TEST_TMPDIR="$(mktemp -d ${TMPDIR:-/tmp}/bazel-test.XXXXXXXX)" 133fi 134if [[ ! -e "${TEST_TMPDIR}" ]]; then 135 mkdir -p -m 0700 "${TEST_TMPDIR}" 136 # Clean TEST_TMPDIR on exit 137 atexit "rm -fr ${TEST_TMPDIR}" 138fi 139 140# Functions to compare the actual output of a test to the expected 141# (golden) output. 142# 143# Usage: 144# capture_test_stdout 145# ... do something ... 146# diff_test_stdout "$TEST_SRCDIR/path/to/golden.out" 147 148# Redirect a file descriptor to a file. 149CAPTURED_STD_OUT="${CAPTURED_STD_OUT:-0}" 150CAPTURED_STD_ERR="${CAPTURED_STD_ERR:-0}" 151 152capture_test_stdout () { 153 exec 3>&1 # Save stdout as fd 3 154 exec 4>"${TEST_TMPDIR}/captured.out" 155 exec 1>&4 156 CAPTURED_STD_OUT=1 157} 158 159capture_test_stderr () { 160 exec 6>&2 # Save stderr as fd 6 161 exec 7>"${TEST_TMPDIR}/captured.err" 162 exec 2>&7 163 CAPTURED_STD_ERR=1 164} 165 166# Force XML_OUTPUT_FILE to an existing path 167if [[ -z "${XML_OUTPUT_FILE:-}" ]]; then 168 XML_OUTPUT_FILE=${TEST_TMPDIR}/output.xml 169fi 170 171# Functions to provide easy access to external repository outputs in the sibling 172# repository layout. 173# 174# Usage: 175# bin_dir <repository name> 176# genfiles_dir <repository name> 177# testlogs_dir <repository name> 178 179testlogs_dir() { 180 echo $(bazel info bazel-testlogs | sed "s|bazel-out|bazel-out/$1|") 181} 182