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 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
|
#!/usr/bin/perl -w
# script to see if new test files increase code coverage.
# compile code with gcc options -fprofile-arcs -ftest-coverage.
# place baseline and candidate test in the relative subdirectories oldtests
# and newtests repectively.
# run this script.
use FILE::Find;
use strict;
# old and new test file locations (relative, recursive, can be sym
# links).
my $baseline_tests='oldtests';
my $testcase_candidates='newtests';
# subdir of all covered files (recursive)
my $cfiles="../../";
# hash - key is c file covered, value percent coverage.
my %baseline_coverage=();
my %new_tests_plus_baseline_coverage=();
# file to hold %baseline_coverage.
my $base="baseline.txt";
# commands to run on test files.
my @args= ( ["./gpcl6", "-n", "-sDEVICE=ppmraw", "-sOutputFile=/dev/null", "-r300", "-dNOPAUSE" ],
["./gpcl6", "-n", "-sDEVICE=pbmraw", "-sOutputFile=/dev/null", "-r300", "-dNOPAUSE" ], );
# parse gcov output
sub get_coverage_for_a_source_file {
my $test = shift(@_);
my $source_file; my $percent;
open (PIPE, "gcov $test 2>&1|") || die "gcov pipe failed $!";
while (<PIPE>) {
if (/^File \'(.*)\'/) { $source_file = $1; }
if (/^Lines executed:(\d+\.\d+)\%/) { $percent = $1; }
}
return ($source_file, $percent);
}
sub clear_coverage {
# yikes
unlink glob("*.gcov");
unlink glob("*.gcda");
}
sub print_coverage_increase {
my $test_file = shift(@_);
my $total = 0;
while (my($f, $p) = each(%baseline_coverage)) {
exists $new_tests_plus_baseline_coverage{$f} ||
die "internal error: regenerate baseline with recompiled code\n";
my $np = $new_tests_plus_baseline_coverage{$f};
if ( $np > $p ) {
print "test file: $test_file caused coverage increase for $f increased from $p to $np\n";
$total++;
}
}
print "test file: $test_file changed coverage for $total files\n";
}
sub proc_new_coverage {
if (/^.*\.c\z/s) {
my $cf = $File::Find::name;
print "$cf\r";
my($f, $p) = get_coverage_for_a_source_file $cf;
$new_tests_plus_baseline_coverage{$f} = $p if (defined($f) && defined($p));
}
}
sub proc_run_tests {
if (-f $_) {
my $f = $File::Find::name;
map(print("@$_ $f\n"), @args);
map(system(@$_, $f), @args);
}
}
sub proc_run_new_tests {
if (-f $_) {
my $f = $File::Find::name;
clear_coverage;
map(print("@$_ $f\n"), @args);
map(system(@$_, $f), @args);
File::Find::find({ wanted => \&proc_new_coverage, no_chdir => 1 }, $cfiles);
print_coverage_increase $f;
}
}
sub proc_baseline_coverage {
if (/^.*\.c\z/s) {
print "$File::Find::name\r";
my($s, $p) = get_coverage_for_a_source_file $File::Find::name;
print(BASE "$s $p\n") if (defined($s) && defined($p));
}
}
sub build_baseline {
open(BASE, ">>$base");
File::Find::find({ wanted => \&proc_run_tests, no_chdir => 1 }, $baseline_tests);
File::Find::find({ wanted => \&proc_baseline_coverage, no_chdir => 1 }, $cfiles);
close(BASE);
}
sub do_new_tests {
File::Find::find({ wanted => \&proc_run_new_tests, no_chdir => 1 }, $testcase_candidates);
}
build_baseline unless (-e $base);
open(BASE, $base) || die "open (BASELINE, $base)";
# read the baseline
%baseline_coverage=();
while (<BASE>) {
chomp;
my ($source_file, $percent) = split(/ /);
$baseline_coverage{$source_file} = $percent;
}
close(BASE);
do_new_tests;
|