template.pl 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. #!perl
  2. use strict;
  3. use warnings;
  4. use TAP::Harness ();
  5. use IO::Scalar;
  6. use Test::More;
  7. #my @optimizations = ( '-O2,-fno-fold', '-O1' );
  8. my @optimizations = $ENV{BC_OPT} ? split(/\s+/,$ENV{BC_OPT}) : ('-O0','-O3');
  9. my $todo = '';
  10. # Setup file_to_test to be the file we actually want to test.
  11. my $file_to_test = $0;
  12. if ( $file_to_test =~ s{==(.*)\.t$}{.t} ) {
  13. my $options = $1;
  14. $todo = "B::C Fails to generate c code. Issues: $1" if ( $options =~ /BC-([\d-]+)/ );
  15. $todo = "gcc cannot compile generated c code. Issues: $1" if ( $options =~ /GCC-([\d-]+)/ );
  16. $todo = "Compiled binary exits with signal. Issues: $1" if ( $options =~ /SIG-([\d-]+)/ );
  17. $todo = "Test crashes before completion. Issues: $1" if ( $options =~ /BADPLAN-([\d-]+)/ );
  18. $todo = "Fails tests when compiled with perlcc. Issues: $1" if ( $options =~ /BADTEST-([\d-]+)/ );
  19. $todo = "Tests out of sequence. Issues: $1" if ( $options =~ /SEQ-([\d-]+)/ );
  20. $todo = "TODO test unexpectedly passing. Issues: $1" if ( $options =~ /TODO-([\d-]+)/ );
  21. }
  22. $file_to_test =~ s{--}{/}g;
  23. $file_to_test =~ s{C-COMPILED/}{}; # Strip the BINARY dir off to look for this test elsewhere.
  24. if ( $] < 5.014 && $file_to_test =~ m{^t/CORE/} ) {
  25. plan skip_all => "Perl CORE tests only supported since 5.14 right now.";
  26. }
  27. else {
  28. plan tests => 3 + 10 * scalar @optimizations;
  29. }
  30. ok( !-z $file_to_test, "$file_to_test exists" );
  31. open( my $fh, '<', $file_to_test ) or die("Can't open $file_to_test");
  32. my $taint = <$fh>;
  33. close $fh;
  34. $taint = ( ( $taint =~ m/\s\-T/ ) ? '-T' : '' );
  35. pass( $taint ? "Taint mode!" : "Not in taint mode" );
  36. ( my $c_file = $file_to_test ) =~ s/\.t$/.c/;
  37. ( my $bin_file = $file_to_test ) =~ s/\.t$/.bin/;
  38. unlink $bin_file, $c_file;
  39. my $PERL = $^X =~ m/\s/ ? qq{"$^X"} : $^X;
  40. my $check = `$PERL -c $taint '$file_to_test' 2>&1`;
  41. like( $check, qr/syntax OK/, "$PERL -c $taint $file_to_test" );
  42. $ENV{HARNESS_NOTTY} = 1;
  43. my %SIGNALS = qw( 11 SEGV 6 SIGABRT 1 SIGHUP 13 SIGPIPE);
  44. $SIGNALS{0} = '';
  45. foreach my $optimization (@optimizations) {
  46. TODO: {
  47. SKIP: {
  48. local $TODO = $todo if ( $todo =~ /B::C Fails to generate c code/ );
  49. local $ENV{BC_OPT} = $optimization;
  50. my $b = $optimization; # protect against parallel test name clashes
  51. #$b =~ s/-(D.*|f.*|v),//g;
  52. #$b =~ s/-/_/g;
  53. #$b =~ s/[, ]//g;
  54. #$b =~ s/_O0$//;
  55. #$b = lc($b);
  56. $b = ''; # need to check $0 diagnostics
  57. ( $c_file = $file_to_test ) =~ s/\.t$/$b.c/;
  58. $b = '.bin'; # need to check $0 diagnostics
  59. ( $bin_file = $file_to_test ) =~ s/\.t$/$b/;
  60. unlink $bin_file, $c_file;
  61. # Generate the C code at $optimization level
  62. my $cmd = "$PERL $taint -Iblib/arch -Iblib/lib -MO=-qq,C,$optimization,-o$c_file $file_to_test 2>&1";
  63. diag $cmd if $ENV{TEST_VERBOSE};
  64. my $BC_output = `$cmd`;
  65. note $BC_output if ($BC_output);
  66. ok( !-z $c_file, "$c_file is generated ($optimization)" );
  67. if ( -z $c_file ) {
  68. unlink $c_file;
  69. skip( "Can't test further due to failure to create a c file.", 9 );
  70. }
  71. # gcc the c code.
  72. local $TODO = $todo if ( $todo =~ /gcc cannot compile generated c code/ );
  73. $cmd = "$PERL -Iblib/arch -Iblib/lib script/cc_harness -q $c_file -o $bin_file 2>&1";
  74. diag $cmd if $ENV{TEST_VERBOSE};
  75. my $compile_output = `$cmd`;
  76. note $compile_output if ($compile_output);
  77. # Validate compiles
  78. ok( -x $bin_file, "$bin_file is compiled and ready to run." );
  79. if ( !-x $bin_file ) {
  80. unlink $c_file, $bin_file unless $ENV{BC_DEVELOPING};
  81. skip( "Can't test further due to failure to create a binary file.", 8 );
  82. }
  83. # Parse through TAP::Harness
  84. my $out = '';
  85. my $out_fh = new IO::Scalar \$out;
  86. my %args = (
  87. verbosity => 1,
  88. lib => [],
  89. merge => 1,
  90. stdout => $out_fh,
  91. );
  92. my $harness = TAP::Harness->new( \%args );
  93. my $res = $harness->runtests($bin_file);
  94. close $out_fh;
  95. my $parser = $res->{parser_for}->{$bin_file};
  96. ok( $parser, "Output parsed by TAP::Harness" );
  97. my $signal = $res->{wait} % 256;
  98. if ( $todo =~ /Compiled binary exits with signal/ ) {
  99. local $TODO = "Tests don't pass at the moment - $todo";
  100. my $sig_name = $SIGNALS{$signal};
  101. ok( $signal == 0, "Exit signal is $signal ($sig_name)" );
  102. note $out if ($out);
  103. skip( "Test failures irrelevant if exits premature with $sig_name", 6 );
  104. }
  105. else {
  106. ok( $signal == 0, "Exit signal is $signal" );
  107. }
  108. if ( $todo =~ m/Test crashes before completion/ ) {
  109. local $TODO = $todo;
  110. ok( $parser->{is_good_plan}, "Plan was valid" );
  111. note $out;
  112. skip( "TAP parse is unpredictable when plan is invalid", 5 );
  113. }
  114. else {
  115. ok( $parser->{is_good_plan}, "Plan was valid" );
  116. }
  117. ok( $parser->{exit} == 0, "Exit code is $parser->{exit}" );
  118. local $TODO = "Tests don't pass at the moment - $todo"
  119. if ( $todo =~ /Fails tests when compiled with perlcc/ );
  120. ok( !scalar @{ $parser->{failed} }, "Test results:" );
  121. print " $_\n" foreach ( split( "\n", $out ) );
  122. if (!ok( !scalar @{ $parser->{failed} }, "No test failures $optimization" )) {
  123. note( "Failed $optimization tests: " . join( ", ", @{ $parser->{failed} } ) );
  124. $ENV{BC_DEVELOPING} = 1; # keep temp files
  125. }
  126. skip( "Don't care about test sequence if tests are failing", 2 )
  127. if ( $todo =~ /Fails tests when compiled with perlcc/ );
  128. local $TODO = $todo if ( $todo =~ m/Tests out of sequence/ );
  129. if (!ok( !scalar @{ $parser->{parse_errors} }, "Tests are in sequence" )) {
  130. note explain $parser->{parse_errors};
  131. $ENV{BC_DEVELOPING} = 1; # keep temp files
  132. }
  133. local $TODO = "tests unexpectedly passing" if scalar @{ $parser->{todo_passed} };
  134. if (!ok( !scalar @{ $parser->{todo_passed} }, "No TODO tests passed $optimization" )) {
  135. note( "TODO Passed: " . join( ", ", @{ $parser->{todo_passed} } ) );
  136. $ENV{BC_DEVELOPING} = 1; # keep temp files
  137. }
  138. $TODO = '';
  139. }
  140. }
  141. unlink $bin_file, $c_file unless $ENV{BC_DEVELOPING};
  142. }