Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test suite hardening #209

Merged
merged 38 commits into from
Nov 23, 2017
Merged
Show file tree
Hide file tree
Changes from 34 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
4a54745
Hardening the shell is the first thing to do
dridi Oct 4, 2017
3b4a693
Run the test suite in a temp directory
dridi Oct 4, 2017
76415aa
Test helper hitch_start to start Hitch as a daemon
dridi Oct 4, 2017
597d515
Print test diagnostics to stderr
dridi Oct 4, 2017
cf39365
Wrap openssl s_client commands in a function
dridi Oct 4, 2017
bc1e6ac
Polish the old cfg test case
dridi Oct 4, 2017
88f6aa5
New more reliable curl_hitch test helper
dridi Oct 4, 2017
f92bf0e
Always use -prexit via s_client test helper
dridi Oct 4, 2017
6a23263
Don't write the hitch listen address in a file
dridi Oct 4, 2017
596f961
Let the s_client helper find where to connect
dridi Oct 4, 2017
5170a0f
Flesh out tests with multiple listen addresses
dridi Oct 4, 2017
9074f41
Polish test 06
dridi Oct 4, 2017
4287d5b
Make sure TEST_TMPDIR is always absolute
dridi Oct 5, 2017
b0352cc
Turn curl errors into automake errors
dridi Oct 5, 2017
bb0ecd1
Teach curl_hitch to skip unknown options
dridi Oct 5, 2017
aa21a7a
Teach curl_hitch when to use the first listen address
dridi Oct 5, 2017
e79b9d3
Listen to what curl_hitch has to say
dridi Oct 5, 2017
e67c34f
New hitch_pid helper to send signals
dridi Oct 5, 2017
d60f1cc
Use hitch_hosts to check the old address in test 11
dridi Oct 5, 2017
806df87
More tests hardening using the new helpers
dridi Oct 5, 2017
94cc6b0
Output all dump files on test failures
dridi Oct 5, 2017
7bf6b4a
A relative --config file name is fine in test cases
dridi Oct 5, 2017
bbb7878
Move the remaining tests to the new helpers
dridi Oct 5, 2017
8d796e5
Port tests 25, 27 and 28 to the new test helpers
dridi Nov 13, 2017
3a3759f
Retire unused test helpers
dridi Oct 5, 2017
2da9405
Make dumps better delimited in test reports
dridi Oct 5, 2017
5387dde
Use automake terminology instead of "die"
dridi Oct 5, 2017
11df1e3
Turn `set -u` hardening on
dridi Oct 5, 2017
48443e1
Retire the $LISTENADDR constant
dridi Oct 5, 2017
413b277
Kill remaining back ticks in test cases
dridi Oct 5, 2017
036432f
lsof may use * for host names
dridi Oct 5, 2017
b353f5f
Missing s/common/hitch_test/
daghf Oct 19, 2017
293221c
Dump log files if any on test failures
dridi Oct 31, 2017
9f80c01
Make start_hitch log to hitch.log
dridi Oct 31, 2017
6b3f783
Re-enable check for issue #22
dridi Nov 13, 2017
e035527
Dead code from the old test suite
dridi Nov 13, 2017
e212bd0
Document the test framework
dridi Nov 13, 2017
6f8cc44
Support sockstat in the test suite
dridi Nov 22, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ sbin_PROGRAMS = hitch
noinst_LIBRARIES = libcfg.a libforeign.a

