diff --git a/.github/workflows/run_test_suite.yml b/.github/workflows/run_test_suite.yml index 3d66cd5d..f7bc0a0e 100644 --- a/.github/workflows/run_test_suite.yml +++ b/.github/workflows/run_test_suite.yml @@ -47,9 +47,12 @@ jobs: - runs-on: ubuntu-24.04 gcc: 14 install: - - runs-on: ubuntu-24.04 - gcc: 15 - install: binutils g++-15 gcc-15 cpp-15 + # gcc-15 no longer available on ubuntu-24.04 + # and job hangs if I try to use 25.10 + # Simply comment out/disable gcc-15 test for now + # - runs-on: ubuntu-25.10 + # gcc: 15 + # install: binutils g++-15 gcc-15 cpp-15 steps: - uses: actions/checkout@v6 diff --git a/bin/py2lcov b/bin/py2lcov index a22a9748..42199859 100755 --- a/bin/py2lcov +++ b/bin/py2lcov @@ -110,7 +110,7 @@ Example: For backward compatibility, py2lcov also supports translation to LCOV format from intermediate XML: - # first translate from Python coerage data to XML: + # first translate from Python coverage data to XML: $ coverage xml --data-file=${PYCOV_DATA} -o pydata.xml |& tee pydata.log # or - if your Coverage.py module is too old to support '--data-file': $ COVERAGE_FILE=${PYCOV_DATA} coverage xml -o pydata.xml |& tee pydata.log diff --git a/example/Makefile b/example/Makefile index 3a5435e8..51a5ca78 100644 --- a/example/Makefile +++ b/example/Makefile @@ -145,7 +145,7 @@ test_overflow: # code and rerun some tests. # The differential coverage report is categorizes the code based on # what changed in the source code and what changed in the tests. -# Note that we are suing perl module for callbacks here - but could use +# Note that we are using perl module for callbacks here - but could use # script or executable if desired. # Could use --verbose and --quiet flags to make the execution less noisy - # but verbosity can help to debug configuration issues. diff --git a/scripts/criteria.pm b/scripts/criteria.pm index dc7088a7..14ddb7fa 100644 --- a/scripts/criteria.pm +++ b/scripts/criteria.pm @@ -20,7 +20,8 @@ # # This script is used as a genhtml "--criteria-script criteria" callback. # It is called by genhtml at each level of hierarchy - but ignores all but -# the top level, and looks only at line coverage. +# the top level, and looks at line coverage and zero or more of function, +# branch, and MC/DC coverage. # # Format of the JSON input is: # {"line":{"found":10,"hit:2,"UNC":2,..},"function":{...},"branch":{}" @@ -33,9 +34,11 @@ # # If passed the "--suppress" flag, this script will exit with status 0, # even if the coverage criteria is not met. -# genhtml --criteria-script 'path/criteria --signoff' .... +# genhtml --criteria-script \ +# 'path/criteria --signoff [--function] [--branch] [--mcdc]' .... # # It is not hard to envision much more complicated coverage criteria. + package criteria; use strict; @@ -44,7 +47,8 @@ use Getopt::Long qw(GetOptionsFromArray); our @ISA = qw(Exporter); our @EXPORT_OK = qw(new); -use constant {SIGNOFF => 0,}; +use constant {SIGNOFF => 0, + TYPES =>1,}; sub new { @@ -53,17 +57,29 @@ sub new my $script = shift; my $standalone = $script eq $0; my @options = @_; + my $function = 0; + my $branch = 0; + my $mcdc = 0; - if (!GetOptionsFromArray(\@_, ('signoff' => \$signoff)) || + if (!GetOptionsFromArray(\@_, ('signoff' => \$signoff, + 'function' => \$function, + 'branch' => \$branch, + 'mcdc' => \$mcdc, + )) || (!$standalone && @_)) { print(STDERR "Error: unexpected option:\n " . join(' ', @options) . - "\nusage: name type json-string [--signoff]\n"); + "\nusage: name type json-string [--signoff] [--branch] [--mcdc] [--function]\n"); exit(1) if $standalone; return undef; } - - my $self = [$signoff]; + my @types = ('line'); + foreach my $t (['function', $function], + ['MC/DC', $mcdc], + ['branch', $branch]) { + push(@types, $t->[0]) if $t->[1]; + } + my $self = [$signoff, \@types]; return bless $self, $class; } @@ -76,18 +92,25 @@ sub check_criteria if ($type eq 'top') { # for the moment - only worry about the top-level coverage - if (exists($db->{'line'})) { + my $s = ''; + foreach my $t (@{$self->[TYPES]}) { + next unless exists($db->{$t}); + # our criteria is LBC + UNC + UIC == 0 my $sep = ''; my $sum = 0; my $msg = ''; my $counts = ''; - my $lines = $db->{'line'}; + my $data = $db->{$t}; + # say which type - if there is more than one + $msg .= "$s$t: " if 1 <= $#{$self->[TYPES]}; + $s = ' '; + foreach my $tla ('UNC', 'LBC', 'UIC') { $msg .= $sep . $tla; $counts .= $sep; - if (exists $lines->{$tla}) { - my $count = $lines->{$tla}; + if (exists $data->{$tla}) { + my $count = $data->{$tla}; $sum += $count; $counts .= "$count"; } else { @@ -95,9 +118,9 @@ sub check_criteria } $sep = ' + '; } - $fail = $sum != 0; + $fail ||= $sum != 0; push(@messages, $msg . " != 0: " . $counts . "\n") - if $fail; + if $sum != 0; } } diff --git a/tests/gendiffcov/filter/filter.pl b/tests/gendiffcov/filter/filter.pl index c5a741f7..a6a37a97 100755 --- a/tests/gendiffcov/filter/filter.pl +++ b/tests/gendiffcov/filter/filter.pl @@ -5,7 +5,7 @@ use FindBin; use lib "$FindBin::RealBin/../../../lib"; # build dir testcase -use lib "$ENV{LCOV_HOME}/lib/lcov"; # install testcase +use lib (exists($ENV{LCOV_HOME}) ? $ENV{LCOV_HOME} : "../../../lib") . '/lib/lcov'; use lcovutil; lcovutil::parseOptions({}, {}); diff --git a/tests/llvm2lcov/llvm2lcov.sh b/tests/llvm2lcov/llvm2lcov.sh index 2de54857..9b4d279e 100755 --- a/tests/llvm2lcov/llvm2lcov.sh +++ b/tests/llvm2lcov/llvm2lcov.sh @@ -19,7 +19,15 @@ fi LCOV_OPTS="--branch-coverage $PARALLEL $PROFILE" -clang++ -fprofile-instr-generate -fcoverage-mapping -fcoverage-mcdc -o test main.cpp +IFS='.' read -r -a LLVM_VER <<< `clang -dumpversion` +if [ "${LLVM_VER[0]}" -ge 18 ] ; then + ENABLE_MCDC=1 + CLANG_FLAGS="-fcoverage-mcdc" + MCDC_FLAG=--mcdc +fi + + +clang++ -fprofile-instr-generate -fcoverage-mapping $CLANG_FLAGS -o test main.cpp if [ $? != 0 ] ; then echo "clang++ exec failed" exit 1 @@ -50,28 +58,30 @@ if [ $? != 0 ] ; then exit 1 fi -# disable branch coverage -$COVER $LLVM2LCOV_TOOL --mcdc -o test.info test.json -if [ $? != 0 ] ; then - echo "llvm2lcov failed" - exit 1 +if [ "$ENABLE_MCDC" == "1" ] ; then + # disable branch coverage + $COVER $LLVM2LCOV_TOOL --mcdc -o test.info test.json + if [ $? != 0 ] ; then + echo "llvm2lcov failed" + exit 1 + fi fi -$COVER $LLVM2LCOV_TOOL --branch --mcdc -o test.info test.json +$COVER $LLVM2LCOV_TOOL --branch $MCDC_FLAG -o test.info test.json if [ $? != 0 ] ; then echo "llvm2lcov failed" exit 1 fi # should be valid data to generate HTML -$COVER $GENHTML_TOOL --flat --branch --mcdc -o report test.info +$COVER $GENHTML_TOOL --flat --branch $MCDC_FLAG -o report test.info if [ $? != 0 ] ; then echo "genhtml failed" exit 1 fi # run again, excluding 'main.cpp' -$COVER $LLVM2LCOV_TOOL --branch --mcdc -o test.excl.info test.json --exclude '*/main.cpp' +$COVER $LLVM2LCOV_TOOL --branch $MCDC_FLAG -o test.excl.info test.json --exclude '*/main.cpp' if [ $? != 0 ] ; then echo "llvm2lcov --exclude failed" exit 1 @@ -189,26 +199,27 @@ for line in 33 36 39 44 ; do fi done -# check branches total number -grep -E "BRF:56$" test.info -if [ $? != 0 ] ; then - echo "unexpected total number of branches" - if [ 0 == $KEEP_GOING ] ; then - exit 1 +if [ "${LLVM_VER[0]}" -ge 16 ] ; then + # check branches total number + grep -E "BRF:56$" test.info + if [ $? != 0 ] ; then + echo "unexpected total number of branches" + if [ 0 == $KEEP_GOING ] ; then + exit 1 + fi fi -fi -# check branches hit number -grep -E "BRH:35$" test.info -if [ $? != 0 ] ; then - echo "unexpected hit number of branches" - if [ 0 == $KEEP_GOING ] ; then - exit 1 + # check branches hit number + grep -E "BRH:35$" test.info + if [ $? != 0 ] ; then + echo "unexpected hit number of branches" + if [ 0 == $KEEP_GOING ] ; then + exit 1 + fi fi fi # LLVM/21 and later generate JSON data files in the new format. # So, these files should be processed differently. -IFS='.' read -r -a LLVM_VER <<< `clang -dumpversion` if [ "${LLVM_VER[0]}" -ge 21 ] ; then # line main.cpp:70 should contain 2 groups of MC/DC entries line=70 @@ -261,7 +272,7 @@ if [ "${LLVM_VER[0]}" -ge 21 ] ; then exit 1 fi fi -else +elif [ "$ENABLE_MCDC" == "1" ] ; then # line main.cpp:70 should contain 2 groups of MC/DC entries line=70 MCDC_1=`grep -c "MCDC:$line,2," test.info`