Devel-NYTProf
view release on metacpan or search on metacpan
t/lib/NYTProfTest.pm view on Meta::CPAN
sub _quote_join {
join ' ', map qq{"$_"}, @_;
}
# some tests use profile_this() in Devel::NYTProf::Run
sub run_perl_command {
my ($cmd, $show_stdout) = @_;
local $ENV{PERL5LIB} = $perl5lib;
my @perl = perl_command_words(skip_sitecustomize => 1);
run_command(_quote_join(@perl) . " $cmd", $show_stdout);
}
sub profile { # TODO refactor to use run_perl_command()?
my ($test, $profile_datafile) = @_;
my @perl = perl_command_words(skip_sitecustomize => 1);
my $cmd = _quote_join(@perl) . " $opts{profperlopts} $test";
return ok run_command($cmd), "$test runs ok under the profiler";
}
sub verify_data {
my ($test, $tag, $profile_datafile) = @_;
my $profile = eval { Devel::NYTProf::Data->new({filename => $profile_datafile}) };
if ($@) {
diag($@);
fail($test);
return;
}
SKIP: {
skip 'Expected profile data does not have VMS paths', 1
if $^O eq 'VMS' and $test =~ m/test60|test14/i;
$profile->normalize_variables(1); # and options
dump_profile_to_file($profile, $test.'_new', $test.'_newp');
is_file_content_same($test.'_new', $test, "$test match generated profile data for $tag");
}
}
sub is_file_content_same {
my ($got_file, $exp_file, $testname) = @_;
my @got = slurp_file($got_file); chomp @got;
my @exp = slurp_file($exp_file); chomp @exp;
my $updated = update_file_content_array (\@got);
# Sort the got and exp data if we updated.
# This avoids mismatches due to file sort orders.
if ($updated) {
@got = sort @got;
@exp = sort @exp;
}
is_deeply(\@got, \@exp, $testname)
? unlink($got_file)
: diff_files($exp_file, $got_file, $got_file."_patch");
}
sub update_file_content_array {
my $lines = shift;
my $file_info_start;
foreach my $i (0 .. $#$lines) {
next if not $lines->[$i] =~ /^fid_fileinfo/;
# Remove path info that creeps in when run under prove
# Should perhaps use Regexp::Common, or borrow from it.
$lines->[$i] =~ s|(\d\t\[ )(\w:/)?([\-\w\s]+/)+|$1|;
$file_info_start ||= $i;
last if $i > $file_info_start + 4;
}
return if !$file_info_start;
my $re_eval_id = qr /\(eval ([0-9]+)\)/;
my $start_eval_id = 1;
# find the first fid_fileinfo line with an eval in it
for my $i ($file_info_start .. 10+$file_info_start) {
if ($lines->[$i] =~ $re_eval_id) {
$start_eval_id = $1;
last;
};
}
return if $start_eval_id <= 1;
my $eval_id_offset = $start_eval_id - 1;
# now update the eval IDs for the offset
foreach my $i ($file_info_start .. $#$lines) {
if (my @matches = ($lines->[$i] =~ m/$re_eval_id/g)) {
foreach my $got (@matches) {
my $replace = $got - $eval_id_offset;
if ($lines->[$i] =~ /test22-strevala.p/) {
# Correct for the alphabetical ordering
# as otherwise the 10 is listed before the 9
# and the line does not match exactly.
# Clunky, but works for now.
if ($got == 10) {
$replace -= 1;
}
elsif (@matches > 2 && $got == 9) {
$replace += 1;
}
}
$lines->[$i] =~ s/\(eval $got\)/\(eval $replace\)/;
}
}
}
# indicate changes
return 1;
}
sub dump_data_to_file {
my ($profile, $file) = @_;
open my $fh, ">", $file or croak "Can't open $file: $!";
local $Data::Dumper::Indent = 1;
local $Data::Dumper::Sortkeys = 1;
print $fh Data::Dumper->Dump([$profile], ['expected']);
( run in 1.358 second using v1.01-cache-2.11-cpan-5b529ec07f3 )