test.pl 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862
  1. #
  2. # t/test.pl - from CORE
  3. use Test::More;
  4. use File::Spec;
  5. sub _where {
  6. my @caller = caller($Level);
  7. return "at $caller[1] line $caller[2]";
  8. }
  9. # runperl - Runs a separate perl interpreter.
  10. # Arguments :
  11. # switches => [ command-line switches ]
  12. # nolib => 1 # don't use -I../lib (included by default)
  13. # prog => one-liner (avoid quotes)
  14. # progs => [ multi-liner (avoid quotes) ]
  15. # progfile => perl script
  16. # stdin => string to feed the stdin
  17. # stderr => redirect stderr to stdout
  18. # args => [ command-line arguments to the perl program ]
  19. # verbose => print the command line
  20. my $is_mswin = $^O eq 'MSWin32';
  21. my $is_netware = $^O eq 'NetWare';
  22. my $is_macos = $^O eq 'MacOS';
  23. my $is_vms = $^O eq 'VMS';
  24. my $is_cygwin = $^O eq 'cygwin';
  25. sub _quote_args {
  26. my ($runperl, $args) = @_;
  27. foreach (@$args) {
  28. # In VMS protect with doublequotes because otherwise
  29. # DCL will lowercase -- unless already doublequoted.
  30. $_ = q(").$_.q(") if $is_vms && !/^\"/ && length($_) > 0;
  31. $$runperl .= ' ' . $_;
  32. }
  33. }
  34. sub _create_runperl { # Create the string to qx in runperl().
  35. my %args = @_;
  36. my $runperl = $^X =~ m/\s/ ? qq{"$^X"} : $^X;
  37. #- this allows, for example, to set PERL_RUNPERL_DEBUG=/usr/bin/valgrind
  38. if ($ENV{PERL_RUNPERL_DEBUG}) {
  39. $runperl = "$ENV{PERL_RUNPERL_DEBUG} $runperl";
  40. }
  41. unless ($args{nolib}) {
  42. if ($is_macos) {
  43. $runperl .= ' -I::lib';
  44. # Use UNIX style error messages instead of MPW style.
  45. $runperl .= ' -MMac::err=unix' if $args{stderr};
  46. }
  47. else {
  48. $runperl .= ' "-I../lib"'; # doublequotes because of VMS
  49. }
  50. }
  51. if ($args{switches}) {
  52. local $Level = 2;
  53. die "test.pl:runperl(): 'switches' must be an ARRAYREF " . _where()
  54. unless ref $args{switches} eq "ARRAY";
  55. _quote_args(\$runperl, $args{switches});
  56. }
  57. if (defined $args{prog}) {
  58. die "test.pl:runperl(): both 'prog' and 'progs' cannot be used " . _where()
  59. if defined $args{progs};
  60. $args{progs} = [$args{prog}]
  61. }
  62. if (defined $args{progs}) {
  63. die "test.pl:runperl(): 'progs' must be an ARRAYREF " . _where()
  64. unless ref $args{progs} eq "ARRAY";
  65. foreach my $prog (@{$args{progs}}) {
  66. if ($is_mswin || $is_netware || $is_vms) {
  67. $runperl .= qq ( -e "$prog" );
  68. }
  69. else {
  70. $runperl .= qq ( -e '$prog' );
  71. }
  72. }
  73. } elsif (defined $args{progfile}) {
  74. $runperl .= qq( "$args{progfile}");
  75. } else {
  76. # You probaby didn't want to be sucking in from the upstream stdin
  77. die "test.pl:runperl(): none of prog, progs, progfile, args, "
  78. . " switches or stdin specified"
  79. unless defined $args{args} or defined $args{switches}
  80. or defined $args{stdin};
  81. }
  82. if (defined $args{stdin}) {
  83. # so we don't try to put literal newlines and crs onto the
  84. # command line.
  85. $args{stdin} =~ s/\n/\\n/g;
  86. $args{stdin} =~ s/\r/\\r/g;
  87. if ($is_mswin || $is_netware || $is_vms) {
  88. $runperl = qq{$^X -e "print qq(} .
  89. $args{stdin} . q{)" | } . $runperl;
  90. }
  91. elsif ($is_macos) {
  92. # MacOS can only do two processes under MPW at once;
  93. # the test itself is one; we can't do two more, so
  94. # write to temp file
  95. my $stdin = qq{$^X -e 'print qq(} . $args{stdin} . qq{)' > teststdin; };
  96. if ($args{verbose}) {
  97. my $stdindisplay = $stdin;
  98. $stdindisplay =~ s/\n/\n\#/g;
  99. print STDERR "# $stdindisplay\n";
  100. }
  101. `$stdin`;
  102. $runperl .= q{ < teststdin };
  103. }
  104. else {
  105. $runperl = qq{$^X -e 'print qq(} .
  106. $args{stdin} . q{)' | } . $runperl;
  107. }
  108. }
  109. if (defined $args{args}) {
  110. _quote_args(\$runperl, $args{args});
  111. }
  112. $runperl .= ' 2>&1' if $args{stderr} && !$is_mswin && !$is_macos;
  113. $runperl .= " \xB3 Dev:Null" if !$args{stderr} && $is_macos;
  114. if ($args{verbose}) {
  115. my $runperldisplay = $runperl;
  116. $runperldisplay =~ s/\n/\n\#/g;
  117. print STDERR "# $runperldisplay\n";
  118. }
  119. return $runperl;
  120. }
  121. sub runperl {
  122. die "test.pl:runperl() does not take a hashref"
  123. if ref $_[0] and ref $_[0] eq 'HASH';
  124. my $runperl = &_create_runperl;
  125. # ${^TAINT} is invalid in perl5.00505
  126. my $tainted;
  127. eval '$tainted = ${^TAINT};' if $] >= 5.006;
  128. my %args = @_;
  129. exists $args{switches} && grep m/^-T$/, @{$args{switches}} and $tainted = $tainted + 1;
  130. if ($tainted) {
  131. # We will assume that if you're running under -T, you really mean to
  132. # run a fresh perl, so we'll brute force launder everything for you
  133. my $sep;
  134. eval "require Config; Config->import";
  135. if ($@) {
  136. warn "test.pl had problems loading Config: $@";
  137. $sep = ':';
  138. } else {
  139. $sep = $Config{path_sep};
  140. }
  141. my @keys = grep {exists $ENV{$_}} qw(CDPATH IFS ENV BASH_ENV);
  142. local @ENV{@keys} = ();
  143. # Untaint, plus take out . and empty string:
  144. local $ENV{'DCL$PATH'} = $1 if $is_vms && ($ENV{'DCL$PATH'} =~ /(.*)/s);
  145. $ENV{PATH} =~ /(.*)/s;
  146. local $ENV{PATH} =
  147. join $sep, grep { $_ ne "" and $_ ne "." and -d $_ and
  148. ($is_mswin or $is_vms or !(stat && (stat _)[2]&0022)) }
  149. split quotemeta ($sep), $1;
  150. $ENV{PATH} .= "$sep/bin" if $is_cygwin; # Must have /bin under Cygwin
  151. $runperl =~ /(.*)/s;
  152. $runperl = $1;
  153. my ($err,$result,$stderr) = run_cmd($runperl, $args{timeout});
  154. $result =~ s/\n\n/\n/ if $is_vms; # XXX pipes sometimes double these
  155. return $result;
  156. } else {
  157. my ($err,$result,$stderr) = run_cmd($runperl, $args{timeout});
  158. $result =~ s/\n\n/\n/ if $is_vms; # XXX pipes sometimes double these
  159. return $result;
  160. }
  161. }
  162. *run_perl = \&runperl; # Nice alias.
  163. sub DIE {
  164. print STDERR "# @_\n";
  165. exit 1;
  166. }
  167. # A somewhat safer version of the sometimes wrong $^X.
  168. my $Perl;
  169. sub which_perl {
  170. unless (defined $Perl) {
  171. $Perl = $^X;
  172. # VMS should have 'perl' aliased properly
  173. return $Perl if $^O eq 'VMS';
  174. my $exe;
  175. eval "require Config; Config->import";
  176. if ($@) {
  177. warn "test.pl had problems loading Config: $@";
  178. $exe = '';
  179. } else {
  180. $exe = $Config{exe_ext};
  181. }
  182. $exe = '' unless defined $exe;
  183. # This doesn't absolutize the path: beware of future chdirs().
  184. # We could do File::Spec->abs2rel() but that does getcwd()s,
  185. # which is a bit heavyweight to do here.
  186. if ($Perl =~ /^perl\Q$exe\E$/i) {
  187. my $perl = "perl$exe";
  188. eval "require File::Spec";
  189. if ($@) {
  190. warn "test.pl had problems loading File::Spec: $@";
  191. $Perl = "./$perl";
  192. } else {
  193. $Perl = File::Spec->catfile(File::Spec->curdir(), $perl);
  194. }
  195. }
  196. # Build up the name of the executable file from the name of
  197. # the command.
  198. if ($Perl !~ /\Q$exe\E$/i) {
  199. $Perl .= $exe;
  200. }
  201. warn "which_perl: cannot find $Perl from $^X" unless -f $Perl;
  202. # For subcommands to use.
  203. $ENV{PERLEXE} = $Perl;
  204. }
  205. return $Perl;
  206. }
  207. sub unlink_all {
  208. foreach my $file (@_) {
  209. 1 while unlink $file;
  210. print STDERR "# Couldn't unlink '$file': $!\n" if -f $file;
  211. }
  212. }
  213. my $tmpfile = "misctmp000";
  214. 1 while -f ++$tmpfile;
  215. END { unlink_all $tmpfile }
  216. #
  217. # _fresh_perl
  218. #
  219. # The $resolve must be a subref that tests the first argument
  220. # for success, or returns the definition of success (e.g. the
  221. # expected scalar) if given no arguments.
  222. #
  223. sub _fresh_perl {
  224. my($prog, $resolve, $runperl_args, $name) = @_;
  225. $runperl_args ||= {};
  226. $runperl_args->{progfile} = $tmpfile;
  227. $runperl_args->{stderr} = 1;
  228. open TEST, ">", $tmpfile or die "Cannot open $tmpfile: $!";
  229. # VMS adjustments
  230. if( $^O eq 'VMS' ) {
  231. $prog =~ s#/dev/null#NL:#;
  232. # VMS file locking
  233. $prog =~ s{if \(-e _ and -f _ and -r _\)}
  234. {if (-e _ and -f _)}
  235. }
  236. print TEST $prog;
  237. close TEST or die "Cannot close $tmpfile: $!";
  238. my $results = runperl(%$runperl_args);
  239. my $status = $?;
  240. # Clean up the results into something a bit more predictable.
  241. $results =~ s/\n+$//;
  242. $results =~ s/at\s+misctmp\d+\s+line/at - line/g;
  243. $results =~ s/of\s+misctmp\d+\s+aborted/of - aborted/g;
  244. # bison says 'parse error' instead of 'syntax error',
  245. # various yaccs may or may not capitalize 'syntax'.
  246. $results =~ s/^(syntax|parse) error/syntax error/mig;
  247. if ($^O eq 'VMS') {
  248. # some tests will trigger VMS messages that won't be expected
  249. $results =~ s/\n?%[A-Z]+-[SIWEF]-[A-Z]+,.*//;
  250. # pipes double these sometimes
  251. $results =~ s/\n\n/\n/g;
  252. }
  253. my $pass = $resolve->($results);
  254. unless ($pass) {
  255. diag "# PROG: \n$prog\n";
  256. diag "# EXPECTED:\n", $resolve->(), "\n";
  257. diag "# GOT:\n$results\n";
  258. diag "# STATUS: $status\n";
  259. }
  260. # Use the first line of the program as a name if none was given
  261. unless( $name ) {
  262. ($first_line, $name) = $prog =~ /^((.{1,50}).*)/;
  263. $name .= '...' if length $first_line > length $name;
  264. }
  265. ok($pass, "fresh_perl - $name");
  266. }
  267. #
  268. # fresh_perl_is
  269. #
  270. # Combination of run_perl() and is().
  271. #
  272. sub fresh_perl_is {
  273. my($prog, $expected, $runperl_args, $name) = @_;
  274. local $Level = 2;
  275. _fresh_perl($prog,
  276. sub { @_ ? $_[0] eq $expected : $expected },
  277. $runperl_args, $name);
  278. }
  279. #
  280. # fresh_perl_like
  281. #
  282. # Combination of run_perl() and like().
  283. #
  284. sub fresh_perl_like {
  285. my($prog, $expected, $runperl_args, $name) = @_;
  286. local $Level = 2;
  287. _fresh_perl($prog,
  288. sub { @_ ?
  289. $_[0] =~ (ref $expected ? $expected : /$expected/) :
  290. $expected },
  291. $runperl_args, $name);
  292. }
  293. # now my new B::C functions
  294. sub run_cmd {
  295. my ($cmd, $timeout) = @_;
  296. my ($result, $out, $err) = (0, '', '');
  297. if ( ! defined $IPC::Run::VERSION ) {
  298. local $@;
  299. if (ref($cmd) eq 'ARRAY') {
  300. $cmd = join " ", @$cmd;
  301. }
  302. # No real way to trap STDERR?
  303. $cmd .= " 2>&1" if ($^O !~ /^MSWin32|VMS/);
  304. $out = `$cmd`;
  305. $result = $?;
  306. }
  307. else {
  308. my $in;
  309. # XXX TODO this fails with spaces in path. pass and check ARRAYREF then
  310. my @cmd = ref($cmd) eq 'ARRAY' ? @$cmd : split /\s+/, $cmd;
  311. eval {
  312. # XXX TODO hanging or stacktrace'd children are not killed on cygwin
  313. my $h = IPC::Run::start(\@cmd, \$in, \$out, \$err);
  314. if ($timeout) {
  315. my $secs10 = $timeout/10;
  316. for (1..$secs10) {
  317. if(!$h->pumpable) {
  318. last;
  319. }
  320. else {
  321. $h->pump_nb;
  322. diag sprintf("waiting %d[s]",$_*10) if $_ > 30;
  323. sleep 10;
  324. }
  325. }
  326. if($h->pumpable) {
  327. $h->kill_kill;
  328. $err .= "Timed out waiting for process exit";
  329. }
  330. }
  331. $h->finish or die "cmd returned $?";
  332. $result = $h->result(0);
  333. };
  334. $err .= "\$\@ = $@" if($@);
  335. }
  336. return ($result, $out, $err);
  337. }
  338. sub Mblib {
  339. $^O eq 'MSWin32' ? '-Iblib\arch -Iblib\lib' : "-Iblib/arch -Iblib/lib";
  340. }
  341. sub tests {
  342. my $in = shift || "t/TESTS";
  343. $in = "TESTS" unless -f $in;
  344. undef $/;
  345. open TEST, "< $in" or die "Cannot open $in";
  346. my @tests = split /\n####+.*##\n/, <TEST>;
  347. close TEST;
  348. delete $tests[$#tests] unless $tests[$#tests];
  349. @tests;
  350. }
  351. sub run_cc_test {
  352. my ($cnt, $backend, $script, $expect, $keep_c, $keep_c_fail, $todo) = @_;
  353. my ($opt, $got);
  354. local($\, $,); # guard against -l and other things that screw with
  355. # print
  356. $expect =~ s/\n$//;
  357. my ($out,$result,$stderr) = ('');
  358. my $fnbackend = lc($backend); #C,-O2
  359. ($fnbackend,$opt) = $fnbackend =~ /^(cc?)(,-o.)?/;
  360. # if ($cnt == 28 and $backend eq 'C,-O3') {
  361. # print "ok $cnt # skip $backend SIGSEGV or hangs\n";
  362. # return 0;
  363. # }
  364. # if ($todo and $cnt =~ /^(103)$/ and $] eq '5.010001') {
  365. # print "ok $cnt # skip $backend hangs\n";
  366. # return 0;
  367. # }
  368. $opt =~ s/,-/_/ if $opt;
  369. $opt = '' unless $opt;
  370. use Config;
  371. require B::C::Flags;
  372. my $test = $fnbackend."code".$cnt.".pl";
  373. my $cfile = $fnbackend."code".$cnt.$opt.".c";
  374. my @obj;
  375. @obj = ($fnbackend."code".$cnt.$opt.".obj",
  376. $fnbackend."code".$cnt.$opt.".ilk",
  377. $fnbackend."code".$cnt.$opt.".pdb")
  378. if $Config{cc} =~ /^cl/i; # MSVC uses a lot of intermediate files
  379. my $exe = $fnbackend."code".$cnt.$opt.$Config{exe_ext};
  380. unlink ($test, $cfile, $exe, @obj);
  381. open T, ">", $test; print T $script; close T;
  382. # Being able to test also the CORE B in older perls
  383. my $Mblib = $] >= 5.009005 ? Mblib() : "";
  384. my $useshrplib = $Config{useshrplib} eq 'true';
  385. unless ($Mblib) { # check for -Mblib from the testsuite
  386. if (grep { m{blib(/|\\)arch$} } @INC) {
  387. $Mblib = Mblib(); # forced -Mblib via cmdline without
  388. # printing to stderr
  389. $backend = "-qq,$backend,-q" if !$ENV{TEST_VERBOSE} and $] > 5.007;
  390. }
  391. } else {
  392. $backend = "-qq,$backend,-q" if !$ENV{TEST_VERBOSE} and $] > 5.007;
  393. }
  394. $backend .= ",-fno-warnings" if $] >= 5.013005;
  395. $backend .= ",-fno-fold" if $] >= 5.013009;
  396. $got = run_perl(switches => [ "$Mblib -MO=$backend,-o${cfile}" ],
  397. verbose => $ENV{TEST_VERBOSE}, # for debugging
  398. nolib => $ENV{PERL_CORE} ? 0 : 1, # include ../lib only in CORE
  399. stderr => 1, # to capture the "ccode.pl syntax ok"
  400. timeout => 120,
  401. progfile => $test);
  402. if (! $? and -s $cfile) {
  403. use ExtUtils::Embed ();
  404. my $command = ExtUtils::Embed::ccopts;
  405. $command .= " -DHAVE_INDEPENDENT_COMALLOC "
  406. if $B::C::Flags::have_independent_comalloc;
  407. $command .= " -o $exe $cfile ".$B::C::Flags::extra_cflags . " ";
  408. my $coredir = $ENV{PERL_SRC} || File::Spec->catdir($Config{installarchlib}, "CORE");
  409. my $libdir = File::Spec->catdir($Config{prefix}, "lib");
  410. my $so = $Config{so};
  411. if ( -e "$coredir/$Config{libperl}" and $Config{libperl} !~ /\.$so$/) {
  412. $linkargs = ExtUtils::Embed::ldopts('-std');
  413. $command .= $linkargs;
  414. } elsif ( $useshrplib and -e "$libdir/$Config{libperl}" ) {
  415. # debian: /usr/lib/libperl.so.5.10.1 and broken ExtUtils::Embed::ldopts
  416. my $linkargs = ExtUtils::Embed::ldopts('-std');
  417. if ($Config{libperl} =~ /\.$so$/) {
  418. my $libperl = File::Spec->catfile($coredir, $Config{libperl});
  419. $linkargs =~ s|-lperl |$libperl |; # link directly
  420. }
  421. $linkargs =~ s/-fstack-protector//
  422. if $command =~ /-fstack-protector/ and $linkargs =~ /-fstack-protector/;
  423. $command .= $linkargs;
  424. } else {
  425. my $linkargs = ExtUtils::Embed::ldopts('-std');
  426. # cygwin gcc-4.3 crashes with -fstack-protector 2x
  427. $linkargs =~ s/-fstack-protector//
  428. if $command =~ /-fstack-protector/ and $linkargs =~ /-fstack-protector/;
  429. $command .= $linkargs;
  430. $command .= " -lperl" if $command !~ /(-lperl|CORE\/libperl5)/ and $^O ne 'MSWin32';
  431. }
  432. $command .= $B::C::Flags::extra_libs;
  433. my $NULL = $^O eq 'MSWin32' ? '' : '2>/dev/null';
  434. if ($^O eq 'MSWin32' and $Config{ccversion} eq '12.0.8804' and $Config{cc} eq 'cl') {
  435. $command =~ s/ -opt:ref,icf//;
  436. }
  437. my $cmdline = "$Config{cc} $command $NULL";
  438. diag ($cmdline) if $ENV{TEST_VERBOSE} and $ENV{TEST_VERBOSE} == 2;
  439. run_cmd($cmdline, 20);
  440. unless (-e $exe) {
  441. print "not ok $cnt $todo failed $cmdline\n";
  442. print STDERR "# ",system("$Config{cc} $command"), "\n";
  443. #unlink ($test, $cfile, $exe, @obj) unless $keep_c_fail;
  444. return 0;
  445. }
  446. $exe = "./".$exe unless $^O eq 'MSWin32';
  447. # system("/bin/bash -c ulimit -d 1000000") if -e "/bin/bash";
  448. ($result,$out,$stderr) = run_cmd($exe, 5);
  449. if (defined($out) and !$result) {
  450. if ($out =~ /^$expect$/) {
  451. print "ok $cnt", $todo eq '#' ? "\n" : " $todo\n";
  452. unlink ($test, $cfile, $exe, @obj) unless $keep_c;
  453. return 1;
  454. } else {
  455. # cc test failed, double check uncompiled
  456. $got = run_perl(verbose => $ENV{TEST_VERBOSE}, # for debugging
  457. nolib => $ENV{PERL_CORE} ? 0 : 1, # include ../lib only in CORE
  458. stderr => 1, # to capture the "ccode.pl syntax ok"
  459. timeout => 10,
  460. progfile => $test);
  461. if (! $? and $got =~ /^$expect$/) {
  462. print "not ok $cnt $todo wanted: \"$expect\", got: \"$out\"\n";
  463. } else {
  464. print "ok $cnt # skip also fails uncompiled\n";
  465. return 1;
  466. }
  467. unlink ($test, $cfile, $exe, @obj) unless $keep_c_fail;
  468. return 0;
  469. }
  470. } else {
  471. $out = '';
  472. }
  473. }
  474. print "not ok $cnt $todo wanted: \"$expect\", \$\? = $?, got: \"$out\"\n";
  475. if ($stderr) {
  476. $stderr =~ s/\n./\n# /xmsg;
  477. print "# $stderr\n";
  478. }
  479. unlink ($test, $cfile, $exe, @obj) unless $keep_c_fail;
  480. return 0;
  481. }
  482. sub prepare_c_tests {
  483. BEGIN {
  484. use Config;
  485. if ($^O eq 'VMS') {
  486. print "1..0 # skip - B::C doesn't work on VMS\n";
  487. exit 0;
  488. }
  489. if (($Config{'extensions'} !~ /\bB\b/) ) {
  490. print "1..0 # Skip -- Perl configured without B module\n";
  491. exit 0;
  492. }
  493. # with 5.10 and 5.8.9 PERL_COPY_ON_WRITE was renamed to PERL_OLD_COPY_ON_WRITE
  494. if ($Config{ccflags} =~ /-DPERL_OLD_COPY_ON_WRITE/) {
  495. print "1..0 # skip - no OLD COW for now\n";
  496. exit 0;
  497. }
  498. }
  499. }
  500. sub run_c_tests {
  501. my $backend = $_[0];
  502. my @todo = @{$_[1]};
  503. my @skip = @{$_[2]};
  504. use Config;
  505. my $AUTHOR = -d ".svn" or -d ".git";
  506. my $keep_c = 0; # set it to keep the pl, c and exe files
  507. my $keep_c_fail = 1; # keep on failures
  508. my %todo = map { $_ => 1 } @todo;
  509. my %skip = map { $_ => 1 } @skip;
  510. my @tests = tests();
  511. # add some CC specific tests after 100
  512. # perl -lne "/^\s*sub pp_(\w+)/ && print \$1" lib/B/CC.pm > ccpp
  513. # for p in `cat ccpp`; do echo -n "$p "; grep -m1 " $p[(\[ ]" *.concise; done
  514. #
  515. # grep -A1 "coverage: ny" lib/B/CC.pm|grep sub
  516. # pp_stub pp_cond_expr pp_dbstate pp_reset pp_stringify pp_ncmp pp_preinc
  517. # pp_formline pp_enterwrite pp_leavewrite pp_entergiven pp_leavegiven
  518. # pp_dofile pp_grepstart pp_mapstart pp_grepwhile pp_mapwhile
  519. if ($backend =~ /^CC/) {
  520. local $/;
  521. my $cctests = <<'CCTESTS';
  522. my ($r_i,$i_i,$d_d)=(0,2,3.0); $r_i=$i_i*$i_i; $r_i*=$d_d; print $r_i;
  523. >>>>
  524. 12
  525. ######### 101 - CC types and arith ###############
  526. if ($x eq "2"){}else{print "ok"}
  527. >>>>
  528. ok
  529. ######### 102 - CC cond_expr,stub,scope ############
  530. require B; my $x=1e1; my $s="$x"; print ref B::svref_2object(\$s)
  531. >>>>
  532. B::PV
  533. ######### 103 - CC stringify srefgen ############
  534. @a=(1..4);while($a=shift@a){print $a;}continue{$a=~/2/ and reset q(a);}
  535. >>>>
  536. 12
  537. ######### 104 CC reset ###############################
  538. use blib;use B::CC;my int $r;my $i:int=2;our double $d=3.0; $r=$i*$i; $r*=$d; print $r;
  539. >>>>
  540. 12
  541. ######### 105 CC attrs ###############################
  542. CCTESTS
  543. my $i = 100;
  544. for (split /\n####+.*##\n/, $cctests) {
  545. next unless $_;
  546. $tests[$i] = $_;
  547. $i++;
  548. }
  549. }
  550. print "1..".(scalar @tests)."\n";
  551. my $cnt = 1;
  552. for (@tests) {
  553. my $todo = $todo{$cnt} ? "#TODO" : "#";
  554. # skip empty CC holes to have the same test indices in STATUS and t/testcc.sh
  555. unless ($_) {
  556. print sprintf("ok %d # skip hole for CC\n", $cnt);
  557. $cnt++;
  558. next;
  559. }
  560. # only once. skip subsequent tests 29 on MSVC. 7:30min!
  561. if ($cnt == 29 and $Config{cc} =~ /^cl/i and $backend ne 'C') {
  562. $todo{$cnt} = $skip{$cnt} = 1;
  563. }
  564. $backend .= ",-UB" if $cnt == 15;
  565. $backend .= ",-fstash" if $cnt == 46;
  566. if ($todo{$cnt} and $skip{$cnt} and
  567. # those are currently blocking the system
  568. # do not even run them at home if TODO+SKIP
  569. (!$AUTHOR
  570. #or ($cnt==15 and $backend eq 'C,-O1') # hanging
  571. or ($cnt==103 and $backend eq 'CC,-O2') # hanging
  572. ))
  573. {
  574. print sprintf("ok %d # skip\n", $cnt);
  575. } else {
  576. my ($script, $expect) = split />>>+\n/;
  577. die "Invalid empty t/TESTS" if !$script or $expect eq '';
  578. run_cc_test($cnt, $backend,
  579. $script, $expect, $keep_c, $keep_c_fail, $todo);
  580. }
  581. $cnt++;
  582. }
  583. }
  584. sub plctestok {
  585. my ($num, $base, $script, $todo) = @_;
  586. plctest($num,'^ok', $base, $script, $todo);
  587. }
  588. sub plctest {
  589. my ($num, $expected, $base, $script, $todo) = @_;
  590. my $name = $base."_$num";
  591. unlink($name, "$name.plc", "$name.pl", "$name.exe");
  592. open F, ">", "$base.pl";
  593. print F $script;
  594. close F;
  595. my $runperl = $^X =~ m/\s/ ? qq{"$^X"} : $^X;
  596. # we don't want to change STDOUT/STDERR on STDOUT/STDERR tests, so no -qq
  597. my $nostdoutclobber = $base !~ /^ccode93i/;
  598. my $b = ($] > 5.008 and $nostdoutclobber) ? "-qq,Bytecode" : "Bytecode";
  599. system "$runperl ".Mblib." -MO=$b,-o$name.plc $base.pl";
  600. # $out =~ s/^$base.pl syntax OK\n//m;
  601. unless (-e "$name.plc") {
  602. print "not ok $num #B::Bytecode failed\n";
  603. exit;
  604. }
  605. my $out = qx($runperl -Mblib -MByteLoader $name.plc);
  606. chomp $out;
  607. my $ok = $out =~ /$expected/;
  608. if ($todo and $todo =~ /TODO/) {
  609. $todo =~ s/TODO //;
  610. TODO: {
  611. local $TODO = $todo;
  612. ok($ok);
  613. }
  614. } else {
  615. ok($ok, "Bytecode $base".($todo ? " $todo" : ''));
  616. }
  617. if ($ok) {
  618. unlink("$name.plc", "$base.pl");
  619. }
  620. }
  621. sub ctestok {
  622. my ($num, $backend, $base, $script, $todo) = @_;
  623. my $qr = '^ok'; # how lame
  624. ctest($num, $qr, $backend, $base, $script, $todo);
  625. }
  626. sub ctest {
  627. my ($num, $expected, $backend, $base, $script, $todo) = @_;
  628. my $name = $base."_$num";
  629. unlink($name, "$name.c", "$name.pl", "$name.exe");
  630. open F, ">", "$name.pl";
  631. print F $script;
  632. close F;
  633. my $runperl = $^X =~ m/\s/ ? qq{"$^X"} : $^X;
  634. # we don't want to change STDOUT/STDERR on STDOUT/STDERR tests, so no -qq
  635. my $nostdoutclobber = $base !~ /^ccode93i/;
  636. my $b = ($] > 5.008 and $nostdoutclobber) ? "-qq,$backend" : "$backend";
  637. $b .= q(,-fno-fold,-fno-warnings) if $] >= 5.013005;
  638. system "$runperl ".Mblib." -MO=$b,-o$name.c $name.pl";
  639. unless (-e "$name.c") {
  640. print "not ok $num #B::$backend failed\n";
  641. exit;
  642. }
  643. system "$runperl ".Mblib." blib/script/cc_harness -q -o $name $name.c";
  644. my $exe = $name.$Config{exe_ext};
  645. unless (-e $exe) {
  646. if ($todo and $todo =~ /TODO/) {
  647. $todo =~ s/TODO //;
  648. TODO: {
  649. local $TODO = $todo;
  650. ok(undef, "failed to compile");
  651. }
  652. } else {
  653. ok(undef, "failed to compile $todo");
  654. }
  655. return;
  656. }
  657. $exe = "./".$exe unless $^O eq 'MSWin32';
  658. ($result,$out,$stderr) = run_cmd($exe, 5);
  659. my $ok;
  660. if (defined($out) and !$result) {
  661. chomp $out;
  662. $ok = $out =~ /$expected/;
  663. diag($out);
  664. unless ($ok) { #crosscheck uncompiled
  665. my $out1 = `$runperl $name.pl`;
  666. unless ($out1 =~ /$expected/) {
  667. ok(1, "skip also fails uncompiled $todo");
  668. return;
  669. }
  670. }
  671. if ($todo and $todo =~ /TODO/) {
  672. $todo =~ s/TODO //;
  673. TODO: {
  674. local $TODO = $todo;
  675. ok ($out =~ /$expected/);
  676. diag($out);
  677. }
  678. } else {
  679. ok ($out =~ /$expected/, $todo);
  680. }
  681. } else {
  682. if ($todo and $todo =~ /TODO/) {
  683. $todo =~ s/TODO //;
  684. TODO: {
  685. local $TODO = $todo;
  686. ok (undef);
  687. }
  688. } else {
  689. #crosscheck uncompiled
  690. my $out1 = `$runperl $name.pl`;
  691. unless ($out1 =~ /$expected/) {
  692. ok(1, "skip also fails uncompiled");
  693. return;
  694. }
  695. ok (undef, $todo);
  696. }
  697. }
  698. unlink("$name.pl");
  699. if ($ok) {
  700. unlink($name, "$name.c", "$name.exe");
  701. }
  702. }
  703. sub ccompileok {
  704. my ($num, $backend, $base, $script, $todo) = @_;
  705. my $name = $base."_$num";
  706. unlink($name, "$name.c", "$name.pl", "$name.exe");
  707. open F, ">", "$name.pl";
  708. print F $script;
  709. close F;
  710. my $runperl = $^X =~ m/\s/ ? qq{"$^X"} : $^X;
  711. my $b = $] > 5.008 ? "-qq,$backend" : "$backend";
  712. my $Mblib = Mblib();
  713. system "$runperl $Mblib -MO=$b,-o$name.c $name.pl";
  714. unless (-e "$name.c") {
  715. print "not ok 1 #B::$backend failed\n";
  716. exit;
  717. }
  718. system "$runperl $Mblib blib/script/cc_harness -q -o $name $name.c";
  719. my $ok = -e $name or -e "$name.exe";
  720. if ($todo and $todo =~ /TODO/) {
  721. TODO: {
  722. $todo =~ s/TODO //;
  723. local $TODO = $todo;
  724. ok($ok);
  725. }
  726. } else {
  727. ok($ok, $todo);
  728. }
  729. unlink("$name.pl");
  730. if ($ok) {
  731. unlink($name, "$name.c", "$name.exe");
  732. }
  733. }
  734. sub todo_tests_default {
  735. my $what = shift;
  736. my $DEBUGGING = ($Config{ccflags} =~ m/-DDEBUGGING/);
  737. my $ITHREADS = ($Config{useithreads});
  738. my @todo = ();
  739. push @todo, (15) if $] < 5.007;
  740. push @todo, (15) if $] >= 5.015;
  741. if ($what =~ /^c(|_o[1-4])$/) {
  742. push @todo, (7) if $] == 5.008005;
  743. push @todo, (21) if $] >= 5.012 and $] < 5.014;
  744. push @todo, (15) if $] > 5.010 and $ITHREADS;
  745. push @todo, (27) if $] >= 5.012 and $] < 5.014 and $ITHREADS and $DEBUGGING;
  746. # @ISA issue 64
  747. push @todo, (10,12,19,25,42,43,50) if $what eq 'c_o4';
  748. push @todo, (48) if $] >= 5.008009 and $] < 5.010 and $what eq 'c_o4';
  749. # DynaLoader::dl_load_file()
  750. push @todo, (15,27,29,41..45,49) if $] > 5.015 and $what eq 'c_o4';
  751. } elsif ($what =~ /^cc/) {
  752. # 8,11,14..16,18..19 fail on 5.00505 + 5.6, old core failures (max 20)
  753. # on cygwin 29 passes
  754. #15,21,27,30,41-45,50,103,105
  755. push @todo, (21,30,46,50,103,105);
  756. push @todo, (15) if $] < 5.008008;
  757. push @todo, (15) if $] >= 5.012 and $] < 5.015 and $ITHREADS;
  758. push @todo, (104,105) if $] < 5.007; # leaveloop, no cxstack
  759. push @todo, (3,7,15,41,44,45) if $] > 5.008 and $] <= 5.008005;
  760. push @todo, (42,43) if $] > 5.008 and $] <= 5.008005 and !$ITHREADS;
  761. push @todo, (14) if $] >= 5.012;
  762. push @todo, (10,16) if $what eq 'cc_o2';
  763. #push @todo, (103) if $] > 5.007 and $] < 5.009 and $what eq 'cc_o1';
  764. # only tested 5.8.4 and .5
  765. push @todo, (29) if $] < 5.008006 or $] > 5.013;
  766. push @todo, (14) if $] >= 5.010 and $^O !~ /MSWin32|cygwin/i;
  767. # solaris also. I suspected nvx<=>cop_seq_*
  768. push @todo, (12) if $^O eq 'MSWin32' and $Config{cc} =~ /^cl/i;
  769. push @todo, (26) if $what =~ /^cc_o[12]/;
  770. push @todo, (27) if $] > 5.008008 and $] < 5.009 and $what eq 'cc_o2';
  771. push @todo, (27) if $] <= 5.008008;
  772. push @todo, (25) if $] >= 5.011004 and $DEBUGGING and $ITHREADS;
  773. push @todo, (3,4) if $] >= 5.011004 and $ITHREADS;
  774. #push @todo, (49) if $] >= 5.013009 and !$ITHREADS;
  775. }
  776. push @todo, (48) if $] > 5.007 and $] < 5.009 and $^O =~ /MSWin32|cygwin/i;
  777. return @todo;
  778. }
  779. 1;
  780. # Local Variables:
  781. # mode: cperl
  782. # cperl-indent-level: 4
  783. # fill-column: 78
  784. # End:
  785. # vim: expandtab shiftwidth=4: