X-Git-Url: http://git.vpit.fr/?a=blobdiff_plain;f=t%2Flib%2FTest%2FValgrind%2FTest%2FAction.pm;h=3f9c0c7bea7632e3ae3cd07d01eb7c7fc7e2bd14;hb=764e57fa66b8998b44e9c8e369df99399e030896;hp=8b41a68d6239bff23f9c0b5dc196a8312fcd3c25;hpb=44f0639e6ac34bdc0be52d47fe2c2df43ab1ca94;p=perl%2Fmodules%2FTest-Valgrind.git diff --git a/t/lib/Test/Valgrind/Test/Action.pm b/t/lib/Test/Valgrind/Test/Action.pm index 8b41a68..3f9c0c7 100644 --- a/t/lib/Test/Valgrind/Test/Action.pm +++ b/t/lib/Test/Valgrind/Test/Action.pm @@ -16,26 +16,44 @@ BEGIN { if ($@) { $extra_tests = 0; } else { - $extra_tests = 2; + $extra_tests = 3; *report = *report_smart; + *abort = *abort_smart; } } use Test::Builder; -sub new { shift->SUPER::new(extra_tests => $extra_tests) } +sub new { + my $class = shift; + + $class->SUPER::new( + diag => 1, + extra_tests => $extra_tests, + ); +} + +my @filtered_reports; sub report_smart { my ($self, $sess, $report) = @_; if ($report->can('is_leak') and $report->is_leak) { my $data = $report->data; - my $trace = join ' ', map { $_->[2] } @{$data->{stack} || []}[0 .. 2]; - if ($trace eq 'malloc XS_Test__Valgrind_leak Perl_pp_entersub') { - my $tb = Test::Builder->new; - $tb->diag("The subsequent report was correctly caught:\n" . $report->dump); - $tb->is_eq($data->{leakedbytes}, 10_000, '10_000 bytes leaked'); - $tb->is_eq($data->{leakedblocks}, 1, ' in one block'); + my @trace = map $_->[2] || '?', + @{$data->{stack} || []}[0 .. 3]; + my $valid_trace = ( + $trace[0] eq 'malloc' + and $trace[1] eq 'tv_leak' + and ($trace[2] eq 'Perl_pp_entersub' or $trace[3] eq 'Perl_pp_entersub') + ); + + if ($valid_trace) { + push @filtered_reports, [ + $report->dump, + $data->{leakedbytes}, + $data->{leakedblocks}, + ]; return; } } @@ -43,4 +61,36 @@ sub report_smart { $self->SUPER::report($sess, $report); } +sub abort_smart { + my $self = shift; + + $extra_tests = 0; + + $self->SUPER::abort(@_); +} + +sub DESTROY { + return unless $extra_tests; + + my $tb = Test::Builder->new; + + $tb->is_eq(scalar(@filtered_reports), 1, 'caught one extra leak'); + + if (@filtered_reports) { + my $first = shift @filtered_reports; + $tb->diag("The subsequent report was correctly caught:\n" . $first->[0]); + $tb->is_eq($first->[1], 10_000, '10_000 bytes leaked'); + $tb->is_eq($first->[2], 1, ' in one block'); + + for my $extra_report (@filtered_reports) { + $tb->diag( + "The subsequent report should NOT have been caught:\n" . $extra_report->[0] + ); + } + } else { + $tb->ok(0, 'no extra leak caught, hence no bytes leaked'); + $tb->ok(0, 'no extra leak caught, hence no block leaked'); + } +} + 1;