1 package Test2::API::Instance;
5 our $VERSION = '1.302097';
8 our @CARP_NOT = qw/Test2::API Test2::API::Instance Test2::IPC::Driver Test2::Formatter/;
9 use Carp qw/confess carp/;
10 use Scalar::Util qw/reftype/;
12 use Test2::Util qw/get_tid USE_THREADS CAN_FORK pkg_to_file try CAN_SIGSYS/;
14 use Test2::EventFacet::Trace();
15 use Test2::API::Stack();
17 use Test2::Util::HashBase qw{
36 context_acquire_callbacks
37 context_init_callbacks
38 context_release_callbacks
41 sub DEFAULT_IPC_TIMEOUT() { 30 }
43 sub pid { $_[0]->{+_PID} }
44 sub tid { $_[0]->{+_TID} }
46 # Wrap around the getters that should call _finalize.
48 for my $finalizer (IPC, FORMATTER) {
49 my $orig = __PACKAGE__->can($finalizer);
52 $self->_finalize unless $self->{+FINALIZED};
57 no warnings 'redefine';
69 sub init { $_[0]->reset }
74 confess "preload cannot be started, Test2::API has already been initialized"
75 if $self->{+FINALIZED} || $self->{+LOADED};
77 return $self->{+PRELOAD} = 1;
83 return 0 unless $self->{+PRELOAD};
84 $self->{+PRELOAD} = 0;
86 $self->post_preload_reset();
91 sub post_preload_reset {
94 delete $self->{+_PID};
95 delete $self->{+_TID};
97 $self->{+CONTEXTS} = {};
99 $self->{+FORMATTERS} = [];
101 $self->{+FINALIZED} = undef;
102 $self->{+IPC} = undef;
104 $self->{+IPC_TIMEOUT} = DEFAULT_IPC_TIMEOUT() unless defined $self->{+IPC_TIMEOUT};
106 $self->{+LOADED} = 0;
108 $self->{+STACK} ||= Test2::API::Stack->new;
114 delete $self->{+_PID};
115 delete $self->{+_TID};
117 $self->{+CONTEXTS} = {};
119 $self->{+IPC_DRIVERS} = [];
120 $self->{+IPC_POLLING} = undef;
122 $self->{+FORMATTERS} = [];
123 $self->{+FORMATTER} = undef;
125 $self->{+FINALIZED} = undef;
126 $self->{+IPC} = undef;
128 $self->{+IPC_TIMEOUT} = DEFAULT_IPC_TIMEOUT() unless defined $self->{+IPC_TIMEOUT};
130 $self->{+NO_WAIT} = 0;
131 $self->{+LOADED} = 0;
133 $self->{+EXIT_CALLBACKS} = [];
134 $self->{+POST_LOAD_CALLBACKS} = [];
135 $self->{+CONTEXT_ACQUIRE_CALLBACKS} = [];
136 $self->{+CONTEXT_INIT_CALLBACKS} = [];
137 $self->{+CONTEXT_RELEASE_CALLBACKS} = [];
139 $self->{+STACK} = Test2::API::Stack->new;
145 $caller ||= [caller(1)];
147 confess "Attempt to initialize Test2::API during preload"
148 if $self->{+PRELOAD};
150 $self->{+FINALIZED} = $caller;
152 $self->{+_PID} = $$ unless defined $self->{+_PID};
153 $self->{+_TID} = get_tid() unless defined $self->{+_TID};
155 unless ($self->{+FORMATTER}) {
156 my ($formatter, $source);
157 if ($ENV{T2_FORMATTER}) {
158 $source = "set by the 'T2_FORMATTER' environment variable";
160 if ($ENV{T2_FORMATTER} =~ m/^(\+)?(.*)$/) {
161 $formatter = $1 ? $2 : "Test2::Formatter::$2"
167 elsif (@{$self->{+FORMATTERS}}) {
168 ($formatter) = @{$self->{+FORMATTERS}};
169 $source = "Most recently added";
172 $formatter = 'Test2::Formatter::TAP';
173 $source = 'default formatter';
176 unless (ref($formatter) || $formatter->can('write')) {
177 my $file = pkg_to_file($formatter);
178 my ($ok, $err) = try { require $file };
180 my $line = "* COULD NOT LOAD FORMATTER '$formatter' ($source) *";
181 my $border = '*' x length($line);
182 die "\n\n $border\n $line\n $border\n\n$err";
186 $self->{+FORMATTER} = $formatter;
189 # Turn on IPC if threads are on, drivers are registered, or the Test2::IPC
191 return unless USE_THREADS || $INC{'Test2/IPC.pm'} || @{$self->{+IPC_DRIVERS}};
193 # Turn on polling by default, people expect it.
194 $self->enable_ipc_polling;
196 unless (@{$self->{+IPC_DRIVERS}}) {
197 my ($ok, $error) = try { require Test2::IPC::Driver::Files };
198 die $error unless $ok;
199 push @{$self->{+IPC_DRIVERS}} => 'Test2::IPC::Driver::Files';
202 for my $driver (@{$self->{+IPC_DRIVERS}}) {
203 next unless $driver->can('is_viable') && $driver->is_viable;
204 $self->{+IPC} = $driver->new or next;
205 $self->ipc_enable_shm if $self->{+IPC}->use_shm;
209 die "IPC has been requested, but no viable drivers were found. Aborting...\n";
212 sub formatter_set { $_[0]->{+FORMATTER} ? 1 : 0 }
216 my ($formatter) = @_;
217 unshift @{$self->{+FORMATTERS}} => $formatter;
219 return unless $self->{+FINALIZED};
221 # Why is the @CARP_NOT entry not enough?
222 local %Carp::Internal = %Carp::Internal;
223 $Carp::Internal{'Test2::Formatter'} = 1;
225 carp "Formatter $formatter loaded too late to be used as the global formatter";
228 sub add_context_acquire_callback {
232 my $rtype = reftype($code) || "";
234 confess "Context-acquire callbacks must be coderefs"
235 unless $code && $rtype eq 'CODE';
237 push @{$self->{+CONTEXT_ACQUIRE_CALLBACKS}} => $code;
240 sub add_context_init_callback {
244 my $rtype = reftype($code) || "";
246 confess "Context-init callbacks must be coderefs"
247 unless $code && $rtype eq 'CODE';
249 push @{$self->{+CONTEXT_INIT_CALLBACKS}} => $code;
252 sub add_context_release_callback {
256 my $rtype = reftype($code) || "";
258 confess "Context-release callbacks must be coderefs"
259 unless $code && $rtype eq 'CODE';
261 push @{$self->{+CONTEXT_RELEASE_CALLBACKS}} => $code;
264 sub add_post_load_callback {
268 my $rtype = reftype($code) || "";
270 confess "Post-load callbacks must be coderefs"
271 unless $code && $rtype eq 'CODE';
273 push @{$self->{+POST_LOAD_CALLBACKS}} => $code;
274 $code->() if $self->{+LOADED};
279 unless ($self->{+LOADED}) {
280 confess "Attempt to initialize Test2::API during preload"
281 if $self->{+PRELOAD};
283 $self->{+_PID} = $$ unless defined $self->{+_PID};
284 $self->{+_TID} = get_tid() unless defined $self->{+_TID};
286 # This is for https://github.com/Test-More/test-more/issues/16
287 # and https://rt.perl.org/Public/Bug/Display.html?id=127774
288 # END blocks run in reverse order. This insures the END block is loaded
289 # as late as possible. It will not solve all cases, but it helps.
290 eval "END { Test2::API::test2_set_is_end() }; 1" or die $@;
292 $self->{+LOADED} = 1;
293 $_->() for @{$self->{+POST_LOAD_CALLBACKS}};
295 return $self->{+LOADED};
298 sub add_exit_callback {
301 my $rtype = reftype($code) || "";
303 confess "End callbacks must be coderefs"
304 unless $code && $rtype eq 'CODE';
306 push @{$self->{+EXIT_CALLBACKS}} => $code;
312 unshift @{$self->{+IPC_DRIVERS}} => $driver;
314 return unless $self->{+FINALIZED};
316 # Why is the @CARP_NOT entry not enough?
317 local %Carp::Internal = %Carp::Internal;
318 $Carp::Internal{'Test2::IPC::Driver'} = 1;
320 carp "IPC driver $driver loaded too late to be used as the global ipc driver";
323 sub enable_ipc_polling {
326 $self->{+_PID} = $$ unless defined $self->{+_PID};
327 $self->{+_TID} = get_tid() unless defined $self->{+_TID};
329 $self->add_context_init_callback(
330 # This is called every time a context is created, it needs to be fast.
331 # $_[0] is a context object
333 return unless $self->{+IPC_POLLING};
334 return $_[0]->{hub}->cull unless $self->{+IPC_SHM_ID};
338 shmread($self->{+IPC_SHM_ID}, $val, 0, $self->{+IPC_SHM_SIZE}) or return;
340 return if $val eq $self->{+IPC_SHM_LAST};
341 $self->{+IPC_SHM_LAST} = $val;
346 ) unless defined $self->ipc_polling;
348 $self->set_ipc_polling(1);
354 return 1 if defined $self->{+IPC_SHM_ID};
356 $self->{+_PID} = $$ unless defined $self->{+_PID};
357 $self->{+_TID} = get_tid() unless defined $self->{+_TID};
359 my ($ok, $err) = try {
360 # SysV IPC can be available but not enabled.
362 # In some systems (*BSD) accessing the SysV IPC APIs without
363 # them being enabled can cause a SIGSYS. We suppress the SIGSYS
364 # and then get ENOSYS from the calls.
365 local $SIG{SYS} = 'IGNORE' if CAN_SIGSYS;
369 my $ipc_key = IPC::SysV::IPC_PRIVATE();
370 my $shm_size = $self->{+IPC}->can('shm_size') ? $self->{+IPC}->shm_size : 64;
371 my $shm_id = shmget($ipc_key, $shm_size, 0666) or die;
373 my $initial = 'a' x $shm_size;
374 shmwrite($shm_id, $initial, 0, $shm_size) or die;
376 $self->{+IPC_SHM_SIZE} = $shm_size;
377 $self->{+IPC_SHM_ID} = $shm_id;
378 $self->{+IPC_SHM_LAST} = $initial;
387 my $id = delete $self->{+IPC_SHM_ID};
388 return unless defined $id;
390 shmctl($id, IPC::SysV::IPC_RMID(), 0);
393 sub get_ipc_pending {
395 return -1 unless defined $self->{+IPC_SHM_ID};
397 shmread($self->{+IPC_SHM_ID}, $val, 0, $self->{+IPC_SHM_SIZE}) or return -1;
398 return 0 if $val eq $self->{+IPC_SHM_LAST};
399 $self->{+IPC_SHM_LAST} = $val;
403 sub set_ipc_pending {
406 return undef unless defined $self->{+IPC_SHM_ID};
410 confess "value is required for set_ipc_pending"
413 shmwrite($self->{+IPC_SHM_ID}, $val, 0, $self->{+IPC_SHM_SIZE});
416 sub disable_ipc_polling {
418 return unless defined $self->{+IPC_POLLING};
419 $self->{+IPC_POLLING} = 0;
426 $timeout = DEFAULT_IPC_TIMEOUT() unless defined $timeout;
430 local $SIG{ALRM} = sub { die "Timeout waiting on child processes" };
434 my $pid = CORE::wait();
440 warn "Process $pid did not exit cleanly (status: $err)\n";
450 last unless threads->list();
451 die "Timeout waiting on child thread" if time - $start >= $timeout;
453 for my $t (threads->list) {
454 # threads older than 1.34 do not have this :-(
455 next if $t->can('is_joinable') && !$t->is_joinable;
457 # In older threads we cannot check if a thread had an error unless
458 # we control it and its return.
459 my $err = $t->can('error') ? $t->error : undef;
464 warn "Thread $tid did not end cleanly: $err\n";
473 return 0 if $ok && !$fail;
474 warn $error unless $ok;
481 return if $self->{+PRELOAD};
483 return unless defined($self->{+_PID}) && $self->{+_PID} == $$;
484 return unless defined($self->{+_TID}) && $self->{+_TID} == get_tid();
486 shmctl($self->{+IPC_SHM_ID}, IPC::SysV::IPC_RMID(), 0)
487 if defined $self->{+IPC_SHM_ID};
493 return if $self->{+PRELOAD};
496 my $new_exit = $exit;
498 if ($INC{'Test/Builder.pm'} && $Test::Builder::VERSION ne $Test2::API::VERSION) {
499 print STDERR <<" EOT";
501 ********************************************************************************
503 * Test::Builder -- Test2::API version mismatch detected *
505 ********************************************************************************
506 Test2::API Version: $Test2::API::VERSION
507 Test::Builder Version: $Test::Builder::VERSION
509 This is not a supported configuration, you will have problems.
514 for my $ctx (values %{$self->{+CONTEXTS}}) {
517 next if $ctx->_aborted && ${$ctx->_aborted};
519 # Only worry about contexts in this PID
520 my $trace = $ctx->trace || next;
521 next unless $trace->pid && $trace->pid == $$;
523 # Do not worry about contexts that have no hub
524 my $hub = $ctx->hub || next;
526 # Do not worry if the state came to a sudden end.
527 next if $hub->bailed_out;
528 next if defined $hub->skip_reason;
531 $trace->alert("context object was never released! This means a testing tool is behaving very badly");
537 if (!defined($self->{+_PID}) or !defined($self->{+_TID}) or $self->{+_PID} != $$ or $self->{+_TID} != get_tid()) {
542 my @hubs = $self->{+STACK} ? $self->{+STACK}->all : ();
544 if (@hubs and $self->{+IPC} and !$self->{+NO_WAIT}) {
547 for my $hub (reverse @hubs) {
548 my $ipc = $hub->ipc or next;
549 next if $seen{$ipc}++;
553 my $ipc_exit = _ipc_wait($self->{+IPC_TIMEOUT});
554 $new_exit ||= $ipc_exit;
557 # None of this is necessary if we never got a root hub
558 if(my $root = shift @hubs) {
559 my $trace = Test2::EventFacet::Trace->new(
560 frame => [__PACKAGE__, __FILE__, 0, __PACKAGE__ . '::END'],
561 detail => __PACKAGE__ . ' END Block finalization',
563 my $ctx = Test2::API::Context->new(
569 $ctx->diag("Test ended with extra hubs on the stack!");
573 unless ($root->no_ending) {
575 $root->finalize($trace) unless $root->ended;
576 $_->($ctx, $exit, \$new_exit) for @{$self->{+EXIT_CALLBACKS}};
577 $new_exit ||= $root->failed;
578 $new_exit ||= 255 unless $root->is_passing;
582 $new_exit = 255 if $new_exit > 255;
584 if ($new_exit && eval { require Test2::API::Breakage; 1 }) {
585 my @warn = Test2::API::Breakage->report();
588 print STDERR "\nYou have loaded versions of test modules known to have problems with Test2.\nThis could explain some test failures.\n";
589 print STDERR "$_\n" for @warn;
607 Test2::API::Instance - Object used by Test2::API under the hood
611 This object encapsulates the global shared state tracked by
612 L<Test2>. A single global instance of this package is stored (and
613 obscured) by the L<Test2::API> package.
615 There is no reason to directly use this package. This package is documented for
616 completeness. This package can change, or go away completely at any time.
617 Directly using, or monkeypatching this package is not supported in any way
622 use Test2::API::Instance;
624 my $obj = Test2::API::Instance->new;
628 =item $pid = $obj->pid
630 PID of this instance.
634 Thread ID of this instance.
638 Reset the object to defaults.
642 Set the internal state to loaded, and run and stored post-load callbacks.
644 =item $bool = $obj->loaded
646 Check if the state is set to loaded.
648 =item $arrayref = $obj->post_load_callbacks
650 Get the post-load callbacks.
652 =item $obj->add_post_load_callback(sub { ... })
654 Add a post-load callback. If C<load()> has already been called then the callback will
655 be immediately executed. If C<load()> has not been called then the callback will be
656 stored and executed later when C<load()> is called.
658 =item $hashref = $obj->contexts()
660 Get a hashref of all active contexts keyed by hub id.
662 =item $arrayref = $obj->context_acquire_callbacks
664 Get all context acquire callbacks.
666 =item $arrayref = $obj->context_init_callbacks
668 Get all context init callbacks.
670 =item $arrayref = $obj->context_release_callbacks
672 Get all context release callbacks.
674 =item $obj->add_context_init_callback(sub { ... })
676 Add a context init callback. Subs are called every time a context is created. Subs
677 get the newly created context as their only argument.
679 =item $obj->add_context_release_callback(sub { ... })
681 Add a context release callback. Subs are called every time a context is released. Subs
682 get the released context as their only argument. These callbacks should not
683 call release on the context.
685 =item $obj->set_exit()
687 This is intended to be called in an C<END { ... }> block. This will look at
688 test state and set $?. This will also call any end callbacks, and wait on child
691 =item $obj->ipc_enable_shm()
693 Turn on SHM for IPC (if possible)
695 =item $shm_id = $obj->ipc_shm_id()
697 If SHM is enabled for IPC this will be the shm_id for it.
699 =item $shm_size = $obj->ipc_shm_size()
701 If SHM is enabled for IPC this will be the size of it.
703 =item $shm_last_val = $obj->ipc_shm_last()
705 If SHM is enabled for IPC this will return the last SHM value seen.
707 =item $obj->set_ipc_pending($val)
709 use the IPC SHM to tell other processes and threads there is a pending event.
710 C<$val> should be a unique value no other thread/process will generate.
712 B<Note:> This will also make the current process see a pending event. It does
713 not set C<ipc_shm_last()>, this is important because doing so could hide a
716 =item $pending = $obj->get_ipc_pending()
718 This returns -1 if SHM is not enabled for IPC.
720 This returns 0 if the SHM value matches the last known value, which means there
721 are no pending events.
723 This returns 1 if the SHM value has changed, which means there are probably
726 When 1 is returned this will set C<< $obj->ipc_shm_last() >>.
728 =item $timeout = $obj->ipc_timeout;
730 =item $obj->set_ipc_timeout($timeout);
732 How long to wait for child processes and threads before aborting.
734 =item $drivers = $obj->ipc_drivers
736 Get the list of IPC drivers.
738 =item $obj->add_ipc_driver($DRIVER_CLASS)
740 Add an IPC driver to the list. The most recently added IPC driver will become
741 the global one during initialization. If a driver is added after initialization
742 has occurred a warning will be generated:
744 "IPC driver $driver loaded too late to be used as the global ipc driver"
746 =item $bool = $obj->ipc_polling
748 Check if polling is enabled.
750 =item $obj->enable_ipc_polling
752 Turn on polling. This will cull events from other processes and threads every
753 time a context is created.
755 =item $obj->disable_ipc_polling
757 Turn off IPC polling.
759 =item $bool = $obj->no_wait
761 =item $bool = $obj->set_no_wait($bool)
763 Get/Set no_wait. This option is used to turn off process/thread waiting at exit.
765 =item $arrayref = $obj->exit_callbacks
767 Get the exit callbacks.
769 =item $obj->add_exit_callback(sub { ... })
771 Add an exit callback. This callback will be called by C<set_exit()>.
773 =item $bool = $obj->finalized
775 Check if the object is finalized. Finalization happens when either C<ipc()>,
776 C<stack()>, or C<format()> are called on the object. Once finalization happens
777 these fields are considered unchangeable (not enforced here, enforced by
780 =item $ipc = $obj->ipc
782 Get the one true IPC instance.
784 =item $stack = $obj->stack
786 Get the one true hub stack.
788 =item $formatter = $obj->formatter
790 Get the global formatter. By default this is the C<'Test2::Formatter::TAP'>
791 package. This could be any package that implements the C<write()> method. This
792 can also be an instantiated object.
794 =item $bool = $obj->formatter_set()
796 Check if a formatter has been set.
798 =item $obj->add_formatter($class)
800 =item $obj->add_formatter($obj)
802 Add a formatter. The most recently added formatter will become the global one
803 during initialization. If a formatter is added after initialization has occurred
804 a warning will be generated:
806 "Formatter $formatter loaded too late to be used as the global formatter"
812 The source code repository for Test2 can be found at
813 F<http://github.com/Test-More/test-more/>.
819 =item Chad Granum E<lt>exodist@cpan.orgE<gt>
827 =item Chad Granum E<lt>exodist@cpan.orgE<gt>
833 Copyright 2017 Chad Granum E<lt>exodist@cpan.orgE<gt>.
835 This program is free software; you can redistribute it and/or
836 modify it under the same terms as Perl itself.
838 See F<http://dev.perl.org/licenses/>