EXTRA_DIST = \
$(top_srcdir)/src/tests/common.sh \
$(top_srcdir)/src/tests/hitch_test.sh \
$(top_srcdir)/src/tests/test*.sh \
$(top_srcdir)/src/tests/certs/* \
$(top_srcdir)/src/tests/configs/default.cfg
Expand Down
174 changes: 141 additions & 33 deletions src/tests/hitch_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,56 +3,68 @@
# export TESTDIR=`pwd`/; export PATH=$PATH:`pwd`/../:`pwd`/../util/
#

export LC_ALL=C
set -e
set -u

cd "$(mktemp -d)"
readonly TEST_TMPDIR=$(pwd)

# begin old setup

export LC_ALL=C

LISTENADDR="localhost"
LISTENPORT=`expr $$ % 62000 + 1024`
PIDFILE=$(mktemp -u)
CONFFILE=$(mktemp -u)
DUMPFILE=$(mktemp -u)
CERTSDIR="${TESTDIR}/certs"
CONFDIR="${TESTDIR}/configs"

HITCH_ARGS="--pidfile=$PIDFILE --daemon --quiet"
# end old setup

dump() {
for LOG in *.log
do
test -f "$LOG" || continue

if [ "$USER" = "root" ]; then
HITCH_ARGS="$HITCH_ARGS --user=nobody"
fi
printf '\nFound log file %s:\n\n' "$LOG"
cat -v "$LOG" | sed -e 's/^/> /'
done >&2

for DUMP in *.dump
do
test -f "$DUMP" || continue

printf '\nFound dump file %s:\n\n' "$DUMP"
cat -v "$DUMP" | sed -e 's/^/> /'
done >&2
}

cleanup() {
test -f "$CONFFILE" && rm -f "$CONFFILE"
test -f "$DUMPFILE" && rm -f "$DUMPFILE"
if [ -s $PIDFILE ]; then
kill `cat "$PIDFILE"`
fi
for PID in *.pid
do
test -f "$PID" &&
kill "$(cat "$PID")"
done

rm -rf "$TEST_TMPDIR"
}

trap cleanup EXIT

die() {
echo "FAILED: $*"
if [ -r "$DUMPFILE" ]; then
cat $DUMPFILE;
fi
fail() {
echo "FAIL: $*" >&2
dump
exit 255
}

skip() {
echo "SKIPPED: $*"
if [ -r "$DUMPFILE" ]; then
cat $DUMPFILE;
fi
echo "SKIP: $*" >&2
dump
exit 77
}

mk_cfg() {
cat > "$CONFFILE"
}

runcurl() {
# Verify that we got a HTTP reply.
curl $CURL_EXTRA -I -X GET --max-time 5 --silent --insecure https://$1:$2/
test $? -eq 0 || die "Incorrect HTTP response code."
error() {
echo "ERROR: $*" >&2
dump
exit 99
}

run_cmd() (
Expand All @@ -72,13 +84,109 @@ run_cmd() (

shift $((OPTIND - 1))

printf 'Running: %s\n' "$*"
printf 'Running: %s\n' "$*" >&2

RUN_STATUS=0
"$@" || RUN_STATUS=$?

if [ "$RUN_STATUS" -ne "$CMD_STATUS" ]
then
die "expected exit status $CMD_STATUS got $RUN_STATUS"
fail "expected exit status $CMD_STATUS got $RUN_STATUS"
fi
)

start_hitch() {
TEST_UID=$(id -u)
HITCH_USER=
test "$TEST_UID" -eq 0 && HITCH_USER=--user=nobody

run_cmd hitch \
--pidfile="$TEST_TMPDIR/hitch.pid" \
--log-filename=hitch.log \
--daemon \
$HITCH_USER \
"$@"
}

hitch_pid() {
cat "$TEST_TMPDIR/hitch.pid"
}

hitch_hosts() {
# XXX: check lsof presence with autoconf
lsof -F -P -n -a -p "$(hitch_pid)" -i 4 -i TCP |
sed 's/*/localhost/' |
awk '/^n/ { print substr($1,2) }'
}

curl_hitch() {
printf 'Running: curl %s\n' "$*" >&2

HAS_SPECIFIC_ARG=false

for ARG
do
test "$ARG" = -- && HAS_SPECIFIC_ARG=true

# ignore non-option arguments
test "${ARG#-}" = "$ARG" && continue

curl --help |
grep -q -e "$ARG" ||
skip "curl: unknown option $ARG"
done

if ! $HAS_SPECIFIC_ARG
then
HITCH_HOST=$(hitch_hosts | sed 1q)
curl_hitch "$@" -- "https://$HITCH_HOST/"
return $?
fi

CURL_STATUS=${CURL_STATUS:-200}
EXIT_STATUS=0
RESP_STATUS=$(curl \
--head \
--max-time 5 \
--silent \
--verbose \
--insecure \
--output /dev/null \
--write-out '%{http_code}' \
"$@") || EXIT_STATUS=$?

# XXX: how to handle the cases where we expect an error?
test $EXIT_STATUS -ne 0 &&
error "curl request failed or timed out (exit status: $EXIT_STATUS)"

test "$CURL_STATUS" = "$RESP_STATUS" ||
fail "expected status $CURL_STATUS got $RESP_STATUS"
}

