This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Fix new B::Concise test output
[perl5.git] / t / TEST
1 #!./perl
2
3 # This is written in a peculiar style, since we're trying to avoid
4 # most of the constructs we'll be testing for.
5
6 $| = 1;
7
8 # Let tests know they're running in the perl core.  Useful for modules
9 # which live dual lives on CPAN.
10 $ENV{PERL_CORE} = 1;
11
12 # remove empty elements due to insertion of empty symbols via "''p1'" syntax
13 @ARGV = grep($_,@ARGV) if $^O eq 'VMS';
14
15 # Cheesy version of Getopt::Std.  Maybe we should replace it with that.
16 @argv = ();
17 if ($#ARGV >= 0) {
18     foreach my $idx (0..$#ARGV) {
19         push( @argv, $ARGV[$idx] ), next unless $ARGV[$idx] =~ /^-(\S+)$/;
20         $core    = 1 if $1 eq 'core';
21         $verbose = 1 if $1 eq 'v';
22         $torture = 1 if $1 eq 'torture';
23         $with_utf= 1 if $1 eq 'utf8';
24         $bytecompile = 1 if $1 eq 'bytecompile';
25         $compile = 1 if $1 eq 'compile';
26         $taintwarn = 1 if $1 eq 'taintwarn';
27         $ENV{PERL_CORE_MINITEST} = 1 if $1 eq 'minitest';
28         if ($1 =~ /^deparse(,.+)?$/) {
29             $deparse = 1;
30             $deparse_opts = $1;
31         }
32     }
33 }
34 @ARGV = @argv;
35
36 chdir 't' if -f 't/TEST';
37
38 die "You need to run \"make test\" first to set things up.\n"
39   unless -e 'perl' or -e 'perl.exe' or -e 'perl.pm';
40
41 if ($ENV{PERL_3LOG}) { # Tru64 third(1) tool, see perlhack
42     unless (-x 'perl.third') {
43         unless (-x '../perl.third') {
44             die "You need to run \"make perl.third first.\n";
45         }
46         else {
47             print "Symlinking ../perl.third as perl.third...\n";
48             die "Failed to symlink: $!\n"
49                 unless symlink("../perl.third", "perl.third");
50             die "Symlinked but no executable perl.third: $!\n"
51                 unless -x 'perl.third';
52         }
53     }
54 }
55
56 # check leakage for embedders
57 $ENV{PERL_DESTRUCT_LEVEL} = 2 unless exists $ENV{PERL_DESTRUCT_LEVEL};
58
59 $ENV{EMXSHELL} = 'sh';        # For OS/2
60
61 # Roll your own File::Find!
62 use TestInit;
63 use File::Spec;
64 my $curdir = File::Spec->curdir;
65 my $updir  = File::Spec->updir;
66
67 sub _find_tests {
68     my($dir) = @_;
69     opendir DIR, $dir or die "Trouble opening $dir: $!";
70     foreach my $f (sort { $a cmp $b } readdir DIR) {
71         next if $f eq $curdir or $f eq $updir;
72
73         my $fullpath = File::Spec->catfile($dir, $f);
74
75         _find_tests($fullpath) if -d $fullpath;
76         $fullpath = VMS::Filespec::unixify($fullpath) if $^O eq 'VMS';
77         push @ARGV, $fullpath if $f =~ /\.t$/;
78     }
79 }
80
81 sub _quote_args {
82     my ($args) = @_;
83     my $argstring = '';
84
85     foreach (split(/\s+/,$args)) {
86        # In VMS protect with doublequotes because otherwise
87        # DCL will lowercase -- unless already doublequoted.
88        $_ = q(").$_.q(") if ($^O eq 'VMS') && !/^\"/ && length($_) > 0;
89        $argstring .= ' ' . $_;
90     }
91     return $argstring;
92 }
93
94 unless (@ARGV) {
95     foreach my $dir (qw(base comp cmd run io op uni)) {
96         _find_tests($dir);
97     }
98     _find_tests("lib") unless $core;
99     my $mani = File::Spec->catfile($updir, "MANIFEST");
100     if (open(MANI, $mani)) {
101         while (<MANI>) { # similar code in t/harness
102             if (m!^(ext/\S+/?(?:[^/\s]+\.t|test\.pl)|lib/\S+?(?:\.t|test\.pl))\s!) {
103                 $t = $1;
104                 if (!$core || $t =~ m!^lib/[a-z]!)
105                 {
106                     $path = File::Spec->catfile($updir, $t);
107                     push @ARGV, $path;
108                     $name{$path} = $t;
109                 }
110             }
111         }
112         close MANI;
113     } else {
114         warn "$0: cannot open $mani: $!\n";
115     }
116     unless ($core) {
117         _find_tests('pod');
118         _find_tests('x2p');
119         _find_tests('japh') if $torture;
120     }
121 }
122
123 # Tests known to cause infinite loops for the perlcc tests.
124 # %infinite = ( 'comp/require.t', 1, 'op/bop.t', 1, 'lib/hostname.t', 1 );
125 %infinite = ();
126
127 if ($deparse) {
128     _testprogs('deparse', '',   @ARGV);
129 }
130 elsif( $compile ) { 
131     _testprogs('compile', '',   @ARGV);
132 }
133 elsif( $bytecompile ) {
134     _testprogs('bytecompile', '', @ARGV);
135 }
136 else {
137     _testprogs('compile', '',   @ARGV) if -e "../testcompile";
138     _testprogs('perl',    '',   @ARGV);
139 }
140
141 sub _testprogs {
142     $type = shift @_;
143     $args = shift;
144     @tests = @_;
145
146     print <<'EOT' if ($type eq 'compile');
147 ------------------------------------------------------------------------------
148 TESTING COMPILER
149 ------------------------------------------------------------------------------
150 EOT
151
152     print <<'EOT' if ($type eq 'deparse');
153 ------------------------------------------------------------------------------
154 TESTING DEPARSER
155 ------------------------------------------------------------------------------
156 EOT
157
158     print <<EOT if ($type eq 'bytecompile');
159 ------------------------------------------------------------------------------
160 TESTING BYTECODE COMPILER
161 ------------------------------------------------------------------------------
162 EOT
163
164     $ENV{PERLCC_TIMEOUT} = 120
165           if ($type eq 'compile' && !$ENV{PERLCC_TIMEOUT});
166
167     $bad = 0;
168     $good = 0;
169     $total = @tests;
170     $files  = 0;
171     $totmax = 0;
172
173     foreach my $t (@tests) {
174       unless (exists $name{$t}) {
175         my $tname = File::Spec->catfile('t',$t);
176         $tname = VMS::Filespec::unixify($tname) if $^O eq 'VMS';
177         $name{$t} = $tname;
178       }
179     }
180     my $maxlen = 0;
181     foreach (@name{@tests}) {
182         s/\.\w+\z/./;
183         my $len = length ;
184         $maxlen = $len if $len > $maxlen;
185     }
186     # + 3 : we want three dots between the test name and the "ok"
187     $dotdotdot = $maxlen + 3 ;
188     my $valgrind = 0;
189     my $valgrind_log = 'current.valgrind';
190     while ($test = shift @tests) {
191
192         if ( $infinite{$test} && $type eq 'compile' ) {
193             print STDERR "$test creates infinite loop! Skipping.\n";
194             next;
195         }
196         if ($test =~ /^$/) {
197             next;
198         }
199         if ($type eq 'deparse') {
200             if ($test eq "comp/redef.t") {
201                 # Redefinition happens at compile time
202                 next;
203             }
204             elsif ($test =~ m{lib/Switch/t/}) {
205                 # B::Deparse doesn't support source filtering
206                 next;
207             }
208         }
209         $te = $name{$test} . '.' x ($dotdotdot - length($name{$test}));
210
211         if ($^O ne 'VMS') {  # defer printing on VMS due to piping bug
212             print $te;
213             $te = '';
214         }
215
216         $test = $OVER{$test} if exists $OVER{$test};
217
218         open(SCRIPT,"<$test") or die "Can't run $test.\n";
219         $_ = <SCRIPT>;
220         close(SCRIPT) unless ($type eq 'deparse');
221         if (/#!.*\bperl.*\s-\w*([tT])/) {
222             $switch = qq{"-$1"};
223         }
224         else {
225             if ($taintwarn) {
226                 # not all tests are expected to pass with this option
227                 $switch = '"-t"';
228             }
229             else {
230                 $switch = '';
231             }
232         }
233
234         my $test_executable; # for 'compile' tests
235         my $file_opts = "";
236         if ($type eq 'deparse') {
237             # Look for #line directives which change the filename
238             while (<SCRIPT>) {
239                 $file_opts .= ",-f$3$4"
240                         if /^#\s*line\s+(\d+)\s+((\w+)|"([^"]+)")/;
241             }
242             close(SCRIPT);
243         }
244
245         my $utf = $with_utf ? '-I../lib -Mutf8' : '';
246         my $testswitch = '-I. -MTestInit'; # -T will strict . from @INC
247         if ($type eq 'deparse') {
248             my $deparse =
249                 "./perl $testswitch $switch -I../lib -MO=-qq,Deparse,-sv1.,".
250                 "-l$deparse_opts$file_opts ".
251                 "$test > $test.dp ".
252                 "&& ./perl $testswitch $switch -I../lib $test.dp |";
253             open(RESULTS, $deparse)
254                 or print "can't deparse '$deparse': $!.\n";
255         }
256         elsif ($type eq 'bytecompile') {
257             my ($pwd, $null);
258             if( $^O eq 'MSWin32') {
259                 $pwd = `cd`;
260                 $null = 'nul';
261             } else {
262                 $pwd = `pwd`;
263                 $null = '/dev/null';
264             }
265             chomp $pwd;
266             my $perl = $ENV{PERL} || "$pwd/perl";
267             my $bswitch = "-MO=Bytecode,-H,-TI,-s$pwd/$test,";
268             $bswitch .= "-TF$test.plc,"
269                 if $test =~ m(chdir|pod/|CGI/t/carp|lib/DB);
270             $bswitch .= "-k,"
271                 if $test =~ m(deparse|terse|ext/Storable/t/code);
272             $bswitch .= "-b,"
273                 if $test =~ m(op/getpid);
274             my $bytecompile =
275                 "$perl $testswitch $switch -I../lib $bswitch". 
276                 "-o$test.plc $test 2>$null &&".
277                 "$perl $testswitch $switch -I../lib $utf $test.plc |";
278             open(RESULTS,$bytecompile)
279                 or print "can't byte-compile '$bytecompile': $!.\n";
280         }
281         elsif ($type eq 'perl') {
282             my $perl = $ENV{PERL} || './perl';
283             my $redir = $^O eq 'VMS' ? '2>&1' : '';
284             if ($ENV{PERL_VALGRIND}) {
285                 $perl = "valgrind --suppressions=perl.supp --leak-check=yes "
286                                . "--leak-resolution=high --show-reachable=yes "
287                                . "--num-callers=50 --logfile-fd=3 $perl";
288                 $redir = "3>$valgrind_log";
289             }
290             my $run = "$perl" . _quote_args("$testswitch $switch $utf") . " $test $redir|";
291             open(RESULTS,$run) or print "can't run '$run': $!.\n";
292         }
293         else {
294             my $compile;
295             my $pl2c = "$testswitch -I../lib ../utils/perlcc --testsuite " .
296               # -O9 for good measure, -fcog is broken ATM
297                        "$switch -Wb=-O9,-fno-cog -L .. " .
298                        "-I \".. ../lib/CORE\" $args $utf $test -o ";
299
300             if( $^O eq 'MSWin32' ) {
301                 $test_executable = "$test.exe";
302                 # hopefully unused name...
303                 open HACK, "> xweghyz.pl";
304                 print HACK <<EOT;
305 #!./perl
306
307 open HACK, '.\\perl $pl2c $test_executable |';
308 # cl.exe prints the name of the .c file on stdout (\%^\$^#)
309 while(<HACK>) {m/^\\w+\\.[cC]\$/ && next;print}
310 open HACK, '$test_executable |';
311 while(<HACK>) {print}
312 EOT
313                 close HACK;
314                 $compile = 'xweghyz.pl |';
315             }
316             else {
317                 $test_executable = "$test.plc";
318                 $compile = "./perl $pl2c $test_executable && $test_executable |";
319             }
320             unlink $test_executable if -f $test_executable;
321             open(RESULTS, $compile)
322                 or print "can't compile '$compile': $!.\n";
323         }
324
325         $ok = 0;
326         $next = 0;
327         my $seen_leader = 0;
328         my $seen_ok = 0;
329         while (<RESULTS>) {
330             next if /^\s*$/; # skip blank lines
331             if ($verbose) {
332                 print $_;
333             }
334             unless (/^\#/) {
335                 if (/^1\.\.([0-9]+)( todo ([\d ]+))?/) {
336                     $max = $1;
337                     %todo = map { $_ => 1 } split / /, $3 if $3;
338                     $totmax += $max;
339                     $files += 1;
340                     unless ($seen_ok) {
341                       $next = 1;
342                       $ok = 1;
343                     }
344                     $seen_leader = 1;
345                 }
346                 else {
347                     if (/^(not )?ok (\d+)[^\#]*(\s*\#.*)?/) {
348                         unless ($seen_leader) {
349                             unless ($seen_ok) {
350                                 $next = 1;
351                                 $ok = 1;
352                             }
353                         }
354                         $seen_ok = 1;
355                         if ($2 == $next) {
356                             my($not, $num, $extra) = ($1, $2, $3);
357                             my($istodo) = $extra =~ /#\s*TODO/ if $extra;
358                             $istodo = 1 if $todo{$num};
359
360                             if( $not && !$istodo ) {
361                                 $ok = 0;
362                                 $next = $num;
363                                 last;
364                             }
365                             else {
366                                 $next = $next + 1;
367                             }
368                         }
369                     }
370                     elsif (/^Bail out!\s*(.*)/i) { # magic words
371                         die "FAILED--Further testing stopped" . ($1 ? ": $1\n" : ".\n");
372                     }
373                     else {
374                         $ok = 0;
375                     }
376                 }
377             }
378         }
379         close RESULTS;
380         if ($ENV{PERL_VALGRIND}) {
381             my @valgrind;
382             if (-e $valgrind_log) {
383                 if (open(V, $valgrind_log)) {
384                     @valgrind = <V>;
385                     close V;
386                 } else {
387                     warn "$0: Failed to open '$valgrind_log': $!\n";
388                 }
389             }
390             if (@valgrind) {
391                 my $leaks = 0;
392                 my $errors = 0;
393                 for my $i (0..$#valgrind) {
394                     local $_ = $valgrind[$i];
395                     if (/^==\d+== ERROR SUMMARY: (\d+) errors? /) {
396                         $errors += $1;   # there may be multiple error summaries
397                     } elsif (/^==\d+== LEAK SUMMARY:/) {
398                         for my $off (1 .. 4) {
399                             if ($valgrind[$i+$off] =~
400                                 /(?:lost|reachable):\s+\d+ bytes in (\d+) blocks/) {
401                                 $leaks += $1;
402                             }
403                         }
404                     }
405                 }
406                 if ($errors or $leaks) {
407                     if (rename $valgrind_log, "$test.valgrind") {
408                         $valgrind++;
409                     } else {
410                         warn "$0: Failed to create '$test.valgrind': $!\n";
411                     }
412                 }
413             } else {
414                 warn "No valgrind output?\n";
415             }
416             if (-e $valgrind_log) {
417                 unlink $valgrind_log
418                     or warn "$0: Failed to unlink '$valgrind_log': $!\n";
419             }
420         }
421         if ($type eq 'deparse') {
422             unlink "./$test.dp";
423         }
424         if ($ENV{PERL_3LOG}) {
425             my $tpp = $test;
426             $tpp =~ s:^\.\./::;
427             $tpp =~ s:/:_:g;
428             $tpp =~ s:\.t$:.3log:;
429             rename("perl.3log", $tpp) ||
430                 die "rename: perl3.log to $tpp: $!\n";
431         }
432         $next = $next - 1;
433         # test if the compiler compiled something
434         if( $type eq 'compile' && !-e "$test_executable" ) {
435             $ok = 0;
436             print "Test did not compile\n";
437         }
438         if ($ok && $next == $max ) {
439             if ($max) {
440                 print "${te}ok\n";
441                 $good = $good + 1;
442             }
443             else {
444                 print "${te}skipping test on this platform\n";
445                 $files -= 1;
446             }
447         }
448         else {
449             $next += 1;
450             print "${te}FAILED at test $next";
451             print ($next > $max) ? "\tpossibly due to extra output\n" : "\n";
452             $bad = $bad + 1;
453             $_ = $test;
454             if (/^base/) {
455                 die "Failed a basic test--cannot continue.\n";
456             }
457         }
458     }
459
460     if ($bad == 0) {
461         if ($ok) {
462             print "All tests successful.\n";
463             # XXX add mention of 'perlbug -ok' ?
464         }
465         else {
466             die "FAILED--no tests were run for some reason.\n";
467         }
468     }
469     else {
470         $pct = $files ? sprintf("%.2f", ($files - $bad) / $files * 100) : "0.00";
471         if ($bad == 1) {
472             warn "Failed 1 test script out of $files, $pct% okay.\n";
473         }
474         else {
475             warn "Failed $bad test scripts out of $files, $pct% okay.\n";
476         }
477         warn <<'SHRDLU_1';
478 ### Since not all tests were successful, you may want to run some of
479 ### them individually and examine any diagnostic messages they produce.
480 ### See the INSTALL document's section on "make test".
481 SHRDLU_1
482         warn <<'SHRDLU_2' if $good / $total > 0.8;
483 ### You have a good chance to get more information by running
484 ###   ./perl harness
485 ### in the 't' directory since most (>=80%) of the tests succeeded.
486 SHRDLU_2
487         if (eval {require Config; import Config; 1}) {
488             if ($Config{usedl} && (my $p = $Config{ldlibpthname})) {
489                 warn <<SHRDLU_3;
490 ### You may have to set your dynamic library search path,
491 ### $p, to point to the build directory:
492 SHRDLU_3
493                 if (exists $ENV{$p} && $ENV{$p} ne '') {
494                     warn <<SHRDLU_4a;
495 ###   setenv $p `pwd`:\$$p; cd t; ./perl harness
496 ###   $p=`pwd`:\$$p; export $p; cd t; ./perl harness
497 ###   export $p=`pwd`:\$$p; cd t; ./perl harness
498 SHRDLU_4a
499                 } else {
500                     warn <<SHRDLU_4b;
501 ###   setenv $p `pwd`; cd t; ./perl harness
502 ###   $p=`pwd`; export $p; cd t; ./perl harness
503 ###   export $p=`pwd`; cd t; ./perl harness
504 SHRDLU_4b
505                 }    
506                 warn <<SHRDLU_5;
507 ### for csh-style shells, like tcsh; or for traditional/modern
508 ### Bourne-style shells, like bash, ksh, and zsh, respectively.
509 SHRDLU_5
510             }
511         }
512     }
513     ($user,$sys,$cuser,$csys) = times;
514     print sprintf("u=%g  s=%g  cu=%g  cs=%g  scripts=%d  tests=%d\n",
515         $user,$sys,$cuser,$csys,$files,$totmax);
516     if ($ENV{PERL_VALGRIND}) {
517         my $s = $valgrind == 1 ? '' : 's';
518         print "$valgrind valgrind report$s created.\n", ;
519     }
520 }
521 exit ($bad != 0);