use strict;
my $testname = shift || die;
my $errfile = shift || "$testname.expected-stderr";
my @input;
my @original_input;
while (my $line = <>) {
chomp $line;
push @input, $line;
push @original_input, $line;
}
my $xit = 0;
my $bad = "";
$bad |= filter_valgrind() if ($ENV{VALGRIND});
$bad = filter_expected() if ($bad eq "" && -e $errfile);
$bad = filter_bad() if ($bad eq "");
$bad = "(output not 'OK: $testname')" if ($bad eq "" && (scalar(@input) != 1 || $input[0] !~ /^OK: $testname/));
if ($bad ne "") {
my $red = "\e[41;37m";
my $def = "\e[0m";
$xit = 1;
print "${red}BAD: /// test '$testname' \\\\\\$def\n";
for my $line (@original_input) {
print "$red $def$line\n";
}
print "${red}BAD: \\\\\\ test '$testname' ///$def\n";
print "${red}FAIL: ## $testname: $bad$def\n";
} else {
print "PASS: $testname\n";
}
exit $xit;
sub filter_expected
{
my $bad = "";
open(my $checkfile, $errfile)
|| die "can't find $errfile\n";
my $check = join('', <$checkfile>);
close($checkfile);
my $input = join("\n", @input) . "\n";
if ($input !~ /^$check$/s) {
$bad = "(didn't match $errfile)";
@input = "BAD: $testname";
} else {
@input = "OK: $testname"; }
return $bad;
}
sub filter_bad
{
my $bad = "";
my @new_input;
for my $line (@input) {
chomp $line;
if ($line =~ /^BAD: (.*)/) {
$bad = "(failed)";
} else {
push @new_input, $line;
}
}
@input = @new_input;
return $bad;
}
sub filter_valgrind
{
my $errors = 0;
my $leaks = 0;
my @new_input;
for my $line (@input) {
if ($line =~ /^Approx: do_origins_Dirty\([RW]\): missed \d bytes$/) {
next;
}
if ($line !~ /^^\.*==\d+==/) {
push @new_input, $line;
next;
}
my ($errcount) = ($line =~ /==\d+== ERROR SUMMARY: (\d+) errors/);
if (defined $errcount && $errcount > 0) {
$errors = 1;
}
(my $leakcount) = ($line =~ /==\d+==\s+(?:definitely|possibly) lost:\s+([0-9,]+)/);
if (defined $leakcount && $leakcount > 0) {
$leaks = 1;
}
}
@input = @new_input;
my $bad = "";
$bad .= "(valgrind errors)" if ($errors);
$bad .= "(valgrind leaks)" if ($leaks);
return $bad;
}