File Coverage

blib/lib/Test2/API/Instance.pm
Criterion Covered Total %
statement 296 304 97.3
branch 126 154 81.8
condition 56 89 62.9
subroutine 43 45 95.5
pod 18 24 75.0
total 539 616 87.5


line stmt bran cond sub pod time code
1             package Test2::API::Instance;
2 254     254   2896 use strict;
  249         474  
  249         7416  
3 249     249   1350 use warnings;
  249         1110  
  246         13807  
4              
5             our $VERSION = '1.302180';
6              
7             our @CARP_NOT = qw/Test2::API Test2::API::Instance Test2::IPC::Driver Test2::Formatter/;
8 246     249   1471 use Carp qw/confess carp/;
  246         545  
  246         15891  
9 246     249   1706 use Scalar::Util qw/reftype/;
  246         487  
  246         15654  
10              
11 246     249   8293 use Test2::Util qw/get_tid USE_THREADS CAN_FORK pkg_to_file try CAN_SIGSYS/;
  246         573  
  246         15711  
12              
13 246     246   108357 use Test2::EventFacet::Trace();
  246         626  
  246         5446  
14 246     246   105687 use Test2::API::Stack();
  246         728  
  246         10475  
15              
16 246         1228 use Test2::Util::HashBase qw{
17             _pid _tid
18             no_wait
19             finalized loaded
20             ipc stack formatter
21             contexts
22              
23             add_uuid_via
24              
25             -preload
26              
27             ipc_disabled
28             ipc_polling
29             ipc_drivers
30             ipc_timeout
31             formatters
32              
33             exit_callbacks
34             post_load_callbacks
35             context_acquire_callbacks
36             context_init_callbacks
37             context_release_callbacks
38             pre_subtest_callbacks
39 246     246   1660 };
  246         484  
