From: David Steele Date: Mon, 8 Aug 2016 19:36:28 +0000 (+0100) Subject: Updated patch-coverage tool to catch fewer errors X-Git-Tag: dali_1.2.1~10 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=commitdiff_plain;h=44857df1489b23e2f4ac5f7b621b0d0722e99ebb Updated patch-coverage tool to catch fewer errors Patch coverage tool was catching coverage errors for files in non-source tree and of non-source code, also was catching changes that had no coverage change. Also added mechanism to choose the right patch, or to fail if there are changes in both the working tree and the index. Also added html output. One minor gotcha spotted - added test code which was in-advertently covered because of a case fallthrough, and passed, though this then caused unchanged code to reduce in coverage. Change-Id: Id49d30935b2dc9ef3145bf6bc78ec7510de01fd0 Signed-off-by: David Steele --- diff --git a/automated-tests/patch-coverage.pl b/automated-tests/patch-coverage.pl index 68754eb..c19953b 100755 --- a/automated-tests/patch-coverage.pl +++ b/automated-tests/patch-coverage.pl @@ -45,16 +45,14 @@ our $repo = Git->repository(); our $debug=0; our $pd_debug=0; our $opt_cached; -our $opt_head; -#our $opt_workingtree; -#our $opt_diff=1; our $opt_help; -our $opt_verbose; +our $opt_output; our $opt_quiet; +our $opt_verbose; my %options = ( "cached" => { "optvar"=>\$opt_cached, "desc"=>"Use index" }, - "head" => { "optvar"=>\$opt_head, "desc"=>"Use git show" }, + "output:s" => { "optvar"=>\$opt_output, "desc"=>"Generate html output"}, "help" => { "optvar"=>\$opt_help, "desc"=>""}, "quiet" => { "optvar"=>\$opt_quiet, "desc"=>""}, "verbose" => { "optvar"=>\$opt_verbose, "desc"=>"" }); @@ -323,6 +321,7 @@ sub get_coverage # output for the patch. sub run_diff { + #print "run_diff(" . join(" ", @_) . ")\n"; my ($fh, $c) = $repo->command_output_pipe(@_); our @patch=(); while(<$fh>) @@ -332,6 +331,8 @@ sub run_diff } $repo->command_close_pipe($fh, $c); + print "Patch size: " . scalar(@patch) . "\n" if $debug; + # @patch has slurped diff for all files... my $filesref = parse_diff ( \@patch ); show_patch_lines($filesref) if $debug; @@ -344,6 +345,7 @@ sub run_diff for my $file (keys(%$filesref)) { my ($name, $path, $suffix) = fileparse($file, qr{\.[^.]*$}); + next if($path !~ /^dali/); if($suffix eq ".cpp" || $suffix eq ".c" || $suffix eq ".h") { get_coverage($file, $filesref); @@ -353,7 +355,6 @@ sub run_diff return $filesref; } - sub calc_patch_coverage_percentage { my $filesref = shift; @@ -362,6 +363,9 @@ sub calc_patch_coverage_percentage foreach my $file (keys(%$filesref)) { + my ($name, $path, $suffix) = fileparse($file, qr{\.[^.]*$}); + next if($path !~ /^dali/); + my $covered_lines = 0; my $uncovered_lines = 0; @@ -401,7 +405,7 @@ sub calc_patch_coverage_percentage my $percent = 0; if($total_exec > 0) { $percent = 100 * $total_covered_lines / $total_exec; } - return $percent; + return [ $total_exec, $percent ]; } sub patch_output @@ -480,6 +484,117 @@ sub patch_output } +sub patch_html_output +{ + my $filesref = shift; + + open( my $filehandle, ">", $opt_output ) || die "Can't open $opt_output for writing:$!\n"; + + my $OUTPUT_FH = select; + select $filehandle; + print < + + +Patch Coverage + + +EOH + + foreach my $file (keys(%$filesref)) + { + my ($name, $path, $suffix) = fileparse($file, qr{\.[^.]*$}); + next if($path !~ /^dali/); + + my $patchref = $filesref->{$file}->{"patch"}; + my $b_lines_ref = $filesref->{$file}->{"b_lines"}; + my $coverage_ref = $filesref->{$file}->{"coverage"}; + print "

$file

\n"; + + if($coverage_ref) + { + if( $coverage_ref->{"covered_lines"} > 0 + || + $coverage_ref->{"uncovered_lines"} > 0 ) + { + print "

