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.