Add test-suite coverage testing using gcov Add a new "coverage" Makefile target that re-builds the library and tests using the gcc compiler/linker flags required by gcov, runs the test suite to capture the runtime data, then compiles a coverage report. The report, which is saved in a file named "untested", consists of a list of untested files, followed by a list of untested functions. More detailed execution statistics are given in the gcov log files which are saved in the top-level directory (named like src#hash.c.gcov). Signed-off-by: Ramsay Jones <ramsay@ramsay1.demon.co.uk>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
diff --git a/.gitignore b/.gitignore
index 66ce776..5c7507c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,3 +4,6 @@
*.o
*.a
*.exe
+*.gcda
+*.gcno
+*.gcov
diff --git a/Makefile b/Makefile
index dfae6ed..a0a6eea 100644
--- a/Makefile
+++ b/Makefile
@@ -72,6 +72,7 @@ clean:
rm -rf apidocs
rm -f *~ src/*~ src/git/*~ src/sha1/*~ src/unix/*~ src/win32/*~
@$(MAKE) -C tests -s --no-print-directory clean
+ @$(MAKE) -s --no-print-directory cov-clean
test-clean:
@$(MAKE) -C tests -s --no-print-directory clean
@@ -134,3 +135,41 @@ libgit2.pc: libgit2.pc.in
.PHONY: install-headers
.PHONY: install uninstall
.PHONY: sparse
+
+### Test suite coverage testing
+#
+.PHONY: coverage cov-clean cov-build cov-report
+
+COV_GCDA = $(patsubst %.c,%.gcda,$(SRC_C))
+COV_GCNO = $(patsubst %.c,%.gcno,$(SRC_C))
+
+coverage:
+ @$(MAKE) -s --no-print-directory clean
+ @$(MAKE) --no-print-directory cov-build
+ @$(MAKE) --no-print-directory cov-report
+
+cov-clean:
+ rm -f $(COV_GCDA) $(COV_GCNO) *.gcov untested
+
+COV_CFLAGS = $(CFLAGS) -O0 -ftest-coverage -fprofile-arcs
+
+cov-build:
+ $(MAKE) CFLAGS="$(COV_CFLAGS)" all
+ $(MAKE) TEST_COVERAGE=1 NO_OPENSSL=$(NO_OPENSSL) test
+
+cov-report:
+ @echo "--- untested files:" | tee untested
+ @{ for f in $(SRC_C); do \
+ gcda=$$(dirname $$f)"/"$$(basename $$f .c)".gcda"; \
+ if test -f $$gcda; then \
+ gcov -b -p -o $$(dirname $$f) $$f >/dev/null; \
+ else \
+ echo $$f | tee -a untested; \
+ fi; \
+ done; }
+ @rm -f *.h.gcov
+ @echo "--- untested functions:" | tee -a untested
+ @grep '^function .* called 0' *.c.gcov \
+ | sed -e 's/\([^:]*\)\.gcov:function \([^ ]*\) called.*/\1: \2/' \
+ | sed -e 's|#|/|g' | tee -a untested
+
diff --git a/tests/Makefile b/tests/Makefile
index 813b246..2ad730b 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -25,6 +25,10 @@ TEST_EXE = $(patsubst %.o,%.exe,$(TEST_OBJ))
TEST_RUN = $(patsubst %.exe,%.run,$(TEST_EXE))
TEST_VAL = $(patsubst %.exe,%.val,$(TEST_EXE))
+ifdef TEST_COVERAGE
+ EXTRA_LIBS += -O0 -lgcov
+endif
+
ifndef NO_OPENSSL
EXTRA_LIBS += $(CRYPTO_LIB)
endif
@@ -32,7 +36,7 @@ endif
BASIC_CFLAGS := -I../src
ALL_CFLAGS = $(CFLAGS) $(BASIC_CFLAGS)
-LIBS += $(EXTRA_LIBS)
+ALL_LIBS = $(LIBS) $(EXTRA_LIBS)
all:: $(TEST_RUN)
@@ -74,7 +78,7 @@ $(TEST_EXE): %.exe: %.o %_main.o
$(LD) -o $@ \
$(patsubst %.exe,%_main.o,$@) \
$(patsubst %.exe,%.o,$@) \
- $(T_LIB) $(LIBS)
+ $(T_LIB) $(ALL_LIBS)
$(TEST_RUN): %.run: %.exe
@t=trash-$(<F) && \