Friday, January 10, 2014

Merging multiple coverage files using lcov


In my earlier posts How to - gcov/lcov for linux user space process and How to - gcov/lcov for linux kernel modules, I covered how to get a code coverage report for user space applications and kernel modules. In this post, I will provide a quick tip for merging multiple coverage files.

When do we need to merge coverage (*.gcda) files?

  • In High availability/Clustering environments, we get coverage information from multiple nodes. Sometimes, developers would like to combine coverage info from all the nodes & view the merged report rather than analyze multiple reports.

Steps to collect & merge coverage info

Lets take this sample program:

#include <stdio.h>

int main ( int argc, char *argv[] )
{
    if ( argc != 2 ) /* argc should be 2 for correct execution */
    {
        /* We print argv[0] assuming it is the program name */
        printf( "usage: %s test_num", argv[0] );
    }
    else
    {
        int i = atoi(argv[1]);

        if (i == 1)
                printf("Testcase 1\r\n");
        else
                printf("Testcase 2\r\n");
    }
}
I ran two tests on this sample program, collected gcda files & merged them using lcov:
root@babu-VirtualBox:~/gcov_tests/merge_tests# ls
a.c
root@babu-VirtualBox:~/gcov_tests/merge_tests# gcc -fprofile-arcs -ftest-coverage a.c
root@babu-VirtualBox:~/gcov_tests/merge_tests# ls
a.c  a.gcno  a.out
root@babu-VirtualBox:~/gcov_tests/merge_tests# ./a.out 1
Testcase 1
root@babu-VirtualBox:~/gcov_tests/merge_tests# ls
a.c  a.gcda  a.gcno  a.out 
root@babu-VirtualBox:~/gcov_tests/merge_tests# geninfo  . -o ./coverage1.info
Found gcov version: 4.8.1
Scanning . for .gcda files ...
Found 1 data files in .
Processing a.gcda
Finished .info-file creation
root@babu-VirtualBox:~/gcov_tests/merge_tests# ls
a.c  a.gcda  a.gcno  a.out  coverage1.info 
root@babu-VirtualBox:~/gcov_tests/merge_tests# rm a.gcda
root@babu-VirtualBox:~/gcov_tests/merge_tests# ./a.out 2
Testcase 2
root@babu-VirtualBox:~/gcov_tests/merge_tests# ls
a.c  a.gcda  a.gcno  a.out  coverage1.info
root@babu-VirtualBox:~/gcov_tests/merge_tests# geninfo  . -o ./coverage2.info
Found gcov version: 4.8.1
Scanning . for .gcda files ...
Found 1 data files in .
Processing a.gcda
Finished .info-file creation
root@babu-VirtualBox:~/gcov_tests/merge_tests# ls
a.c  a.gcda  a.gcno  a.out  coverage1.info  coverage2.info
root@babu-VirtualBox:~/gcov_tests/merge_tests# mkdir lcov_data
root@babu-VirtualBox:~/gcov_tests/merge_tests# lcov --add-tracefile coverage2.info -t test2 -a coverage1.info -t test1 -o coverage_merged.info
Combining tracefiles.
Reading tracefile coverage2.info
Reading tracefile coverage1.info
Writing data to coverage_merged.info
Overall coverage rate:
  lines......: 87.5% (7 of 8 lines)
  functions..: 100.0% (1 of 1 function)
  branches...: 75.0% (3 of 4 branches)
root@babu-VirtualBox:~/gcov_tests/merge_tests# ls
a.c     a.gcno  coverage1.info  coverage_merged.info  lcov_data
a.gcda  a.out   coverage2.info  
root@babu-VirtualBox:~/gcov_tests/merge_tests# genhtml -o ./lcov_data/ ./coverage_merged.info
Reading data file ./coverage_merged.info
Found 1 entries.
Found common filename prefix "/home/babu"
Writing .css and .png files.
Generating output.
Processing file gcov_tests/merge_tests/a.c
Writing directory view page.
Overall coverage rate:
  lines......: 87.5% (7 of 8 lines)
  functions..: 100.0% (1 of 1 function)
  branches...: 75.0% (3 of 4 branches)
root@babu-VirtualBox:~/gcov_tests/merge_tests# 

I hosted my code coverage results on my google drive - https://googledrive.com/host/0B4xkNcpT6ZbddzlPMHp3bEV3dk0/. Here is the screenshot that shows coverage for a.c:

  


As we can see both the lines which prints" Testcase 1" & "Testcase 2" are shown as covered lines in the merged report. 


What are the caveats when interpreting a merged coverage report?
  • TBD

References:

1 comment:

Unknown said...

What if I want to combine 100 test results,then do I need to specify every .info file with -a option or is there a simpler way?

UA-48797665-1