Skip to content

Commit

Permalink
Rework and simplify the "lcov" support for the testsuite.
Browse files Browse the repository at this point in the history
  • Loading branch information
blp committed Feb 2, 2010
1 parent a778696 commit 7c126fb
Show file tree
Hide file tree
Showing 31 changed files with 229 additions and 162 deletions.
19 changes: 6 additions & 13 deletions README-gcov
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,10 @@ code-coverage related options:
--enable-coverage
--enable-coverage=yes

Build with gcov code coverage support, but do not assume that any
coverage-related tools are installed and do not add special
coverage support to the test suite.
Build with gcov code coverage support.

--enable-coverage=lcov

Build with gcov code coverage support, as above, but also add
support for coverage analysis to the test suite. Running "make
check" will produce a directory "tests/coverage.html" in the build
directory with an analysis of the test suite's coverage.

This setting requires the lcov suite of utilities to be installed.
The "lcov" and "genhtml" programs from lcov must be in PATH. lcov
is available at: http://ltp.sourceforge.net/coverage/lcov.php
If you enable coverage and you have the "lcov" and "genhtml"
programs in PATH, then you may run "make check-lcov" to produce a
directory "tests/coverage.html" in the build directory with an
analysis of the test suite's coverage. lcov is available at
http://ltp.sourceforge.net/coverage/lcov.php
15 changes: 4 additions & 11 deletions m4/openvswitch.m4
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,15 @@ AC_DEFUN([OVS_CHECK_COVERAGE],
[AC_HELP_STRING([--enable-coverage],
[Enable gcov coverage tool.])],
[case "${enableval}" in
(lcov) coverage=true lcov=true ;;
(yes) coverage=true lcov=false ;;
(no) coverage=false lcov=false ;;
(lcov|yes) coverage=true ;;
(no) coverage=false ;;
(*) AC_MSG_ERROR([bad value ${enableval} for --enable-coverage]) ;;
esac],
[coverage=false lcov=false])
[coverage=false])
if $coverage; then
CFLAGS="$CFLAGS -O0 --coverage"
LDFLAGS="$LDFLAGS --coverage"
fi
if $lcov; then
if lcov --version >/dev/null 2>&1; then :; else
AC_MSG_ERROR([--enable-coverage=lcov was specified but lcov is not in \$PATH])
fi
fi
AC_SUBST([LCOV], [$lcov])])
fi])