40              
41             sub DEFAULT_IPC_TIMEOUT() { 30 }
42              
43 219     219 1 1757 sub pid { $_[0]->{+_PID} }
44 212     212 1 1196 sub tid { $_[0]->{+_TID} }
45              
46             # Wrap around the getters that should call _finalize.
47             BEGIN {
48 246     246   1062 for my $finalizer (IPC, FORMATTER) {
49 492         2263 my $orig = __PACKAGE__->can($finalizer);
50             my $new = sub {
51 715     715   1639 my $self = shift;
52 715 100       3385 $self->_finalize unless $self->{+FINALIZED};
53 709         2978 $self->$orig;
54 492         2385 };
55              
56 246     246   2066 no strict 'refs';
  246         584  
  246         9695  
57 246     246   1460 no warnings 'redefine';
  246         502  
  246         10364  
58 492         1013 *{$finalizer} = $new;
  492         813643  
59             }
60             }
61              
62 188     188 0 1153 sub has_ipc { !!$_[0]->{+IPC} }
63              
64             sub import {
65 273     273   689 my $class = shift;
66 273 100       1779 return unless @_;
67 246         647 my ($ref) = @_;
68 246         1142 $$ref = $class->new;
69             }
70              
71 298     298 0 981 sub init { $_[0]->reset }
72              
73             sub start_preload {
74 1     1 0 3 my $self = shift;
75              
76             confess "preload cannot be started, Test2::API has already been initialized"
77 1 50 33     9 if $self->{+FINALIZED} || $self->{+LOADED};
78              
79 1         30 return $self->{+PRELOAD} = 1;
80             }
81              
82             sub stop_preload {
83 1     1 0 3 my $self = shift;
84              
85 1 50       5 return 0 unless $self->{+PRELOAD};
86 1         3 $self->{+PRELOAD} = 0;
87              
88 1         5 $self->post_preload_reset();
89              
90 1         3 return 1;
91             }
92              
93             sub post_preload_reset {
94 1     1 0 3 my $self = shift;
95              
96 1         2 delete $self->{+_PID};
97 1         2 delete $self->{+_TID};
98              
99 1 50       4 $self->{+ADD_UUID_VIA} = undef unless exists $self->{+ADD_UUID_VIA};
100              
101 1         3 $self->{+CONTEXTS} = {};
102              
103 1         5 $self->{+FORMATTERS} = [];
104              
105 1         2 $self->{+FINALIZED} = undef;
106 1         3 $self->{+IPC} = undef;
107 1 50       7 $self->{+IPC_DISABLED} = $ENV{T2_NO_IPC} ? 1 : 0;
108              
109 1 50       4 $self->{+IPC_TIMEOUT} = DEFAULT_IPC_TIMEOUT() unless defined $self->{+IPC_TIMEOUT};
110              
111 1         3 $self->{+LOADED} = 0;
112              
113 1   33     8 $self->{+STACK} ||= Test2::API::Stack->new;
114             }
115              
116             sub reset {
117 355     355 1 869 my $self = shift;
118              
119 355         1541 delete $self->{+_PID};
120 355         662 delete $self->{+_TID};
121              
122 355         870 $self->{+ADD_UUID_VIA} = undef;
123              
124 355         835 $self->{+CONTEXTS} = {};
125              
126 355         856 $self->{+IPC_DRIVERS} = [];
127 355         696 $self->{+IPC_POLLING} = undef;
128              
129 355         759 $self->{+FORMATTERS} = [];
130 355         700 $self->{+FORMATTER} = undef;
131              
132 355         666 $self->{+FINALIZED} = undef;
133 355         1022 $self->{+IPC} = undef;
134 355 100       1710 $self->{+IPC_DISABLED} = $ENV{T2_NO_IPC} ? 1 : 0;
135              
136 355 100       1269 $self->{+IPC_TIMEOUT} = DEFAULT_IPC_TIMEOUT() unless defined $self->{+IPC_TIMEOUT};
137              
138 355         705 $self->{+NO_WAIT} = 0;
139 355         682 $self->{+LOADED} = 0;
140              
141 355         700 $self->{+EXIT_CALLBACKS} = [];
142 355         727 $self->{+POST_LOAD_CALLBACKS} = [];
143 355         691 $self->{+CONTEXT_ACQUIRE_CALLBACKS} = [];
144 355         1203 $self->{+CONTEXT_INIT_CALLBACKS} = [];
145 355         725 $self->{+CONTEXT_RELEASE_CALLBACKS} = [];
146 355         761 $self->{+PRE_SUBTEST_CALLBACKS} = [];
147              
148 355         2417 $self->{+STACK} = Test2::API::Stack->new;
149             }
150              
151             sub _finalize {
152 284     284   2499 my $self = shift;
153 284         858 my ($caller) = @_;
154 284   50     4516 $caller ||= [caller(1)];
155              
156             confess "Attempt to initialize Test2::API during preload"
157 284 50       1387 if $self->{+PRELOAD};
158              
159 284         829 $self->{+FINALIZED} = $caller;
160              
161 284 100       1593 $self->{+_PID} = $$ unless defined $self->{+_PID};
162 284 100       1354 $self->{+_TID} = get_tid() unless defined $self->{+_TID};
163              
164 284 100       1115 unless ($self->{+FORMATTER}) {
165 279         900 my ($formatter, $source);
166 279 100       1244 if ($ENV{T2_FORMATTER}) {
    100          
167 34         106 $source = "set by the 'T2_FORMATTER' environment variable";
168              
169 34 50       441 if ($ENV{T2_FORMATTER} =~ m/^(\+)?(.*)$/) {
170 34 100       272 $formatter = $1 ? $2 : "Test2::Formatter::$2"
171             }
172             else {
173 0         0 $formatter = '';
174             }
175             }
176 245         1672 elsif (@{$self->{+FORMATTERS}}) {
177 159         460 ($formatter) = @{$self->{+FORMATTERS}};
  159         635  
178 159         472 $source = "Most recently added";
179             }
180             else {
181 86         248 $formatter = 'Test2::Formatter::TAP';
182 86         202 $source = 'default formatter';
183             }
184              
185 279 100 66     5073 unless (ref($formatter) || $formatter->can('write')) {
186 88         469 my $file = pkg_to_file($formatter);
187 88     88   708 my ($ok, $err) = try { require $file };
  88         45329  
188 88 100       580 unless ($ok) {
189 5         30 my $line = "* COULD NOT LOAD FORMATTER '$formatter' ($source) *";
190 5         20 my $border = '*' x length($line);
191 5         55 die "\n\n $border\n $line\n $border\n\n$err";
192             }
193             }
194              
195 274         1088 $self->{+FORMATTER} = $formatter;
196             }
197              
198             # Turn on IPC if threads are on, drivers are registered, or the Test2::IPC
199             # module is loaded.
200 279 100       1248 return if $self->{+IPC_DISABLED};
201 275 100 100     1581 return unless USE_THREADS || $INC{'Test2/IPC.pm'} || @{$self->{+IPC_DRIVERS}};
  220         1580  
202              
203             # Turn on polling by default, people expect it.
204 58         317 $self->enable_ipc_polling;
205              
206 58 100       114 unless (@{$self->{+IPC_DRIVERS}}) {
  58         201  
207 55     55   464 my ($ok, $error) = try { require Test2::IPC::Driver::Files };
  55         13983  
208 55 50       351 die $error unless $ok;
209 55         119 push @{$self->{+IPC_DRIVERS}} => 'Test2::IPC::Driver::Files';
  55         309  
210             }
211              
212 58         134 for my $driver (@{$self->{+IPC_DRIVERS}}) {
  58         197  
213 58 100 66     1043 next unless $driver->can('is_viable') && $driver->is_viable;
214 57 50       431 $self->{+IPC} = $driver->new or next;
215 57         176 return;
216             }
217              
218 1         12 die "IPC has been requested, but no viable drivers were found. Aborting...\n";
219             }
220              
221 11 100   11 1 338 sub formatter_set { $_[0]->{+FORMATTER} ? 1 : 0 }
222              
223             sub add_formatter {
224 162     162 1 402 my $self = shift;
225 162         521 my ($formatter) = @_;
226 162         353 unshift @{$self->{+FORMATTERS}} => $formatter;
  162         684  
227              
228 162 100       4509 return unless $self->{+FINALIZED};
229              
230             # Why is the @CARP_NOT entry not enough?
231 2         18 local %Carp::Internal = %Carp::Internal;
232 2         6 $Carp::Internal{'Test2::Formatter'} = 1;
233              
234 2         517 carp "Formatter $formatter loaded too late to be used as the global formatter";
235             }
236              
237             sub add_context_acquire_callback {
238 165     165 0 456 my $self = shift;
239 165         479 my ($code) = @_;
240              
241 165   50     880 my $rtype = reftype($code) || "";
242              
243 165 50 33     1194 confess "Context-acquire callbacks must be coderefs"
244             unless $code && $rtype eq 'CODE';
245              
246 165         387 push @{$self->{+CONTEXT_ACQUIRE_CALLBACKS}} => $code;
  165         687  
247             }
248              
249             sub add_context_init_callback {
250 62     62 1 151 my $self = shift;
251 62         155 my ($code) = @_;
252              
253 62   50     395 my $rtype = reftype($code) || "";
254              
255 62 50 33     443 confess "Context-init callbacks must be coderefs"
256             unless $code && $rtype eq 'CODE';
257              
258 62         114 push @{$self->{+CONTEXT_INIT_CALLBACKS}} => $code;
  62         238  
259             }
260              
261             sub add_context_release_callback {
262 3     3 1 5 my $self = shift;
263 3         8 my ($code) = @_;
264              
265 3   50     10 my $rtype = reftype($code) || "";
266              
267 3 50 33     15 confess "Context-release callbacks must be coderefs"
268             unless $code && $rtype eq 'CODE';
269              
270 3         5 push @{$self->{+CONTEXT_RELEASE_CALLBACKS}} => $code;
  3         9  
271             }
272              
273             sub add_post_load_callback {
274 180     180 1 488 my $self = shift;
275 180         517 my ($code) = @_;
276              
277 180   50     1340 my $rtype = reftype($code) || "";
278              
279 180 100 66     2602 confess "Post-load callbacks must be coderefs"
280             unless $code && $rtype eq 'CODE';
281              
282 175         399 push @{$self->{+POST_LOAD_CALLBACKS}} => $code;
  175         626  
283 175 100       870 $code->() if $self->{+LOADED};
284             }
285              
286             sub add_pre_subtest_callback {
287 17     17 1 50 my $self = shift;
288 17         36 my ($code) = @_;
289              
290 17   50     80 my $rtype = reftype($code) || "";
291              
292 17 100 66     601 confess "Pre-subtest callbacks must be coderefs"
293             unless $code && $rtype eq 'CODE';
294              
295 12         24 push @{$self->{+PRE_SUBTEST_CALLBACKS}} => $code;
  12         42  
296             }
297              
298             sub load {
299 532     532 1 1400 my $self = shift;
300 532 100       2107 unless ($self->{+LOADED}) {
301             confess "Attempt to initialize Test2::API during preload"
302 265 50       1143 if $self->{+PRELOAD};
303              
304 265 100       3006 $self->{+_PID} = $$ unless defined $self->{+_PID};
305 265 100       1280 $self->{+_TID} = get_tid() unless defined $self->{+_TID};
306              
307             # This is for https://github.com/Test-More/test-more/issues/16
308             # and https://rt.perl.org/Public/Bug/Display.html?id=127774
309             # END blocks run in reverse order. This insures the END block is loaded
310             # as late as possible. It will not solve all cases, but it helps.
311 265 50   243   21574 eval "END { Test2::API::test2_set_is_end() }; 1" or die $@;
  243         35376  
312              
313 265         1783 $self->{+LOADED} = 1;
314 265         655 $_->() for @{$self->{+POST_LOAD_CALLBACKS}};
  265         1518  
315             }
316 532         2760 return $self->{+LOADED};
317             }
318              
319             sub add_exit_callback {
320 180     180 1 486 my $self = shift;
321 180         522 my ($code) = @_;
322 180   50     866 my $rtype = reftype($code) || "";
323              
324 180 100 66     2267 confess "End callbacks must be coderefs"
325             unless $code && $rtype eq 'CODE';
326              
327 175         450 push @{$self->{+EXIT_CALLBACKS}} => $code;
  175         651  
328             }
329              
330             sub ipc_disable {
331 4     4 1 16 my $self = shift;
332              
333             confess "Attempt to disable IPC after it has been initialized"
334 4 100       195 if $self->{+IPC};
335              
336 3         52 $self->{+IPC_DISABLED} = 1;
337             }
338              
339             sub add_ipc_driver {
340 9     9 1 35 my $self = shift;
341 9         32 my ($driver) = @_;
342 9         18 unshift @{$self->{+IPC_DRIVERS}} => $driver;
  9         36  
343              
344 9 100       4614 return unless $self->{+FINALIZED};
345              
346             # Why is the @CARP_NOT entry not enough?
347 2         33 local %Carp::Internal = %Carp::Internal;
348 2         9 $Carp::Internal{'Test2::IPC::Driver'} = 1;
349              
350 2         620 carp "IPC driver $driver loaded too late to be used as the global ipc driver";
351             }
352              
353             sub enable_ipc_polling {
354 61     61 1 181 my $self = shift;
355              
356 61 100       195 $self->{+_PID} = $$ unless defined $self->{+_PID};
357 61 100       180 $self->{+_TID} = get_tid() unless defined $self->{+_TID};
358              
359             $self->add_context_init_callback(
360             # This is called every time a context is created, it needs to be fast.
361             # $_[0] is a context object
362             sub {
363 693 100   693   1854 return unless $self->{+IPC_POLLING};
364 691 50       1599 return unless $self->{+IPC};
365 691 50       2806 return unless $self->{+IPC}->pending();
366 691         2913 return $_[0]->{hub}->cull;
367             }
368 61 100       401 ) unless defined $self->ipc_polling;
369              
370 61         248 $self->set_ipc_polling(1);
371             }
372              
373             sub get_ipc_pending {
374 0     0 1 0 my $self = shift;
375 0 0       0 return -1 unless $self->{+IPC};
376 0         0 $self->{+IPC}->pending();
377             }
378              
379             sub _check_pid {
380 0     0   0 my $self = shift;
381 0         0 my ($pid) = @_;
382 0         0 return kill(0, $pid);
383             }
384              
385             sub set_ipc_pending {
386 35     35 1 118 my $self = shift;
387 35 100       181 return unless $self->{+IPC};
388 29         128 my ($val) = @_;
389              
390 29 50       125 confess "value is required for set_ipc_pending"
391             unless $val;
392              
393 29         632 $self->{+IPC}->set_pending($val);
394             }
395              
396             sub disable_ipc_polling {
397 3     3 1 8 my $self = shift;
398 3 100       13 return unless defined $self->{+IPC_POLLING};
399 2         6 $self->{+IPC_POLLING} = 0;
400             }
401              
402             sub _ipc_wait {
403 29     29   55303 my ($timeout) = @_;
404 29         172 my $fail = 0;
405              
406 29 100       543 $timeout = DEFAULT_IPC_TIMEOUT() unless defined $timeout;
407              
408 29         223 my $ok = eval {
409 29 50       559 if (CAN_FORK) {
410 29     1   1645 local $SIG{ALRM} = sub { die "Timeout waiting on child processes" };
  1         68  
411 29         385 alarm $timeout;
412              
413 29         174 while (1) {
414 46         33737692 my $pid = CORE::wait();
415 45         501 my $err = $?;
416 45 100       335 last if $pid == -1;
417 17 100       140 next unless $err;
418 9         60 $fail++;
419              
420 9         54 my $sig = $err & 127;
421 9         36 my $exit = $err >> 8;
422 9         632 warn "Process $pid did not exit cleanly (wstat: $err, exit: $exit, sig: $sig)\n";
423             }
424              
425 28         918 alarm 0;
426             }
427              
428 28         109 if (USE_THREADS) {
429             my $start = time;
430              
431             while (1) {
432             last unless threads->list();
433             die "Timeout waiting on child thread" if time - $start >= $timeout;
434             sleep 1;
435             for my $t (threads->list) {
436             # threads older than 1.34 do not have this :-(
437             next if $t->can('is_joinable') && !$t->is_joinable;
438             $t->join;
439             # In older threads we cannot check if a thread had an error unless
440             # we control it and its return.
441             my $err = $t->can('error') ? $t->error : undef;
442             next unless $err;
443             my $tid = $t->tid();
444             $fail++;
445             chomp($err);
446             warn "Thread $tid did not end cleanly: $err\n";
447             }
448             }
449             }
450              
451 28         147 1;
452             };
453 29         140 my $error = $@;
454              
455 29 100 100     518 return 0 if $ok && !$fail;
456 10 100       146 warn $error unless $ok;
457 10         231 return 255;
458             }
459              
460             sub set_exit {
461 280     280 1 4194 my $self = shift;
462              
463 280 50       1518 return if $self->{+PRELOAD};
464              
465 280         939 my $exit = $?;
466 280         860 my $new_exit = $exit;
467              
468 280 100 100     2436 if ($INC{'Test/Builder.pm'} && $Test::Builder::VERSION ne $Test2::API::VERSION) {
469 3         24 print STDERR <<" EOT";
470              
471             ********************************************************************************
472             * *
473             * Test::Builder -- Test2::API version mismatch detected *
474             * *
475             ********************************************************************************
476             Test2::API Version: $Test2::API::VERSION
477             Test::Builder Version: $Test::Builder::VERSION
478              
479             This is not a supported configuration, you will have problems.
480              
481             EOT
482             }
483              
484 280         790 for my $ctx (values %{$self->{+CONTEXTS}}) {
  280         2014  
485 30 100       108 next unless $ctx;
486              
487 1 50 33     5 next if $ctx->_aborted && ${$ctx->_aborted};
  0         0  
488              
489             # Only worry about contexts in this PID
490 1   50     19 my $trace = $ctx->trace || next;
491 1 50 33     11 next unless $trace->pid && $trace->pid == $$;
492              
493             # Do not worry about contexts that have no hub
494 1   50     15 my $hub = $ctx->hub || next;
495              
496             # Do not worry if the state came to a sudden end.
497 1 50       5 next if $hub->bailed_out;
498 1 50       12 next if defined $hub->skip_reason;
499              
500             # now we worry
501 1         7 $trace->alert("context object was never released! This means a testing tool is behaving very badly");
502              
503 1         3 $exit = 255;
504 1         3 $new_exit = 255;
505             }
506              
507 280 100 66     5516 if (!defined($self->{+_PID}) or !defined($self->{+_TID}) or $self->{+_PID} != $$ or $self->{+_TID} != get_tid()) {
      100        
      66        
508 31         146 $? = $exit;
509 31         88 return;
510             }
511              
512 249 50       2701 my @hubs = $self->{+STACK} ? $self->{+STACK}->all : ();
513              
514 249 100 100     2699 if (@hubs and $self->{+IPC} and !$self->{+NO_WAIT}) {
      66        
515 18         95 local $?;
516 18         93 my %seen;
517 18         71 for my $hub (reverse @hubs) {
518 18 50       189 my $ipc = $hub->ipc or next;
519 18 50       138 next if $seen{$ipc}++;
520 18         140 $ipc->waiting();
521             }
522              
523 18         119 my $ipc_exit = _ipc_wait($self->{+IPC_TIMEOUT});
524 18   100     183 $new_exit ||= $ipc_exit;
525             }
526              
527             # None of this is necessary if we never got a root hub
528 249 100       1453 if(my $root = shift @hubs) {
529 243         2526 my $trace = Test2::EventFacet::Trace->new(
530             frame => [__PACKAGE__, __FILE__, 0, __PACKAGE__ . '::END'],
531             detail => __PACKAGE__ . ' END Block finalization',
532             );
533 243         1615 my $ctx = Test2::API::Context->new(
534             trace => $trace,
535             hub => $root,
536             );
537              
538 243 100       1158 if (@hubs) {
539 6         51 $ctx->diag("Test ended with extra hubs on the stack!");
540 6         15 $new_exit = 255;
541             }
542              
543 243 100       1315 unless ($root->no_ending) {
544 224         1008 local $?;
545 224 100       1410 $root->finalize($trace) unless $root->ended;
546 224         597 $_->($ctx, $exit, \$new_exit) for @{$self->{+EXIT_CALLBACKS}};
  224         1844  
547 224   100     2080 $new_exit ||= $root->failed;
548 224 100 50     1215 $new_exit ||= 255 unless $root->is_passing;
549             }
550             }
551              
552 249 100       1643 $new_exit = 255 if $new_exit > 255;
553              
554 249 100 66     1707 if ($new_exit && eval { require Test2::API::Breakage; 1 }) {
  24         7059  
  24         133  
555 24         187 my @warn = Test2::API::Breakage->report();
556              
557 24 100       112 if (@warn) {
558 3         15 print STDERR "\nYou have loaded versions of test modules known to have problems with Test2.\nThis could explain some test failures.\n";
559 3         15 print STDERR "$_\n" for @warn;
560 3         9 print STDERR "\n";
561             }
562             }
563              
564 249         209 $? = $new_exit;
565             }
566              
567             1;
568              
569             __END__