source: mod_gnutls/test/runtests @ 03295a9

debian/masterdebian/stretch-backportsjessie-backportsupstream
Last change on this file since 03295a9 was 03295a9, checked in by Thomas Klute <thomas2.klute@…>, 4 years ago

Test suite: Prevent race over error log for server fail cases

In some test cases that expect the server to fail to start, it won't
even get far enough to write an error log. Sometimes these tests failed
because tail could not find the error log in the apache_down_err hook,
which shouldn't have been called at that point.

Two changes to the runtests script should remove the problem:

a) Call tail on the error log only if it is readable
b) Remove Apache error hook before trying to stop the server

  • Property mode set to 100755
File size: 5.2 KB
Line 
1#!/bin/bash
2
3# Author: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
4
5set -e
6
7tests="${1##t-}"
8
9if [ -n "${TEST_LOCK}" ]; then
10    TEST_LOCK="$(realpath ${TEST_LOCK})"
11    flock_cmd="flock -w 10 ${TEST_LOCK}"
12fi
13
14BADVARS=0
15for v in TEST_HOST TEST_IP TEST_PORT TEST_QUERY_DELAY TEST_GAP MSVA_PORT; do
16    if [ ! -v "$v" ]; then
17        printf "You need to set the %s environment variable\n" "$v" >&2
18        BADVARS=1
19    fi
20done
21
22if [ 0 != "$BADVARS" ]; then
23    exit 1
24fi
25
26function stop_msva() {
27    kill %1
28}
29
30# Compare expected/actual outputs, filtering out headers from actual
31# output that are expected to change between runs or builds (currently
32# "Date" and "Server"). The headers must be excluded in the expected
33# output.
34#
35# Parameters:
36# $1: path to expected output
37# $2: path to actual output
38# $3: additional options for diff (optional)
39function diff_output_filter_headers()
40{
41    local expected="$1"
42    local actual="$2"
43    diff $3 -u "${expected}" <( cat "${actual}" | \
44        grep -v -P '^Date:\s.*GMT\s?$' | \
45        grep -v -P '^Server:\sApache'  | \
46        tail -n "$(wc -l < ${expected})" )
47}
48
49# Run a command, storing its PID in the given file
50# Usage: run_with_pidfile PIDFILE COMMAND [ARGS]
51function run_with_pidfile()
52{
53    local pidfile=$1
54    local cmd=$2
55    shift 2
56    echo $BASHPID >${pidfile}
57    exec ${cmd} $*
58}
59
60# Kills the process with the PID contained in a given file, then
61# deletes the file.
62# Usage: kill_by_pidfile PIDFILE
63function kill_by_pidfile()
64{
65    local pidfile="${1}"
66    # In some testcases with expected failure, gnutls-cli sometimes
67    # failed before the subshell in front of the pipe (see gnutls-cli
68    # call below) got so far as to write the PID, much less exec
69    # sleep. So we need to check if there actually is anything to
70    # kill.
71    if [ -n "${pidfile}" ]; then
72        local pid=$(cat "${pidfile}")
73        if [ -n "${pid}" ] && ps -p "${pid}"; then
74            kill "${pid}"
75        fi
76        rm "${pidfile}"
77    fi
78}
79
80function apache_down_err() {
81    printf "FAILURE: %s\n" "$TEST_NAME"
82    /usr/sbin/apache2 -f "${t}/apache.conf" -k stop || true
83    if [ -e output ]; then
84        printf "\ngnutls-cli outputs:\n"
85        diff_output_filter_headers "output" "$output" || true
86    fi
87
88    if [ -n "${sleep_pidfile}" ]; then
89        kill_by_pidfile "${sleep_pidfile}"
90    fi
91
92    local errlog="logs/${TEST_NAME}.error.log"
93    if [ -r "${errlog}" ]; then
94        printf "\nApache error logs:\n"
95        tail "${errlog}"
96    fi
97
98    if [ -n "${USE_MSVA}" ]; then
99        stop_msva
100    fi
101}
102
103if [ -z "$tests" ] ; then
104    tests=${srcdir}/tests/*
105else
106    tests=${srcdir}/tests/"$(printf "%02d" "$tests")"_*
107fi
108
109if [ -n "${USE_MSVA}" ]; then
110    GNUPGHOME=msva.gnupghome MSVA_KEYSERVER_POLICY=never monkeysphere-validation-agent &
111    trap stop_msva EXIT
112
113    sleep "$TEST_GAP"
114
115    printf "TESTING: initial MSVA verification\n"
116    MONKEYSPHERE_VALIDATION_AGENT_SOCKET="http://127.0.0.1:$MSVA_PORT" msva-query-agent https "$(cat client.uid)" x509pem client < client/x509.pem
117    printf "\nSUCCESS: initial MSVA verification\n"
118fi
119
120for t in $tests; do
121    if [ -z "${flock_cmd}" ]; then
122        echo "Warning: no lock file set"
123        sleep "$TEST_GAP"
124    fi
125    t="$(realpath ${t})"
126    export srcdir="$(realpath ${srcdir})"
127    export TEST_NAME="$(basename "$t")"
128    output="outputs/${TEST_NAME}.output"
129    rm -f "$output"
130
131    if [ -e ${t}/fail.* ]; then
132        EXPECTED_FAILURE="$(printf " (expected: %s)" fail.*)"
133    else
134        unset EXPECTED_FAILURE
135    fi
136    printf "TESTING: %s%s\n" "$TEST_NAME" "$EXPECTED_FAILURE"
137    trap apache_down_err EXIT
138    if [ -n "${USE_MSVA}" ]; then
139        MONKEYSPHERE_VALIDATION_AGENT_SOCKET="http://127.0.0.1:$MSVA_PORT" \
140            ${flock_cmd} \
141            /usr/sbin/apache2 -f "${t}/apache.conf" -k start \
142            || [ -e "${t}/fail.server" ]
143    else
144        ${flock_cmd} \
145            /usr/sbin/apache2 -f "${t}/apache.conf" -k start \
146            || [ -e "${t}/fail.server" ]
147    fi
148
149    # PID file for sleep command (explanation below)
150    sleep_pidfile="$(mktemp mod_gnutls_test-XXXXXX.pid)"
151
152    # The sleep call keeps the pipe from the subshell to gnutls-cli
153    # open. Without it gnutls-cli would terminate as soon as sed is
154    # done, and not wait for a response from the server, leading to
155    # failing tests. Sending sleep to the background allows the test
156    # case to proceed instead of waiting for it to return. The sleep
157    # process is stopped after gnutls-cli terminates.
158    if (sed "s/__HOSTNAME__/${TEST_HOST}/" <${t}/input && \
159        run_with_pidfile "${sleep_pidfile}" sleep "${TEST_QUERY_DELAY}" &) | \
160        gnutls-cli -p "${TEST_PORT}" $(cat ${t}/gnutls-cli.args) "${TEST_HOST}" \
161        >"$output";
162    then
163        if [ -e ${t}/fail* ]; then
164            printf "%s should have failed but succeeded\n" "$(basename "$t")" >&2
165            exit 1
166        fi
167    else
168        if [ ! -e ${t}/fail* ]; then
169            printf "%s should have succeeded but failed\n" "$(basename "$t")" >&2
170            exit 1
171        fi
172    fi
173
174    kill_by_pidfile "${sleep_pidfile}"
175    unset sleep_pidfile
176
177    if [ -e ${t}/output ] ; then
178        diff_output_filter_headers "${t}/output" "$output" "-q"
179    fi
180    if [ -n "${USE_MSVA}" ]; then
181        trap stop_msva EXIT
182    else
183        trap - EXIT
184    fi
185    /usr/sbin/apache2 -f "${t}/apache.conf" -k stop || [ -e ${t}/fail.server ]
186    printf "SUCCESS: %s\n" "$TEST_NAME"
187done
188
189if [ -n "${USE_MSVA}" ]; then
190    stop_msva
191fi
Note: See TracBrowser for help on using the repository browser.