#!./perl
# This is written in a peculiar style, since we're trying to avoid
-# most of the constructs we'll be testing for.
+# most of the constructs we'll be testing for. (This comment is
+# probably obsolete on the avoidance side, though still currrent
+# on the peculiarity side.)
$| = 1;
$core = 1 if $1 eq 'core';
$verbose = 1 if $1 eq 'v';
$torture = 1 if $1 eq 'torture';
- $with_utf= 1 if $1 eq 'utf8';
- $bytecompile = 1 if $1 eq 'bytecompile';
- $compile = 1 if $1 eq 'compile';
+ $with_utf8 = 1 if $1 eq 'utf8';
+ $with_utf16 = 1 if $1 eq 'utf16';
+ $bytecompile = 1 if $1 eq 'bytecompile';
+ $compile = 1 if $1 eq 'compile';
+ $taintwarn = 1 if $1 eq 'taintwarn';
+ $ENV{PERL_CORE_MINITEST} = 1 if $1 eq 'minitest';
if ($1 =~ /^deparse(,.+)?$/) {
$deparse = 1;
$deparse_opts = $1;
my($dir) = @_;
opendir DIR, $dir or die "Trouble opening $dir: $!";
foreach my $f (sort { $a cmp $b } readdir DIR) {
- next if $f eq $curdir or $f eq $updir;
+ next if $f eq $curdir or $f eq $updir or
+ $f =~ /^(?:CVS|RCS|SCCS|\.svn)$/;
my $fullpath = File::Spec->catfile($dir, $f);
return $argstring;
}
+sub _populate_hash {
+ return map {$_, 1} split /\s+/, $_[0];
+}
+
unless (@ARGV) {
foreach my $dir (qw(base comp cmd run io op uni)) {
_find_tests($dir);
}
_find_tests("lib") unless $core;
+ # Config.pm may be broken for make minitest. And this is only a refinement
+ # for skipping tests on non-default builds, so it is allowed to fail.
+ # What we want to to is make a list of extensions which we did not build.
+ my $configsh = File::Spec->catfile($updir, "config.sh");
+ my %skip;
+ if (-f $configsh) {
+ my (%extensions, %known_extensions);
+ open FH, $configsh or die "Can't open $configsh: $!";
+ while (<FH>) {
+ if (/^extensions=['"](.*)['"]$/) {
+ # Deliberate string interpolation to avoid triggering possible
+ # $1 resetting bugs.
+ %extensions = _populate_hash ("$1");
+ }
+ elsif (/^known_extensions=['"](.*)['"]$/) {
+ %known_extensions = _populate_hash ($1);
+ }
+ }
+ if (%extensions) {
+ if (%known_extensions) {
+ foreach (keys %known_extensions) {
+ $skip{$_}++ unless $extensions{$_};
+ }
+ } else {
+ warn "No known_extensions line found in $configsh";
+ }
+ } else {
+ warn "No extensions line found in $configsh";
+ }
+ }
my $mani = File::Spec->catfile($updir, "MANIFEST");
if (open(MANI, $mani)) {
while (<MANI>) { # similar code in t/harness
- if (m!^(ext/\S+/?(?:[^/\s]+\.t|test\.pl)|lib/\S+?(?:\.t|test\.pl))\s!) {
+ if (m!^(ext/(\S+)/+(?:[^/\s]+\.t|test\.pl)|lib/\S+?(?:\.t|test\.pl))\s!) {
$t = $1;
+ $extension = $2;
if (!$core || $t =~ m!^lib/[a-z]!)
{
+ if (defined $extension) {
+ $extension =~ s!/t$!!;
+ # XXX Do I want to warn that I'm skipping these?
+ next if $skip{$extension};
+ }
$path = File::Spec->catfile($updir, $t);
push @ARGV, $path;
$name{$path} = $t;
elsif( $bytecompile ) {
_testprogs('bytecompile', '', @ARGV);
}
+elsif ($with_utf16) {
+ for my $e (0, 1) {
+ for my $b (0, 1) {
+ print STDERR "# ENDIAN $e BOM $b\n";
+ my @UARGV;
+ for my $a (@ARGV) {
+ my $u = $a . "." . ($e ? "l" : "b") . "e" . ($b ? "b" : "");
+ my $f = $e ? "v" : "n";
+ push @UARGV, $u;
+ unlink($u);
+ if (open(A, $a)) {
+ if (open(U, ">$u")) {
+ print U pack("$f", 0xFEFF) if $b;
+ while (<A>) {
+ print U pack("$f*", unpack("C*", $_));
+ }
+ close(A);
+ }
+ close(B);
+ }
+ }
+ _testprogs('perl', '', @UARGV);
+ unlink(@UARGV);
+ }
+ }
+}
else {
_testprogs('compile', '', @ARGV) if -e "../testcompile";
_testprogs('perl', '', @ARGV);
# + 3 : we want three dots between the test name and the "ok"
$dotdotdot = $maxlen + 3 ;
my $valgrind = 0;
+ my $valgrind_log = 'current.valgrind';
while ($test = shift @tests) {
if ( $infinite{$test} && $type eq 'compile' ) {
open(SCRIPT,"<$test") or die "Can't run $test.\n";
$_ = <SCRIPT>;
close(SCRIPT) unless ($type eq 'deparse');
+ if ($with_utf16) {
+ $_ =~ tr/\0//d;
+ }
if (/#!.*\bperl.*\s-\w*([tT])/) {
$switch = qq{"-$1"};
}
else {
- $switch = '';
+ if ($taintwarn) {
+ # not all tests are expected to pass with this option
+ $switch = '"-t"';
+ }
+ else {
+ $switch = '';
+ }
}
my $test_executable; # for 'compile' tests
close(SCRIPT);
}
- my $utf = $with_utf ? '-I../lib -Mutf8' : '';
+ my $utf8 = $with_utf8 ? '-I../lib -Mutf8' : '';
my $testswitch = '-I. -MTestInit'; # -T will strict . from @INC
if ($type eq 'deparse') {
my $deparse =
or print "can't deparse '$deparse': $!.\n";
}
elsif ($type eq 'bytecompile') {
- my $perl = $ENV{PERL} || './perl';
- my $redir = ($^O eq 'VMS' ? '2>&1' : '');
- my $bswitch = "-MO=Bytecode,-H,-TI,-s`pwd`/$test,";
+ my ($pwd, $null);
+ if( $^O eq 'MSWin32') {
+ $pwd = `cd`;
+ $null = 'nul';
+ } else {
+ $pwd = `pwd`;
+ $null = '/dev/null';
+ }
+ chomp $pwd;
+ my $perl = $ENV{PERL} || "$pwd/perl";
+ my $bswitch = "-MO=Bytecode,-H,-TI,-s$pwd/$test,";
$bswitch .= "-TF$test.plc,"
if $test =~ m(chdir|pod/|CGI/t/carp|lib/DB);
$bswitch .= "-k,"
if $test =~ m(op/getpid);
my $bytecompile =
"$perl $testswitch $switch -I../lib $bswitch".
- "-o$test.plc $test 2>/dev/null &&".
- "$perl $testswitch $switch -I../lib $utf $test.plc $redir|";
+ "-o$test.plc $test 2>$null &&".
+ "$perl $testswitch $switch -I../lib $utf8 $test.plc |";
open(RESULTS,$bytecompile)
or print "can't byte-compile '$bytecompile': $!.\n";
}
elsif ($type eq 'perl') {
my $perl = $ENV{PERL} || './perl';
- my $redir = ($^O eq 'VMS' || $ENV{PERL_VALGRIND} ? '2>&1' : '');
+ my $redir = $^O eq 'VMS' ? '2>&1' : '';
if ($ENV{PERL_VALGRIND}) {
$perl = "valgrind --suppressions=perl.supp --leak-check=yes "
. "--leak-resolution=high --show-reachable=yes "
- . "--num-callers=50 $perl";
+ . "--num-callers=50 --logfile-fd=3 $perl";
+ $redir = "3>$valgrind_log";
}
- my $run = "$perl" . _quote_args("$testswitch $switch $utf") . " $test $redir|";
+ my $run = "$perl" . _quote_args("$testswitch $switch $utf8") . " $test $redir|";
open(RESULTS,$run) or print "can't run '$run': $!.\n";
}
else {
my $pl2c = "$testswitch -I../lib ../utils/perlcc --testsuite " .
# -O9 for good measure, -fcog is broken ATM
"$switch -Wb=-O9,-fno-cog -L .. " .
- "-I \".. ../lib/CORE\" $args $utf $test -o ";
+ "-I \".. ../lib/CORE\" $args $utf8 $test -o ";
if( $^O eq 'MSWin32' ) {
$test_executable = "$test.exe";
$next = 0;
my $seen_leader = 0;
my $seen_ok = 0;
- my @valgrind;
while (<RESULTS>) {
next if /^\s*$/; # skip blank lines
if ($verbose) {
print $_;
}
- if ($ENV{PERL_VALGRIND} && /^==\d+== /) {
- push @valgrind, $_;
- next;
- }
unless (/^\#/) {
if (/^1\.\.([0-9]+)( todo ([\d ]+))?/) {
$max = $1;
$seen_ok = 1;
if ($2 == $next) {
my($not, $num, $extra) = ($1, $2, $3);
- my($istodo) = $extra =~ /^\s*#\s*TODO/ if $extra;
+ my($istodo) = $extra =~ /#\s*TODO/ if $extra;
$istodo = 1 if $todo{$num};
if( $not && !$istodo ) {
}
close RESULTS;
if ($ENV{PERL_VALGRIND}) {
+ my @valgrind;
+ if (-e $valgrind_log) {
+ if (open(V, $valgrind_log)) {
+ @valgrind = <V>;
+ close V;
+ } else {
+ warn "$0: Failed to open '$valgrind_log': $!\n";
+ }
+ }
if (@valgrind) {
my $leaks = 0;
my $errors = 0;
}
}
if ($errors or $leaks) {
- if (open(V, ">$test.valgrind")) {
- for (@valgrind) {
- print V $_;
- }
- close V;
+ if (rename $valgrind_log, "$test.valgrind") {
$valgrind++;
} else {
warn "$0: Failed to create '$test.valgrind': $!\n";
} else {
warn "No valgrind output?\n";
}
+ if (-e $valgrind_log) {
+ unlink $valgrind_log
+ or warn "$0: Failed to unlink '$valgrind_log': $!\n";
+ }
}
if ($type eq 'deparse') {
unlink "./$test.dp";
}
else {
$next += 1;
- print "${te}FAILED at test $next\n";
+ if ($next > $max) {
+ print "${te}FAILED at test $next\tpossibly due to extra output\n";
+ }
+ else {
+ print "${te}FAILED at test $next\n";
+ }
$bad = $bad + 1;
$_ = $test;
if (/^base/) {