Covered: " . + $coverage_ref->{"covered_lines"} . "

" . + "

Uncovered: " . + $coverage_ref->{"uncovered_lines"} . "

"; + } + } + else + { + print "

"; + my $span=0; + if($suffix eq ".cpp" || $suffix eq ".c" || $suffix eq ".h") + { + print ""; + $span=1; + } + print "No coverage found"; + print "" if $span; + } + print "

"; + + for my $patch (@$patchref) + { + my $hunkstr="Hunk: " . $patch->[0]; + if( $patch->[1] > 1 ) + { + $hunkstr .= " - " . ($patch->[0]+$patch->[1]-1); + } + print "

" . $hunkstr . "

"; + + print "
";
+            for(my $i = 0; $i < $patch->[1]; $i++ )
+            {
+                my $line = $i + $patch->[0];
+                my $num_line_digits=log($line)/log(10);
+                for $i (0..(6-$num_line_digits-1))
+                {
+                    print " ";
+                }
+                print "$line  ";
+
+                if($coverage_ref)
+                {
+                    my $color;
+                    if($coverage_ref->{"covered"}->{$line})
+                    {
+                        print("");
+                    }
+                    elsif($coverage_ref->{"uncovered"}->{$line})
+                    {
+                        print("");
+                    }
+                    else
+                    {
+                        #print("");
+                    }
+                    my $src=$coverage_ref->{"src"}->{$line};
+                    chomp($src);
+                    #print $color, "$src\n", RESET;
+                    print "$src\n";
+                }
+                else
+                {
+                    # We don't have coverage data, so print it from the patch instead.
+                    my $src = $b_lines_ref->{$line};
+                    print "$src\n";
+                }
+            }
+            print "<\pre>\n";
+        }
+    }
+
+    print $filehandle "
\n\n\n"; + close $filehandle; + select $OUTPUT_FH; +} + + ################################################################################ ## MAIN ## ################################################################################ @@ -492,30 +607,82 @@ chdir "build/tizen"; my @cmd=('--no-pager','diff','--no-ext-diff','-U0','--no-color'); my $status = $repo->command("status", "-s"); -if( $status eq "" ) +if( $status eq "" && !scalar(@ARGV)) { - # There are no changes in the index or working tree. Use the last patch instead + # There are no changes in the index or working tree, and + # no diff arguments to append. Use the last patch instead. push @cmd, ('HEAD~1','HEAD'); } -elsif($opt_cached) # TODO: Remove this option. Instead, need full diff +else { - push @cmd, "--cached"; + # detect if there are only cached changes or only working tree changes + my $cached = 0; + my $working = 0; + for my $fstat ( split(/\n/, $status) ) + { + if(substr( $fstat, 0, 1 ) ne " "){ $cached++; } + if(substr( $fstat, 1, 1 ) ne " "){ $working++; } + } + if($cached > 0 ) + { + if($working == 0) + { + push @cmd, "--cached"; + } + else + { + die "Both cached & working files - cannot get correct patch from git\n"; + # Would have to diff from separate clone. + } + } } push @cmd, @ARGV; my $filesref = run_diff(@cmd); -my $percent = calc_patch_coverage_percentage($filesref); -if( ! $opt_quiet ) +chdir $cwd; + +# Check how many actual source files there are in the patch +my $filecount = 0; +foreach my $file (keys(%$filesref)) +{ + my ($name, $path, $suffix) = fileparse($file, qr{\.[^.]*$}); + next if($path !~ /^dali/); + next if($suffix ne ".cpp" && $suffix ne ".c" && $suffix ne ".h"); + $filecount++; +} +if( $filecount == 0 ) +{ + print "No source files found\n"; + exit 0; # Exit with no error. +} + +my $percentref = calc_patch_coverage_percentage($filesref); +if($percentref->[0] == 0) +{ + print "No coverable lines found\n"; + exit 0; +} +my $percent = $percentref->[1]; + +my $color=BOLD RED; +if($opt_output) +{ + print "Outputing to $opt_output\n" if $debug; + patch_html_output($filesref); +} +elsif( ! $opt_quiet ) { patch_output($filesref); - my $color=BOLD RED; if($percent>=90) { $color=GREEN; } - printf("Percentage of change covered: $color %5.2f%\n" . RESET, $percent); + print RESET; } + +printf("Percentage of change covered: %5.2f%\n", $percent); + exit($percent<90);