Add asan and ubsan to tests, watch stderr.
authorEmil Mikulic <emikulic@gmail.com>
Sun, 24 Jan 2016 05:39:32 +0000 (16:39 +1100)
committerEmil Mikulic <emikulic@gmail.com>
Sun, 24 Jan 2016 05:39:32 +0000 (16:39 +1100)
devel/Makefile
devel/run-tests

index 6e5f6bd..e416d25 100644 (file)
@@ -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
index 20589cd..cc9aeee 100755 (executable)
-#!/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
-
-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
-
-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
+# 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
+
+# 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
+
+(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"