source: mod_gnutls/test/runtests @ 321912b

debian/masterdebian/stretch-backportsupstream
Last change on this file since 321912b was 321912b, checked in by Thomas Klute <thomas2.klute@…>, 8 months ago

Test suite: Start OCSP responder from runtests if config exists

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