Philip Tricca | 99d4142 | 2017-06-18 15:11:50 -0700 | [diff] [blame] | 1 | #!/usr/bin/env bash |
| 2 | #;**********************************************************************; |
dantpm | 01a01cd | 2018-02-27 11:25:01 -0800 | [diff] [blame] | 3 | # Copyright (c) 2017 - 2018, Intel Corporation |
Philip Tricca | 99d4142 | 2017-06-18 15:11:50 -0700 | [diff] [blame] | 4 | # All rights reserved. |
| 5 | # |
| 6 | # Redistribution and use in source and binary forms, with or without |
| 7 | # modification, are permitted provided that the following conditions are met: |
| 8 | # |
| 9 | # 1. Redistributions of source code must retain the above copyright notice, |
| 10 | # this list of conditions and the following disclaimer. |
| 11 | # |
| 12 | # 2. Redistributions in binary form must reproduce the above copyright notice, |
| 13 | # this list of conditions and the following disclaimer in the documentation |
| 14 | # and/or other materials provided with the distribution. |
| 15 | # |
| 16 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
| 17 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| 18 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| 19 | # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE |
| 20 | # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| 21 | # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| 22 | # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| 23 | # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
| 24 | # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| 25 | # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
| 26 | # THE POSSIBILITY OF SUCH DAMAGE. |
| 27 | #;**********************************************************************; |
| 28 | set -u |
| 29 | |
| 30 | usage_error () |
| 31 | { |
| 32 | echo "$0: $*" >&2 |
| 33 | print_usage >&2 |
| 34 | exit 2 |
| 35 | } |
| 36 | print_usage () |
| 37 | { |
| 38 | cat <<END |
| 39 | Usage: |
| 40 | int-log-compiler.sh --simulator-bin=FILE |
| 41 | TEST-SCRIPT [TEST-SCRIPT-ARGUMENTS] |
| 42 | The '--simulator-bin' option is mandatory. |
| 43 | END |
| 44 | } |
| 45 | while test $# -gt 0; do |
| 46 | case $1 in |
| 47 | --help) print_usage; exit $?;; |
| 48 | -s|--simulator-bin) SIM_BIN=$2; shift;; |
| 49 | -s=*|--simulator-bin=*) SIM_BIN="${1#*=}";; |
| 50 | --) shift; break;; |
| 51 | -*) usage_error "invalid option: '$1'";; |
| 52 | *) break;; |
| 53 | esac |
| 54 | shift |
| 55 | done |
| 56 | |
dantpm | 01a01cd | 2018-02-27 11:25:01 -0800 | [diff] [blame] | 57 | # Verify the running shell and OS environment is sufficient to run these tests. |
| 58 | sanity_test () |
| 59 | { |
Philip Tricca | 7397728 | 2018-03-12 11:10:43 -0700 | [diff] [blame] | 60 | # Check special file |
| 61 | if [ ! -e /dev/urandom ]; then |
dantpm | 01a01cd | 2018-02-27 11:25:01 -0800 | [diff] [blame] | 62 | echo "Missing file /dev/urandom; exiting" |
| 63 | exit 1 |
Philip Tricca | 7397728 | 2018-03-12 11:10:43 -0700 | [diff] [blame] | 64 | fi |
dantpm | 01a01cd | 2018-02-27 11:25:01 -0800 | [diff] [blame] | 65 | |
Philip Tricca | 7397728 | 2018-03-12 11:10:43 -0700 | [diff] [blame] | 66 | # Check ps |
| 67 | PS_LINES=$(ps -e 2>/dev/null | wc -l) |
| 68 | if [ "$PS_LINES" -eq 0 ] ; then |
dantpm | 01a01cd | 2018-02-27 11:25:01 -0800 | [diff] [blame] | 69 | echo "Command ps not listing processes; exiting" |
| 70 | exit 1 |
Philip Tricca | 7397728 | 2018-03-12 11:10:43 -0700 | [diff] [blame] | 71 | fi |
dantpm | 01a01cd | 2018-02-27 11:25:01 -0800 | [diff] [blame] | 72 | } |
| 73 | |
Philip Tricca | 99d4142 | 2017-06-18 15:11:50 -0700 | [diff] [blame] | 74 | # This function takes a PID as a parameter and determines whether or not the |
| 75 | # process is currently running. If the daemon is running 0 is returned. Any |
| 76 | # other value indicates that the daemon isn't running. |
| 77 | daemon_status () |
| 78 | { |
| 79 | local pid=$1 |
| 80 | |
| 81 | if [ $(kill -0 "${pid}" 2> /dev/null) ]; then |
| 82 | echo "failed to detect running daemon with PID: ${pid}"; |
| 83 | return 1 |
| 84 | fi |
| 85 | return 0 |
| 86 | } |
| 87 | |
| 88 | # This is a generic function to start a daemon, setup the environment |
| 89 | # variables, redirect output to a log file, store the PID of the daemon |
| 90 | # in a file and disconnect the daemon from the parent shell. |
| 91 | daemon_start () |
| 92 | { |
| 93 | local daemon_bin="$1" |
| 94 | local daemon_opts="$2" |
| 95 | local daemon_log_file="$3" |
| 96 | local daemon_pid_file="$4" |
| 97 | local daemon_env="$5" |
| 98 | |
| 99 | env ${daemon_env} nohup ${daemon_bin} ${daemon_opts} > ${daemon_log_file} 2>&1 & |
| 100 | local ret=$? |
| 101 | local pid=$! |
| 102 | if [ ${ret} -ne 0 ]; then |
| 103 | echo "failed to start daemon: \"${daemon_bin}\" with env: \"${daemon_env}\"" |
| 104 | exit ${ret} |
| 105 | fi |
| 106 | sleep 1 |
| 107 | daemon_status "${pid}" |
| 108 | if [ $? -ne 0 ]; then |
| 109 | echo "daemon died after successfully starting in background, check " \ |
| 110 | "log file: ${daemon_log_file}" |
| 111 | return 1 |
| 112 | fi |
| 113 | echo ${pid} > ${daemon_pid_file} |
| 114 | disown ${pid} |
| 115 | echo "successfully started daemon: ${daemon_bin} with PID: ${pid}" |
| 116 | return 0 |
| 117 | } |
| 118 | # function to start the simulator |
| 119 | # This also that we have a private place to store the NVChip file. Since we |
| 120 | # can't tell the simulator what to name this file we must generate a random |
| 121 | # directory under /tmp, move to this directory, start the simulator, then |
| 122 | # return to the old pwd. |
| 123 | simulator_start () |
| 124 | { |
| 125 | local sim_bin="$1" |
| 126 | local sim_port="$2" |
| 127 | local sim_log_file="$3" |
| 128 | local sim_pid_file="$4" |
| 129 | local sim_tmp_dir="$5" |
| 130 | # simulator port is a random port between 1024 and 65535 |
| 131 | |
| 132 | cd ${sim_tmp_dir} |
| 133 | daemon_start "${sim_bin}" "-port ${sim_port}" "${sim_log_file}" \ |
| 134 | "${sim_pid_file}" "" |
| 135 | local ret=$? |
| 136 | cd - |
| 137 | return $ret |
| 138 | } |
| 139 | # function to stop a running daemon |
| 140 | # This function takes a single parameter: a file containing the PID of the |
| 141 | # process to be killed. The PID is extracted and the daemon killed. |
| 142 | daemon_stop () |
| 143 | { |
| 144 | local pid_file=$1 |
| 145 | local pid=0 |
| 146 | local ret=0 |
| 147 | |
| 148 | if [ ! -f ${pid_file} ]; then |
| 149 | echo "failed to stop daemon, no pid file: ${pid_file}" |
| 150 | return 1 |
| 151 | fi |
| 152 | pid=$(cat ${pid_file}) |
| 153 | daemon_status "${pid}" |
| 154 | ret=$? |
| 155 | if [ ${ret} -ne 0 ]; then |
| 156 | echo "failed to detect running daemon with PID: ${pid}"; |
| 157 | return ${ret} |
| 158 | fi |
| 159 | kill ${pid} |
| 160 | ret=$? |
| 161 | if [ ${ret} -ne 0 ]; then |
| 162 | echo "failed to kill daemon process with PID: ${pid}" |
| 163 | fi |
| 164 | return ${ret} |
| 165 | } |
| 166 | |
dantpm | 01a01cd | 2018-02-27 11:25:01 -0800 | [diff] [blame] | 167 | sanity_test |
| 168 | |
Philip Tricca | 99d4142 | 2017-06-18 15:11:50 -0700 | [diff] [blame] | 169 | # Once option processing is done, $@ should be the name of the test executable |
| 170 | # followed by all of the options passed to the test executable. |
| 171 | TEST_BIN=$(realpath "$1") |
| 172 | TEST_DIR=$(dirname "$1") |
| 173 | TEST_NAME=$(basename "${TEST_BIN}") |
| 174 | |
| 175 | # start an instance of the simulator for the test, have it use a random port |
| 176 | SIM_LOG_FILE=${TEST_BIN}_simulator.log |
| 177 | SIM_PID_FILE=${TEST_BIN}_simulator.pid |
| 178 | SIM_TMP_DIR=$(mktemp --directory --tmpdir=/tmp tpm_server_XXXXXX) |
Philip Tricca | 21a8b73 | 2017-12-29 14:06:25 -0800 | [diff] [blame] | 179 | PORT_MIN=1024 |
| 180 | PORT_MAX=65534 |
| 181 | BACKOFF_FACTOR=2 |
| 182 | BACKOFF_MAX=6 |
| 183 | BACKOFF=1 |
| 184 | for i in $(seq ${BACKOFF_MAX}); do |
| 185 | SIM_PORT_DATA=$(od -A n -N 2 -t u2 /dev/urandom | awk -v min=${PORT_MIN} -v max=${PORT_MAX} '{print ($1 % (max - min)) + min}') |
| 186 | if [ $(expr ${SIM_PORT_DATA} % 2) -eq 1 ]; then |
| 187 | SIM_PORT_DATA=$((${SIM_PORT_DATA}-1)) |
| 188 | fi |
| 189 | SIM_PORT_CMD=$((${SIM_PORT_DATA}+1)) |
| 190 | echo "Starting simulator on port ${SIM_PORT_DATA}" |
| 191 | simulator_start ${SIM_BIN} ${SIM_PORT_DATA} ${SIM_LOG_FILE} ${SIM_PID_FILE} ${SIM_TMP_DIR} |
| 192 | sleep 1 # give daemon time to bind to ports |
dantpm | 01a01cd | 2018-02-27 11:25:01 -0800 | [diff] [blame] | 193 | if [ ! -s ${SIM_PID_FILE} ] ; then |
| 194 | echo "Simulator PID file is empty or missing. Giving up." |
| 195 | exit 1 |
| 196 | fi |
Philip Tricca | 21a8b73 | 2017-12-29 14:06:25 -0800 | [diff] [blame] | 197 | PID=$(cat ${SIM_PID_FILE}) |
| 198 | echo "simulator PID: ${PID}"; |
| 199 | netstat -ltpn 2> /dev/null | grep "${PID}" | grep -q "${SIM_PORT_DATA}" |
| 200 | ret_data=$? |
| 201 | netstat -ltpn 2> /dev/null | grep "${PID}" | grep -q "${SIM_PORT_CMD}" |
| 202 | ret_cmd=$? |
| 203 | if [ \( $ret_data -eq 0 \) -a \( $ret_cmd -eq 0 \) ]; then |
| 204 | echo "Simulator with PID ${PID} bound to port ${SIM_PORT_DATA} and " \ |
| 205 | "${SIM_PORT_CMD} successfully."; |
| 206 | break |
| 207 | fi |
| 208 | echo "Port conflict? Cleaning up PID: ${PID}" |
| 209 | kill "${PID}" |
| 210 | BACKOFF=$((${BACKOFF}*${BACKOFF_FACTOR})) |
| 211 | echo "Failed to start simulator: port ${SIM_PORT_DATA} or " \ |
| 212 | "${SIM_PORT_CMD} probably in use. Retrying in ${BACKOFF}." |
| 213 | sleep ${BACKOFF} |
| 214 | if [ $i -eq 10 ]; then |
| 215 | echo "Failed to start simulator after $i tries. Giving up."; |
| 216 | exit 1 |
Philip Tricca | 99d4142 | 2017-06-18 15:11:50 -0700 | [diff] [blame] | 217 | fi |
| 218 | done |
| 219 | |
Andreas Fuchs | a0eda36 | 2018-03-28 11:56:42 +0200 | [diff] [blame] | 220 | while true; do |
| 221 | |
| 222 | env TPM20TEST_TCTI_NAME="socket" \ |
| 223 | TPM20TEST_SOCKET_ADDRESS="127.0.0.1" \ |
| 224 | TPM20TEST_SOCKET_PORT="${SIM_PORT_DATA}" \ |
| 225 | G_MESSAGES_DEBUG=all ./test/helper/tpm_startup |
| 226 | if [ $? -ne 0 ]; then |
| 227 | echo "TPM_StartUp failed" |
| 228 | ret=99 |
| 229 | break |
| 230 | fi |
| 231 | |
Andreas Fuchs | 6ab3fd8 | 2018-03-28 12:23:19 +0200 | [diff] [blame] | 232 | env TPM20TEST_TCTI_NAME="socket" \ |
| 233 | TPM20TEST_SOCKET_ADDRESS="127.0.0.1" \ |
| 234 | TPM20TEST_SOCKET_PORT="${SIM_PORT_DATA}" \ |
| 235 | G_MESSAGES_DEBUG=all ./test/helper/tpm_transientempty |
| 236 | if [ $? -ne 0 ]; then |
| 237 | echo "TPM transient area not empty => skipping" |
| 238 | ret=77 |
| 239 | break |
| 240 | fi |
| 241 | |
Andreas Fuchs | a0eda36 | 2018-03-28 11:56:42 +0200 | [diff] [blame] | 242 | echo "Execute the test script" |
Philip Tricca | 99d4142 | 2017-06-18 15:11:50 -0700 | [diff] [blame] | 243 | env TPM20TEST_TCTI_NAME="socket" \ |
| 244 | TPM20TEST_SOCKET_ADDRESS="127.0.0.1" \ |
Philip Tricca | 21a8b73 | 2017-12-29 14:06:25 -0800 | [diff] [blame] | 245 | TPM20TEST_SOCKET_PORT="${SIM_PORT_DATA}" \ |
Philip Tricca | 99d4142 | 2017-06-18 15:11:50 -0700 | [diff] [blame] | 246 | G_MESSAGES_DEBUG=all $@ |
| 247 | ret=$? |
Andreas Fuchs | a0eda36 | 2018-03-28 11:56:42 +0200 | [diff] [blame] | 248 | echo "Script returned $ret" |
| 249 | |
Andreas Fuchs | c0c19c6 | 2018-03-28 12:35:30 +0200 | [diff] [blame] | 250 | env TPM20TEST_TCTI_NAME="socket" \ |
| 251 | TPM20TEST_SOCKET_ADDRESS="127.0.0.1" \ |
| 252 | TPM20TEST_SOCKET_PORT="${SIM_PORT_DATA}" \ |
| 253 | G_MESSAGES_DEBUG=all ./test/helper/tpm_transientempty |
| 254 | if [ $? -ne 0 ]; then |
| 255 | echo "TPM transient area not empty or generally failed after test" |
| 256 | ret=99 |
| 257 | break |
| 258 | fi |
| 259 | |
Andreas Fuchs | a0eda36 | 2018-03-28 11:56:42 +0200 | [diff] [blame] | 260 | break |
| 261 | done |
Philip Tricca | 99d4142 | 2017-06-18 15:11:50 -0700 | [diff] [blame] | 262 | |
| 263 | # This sleep is sadly necessary: If we kill the tabrmd w/o sleeping for a |
| 264 | # second after the test finishes the simulator will die too. Bug in the |
| 265 | # simulator? |
| 266 | sleep 1 |
| 267 | # teardown |
| 268 | daemon_stop ${SIM_PID_FILE} |
| 269 | rm -rf ${SIM_TMP_DIR} ${SIM_PID_FILE} |
| 270 | exit $ret |