File Coverage

blib/lib/Test2/Harness.pm
Criterion Covered Total %
statement 93 103 90.2
branch 22 32 68.7
condition 9 19 47.3
subroutine 14 14 100.0
pod 0 3 0.0
total 138 171 80.7


line stmt bran cond sub pod time code
1             package Test2::Harness;
2 22     22   66 use strict;
  22         1  
  22         461  
3 22     22   66 use warnings;
  22         1  
  22         638  
4              
5             our $VERSION = '0.000013';
6              
7 22     22   66 use Carp qw/croak/;
  22         22  
  22         1315  
8 22     22   9684 use Time::HiRes qw/sleep/;
  22         19575  
  22         67  
9 22     22   2595 use Scalar::Util qw/blessed/;
  22         22  
  22         1509  
10              
11 22     22   7588 use Test2::Harness::Job;
  22         22  
  22         418  
12 22     22   7637 use Test2::Harness::Runner;
  22         24  
  22         552  
13 22     22   7988 use Test2::Harness::Parser;
  22         22  
  22         572  
14              
15 22         67 use Test2::Util::HashBase qw{
16             parser_class
17             runner
18             listeners
19             switches libs env_vars
20             jobs
21             verbose
22             timeout
23 22     22   87 };
  22         22  
24              
25             sub STEP_DELAY() { '0.05' }
26              
27             sub init {
28 54     54 0 668 my $self = shift;
29              
30 54   50     195 $self->{+ENV_VARS} ||= {};
31 54   50     158 $self->{+LIBS} ||= [];
32 54   50     147 $self->{+SWITCHES} ||= [];
33 54   50     148 $self->{+LISTENERS} ||= [];
34              
35 54   50     125 $self->{+PARSER_CLASS} ||= 'Test2::Harness::Parser';
36              
37 54   33     105 $self->{+RUNNER} ||= Test2::Harness::Runner->new();
38 54   50     174 $self->{+JOBS} ||= 1;
39             }
40              
41             sub environment {
42 663     663 0 1438 my $self = shift;
43              
44 663         4288 my $class = blessed($self);
45              
46             my %out = (
47             'HARNESS_CLASS' => $class,
48              
49             'HARNESS_ACTIVE' => '1',
50             'HARNESS_VERSION' => $Test2::Harness::VERSION,
51              
52             'HARNESS_IS_VERBOSE' => $self->verbose ? 1 : 0,
53              
54             'T2_HARNESS_ACTIVE' => '1',
55             'T2_HARNESS_VERSION' => $Test2::Harness::VERSION,
56              
57             'T2_FORMATTER' => 'T2Harness',
58              
59 663         11630 %{$self->{+ENV_VARS}},
60              
61 663 50 50     2817 'HARNESS_JOBS' => $self->{+JOBS} || 1,
62             );
63              
64 663         5985 return \%out;
65             }
66              
67             sub run {
68 42     42 0 42 my $self = shift;
69 42         126 my (@files) = @_;
70              
71 42 50       126 croak "No files to run" unless @files;
72              
73 42         105 my $pclass = $self->{+PARSER_CLASS};
74 42         63 my $listen = $self->{+LISTENERS};
75 42         42 my $runner = $self->{+RUNNER};
76 42   50     168 my $jobs = $self->{+JOBS} || 1;
77 42         42 my $timeout = $self->{+TIMEOUT};
78 42         147 my $env = $self->environment;
79              
80 42         105 my $slots = [];
81 42         63 my (@queue, @results);
82              
83 42         63 my $counter = 1;
84             my $start_file = sub {
85 621     621   1652 my $file = shift;
86 621         1219 my $job_id = $counter++;
87              
88 621         8455 my $job = Test2::Harness::Job->new(
89             id => $job_id,
90             file => $file,
91             listeners => $listen,
92             event_timeout => $timeout,
93             );
94              
95             $job->start(
96             runner => $runner,
97             start_args => {
98             env => $self->environment,
99             libs => $self->{+LIBS},
100 621         6433 switches => $self->{+SWITCHES},
101             },
102             parser_class => $pclass,
103             );
104              
105 601         28127 return $job;
106 42         147 };
107              
108             my $wait = sub {
109 621     621   481 my $slot;
110 621         1288 until($slot) {
111 18183         26085 my $no_sleep = 0;
112 18183         43673 for my $s (1 .. $jobs) {
113 18183         25242 my $job = $slots->[$s];
114              
115 18183 100       39446 if ($job) {
116 18141 100       70686 $no_sleep = 1 if $job->step;
117 18141 100       41028 next unless $job->is_done;
118 579         3532 push @results => $job->result;
119 579         3526 $slots->[$s] = undef;
120             }
121              
122 621 50       2010 next if $slots->[$s];
123              
124 621         1096 $slot = $s;
125 621         44004 last;
126             }
127              
128 18183 100       29519 last if $slot;
129 17562 100       37157 next if $no_sleep;
130 6420         321782798 sleep STEP_DELAY();
131             }
132 621         1804 return $slot;
133 42         168 };
134              
135 42         105 for my $file (@files) {
136 621 50       1913 if ($self->{+JOBS} > 1) {
137 0         0 my $header = $runner->header($file);
138 0         0 my $concurrent = $header->{features}->{concurrency};
139 0 0       0 $concurrent = 1 unless defined($concurrent);
140              
141 0 0       0 unless ($concurrent) {
142 0         0 push @queue => $file;
143 0         0 next;
144             }
145             }
146              
147 621         2060 my $slot = $wait->();
148 621         2829 $slots->[$slot] = $start_file->($file);
149             }
150              
151 22         245 while (@$slots) {
152 1805         5843 my $no_sleep = 0;
153              
154 1805         3925 my @keep;
155 1805         9708 for my $j (@$slots) {
156 1827 100       7766 next unless $j;
157              
158 1805 100       19937 $no_sleep = 1 if $j->step;
159              
160 1805 100       6657 if($j->is_done) {
161 22         447 push @results => $j->result;
162             }
163             else {
164 1783         6071 push @keep => $j;
165             }
166             }
167              
168 1805         5866 @$slots = @keep;
169              
170 1805 100       87201241 sleep STEP_DELAY() unless $no_sleep;
171             }
172              
173 22         107 for my $file (@queue) {
174 0         0 my $job = $start_file->($file);
175              
176 0         0 while(!$job->is_done) {
177 0 0       0 sleep STEP_DELAY() unless $job->step;
178             }
179              
180 0         0 push @results => $job->result;
181             }
182              
183 22         1340 return \@results;
184             }
185              
186             1;
187              
188             __END__