s_client() {
printf 'Running: s_client %s\n' "$*" >&2

HAS_CONNECT_OPT=false

for ARG
do
# ignore non-option arguments
test "${ARG#-}" = "$ARG" && continue

test "$ARG" = -connect && HAS_CONNECT_OPT=true

openssl s_client -help 2>&1 |
grep -q -e "$ARG" ||
skip "openssl s_client: unknown option $ARG"
done

if ! $HAS_CONNECT_OPT
then
HITCH_HOST=$(hitch_hosts | sed 1q)
s_client "$@" -connect "$HITCH_HOST"
return $?
fi

printf '\n' |
openssl s_client -prexit "$@" 2>&1
}
17 changes: 7 additions & 10 deletions src/tests/test02-simple-request.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,12 @@
# Test basic argument handling.
#
. hitch_test.sh
set +o errexit

hitch $HITCH_ARGS --backend=[hitch-tls.org]:80 "--frontend=[${LISTENADDR}]:$LISTENPORT" ${CERTSDIR}/site1.example.com
test $? -eq 0 || die "Hitch did not start."
start_hitch \
--backend="[hitch-tls.org]:80" \
--frontend="[localhost]:$LISTENPORT" \
"${CERTSDIR}/site1.example.com"

echo -e "\n" | openssl s_client -prexit -connect $LISTENADDR:$LISTENPORT >$DUMPFILE 2>&1
test $? -eq 0 || die "s_client failed"

grep -q -c "subject=/CN=site1.example.com" $DUMPFILE
test $? -eq 0 || die "Got wrong certificate."

runcurl $LISTENADDR $LISTENPORT
s_client >s_client.dump
run_cmd grep -q "subject=/CN=site1.example.com" s_client.dump
curl_hitch
29 changes: 12 additions & 17 deletions src/tests/test03-multiple-listen.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,17 @@
#
. hitch_test.sh

PORT2=`expr $$ % 60000 + 3000`
PORT2=$(expr $$ % 60000 + 3000)

hitch $HITCH_ARGS --backend=[hitch-tls.org]:80 \
"--frontend=[${LISTENADDR}]:$LISTENPORT" \
"--frontend=[${LISTENADDR}]:$PORT2" \
${CERTSDIR}/site1.example.com
test $? -eq 0 || die "Hitch did not start."
start_hitch \
--backend=[hitch-tls.org]:80 \
--frontend="[localhost]:$LISTENPORT" \
--frontend="[localhost]:$PORT2" \
"${CERTSDIR}/site1.example.com"

echo -e "\n" | openssl s_client -prexit -connect $LISTENADDR:$LISTENPORT >$DUMPFILE 2>&1
test $? -eq 0 || die "s_client failed"
grep -q -c "subject=/CN=site1.example.com" $DUMPFILE

# Second listen port.
echo -e "\n" | openssl s_client -prexit -connect $LISTENADDR:$PORT2 >$DUMPFILE 2>&1
test $? -eq 0 || die "s_client failed"
grep -q -c "subject=/CN=site1.example.com" $DUMPFILE

runcurl $LISTENADDR $LISTENPORT
runcurl $LISTENADDR $PORT2
for host in $(hitch_hosts)
do
s_client -connect "$host" >"$host.dump"
run_cmd grep -q "subject=/CN=site1.example.com" "$host.dump"
curl_hitch -- "https://$host/"
done
29 changes: 14 additions & 15 deletions src/tests/test04-listen-with-own-certs.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,23 @@
# Test multiple listening sockets, each with their own certificate.
#
. hitch_test.sh
set +o errexit

PORT2=`expr $$ % 60000 + 4000`
PORT2=$(expr $$ % 60000 + 4000)

hitch $HITCH_ARGS --backend=[hitch-tls.org]:80 \
"--frontend=[${LISTENADDR}]:$LISTENPORT+${CERTSDIR}/site1.example.com" \
"--frontend=[${LISTENADDR}]:$PORT2+${CERTSDIR}/site2.example.com" \
${CERTSDIR}/default.example.com
test $? -eq 0 || die "Hitch did not start."
start_hitch \
--backend='[hitch-tls.org]:80' \
--frontend="[localhost]:$LISTENPORT+${CERTSDIR}/site1.example.com" \
--frontend="[localhost]:$PORT2+${CERTSDIR}/site2.example.com" \
"${CERTSDIR}/default.example.com"

