source: mod_gnutls/test/runtests @ bbfcbb5

asynciodebian/masterdebian/stretch-backportsproxy-ticketupstream
Last change on this file since bbfcbb5 was bbfcbb5, checked in by Thomas Klute <thomas2.klute@…>, 4 years ago

Test suite: Log if a process to be stopped by PID file is not running

The runtests script calls "sleep ${TEST_QUERY_DELAY}" to keep the
input pipeline for gnutls-cli open, effectively creating a timeout of
TEST_QUERY_DELAY seconds for the HTTPS request. Normally the sleep
process is killed after the request completes to avoid stalling the
test suite. The sleep process no longer running at that point
indicates that the request timed out.

  • Property mode set to 100755
File size: 7.2 KB
RevLine 
[4b53371]1#!/bin/bash
2
[ae38a49]3# Authors:
4# Daniel Kahn Gillmor <dkg@fifthhorseman.net>
5# Thomas Klute <thomas2.klute@uni-dortmund.de>
[4b53371]6
7set -e
[412ee84]8. ${srcdir}/common.bash
[cf4e708]9netns_reexec ${@}
[4b53371]10
[56056de]11testid="${1##t-}"
12
13if [ -z "$testid" ] ; then
14    echo -e "No test case selected.\nUsage: ${0} t-N" >&2
15    exit 1
16else
17    testid=${srcdir}/tests/"$(printf "%02d" "$testid")"_*
18fi
[4b53371]19
20BADVARS=0
[a08b25e]21for v in APACHE2 TEST_HOST TEST_PORT TEST_QUERY_DELAY TEST_MSVA_WAIT \
[412ee84]22                 MSVA_PORT; do
[4b53371]23    if [ ! -v "$v" ]; then
24        printf "You need to set the %s environment variable\n" "$v" >&2
25        BADVARS=1
26    fi
27done
28
29if [ 0 != "$BADVARS" ]; then
30    exit 1
31fi
32
[45ae2ef]33# write script file and line to stderr on error
34function pinpoint_error()
35{
36    echo "${1} failed at line ${2}!" >&2
37}
38trap 'pinpoint_error ${BASH_SOURCE} ${LINENO}' ERR
39
[ae38a49]40function stop_msva()
41{
42    kill_by_pidfile "${msva_pidfile}"
43    unset msva_pidfile
[e3cbda4]44}
45
[a213967]46# Compare expected/actual outputs, filtering out headers from actual
47# output that are expected to change between runs or builds (currently
48# "Date" and "Server"). The headers must be excluded in the expected
49# output.
[54aa269]50#
51# Parameters:
52# $1: path to expected output
53# $2: path to actual output
54# $3: additional options for diff (optional)
[a213967]55function diff_output_filter_headers()
[54aa269]56{
[232fb60]57    local expected="$1"
58    local actual="$2"
[54aa269]59    diff $3 -u "${expected}" <( cat "${actual}" | \
[a213967]60        grep -v -P '^Date:\s.*GMT\s?$' | \
61        grep -v -P '^Server:\sApache'  | \
62        tail -n "$(wc -l < ${expected})" )
[54aa269]63}
64
[232fb60]65# Run a command, storing its PID in the given file
66# Usage: run_with_pidfile PIDFILE COMMAND [ARGS]
67function run_with_pidfile()
68{
69    local pidfile=$1
70    local cmd=$2
71    shift 2
72    echo $BASHPID >${pidfile}
73    exec ${cmd} $*
74}
75
76# Kills the process with the PID contained in a given file, then
77# deletes the file.
78# Usage: kill_by_pidfile PIDFILE
79function kill_by_pidfile()
80{
81    local pidfile="${1}"
82    # In some testcases with expected failure, gnutls-cli sometimes
83    # failed before the subshell in front of the pipe (see gnutls-cli
84    # call below) got so far as to write the PID, much less exec
85    # sleep. So we need to check if there actually is anything to
86    # kill.
87    if [ -n "${pidfile}" ]; then
88        local pid=$(cat "${pidfile}")
89        if [ -n "${pid}" ] && ps -p "${pid}"; then
90            kill "${pid}"
[bbfcbb5]91        else
92            echo "No running process with PID ${pid} (${pidfile})."
[232fb60]93        fi
94        rm "${pidfile}"
95    fi
96}
97
[4b53371]98function apache_down_err() {
99    printf "FAILURE: %s\n" "$TEST_NAME"
[af7da2d]100    ${APACHE2} -f "${t}/apache.conf" -k stop || true
[4b53371]101    if [ -e output ]; then
[54aa269]102        printf "\ngnutls-cli outputs:\n"
[a213967]103        diff_output_filter_headers "output" "$output" || true
[4b53371]104    fi
[232fb60]105
106    if [ -n "${sleep_pidfile}" ]; then
107        kill_by_pidfile "${sleep_pidfile}"
108    fi
109
[03295a9]110    local errlog="logs/${TEST_NAME}.error.log"
111    if [ -r "${errlog}" ]; then
112        printf "\nApache error logs:\n"
113        tail "${errlog}"
114    fi
[232fb60]115
[302965e]116    if [ -n "${USE_MSVA}" ]; then
117        stop_msva
118    fi
[4b53371]119}
120
[302965e]121if [ -n "${USE_MSVA}" ]; then
[ae38a49]122    msva_pidfile="$(mktemp mod_gnutls_test-XXXXXX.pid)"
123    GNUPGHOME=msva.gnupghome MSVA_KEYSERVER_POLICY=never run_with_pidfile "${msva_pidfile}" monkeysphere-validation-agent &
[302965e]124    trap stop_msva EXIT
[e3cbda4]125
[302965e]126    printf "TESTING: initial MSVA verification\n"
[7adbcd7]127    # set to 0 if MSVA is up
128    ret=1
129    export MONKEYSPHERE_VALIDATION_AGENT_SOCKET="http://127.0.0.1:$MSVA_PORT"
[a61edfd]130
131    # convert TEST_MSVA_WAIT to seconds because that's what "sleep" expects
132    TEST_MSVA_SLEEP="$((${TEST_MSVA_WAIT} / 1000)).$((${TEST_MSVA_WAIT} % 1000))"
133    # wait at most TEST_MSVA_MAX_WAIT milliseconds for MSVA to get ready
134    waited=0
[7adbcd7]135    until [ ${ret} -eq 0 ] \
[a61edfd]136              || [ ${waited} -ge ${TEST_MSVA_MAX_WAIT} ]; do
[7adbcd7]137        if msva-query-agent https "$(cat client.uid)" x509pem client < client/x509.pem
138        then
139            ret=0
140        else
141            echo "MSVA not ready yet"
142        fi
[a61edfd]143        sleep "${TEST_MSVA_SLEEP}"
144        waited=$((${waited} + ${TEST_MSVA_WAIT}))
[7adbcd7]145    done
146
147    # check if MSVA is up, fail if not
148    if [ ${ret} -eq 0 ]; then
149        printf "\nSUCCESS: initial MSVA verification\n"
150    else
151        printf "\nFAIL: initial MSVA verification\n"
152        exit 1
153    fi
[302965e]154fi
[e3cbda4]155
[412ee84]156TEST_PID="apache2.pid"
[dbec528]157# configure locking for the Apache process
[cf4e708]158if [ -n "${USE_TEST_NAMESPACE}" ]; then
159    echo "Using namespaces to isolate tests, no need for locking."
160    flock_cmd=""
161elif [ -n "${TEST_LOCK}" ]; then
[8184ad0]162    flock_cmd="${FLOCK} --verbose -w ${TEST_LOCK_WAIT} $(realpath ${TEST_LOCK})"
[412ee84]163else
164    echo "Locking disabled, using wait based on Apache PID file."
165    wait_pid_gone "${TEST_PID}"
166    flock_cmd=""
167fi
[dbec528]168
[5d85ad3]169t="$(realpath ${testid})"
170export srcdir="$(realpath ${srcdir})"
171export TEST_NAME="$(basename "$t")"
172output="outputs/${TEST_NAME}.output"
173rm -f "$output"
174
175if [ -e ${t}/fail.* ]; then
176    EXPECTED_FAILURE="$(printf " (expected: %s)" fail.*)"
177else
178    unset EXPECTED_FAILURE
179fi
180printf "TESTING: %s%s\n" "$TEST_NAME" "$EXPECTED_FAILURE"
181trap apache_down_err EXIT
182if [ -n "${USE_MSVA}" ]; then
[d39ea18]183    export MONKEYSPHERE_VALIDATION_AGENT_SOCKET="http://127.0.0.1:$MSVA_PORT"
184fi
185if ! ${flock_cmd} ${APACHE2} -f "${t}/apache.conf" -k start; then
186    if [ -e "${t}/fail.server" ]; then
187        echo "Apache HTTPD failed to start as expected."
188        exit 0
189    else
190        echo "Apache HTTPD unexpectedly failed to start."
191        exit 1
192    fi
[5d85ad3]193fi
[4b53371]194
[c4d6e77]195# check OCSP server
196if [ -n "${CHECK_OCSP_SERVER}" ]; then
[94cb972]197    if [ -n "${OCSP_RESPONSE_FILE}" ]; then
198        store_ocsp="--outfile ${OCSP_RESPONSE_FILE}"
199    fi
[c4d6e77]200    echo "---- Testing OCSP server ----"
[94cb972]201    ocsptool --ask --nonce --load-issuer authority/x509.pem --load-cert server/x509.pem ${store_ocsp}
[c4d6e77]202    echo "---- OCSP test done ----"
203fi
204
[5d85ad3]205# PID file for sleep command (explanation below)
206sleep_pidfile="$(mktemp mod_gnutls_test-XXXXXX.pid)"
207
208# The sleep call keeps the pipe from the subshell to gnutls-cli
209# open. Without it gnutls-cli would terminate as soon as sed is
210# done, and not wait for a response from the server, leading to
211# failing tests. Sending sleep to the background allows the test
212# case to proceed instead of waiting for it to return. The sleep
213# process is stopped after gnutls-cli terminates.
[0a12ff8]214#
215# The line end manipulation in sed guarantees that all header lines
216# end with CRLF as required by RFC 7230, Section 3.1.1 regardless of
217# the line ends in the input file.
218if (sed -r "s/__HOSTNAME__/${TEST_HOST}/;s/\r?$/\r/" <${t}/input && \
[5d85ad3]219           run_with_pidfile "${sleep_pidfile}" sleep "${TEST_QUERY_DELAY}" &) | \
220       gnutls-cli -p "${TEST_PORT}" $(cat ${t}/gnutls-cli.args) "${TEST_HOST}" \
[28fc74b]221       | tee "$output" && test "${PIPESTATUS[1]}" -eq 0;
[5d85ad3]222then
223    if [ -e ${t}/fail* ]; then
224        printf "%s should have failed but succeeded\n" "$(basename "$t")" >&2
225        exit 1
[4b53371]226    fi
[5d85ad3]227else
228    if [ ! -e ${t}/fail* ]; then
229        printf "%s should have succeeded but failed\n" "$(basename "$t")" >&2
230        exit 1
231    fi
232fi
[dda3acf]233
[5d85ad3]234kill_by_pidfile "${sleep_pidfile}"
235unset sleep_pidfile
[232fb60]236
[5d85ad3]237if [ -e ${t}/output ] ; then
[13ffeff]238    diff_output_filter_headers "${t}/output" "$output" >&2
[5d85ad3]239fi
240if [ -n "${USE_MSVA}" ]; then
241    trap stop_msva EXIT
242else
243    trap - EXIT
244fi
245${APACHE2} -f "${t}/apache.conf" -k stop || [ -e ${t}/fail.server ]
246printf "SUCCESS: %s\n" "$TEST_NAME"
[e3cbda4]247
[302965e]248if [ -n "${USE_MSVA}" ]; then
249    stop_msva
[ae38a49]250    # Without explicitly resetting the trap function, it would be
251    # called again on exit. Of course, we could just not stop MSVA and
252    # let the trap do the work, but I think the code is easier to
253    # understand like this.
254    trap - EXIT
[302965e]255fi
Note: See TracBrowser for help on using the repository browser.