]> git.vpit.fr Git - perl/modules/Test-Valgrind.git/blobdiff - lib/Test/Valgrind.pm
This is 0.06
[perl/modules/Test-Valgrind.git] / lib / Test / Valgrind.pm
index 29e88580d63def80614a37f1a01c4b5f612ff21d..34ff5d903cc5c75ee06c7b2152870749ec789047 100644 (file)
@@ -17,11 +17,11 @@ Test::Valgrind - Test Perl code through valgrind.
 
 =head1 VERSION
 
-Version 0.04
+Version 0.06
 
 =cut
 
-our $VERSION = '0.04';
+our $VERSION = '0.06';
 
 =head1 SYNOPSIS
 
@@ -39,55 +39,98 @@ You can also use it from the command-line to test a given script :
 
     perl -MTest::Valgrind leaky.pl
 
+Due to the nature of perl's memory allocator, this module can't track leaks of Perl objects. This includes non-mortalized scalars and memory cycles. However, it can track leaks of chunks of memory allocated in XS extensions with C<Newx> and friends or C<malloc>. As such, it's complementary to the other very good leak detectors listed in the L</SEE ALSO> section.
+
 =head1 CONFIGURATION
 
 You can pass parameters to C<import> as a list of key / value pairs, where valid keys are :
 
 =over 4
 
-=item C<< supp => $file >>
+=item *
+
+C<< supp => $file >>
 
 Also use suppressions from C<$file> besides perl's.
 
-=item C<< no_supp => $bool >>
+=item *
+
+C<< no_supp => $bool >>
 
 If true, do not use any suppressions.
 
-=item C<< callers => $number >>
+=item *
+
+C<< callers => $number >>
 
 Specify the maximum stack depth studied when valgrind encounters an error. Raising this number improves granularity. Default is 12.
 
-=item C<< extra => [ @args ] >>
+=item *
+
+C<< extra => [ @args ] >>
 
 Add C<@args> to valgrind parameters.
 
-=item C<< diag => $bool >>
+=item *
+
+C<< diag => $bool >>
 
 If true, print the raw output of valgrind as diagnostics (may be quite verbose).
 
-=item C<< no_test => $bool >>
+=item *
+
+C<< no_test => $bool >>
 
 If true, do not actually output the plan and the tests results.
 
+=item *
+
+C<< cb => sub { my ($val, $name) = @_; ...; return $passed } >>
+
+Specifies a subroutine to execute for each test instead of C<Test::More::is>. It receives the number of bytes leaked in C<$_[0]> and the test name in C<$_[1]>, and is expected to return true if the test passed and false otherwise. Defaults to
+
+    sub {
+     is($_[0], 0, $_[1]);
+     (defined $_[0] and $_[0] == 0) : 1 : 0
+    }
+
 =back
 
 =cut
 
 my $run;
 
+sub _counter {
+ (defined $_[0] and $_[0] == 0) ? 1 : 0;
+}
+
+sub _tester {
+ is($_[0], 0, $_[1]);
+ _counter(@_);
+}
+
 sub import {
  shift;
  croak 'Optional arguments must be passed as key => value pairs' if @_ % 2;
  my %args = @_;
  if (!defined $args{run} && !$run) {
-  my ($file, $next);
+  my ($file, $pm, $next);
   my $l = 0;
   while ($l < 1000) {
    $next = (caller $l++)[1];
    last unless defined $next;
-   $file = $next;
+   next unless $next ne '-e' and $next !~ /^\s*\(\s*eval\s*\d*\s*\)\s*$/
+                             and -f $next;
+   if ($next =~ /\.pm$/) {
+    $pm = $next;
+   } else {
+    $file = $next;
+   }
+  }
+  unless (defined $file) {
+   $file = $pm;
+   return unless defined $pm;
   }
-  return if not $file or $file eq '-e';
   my $callers = $args{callers};
   $callers = 12 unless defined $callers;
   $callers = int $callers;
@@ -134,7 +177,7 @@ sub import {
    print STDERR "valgrind @args\n" if $args{diag};
    local $ENV{PERL_DESTRUCT_LEVEL} = 3;
    local $ENV{PERL_DL_NONLAZY} = 1;
-   exec $vg, @args if $vg and -x $vg;
+   exec $vg, @args;
   }
   close $wtr or croak "close(\$wtr): $!";
   local $SIG{INT} = sub { kill -(SIGTERM) => $pid };
@@ -163,10 +206,11 @@ sub import {
    }
   }
   waitpid $pid, 0;
-  my $failed = 0;
+  my $failed = 5;
+  my $cb = ($args{no_test} ? \&_counter
+                           : ($args{cb} ? $args{cb} : \&_tester));
   for (@tests) {
-   is($res{$_}, 0, 'valgrind ' . $_) unless $args{no_test};
-   ++$failed if defined $res{$_} and $res{$_} != 0;
+   $failed -= $cb->($res{$_}, 'valgrind ' . $_) ? 1 : 0;
   }
   exit $failed;
  } else {
@@ -192,6 +236,10 @@ L<Carp>, L<POSIX> (core modules since perl 5) and L<Test::More> (since 5.6.2).
 
 L<Perl::Destruct::Level>.
 
+=head1 SEE ALSO
+
+L<Devel::Leak>, L<Devel::LeakTrace>, L<Devel::LeakTrace::Fast>.
+
 =head1 AUTHOR
 
 Vincent Pit, C<< <perl at profvince.com> >>, L<http://www.profvince.com>.