xref: /aosp_15_r20/external/tink/kokoro/testutils/test_utils.sh (revision e7b1675dde1b92d52ec075b0a92829627f2c52a5)
1*e7b1675dSTing-Kang Chang#!/bin/bash
2*e7b1675dSTing-Kang Chang# Copyright 2022 Google LLC
3*e7b1675dSTing-Kang Chang#
4*e7b1675dSTing-Kang Chang# Licensed under the Apache License, Version 2.0 (the "License");
5*e7b1675dSTing-Kang Chang# you may not use this file except in compliance with the License.
6*e7b1675dSTing-Kang Chang# You may obtain a copy of the License at
7*e7b1675dSTing-Kang Chang#
8*e7b1675dSTing-Kang Chang#      http://www.apache.org/licenses/LICENSE-2.0
9*e7b1675dSTing-Kang Chang#
10*e7b1675dSTing-Kang Chang# Unless required by applicable law or agreed to in writing, software
11*e7b1675dSTing-Kang Chang# distributed under the License is distributed on an "AS IS" BASIS,
12*e7b1675dSTing-Kang Chang# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*e7b1675dSTing-Kang Chang# See the License for the specific language governing permissions and
14*e7b1675dSTing-Kang Chang# limitations under the License.
15*e7b1675dSTing-Kang Chang################################################################################
16*e7b1675dSTing-Kang Chang
17*e7b1675dSTing-Kang Chang# Set of utilities to run unit tests for bash scripts.
18*e7b1675dSTing-Kang Chang#
19*e7b1675dSTing-Kang Chang# Example usage:
20*e7b1675dSTing-Kang Chang# From your test script:
21*e7b1675dSTing-Kang Chang#   source some/path/to/test_utils.sh
22*e7b1675dSTing-Kang Chang#
23*e7b1675dSTing-Kang Chang#   # Test functions must be defined as follows:
24*e7b1675dSTing-Kang Chang#   test_<Test Name>_<Test Case Name>() {
25*e7b1675dSTing-Kang Chang#     # Do some ground work.
26*e7b1675dSTing-Kang Chang#     # Run the test script.
27*e7b1675dSTing-Kang Chang#     ./path/to/script_to_test <input1> <input2> ...
28*e7b1675dSTing-Kang Chang#     ASSERT_CMD_SUCCEEDED
29*e7b1675dSTing-Kang Chang#     ASSERT_FILE_EQUALS <file1> <file2>
30*e7b1675dSTing-Kang Chang#   }
31*e7b1675dSTing-Kang Chang#
32*e7b1675dSTing-Kang Chang#   # Finds all the functions starting with `test_`, extracts test name and
33*e7b1675dSTing-Kang Chang#   # test case, and run them.
34*e7b1675dSTing-Kang Chang#   run_all_tests "$@"
35*e7b1675dSTing-Kang Chang#
36*e7b1675dSTing-Kang Chang
37*e7b1675dSTing-Kang Chang# This is either set by Bazel or generated.
38*e7b1675dSTing-Kang Chang: "${TEST_TMPDIR:="$(mktemp -td test.XXXXX)"}"
39*e7b1675dSTing-Kang Changreadonly TEST_TMPDIR
40*e7b1675dSTing-Kang Chang
41*e7b1675dSTing-Kang Chang# Temporary directory for the testcase to use.
42*e7b1675dSTing-Kang ChangTEST_CASE_TMPDIR=
43*e7b1675dSTing-Kang Chang
44*e7b1675dSTing-Kang Chang# Current test name.
45*e7b1675dSTing-Kang Chang_CURRENT_TEST_SCOPE=
46*e7b1675dSTing-Kang Chang
47*e7b1675dSTing-Kang Chang# Current test case.
48*e7b1675dSTing-Kang Chang_CURRENT_TEST_CASE=
49*e7b1675dSTing-Kang Chang
50*e7b1675dSTing-Kang Chang# True if at least one of the test cases terminated with an error.
51*e7b1675dSTing-Kang Chang_HAS_ERROR="false"
52*e7b1675dSTing-Kang Chang
53*e7b1675dSTing-Kang Chang_print_testcase_failed_and_exit() {
54*e7b1675dSTing-Kang Chang  echo "[   FAILED ] ${_CURRENT_TEST_SCOPE}.${_CURRENT_TEST_CASE}"
55*e7b1675dSTing-Kang Chang  exit 1
56*e7b1675dSTing-Kang Chang}
57*e7b1675dSTing-Kang Chang
58*e7b1675dSTing-Kang Chang#######################################
59*e7b1675dSTing-Kang Chang# Starts a new test case.
60*e7b1675dSTing-Kang Chang#
61*e7b1675dSTing-Kang Chang# Globals:
62*e7b1675dSTing-Kang Chang#   _CURRENT_TEST_SCOPE
63*e7b1675dSTing-Kang Chang#   _CURRENT_TEST_CASE
64*e7b1675dSTing-Kang Chang#######################################
65*e7b1675dSTing-Kang Chang_start_test_case() {
66*e7b1675dSTing-Kang Chang  echo "[ RUN      ] ${_CURRENT_TEST_SCOPE}.${_CURRENT_TEST_CASE}"
67*e7b1675dSTing-Kang Chang  # Create a tmp dir for the test case.
68*e7b1675dSTing-Kang Chang  TEST_CASE_TMPDIR="${TEST_TMPDIR}/${_CURRENT_TEST_SCOPE}/${_CURRENT_TEST_CASE}"
69*e7b1675dSTing-Kang Chang  mkdir -p "${TEST_CASE_TMPDIR}"
70*e7b1675dSTing-Kang Chang}
71*e7b1675dSTing-Kang Chang
72*e7b1675dSTing-Kang Chang#######################################
73*e7b1675dSTing-Kang Chang# Ends a test case printing a success message.
74*e7b1675dSTing-Kang Chang#
75*e7b1675dSTing-Kang Chang# Globals:
76*e7b1675dSTing-Kang Chang#   _CURRENT_TEST_SCOPE
77*e7b1675dSTing-Kang Chang#   _CURRENT_TEST_CASE
78*e7b1675dSTing-Kang Chang#######################################
79*e7b1675dSTing-Kang Chang_end_test_case_with_success() {
80*e7b1675dSTing-Kang Chang  test_case="$1"
81*e7b1675dSTing-Kang Chang  echo "[       OK ] ${_CURRENT_TEST_SCOPE}.${_CURRENT_TEST_CASE}"
82*e7b1675dSTing-Kang Chang}
83*e7b1675dSTing-Kang Chang
84*e7b1675dSTing-Kang Chang#######################################
85*e7b1675dSTing-Kang Chang# Returns the list of tests defined in the test script.
86*e7b1675dSTing-Kang Chang#
87*e7b1675dSTing-Kang Chang# A test case is a function of the form:
88*e7b1675dSTing-Kang Chang#     test_<Test Name>_<Test Case>
89*e7b1675dSTing-Kang Chang#
90*e7b1675dSTing-Kang Chang# This function returns all the functions starting with `test_`.
91*e7b1675dSTing-Kang Chang#
92*e7b1675dSTing-Kang Chang# Globals:
93*e7b1675dSTing-Kang Chang#   None
94*e7b1675dSTing-Kang Chang# Arguments:
95*e7b1675dSTing-Kang Chang#   None
96*e7b1675dSTing-Kang Chang#######################################
97*e7b1675dSTing-Kang Chang_get_all_tests() {
98*e7b1675dSTing-Kang Chang  declare -F |
99*e7b1675dSTing-Kang Chang    while read line; do
100*e7b1675dSTing-Kang Chang      case "${line}" in "declare -f test_"*)
101*e7b1675dSTing-Kang Chang          echo "${line#declare -f }"
102*e7b1675dSTing-Kang Chang        ;;
103*e7b1675dSTing-Kang Chang      esac
104*e7b1675dSTing-Kang Chang    done
105*e7b1675dSTing-Kang Chang}
106*e7b1675dSTing-Kang Chang
107*e7b1675dSTing-Kang Chang#######################################
108*e7b1675dSTing-Kang Chang# Runs a given test function.
109*e7b1675dSTing-Kang Chang#
110*e7b1675dSTing-Kang Chang# A test case is a function of the form:
111*e7b1675dSTing-Kang Chang#     test_<Test Name>_<Test Case>
112*e7b1675dSTing-Kang Chang#
113*e7b1675dSTing-Kang Chang# This script extracts test name and test case from the name.
114*e7b1675dSTing-Kang Chang#
115*e7b1675dSTing-Kang Chang# Globals:
116*e7b1675dSTing-Kang Chang#   _CURRENT_TEST_SCOPE
117*e7b1675dSTing-Kang Chang# Arguments:
118*e7b1675dSTing-Kang Chang#   None
119*e7b1675dSTing-Kang Chang#######################################
120*e7b1675dSTing-Kang Chang_do_run_test() {
121*e7b1675dSTing-Kang Chang  test_function="$1"
122*e7b1675dSTing-Kang Chang  IFS=_ read _CURRENT_TEST_SCOPE _CURRENT_TEST_CASE <<< "${test_function#test_}"
123*e7b1675dSTing-Kang Chang  _start_test_case
124*e7b1675dSTing-Kang Chang  (
125*e7b1675dSTing-Kang Chang    # Make sure we exit only when assertions fail.
126*e7b1675dSTing-Kang Chang    set +e
127*e7b1675dSTing-Kang Chang    "${test_function}"
128*e7b1675dSTing-Kang Chang  )
129*e7b1675dSTing-Kang Chang  local -r result=$?
130*e7b1675dSTing-Kang Chang  if (( $result == 0 )); then
131*e7b1675dSTing-Kang Chang    _end_test_case_with_success
132*e7b1675dSTing-Kang Chang  else
133*e7b1675dSTing-Kang Chang    _HAS_ERROR="true"
134*e7b1675dSTing-Kang Chang  fi
135*e7b1675dSTing-Kang Chang}
136*e7b1675dSTing-Kang Chang
137*e7b1675dSTing-Kang Chang#######################################
138*e7b1675dSTing-Kang Chang# Runs all the test cases defined in the test script file.
139*e7b1675dSTing-Kang Chang# Globals:
140*e7b1675dSTing-Kang Chang#   None
141*e7b1675dSTing-Kang Chang# Arguments:
142*e7b1675dSTing-Kang Chang#   None
143*e7b1675dSTing-Kang Chang#
144*e7b1675dSTing-Kang Chang#######################################
145*e7b1675dSTing-Kang Changrun_all_tests() {
146*e7b1675dSTing-Kang Chang  for test in $(_get_all_tests); do
147*e7b1675dSTing-Kang Chang    _do_run_test "${test}"
148*e7b1675dSTing-Kang Chang  done
149*e7b1675dSTing-Kang Chang  # Make sure we return an error code for the failing test
150*e7b1675dSTing-Kang Chang  if [[ "${_HAS_ERROR}" == "true" ]]; then
151*e7b1675dSTing-Kang Chang    exit 1
152*e7b1675dSTing-Kang Chang  fi
153*e7b1675dSTing-Kang Chang}
154*e7b1675dSTing-Kang Chang
155*e7b1675dSTing-Kang ChangASSERT_CMD_SUCCEEDED() {
156*e7b1675dSTing-Kang Chang  if (( $? != 0 )); then
157*e7b1675dSTing-Kang Chang      _print_testcase_failed_and_exit
158*e7b1675dSTing-Kang Chang  fi
159*e7b1675dSTing-Kang Chang}
160*e7b1675dSTing-Kang Chang
161*e7b1675dSTing-Kang ChangASSERT_CMD_FAILED() {
162*e7b1675dSTing-Kang Chang  if (( $? == 0 )); then
163*e7b1675dSTing-Kang Chang      _print_testcase_failed_and_exit
164*e7b1675dSTing-Kang Chang  fi
165*e7b1675dSTing-Kang Chang}
166*e7b1675dSTing-Kang Chang
167*e7b1675dSTing-Kang ChangASSERT_FILE_EQUALS() {
168*e7b1675dSTing-Kang Chang  input_file="$1"
169*e7b1675dSTing-Kang Chang  expected_file="$2"
170*e7b1675dSTing-Kang Chang  if ! diff "${input_file}" "${expected_file}"; then
171*e7b1675dSTing-Kang Chang    _print_testcase_failed_and_exit
172*e7b1675dSTing-Kang Chang  fi
173*e7b1675dSTing-Kang Chang}
174