Add support for code coverage analysis with gcov and lcov.
authorBen Pfaff <blp@nicira.com>
Mon, 27 Jul 2009 23:42:51 +0000 (16:42 -0700)
committerBen Pfaff <blp@nicira.com>
Wed, 29 Jul 2009 19:33:32 +0000 (12:33 -0700)
README-gcov [new file with mode: 0644]
configure.ac
m4/openvswitch.m4
tests/atlocal.in
tests/automake.mk
tests/lcov-post.at [new file with mode: 0644]
tests/lcov-pre.at [new file with mode: 0644]
tests/library.at
tests/stp.at
tests/testsuite.at

diff --git a/README-gcov b/README-gcov
new file mode 100644 (file)
index 0000000..665a1ec
--- /dev/null
@@ -0,0 +1,31 @@
+Building with gcov support
+==========================
+
+The Open vSwitch "configure" script supports the following
+code-coverage related options:
+
+  --disable-coverage
+  --enable-coverage=no
+
+    Do not build with gcov code coverage support.
+
+    This is the default if no coverage option is passed to
+    "configure".
+
+  --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.
+
+  --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
index 1628146..ad38ea7 100644 (file)
@@ -39,6 +39,7 @@ AC_C_BIGENDIAN
 AC_SYS_LARGEFILE
 
 OVS_CHECK_USERSPACE
+OVS_CHECK_COVERAGE
 OVS_CHECK_NDEBUG
 OVS_CHECK_NETLINK
 OVS_CHECK_OPENSSL
