forked from rurban/perl-compiler
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmodules.t
349 lines (323 loc) · 11.7 KB
/
modules.t
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
# -*- cperl -*-
# t/modules.t [OPTIONS] [t/mymodules]
# check if some common CPAN modules exist and
# can be compiled successfully. Only B::C is fatal,
# CC and Bytecode optional. Use -all for all three (optional), and
# -log for the reports (now default).
#
# OPTIONS:
# -all - run also B::CC and B::Bytecode
# -subset - run only random 10 of all modules. default if ! -d .svn
# -no-subset - all 100 modules
# -no-date - no date added at the logfile
# -t - run also tests
# -log - save log file. default on test10 and without subset
#
# The list in t/mymodules comes from two bigger projects.
# Recommended general lists are Task::Kensho and http://ali.as/top100/
# We are using 10 problematic modules from the latter.
# We are NOT running the full module testsuite yet with -t, we can do that
# in another author test to burn CPU for a few hours resp. days.
#
# Reports:
# for p in 5.6.2 5.8.9 5.10.1 5.12.2; do make -S clean; perl$p Makefile.PL; make; perl$p -Mblib t/modules.t -log; done
#
# How to installed skip modules:
# grep ^skip log.modules-bla|perl -lane'print $F[1]'| xargs perlbla -S cpan
# or t/testm.sh -s
use strict;
use Test::More;
use File::Temp;
# Try some simple XS module which exists in 5.6.2 and blead
# otherwise we'll get a bogus 40% failure rate
my $staticxs = '';
my $Mblib = $^O eq 'MSWin32' ? '-Iblib\arch -Iblib\lib' : "-Iblib/arch -Iblib/lib";
BEGIN {
$staticxs = '--staticxs';
# check whether linking with xs works at all. Try with and without --staticxs
if ($^O eq 'darwin') { $staticxs = ''; goto BEGIN_END; }
my $X = $^X =~ m/\s/ ? qq{"$^X"} : $^X;
my $Mblib = $^O eq 'MSWin32' ? '-Iblib\arch -Iblib\lib' : "-Iblib/arch -Iblib/lib";
my $tmp = File::Temp->new(TEMPLATE => 'pccXXXXX');
my $out = $tmp->filename;
my $result = `$X $Mblib blib/script/perlcc --staticxs -o$out -e"use Data::Dumper;"`;
my $exe = $^O eq 'MSWin32' ? "$out.exe" : $out;
unless (-e $exe or -e 'a.out') {
my $result = `$X $Mblib blib/script/perlcc -o$out -e"use Data::Dumper;"`;
unless (-e $out or -e 'a.out') {
plan skip_all => "perlcc cannot link XS module Data::Dumper. Most likely wrong ldopts.";
unlink $out;
exit;
} else {
$staticxs = '';
}
}
BEGIN_END:
unshift @INC, 't';
}
our %modules;
our $keep = '';
our $log = 0;
use modules;
require "test.pl";
my $opts_to_test = 1;
my $do_test;
$opts_to_test = 3 if grep /^-all$/, @ARGV;
$do_test = 1 if grep /^-t$/, @ARGV;
# Determine list of modules to action.
our @modules = get_module_list();
my $test_count = scalar @modules * $opts_to_test * ($do_test ? 5 : 4);
# $test_count -= 4 * $opts_to_test * (scalar @modules - scalar(keys %modules));
plan tests => $test_count;
use Config;
use B::C;
use POSIX qw(strftime);
eval { require IPC::Run; };
my $have_IPC_Run = defined $IPC::Run::VERSION;
log_diag("Warning: IPC::Run is not available. Error trapping will be limited, no timeouts.")
unless $have_IPC_Run;
my @opts = (""); # only B::C
@opts = ("", "-O", "-B") if grep /-all/, @ARGV; # all 3 compilers
my $perlversion = perlversion();
$log = 0 if @ARGV;
$log = 1 if grep /top100$/, @ARGV;
$log = 1 if grep /-log/, @ARGV or $ENV{TEST_LOG};
my $nodate = 1 if grep /-no-date/, @ARGV;
if ($log) {
$log = (@ARGV and !$nodate)
? "log.modules-$perlversion-".strftime("%Y%m%d-%H%M%S",localtime)
: "log.modules-$perlversion";
if (-e $log) {
use File::Copy;
copy $log, "$log.bak";
}
open(LOG, ">", "$log");
close LOG;
}
unless (is_subset) {
my $svnrev = "";
if (-d '.svn') {
local $ENV{LC_MESSAGES} = "C";
$svnrev = `svn info|grep Revision:`;
chomp $svnrev;
$svnrev =~ s/Revision:\s+/r/;
my $svnstat = `svn status lib/B/C.pm t/test.pl t/*.t`;
chomp $svnstat;
$svnrev .= " M" if $svnstat;
} elsif (-d '.git') {
local $ENV{LC_MESSAGES} = "C";
$svnrev = `git log -1 --pretty=format:"%h %ad | %s" --date=short`;
chomp $svnrev;
my $gitdiff = `git diff lib/B/C.pm t/test.pl t/*.t`;
chomp $gitdiff;
$svnrev .= " M" if $gitdiff;
}
log_diag("B::C::VERSION = $B::C::VERSION $svnrev");
log_diag("perlversion = $perlversion");
log_diag("path = $^X");
my $bits = 8 * $Config{ptrsize};
log_diag("platform = $^O $bits"."bit ".(
$Config{'useithreads'} ? "threaded"
: $Config{'usemultiplicity'} ? "multi"
: "non-threaded").
($Config{ccflags} =~ m/-DDEBUGGING/ ? " debug" : ""));
}
my $module_count = 0;
my ($skip, $pass, $fail, $todo) = (0,0,0,0);
MODULE:
for my $module (@modules) {
$module_count++;
local($\, $,); # guard against -l and other things that screw with
# print
# Possible binary files.
my $name = $module;
$name =~ s/::/_/g;
$name =~ s{(install|setup|update)}{substr($1,0,4)}ie;
my $out = 'pcc'.$name;
my $out_c = "$out.c";
my $out_pl = "$out.pl";
$out = "$out.exe" if $^O eq 'MSWin32';
SKIP: {
# if is a special module that can't be required like others
unless ($modules{$module}) {
$skip++;
log_pass("skip", "$module", 0);
skip("$module not installed", 4 * scalar @opts);
next MODULE;
}
if (is_skip($module)) { # !$have_IPC_Run is not really helpful here
my $why = is_skip($module);
$skip++;
log_pass("skip", "$module #$why", 0);
skip("$module $why", 4 * scalar @opts);
next MODULE;
}
$module = 'if(1) => "Sys::Hostname"' if $module eq 'if';
TODO: {
my $s = is_todo($module);
local $TODO = $s if $s;
$todo++ if $TODO;
open F, ">", $out_pl or die;
print F "use $module;\nprint 'ok';\n" or die;
close F or die;
my ($result, $stdout, $err);
my $module_passed = 1;
my $runperl = $^X =~ m/\s/ ? qq{"$^X"} : $^X;
foreach my $opt (@opts) {
$opt .= " $keep" if $keep;
# TODO ./a often hangs but perlcc not
my @cmd = grep {!/^$/}
$runperl,split(/ /,$Mblib),"blib/script/perlcc",split(/ /,$opt),$staticxs,"-o$out","-r",$out_pl;
my $cmd = "$runperl $Mblib blib/script/perlcc $opt $staticxs -o$out -r"; # only for the msg
# My Macbook Air with gcc-mp and with 1GB RAM has insane compile times
($result, $stdout, $err) = run_cmd(\@cmd, 720); # in secs.
ok(-s $out,
"$module_count: use $module generates non-zero binary")
or $module_passed = 0;
is($result, 0, "$module_count: use $module $opt exits with 0")
or $module_passed = 0;
$err =~ s/^Using .+blib\n//m if $] < 5.007;
like($stdout, qr/ok$/ms, "$module_count: use $module $opt gives expected 'ok' output");
unless ($stdout =~ /ok$/ms) { # crosscheck for a perlcc problem (XXX not needed anymore)
my ($r, $err1);
$module_passed = 0;
@cmd = ($runperl,$Mblib,"-MO=C,-o$out_c",$out_pl);
($r, $stdout, $err1) = run_cmd(\@cmd, 60); # in secs
@cmd = ($runperl,$Mblib,"script/cc_harness","-o$out",$out_c);
($r, $stdout, $err1) = run_cmd(\@cmd, 360); # in secs
@cmd = ($^O eq 'MSWin32' ? "$out" : "./$out");
($r, $stdout, $err1) = run_cmd(\@cmd, 20); # in secs
if ($stdout =~ /ok$/ms) {
$module_passed = 1;
diag "crosscheck that only perlcc $staticxs failed. With -MO=C + cc_harness => ok";
}
}
log_pass($module_passed ? "pass" : "fail", $module, $TODO);
if ($module_passed) {
$pass++;
} else {
diag "Failed: $cmd -e 'use $module; print \"ok\"'";
$fail++;
}
TODO: {
local $TODO = 'STDERR from compiler warnings in work' if $err;
is($err, '', "$module_count: use $module no error output compiling")
&& ($module_passed)
or log_err($module, $stdout, $err)
}
}
if ($do_test) {
TODO: {
local $TODO = 'all module tests';
`$runperl $Mblib -It -MCPAN -Mmodules -e "CPAN::Shell->testcc("$module")"`;
}
}
for ($out_pl, $out, $out_c, $out_c.".lst") {
unlink $_ if -f $_ ;
}
}}
}
my $count = scalar @modules - $skip;
log_diag("$count / $module_count modules tested with B-C-${B::C::VERSION} - perl-$perlversion");
log_diag(sprintf("pass %3d / %3d (%s)", $pass, $count, percent($pass,$count)));
log_diag(sprintf("fail %3d / %3d (%s)", $fail, $count, percent($fail,$count)));
log_diag(sprintf("todo %3d / %3d (%s)", $todo, $fail, percent($todo,$fail)));
log_diag(sprintf("skip %3d / %3d (%s not installed)\n",
$skip, $module_count, percent($skip,$module_count)));
exit;
# t/todomod.pl
# for t in $(cat t/top100); do perl -ne"\$ARGV=~s/log.modules-//;print \$ARGV,': ',\$_ if / $t\s/" t/modules.t `ls log.modules-5.0*|grep -v .err`; read; done
sub is_todo {
my $module = shift or die;
my $DEBUGGING = ($Config{ccflags} =~ m/-DDEBUGGING/);
# ---------------------------------------
foreach(qw(
Module::Build
)) { return 'overlong linking time' if $_ eq $module; }
foreach(qw(
Test::NoWarnings
)) { return 'print() on unopened filehandle $Testout' if $_ eq $module; }
#if ($] < 5.007) { foreach(qw(
# ExtUtils::CBuilder
#)) { return '5.6' if $_ eq $module; }}
if ($] >= 5.008004 and $] < 5.0080006) { foreach(qw(
Module::Pluggable
)) { return '5.8.5 CopFILE_set' if $_ eq $module; }}
# restricted v_string hash?
if ($] eq '5.010000') { foreach(qw(
IO
Path::Class
DateTime::TimeZone
)) { return '5.10.0 restricted hash/...' if $_ eq $module; }}
# fixed between v5.15.6-210-g5343a61 and v5.15.6-233-gfb7aafe
if ($] > 5.015 and $] < 5.015006) { foreach(qw(
B::Hooks::EndOfScope
)) { return '> 5.15' if $_ eq $module; }}
#if ($] > 5.015) { foreach(qw(
# Moose
# MooseX::Types
# DateTime
#)) { return '> 5.15 (unshare_hek)' if $_ eq $module; }}
# ---------------------------------------
if ($Config{useithreads}) {
if (!$DEBUGGING) { foreach(qw(
Test::Tester
)) { return 'non-debugging with threads' if $_ eq $module; }}
if ($] >= 5.008005 and $] < 5.008006) { foreach(qw(
Module::Build
Test::NoWarnings
Test::Warn
Test::Simple
Test::Exception
Test::Tester
Test::Deep
)) { return '5.8.4-5 shared_scalar n-magic (\156)' if $_ eq $module; }}
if ($] > 5.008001 and $] < 5.008009) { foreach(qw(
Test::Pod
)) { return '5.8.1-5.8.8 with threads' if $_ eq $module; }}
if ($] >= 5.009 and $] < 5.012) { foreach(qw(
Carp::Clan
DateTime
Encode
ExtUtils::Install
Module::Build
MooseX::Types
Pod::Text
Template::Stash
)) { return '5.10 with threads' if $_ eq $module; }}
# XXX 5.12.0 not tested recently
if ($] eq 5.012000) { foreach(qw(
DBI
DateTime
DateTime::Locale
Filter::Util::Call
Storable
Sub::Name
)) { return '5.12.0 with threads' if $_ eq $module; }}
} else { #no threads --------------------------------
# This was related to aelemfast->sv with SPECIAL pads fixed with 033d200
if ($] > 5.008004 and $] <= 5.008005) { foreach(qw(
DateTime
)) { return '5.8.5 without threads' if $_ eq $module; }}
if ($] > 5.015) { foreach(qw(
DateTime::TimeZone
Module::Build
)) { return '> 5.15 without threads' if $_ eq $module; }}
}
# ---------------------------------------
}
sub is_skip {
my $module = shift or die;
if ($] >= 5.011004) {
#foreach (qw(Attribute::Handlers)) {
# return 'fails $] >= 5.011004' if $_ eq $module;
#}
if ($Config{useithreads}) { # hangs and crashes threaded since 5.12
foreach (qw( )) {
# Old: Recursive inheritance detected in package 'Moose::Object' at /usr/lib/perl5/5.13.10/i686-debug-cygwin/DynaLoader.pm line 103
# Update: Moose works ok with r1013
return 'hangs threaded, $] >= 5.011004' if $_ eq $module;
}
}
}
}