Getting a sense of code coverage for open-source projects is necessary due-diligence for any dependent project. On OS X, it’s also a little more work. While doing some of my own research, I wanted to see how well tested the libevent
library was, but wasn’t finding much info online. So here’s a log of what I needed to do, to get this information on a Mac.
First things first (and this should apply for many more open-source projects), after I checked out the latest code from github, I added an option to the configure.ac
Autoconf source file to insert the necessary profiling code calls for code coverage:
With that added, I reran the autogen.sh
file, which pulls in the configure.ac
file, and regenerates the configure script, and then I ran ./configure --enable-coverage
.
Then I ran make
and specified clang
as the C compiler instead of old-school gcc
. Besides better code quality and error reports, only clang
will generate the coverage code. The Apple version of gcc
did not do so, leading to some initial confusion.
Once the build was complete, I ran the regression tests with:
Unfortunately, the following error occurred:
So I tried running tests/regress
directly and saw:
Oops.
Turns out that Apple uses the profile_rt
library to handle code coverage instead of the former gcov
library, which is why the _llvm_gcda_start_file
function symbol is missing. So I linked to the libprofile_rt.dylib
library by specifying LDFLAGS=-lprofile_rt
on the make
command line:
Rerunning make verify
, the following was output, which indicated which of the event notification subsystems were available and being tested on the system:
Once the regression tests finished, the coverage data became available in the form of *.gcno
and *.gcda
files in the test/
folder and in the .libs/
folder.
Running lcov
generated easier-to-interpret HTML files:
Once lcov
finished, all I had to do was open up html/index.html
and see how much code the coverage tests executed. (And panic? In this case, 14.5% coverage seems pretty low!)
Here’s what the lcov summary looks like:
I reran the test/regress
command to see if that would help, and it did push the coverage rate to 20%, but I need more insight into how the coverage tests are laid out, to see what else I can do. It is not clear how well the coverage tools work on multiplatform libraries like libevent
, which have configurably-included backend code that may or may not run on the platform under test. In these cases, entire sections of code can be safely ignored. But it is unclear that code coverage tools in general are going to be aware of the preprocessor conditions that were used to build a piece of software (nor would I trust most coverage tools to be able to apply those rules to a piece of source code, especially if that code is written in C++).
In any case, like I said in a previous entry, coverage ultimately is not proof of correct behavior, but it is a good start to see what parts of your code may need more attention for quality assurance tests.