index ce55311..3fe053b 100644 (file)
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+dnl Checks for --enable-coverage and updates CFLAGS and LDFLAGS appropriately.
+AC_DEFUN([OVS_CHECK_COVERAGE],
+  [AC_REQUIRE([AC_PROG_CC])
+   AC_ARG_ENABLE(
+     [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 ;;
+        (*) AC_MSG_ERROR([bad value ${enableval} for --enable-coverage]) ;;
+      esac],
+     [coverage=false lcov=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])])
+
 dnl Checks for --enable-ndebug and defines NDEBUG if it is specified.
 AC_DEFUN([OVS_CHECK_NDEBUG],
   [AC_ARG_ENABLE(
index 1328d4a..d0ca704 100644 (file)
@@ -1,2 +1,3 @@
 # -*- shell-script -*-
 PERL='@PERL@'
+LCOV='@LCOV@'
index 6dc109d..07e56ff 100644 (file)
@@ -6,8 +6,10 @@ EXTRA_DIST += \
        $(srcdir)/tests/testsuite
 TESTSUITE_AT = \
        tests/testsuite.at \
+       tests/lcov-pre.at \
        tests/library.at \
-       tests/stp.at
+       tests/stp.at \
+       tests/lcov-post.at
 TESTSUITE = $(srcdir)/tests/testsuite
 DISTCLEANFILES += tests/atconfig tests/atlocal $(TESTSUITE)
 
diff --git a/tests/lcov-post.at b/tests/lcov-post.at
new file mode 100644 (file)
index 0000000..957cdfa
--- /dev/null
@@ -0,0 +1,6 @@
+AT_BANNER([code coverage])
+
+AT_SETUP([generate coverage.html with lcov])
+AT_CHECK([$LCOV || exit 77])
+AT_CHECK([cd $abs_builddir && genhtml -o coverage.html coverage.info], [0], [ignore], [ignore])
+AT_CLEANUP
diff --git a/tests/lcov-pre.at b/tests/lcov-pre.at
new file mode 100644 (file)
index 0000000..1ecfeb1
--- /dev/null
@@ -0,0 +1,21 @@
+AT_BANNER([code coverage])
+
+m4_define([_OVS_RUN_LCOV], [test $LCOV = false || lcov -b $abs_top_builddir -d $abs_top_builddir $1])
+
+AT_SETUP([initialize lcov])
+AT_CHECK([rm -fr $abs_builddir/coverage.html])
+AT_CHECK([rm -f $abs_builddir/coverage.info])
+AT_CHECK([$LCOV || exit 77])
+AT_CHECK([_OVS_RUN_LCOV([-c -i -o - > $abs_builddir/coverage.info])], [0], [ignore], [ignore])
+AT_CLEANUP
+
+# OVS_CHECK_LCOV(COMMAND, [STATUS = `0'], [STDOUT = `'], [STDERR = `'], 
+#                [RUN-IF-FAIL], [RUN-IF-PASS])
+#
+# This macro is equivalent to AT_CHECK, except that COMMAND should be a single
+# shell command that invokes a program whose code coverage is to be measured
+# (if configure was invoked with --coverage).  
+m4_define([OVS_CHECK_LCOV],
+    [AT_CHECK([_OVS_RUN_LCOV([-z])], [0], [ignore], [ignore])
+     AT_CHECK($@)
+     AT_CHECK([_OVS_RUN_LCOV([-c -o - >> $abs_builddir/coverage.info])], [0], [ignore], [ignore])])
index c703241..c48828e 100644 (file)
@@ -2,38 +2,38 @@ AT_BANNER([library unit tests])
 
 AT_SETUP([test flow extractor])
 AT_CHECK([$PERL `which flowgen.pl` >/dev/null 3>flows 4>pcap])
-AT_CHECK([test-flows <flows 3<pcap], [0], [checked 247 packets, 0 errors
+OVS_CHECK_LCOV([test-flows <flows 3<pcap], [0], [checked 247 packets, 0 errors
 ])
 AT_CLEANUP
 
 AT_SETUP([test TCP/IP checksumming])
-AT_CHECK([test-csum], [0], [ignore])
+OVS_CHECK_LCOV([test-csum], [0], [ignore])
 AT_CLEANUP
 
 AT_SETUP([test flow classifier])
-AT_CHECK([test-classifier], [0], [ignore])
+OVS_CHECK_LCOV([test-classifier], [0], [ignore])
 AT_CLEANUP
 
 AT_SETUP([test hash functions])
-AT_CHECK([test-hash], [0], [ignore])
+OVS_CHECK_LCOV([test-hash], [0], [ignore])
 AT_CLEANUP
 
 AT_SETUP([test hash map])
-AT_CHECK([test-hmap], [0], [ignore])
+OVS_CHECK_LCOV([test-hmap], [0], [ignore])
 AT_CLEANUP
 
 AT_SETUP([test linked lists])
-AT_CHECK([test-list], [0], [ignore])
+OVS_CHECK_LCOV([test-list], [0], [ignore])
 AT_CLEANUP
 
 AT_SETUP([test SHA-1])
-AT_CHECK([test-sha1], [0], [ignore])
+OVS_CHECK_LCOV([test-sha1], [0], [ignore])
 AT_CLEANUP
 
 AT_SETUP([test type properties])
-AT_CHECK([test-type-props], [0], [ignore])
+OVS_CHECK_LCOV([test-type-props], [0], [ignore])
 AT_CLEANUP
 
 AT_SETUP([test vconn library])
-AT_CHECK([test-vconn], [0], [ignore])
+OVS_CHECK_LCOV([test-vconn], [0], [ignore])
 AT_CLEANUP
index 4e25af7..6e2bcf9 100644 (file)
@@ -15,7 +15,7 @@ check 2 = F:10 B
 check 3 = F:5 F
 check 4 = F:5 B
 ])
-AT_CHECK([test-stp test-stp-ieee802.1d-1998])
+OVS_CHECK_LCOV([test-stp test-stp-ieee802.1d-1998])
 AT_CLEANUP
 
 AT_SETUP([STP example from IEEE 802.1D-2004 figures 17.4 and 17.5])
@@ -52,7 +52,7 @@ check 5 = F:20 B F F
 check 6 = F:20 B F F
 check 7 = F:20 B F B
 ])
-AT_CHECK([test-stp test-stp-ieee802.1d-2004-fig17.4])
+OVS_CHECK_LCOV([test-stp test-stp-ieee802.1d-2004-fig17.4])
 AT_CLEANUP
 
 AT_SETUP([STP example from IEEE 802.1D-2004 figure 17.6])
@@ -72,7 +72,7 @@ check 3 = F:30 F B
 check 4 = F:20 F F
 check 5 = F:10 F F
 ])
-AT_CHECK([test-stp test-stp-ieee802.1d-2004-fig17.6])
+OVS_CHECK_LCOV([test-stp test-stp-ieee802.1d-2004-fig17.6])
 AT_CLEANUP
 
 AT_SETUP([STP example from IEEE 802.1D-2004 figure 17.7])
@@ -95,7 +95,7 @@ check 0 = root
 check 1 = F F:10 F F F F F F
 check 2 = F:20 D F F F F F F
 ])
