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