blob: d803df08222d30fad3906e2f97c3bdb6f5fef334 [file] [log] [blame]
Philip Tricca99d41422017-06-18 15:11:50 -07001#!/usr/bin/env bash
2#;**********************************************************************;
dantpm01a01cd2018-02-27 11:25:01 -08003# Copyright (c) 2017 - 2018, Intel Corporation
Philip Tricca99d41422017-06-18 15:11:50 -07004# 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#;**********************************************************************;
28set -u
29
30usage_error ()
31{
32 echo "$0: $*" >&2
33 print_usage >&2
34 exit 2
35}
36print_usage ()
37{
38 cat <<END
39Usage:
40 int-log-compiler.sh --simulator-bin=FILE
41 TEST-SCRIPT [TEST-SCRIPT-ARGUMENTS]
42The '--simulator-bin' option is mandatory.
43END
44}
45while 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
55done
56
dantpm01a01cd2018-02-27 11:25:01 -080057# Verify the running shell and OS environment is sufficient to run these tests.
58sanity_test ()
59{
Philip Tricca73977282018-03-12 11:10:43 -070060 # Check special file
61 if [ ! -e /dev/urandom ]; then
dantpm01a01cd2018-02-27 11:25:01 -080062 echo "Missing file /dev/urandom; exiting"
63 exit 1
Philip Tricca73977282018-03-12 11:10:43 -070064 fi
dantpm01a01cd2018-02-27 11:25:01 -080065
Philip Tricca73977282018-03-12 11:10:43 -070066 # Check ps
67 PS_LINES=$(ps -e 2>/dev/null | wc -l)
68 if [ "$PS_LINES" -eq 0 ] ; then
dantpm01a01cd2018-02-27 11:25:01 -080069 echo "Command ps not listing processes; exiting"
70 exit 1
Philip Tricca73977282018-03-12 11:10:43 -070071 fi
dantpm01a01cd2018-02-27 11:25:01 -080072}
73
Philip Tricca99d41422017-06-18 15:11:50 -070074# 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.
77daemon_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.
91daemon_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.
123simulator_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.
142daemon_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
dantpm01a01cd2018-02-27 11:25:01 -0800167sanity_test
168
Philip Tricca99d41422017-06-18 15:11:50 -0700169# 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.
171TEST_BIN=$(realpath "$1")
172TEST_DIR=$(dirname "$1")
173TEST_NAME=$(basename "${TEST_BIN}")
174
175# start an instance of the simulator for the test, have it use a random port
176SIM_LOG_FILE=${TEST_BIN}_simulator.log
177SIM_PID_FILE=${TEST_BIN}_simulator.pid
178SIM_TMP_DIR=$(mktemp --directory --tmpdir=/tmp tpm_server_XXXXXX)
Philip Tricca21a8b732017-12-29 14:06:25 -0800179PORT_MIN=1024
180PORT_MAX=65534
181BACKOFF_FACTOR=2
182BACKOFF_MAX=6
183BACKOFF=1
184for 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
dantpm01a01cd2018-02-27 11:25:01 -0800193 if [ ! -s ${SIM_PID_FILE} ] ; then
194 echo "Simulator PID file is empty or missing. Giving up."
195 exit 1
196 fi
Philip Tricca21a8b732017-12-29 14:06:25 -0800197 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 Tricca99d41422017-06-18 15:11:50 -0700217 fi
218done
219
Andreas Fuchsa0eda362018-03-28 11:56:42 +0200220while true; do
221
222env 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
226if [ $? -ne 0 ]; then
227 echo "TPM_StartUp failed"
228 ret=99
229 break
230fi
231
Andreas Fuchs6ab3fd82018-03-28 12:23:19 +0200232env 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
236if [ $? -ne 0 ]; then
237 echo "TPM transient area not empty => skipping"
238 ret=77
239 break
240fi
241
Andreas Fuchsa0eda362018-03-28 11:56:42 +0200242echo "Execute the test script"
Philip Tricca99d41422017-06-18 15:11:50 -0700243env TPM20TEST_TCTI_NAME="socket" \
244 TPM20TEST_SOCKET_ADDRESS="127.0.0.1" \
Philip Tricca21a8b732017-12-29 14:06:25 -0800245 TPM20TEST_SOCKET_PORT="${SIM_PORT_DATA}" \
Philip Tricca99d41422017-06-18 15:11:50 -0700246 G_MESSAGES_DEBUG=all $@
247ret=$?
Andreas Fuchsa0eda362018-03-28 11:56:42 +0200248echo "Script returned $ret"
249
Andreas Fuchsc0c19c62018-03-28 12:35:30 +0200250env 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
254if [ $? -ne 0 ]; then
255 echo "TPM transient area not empty or generally failed after test"
256 ret=99
257 break
258fi
259
Andreas Fuchsa0eda362018-03-28 11:56:42 +0200260break
261done
Philip Tricca99d41422017-06-18 15:11:50 -0700262
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?
266sleep 1
267# teardown
268daemon_stop ${SIM_PID_FILE}
269rm -rf ${SIM_TMP_DIR} ${SIM_PID_FILE}
270exit $ret