From: Derrick Stolee <[email protected]>

We have coverage targets in our Makefile for using gcov to display line
coverage based on our test suite. The way I like to do it is to run:

    make coverage-test
    make coverage-report

This leaves the repo in a state where every X.c file that was covered has
an X.c.gcov file containing the coverage counts for every line, and "#####"
at every uncovered line.

There have been a few bugs in recent patches what would have been caught
if the test suite covered those blocks (including a few of mine). I want
to work towards a "sensible" amount of coverage on new topics. In my opinion,
this means that any logic should be covered, but the 'die()' blocks covering
very unlikely (or near-impossible) situations may not warrant coverage.

It is important to not measure the coverage of the codebase by what old code
is not covered. To help, I created the 'contrib/coverage-diff.sh' script.
After creating the coverage statistics at a version (say, 'topic') you can
then run

    contrib/coverage-diff.sh base topic

to see the lines added between 'base' and 'topic' that are not covered by the
test suite. The output uses 'git blame -c' format so you can find the commits
responsible and view the line numbers for quick access to the context.

Helped-by: Junio C Hamano <[email protected]>
Signed-off-by: Derrick Stolee <[email protected]>
---
 contrib/coverage-diff.sh | 79 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 79 insertions(+)
 create mode 100755 contrib/coverage-diff.sh

diff --git a/contrib/coverage-diff.sh b/contrib/coverage-diff.sh
new file mode 100755
index 0000000000..48b9a3ae96
--- /dev/null
+++ b/contrib/coverage-diff.sh
@@ -0,0 +1,79 @@
+#!/bin/sh
+
+# Usage: Run 'contrib/coverage-diff.sh <version1> <version2>' from source-root
+# after running
+#
+#     make coverage-test
+#     make coverage-report
+#
+# while checked out at <version2>. This script combines the *.gcov files
+# generated by the 'make' commands above with 'git diff <version1> <version2>'
+# to report new lines that are not covered by the test suite.
+
+V1=$1
+V2=$2
+
+diff_lines () {
+       perl -e '
+               my $line_num;
+               while (<>) {
+                       # Hunk header?  Grab the beginning in postimage.
+                       if (/^@@ -\d+(?:,\d+)? \+(\d+)(?:,\d+)? @@/) {
+                               $line_num = $1;
+                               next;
+                       }
+
+                       # Have we seen a hunk?  Ignore "diff --git" etc.
+                       next unless defined $line_num;
+
+                       # Deleted line? Ignore.
+                       if (/^-/) {
+                               next;
+                       }
+
+                       # Show only the line number of added lines.
+                       if (/^\+/) {
+                               print "$line_num\n";
+                       }
+                       # Either common context or added line appear in
+                       # the postimage.  Count it.
+                       $line_num++;
+               }
+       '
+}
+
+files=$(git diff --name-only $V1 $V2 -- *.c)
+
+for file in $files
+do
+       git diff $V1 $V2 -- $file \
+               | diff_lines \
+               | sort >new_lines.txt
+
+       if ! test -s new_lines.txt
+       then
+               continue
+       fi
+
+       hash_file=$(echo $file | sed "s/\//\#/")
+       sed -ne '/#####:/{
+                       s/    #####://
+                       s/:.*//
+                       s/ //g
+                       p
+               }' "$hash_file.gcov" \
+               | sort >uncovered_lines.txt
+
+       comm -12 uncovered_lines.txt new_lines.txt \
+               | sed -e 's/$/\)/' \
+               | sed -e 's/^/\t/' \
+               >uncovered_new_lines.txt
+
+       grep -q '[^[:space:]]' < uncovered_new_lines.txt && \
+               echo $file && \
+               git blame -c $file \
+                       | grep -f uncovered_new_lines.txt
+
+       rm -f new_lines.txt uncovered_lines.txt uncovered_new_lines.txt
+done
+
-- 
gitgitgadget

Reply via email to