From: Richard Kettlewell Date: Tue, 27 Nov 2007 20:43:03 +0000 (+0000) Subject: gcov to report test coverage X-Git-Tag: 1.5.99+dev10~54 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~mdw/git/disorder/commitdiff_plain/1a00f59083722d4d0e273339b1f4dc28a0fb2fa3 gcov to report test coverage --- diff --git a/.bzrignore b/.bzrignore index 1b45fb1..3ccc643 100644 --- a/.bzrignore +++ b/.bzrignore @@ -130,3 +130,11 @@ tests/*.log server/disorder-dbupgrade doc/disorder-dbupgrade.8.html doc/disorder-dbupgrade.8 +*.gcov +*.gcno +*.gcda +*.c.html +clients/index.html +disobedience/index.html +lib/index.html +server/index.html diff --git a/Makefile.am b/Makefile.am index 0b6f5a7..99c4710 100644 --- a/Makefile.am +++ b/Makefile.am @@ -22,6 +22,21 @@ EXTRA_DIST=TODO CHANGES README.streams BUGS ChangeLog.d \ README.upgrades README.client README.mac README.raw SUBDIRS=@subdirs@ +check-recursive: before-check +before-check: + rm -f */*.gcda */*.gcov + +check-report: check make-coverage-reports +make-coverage-reports: + @for subdir in lib plugins server clients disobedience; do \ + echo cd $$subdir;\ + cd $$subdir;\ + echo ${GCOV} *.c | ${PYTHON} ../scripts/format-gcov-report --html . ;\ + ${GCOV} *.c | ${PYTHON} ../scripts/format-gcov-report --html . ;\ + echo cd ..;\ + cd ..;\ + done + dist-hook: bzr log > ${distdir}/ChangeLog.d/bzr-changelog diff --git a/acinclude.m4 b/acinclude.m4 index 562872a..96670f7 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -102,3 +102,15 @@ AC_DEFUN([RJK_REQUIRE_PCRE_UTF8],[ AC_MSG_ERROR([please rebuild your pcre library with --enable-utf8]) fi ]) + +AC_DEFUN([RJK_GCOV],[ + GCOV=${GCOV:-true} + AC_ARG_WITH([gcov], + [AS_HELP_STRING([--with-gcov], + [Enable coverage testing])], + [if test $withval = yes; then + CFLAGS="${CFLAGS} -O0 -fprofile-arcs -ftest-coverage" + GCOV=`echo $CC | sed s'/gcc/gcov/;s/ .*$//'`; + fi]) + AC_SUBST([GCOV],[$GCOV]) +]) diff --git a/configure.ac b/configure.ac index 99b2e97..c38990c 100644 --- a/configure.ac +++ b/configure.ac @@ -466,10 +466,10 @@ if test "x$GCC" = xyes; then if test $rjk_cv_shadow = yes; then CC="${CC} -Wshadow" fi - - fi +RJK_GCOV + AH_BOTTOM([#ifdef __GNUC__ # define attribute(x) __attribute__(x) #else diff --git a/scripts/Makefile.am b/scripts/Makefile.am index 8f1a666..81d022f 100644 --- a/scripts/Makefile.am +++ b/scripts/Makefile.am @@ -20,4 +20,5 @@ dist_pkgdata_DATA=completion.bash -EXTRA_DIST=htmlman sedfiles.make text2c oggrename make-unidata +EXTRA_DIST=htmlman sedfiles.make text2c oggrename make-unidata \ + format-gcov-report diff --git a/scripts/format-gcov-report b/scripts/format-gcov-report new file mode 100755 index 0000000..f445329 --- /dev/null +++ b/scripts/format-gcov-report @@ -0,0 +1,100 @@ +#! /usr/bin/env python +# +# This file is part of DisOrder. +# Copyright (C) 2007 Richard Kettlewell +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +# USA +# +import re,sys,os,string + +def fatal(msg): + sys.stderr.write("%s\n" % msg) + sys.exit(1) + +def sgmlquotechar(c): + if c == '&' or c == '<' or ord(c) < 32 or ord(c) > 126: + return "&#%d;" % ord(c) + else: + return c + +def sgmlquote(s): + return string.join(map(sgmlquotechar, s),'') + +percent = {} +total_lines = 0 +covered_lines = 0 +args = sys.argv[1:] +htmldir = None +while len(args) > 0: + if args[0] == "--html": + htmldir = args[1] + args = args[2:] + else: + fatal("unknown option '%s'" % args[0]) + +name = None +for line in sys.stdin: + line = line[:-1] + r = re.match("File ['`](?:.*/)?([^/]+.c)'", line) + if r: + name = r.group(1) + r = re.match("Lines executed:([0-9\\.]+)% of ([0-9]+)", line) + if r: + if name: + this_pc = float(r.group(1)) + this_lines = int(r.group(2)) + percent[name] = this_pc + total_lines += this_lines + covered_lines += this_lines * this_pc / 100.0 + name = None + +def cmp(a,b): + if percent[a] < percent[b]: return -1 + elif percent[a] > percent[b]: return 1 + else: return 0 + +keys = percent.keys() +keys.sort(cmp) + +if len(keys): + for k in keys: + print "%20s: %d%%" % (k, percent[k]) + print "Total coverage: %d%%" % (100 * (covered_lines / total_lines)) + +if htmldir is not None and len(keys): + index = open(os.path.join(htmldir, "index.html"), "w") + index.write("gcov report\n") + index.write("

gcov report

\n") + index.write("\n") + for k in keys: + index.write("
FileCoverage
%s%d%%\n" % + (sgmlquote(k), sgmlquote(k), percent[k])) + index.write("
\n") + index.write("

Total coverage: %d%%

\n" % (100 * (covered_lines / total_lines))) + for k in keys: + html = open(os.path.join(htmldir, "%s.html" % k), "w") + html.write("%s\n" % sgmlquote(k)) + html.write("

%s

\n" % sgmlquote(k)) + html.write("
")
+    r = re.compile("^ *#####:.*")
+    for line in open("%s.gcov" % k, "r"):
+      if len(line) > 0 and line[-1] == '\n':
+        line = line[:-1]
+      if r.match(line):
+        html.write("%s\n" % sgmlquote(line))
+      else:
+        html.write("%s\n" % sgmlquote(line))
+    html.write("
\n")