dnl Checks for --enable-ndebug and defines NDEBUG if it is specified.
AC_DEFUN([OVS_CHECK_NDEBUG],
Expand Down
2 changes: 1 addition & 1 deletion tests/aes128.at
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ AT_BANNER([AES-128 unit tests])
m4_define([AES128_CHECK],
[AT_SETUP([$1])
AT_KEYWORDS([aes128])
OVS_CHECK_LCOV([test-aes128 $2 $3], [0], [$4
AT_CHECK([test-aes128 $2 $3], [0], [$4
], [])
AT_CLEANUP])

Expand Down
1 change: 0 additions & 1 deletion tests/atlocal.in
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# -*- shell-script -*-
HAVE_OPENSSL='@HAVE_OPENSSL@'
HAVE_PYTHON='@HAVE_PYTHON@'
LCOV='@LCOV@'
PERL='@PERL@'
PYTHON='@PYTHON@'
59 changes: 54 additions & 5 deletions tests/automake.mk
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ EXTRA_DIST += \
TESTSUITE_AT = \
tests/testsuite.at \
tests/ovsdb-macros.at \
tests/lcov-pre.at \
tests/library.at \
tests/check-structs.at \
tests/daemon.at \
Expand Down Expand Up @@ -38,14 +37,64 @@ TESTSUITE_AT = \
tests/ovsdb-monitor.at \
tests/ovsdb-idl.at \
tests/stp.at \
tests/ovs-vsctl.at \
tests/lcov-post.at
tests/ovs-vsctl.at
TESTSUITE = $(srcdir)/tests/testsuite
DISTCLEANFILES += tests/atconfig tests/atlocal $(TESTSUITE)

check-local: tests/atconfig tests/atlocal $(TESTSUITE)
$(SHELL) '$(TESTSUITE)' -C tests AUTOTEST_PATH='utilities:vswitchd:ovsdb:tests' $(TESTSUITEFLAGS)
AUTOTEST_PATH = utilities:vswitchd:ovsdb:tests

check-local: tests/atconfig tests/atlocal $(TESTSUITE)
$(SHELL) '$(TESTSUITE)' -C tests AUTOTEST_PATH=$(AUTOTEST_PATH) $(TESTSUITEFLAGS)

# lcov support

lcov_wrappers = \
tests/lcov/ovs-appctl \
tests/lcov/ovs-vsctl \
tests/lcov/ovsdb-client \
tests/lcov/ovsdb-server \
tests/lcov/ovsdb-tool \
tests/lcov/test-aes128 \
tests/lcov/test-classifier \
tests/lcov/test-csum \
tests/lcov/test-dhcp-client \
tests/lcov/test-dir_name \
tests/lcov/test-flows \
tests/lcov/test-hash \
tests/lcov/test-hmap \
tests/lcov/test-json \
tests/lcov/test-jsonrpc \
tests/lcov/test-list \
tests/lcov/test-lockfile \
tests/lcov/test-ovsdb \
tests/lcov/test-reconnect \
tests/lcov/test-sha1 \
tests/lcov/test-stp \
tests/lcov/test-timeval \
tests/lcov/test-type-props \
tests/lcov/test-uuid \
tests/lcov/test-vconn

$(lcov_wrappers): tests/lcov-wrapper.in
@test -d tests/lcov || mkdir tests/lcov
sed -e 's,[@]abs_top_builddir[@],$(abs_top_builddir),' \
-e 's,[@]wrap_program[@],$@,' \
$(top_srcdir)/tests/lcov-wrapper.in > $@.tmp
chmod +x $@.tmp
mv $@.tmp $@
CLEANFILES += $(lcov_wrappers)
EXTRA_DIST += tests/lcov-wrapper.in

LCOV = lcov -b $(abs_top_builddir) -d $(abs_top_builddir) -q
check-lcov: all tests/atconfig tests/atlocal $(TESTSUITE) $(lcov_wrappers)
rm -fr tests/coverage.html tests/coverage.info
$(LCOV) -c -i -o - > tests/coverage.info
$(SHELL) '$(TESTSUITE)' -C tests CHECK_LCOV=true AUTOTEST_PATH='tests/lcov:$(AUTOTEST_PATH)' $(TESTSUITEFLAGS); \
rc=$$?; \
echo "Producing coverage.html..."; \
cd tests && genhtml -q -o coverage.html coverage.info; \
exit $$rc

clean-local:
test ! -f '$(TESTSUITE)' || $(SHELL) '$(TESTSUITE)' -C tests --clean

Expand Down
8 changes: 6 additions & 2 deletions tests/daemon.at
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
AT_BANNER([daemon unit tests])

AT_SETUP([daemon])
AT_SKIP_IF([test "$CHECK_LCOV" = true]) # lcov wrapper make pids differ
OVSDB_INIT([db])
AT_CAPTURE_FILE([pid])
AT_CAPTURE_FILE([expected])
Expand All @@ -19,6 +20,7 @@ AT_CHECK([test ! -e pid])
AT_CLEANUP

AT_SETUP([daemon --monitor])
AT_SKIP_IF([test "$CHECK_LCOV" = true]) # lcov wrapper make pids differ
OVSDB_INIT([db])
AT_CAPTURE_FILE([pid])
AT_CAPTURE_FILE([parent])
Expand Down Expand Up @@ -62,6 +64,7 @@ OVS_WAIT_WHILE([kill -0 `cat parent` || kill -0 `cat newpid` || test -e pid],
AT_CLEANUP

AT_SETUP([daemon --detach])
AT_SKIP_IF([test "$CHECK_LCOV" = true]) # lcov wrapper make pids differ
AT_CAPTURE_FILE([pid])
OVSDB_INIT([db])
# Start the daemon and make sure that the pidfile exists immediately.
Expand All @@ -78,6 +81,7 @@ AT_CHECK([test ! -e pid])
AT_CLEANUP

AT_SETUP([daemon --detach --monitor])
AT_SKIP_IF([test "$CHECK_LCOV" = true]) # lcov wrapper make pids differ
m4_define([CHECK],
[AT_CHECK([$1], [$2], [$3], [$4], [kill `cat daemon monitor`])])
OVSDB_INIT([db])
Expand Down Expand Up @@ -129,7 +133,7 @@ AT_CLEANUP
AT_SETUP([daemon --detach startup errors])
AT_CAPTURE_FILE([pid])
OVSDB_INIT([db])
OVS_CHECK_LCOV([ovsdb-server --detach --pidfile=$PWD/pid --unixctl=$PWD/nonexistent/unixctl db], [1], [], [stderr])
AT_CHECK([ovsdb-server --detach --pidfile=$PWD/pid --unixctl=$PWD/nonexistent/unixctl db], [1], [], [stderr])
AT_CHECK([grep 'ovsdb-server: could not initialize control socket' stderr],
[0], [ignore], [])
AT_CHECK([test ! -s pid])
Expand All @@ -138,7 +142,7 @@ AT_CLEANUP
AT_SETUP([daemon --detach --monitor startup errors])
AT_CAPTURE_FILE([pid])
OVSDB_INIT([db])
OVS_CHECK_LCOV([ovsdb-server --detach --pidfile=$PWD/pid --monitor --unixctl=$PWD/nonexistent/unixctl db], [1], [], [stderr])
AT_CHECK([ovsdb-server --detach --pidfile=$PWD/pid --monitor --unixctl=$PWD/nonexistent/unixctl db], [1], [], [stderr])
AT_CHECK([grep 'ovsdb-server: could not initialize control socket' stderr],
[0], [ignore], [])
AT_CHECK([test ! -s pid])
Expand Down
2 changes: 1 addition & 1 deletion tests/dir_name.at
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ AT_BANNER([test dir_name function])
m4_define([CHECK_DIR_NAME],
[AT_SETUP([dir_name("$1") returns "$2"])
AT_KEYWORDS([dir_name])
OVS_CHECK_LCOV([test-dir_name "AS_ESCAPE($1)"], [0], [$2
AT_CHECK([test-dir_name "AS_ESCAPE($1)"], [0], [$2
])
AT_CLEANUP])

Expand Down
4 changes: 2 additions & 2 deletions tests/json.at
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ m4_define([JSON_CHECK_POSITIVE],
AT_KEYWORDS([json positive])
AT_CHECK([printf %s "AS_ESCAPE([$2])" > input])
AT_CAPTURE_FILE([input])
OVS_CHECK_LCOV([test-json $4 input], [0], [stdout], [])
AT_CHECK([test-json $4 input], [0], [stdout], [])
AT_CHECK([cat stdout], [0], [$3
])
AT_CLEANUP])
Expand All @@ -13,7 +13,7 @@ m4_define([JSON_CHECK_NEGATIVE],
AT_KEYWORDS([json negative])
AT_CHECK([printf %s "AS_ESCAPE([$2])" > input])
AT_CAPTURE_FILE([input])
OVS_CHECK_LCOV([test-json $4 input], [1], [stdout], [])
AT_CHECK([test-json $4 input], [1], [stdout], [])
AT_CHECK([[sed 's/^error: [^:]*:/error:/' < stdout]], [0], [$3
])
AT_CLEANUP])
Expand Down
2 changes: 1 addition & 1 deletion tests/jsonrpc.at
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ AT_CHECK([test -s pid])
# When a daemon dies it deletes its pidfile, so make a copy.
AT_CHECK([cp pid pid2])
AT_CHECK([kill -0 `cat pid2`])
OVS_CHECK_LCOV([[test-jsonrpc notify unix:socket shutdown '[]']], [0], [],
AT_CHECK([[test-jsonrpc notify unix:socket shutdown '[]']], [0], [],
[ignore], [kill `cat pid2`])
AT_CHECK(
[pid=`cat pid2`
Expand Down
6 changes: 0 additions & 6 deletions tests/lcov-post.at

This file was deleted.

21 changes: 0 additions & 21 deletions tests/lcov-pre.at

This file was deleted.

58 changes: 58 additions & 0 deletions tests/lcov-wrapper.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#! /bin/sh

abs_top_builddir='@abs_top_builddir@'
wrap_program=`basename '@wrap_program@'`

# Strip the first directory from $PATH that contains $wrap_program,
# so that below we run the real $wrap_program, not ourselves.
not_found=true
new_path=
first=true
save_IFS=$IFS
IFS=:
for dir in $PATH; do
IFS=$save_IFS
if $not_found && test -x "$dir/$wrap_program"; then
not_found=false
else
if $first; then
first=false
new_path=$dir
else
new_path=$new_path:$dir
fi
fi
done
IFS=$save_IFS
if $not_found; then
echo "$0: error: cannot find $wrap_program in \$PATH" >&2
exit 1
fi
PATH=$new_path
export PATH

# XXX Probably want some kind of synchronization here to deal with
# programs running in parallel.
LCOV="lcov -b $abs_top_builddir -d $abs_top_builddir -q"
$LCOV -z

# Run the subprocess and propagate signals to it.
for signal in 1 2 3 5 15; do
trap "kill -$signal \$! # Propagate signal
trap - $signal # Reset signal to default
wait # Wait for child to die
kill -$signal $$ # Kill ourselves with same signal
exit 1 # Exit in case 'kill' failed" $signal
done
$wrap_program 0<&0 "$@" & # 0<&0 prevents shell from closing stdin
exec 0</dev/null # Don't hold stdin open unnecessarily
wait $!; rc=$?

# Run lcov, but only if some .gcda files were produced, since lcov
# complains otherwise.
for file in `find "$abs_top_builddir" -name '*.gcda'`; do
$LCOV -c -o - >> "$abs_top_builddir/tests/coverage.info"
break
done

exit $rc
16 changes: 8 additions & 8 deletions tests/library.at
Original file line number Diff line number Diff line change
Expand Up @@ -2,35 +2,35 @@ AT_BANNER([library unit tests])

AT_SETUP([test flow extractor])
AT_CHECK([$PERL `which flowgen.pl` >/dev/null 3>flows 4>pcap])
OVS_CHECK_LCOV([test-flows <flows 3<pcap], [0], [checked 247 packets, 0 errors
AT_CHECK([test-flows <flows 3<pcap], [0], [checked 247 packets, 0 errors
])
AT_CLEANUP

AT_SETUP([test TCP/IP checksumming])
OVS_CHECK_LCOV([test-csum], [0], [ignore])
AT_CHECK([test-csum], [0], [ignore])
AT_CLEANUP

AT_SETUP([test flow classifier])
AT_KEYWORDS([slow])
OVS_CHECK_LCOV([test-classifier], [0], [ignore])
AT_CHECK([test-classifier], [0], [ignore])
AT_CLEANUP

AT_SETUP([test hash functions])
OVS_CHECK_LCOV([test-hash], [0], [ignore])
AT_CHECK([test-hash], [0], [ignore])
AT_CLEANUP

AT_SETUP([test hash map])
OVS_CHECK_LCOV([test-hmap], [0], [ignore])
AT_CHECK([test-hmap], [0], [ignore])
AT_CLEANUP

AT_SETUP([test linked lists])
OVS_CHECK_LCOV([test-list], [0], [ignore])
AT_CHECK([test-list], [0], [ignore])
AT_CLEANUP

AT_SETUP([test SHA-1])
OVS_CHECK_LCOV([test-sha1], [0], [ignore])
AT_CHECK([test-sha1], [0], [ignore])
AT_CLEANUP

AT_SETUP([test type properties])
OVS_CHECK_LCOV([test-type-props], [0], [ignore])
AT_CHECK([test-type-props], [0], [ignore])
AT_CLEANUP
2 changes: 1 addition & 1 deletion tests/lockfile.at
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ AT_BANNER([lockfile unit tests])
m4_define([CHECK_LOCKFILE],
[AT_SETUP([m4_translit([$1], [_], [ ])])
AT_KEYWORDS([lockfile])
OVS_CHECK_LCOV([test-lockfile $1], [0], [$1: success (m4_if(
AT_CHECK([test-lockfile $1], [0], [$1: success (m4_if(
[$2], [1], [$2 child], [$2 children]))
])
AT_CLEANUP])
Expand Down
2 changes: 1 addition & 1 deletion tests/ovsdb-condition.at
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ OVSDB_CHECK_POSITIVE([conditions on scalars],

AT_SETUP([disallowed conditions on scalars])
AT_KEYWORDS([ovsdb negative condition])
OVS_CHECK_LCOV([[test-ovsdb parse-conditions \
AT_CHECK([[test-ovsdb parse-conditions \
'{"columns":
{"i": {"type": "integer"},
"r": {"type": "real"},
Expand Down
2 changes: 1 addition & 1 deletion tests/ovsdb-execution.at
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ m4_define([ORDINAL_SCHEMA],
m4_define([OVSDB_CHECK_EXECUTION],
[AT_SETUP([$1])
AT_KEYWORDS([ovsdb execute execution positive $5])
OVS_CHECK_LCOV([test-ovsdb execute '$2' m4_foreach([txn], [$3], [ 'txn'])],
AT_CHECK([test-ovsdb execute '$2' m4_foreach([txn], [$3], [ 'txn'])],
[0], [stdout], [])
AT_CHECK([perl $srcdir/uuidfilt.pl stdout], [0], [$4])
AT_CLEANUP])
Expand Down
Loading

0 comments on commit 7c126fb

Please sign in to comment.