echo -e "\n" | openssl s_client -prexit -connect $LISTENADDR:$LISTENPORT >$DUMPFILE 2>&1 || die "s_client failed"
grep -q -c "subject=/CN=site1.example.com" $DUMPFILE
test $? -eq 0 || die "s_client got wrong certificate on listen port #1"
s_client -connect localhost:$LISTENPORT >s_client1.dump
run_cmd grep -q 'subject=/CN=site1.example.com' s_client1.dump

# Second listen port.
echo -e "\n" | openssl s_client -prexit -connect $LISTENADDR:$PORT2 >$DUMPFILE 2>&1 || die "s_client failed"
grep -q -c "subject=/CN=site2.example.com" $DUMPFILE
test $? -eq 0 || die "s_client got wrong certificate in listen port #2"
s_client -connect localhost:$PORT2 >s_client2.dump
run_cmd grep -q 'subject=/CN=site2.example.com' s_client2.dump

runcurl $LISTENADDR $LISTENPORT
runcurl $LISTENADDR $PORT2
for host in $(hitch_hosts)
do
curl_hitch -- "https://$host/"
done
26 changes: 12 additions & 14 deletions src/tests/test05-multiple-listen-SNI.sh
Original file line number Diff line number Diff line change
@@ -1,23 +1,21 @@
#!/bin/sh
#
# Test multiple certificates (SNI) on a listening socket.
#

. hitch_test.sh
set +o errexit

hitch $HITCH_ARGS --backend=[hitch-tls.org]:80 "--frontend=[${LISTENADDR}]:$LISTENPORT" \
${CERTSDIR}/site1.example.com ${CERTSDIR}/site2.example.com ${CERTSDIR}/default.example.com
test $? -eq 0 || die "Hitch did not start."
start_hitch \
--backend='[hitch-tls.org]:80' \
--frontend="[localhost]:$LISTENPORT" \
"${CERTSDIR}/site1.example.com" \
"${CERTSDIR}/site2.example.com" \
"${CERTSDIR}/default.example.com"

echo -e "\n" | openssl s_client -prexit -connect $LISTENADDR:$LISTENPORT >$DUMPFILE 2>&1
test $? -eq 0 || die "s_client failed"
grep -q -c "subject=/CN=default.example.com" $DUMPFILE
test $? -eq 0 || die "s_client got wrong certificate on listen port #1"
s_client >no-sni.dump
run_cmd grep -q 'subject=/CN=default.example.com' no-sni.dump

# send a SNI request
echo -e "\n" | openssl s_client -servername site1.example.com -prexit -connect $LISTENADDR:$LISTENPORT >$DUMPFILE 2>&1
test $? -eq 0 || die "s_client failed"
grep -q -c "subject=/CN=site1.example.com" $DUMPFILE
test $? -eq 0 || die "s_client got wrong certificate in listen port #2"
s_client -servername site1.example.com >sni.dump
run_cmd grep -q 'subject=/CN=site1.example.com' sni.dump

runcurl $LISTENADDR $LISTENPORT
curl_hitch
27 changes: 8 additions & 19 deletions src/tests/test06-ticket-resume.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,15 @@
# Test resuming a session via a session ticket

. hitch_test.sh
set +o errexit

SESSFILE=`mktemp`
rmsess() {
rm -f $SESSFILE
cleanup
}
trap rmsess EXIT
start_hitch \
--backend="[hitch-tls.org]:80" \
--frontend="[localhost]:$LISTENPORT" \
"${CERTSDIR}/site1.example.com"

hitch $HITCH_ARGS --backend=[hitch-tls.org]:80 "--frontend=[${LISTENADDR}]:$LISTENPORT" \
${CERTSDIR}/site1.example.com
test $? -eq 0 || die "Hitch did not start."
s_client -sess_out sess_ticket.txt >out.dump
s_client -sess_in sess_ticket.txt >in.dump

echo -e "\n" | openssl s_client -prexit -sess_out $SESSFILE -connect $LISTENADDR:$LISTENPORT
test $? -eq 0 || die "s_client failed (1)"
run_cmd grep Reused, in.dump

echo -e "\n" | openssl s_client -prexit -sess_in $SESSFILE -connect $LISTENADDR:$LISTENPORT >$DUMPFILE 2>&1
test $? -eq 0 || die "s_client failed (2)"

grep -q -c "Reused, " $DUMPFILE
test $? -eq 0 || die "Unable to resume session via session ticket."

runcurl $LISTENADDR $LISTENPORT
curl_hitch
Loading