1package Test2::API::Instance; 2use strict; 3use warnings; 4 5our $VERSION = '1.302133'; 6 7 8our @CARP_NOT = qw/Test2::API Test2::API::Instance Test2::IPC::Driver Test2::Formatter/; 9use Carp qw/confess carp/; 10use Scalar::Util qw/reftype/; 11 12use Test2::Util qw/get_tid USE_THREADS CAN_FORK pkg_to_file try CAN_SIGSYS/; 13 14use Test2::EventFacet::Trace(); 15use Test2::API::Stack(); 16 17use Test2::Util::HashBase qw{ 18 _pid _tid 19 no_wait 20 finalized loaded 21 ipc stack formatter 22 contexts 23 24 add_uuid_via 25 26 -preload 27 28 ipc_disabled 29 ipc_shm_size 30 ipc_shm_last 31 ipc_shm_id 32 ipc_polling 33 ipc_drivers 34 ipc_timeout 35 formatters 36 37 exit_callbacks 38 post_load_callbacks 39 context_acquire_callbacks 40 context_init_callbacks 41 context_release_callbacks 42 pre_subtest_callbacks 43}; 44 45sub DEFAULT_IPC_TIMEOUT() { 30 } 46 47sub pid { $_[0]->{+_PID} } 48sub tid { $_[0]->{+_TID} } 49 50# Wrap around the getters that should call _finalize. 51BEGIN { 52 for my $finalizer (IPC, FORMATTER) { 53 my $orig = __PACKAGE__->can($finalizer); 54 my $new = sub { 55 my $self = shift; 56 $self->_finalize unless $self->{+FINALIZED}; 57 $self->$orig; 58 }; 59 60 no strict 'refs'; 61 no warnings 'redefine'; 62 *{$finalizer} = $new; 63 } 64} 65 66sub has_ipc { !!$_[0]->{+IPC} } 67 68sub import { 69 my $class = shift; 70 return unless @_; 71 my ($ref) = @_; 72 $$ref = $class->new; 73} 74 75sub init { $_[0]->reset } 76 77sub start_preload { 78 my $self = shift; 79 80 confess "preload cannot be started, Test2::API has already been initialized" 81 if $self->{+FINALIZED} || $self->{+LOADED}; 82 83 return $self->{+PRELOAD} = 1; 84} 85 86sub stop_preload { 87 my $self = shift; 88 89 return 0 unless $self->{+PRELOAD}; 90 $self->{+PRELOAD} = 0; 91 92 $self->post_preload_reset(); 93 94 return 1; 95} 96 97sub post_preload_reset { 98 my $self = shift; 99 100 delete $self->{+_PID}; 101 delete $self->{+_TID}; 102 103 $self->{+ADD_UUID_VIA} = undef unless exists $self->{+ADD_UUID_VIA}; 104 105 $self->{+CONTEXTS} = {}; 106 107 $self->{+FORMATTERS} = []; 108 109 $self->{+FINALIZED} = undef; 110 $self->{+IPC} = undef; 111 $self->{+IPC_DISABLED} = $ENV{T2_NO_IPC} ? 1 : 0; 112 113 $self->{+IPC_TIMEOUT} = DEFAULT_IPC_TIMEOUT() unless defined $self->{+IPC_TIMEOUT}; 114 115 $self->{+LOADED} = 0; 116 117 $self->{+STACK} ||= Test2::API::Stack->new; 118} 119 120sub reset { 121 my $self = shift; 122 123 delete $self->{+_PID}; 124 delete $self->{+_TID}; 125 126 $self->{+ADD_UUID_VIA} = undef; 127 128 $self->{+CONTEXTS} = {}; 129 130 $self->{+IPC_DRIVERS} = []; 131 $self->{+IPC_POLLING} = undef; 132 133 $self->{+FORMATTERS} = []; 134 $self->{+FORMATTER} = undef; 135 136 $self->{+FINALIZED} = undef; 137 $self->{+IPC} = undef; 138 $self->{+IPC_DISABLED} = $ENV{T2_NO_IPC} ? 1 : 0; 139 140 $self->{+IPC_TIMEOUT} = DEFAULT_IPC_TIMEOUT() unless defined $self->{+IPC_TIMEOUT}; 141 142 $self->{+NO_WAIT} = 0; 143 $self->{+LOADED} = 0; 144 145 $self->{+EXIT_CALLBACKS} = []; 146 $self->{+POST_LOAD_CALLBACKS} = []; 147 $self->{+CONTEXT_ACQUIRE_CALLBACKS} = []; 148 $self->{+CONTEXT_INIT_CALLBACKS} = []; 149 $self->{+CONTEXT_RELEASE_CALLBACKS} = []; 150 $self->{+PRE_SUBTEST_CALLBACKS} = []; 151 152 $self->{+STACK} = Test2::API::Stack->new; 153} 154 155sub _finalize { 156 my $self = shift; 157 my ($caller) = @_; 158 $caller ||= [caller(1)]; 159 160 confess "Attempt to initialize Test2::API during preload" 161 if $self->{+PRELOAD}; 162 163 $self->{+FINALIZED} = $caller; 164 165 $self->{+_PID} = $$ unless defined $self->{+_PID}; 166 $self->{+_TID} = get_tid() unless defined $self->{+_TID}; 167 168 unless ($self->{+FORMATTER}) { 169 my ($formatter, $source); 170 if ($ENV{T2_FORMATTER}) { 171 $source = "set by the 'T2_FORMATTER' environment variable"; 172 173 if ($ENV{T2_FORMATTER} =~ m/^(\+)?(.*)$/) { 174 $formatter = $1 ? $2 : "Test2::Formatter::$2" 175 } 176 else { 177 $formatter = ''; 178 } 179 } 180 elsif (@{$self->{+FORMATTERS}}) { 181 ($formatter) = @{$self->{+FORMATTERS}}; 182 $source = "Most recently added"; 183 } 184 else { 185 $formatter = 'Test2::Formatter::TAP'; 186 $source = 'default formatter'; 187 } 188 189 unless (ref($formatter) || $formatter->can('write')) { 190 my $file = pkg_to_file($formatter); 191 my ($ok, $err) = try { require $file }; 192 unless ($ok) { 193 my $line = "* COULD NOT LOAD FORMATTER '$formatter' ($source) *"; 194 my $border = '*' x length($line); 195 die "\n\n $border\n $line\n $border\n\n$err"; 196 } 197 } 198 199 $self->{+FORMATTER} = $formatter; 200 } 201 202 # Turn on IPC if threads are on, drivers are registered, or the Test2::IPC 203 # module is loaded. 204 return if $self->{+IPC_DISABLED}; 205 return unless USE_THREADS || $INC{'Test2/IPC.pm'} || @{$self->{+IPC_DRIVERS}}; 206 207 # Turn on polling by default, people expect it. 208 $self->enable_ipc_polling; 209 210 unless (@{$self->{+IPC_DRIVERS}}) { 211 my ($ok, $error) = try { require Test2::IPC::Driver::Files }; 212 die $error unless $ok; 213 push @{$self->{+IPC_DRIVERS}} => 'Test2::IPC::Driver::Files'; 214 } 215 216 for my $driver (@{$self->{+IPC_DRIVERS}}) { 217 next unless $driver->can('is_viable') && $driver->is_viable; 218 $self->{+IPC} = $driver->new or next; 219 $self->ipc_enable_shm if $self->{+IPC}->use_shm; 220 return; 221 } 222 223 die "IPC has been requested, but no viable drivers were found. Aborting...\n"; 224} 225 226sub formatter_set { $_[0]->{+FORMATTER} ? 1 : 0 } 227 228sub add_formatter { 229 my $self = shift; 230 my ($formatter) = @_; 231 unshift @{$self->{+FORMATTERS}} => $formatter; 232 233 return unless $self->{+FINALIZED}; 234 235 # Why is the @CARP_NOT entry not enough? 236 local %Carp::Internal = %Carp::Internal; 237 $Carp::Internal{'Test2::Formatter'} = 1; 238 239 carp "Formatter $formatter loaded too late to be used as the global formatter"; 240} 241 242sub add_context_acquire_callback { 243 my $self = shift; 244 my ($code) = @_; 245 246 my $rtype = reftype($code) || ""; 247 248 confess "Context-acquire callbacks must be coderefs" 249 unless $code && $rtype eq 'CODE'; 250 251 push @{$self->{+CONTEXT_ACQUIRE_CALLBACKS}} => $code; 252} 253 254sub add_context_init_callback { 255 my $self = shift; 256 my ($code) = @_; 257 258 my $rtype = reftype($code) || ""; 259 260 confess "Context-init callbacks must be coderefs" 261 unless $code && $rtype eq 'CODE'; 262 263 push @{$self->{+CONTEXT_INIT_CALLBACKS}} => $code; 264} 265 266sub add_context_release_callback { 267 my $self = shift; 268 my ($code) = @_; 269 270 my $rtype = reftype($code) || ""; 271 272 confess "Context-release callbacks must be coderefs" 273 unless $code && $rtype eq 'CODE'; 274 275 push @{$self->{+CONTEXT_RELEASE_CALLBACKS}} => $code; 276} 277 278sub add_post_load_callback { 279 my $self = shift; 280 my ($code) = @_; 281 282 my $rtype = reftype($code) || ""; 283 284 confess "Post-load callbacks must be coderefs" 285 unless $code && $rtype eq 'CODE'; 286 287 push @{$self->{+POST_LOAD_CALLBACKS}} => $code; 288 $code->() if $self->{+LOADED}; 289} 290 291sub add_pre_subtest_callback { 292 my $self = shift; 293 my ($code) = @_; 294 295 my $rtype = reftype($code) || ""; 296 297 confess "Pre-subtest callbacks must be coderefs" 298 unless $code && $rtype eq 'CODE'; 299 300 push @{$self->{+PRE_SUBTEST_CALLBACKS}} => $code; 301} 302 303sub load { 304 my $self = shift; 305 unless ($self->{+LOADED}) { 306 confess "Attempt to initialize Test2::API during preload" 307 if $self->{+PRELOAD}; 308 309 $self->{+_PID} = $$ unless defined $self->{+_PID}; 310 $self->{+_TID} = get_tid() unless defined $self->{+_TID}; 311 312 # This is for https://github.com/Test-More/test-more/issues/16 313 # and https://rt.perl.org/Public/Bug/Display.html?id=127774 314 # END blocks run in reverse order. This insures the END block is loaded 315 # as late as possible. It will not solve all cases, but it helps. 316 eval "END { Test2::API::test2_set_is_end() }; 1" or die $@; 317 318 $self->{+LOADED} = 1; 319 $_->() for @{$self->{+POST_LOAD_CALLBACKS}}; 320 } 321 return $self->{+LOADED}; 322} 323 324sub add_exit_callback { 325 my $self = shift; 326 my ($code) = @_; 327 my $rtype = reftype($code) || ""; 328 329 confess "End callbacks must be coderefs" 330 unless $code && $rtype eq 'CODE'; 331 332 push @{$self->{+EXIT_CALLBACKS}} => $code; 333} 334 335sub ipc_disable { 336 my $self = shift; 337 338 confess "Attempt to disable IPC after it has been initialized" 339 if $self->{+IPC}; 340 341 $self->{+IPC_DISABLED} = 1; 342} 343 344sub add_ipc_driver { 345 my $self = shift; 346 my ($driver) = @_; 347 unshift @{$self->{+IPC_DRIVERS}} => $driver; 348 349 return unless $self->{+FINALIZED}; 350 351 # Why is the @CARP_NOT entry not enough? 352 local %Carp::Internal = %Carp::Internal; 353 $Carp::Internal{'Test2::IPC::Driver'} = 1; 354 355 carp "IPC driver $driver loaded too late to be used as the global ipc driver"; 356} 357 358sub enable_ipc_polling { 359 my $self = shift; 360 361 $self->{+_PID} = $$ unless defined $self->{+_PID}; 362 $self->{+_TID} = get_tid() unless defined $self->{+_TID}; 363 364 $self->add_context_init_callback( 365 # This is called every time a context is created, it needs to be fast. 366 # $_[0] is a context object 367 sub { 368 return unless $self->{+IPC_POLLING}; 369 return $_[0]->{hub}->cull unless $self->{+IPC_SHM_ID}; 370 371 my $val; 372 if(shmread($self->{+IPC_SHM_ID}, $val, 0, $self->{+IPC_SHM_SIZE})) { 373 return if $val eq $self->{+IPC_SHM_LAST}; 374 $self->{+IPC_SHM_LAST} = $val; 375 } 376 else { 377 warn "SHM Read error: $!\n"; 378 } 379 380 $_[0]->{hub}->cull; 381 } 382 ) unless defined $self->ipc_polling; 383 384 $self->set_ipc_polling(1); 385} 386 387sub ipc_enable_shm { 388 my $self = shift; 389 390 return 1 if defined $self->{+IPC_SHM_ID}; 391 392 $self->{+_PID} = $$ unless defined $self->{+_PID}; 393 $self->{+_TID} = get_tid() unless defined $self->{+_TID}; 394 395 my ($ok, $err) = try { 396 # SysV IPC can be available but not enabled. 397 # 398 # In some systems (*BSD) accessing the SysV IPC APIs without 399 # them being enabled can cause a SIGSYS. We suppress the SIGSYS 400 # and then get ENOSYS from the calls. 401 local $SIG{SYS} = 'IGNORE' if CAN_SIGSYS; 402 403 require IPC::SysV; 404 405 my $ipc_key = IPC::SysV::IPC_PRIVATE(); 406 my $shm_size = $self->{+IPC}->can('shm_size') ? $self->{+IPC}->shm_size : 64; 407 my $shm_id = shmget($ipc_key, $shm_size, 0666) or die "Could not get shm: $!"; 408 409 my $initial = 'a' x $shm_size; 410 shmwrite($shm_id, $initial, 0, $shm_size) or die "Could not write to shm: $!"; 411 my $val; 412 shmread($shm_id, $val, 0, $shm_size) or die "Could not read from shm: $!"; 413 die "Read SHM value does not match the initial value ('$val' vs '$initial')" 414 unless $val eq $initial; 415 416 $self->{+IPC_SHM_SIZE} = $shm_size; 417 $self->{+IPC_SHM_ID} = $shm_id; 418 $self->{+IPC_SHM_LAST} = $initial; 419 }; 420 421 return $ok; 422} 423 424sub ipc_free_shm { 425 my $self = shift; 426 427 my $id = delete $self->{+IPC_SHM_ID}; 428 return unless defined $id; 429 430 shmctl($id, IPC::SysV::IPC_RMID(), 0); 431} 432 433sub get_ipc_pending { 434 my $self = shift; 435 return -1 unless defined $self->{+IPC_SHM_ID}; 436 my $val; 437 shmread($self->{+IPC_SHM_ID}, $val, 0, $self->{+IPC_SHM_SIZE}) or return -1; 438 return 0 if $val eq $self->{+IPC_SHM_LAST}; 439 $self->{+IPC_SHM_LAST} = $val; 440 return 1; 441} 442 443sub set_ipc_pending { 444 my $self = shift; 445 446 return undef unless defined $self->{+IPC_SHM_ID}; 447 448 my ($val) = @_; 449 450 confess "value is required for set_ipc_pending" 451 unless $val; 452 453 shmwrite($self->{+IPC_SHM_ID}, $val, 0, $self->{+IPC_SHM_SIZE}); 454} 455 456sub disable_ipc_polling { 457 my $self = shift; 458 return unless defined $self->{+IPC_POLLING}; 459 $self->{+IPC_POLLING} = 0; 460} 461 462sub _ipc_wait { 463 my ($timeout) = @_; 464 my $fail = 0; 465 466 $timeout = DEFAULT_IPC_TIMEOUT() unless defined $timeout; 467 468 my $ok = eval { 469 if (CAN_FORK) { 470 local $SIG{ALRM} = sub { die "Timeout waiting on child processes" }; 471 alarm $timeout; 472 473 while (1) { 474 my $pid = CORE::wait(); 475 my $err = $?; 476 last if $pid == -1; 477 next unless $err; 478 $fail++; 479 480 my $sig = $err & 127; 481 my $exit = $err >> 8; 482 warn "Process $pid did not exit cleanly (wstat: $err, exit: $exit, sig: $sig)\n"; 483 } 484 485 alarm 0; 486 } 487 488 if (USE_THREADS) { 489 my $start = time; 490 491 while (1) { 492 last unless threads->list(); 493 die "Timeout waiting on child thread" if time - $start >= $timeout; 494 sleep 1; 495 for my $t (threads->list) { 496 # threads older than 1.34 do not have this :-( 497 next if $t->can('is_joinable') && !$t->is_joinable; 498 $t->join; 499 # In older threads we cannot check if a thread had an error unless 500 # we control it and its return. 501 my $err = $t->can('error') ? $t->error : undef; 502 next unless $err; 503 my $tid = $t->tid(); 504 $fail++; 505 chomp($err); 506 warn "Thread $tid did not end cleanly: $err\n"; 507 } 508 } 509 } 510 511 1; 512 }; 513 my $error = $@; 514 515 return 0 if $ok && !$fail; 516 warn $error unless $ok; 517 return 255; 518} 519 520sub DESTROY { 521 my $self = shift; 522 523 return if $self->{+PRELOAD}; 524 525 return unless defined($self->{+_PID}) && $self->{+_PID} == $$; 526 return unless defined($self->{+_TID}) && $self->{+_TID} == get_tid(); 527 528 shmctl($self->{+IPC_SHM_ID}, IPC::SysV::IPC_RMID(), 0) 529 if defined $self->{+IPC_SHM_ID}; 530} 531 532sub set_exit { 533 my $self = shift; 534 535 return if $self->{+PRELOAD}; 536 537 my $exit = $?; 538 my $new_exit = $exit; 539 540 if ($INC{'Test/Builder.pm'} && $Test::Builder::VERSION ne $Test2::API::VERSION) { 541 print STDERR <<" EOT"; 542 543******************************************************************************** 544* * 545* Test::Builder -- Test2::API version mismatch detected * 546* * 547******************************************************************************** 548 Test2::API Version: $Test2::API::VERSION 549Test::Builder Version: $Test::Builder::VERSION 550 551This is not a supported configuration, you will have problems. 552 553 EOT 554 } 555 556 for my $ctx (values %{$self->{+CONTEXTS}}) { 557 next unless $ctx; 558 559 next if $ctx->_aborted && ${$ctx->_aborted}; 560 561 # Only worry about contexts in this PID 562 my $trace = $ctx->trace || next; 563 next unless $trace->pid && $trace->pid == $$; 564 565 # Do not worry about contexts that have no hub 566 my $hub = $ctx->hub || next; 567 568 # Do not worry if the state came to a sudden end. 569 next if $hub->bailed_out; 570 next if defined $hub->skip_reason; 571 572 # now we worry 573 $trace->alert("context object was never released! This means a testing tool is behaving very badly"); 574 575 $exit = 255; 576 $new_exit = 255; 577 } 578 579 if (!defined($self->{+_PID}) or !defined($self->{+_TID}) or $self->{+_PID} != $$ or $self->{+_TID} != get_tid()) { 580 $? = $exit; 581 return; 582 } 583 584 my @hubs = $self->{+STACK} ? $self->{+STACK}->all : (); 585 586 if (@hubs and $self->{+IPC} and !$self->{+NO_WAIT}) { 587 local $?; 588 my %seen; 589 for my $hub (reverse @hubs) { 590 my $ipc = $hub->ipc or next; 591 next if $seen{$ipc}++; 592 $ipc->waiting(); 593 } 594 595 my $ipc_exit = _ipc_wait($self->{+IPC_TIMEOUT}); 596 $new_exit ||= $ipc_exit; 597 } 598 599 # None of this is necessary if we never got a root hub 600 if(my $root = shift @hubs) { 601 my $trace = Test2::EventFacet::Trace->new( 602 frame => [__PACKAGE__, __FILE__, 0, __PACKAGE__ . '::END'], 603 detail => __PACKAGE__ . ' END Block finalization', 604 ); 605 my $ctx = Test2::API::Context->new( 606 trace => $trace, 607 hub => $root, 608 ); 609 610 if (@hubs) { 611 $ctx->diag("Test ended with extra hubs on the stack!"); 612 $new_exit = 255; 613 } 614 615 unless ($root->no_ending) { 616 local $?; 617 $root->finalize($trace) unless $root->ended; 618 $_->($ctx, $exit, \$new_exit) for @{$self->{+EXIT_CALLBACKS}}; 619 $new_exit ||= $root->failed; 620 $new_exit ||= 255 unless $root->is_passing; 621 } 622 } 623 624 $new_exit = 255 if $new_exit > 255; 625 626 if ($new_exit && eval { require Test2::API::Breakage; 1 }) { 627 my @warn = Test2::API::Breakage->report(); 628 629 if (@warn) { 630 print STDERR "\nYou have loaded versions of test modules known to have problems with Test2.\nThis could explain some test failures.\n"; 631 print STDERR "$_\n" for @warn; 632 print STDERR "\n"; 633 } 634 } 635 636 $? = $new_exit; 637} 638 6391; 640 641__END__ 642 643=pod 644 645=encoding UTF-8 646 647=head1 NAME 648 649Test2::API::Instance - Object used by Test2::API under the hood 650 651=head1 DESCRIPTION 652 653This object encapsulates the global shared state tracked by 654L<Test2>. A single global instance of this package is stored (and 655obscured) by the L<Test2::API> package. 656 657There is no reason to directly use this package. This package is documented for 658completeness. This package can change, or go away completely at any time. 659Directly using, or monkeypatching this package is not supported in any way 660shape or form. 661 662=head1 SYNOPSIS 663 664 use Test2::API::Instance; 665 666 my $obj = Test2::API::Instance->new; 667 668=over 4 669 670=item $pid = $obj->pid 671 672PID of this instance. 673 674=item $obj->tid 675 676Thread ID of this instance. 677 678=item $obj->reset() 679 680Reset the object to defaults. 681 682=item $obj->load() 683 684Set the internal state to loaded, and run and stored post-load callbacks. 685 686=item $bool = $obj->loaded 687 688Check if the state is set to loaded. 689 690=item $arrayref = $obj->post_load_callbacks 691 692Get the post-load callbacks. 693 694=item $obj->add_post_load_callback(sub { ... }) 695 696Add a post-load callback. If C<load()> has already been called then the callback will 697be immediately executed. If C<load()> has not been called then the callback will be 698stored and executed later when C<load()> is called. 699 700=item $hashref = $obj->contexts() 701 702Get a hashref of all active contexts keyed by hub id. 703 704=item $arrayref = $obj->context_acquire_callbacks 705 706Get all context acquire callbacks. 707 708=item $arrayref = $obj->context_init_callbacks 709 710Get all context init callbacks. 711 712=item $arrayref = $obj->context_release_callbacks 713 714Get all context release callbacks. 715 716=item $arrayref = $obj->pre_subtest_callbacks 717 718Get all pre-subtest callbacks. 719 720=item $obj->add_context_init_callback(sub { ... }) 721 722Add a context init callback. Subs are called every time a context is created. Subs 723get the newly created context as their only argument. 724 725=item $obj->add_context_release_callback(sub { ... }) 726 727Add a context release callback. Subs are called every time a context is released. Subs 728get the released context as their only argument. These callbacks should not 729call release on the context. 730 731=item $obj->add_pre_subtest_callback(sub { ... }) 732 733Add a pre-subtest callback. Subs are called every time a subtest is 734going to be run. Subs get the subtest name, coderef, and any 735arguments. 736 737=item $obj->set_exit() 738 739This is intended to be called in an C<END { ... }> block. This will look at 740test state and set $?. This will also call any end callbacks, and wait on child 741processes/threads. 742 743=item $obj->ipc_enable_shm() 744 745Turn on SHM for IPC (if possible) 746 747=item $shm_id = $obj->ipc_shm_id() 748 749If SHM is enabled for IPC this will be the shm_id for it. 750 751=item $shm_size = $obj->ipc_shm_size() 752 753If SHM is enabled for IPC this will be the size of it. 754 755=item $shm_last_val = $obj->ipc_shm_last() 756 757If SHM is enabled for IPC this will return the last SHM value seen. 758 759=item $obj->set_ipc_pending($val) 760 761use the IPC SHM to tell other processes and threads there is a pending event. 762C<$val> should be a unique value no other thread/process will generate. 763 764B<Note:> This will also make the current process see a pending event. It does 765not set C<ipc_shm_last()>, this is important because doing so could hide a 766previous change. 767 768=item $pending = $obj->get_ipc_pending() 769 770This returns -1 if SHM is not enabled for IPC. 771 772This returns 0 if the SHM value matches the last known value, which means there 773are no pending events. 774 775This returns 1 if the SHM value has changed, which means there are probably 776pending events. 777 778When 1 is returned this will set C<< $obj->ipc_shm_last() >>. 779 780=item $timeout = $obj->ipc_timeout; 781 782=item $obj->set_ipc_timeout($timeout); 783 784How long to wait for child processes and threads before aborting. 785 786=item $drivers = $obj->ipc_drivers 787 788Get the list of IPC drivers. 789 790=item $obj->add_ipc_driver($DRIVER_CLASS) 791 792Add an IPC driver to the list. The most recently added IPC driver will become 793the global one during initialization. If a driver is added after initialization 794has occurred a warning will be generated: 795 796 "IPC driver $driver loaded too late to be used as the global ipc driver" 797 798=item $bool = $obj->ipc_polling 799 800Check if polling is enabled. 801 802=item $obj->enable_ipc_polling 803 804Turn on polling. This will cull events from other processes and threads every 805time a context is created. 806 807=item $obj->disable_ipc_polling 808 809Turn off IPC polling. 810 811=item $bool = $obj->no_wait 812 813=item $bool = $obj->set_no_wait($bool) 814 815Get/Set no_wait. This option is used to turn off process/thread waiting at exit. 816 817=item $arrayref = $obj->exit_callbacks 818 819Get the exit callbacks. 820 821=item $obj->add_exit_callback(sub { ... }) 822 823Add an exit callback. This callback will be called by C<set_exit()>. 824 825=item $bool = $obj->finalized 826 827Check if the object is finalized. Finalization happens when either C<ipc()>, 828C<stack()>, or C<format()> are called on the object. Once finalization happens 829these fields are considered unchangeable (not enforced here, enforced by 830L<Test2>). 831 832=item $ipc = $obj->ipc 833 834Get the one true IPC instance. 835 836=item $obj->ipc_disable 837 838Turn IPC off 839 840=item $bool = $obj->ipc_disabled 841 842Check if IPC is disabled 843 844=item $stack = $obj->stack 845 846Get the one true hub stack. 847 848=item $formatter = $obj->formatter 849 850Get the global formatter. By default this is the C<'Test2::Formatter::TAP'> 851package. This could be any package that implements the C<write()> method. This 852can also be an instantiated object. 853 854=item $bool = $obj->formatter_set() 855 856Check if a formatter has been set. 857 858=item $obj->add_formatter($class) 859 860=item $obj->add_formatter($obj) 861 862Add a formatter. The most recently added formatter will become the global one 863during initialization. If a formatter is added after initialization has occurred 864a warning will be generated: 865 866 "Formatter $formatter loaded too late to be used as the global formatter" 867 868=item $obj->set_add_uuid_via(sub { ... }) 869 870=item $sub = $obj->add_uuid_via() 871 872This allows you to provide a UUID generator. If provided UUIDs will be attached 873to all events, hubs, and contexts. This is useful for storing, tracking, and 874linking these objects. 875 876The sub you provide should always return a unique identifier. Most things will 877expect a proper UUID string, however nothing in Test2::API enforces this. 878 879The sub will receive exactly 1 argument, the type of thing being tagged 880'context', 'hub', or 'event'. In the future additional things may be tagged, in 881which case new strings will be passed in. These are purely informative, you can 882(and usually should) ignore them. 883 884=back 885 886=head1 SOURCE 887 888The source code repository for Test2 can be found at 889F<http://github.com/Test-More/test-more/>. 890 891=head1 MAINTAINERS 892 893=over 4 894 895=item Chad Granum E<lt>exodist@cpan.orgE<gt> 896 897=back 898 899=head1 AUTHORS 900 901=over 4 902 903=item Chad Granum E<lt>exodist@cpan.orgE<gt> 904 905=back 906 907=head1 COPYRIGHT 908 909Copyright 2018 Chad Granum E<lt>exodist@cpan.orgE<gt>. 910 911This program is free software; you can redistribute it and/or 912modify it under the same terms as Perl itself. 913 914See F<http://dev.perl.org/licenses/> 915 916=cut 917