line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package App::TestOnTap::Harness; |
2
|
|
|
|
|
|
|
|
3
|
19
|
|
|
19
|
|
151
|
use strict; |
|
19
|
|
|
|
|
42
|
|
|
19
|
|
|
|
|
657
|
|
4
|
19
|
|
|
19
|
|
110
|
use warnings; |
|
19
|
|
|
|
|
56
|
|
|
19
|
|
|
|
|
1313
|
|
5
|
|
|
|
|
|
|
|
6
|
|
|
|
|
|
|
our $VERSION = '1.001'; |
7
|
|
|
|
|
|
|
my $version = $VERSION; |
8
|
|
|
|
|
|
|
$VERSION = eval $VERSION; |
9
|
|
|
|
|
|
|
|
10
|
19
|
|
|
19
|
|
153
|
use base qw(TAP::Harness); |
|
19
|
|
|
|
|
64
|
|
|
19
|
|
|
|
|
10864
|
|
11
|
|
|
|
|
|
|
|
12
|
19
|
|
|
19
|
|
120217
|
use App::TestOnTap::Scheduler; |
|
19
|
|
|
|
|
54
|
|
|
19
|
|
|
|
|
598
|
|
13
|
19
|
|
|
19
|
|
8749
|
use App::TestOnTap::Dispenser; |
|
19
|
|
|
|
|
52
|
|
|
19
|
|
|
|
|
663
|
|
14
|
19
|
|
|
19
|
|
125
|
use App::TestOnTap::Util qw(slashify runprocess $IS_PACKED); |
|
19
|
|
|
|
|
46
|
|
|
19
|
|
|
|
|
2085
|
|
15
|
|
|
|
|
|
|
|
16
|
19
|
|
|
19
|
|
8974
|
use TAP::Formatter::Console; |
|
19
|
|
|
|
|
66453
|
|
|
19
|
|
|
|
|
577
|
|
17
|
19
|
|
|
19
|
|
8028
|
use TAP::Formatter::File; |
|
19
|
|
|
|
|
54052
|
|
|
19
|
|
|
|
|
603
|
|
18
|
|
|
|
|
|
|
|
19
|
19
|
|
|
19
|
|
155
|
use List::Util qw(max); |
|
19
|
|
|
|
|
48
|
|
|
19
|
|
|
|
|
19941
|
|
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
sub new |
22
|
|
|
|
|
|
|
{ |
23
|
27
|
|
|
27
|
1
|
74
|
my $class = shift; |
24
|
27
|
|
|
|
|
59
|
my $args = shift; |
25
|
|
|
|
|
|
|
|
26
|
27
|
|
|
|
|
154
|
my $self = $class->SUPER::new |
27
|
|
|
|
|
|
|
( |
28
|
|
|
|
|
|
|
{ |
29
|
|
|
|
|
|
|
formatter => __getFormatter($args), |
30
|
|
|
|
|
|
|
jobs => $args->getJobs(), |
31
|
|
|
|
|
|
|
merge => $args->getMerge(), |
32
|
|
|
|
|
|
|
callbacks => { after_test => $args->getWorkDirManager()->getResultCollector() }, |
33
|
|
|
|
|
|
|
'exec' => __getExecMapper($args), |
34
|
|
|
|
|
|
|
scheduler_class => 'App::TestOnTap::Scheduler' |
35
|
|
|
|
|
|
|
} |
36
|
|
|
|
|
|
|
); |
37
|
|
|
|
|
|
|
|
38
|
27
|
|
|
|
|
10391
|
$self->{testontap} = { args => $args, pez => App::TestOnTap::Dispenser->new($args) }; |
39
|
|
|
|
|
|
|
|
40
|
26
|
|
|
|
|
149
|
return $self; |
41
|
|
|
|
|
|
|
} |
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
sub make_scheduler |
44
|
|
|
|
|
|
|
{ |
45
|
26
|
|
|
26
|
1
|
125756
|
my $self = shift; |
46
|
|
|
|
|
|
|
|
47
|
26
|
|
|
|
|
354
|
return $self->{scheduler_class}->new($self->{testontap}->{pez}, @_); |
48
|
|
|
|
|
|
|
} |
49
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
sub runtests |
51
|
|
|
|
|
|
|
{ |
52
|
26
|
|
|
26
|
1
|
61
|
my $self = shift; |
53
|
|
|
|
|
|
|
|
54
|
26
|
|
|
|
|
69
|
my $args = $self->{testontap}->{args}; |
55
|
26
|
|
|
|
|
96
|
my $sr = $args->getSuiteRoot(); |
56
|
|
|
|
|
|
|
|
57
|
26
|
|
|
|
|
80
|
my @pairs; |
58
|
26
|
|
|
|
|
194
|
push(@pairs, [ slashify("$sr/$_"), $_ ]) foreach ($self->{testontap}->{pez}->getAllTests()); |
59
|
|
|
|
|
|
|
|
60
|
26
|
|
|
|
|
83
|
my $failed = 0; |
61
|
|
|
|
|
|
|
{ |
62
|
26
|
|
|
|
|
50
|
my $wdmgr = $self->{testontap}->{args}->getWorkDirManager(); |
|
26
|
|
|
|
|
145
|
|
63
|
|
|
|
|
|
|
|
64
|
26
|
|
|
|
|
58
|
local %ENV = %{$self->{testontap}->{args}->getPreprocess()->getEnv()}; |
|
26
|
|
|
|
|
127
|
|
65
|
26
|
|
|
|
|
215
|
$ENV{TESTONTAP_SUITE_DIR} = $sr; |
66
|
26
|
|
|
|
|
165
|
$ENV{TESTONTAP_TMP_DIR} = $wdmgr->getTmp(); |
67
|
26
|
|
|
|
|
141
|
$ENV{TESTONTAP_SAVE_DIR} = $wdmgr->getSaveSuite(); |
68
|
|
|
|
|
|
|
|
69
|
26
|
100
|
|
|
|
161
|
if ($self->{testontap}->{args}->useHarness()) |
70
|
|
|
|
|
|
|
{ |
71
|
|
|
|
|
|
|
# the normal case is to run with a 'real' harness that parses |
72
|
|
|
|
|
|
|
# TAP, handles parallelization, formatters and all that |
73
|
|
|
|
|
|
|
# |
74
|
25
|
|
|
|
|
143
|
$wdmgr->beginTestRun(); |
75
|
25
|
|
|
|
|
6535
|
my $aggregator = $self->SUPER::runtests(@pairs); |
76
|
25
|
|
|
|
|
17040
|
$wdmgr->endTestRun($self->{testontap}->{args}, $aggregator); |
77
|
25
|
|
100
|
|
|
339
|
$failed = $aggregator->failed() || 0; |
78
|
|
|
|
|
|
|
} |
79
|
|
|
|
|
|
|
else |
80
|
|
|
|
|
|
|
{ |
81
|
|
|
|
|
|
|
# if the user has requested 'no harness', just run the jobs serially |
82
|
|
|
|
|
|
|
# in the right context, but make no effort to parse their output |
83
|
|
|
|
|
|
|
# in any way - more convenient for debugging (esp. with an execmap |
84
|
|
|
|
|
|
|
# that can start a test in debug mode) |
85
|
|
|
|
|
|
|
# |
86
|
1
|
|
|
|
|
5
|
my $scheduler = $self->make_scheduler(@pairs); |
87
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
# figure out the longest test file name with some extra to produce some |
89
|
|
|
|
|
|
|
# nice delimiters... |
90
|
|
|
|
|
|
|
# |
91
|
1
|
|
|
|
|
2
|
my $longestTestFileName = 0; |
92
|
1
|
|
|
|
|
7
|
$longestTestFileName = max($longestTestFileName, length($_->[0])) foreach (@pairs); |
93
|
1
|
|
|
|
|
10
|
$longestTestFileName += 10; |
94
|
1
|
|
|
|
|
4
|
my $topDelimLine = '#' x $longestTestFileName; |
95
|
1
|
|
|
|
|
3
|
my $bottomDelimLine = '-' x $longestTestFileName; |
96
|
|
|
|
|
|
|
|
97
|
1
|
|
|
|
|
7
|
while (my $job = $scheduler->get_job()) |
98
|
|
|
|
|
|
|
{ |
99
|
1
|
|
|
|
|
4
|
my $desc = $job->description(); |
100
|
1
|
|
|
|
|
6
|
my $filename = $job->filename; |
101
|
1
|
|
|
|
|
7
|
my $cmdline = $self->exec()->($self, $filename); |
102
|
1
|
|
|
|
|
5
|
my $dryrun = $self->{testontap}->{args}->doDryRun(); |
103
|
1
|
50
|
|
|
|
12
|
my $parallelizable = ($self->{testontap}->{args}->getConfig()->parallelizable($desc) ? '' : 'not ') . 'parallelizable'; |
104
|
1
|
|
|
|
|
56
|
print "$topDelimLine\n"; |
105
|
1
|
|
|
|
|
16
|
print "Run test '$desc' ($parallelizable) using:\n"; |
106
|
1
|
|
|
|
|
21
|
print " $_\n" foreach (@$cmdline); |
107
|
1
|
|
|
|
|
12
|
print "$bottomDelimLine\n"; |
108
|
1
|
50
|
|
|
|
5
|
if ($dryrun) |
109
|
|
|
|
|
|
|
{ |
110
|
0
|
|
|
|
|
0
|
print "(dry run only, actual test not executed)\n"; |
111
|
|
|
|
|
|
|
} |
112
|
|
|
|
|
|
|
else |
113
|
|
|
|
|
|
|
{ |
114
|
1
|
50
|
|
|
|
100344
|
$failed++ if system(@$cmdline) >> 8; |
115
|
|
|
|
|
|
|
} |
116
|
1
|
|
|
|
|
67
|
$job->finish(); |
117
|
|
|
|
|
|
|
} |
118
|
|
|
|
|
|
|
} |
119
|
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
# run postprocessing |
121
|
|
|
|
|
|
|
# |
122
|
26
|
|
|
|
|
2193
|
my $postcmd = $self->{testontap}->{args}->getConfig()->getPostprocessCmd(); |
123
|
26
|
100
|
66
|
|
|
341
|
if ($postcmd && @$postcmd) |
124
|
|
|
|
|
|
|
{ |
125
|
1
|
|
|
|
|
4
|
my @postproc; |
126
|
|
|
|
|
|
|
my $xit = runprocess |
127
|
|
|
|
|
|
|
( |
128
|
|
|
|
|
|
|
sub |
129
|
|
|
|
|
|
|
{ |
130
|
1
|
|
|
1
|
|
33
|
push(@postproc, $_[0]); |
131
|
1
|
|
|
|
|
480
|
print STDERR $_[0] |
132
|
|
|
|
|
|
|
}, |
133
|
|
|
|
|
|
|
$sr, |
134
|
|
|
|
|
|
|
( |
135
|
|
|
|
|
|
|
@$postcmd, |
136
|
1
|
|
|
|
|
19
|
@{$self->{testontap}->{args}->getPreprocess()->getArgv()} |
|
1
|
|
|
|
|
12
|
|
137
|
|
|
|
|
|
|
) |
138
|
|
|
|
|
|
|
); |
139
|
1
|
50
|
|
|
|
41
|
if ($xit) |
140
|
|
|
|
|
|
|
{ |
141
|
1
|
|
|
|
|
9
|
$failed++; |
142
|
1
|
|
|
|
|
40
|
warn("WARNING: exit code '$xit' when running postprocess command\n"); |
143
|
|
|
|
|
|
|
} |
144
|
1
|
50
|
|
|
|
13
|
$failed++ if $xit; |
145
|
|
|
|
|
|
|
|
146
|
1
|
|
|
|
|
37
|
$args->getWorkDirManager()->recordPostprocess([ @postproc ]); |
147
|
|
|
|
|
|
|
} |
148
|
|
|
|
|
|
|
|
149
|
|
|
|
|
|
|
# drop the special workaround envvar... |
150
|
|
|
|
|
|
|
# |
151
|
26
|
50
|
|
|
|
3805
|
delete $ENV{PERL5LIB} if $IS_PACKED; |
152
|
|
|
|
|
|
|
} |
153
|
|
|
|
|
|
|
|
154
|
26
|
50
|
|
|
|
789
|
return ($failed > 127) ? 127 : $failed; |
155
|
|
|
|
|
|
|
} |
156
|
|
|
|
|
|
|
|
157
|
|
|
|
|
|
|
sub _open_spool |
158
|
|
|
|
|
|
|
{ |
159
|
47
|
|
|
47
|
|
3761
|
my $self = shift; |
160
|
47
|
|
|
|
|
107
|
my $testpath = shift; |
161
|
|
|
|
|
|
|
|
162
|
47
|
|
|
|
|
228
|
return $self->{testontap}->{args}->getWorkDirManager()->openTAPHandle($testpath); |
163
|
|
|
|
|
|
|
} |
164
|
|
|
|
|
|
|
|
165
|
|
|
|
|
|
|
sub _close_spool |
166
|
|
|
|
|
|
|
{ |
167
|
47
|
|
|
47
|
|
24974146
|
my $self = shift; |
168
|
47
|
|
|
|
|
252
|
my $parser = shift; |
169
|
|
|
|
|
|
|
|
170
|
47
|
|
|
|
|
1058
|
$self->{testontap}->{args}->getWorkDirManager()->closeTAPHandle($parser); |
171
|
|
|
|
|
|
|
|
172
|
47
|
|
|
|
|
271
|
return; |
173
|
|
|
|
|
|
|
} |
174
|
|
|
|
|
|
|
|
175
|
|
|
|
|
|
|
sub __getExecMapper |
176
|
|
|
|
|
|
|
{ |
177
|
27
|
|
|
27
|
|
97
|
my $args = shift; |
178
|
|
|
|
|
|
|
|
179
|
|
|
|
|
|
|
return sub |
180
|
|
|
|
|
|
|
{ |
181
|
48
|
|
|
48
|
|
1760
|
my $harness = shift; |
182
|
48
|
|
|
|
|
128
|
my $testfile = shift; |
183
|
|
|
|
|
|
|
|
184
|
|
|
|
|
|
|
# trim down the full file name to the test name |
185
|
|
|
|
|
|
|
# |
186
|
48
|
|
|
|
|
296
|
my $srfs = slashify($args->getSuiteRoot(), '/'); |
187
|
48
|
|
|
|
|
18970
|
my $testname = slashify($testfile, '/'); |
188
|
48
|
|
|
|
|
790
|
$testname =~ s#^\Q$srfs\E/##; |
189
|
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
# get the commandline corresponding to the test name |
191
|
|
|
|
|
|
|
# |
192
|
48
|
|
|
|
|
255
|
my $cmdline = $args->getConfig()->getExecMapping($testname); |
193
|
|
|
|
|
|
|
|
194
|
|
|
|
|
|
|
# expand it with the full set |
195
|
|
|
|
|
|
|
# |
196
|
48
|
|
|
|
|
9683
|
$cmdline = [ @$cmdline, $testfile, @{$args->getArgv()} ]; |
|
48
|
|
|
|
|
368
|
|
197
|
|
|
|
|
|
|
|
198
|
|
|
|
|
|
|
# make a note of the result for the work area records |
199
|
|
|
|
|
|
|
# |
200
|
48
|
|
|
|
|
254
|
$args->getWorkDirManager()->recordCommandLine($testname, $cmdline); |
201
|
|
|
|
|
|
|
|
202
|
48
|
|
|
|
|
243
|
return $cmdline; |
203
|
27
|
|
|
|
|
484
|
}; |
204
|
|
|
|
|
|
|
} |
205
|
|
|
|
|
|
|
|
206
|
|
|
|
|
|
|
sub __getFormatter |
207
|
|
|
|
|
|
|
{ |
208
|
27
|
|
|
27
|
|
73
|
my $args = shift; |
209
|
|
|
|
|
|
|
|
210
|
27
|
|
|
|
|
164
|
my $formatterArgs = |
211
|
|
|
|
|
|
|
{ |
212
|
|
|
|
|
|
|
jobs => $args->getJobs(), |
213
|
|
|
|
|
|
|
timer => $args->getTimer(), |
214
|
|
|
|
|
|
|
show_count => 1, |
215
|
|
|
|
|
|
|
verbosity => $args->getVerbose(), |
216
|
|
|
|
|
|
|
}; |
217
|
|
|
|
|
|
|
|
218
|
|
|
|
|
|
|
return |
219
|
27
|
50
|
|
|
|
965
|
-t \*STDOUT |
220
|
|
|
|
|
|
|
? TAP::Formatter::Console->new($formatterArgs) |
221
|
|
|
|
|
|
|
: TAP::Formatter::File->new($formatterArgs); |
222
|
|
|
|
|
|
|
} |
223
|
|
|
|
|
|
|
|
224
|
|
|
|
|
|
|
1; |