-AT_CHECK([test-stp test-stp-ieee802.1d-2004-fig17.7])
+OVS_CHECK_LCOV([test-stp test-stp-ieee802.1d-2004-fig17.7])
 AT_CLEANUP
 
 AT_SETUP([STP.io.1.1: Link Failure])
@@ -128,7 +128,7 @@ run 1000
 check 0 = root
 check 1 = D D F:10
 ])
-AT_CHECK([test-stp test-stp-iol-io-1.1])
+OVS_CHECK_LCOV([test-stp test-stp-iol-io-1.1])
 AT_CLEANUP
 
 AT_SETUP([STP.io.1.2: Repeated Network])
@@ -148,7 +148,7 @@ run 1000
 check 0 = rootid:0x111 F B
 check 1 = rootid:0x111 B F:10
 ])
-AT_CHECK([test-stp test-stp-iol-io-1.2])
+OVS_CHECK_LCOV([test-stp test-stp-iol-io-1.2])
 AT_CLEANUP
 
 AT_SETUP([STP.io.1.4: Network Initialization])
@@ -168,7 +168,7 @@ check 1 = F:10 F F
 check 2 = F:10 B F
 check 3 = F:10 B B
 ])
-AT_CHECK([test-stp test-stp-iol-io-1.4])
+OVS_CHECK_LCOV([test-stp test-stp-iol-io-1.4])
 AT_CLEANUP
 
 AT_SETUP([STP.io.1.5: Topology Change])
@@ -215,7 +215,7 @@ check 1 = F:10 B F F
 check 2 = B F:10 F F
 check 3 = B F:20 B B
 ])
-AT_CHECK([test-stp test-stp-iol-io-1.5])
+OVS_CHECK_LCOV([test-stp test-stp-iol-io-1.5])
 AT_CLEANUP
 
 AT_SETUP([STP.op.1.1 and STP.op.1.2])
@@ -229,7 +229,7 @@ AT_DATA([test-stp-iol-op-1.1],
 bridge 0 0x123 =
 check 0 = root
 ])
-AT_CHECK([test-stp test-stp-iol-op-1.1])
+OVS_CHECK_LCOV([test-stp test-stp-iol-op-1.1])
 AT_CLEANUP
 
 AT_SETUP([STP.op.1.4: All Ports Initialized to Designated Ports])
@@ -244,7 +244,7 @@ check 0 = Li Li Li Li Li Li
 run 1000
 check 0 = F F F F F F
 ])
-AT_CHECK([test-stp test-stp-iol-op-1.4])
+OVS_CHECK_LCOV([test-stp test-stp-iol-op-1.4])
 AT_CLEANUP
 
 AT_SETUP([STP.op.3.1: Root Bridge Selection: Root ID Values])
@@ -262,7 +262,7 @@ run 1000
 check 0 = rootid:0x111 root
 check 1 = rootid:0x111 F:10
 ])
-AT_CHECK([test-stp test-stp-iol-op-3.1])
+OVS_CHECK_LCOV([test-stp test-stp-iol-op-3.1])
 AT_CLEANUP
 
 AT_SETUP([STP.op.3.3: Root Bridge Selection: Bridge ID Values])
@@ -280,7 +280,7 @@ check 0 = rootid:0x333^0x6000 root
 check 1 = rootid:0x333^0x6000 F:20
 check 2 = rootid:0x333^0x6000 F:10 F
 ])
-AT_CHECK([test-stp test-stp-iol-op-3.3])
+OVS_CHECK_LCOV([test-stp test-stp-iol-op-3.3])
 AT_CLEANUP
 
 AT_SETUP([STP.op.3.3: Root Bridge Selection: Bridge ID Values])
@@ -298,6 +298,6 @@ check 0 = rootid:0x333^0x6000 root
 check 1 = rootid:0x333^0x6000 F:20
 check 2 = rootid:0x333^0x6000 F:10 F
 ])
-AT_CHECK([test-stp test-stp-iol-op-3.4])
+OVS_CHECK_LCOV([test-stp test-stp-iol-op-3.4])
 AT_CLEANUP
 
index 0ad34c2..f894c2a 100644 (file)
@@ -16,5 +16,7 @@ limitations under the License.])
 
 AT_TESTED([ovs-vswitchd])
 
+m4_include([tests/lcov-pre.at])
 m4_include([tests/library.at])
 m4_include([tests/stp.at])
+m4_include([tests/lcov-post.at])