From 26e7adea150b371ee059ffc85f5e643e8d6e9b14 Mon Sep 17 00:00:00 2001 From: Emil Mikulic Date: Sun, 24 Jan 2016 16:39:32 +1100 Subject: [PATCH] Add asan and ubsan to tests, watch stderr. --- devel/Makefile | 6 +- devel/run-tests | 196 ++++++++++++++++++++++++++++-------------------- 2 files changed, 118 insertions(+), 84 deletions(-) diff --git a/devel/Makefile b/devel/Makefile index 6e5f6bd..e416d25 100644 --- a/devel/Makefile +++ b/devel/Makefile @@ -3,8 +3,8 @@ all: clean: rm -f *.gcov \ - cover.out.log \ - cover.out.stderr \ - cover.out.stdout \ + test.out.log \ + test.out.stderr \ + test.out.stdout \ test.pyc \ test_make_safe_uri diff --git a/devel/run-tests b/devel/run-tests index 20589cd..cc9aeee 100755 --- a/devel/run-tests +++ b/devel/run-tests @@ -1,104 +1,138 @@ -#!/bin/sh +#!/bin/bash # # Build a coverage-enabled darkhttpd, run unit tests and calculate coverage. # cd $(dirname $0) -DIR=tmp.httpd.tests -PORT=12346 -CC=gcc +declare -r DIR=tmp.httpd.tests +declare -r PORT=12346 +declare -r CC=gcc if [ ! -e test.py ]; then - echo "can't find test.py, aborting" >&2 + echo "fatal: can't find test.py. are you in the right directory?" >&2 exit 1 fi -echo "===> building without -DDEBUG" -$CC -O2 ../darkhttpd.c || exit 1 -echo "===> building with -DNO_IPV6" -$CC -O2 -DNO_IPV6 ../darkhttpd.c || exit 1 -echo "===> building a.out and darkhttpd.gcno for coverage" -$CC -g -O2 -fprofile-arcs -ftest-coverage -DDEBUG -DAPBUF_INIT=1 ../darkhttpd.c || exit 1 -if [ -e $DIR ]; then - rm -rf $DIR || exit 1 -fi -mkdir $DIR || exit 1 -mkdir $DIR/forbidden || exit 1 -chmod 0 $DIR/forbidden || exit 1 -mkdir $DIR/unreadable || exit 1 -chmod 0100 $DIR/unreadable || exit 1 -rm -f darkhttpd.gcda darkhttpd.log +runtests() { + if [ -e $DIR ]; then + rm -rf $DIR || exit 1 + fi + mkdir $DIR || exit 1 + mkdir $DIR/forbidden || exit 1 + chmod 0 $DIR/forbidden || exit 1 + mkdir $DIR/unreadable || exit 1 + chmod 0100 $DIR/unreadable || exit 1 + rm -f darkhttpd.gcda test.out.log test.out.stdout test.out.stderr + + echo "===> run usage statement" + # Early exit if we can't even survive usage. + ./a.out >/dev/null 2>>test.out.stderr || exit 1 + + echo "===> run tests against a basic instance (generates darkhttpd.gcda)" + ./a.out $DIR --port $PORT --log test.out.log \ + >>test.out.stdout 2>>test.out.stderr & + PID=$! + kill -0 $PID || exit 1 + python test.py + kill $PID + wait $PID + + echo "===> run --forward tests" + ./a.out $DIR --port $PORT \ + --forward example.com http://www.example.com \ + --forward secure.example.com https://www.example.com/secure \ + >>test.out.stdout 2>>test.out.stderr & + PID=$! + kill -0 $PID || exit 1 + python test_forward.py + kill $PID + wait $PID + + echo "===> run --forward-all tests" + ./a.out $DIR --port $PORT \ + --forward example.com http://www.example.com \ + --forward-all http://catchall.example.com \ + >>test.out.stdout 2>>test.out.stderr & + PID=$! + kill -0 $PID || exit 1 + python test_forward_all.py + kill $PID + wait $PID + + echo "===> run --no-server-id tests" + ./a.out $DIR --port $PORT --no-server-id \ + >>test.out.stdout 2>>test.out.stderr & + PID=$! + kill -0 $PID || exit 1 + python test_server_id.py + kill $PID + wait $PID + + echo "===> run mimemap tests" + echo "test/type1 a1" > $DIR/mimemap + echo "test/this-gets-replaced ap2" >> $DIR/mimemap + echo "# this is a comment" >> $DIR/mimemap + printf "test/type3\\tapp3\r\n" >> $DIR/mimemap + echo "test/type2 ap2" >> $DIR/mimemap + ./a.out $DIR --port $PORT \ + --mimetypes $DIR/mimemap \ + --default-mimetype test/default \ + >>test.out.stdout 2>>test.out.stderr & + PID=$! + kill -0 $PID || exit 1 + python test_mimemap.py + kill $PID + wait $PID + + echo "===> run --no-listing tests" + ./a.out $DIR --port $PORT --no-listing \ + >>test.out.stdout 2>>test.out.stderr & + PID=$! + kill -0 $PID || exit 1 + python test_no_listing.py + kill $PID + wait $PID + + if [[ -s test.out.stderr ]]; then + echo "FAIL: stderr should have been empty." + exit 1 + fi +} + +# --- main --- + +# Unit test. echo "===> test_make_safe_uri" -$CC -g -O2 test_make_safe_uri.c -o test_make_safe_uri || exit 1 +$CC -g -O2 -fsanitize=address -fsanitize=undefined \ + test_make_safe_uri.c -o test_make_safe_uri || exit 1 if ./test_make_safe_uri | egrep '^FAIL:'; then echo test_make_safe_uri failed >&2 exit 1 fi -echo "===> run usage statement" -./a.out >/dev/null +# Check that the code builds with various defines. +echo "===> building without -DDEBUG" +$CC -O2 ../darkhttpd.c || exit 1 +echo "===> building with -DNO_IPV6" +$CC -O2 -DNO_IPV6 ../darkhttpd.c || exit 1 -echo "===> run tests against a basic instance (generates darkhttpd.gcda)" -./a.out $DIR --port $PORT --log cover.out.log >cover.out.stdout 2>cover.out.stderr & -PID=$! -kill -0 $PID || exit 1 -python test.py -kill $PID -wait $PID +# Do coverage and sanitizers. +# -fsanitize=undefined produces stderr. +# -fsanitize=address produces stderr and crashes. +echo "===> building a.out and darkhttpd.gcno for coverage + asan + ubsan" +$CC -g -O2 -fprofile-arcs -ftest-coverage -fsanitize=address \ + -fsanitize=undefined -DDEBUG -DAPBUF_INIT=1 ../darkhttpd.c || exit 1 -echo "===> run --forward tests" -./a.out $DIR --port $PORT \ - --forward example.com http://www.example.com \ - --forward secure.example.com https://www.example.com/secure >/dev/null & -PID=$! -kill -0 $PID || exit 1 -python test_forward.py -kill $PID -wait $PID - -echo "===> run --forward-all tests" -./a.out $DIR --port $PORT \ - --forward example.com http://www.example.com \ - --forward-all http://catchall.example.com >/dev/null & -PID=$! -kill -0 $PID || exit 1 -python test_forward_all.py -kill $PID -wait $PID - -echo "===> run --no-server-id tests" -./a.out $DIR --port $PORT --no-server-id >/dev/null & -PID=$! -kill -0 $PID || exit 1 -python test_server_id.py -kill $PID -wait $PID - -echo "===> run mimemap tests" -echo "test/type1 a1" > $DIR/mimemap -echo "test/this-gets-replaced ap2" >> $DIR/mimemap -echo "# this is a comment" >> $DIR/mimemap -printf "test/type3\\tapp3\r\n" >> $DIR/mimemap -echo "test/type2 ap2" >> $DIR/mimemap -./a.out $DIR --port $PORT \ - --mimetypes $DIR/mimemap \ - --default-mimetype test/default >/dev/null & -PID=$! -kill -0 $PID || exit 1 -python test_mimemap.py -kill $PID -wait $PID - -echo "===> run --no-listing tests" -./a.out $DIR --port $PORT --no-listing >/dev/null & -PID=$! -kill -0 $PID || exit 1 -python test_no_listing.py -kill $PID -wait $PID +(runtests) || { + echo "FAILED! stderr was:" + echo "---" + cat test.out.stderr + echo "---" + exit 1 +} echo "===> generating report" gcov darkhttpd rm -rf $DIR rm -f darkhttpd.gcda darkhttpd.gcno a.out -echo "===> done!" +echo "===> PASSED!" echo "===> read the report: less darkhttpd.c.gcov"