Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Devel::Cover force adding unseen files - feedback requested.

5 views
Skip to first unread message

Jason Pyeron

unread,
Dec 25, 2016, 9:45:04 PM12/25/16
to per...@perl.org
Coverage works great as part on continuous integration, until a new file is added and the unit tests are blissfully ignorant of the new file's existence.

In the past with other coverage tools we would scan the source tree and do some mock operation to get the coverage tool to become aware of the source file.

Sometimes it is a bit messy, sometimes not. I think this one falls into the a little bit messy, because we had to go the internals of Devel::Cover::DB and reproduce how Cover.pm uses it.

Below is the script we are using. It provides the minimum functionality required, showing the file as 0% covered.

Does anyone have better suggestions?

-Jason Pyeron


#!/usr/bin/perl -w

use Time::HiRes qw(time);
use Data::Dumper;
use File::Find;
use Cwd;

print "load\n";

use Devel::Cover::DB;

my $dbpath="cover_db";
my $db = Devel::Cover::DB->new(db => $dbpath);
my $timeStart=time;
my $runKey="$timeStart.$$";
my %known;

print "ingest\n";

find({ wanted => \&process_coverfile, no_chdir => 1 }, "$dbpath/runs/");
find({ wanted => \&process_coverfile, no_chdir => 1 }, "$dbpath/digests");
find({ wanted => \&process_coverfile, no_chdir => 1 }, "$dbpath/structure/");

sub process_coverfile
{
if (-f $_)
{
my $x=$db->read($_);
foreach my $run ($x->runs)
{
my $h=$run->{digests};
foreach my $file (keys %$h)
{
if ( ! exists $known{$file} )
{
$known{$file}=$run->{digests}{$file};
}
}
}
}
}

print scalar keys %known, " known covered file(s) found\n";

print "preprocess\n";

my %toadd;

find({ wanted => \&process_file, no_chdir => 1 }, "scripts");

sub process_file
{
if (-f $_)
{
if ( ! exists $known{$_} )
{
$toadd{$_}=Devel::Cover::DB::Structure->digest($_);
}
}
}

print scalar keys %toadd, " uncovered file(s) found and hashed\n";


print "process\n";

if (scalar keys %toadd == 0)
{
print "no files to process\n";
exit;
}

print "run: $runKey\n";

$db->{runs}{$runKey}{"OS"}=$^O;
$db->{runs}{$runKey}{"collected"}=["branch","condition","pod","statement","subroutine","time"];
$db->{runs}{$runKey}{"dir"}=Cwd::abs_path();
$db->{runs}{$runKey}{"vec"}={};
$db->{runs}{$runKey}{"start"}=$timeStart;
$db->{runs}{$runKey}{"run"}=$0;
$_=$^V;
s/v//;
$db->{runs}{$runKey}{"perl"}=$_;

my $s=$db->{structure}=Devel::Cover::DB::Structure->new;

foreach my $file (keys %toadd)
{
$db->{structure}->{f}{$file}{start}{-1}{"__COVER__"}[0]{"branch"}=undef;
$db->{structure}->{f}{$file}{start}{-1}{"__COVER__"}[0]{"condition"}=undef;
$db->{structure}->{f}{$file}{start}{-1}{"__COVER__"}[0]{"pod"}=undef;
$db->{structure}->{f}{$file}{start}{-1}{"__COVER__"}[0]{"subroutine"}=undef;
$db->{structure}->{f}{$file}{start}{-1}{"__COVER__"}[0]{"time"}=undef;
$db->{structure}->{f}{$file}{start}{-1}{"__COVER__"}[0]{"statement"}=0;
$db->{structure}->{f}{$file}{file}=$file;
$db->{structure}->{f}{$file}{digest}=$toadd{$file};
$db->{structure}->{f}{$file}{statement}=[1];
$db->{runs}{$runKey}{"count"}{$file}{'statement'}=[0];
$db->{runs}{$runKey}{"digests"}{$file}=$toadd{$file};
}

$db->{runs}{$runKey}{"finish"}=time;

print "saving\n";

$db->write("$dbpath/runs/$runKey");

--
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- -
- Jason Pyeron PD Inc. http://www.pdinc.us -
- Principal Consultant 10 West 24th Street #100 -
- +1 (443) 269-1555 x333 Baltimore, Maryland 21218 -
- -
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

Tina Müller

unread,
Dec 26, 2016, 7:15:02 AM12/26/16
to Jason Pyeron, per...@perl.org
Hi Jason,

On Sun, 25 Dec 2016, Jason Pyeron wrote:

> Coverage works great as part on continuous integration, until a new file is added and the unit tests are blissfully ignorant of the new file's existence.

Maybe this is not what you're looking for, but it works well
for me loading any module in t/00.load.t:

use Test::More;

# unorthodox but works fine
use Module::Pluggable search_path => ['Module::Namespace'];
my @plugins = main->plugins;
for my $module (@plugins) {
use_ok( $module );
}

done_testing;

This way I never have to touch that test again and still every new module
will show up in coverage.

Using Dist::Zilla, you can also use the Test::Compile plugin.

Of course, this only works for .pm files.

cheers,
tina

Jason Pyeron

unread,
Dec 26, 2016, 9:30:04 AM12/26/16
to per...@perl.org
> -----Original Message-----
> From: Tina Muller
> Sent: Monday, December 26, 2016 07:04
>
> Hi Jason,
>
> On Sun, 25 Dec 2016, Jason Pyeron wrote:
>
> > Coverage works great as part on continuous integration,
> > until a new file is added and the unit tests are blissfully
> > ignorant of the new file's existence.
>
> Maybe this is not what you're looking for, but it works well
> for me loading any module in t/00.load.t:
>
> use Test::More;
>
> # unorthodox but works fine
> use Module::Pluggable search_path => ['Module::Namespace'];
> my @plugins = main->plugins;
> for my $module (@plugins) {
> use_ok( $module );
> }
>
> done_testing;

Cute way to search, thanks.

<snip/>

>
> Of course, this only works for .pm files.

Here in lies the rub, the files (e.g. https://sourceforge.net/p/logwatch/git/ci/master/tree/scripts/) are just plain old perl files.

-Jason

0 new messages