Mercurial > hg > Others > Rakudo
comparison t/harness5 @ 0:c341f82e7ad7 default tip
Rakudo branch in cr.ie.u-ryukyu.ac.jp
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Thu, 26 Dec 2019 16:50:27 +0900 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:c341f82e7ad7 |
---|---|
1 #!/usr/bin/env perl | |
2 | |
3 # note: Due to a limitation in Getopt::Long options that should be passed | |
4 # through to fudgeall have to come after all other options | |
5 | |
6 use strict; | |
7 use warnings; | |
8 | |
9 use FindBin; | |
10 use File::Spec; | |
11 use List::Util qw(shuffle); | |
12 use Getopt::Long qw(:config pass_through); | |
13 use Pod::Usage; | |
14 | |
15 use Test::Harness; | |
16 $Test::Harness::switches = ''; | |
17 | |
18 use constant FULL_ROAST_TEST_LIST_FILE => 't/spectest.data'; | |
19 use constant ROAST_VERSION_FILE => 't/spec/VERSION'; | |
20 my $win = $^O eq 'MSWin32'; | |
21 my $slash = $win ? '\\' : '/'; | |
22 | |
23 GetOptions( | |
24 'tests-from-file=s' => \my $list_file, | |
25 'fudge' => \my $do_fudge, | |
26 'verbosity=i' => \$Test::Harness::verbose, | |
27 'jobs:1' => \(my $jobs = $ENV{TEST_JOBS} || 6), | |
28 'quick:1' => \my $do_quick, | |
29 'stress:1' => \my $do_stress, | |
30 'archive=s' => \my $archive, | |
31 'precompile' => \my $precompile, | |
32 'jvm' => \my $jvm, | |
33 'js' => \my $js, | |
34 'moar' => \my $moar, | |
35 'randomize' => \my $randomize, | |
36 'slow' => \(my $slow = !$win), | |
37 'no-merge' => \my $no_merge, | |
38 'help|h' => sub { pod2usage(1); }, | |
39 ) or pod2usage(2); | |
40 | |
41 my @pass_through_options = grep m/^--?[^-]/, @ARGV; | |
42 my @files = grep m/^[^-]/, @ARGV; | |
43 | |
44 $ENV{'HARNESS_PERL'} = ".${slash}perl6-" . ($js ? "js" : $moar ? "m" : $jvm ? "j" : "m"); | |
45 $ENV{'PERL6LIB'} = "./lib"; | |
46 | |
47 my @slow; | |
48 if ($list_file) { | |
49 $list_file = convert_to_versioned_file($list_file); | |
50 | |
51 my $perl5 = not system $ENV{HARNESS_PERL} . ' -e "exit !try { require Inline::Perl5; 1 }"'; | |
52 if (!$perl5) { | |
53 print "Inline::Perl5 not installed: not running Perl 5 integration tests\n"; | |
54 print "You can install Inline::Perl5 into the build directory with\n\n"; | |
55 print " zef --install-to=inst#$FindBin::Bin/../gen/build_rakudo_home/site install Inline::Perl5\n\n"; | |
56 } | |
57 | |
58 open(my $f, '<', $list_file) | |
59 or die "Can't open file '$list_file' for reading: $!"; | |
60 while (<$f>) { | |
61 next if m/^\s*#/; | |
62 next unless m/\S/; | |
63 s/^\s+//; | |
64 s/\s+\z//; | |
65 my ($fn, $fudgespec) = split /\s+#\s*/; | |
66 if ($fudgespec) { | |
67 next if ($fudgespec =~ m/perl5/) && !$perl5; | |
68 next if ($fudgespec =~ m/long/) && $do_quick; | |
69 next if ($fudgespec =~ m/stress/) && !$do_stress; | |
70 next if ($fudgespec =~ m/jvm/) && !$jvm; | |
71 next if ($fudgespec =~ m/moar/) && !$moar; | |
72 next if ($fudgespec =~ m/conc/) && !($moar || $jvm); | |
73 } | |
74 | |
75 $fn = "t/spec/$fn" unless $fn =~ m/^t\Q$slash\Espec\Q$slash\E/; | |
76 $fn =~ s{/}{$slash}g; | |
77 if ( -r $fn ) { | |
78 $slow && $fudgespec && $fudgespec =~ m/slow/ | |
79 ? push @slow, $fn | |
80 : push @files, $fn; | |
81 } else { | |
82 warn "Missing test file: $fn\n"; | |
83 } | |
84 } | |
85 close $f or die $!; | |
86 } | |
87 | |
88 my @tfiles = $randomize | |
89 ? shuffle map { all_in($_) } @files | |
90 : map { all_in($_) } sort @files; | |
91 | |
92 | |
93 if (@slow) { | |
94 @slow = map { all_in($_) } @slow; | |
95 | |
96 if ($jobs > 1) { | |
97 @tfiles = batch( @tfiles/(@slow + 1), @tfiles ); | |
98 @tfiles = map { (@slow ? shift(@slow) : ()), @$_ } @tfiles; | |
99 } | |
100 else { | |
101 unshift @tfiles, map { all_in($_) } @slow; | |
102 } | |
103 } | |
104 | |
105 if ($do_fudge) { | |
106 @tfiles = map { fudge(@$_) } batch( 200, @tfiles ); | |
107 } | |
108 | |
109 sub has_use_lib { | |
110 my ($file) = @_; | |
111 my $seen_use_lib = 0; | |
112 open(my $fh, '<', $file); | |
113 while (my $line = <$fh>) { | |
114 $seen_use_lib = 1 if $line =~ /^\s*use lib/; | |
115 } | |
116 $seen_use_lib; | |
117 } | |
118 | |
119 if ($precompile) { | |
120 @tfiles = map { | |
121 if (ref $_) { | |
122 [grep {!has_use_lib($_)} @$_]; | |
123 } else { | |
124 has_use_lib($_) ? () : $_; | |
125 } | |
126 } @tfiles; | |
127 } | |
128 | |
129 my $tap_harness_class = 'TAP::Harness'; | |
130 $tap_harness_class .= '::Archive' if $archive; | |
131 | |
132 my $extra_properties; | |
133 if ($archive) { | |
134 $extra_properties->{'Submitter'} = $ENV{SMOLDER_SUBMITTER} | |
135 if $ENV{SMOLDER_SUBMITTER}; | |
136 } | |
137 | |
138 if ($jvm) { | |
139 unlink("TESTTOKEN"); | |
140 $ENV{HARNESS_PERL} = "$^X .${slash}eval-client.pl TESTTOKEN run"; | |
141 | |
142 no warnings 'once'; | |
143 # leak the filehandle; it will be closed at exit, robustly telling the server to terminate | |
144 open JVMSERVER, "| .${slash}perl6-eval-server -bind-stdin -cookie TESTTOKEN -app .${slash}perl6.jar" or die "cannot fork eval server: $!\n"; | |
145 sleep 1; | |
146 } | |
147 | |
148 if (eval "require $tap_harness_class;") { | |
149 my $run_with_perl = $precompile ? [$ENV{HARNESS_PERL}, 't/precompileandrun'] : [$ENV{HARNESS_PERL}]; | |
150 my %harness_options = ( | |
151 exec => $jvm ? [$^X, "./eval-client.pl", "TESTTOKEN", "run"] : $run_with_perl, | |
152 verbosity => 0+$Test::Harness::verbose, | |
153 jobs => $jobs, | |
154 ignore_exit => 1, | |
155 merge => ($no_merge ? 0 : 1), | |
156 $TAP::Harness::VERSION gt 3.21 ? (trap => 1) : (), | |
157 $archive ? ( archive => $archive ) : (), | |
158 $extra_properties ? ( extra_properties => $extra_properties ) : (), | |
159 ); | |
160 my $results = $tap_harness_class->new( \%harness_options )->runtests(@tfiles); | |
161 exit 1 if $results->has_errors; | |
162 } | |
163 elsif ($archive) { | |
164 die "Can't load $tap_harness_class, which is needed for smolder submissions: $@"; | |
165 } | |
166 else { | |
167 runtests(@tfiles); | |
168 } | |
169 | |
170 sub batch { | |
171 my $size = shift; | |
172 my @batches; | |
173 while (@_) { | |
174 my @batch = splice @_, 0, $size; | |
175 push @batches, \@batch; | |
176 } | |
177 @batches | |
178 } | |
179 | |
180 # adapted to return only files ending in '.t' | |
181 sub all_in { | |
182 my $start = shift; | |
183 | |
184 return $start unless -d $start; | |
185 | |
186 my @skip = ( File::Spec->updir, File::Spec->curdir, qw( .svn CVS .git ) ); | |
187 my %skip = map {($_,1)} @skip; | |
188 | |
189 my @hits = (); | |
190 | |
191 if ( opendir( my $dh, $start ) ) { | |
192 my @files = sort readdir $dh; | |
193 closedir $dh or die $!; | |
194 for my $file ( @files ) { | |
195 next if $skip{$file}; | |
196 | |
197 my $currfile = File::Spec->catfile( $start, $file ); | |
198 if ( -d $currfile ) { | |
199 push( @hits, all_in( $currfile ) ); | |
200 } else { | |
201 push( @hits, $currfile ) if $currfile =~ /\.t$/; | |
202 } | |
203 } | |
204 } else { | |
205 warn "$start: $!\n"; | |
206 } | |
207 | |
208 return @hits; | |
209 } | |
210 | |
211 sub fudge { | |
212 my $impl = $js ? 'rakudo.js' : $moar ? 'rakudo.moar' : 'rakudo.jvm'; | |
213 my $cmd = join ' ', $^X, 't/spec/fudgeall', | |
214 @pass_through_options, $impl, @_; | |
215 return split ' ', `$cmd`; | |
216 } | |
217 | |
218 sub warn_in_box { | |
219 warn +('#' x 76) . "\n\n" . shift . "\n\n" . ('#' x 76) . "\n"; | |
220 } | |
221 | |
222 sub convert_to_versioned_file { | |
223 my $file = shift; | |
224 return $file unless $file eq FULL_ROAST_TEST_LIST_FILE; | |
225 | |
226 open my $fh, '<', ROAST_VERSION_FILE or do { | |
227 warn_in_box "Failed to open roast VERSION file in " | |
228 . ROAST_VERSION_FILE . ": $!\n" | |
229 . "Defaulting to test files from $file"; | |
230 return $file; | |
231 }; | |
232 (my $ver = (grep !/^\s*#/ && /\S/, <$fh>)[0]) =~ s/^\s+|\s+$//g; | |
233 | |
234 # Make a new test file name using the version of the roast. The master | |
235 # branch would have version something like `6.d-proposals`; in such | |
236 # a case, we'll use the default test file list | |
237 my $new_file = $ver =~ /propos/i ? $file : "$file.$ver"; | |
238 if (-r $new_file) { | |
239 print "Testing Roast version $ver using test file list from $new_file\n"; | |
240 return $new_file; | |
241 } | |
242 | |
243 warn_in_box "Test list file `$new_file` for Roast version $ver does not exist\n" | |
244 . "or isn't readable. Defaulting to $file"; | |
245 return $file; | |
246 } | |
247 | |
248 =head1 NAME | |
249 | |
250 t/harness - run the harness tests for Rakudo. | |
251 | |
252 =head1 SYNOPSIS | |
253 | |
254 t/harness [options] [files] | |
255 | |
256 Options: | |
257 | |
258 --help / -h - display the help message. | |
259 --tests-from-file=[filename] - get the tests from the filename. | |
260 --fudge - fudge (?) | |
261 --jobs - number of jobs. Defaults to TEST_JOBS env var if specified, or 1 | |
262 --quick - do not run tests marked as long-running | |
263 --stress - run tests marked as stress tests | |
264 --archive=[archive] - write to an archive. | |
265 --randomize randomize the order in which test-files are processed. | |
266 --slow - spread tests marked "slow" equally over the run (default on non-Win) | |
267 --moar/--jvm/--js - mutually exclusive. Use MoarVM/JVM backend | |
268 --no-merge - pass STDERR from the tests through to the terminal's STDERR | |
269 --precompile - precompile tests before running them | |
270 | |
271 --verbosity=[level] - set the verbosity level. | |
272 1 verbose Print individual test results to STDOUT. | |
273 0 normal | |
274 -1 quiet Suppress some test output. Mostly failures when tests running. | |
275 -2 really quiet Suppress everything but the tests summary. | |
276 -3 silent Suppress everything. |