Profile of Test2/API.pm

← Index
NYTProf Performance Profile «line view»
For t/bug-md-11.t
Run on Fri Mar 8 13:27:24 2024
Reported on Fri Mar 8 13:30:23 2024

Filename | /home/micha/.plenv/versions/5.38.2/lib/perl5/site_perl/5.38.2/Test2/API.pm
Statements | Executed 341 statements in 3.95ms

Subroutines
Calls | P | F | Exclusive Time | Inclusive Time | Subroutine
--- | --- | --- | --- | --- | ---
1 | 1 | 1 | 1.99ms | 8.02ms | Test2::API::::BEGIN@51Test2::API::BEGIN@51
1 | 1 | 1 | 475µs | 631µs | Test2::API::::BEGIN@100Test2::API::BEGIN@100
1 | 1 | 1 | 456µs | 1.89ms | Test2::API::::BEGIN@5Test2::API::BEGIN@5
1 | 1 | 1 | 429µs | 660µs | Test2::API::::BEGIN@89Test2::API::BEGIN@89
1 | 1 | 1 | 419µs | 535µs | Test2::API::::BEGIN@95Test2::API::BEGIN@95
1 | 1 | 1 | 403µs | 5.20ms | Test2::API::::BEGIN@92Test2::API::BEGIN@92
1 | 1 | 1 | 397µs | 586µs | Test2::API::::BEGIN@88Test2::API::BEGIN@88
1 | 1 | 1 | 230µs | 333µs | Test2::API::::BEGIN@97Test2::API::BEGIN@97
1 | 1 | 1 | 224µs | 306µs | Test2::API::::BEGIN@99Test2::API::BEGIN@99
8 | 1 | 1 | 221µs | 400µs | Test2::API::::contextTest2::API::context
1 | 1 | 1 | 206µs | 296µs | Test2::API::::BEGIN@96Test2::API::BEGIN@96
1 | 1 | 1 | 202µs | 284µs | Test2::API::::BEGIN@93Test2::API::BEGIN@93
1 | 1 | 1 | 200µs | 281µs | Test2::API::::BEGIN@94Test2::API::BEGIN@94
1 | 1 | 1 | 176µs | 239µs | Test2::API::::BEGIN@98Test2::API::BEGIN@98
1 | 1 | 1 | 110µs | 145µs | Test2::API::::BEGIN@86Test2::API::BEGIN@86
3 | 3 | 3 | 31µs | 188µs | Test2::API::::test2_set_is_endTest2::API::test2_set_is_end
1 | 1 | 1 | 25µs | 25µs | Test2::API::::INITTest2::API::INIT
4 | 3 | 2 | 14µs | 18µs | Test2::API::::test2_in_preloadTest2::API::test2_in_preload
1 | 1 | 1 | 10µs | 12µs | Test2::API::::BEGIN@2Test2::API::BEGIN@2
3 | 3 | 1 | 7µs | 18µs | Test2::API::::releaseTest2::API::release
1 | 1 | 1 | 7µs | 7µs | Test2::API::::BEGIN@179Test2::API::BEGIN@179
1 | 1 | 1 | 7µs | 7µs | Test2::API::::BEGIN@8Test2::API::BEGIN@8
3 | 2 | 2 | 6µs | 491µs | Test2::API::::test2_loadTest2::API::test2_load
1 | 1 | 1 | 5µs | 27µs | Test2::API::::BEGIN@102Test2::API::BEGIN@102
1 | 1 | 1 | 5µs | 18µs | Test2::API::::BEGIN@71Test2::API::BEGIN@71
1 | 1 | 1 | 5µs | 6µs | Test2::API::::_context_release_callbacks_refTest2::API::_context_release_callbacks_ref
1 | 1 | 1 | 5µs | 8µs | Test2::API::::test2_formatter_addTest2::API::test2_formatter_add
1 | 1 | 1 | 5µs | 6µs | Test2::API::::test2_stackTest2::API::test2_stack
1 | 1 | 1 | 4µs | 18µs | Test2::API::::BEGIN@103Test2::API::BEGIN@103
1 | 1 | 1 | 4µs | 18µs | Test2::API::::BEGIN@6Test2::API::BEGIN@6
1 | 1 | 1 | 4µs | 14µs | Test2::API::::BEGIN@76Test2::API::BEGIN@76
1 | 1 | 1 | 4µs | 21µs | Test2::API::::BEGIN@3Test2::API::BEGIN@3
1 | 1 | 1 | 4µs | 18µs | Test2::API::::BEGIN@104Test2::API::BEGIN@104
1 | 1 | 1 | 4µs | 5µs | Test2::API::::test2_init_doneTest2::API::test2_init_done
1 | 1 | 1 | 3µs | 21µs | Test2::API::::test2_formatterTest2::API::test2_formatter
1 | 1 | 1 | 3µs | 3µs | Test2::API::::BEGIN@75Test2::API::BEGIN@75
1 | 1 | 1 | 3µs | 11µs | Test2::API::::test2_add_callback_post_loadTest2::API::test2_add_callback_post_load
1 | 1 | 1 | 2µs | 3µs | Test2::API::::_contexts_refTest2::API::_contexts_ref
1 | 1 | 1 | 2µs | 2µs | Test2::API::::BEGIN@90Test2::API::BEGIN@90
1 | 1 | 1 | 2µs | 5µs | Test2::API::::test2_add_callback_context_aquireTest2::API::test2_add_callback_context_aquire
1 | 1 | 1 | 2µs | 3µs | Test2::API::::test2_has_ipcTest2::API::test2_has_ipc
1 | 1 | 1 | 2µs | 4µs | Test2::API::::test2_add_callback_exitTest2::API::test2_add_callback_exit
1 | 1 | 1 | 2µs | 4µs | Test2::API::::test2_ipcTest2::API::test2_ipc
1 | 1 | 1 | 2µs | 2µs | Test2::API::::BEGIN@85Test2::API::BEGIN@85
2 | 2 | 2 | 2µs | 2µs | Test2::API::::_add_uuid_via_refTest2::API::_add_uuid_via_ref
1 | 1 | 1 | 1µs | 2µs | Test2::API::::test2_load_doneTest2::API::test2_load_done
1 | 1 | 1 | 700ns | 700ns | Test2::API::::test2_unset_is_endTest2::API::test2_unset_is_end
1 | 1 | 1 | 600ns | 600ns | Test2::API::::test2_stdoutTest2::API::test2_stdout
1 | 1 | 1 | 500ns | 500ns | Test2::API::::test2_stderrTest2::API::test2_stderr
0 | 0 | 0 | 0s | 0s | Test2::API::::CLONETest2::API::CLONE
0 | 0 | 0 | 0s | 0s | Test2::API::::__ANON__[:257]Test2::API::__ANON__[:257]
0 | 0 | 0 | 0s | 0s | Test2::API::::__ANON__[:613]Test2::API::__ANON__[:613]
0 | 0 | 0 | 0s | 0s | Test2::API::::__ANON__[:679]Test2::API::__ANON__[:679]
0 | 0 | 0 | 0s | 0s | Test2::API::::__ANON__[:698]Test2::API::__ANON__[:698]
0 | 0 | 0 | 0s | 0s | Test2::API::::_canon_errorTest2::API::_canon_error
0 | 0 | 0 | 0s | 0s | Test2::API::::_context_acquire_callbacks_refTest2::API::_context_acquire_callbacks_ref
0 | 0 | 0 | 0s | 0s | Test2::API::::_context_init_callbacks_refTest2::API::_context_init_callbacks_ref
0 | 0 | 0 | 0s | 0s | Test2::API::::_depth_errorTest2::API::_depth_error
0 | 0 | 0 | 0s | 0s | Test2::API::::_existing_errorTest2::API::_existing_error
0 | 0 | 0 | 0s | 0s | Test2::API::::_interceptTest2::API::_intercept
0 | 0 | 0 | 0s | 0s | Test2::API::::_set_ipcTest2::API::_set_ipc
0 | 0 | 0 | 0s | 0s | Test2::API::::context_doTest2::API::context_do
0 | 0 | 0 | 0s | 0s | Test2::API::::interceptTest2::API::intercept
0 | 0 | 0 | 0s | 0s | Test2::API::::intercept_deepTest2::API::intercept_deep
0 | 0 | 0 | 0s | 0s | Test2::API::::no_contextTest2::API::no_context
0 | 0 | 0 | 0s | 0s | Test2::API::::run_subtestTest2::API::run_subtest
0 | 0 | 0 | 0s | 0s | Test2::API::::test2_add_callback_context_acquireTest2::API::test2_add_callback_context_acquire
0 | 0 | 0 | 0s | 0s | Test2::API::::test2_add_callback_context_initTest2::API::test2_add_callback_context_init
0 | 0 | 0 | 0s | 0s | Test2::API::::test2_add_callback_context_releaseTest2::API::test2_add_callback_context_release
0 | 0 | 0 | 0s | 0s | Test2::API::::test2_add_callback_pre_subtestTest2::API::test2_add_callback_pre_subtest
0 | 0 | 0 | 0s | 0s | Test2::API::::test2_add_callback_testing_doneTest2::API::test2_add_callback_testing_done
0 | 0 | 0 | 0s | 0s | Test2::API::::test2_add_uuid_viaTest2::API::test2_add_uuid_via
0 | 0 | 0 | 0s | 0s | Test2::API::::test2_disable_trace_stampsTest2::API::test2_disable_trace_stamps
0 | 0 | 0 | 0s | 0s | Test2::API::::test2_enable_trace_stampsTest2::API::test2_enable_trace_stamps
0 | 0 | 0 | 0s | 0s | Test2::API::::test2_formatter_setTest2::API::test2_formatter_set
0 | 0 | 0 | 0s | 0s | Test2::API::::test2_formattersTest2::API::test2_formatters
0 | 0 | 0 | 0s | 0s | Test2::API::::test2_get_is_endTest2::API::test2_get_is_end
0 | 0 | 0 | 0s | 0s | Test2::API::::test2_ipc_add_driverTest2::API::test2_ipc_add_driver
0 | 0 | 0 | 0s | 0s | Test2::API::::test2_ipc_disableTest2::API::test2_ipc_disable
0 | 0 | 0 | 0s | 0s | Test2::API::::test2_ipc_disable_pollingTest2::API::test2_ipc_disable_polling
0 | 0 | 0 | 0s | 0s | Test2::API::::test2_ipc_disabledTest2::API::test2_ipc_disabled
0 | 0 | 0 | 0s | 0s | Test2::API::::test2_ipc_driversTest2::API::test2_ipc_drivers
0 | 0 | 0 | 0s | 0s | Test2::API::::test2_ipc_enable_pollingTest2::API::test2_ipc_enable_polling
0 | 0 | 0 | 0s | 0s | Test2::API::::test2_ipc_enable_shmTest2::API::test2_ipc_enable_shm
0 | 0 | 0 | 0s | 0s | Test2::API::::test2_ipc_get_pendingTest2::API::test2_ipc_get_pending
0 | 0 | 0 | 0s | 0s | Test2::API::::test2_ipc_get_timeoutTest2::API::test2_ipc_get_timeout
0 | 0 | 0 | 0s | 0s | Test2::API::::test2_ipc_pollingTest2::API::test2_ipc_polling
0 | 0 | 0 | 0s | 0s | Test2::API::::test2_ipc_set_pendingTest2::API::test2_ipc_set_pending
0 | 0 | 0 | 0s | 0s | Test2::API::::test2_ipc_set_timeoutTest2::API::test2_ipc_set_timeout
0 | 0 | 0 | 0s | 0s | Test2::API::::test2_ipc_wait_disableTest2::API::test2_ipc_wait_disable
0 | 0 | 0 | 0s | 0s | Test2::API::::test2_ipc_wait_enableTest2::API::test2_ipc_wait_enable
0 | 0 | 0 | 0s | 0s | Test2::API::::test2_ipc_wait_enabledTest2::API::test2_ipc_wait_enabled
0 | 0 | 0 | 0s | 0s | Test2::API::::test2_is_testing_doneTest2::API::test2_is_testing_done
0 | 0 | 0 | 0s | 0s | Test2::API::::test2_list_context_acquire_callbacksTest2::API::test2_list_context_acquire_callbacks
0 | 0 | 0 | 0s | 0s | Test2::API::::test2_list_context_aquire_callbacksTest2::API::test2_list_context_aquire_callbacks
0 | 0 | 0 | 0s | 0s | Test2::API::::test2_list_context_init_callbacksTest2::API::test2_list_context_init_callbacks
0 | 0 | 0 | 0s | 0s | Test2::API::::test2_list_context_release_callbacksTest2::API::test2_list_context_release_callbacks
0 | 0 | 0 | 0s | 0s | Test2::API::::test2_list_exit_callbacksTest2::API::test2_list_exit_callbacks
0 | 0 | 0 | 0s | 0s | Test2::API::::test2_list_post_load_callbacksTest2::API::test2_list_post_load_callbacks
0 | 0 | 0 | 0s | 0s | Test2::API::::test2_list_pre_subtest_callbacksTest2::API::test2_list_pre_subtest_callbacks
0 | 0 | 0 | 0s | 0s | Test2::API::::test2_no_waitTest2::API::test2_no_wait
0 | 0 | 0 | 0s | 0s | Test2::API::::test2_pidTest2::API::test2_pid
0 | 0 | 0 | 0s | 0s | Test2::API::::test2_post_preload_resetTest2::API::test2_post_preload_reset
0 | 0 | 0 | 0s | 0s | Test2::API::::test2_reset_ioTest2::API::test2_reset_io
0 | 0 | 0 | 0s | 0s | Test2::API::::test2_start_preloadTest2::API::test2_start_preload
0 | 0 | 0 | 0s | 0s | Test2::API::::test2_stop_preloadTest2::API::test2_stop_preload
0 | 0 | 0 | 0s | 0s | Test2::API::::test2_tidTest2::API::test2_tid
0 | 0 | 0 | 0s | 0s | Test2::API::::test2_trace_stamps_enabledTest2::API::test2_trace_stamps_enabled

Call graph for these subroutines as a Graphviz dot language file.

Line | State ments | Time on line | Calls | Time in subs | Code
--- | --- | --- | --- | --- | ---
1 |  |  |  |  | package Test2::API;
2 | 2 | 21µs | 2 | 14µs | # spent 12µs (10+2) within Test2::API::BEGIN@2 which was called: # once (10µs+2µs) by Test::Builder::BEGIN@18 at line 2 use strict; # spent 12µs making 1 call to Test2::API::BEGIN@2 # spent 2µs making 1 call to strict::import
3 | 2 | 18µs | 2 | 38µs | # spent 21µs (4+17) within Test2::API::BEGIN@3 which was called: # once (4µs+17µs) by Test::Builder::BEGIN@18 at line 3 use warnings; # spent 21µs making 1 call to Test2::API::BEGIN@3 # spent 17µs making 1 call to warnings::import
4 |  |  |  |  |
5 | 2 | 80µs | 2 | 3.18ms | # spent 1.89ms (456µs+1.44) within Test2::API::BEGIN@5 which was called: # once (456µs+1.44ms) by Test::Builder::BEGIN@18 at line 5 use Time::HiRes qw/time/; # spent 1.89ms making 1 call to Test2::API::BEGIN@5 # spent 1.28ms making 1 call to Time::HiRes::import
6 | 2 | 32µs | 2 | 33µs | # spent 18µs (4+14) within Test2::API::BEGIN@6 which was called: # once (4µs+14µs) by Test::Builder::BEGIN@18 at line 6 use Test2::Util qw/USE_THREADS/; # spent 18µs making 1 call to Test2::API::BEGIN@6 # spent 14µs making 1 call to Exporter::import
7 |  |  |  |  |
8 |  |  |  |  | # spent 7µs within Test2::API::BEGIN@8 which was called: # once (7µs+0s) by Test::Builder::BEGIN@18 at line 11 BEGIN {
9 | 1 | 3µs |  |  | $ENV{TEST_ACTIVE} ||= 1;
10 | 1 | 4µs |  |  | $ENV{TEST2_ACTIVE} = 1;
11 | 1 | 130µs | 1 | 7µs | } # spent 7µs making 1 call to Test2::API::BEGIN@8
12 |  |  |  |  |
13 | 1 | 400ns |  |  | our $VERSION = '1.302198';
14 |  |  |  |  |
15 |  |  |  |  |
16 | 1 | 200ns |  |  | my $INST;
17 | 1 | 100ns |  |  | my $ENDING = 0;
18 | 1 | 3µs |  |  | # spent 700ns within Test2::API::test2_unset_is_end which was called: # once (700ns+0s) by Test::Builder::reset at line 434 of Test/Builder.pm sub test2_unset_is_end { $ENDING = 0 }
19 |  |  |  |  | sub test2_get_is_end { $ENDING }
20 |  |  |  |  |
21 |  |  |  |  | # spent 188µs (31+156) within Test2::API::test2_set_is_end which was called 3 times, avg 63µs/call: # once (30µs+156µs) by Test2::API::END at line 1 of (eval 56)[Test2/API.pm:72] # once (800ns+0s) by Test2::API::Instance::END at line 1 of (eval 7)[Test2/API/Instance.pm:319] # once (400ns+0s) by Test2::API::END at line 55 sub test2_set_is_end {
22 | 3 | 500ns |  |  | my $before = $ENDING;
23 | 3 | 1µs |  |  | ($ENDING) = @_ ? @_ : (1);
24 |  |  |  |  |
25 |  |  |  |  | # Only send the event in a transition from false to true
26 | 3 | 2µs |  |  | return if $before;
27 | 1 | 200ns |  |  | return unless $ENDING;
28 |  |  |  |  |
29 | 1 | 200ns |  |  | return unless $INST;
30 | 1 | 2µs | 1 | 1µs | my $stack = $INST->stack or return; # spent 1µs making 1 call to Test2::Util::HashBase::__ANON__[Test2/Util/HashBase.pm:84]
31 | 1 | 2µs | 1 | 2µs | my $root = $stack->root or return; # spent 2µs making 1 call to Test2::API::Stack::root
32 |  |  |  |  |
33 | 1 | 800ns | 1 | 500ns | return unless $root->count; # spent 500ns making 1 call to Test2::Util::HashBase::__ANON__[Test2/Util/HashBase.pm:84]
34 |  |  |  |  |
35 | 1 | 3µs | 1 | 2µs | return unless $$ == $INST->pid; # spent 2µs making 1 call to Test2::API::Instance::pid
36 | 1 | 5µs | 2 | 2µs | return unless get_tid() == $INST->tid; # spent 1µs making 1 call to Test2::API::Instance::tid # spent 800ns making 1 call to Test2::Util::__ANON__
37 |  |  |  |  |
38 | 1 | 4µs | 1 | 12µs | my $trace = Test2::EventFacet::Trace->new( # spent 12µs making 1 call to Test2::Util::HashBase::_new
39 |  |  |  |  | frame => [__PACKAGE__, __FILE__, __LINE__, __PACKAGE__ . '::test2_set_is_end'],
40 |  |  |  |  | );
41 | 1 | 1µs | 1 | 21µs | my $ctx = Test2::API::Context->new( # spent 21µs making 1 call to Test2::Util::HashBase::_new
42 |  |  |  |  | trace => $trace,
43 |  |  |  |  | hub => $root,
44 |  |  |  |  | );
45 |  |  |  |  |
46 | 1 | 3µs | 1 | 116µs | $ctx->send_ev2(control => { phase => 'END', details => 'Transition to END phase' }); # spent 116µs making 1 call to Test2::API::Context::send_ev2
47 |  |  |  |  |
48 | 1 | 4µs | 1 | 700ns | 1; # spent 700ns making 1 call to Test2::API::Context::DESTROY
49 |  |  |  |  | }
50 |  |  |  |  |
51 | 2 | 137µs | 2 | 8.05ms | # spent 8.02ms (1.99+6.04) within Test2::API::BEGIN@51 which was called: # once (1.99ms+6.04ms) by Test::Builder::BEGIN@18 at line 51 use Test2::API::Instance(\$INST); # spent 8.02ms making 1 call to Test2::API::BEGIN@51 # spent 26µs making 1 call to Test2::API::Instance::import
52 |  |  |  |  |
53 |  |  |  |  | # Set the exit status
54 |  |  |  |  | END {
55 | 1 | 400ns | 1 | 400ns | test2_set_is_end(); # See gh #16 # spent 400ns making 1 call to Test2::API::test2_set_is_end
56 | 1 | 3µs | 1 | 113µs | $INST->set_exit(); # spent 113µs making 1 call to Test2::API::Instance::set_exit
57 |  |  |  |  | }
58 |  |  |  |  |
59 |  |  |  |  | sub CLONE {
60 |  |  |  |  | my $init = test2_init_done();
61 |  |  |  |  | my $load = test2_load_done();
62 |  |  |  |  |
63 |  |  |  |  | return if $init && $load;
64 |  |  |  |  |
65 |  |  |  |  | require Carp;
66 |  |  |  |  | Carp::croak "Test2 must be fully loaded before you start a new thread!\n";
67 |  |  |  |  | }
68 |  |  |  |  |
69 |  |  |  |  | # See gh #16
70 |  |  |  |  | {
71 | 2 | 34µs | 2 | 32µs | # spent 18µs (5+13) within Test2::API::BEGIN@71 which was called: # once (5µs+13µs) by Test::Builder::BEGIN@18 at line 71 no warnings; # spent 18µs making 1 call to Test2::API::BEGIN@71 # spent 13µs making 1 call to warnings::unimport
72 | 1 | 25µs |  |  | # spent 25µs within Test2::API::INIT which was called: # once (25µs+0s) by main::RUNTIME at line 0 of /home/micha/Projekt/spreadsheet-parsexlsx/t/bug-md-11.t INIT { eval 'END { test2_set_is_end() }; 1' or die $@ } # spent 4µs executing statements in string eval # includes 8µs spent executing 2 calls to 1 sub defined therein.
73 |  |  |  |  | }
74 |  |  |  |  |
75 | 1 | 400ns |  |  | # spent 3µs within Test2::API::BEGIN@75 which was called: # once (3µs+0s) by Test::Builder::BEGIN@18 at line 83 BEGIN {
76 | 2 | 45µs | 2 | 24µs | # spent 14µs (4+10) within Test2::API::BEGIN@76 which was called: # once (4µs+10µs) by Test::Builder::BEGIN@18 at line 76 no warnings 'once'; # spent 14µs making 1 call to Test2::API::BEGIN@76 # spent 10µs making 1 call to warnings::unimport
77 | 1 | 3µs |  |  | if($] ge '5.014' || $ENV{T2_CHECK_DEPTH} || $Test2::API::DO_DEPTH_CHECK) {
78 |  |  |  |  | *DO_DEPTH_CHECK = sub() { 1 };
79 |  |  |  |  | }
80 |  |  |  |  | else {
81 |  |  |  |  | *DO_DEPTH_CHECK = sub() { 0 };
82 |  |  |  |  | }
83 | 1 | 13µs | 1 | 3µs | } # spent 3µs making 1 call to Test2::API::BEGIN@75
84 |  |  |  |  |
85 | 2 | 10µs | 1 | 2µs | # spent 2µs within Test2::API::BEGIN@85 which was called: # once (2µs+0s) by Test::Builder::BEGIN@18 at line 85 use Test2::EventFacet::Trace(); # spent 2µs making 1 call to Test2::API::BEGIN@85
86 | 2 | 82µs | 1 | 145µs | # spent 145µs (110+34) within Test2::API::BEGIN@86 which was called: # once (110µs+34µs) by Test::Builder::BEGIN@18 at line 86 use Test2::Util::Trace(); # Legacy # spent 145µs making 1 call to Test2::API::BEGIN@86
87 |  |  |  |  |
88 | 2 | 68µs | 1 | 586µs | # spent 586µs (397+188) within Test2::API::BEGIN@88 which was called: # once (397µs+188µs) by Test::Builder::BEGIN@18 at line 88 use Test2::Hub::Subtest(); # spent 586µs making 1 call to Test2::API::BEGIN@88
89 | 2 | 68µs | 1 | 660µs | # spent 660µs (429+231) within Test2::API::BEGIN@89 which was called: # once (429µs+231µs) by Test::Builder::BEGIN@18 at line 89 use Test2::Hub::Interceptor(); # spent 660µs making 1 call to Test2::API::BEGIN@89
90 | 2 | 10µs | 1 | 2µs | # spent 2µs within Test2::API::BEGIN@90 which was called: # once (2µs+0s) by Test::Builder::BEGIN@18 at line 90 use Test2::Hub::Interceptor::Terminator(); # spent 2µs making 1 call to Test2::API::BEGIN@90
91 |  |  |  |  |
92 | 2 | 102µs | 1 | 5.20ms | # spent 5.20ms (403µs+4.80) within Test2::API::BEGIN@92 which was called: # once (403µs+4.80ms) by Test::Builder::BEGIN@18 at line 92 use Test2::Event::Ok(); # spent 5.20ms making 1 call to Test2::API::BEGIN@92
93 | 2 | 68µs | 1 | 284µs | # spent 284µs (202+83) within Test2::API::BEGIN@93 which was called: # once (202µs+83µs) by Test::Builder::BEGIN@18 at line 93 use Test2::Event::Diag(); # spent 284µs making 1 call to Test2::API::BEGIN@93
94 | 2 | 69µs | 1 | 281µs | # spent 281µs (200+81) within Test2::API::BEGIN@94 which was called: # once (200µs+81µs) by Test::Builder::BEGIN@18 at line 94 use Test2::Event::Note(); # spent 281µs making 1 call to Test2::API::BEGIN@94
95 | 2 | 74µs | 1 | 535µs | # spent 535µs (419+116) within Test2::API::BEGIN@95 which was called: # once (419µs+116µs) by Test::Builder::BEGIN@18 at line 95 use Test2::Event::Plan(); # spent 535µs making 1 call to Test2::API::BEGIN@95
96 | 2 | 68µs | 1 | 296µs | # spent 296µs (206+90) within Test2::API::BEGIN@96 which was called: # once (206µs+90µs) by Test::Builder::BEGIN@18 at line 96 use Test2::Event::Bail(); # spent 296µs making 1 call to Test2::API::BEGIN@96
97 | 2 | 72µs | 1 | 333µs | # spent 333µs (230+103) within Test2::API::BEGIN@97 which was called: # once (230µs+103µs) by Test::Builder::BEGIN@18 at line 97 use Test2::Event::Exception(); # spent 333µs making 1 call to Test2::API::BEGIN@97
98 | 2 | 68µs | 1 | 239µs | # spent 239µs (176+63) within Test2::API::BEGIN@98 which was called: # once (176µs+63µs) by Test::Builder::BEGIN@18 at line 98 use Test2::Event::Waiting(); # spent 239µs making 1 call to Test2::API::BEGIN@98
99 | 2 | 71µs | 1 | 306µs | # spent 306µs (224+83) within Test2::API::BEGIN@99 which was called: # once (224µs+83µs) by Test::Builder::BEGIN@18 at line 99 use Test2::Event::Skip(); # spent 306µs making 1 call to Test2::API::BEGIN@99
100 | 2 | 80µs | 1 | 631µs | # spent 631µs (475+156) within Test2::API::BEGIN@100 which was called: # once (475µs+156µs) by Test::Builder::BEGIN@18 at line 100 use Test2::Event::Subtest(); # spent 631µs making 1 call to Test2::API::BEGIN@100
101 |  |  |  |  |
102 | 2 | 19µs | 2 | 50µs | # spent 27µs (5+22) within Test2::API::BEGIN@102 which was called: # once (5µs+22µs) by Test::Builder::BEGIN@18 at line 102 use Carp qw/carp croak confess/; # spent 27µs making 1 call to Test2::API::BEGIN@102 # spent 22µs making 1 call to Exporter::import
103 | 2 | 16µs | 2 | 32µs | # spent 18µs (4+14) within Test2::API::BEGIN@103 which was called: # once (4µs+14µs) by Test::Builder::BEGIN@18 at line 103 use Scalar::Util qw/blessed weaken/; # spent 18µs making 1 call to Test2::API::BEGIN@103 # spent 14µs making 1 call to Exporter::import
104 | 2 | 73µs | 2 | 33µs | # spent 18µs (4+15) within Test2::API::BEGIN@104 which was called: # once (4µs+15µs) by Test::Builder::BEGIN@18 at line 104 use Test2::Util qw/get_tid clone_io pkg_to_file gen_uid/; # spent 18µs making 1 call to Test2::API::BEGIN@104 # spent 15µs making 1 call to Exporter::import
105 |  |  |  |  |
106 | 1 | 4µs |  |  | our @EXPORT_OK = qw{
107 |  |  |  |  | context release
108 |  |  |  |  | context_do
109 |  |  |  |  | no_context
110 |  |  |  |  | intercept intercept_deep
111 |  |  |  |  | run_subtest
112 |  |  |  |  |
113 |  |  |  |  | test2_init_done
114 |  |  |  |  | test2_load_done
115 |  |  |  |  | test2_load
116 |  |  |  |  | test2_start_preload
117 |  |  |  |  | test2_stop_preload
118 |  |  |  |  | test2_in_preload
119 |  |  |  |  | test2_is_testing_done
120 |  |  |  |  |
121 |  |  |  |  | test2_set_is_end
122 |  |  |  |  | test2_unset_is_end
123 |  |  |  |  | test2_get_is_end
124 |  |  |  |  |
125 |  |  |  |  | test2_pid
126 |  |  |  |  | test2_tid
127 |  |  |  |  | test2_stack
128 |  |  |  |  | test2_no_wait
129 |  |  |  |  | test2_ipc_wait_enable
130 |  |  |  |  | test2_ipc_wait_disable
131 |  |  |  |  | test2_ipc_wait_enabled
132 |  |  |  |  |
133 |  |  |  |  | test2_add_uuid_via
134 |  |  |  |  |
135 |  |  |  |  | test2_add_callback_testing_done
136 |  |  |  |  |
137 |  |  |  |  | test2_add_callback_context_aquire
138 |  |  |  |  | test2_add_callback_context_acquire
139 |  |  |  |  | test2_add_callback_context_init
140 |  |  |  |  | test2_add_callback_context_release
141 |  |  |  |  | test2_add_callback_exit
142 |  |  |  |  | test2_add_callback_post_load
143 |  |  |  |  | test2_add_callback_pre_subtest
144 |  |  |  |  | test2_list_context_aquire_callbacks
145 |  |  |  |  | test2_list_context_acquire_callbacks
146 |  |  |  |  | test2_list_context_init_callbacks
147 |  |  |  |  | test2_list_context_release_callbacks
148 |  |  |  |  | test2_list_exit_callbacks
149 |  |  |  |  | test2_list_post_load_callbacks
150 |  |  |  |  | test2_list_pre_subtest_callbacks
151 |  |  |  |  |
152 |  |  |  |  | test2_ipc
153 |  |  |  |  | test2_has_ipc
154 |  |  |  |  | test2_ipc_disable
155 |  |  |  |  | test2_ipc_disabled
156 |  |  |  |  | test2_ipc_drivers
157 |  |  |  |  | test2_ipc_add_driver
158 |  |  |  |  | test2_ipc_polling
159 |  |  |  |  | test2_ipc_disable_polling
160 |  |  |  |  | test2_ipc_enable_polling
161 |  |  |  |  | test2_ipc_get_pending
162 |  |  |  |  | test2_ipc_set_pending
163 |  |  |  |  | test2_ipc_get_timeout
164 |  |  |  |  | test2_ipc_set_timeout
165 |  |  |  |  |
166 |  |  |  |  | test2_formatter
167 |  |  |  |  | test2_formatters
168 |  |  |  |  | test2_formatter_add
169 |  |  |  |  | test2_formatter_set
170 |  |  |  |  |
171 |  |  |  |  | test2_stdout
172 |  |  |  |  | test2_stderr
173 |  |  |  |  | test2_reset_io
174 |  |  |  |  |
175 |  |  |  |  | test2_enable_trace_stamps
176 |  |  |  |  | test2_disable_trace_stamps
177 |  |  |  |  | test2_trace_stamps_enabled
178 |  |  |  |  | };
179 | 2 | 1.97ms | 1 | 7µs | # spent 7µs within Test2::API::BEGIN@179 which was called: # once (7µs+0s) by Test::Builder::BEGIN@18 at line 179 BEGIN { require Exporter; our @ISA = qw(Exporter) } # spent 7µs making 1 call to Test2::API::BEGIN@179
180 |  |  |  |  |
181 | 1 | 2µs | 1 | 2µs | my $STACK = $INST->stack; # spent 2µs making 1 call to Test2::Util::HashBase::__ANON__[Test2/Util/HashBase.pm:84]
182 | 1 | 600ns | 1 | 500ns | my $CONTEXTS = $INST->contexts; # spent 500ns making 1 call to Test2::Util::HashBase::__ANON__[Test2/Util/HashBase.pm:84]
183 | 1 | 400ns | 1 | 500ns | my $INIT_CBS = $INST->context_init_callbacks; # spent 500ns making 1 call to Test2::Util::HashBase::__ANON__[Test2/Util/HashBase.pm:84]
184 | 1 | 500ns | 1 | 400ns | my $ACQUIRE_CBS = $INST->context_acquire_callbacks; # spent 400ns making 1 call to Test2::Util::HashBase::__ANON__[Test2/Util/HashBase.pm:84]
185 |  |  |  |  |
186 | 1 | 1µs | 1 | 48µs | my $STDOUT = clone_io(\*STDOUT); # spent 48µs making 1 call to Test2::Util::clone_io
187 | 1 | 800ns | 1 | 22µs | my $STDERR = clone_io(\*STDERR); # spent 22µs making 1 call to Test2::Util::clone_io
188 | 1 | 1µs |  |  | # spent 600ns within Test2::API::test2_stdout which was called: # once (600ns+0s) by Test2::Formatter::TAP::_open_handles at line 57 of Test2/Formatter/TAP.pm sub test2_stdout { $STDOUT ||= clone_io(\*STDOUT) }
189 | 1 | 6µs |  |  | # spent 500ns within Test2::API::test2_stderr which was called: # once (500ns+0s) by Test2::Formatter::TAP::_open_handles at line 58 of Test2/Formatter/TAP.pm sub test2_stderr { $STDERR ||= clone_io(\*STDERR) }
190 |  |  |  |  |
191 |  |  |  |  | sub test2_post_preload_reset {
192 |  |  |  |  | test2_reset_io();
193 |  |  |  |  | $INST->post_preload_reset;
194 |  |  |  |  | }
195 |  |  |  |  |
196 |  |  |  |  | sub test2_reset_io {
197 |  |  |  |  | $STDOUT = clone_io(\*STDOUT);
198 |  |  |  |  | $STDERR = clone_io(\*STDERR);
199 |  |  |  |  | }
200 |  |  |  |  |
201 | 1 | 3µs | 1 | 1µs | # spent 5µs (4+1) within Test2::API::test2_init_done which was called: # once (4µs+1µs) by Test::Builder::BEGIN@20 at line 21 of Test/Builder.pm sub test2_init_done { $INST->finalized } # spent 1µs making 1 call to Test2::Util::HashBase::__ANON__[Test2/Util/HashBase.pm:84]
202 | 1 | 1µs | 1 | 700ns | # spent 2µs (1+700ns) within Test2::API::test2_load_done which was called: # once (1µs+700ns) by Test::Builder::BEGIN@20 at line 21 of Test/Builder.pm sub test2_load_done { $INST->loaded } # spent 700ns making 1 call to Test2::Util::HashBase::__ANON__[Test2/Util/HashBase.pm:84]
203 |  |  |  |  |
204 | 3 | 6µs | 3 | 485µs | # spent 491µs (6+485) within Test2::API::test2_load which was called 3 times, avg 164µs/call: # 2 times (3µs+483µs) by Test::Builder::Module::import at line 78 of Test/Builder/Module.pm, avg 243µs/call # once (3µs+2µs) by Test::Builder::INIT at line 134 of Test/Builder.pm sub test2_load { $INST->load } # spent 485µs making 3 calls to Test2::API::Instance::load, avg 162µs/call
205 |  |  |  |  | sub test2_start_preload { $ENV{T2_IN_PRELOAD} = 1; $INST->start_preload }
206 |  |  |  |  | sub test2_stop_preload { $ENV{T2_IN_PRELOAD} = 0; $INST->stop_preload }
207 | 4 | 10µs | 4 | 4µs | # spent 18µs (14+4) within Test2::API::test2_in_preload which was called 4 times, avg 5µs/call: # 2 times (8µs+2µs) by Test::Builder::Module::import at line 78 of Test/Builder/Module.pm, avg 5µs/call # once (4µs+2µs) by Test::Builder::INIT at line 134 of Test/Builder.pm # once (2µs+600ns) by Test::Builder::reset at line 443 of Test/Builder.pm sub test2_in_preload { $INST->preload } # spent 4µs making 4 calls to Test2::Util::HashBase::__ANON__[Test2/Util/HashBase.pm:84], avg 1µs/call
208 |  |  |  |  |
209 |  |  |  |  | sub test2_pid { $INST->pid }
210 |  |  |  |  | sub test2_tid { $INST->tid }
211 | 1 | 3µs | 1 | 1µs | # spent 6µs (5+1) within Test2::API::test2_stack which was called: # once (5µs+1µs) by Test::Builder::create at line 168 of Test/Builder.pm sub test2_stack { $INST->stack } # spent 1µs making 1 call to Test2::Util::HashBase::__ANON__[Test2/Util/HashBase.pm:84]
212 |  |  |  |  | sub test2_ipc_wait_enable { $INST->set_no_wait(0) }
213 |  |  |  |  | sub test2_ipc_wait_disable { $INST->set_no_wait(1) }
214 |  |  |  |  | sub test2_ipc_wait_enabled { !$INST->no_wait }
215 |  |  |  |  |
216 |  |  |  |  | sub test2_enable_trace_stamps { $INST->test2_enable_trace_stamps }
217 |  |  |  |  | sub test2_disable_trace_stamps { $INST->test2_disable_trace_stamps }
218 |  |  |  |  | sub test2_trace_stamps_enabled { $INST->test2_trace_stamps_enabled }
219 |  |  |  |  |
220 |  |  |  |  | sub test2_is_testing_done {
221 |  |  |  |  | # No instance? VERY DONE!
222 |  |  |  |  | return 1 unless $INST;
223 |  |  |  |  |
224 |  |  |  |  | # No stack? tests must be done, it is created pretty early
225 |  |  |  |  | my $stack = $INST->stack or return 1;
226 |  |  |  |  |
227 |  |  |  |  | # Nothing on the stack, no root hub yet, likely have not started testing
228 |  |  |  |  | return 0 unless @$stack;
229 |  |  |  |  |
230 |  |  |  |  | # Stack has a slot for the root hub (see above) but it is undefined, likely
231 |  |  |  |  | # garbage collected, test is done
232 |  |  |  |  | my $root_hub = $stack->[0] or return 1;
233 |  |  |  |  |
234 |  |  |  |  | # If the root hub is ended than testing is done.
235 |  |  |  |  | return 1 if $root_hub->ended;
236 |  |  |  |  |
237 |  |  |  |  | # Looks like we are still testing!
238 |  |  |  |  | return 0;
239 |  |  |  |  | }
240 |  |  |  |  |
241 |  |  |  |  | sub test2_no_wait {
242 |  |  |  |  | $INST->set_no_wait(@_) if @_;
243 |  |  |  |  | $INST->no_wait;
244 |  |  |  |  | }
245 |  |  |  |  |
246 |  |  |  |  | sub test2_add_callback_testing_done {
247 |  |  |  |  | my $cb = shift;
248 |  |  |  |  |
249 |  |  |  |  | test2_add_callback_post_load(sub {
250 |  |  |  |  | my $stack = test2_stack();
251 |  |  |  |  | $stack->top; # Ensure we have a hub
252 |  |  |  |  | my ($hub) = Test2::API::test2_stack->all;
253 |  |  |  |  |
254 |  |  |  |  | $hub->set_active(1);
255 |  |  |  |  |
256 |  |  |  |  | $hub->follow_up($cb);
257 |  |  |  |  | });
258 |  |  |  |  |
259 |  |  |  |  | return;
260 |  |  |  |  | }
261 |  |  |  |  |
262 |  |  |  |  | sub test2_add_callback_context_acquire { $INST->add_context_acquire_callback(@_) }
263 | 1 | 2µs | 1 | 3µs | # spent 5µs (2+3) within Test2::API::test2_add_callback_context_aquire which was called: # once (2µs+3µs) by Test::Builder::new at line 154 of Test/Builder.pm sub test2_add_callback_context_aquire { $INST->add_context_acquire_callback(@_) } # spent 3µs making 1 call to Test2::API::Instance::add_context_acquire_callback
264 |  |  |  |  | sub test2_add_callback_context_init { $INST->add_context_init_callback(@_) }
265 |  |  |  |  | sub test2_add_callback_context_release { $INST->add_context_release_callback(@_) }
266 | 1 | 2µs | 1 | 3µs | # spent 4µs (2+3) within Test2::API::test2_add_callback_exit which was called: # once (2µs+3µs) by Test::Builder::new at line 156 of Test/Builder.pm sub test2_add_callback_exit { $INST->add_exit_callback(@_) } # spent 3µs making 1 call to Test2::API::Instance::add_exit_callback
267 | 1 | 2µs | 1 | 8µs | # spent 11µs (3+8) within Test2::API::test2_add_callback_post_load which was called: # once (3µs+8µs) by Test::Builder::new at line 149 of Test/Builder.pm sub test2_add_callback_post_load { $INST->add_post_load_callback(@_) } # spent 8µs making 1 call to Test2::API::Instance::add_post_load_callback
268 |  |  |  |  | sub test2_add_callback_pre_subtest { $INST->add_pre_subtest_callback(@_) }
269 |  |  |  |  | sub test2_list_context_aquire_callbacks { @{$INST->context_acquire_callbacks} }
270 |  |  |  |  | sub test2_list_context_acquire_callbacks { @{$INST->context_acquire_callbacks} }
271 |  |  |  |  | sub test2_list_context_init_callbacks { @{$INST->context_init_callbacks} }
272 |  |  |  |  | sub test2_list_context_release_callbacks { @{$INST->context_release_callbacks} }
273 |  |  |  |  | sub test2_list_exit_callbacks { @{$INST->exit_callbacks} }
274 |  |  |  |  | sub test2_list_post_load_callbacks { @{$INST->post_load_callbacks} }
275 |  |  |  |  | sub test2_list_pre_subtest_callbacks { @{$INST->pre_subtest_callbacks} }
276 |  |  |  |  |
277 |  |  |  |  | sub test2_add_uuid_via {
278 |  |  |  |  | $INST->set_add_uuid_via(@_) if @_;
279 |  |  |  |  | $INST->add_uuid_via();
280 |  |  |  |  | }
281 |  |  |  |  |
282 | 1 | 2µs | 1 | 3µs | # spent 4µs (2+3) within Test2::API::test2_ipc which was called: # once (2µs+3µs) by Test2::API::Stack::new_hub at line 33 of Test2/API/Stack.pm sub test2_ipc { $INST->ipc } # spent 3µs making 1 call to Test2::API::Instance::__ANON__[Test2/API/Instance.pm:60]
283 | 1 | 2µs | 1 | 1µs | # spent 3µs (2+1) within Test2::API::test2_has_ipc which was called: # once (2µs+1µs) by Test::Builder::new at line 158 of Test/Builder.pm sub test2_has_ipc { $INST->has_ipc } # spent 1µs making 1 call to Test2::API::Instance::has_ipc
284 |  |  |  |  | sub test2_ipc_disable { $INST->ipc_disable }
285 |  |  |  |  | sub test2_ipc_disabled { $INST->ipc_disabled }
286 |  |  |  |  | sub test2_ipc_add_driver { $INST->add_ipc_driver(@_) }
287 |  |  |  |  | sub test2_ipc_drivers { @{$INST->ipc_drivers} }
288 |  |  |  |  | sub test2_ipc_polling { $INST->ipc_polling }
289 |  |  |  |  | sub test2_ipc_enable_polling { $INST->enable_ipc_polling }
290 |  |  |  |  | sub test2_ipc_disable_polling { $INST->disable_ipc_polling }
291 |  |  |  |  | sub test2_ipc_get_pending { $INST->get_ipc_pending }
292 |  |  |  |  | sub test2_ipc_set_pending { $INST->set_ipc_pending(@_) }
293 |  |  |  |  | sub test2_ipc_set_timeout { $INST->set_ipc_timeout(@_) }
294 |  |  |  |  | sub test2_ipc_get_timeout { $INST->ipc_timeout() }
295 |  |  |  |  | sub test2_ipc_enable_shm { 0 }
296 |  |  |  |  |
297 |  |  |  |  | # spent 21µs (3+18) within Test2::API::test2_formatter which was called: # once (3µs+18µs) by Test2::API::Stack::new_hub at line 31 of Test2/API/Stack.pm sub test2_formatter {
298 | 1 | 300ns |  |  | if ($ENV{T2_FORMATTER} && $ENV{T2_FORMATTER} =~ m/^(\+)?(.*)$/) {
299 |  |  |  |  | my $formatter = $1 ? $2 : "Test2::Formatter::$2";
300 |  |  |  |  | my $file = pkg_to_file($formatter);
301 |  |  |  |  | require $file;
302 |  |  |  |  | return $formatter;
303 |  |  |  |  | }
304 |  |  |  |  |
305 | 1 | 2µs | 1 | 18µs | return $INST->formatter; # spent 18µs making 1 call to Test2::API::Instance::__ANON__[Test2/API/Instance.pm:60]
306 |  |  |  |  | }
307 |  |  |  |  |
308 |  |  |  |  | sub test2_formatters { @{$INST->formatters} }
309 | 1 | 3µs | 1 | 3µs | # spent 8µs (5+3) within Test2::API::test2_formatter_add which was called: # once (5µs+3µs) by Test2::Formatter::import at line 14 of Test2/Formatter.pm sub test2_formatter_add { $INST->add_formatter(@_) } # spent 3µs making 1 call to Test2::API::Instance::add_formatter
310 |  |  |  |  | sub test2_formatter_set {
311 |  |  |  |  | my ($formatter) = @_;
312 |  |  |  |  | croak "No formatter specified" unless $formatter;
313 |  |  |  |  | croak "Global Formatter already set" if $INST->formatter_set;
314 |  |  |  |  | $INST->set_formatter($formatter);
315 |  |  |  |  | }
316 |  |  |  |  |
317 |  |  |  |  | # Private, for use in Test2::API::Context
318 | 1 | 2µs | 1 | 500ns | # spent 3µs (2+500ns) within Test2::API::_contexts_ref which was called: # once (2µs+500ns) by Test::Builder::BEGIN@18 at line 34 of Test2/API/Context.pm sub _contexts_ref { $INST->contexts } # spent 500ns making 1 call to Test2::Util::HashBase::__ANON__[Test2/Util/HashBase.pm:84]
319 |  |  |  |  | sub _context_acquire_callbacks_ref { $INST->context_acquire_callbacks }
320 |  |  |  |  | sub _context_init_callbacks_ref { $INST->context_init_callbacks }
321 | 1 | 3µs | 1 | 1µs | # spent 6µs (5+1) within Test2::API::_context_release_callbacks_ref which was called: # once (5µs+1µs) by Test::Builder::BEGIN@18 at line 33 of Test2/API/Context.pm sub _context_release_callbacks_ref { $INST->context_release_callbacks } # spent 1µs making 1 call to Test2::Util::HashBase::__ANON__[Test2/Util/HashBase.pm:84]
322 | 2 | 6µs |  |  | # spent 2µs within Test2::API::_add_uuid_via_ref which was called 2 times, avg 800ns/call: # once (900ns+0s) by Test::Builder::BEGIN@18 at line 370 # once (700ns+0s) by Test2::Hub::init at line 48 of Test2/Hub.pm sub _add_uuid_via_ref { \($INST->{Test2::API::Instance::ADD_UUID_VIA()}) }
323 |  |  |  |  |
324 |  |  |  |  | # Private, for use in Test2::IPC
325 |  |  |  |  | sub _set_ipc { $INST->set_ipc(@_) }
326 |  |  |  |  |
327 |  |  |  |  | sub context_do(&;@) {
328 |  |  |  |  | my $code = shift;
329 |  |  |  |  | my @args = @_;
330 |  |  |  |  |
331 |  |  |  |  | my $ctx = context(level => 1);
332 |  |  |  |  |
333 |  |  |  |  | my $want = wantarray;
334 |  |  |  |  |
335 |  |  |  |  | my @out;
336 |  |  |  |  | my $ok = eval {
337 |  |  |  |  | $want ? @out = $code->($ctx, @args) :
338 |  |  |  |  | defined($want) ? $out[0] = $code->($ctx, @args) :
339 |  |  |  |  | $code->($ctx, @args) ;
340 |  |  |  |  | 1;
341 |  |  |  |  | };
342 |  |  |  |  | my $err = $@;
343 |  |  |  |  |
344 |  |  |  |  | $ctx->release;
345 |  |  |  |  |
346 |  |  |  |  | die $err unless $ok;
347 |  |  |  |  |
348 |  |  |  |  | return @out if $want;
349 |  |  |  |  | return $out[0] if defined $want;
350 |  |  |  |  | return;
351 |  |  |  |  | }
352 |  |  |  |  |
353 |  |  |  |  | sub no_context(&;$) {
354 |  |  |  |  | my ($code, $hid) = @_;
355 |  |  |  |  | $hid ||= $STACK->top->hid;
356 |  |  |  |  |
357 |  |  |  |  | my $ctx = $CONTEXTS->{$hid};
358 |  |  |  |  | delete $CONTEXTS->{$hid};
359 |  |  |  |  | my $ok = eval { $code->(); 1 };
360 |  |  |  |  | my $err = $@;
361 |  |  |  |  |
362 |  |  |  |  | $CONTEXTS->{$hid} = $ctx;
363 |  |  |  |  | weaken($CONTEXTS->{$hid});
364 |  |  |  |  |
365 |  |  |  |  | die $err unless $ok;
366 |  |  |  |  |
367 |  |  |  |  | return;
368 |  |  |  |  | };
369 |  |  |  |  |
370 | 1 | 700ns | 1 | 900ns | my $UUID_VIA = _add_uuid_via_ref(); # spent 900ns making 1 call to Test2::API::_add_uuid_via_ref
371 |  |  |  |  | # spent 400µs (221+179) within Test2::API::context which was called 8 times, avg 50µs/call: # 8 times (221µs+179µs) by Test::Builder::ctx at line 193 of Test/Builder.pm, avg 50µs/call sub context {
372 |  |  |  |  | # We need to grab these before anything else to ensure they are not
373 |  |  |  |  | # changed.
374 | 8 | 12µs |  |  | my ($errno, $eval_error, $child_error, $extended_error) = (0 + $!, $@, $?, $^E);
375 |  |  |  |  |
376 | 8 | 14µs |  |  | my %params = (level => 0, wrapped => 0, @_);
377 |  |  |  |  |
378 |  |  |  |  | # If something is getting a context then the sync system needs to be
379 |  |  |  |  | # considered loaded...
380 | 8 | 2µs |  |  | $INST->load unless $INST->{loaded};
381 |  |  |  |  |
382 | 8 | 1µs |  |  | croak "context() called, but return value is ignored"
383 |  |  |  |  | unless defined wantarray;
384 |  |  |  |  |
385 | 8 | 3µs |  |  | my $stack = $params{stack} || $STACK;
386 | 8 | 5µs | 1 | 157µs | my $hub = $params{hub} || (@$stack ? $stack->[-1] : $stack->top); # spent 157µs making 1 call to Test2::API::Stack::top
387 |  |  |  |  |
388 |  |  |  |  | # Catch an edge case where we try to get context after the root hub has
389 |  |  |  |  | # been garbage collected resulting in a stack that has a single undef
390 |  |  |  |  | # hub
391 | 8 | 4µs |  |  | if (!($hub && $hub->{hid}) && !exists($params{hub}) && @$stack) {
392 |  |  |  |  | my $msg;
393 |  |  |  |  |
394 |  |  |  |  | if ($hub && !$hub->{hid}) {
395 |  |  |  |  | $msg = Carp::longmess("$hub has no hid! (did you attempt a testing event after done_testing?). You may be relying on a tool or plugin that was based off an old Test2 that did not require hids.");
396 |  |  |  |  | }
397 |  |  |  |  | else {
398 |  |  |  |  | $msg = Carp::longmess("Attempt to get Test2 context after testing has completed (did you attempt a testing event after done_testing?)");
399 |  |  |  |  | }
400 |  |  |  |  |
401 |  |  |  |  | # The error message is usually masked by the global destruction, so we have to print to STDER
402 |  |  |  |  | print STDERR $msg;
403 |  |  |  |  |
404 |  |  |  |  | # Make sure this is a failure, we are probably already in END, so set $? to change the exit code
405 |  |  |  |  | $? = 1;
406 |  |  |  |  |
407 |  |  |  |  | # Now we actually die to interrupt the program flow and avoid undefined his warnings
408 |  |  |  |  | die $msg;
409 |  |  |  |  | }
410 |  |  |  |  |
411 | 8 | 2µs |  |  | my $hid = $hub->{hid};
412 | 8 | 2µs |  |  | my $current = $CONTEXTS->{$hid};
413 |  |  |  |  |
414 | 8 | 11µs | 8 | 7µs | $_->(\%params) for @$ACQUIRE_CBS; # spent 7µs making 8 calls to Test::Builder::__ANON__[Test/Builder.pm:154], avg 862ns/call
415 | 8 | 2µs |  |  | map $_->(\%params), @{$hub->{_context_acquire}} if $hub->{_context_acquire};
416 |  |  |  |  |
417 |  |  |  |  | # This is for https://github.com/Test-More/test-more/issues/16
418 |  |  |  |  | # and https://rt.perl.org/Public/Bug/Display.html?id=127774
419 | 8 | 5µs |  |  | my $phase = ${^GLOBAL_PHASE} || 'NA';
420 | 8 | 4µs |  |  | my $end_phase = $ENDING || $phase eq 'END' || $phase eq 'DESTRUCT';
421 |  |  |  |  |
422 | 8 | 2µs |  |  | my $level = 1 + $params{level};
423 | 8 | 20µs |  |  | my ($pkg, $file, $line, $sub, @other) = $end_phase ? caller(0) : caller($level);
424 | 8 | 900ns |  |  | unless ($pkg || $end_phase) {
425 |  |  |  |  | confess "Could not find context at depth $level" unless $params{fudge};
426 |  |  |  |  | ($pkg, $file, $line, $sub, @other) = caller(--$level) while ($level >= 0 && !$pkg);
427 |  |  |  |  | }
428 |  |  |  |  |
429 | 8 | 1µs |  |  | my $depth = $level;
430 | 8 | 16µs |  |  | $depth++ while DO_DEPTH_CHECK && !$end_phase && (!$current || $depth <= $current->{_depth} + $params{wrapped}) && caller($depth + 1);
431 | 8 | 2µs |  |  | $depth -= $params{wrapped};
432 | 8 | 2µs |  |  | my $depth_ok = !DO_DEPTH_CHECK || $end_phase || !$current || $current->{_depth} < $depth;
433 |  |  |  |  |
434 | 8 | 1µs |  |  | if ($current && $params{on_release} && $depth_ok) {
435 |  |  |  |  | $current->{_on_release} ||= [];
436 |  |  |  |  | push @{$current->{_on_release}} => $params{on_release};
437 |  |  |  |  | }
438 |  |  |  |  |
439 |  |  |  |  | # I know this is ugly....
440 | 8 | 25µs |  |  | ($!, $@, $?, $^E) = ($errno, $eval_error, $child_error, $extended_error) and return bless(
441 |  |  |  |  | {
442 |  |  |  |  | %$current,
443 |  |  |  |  | _is_canon => undef,
444 |  |  |  |  | errno => $errno,
445 |  |  |  |  | eval_error => $eval_error,
446 |  |  |  |  | child_error => $child_error,
447 |  |  |  |  | _is_spawn => [$pkg, $file, $line, $sub],
448 |  |  |  |  | },
449 |  |  |  |  | 'Test2::API::Context'
450 |  |  |  |  | ) if $current && $depth_ok;
451 |  |  |  |  |
452 |  |  |  |  | # Handle error condition of bad level
453 | 4 | 700ns |  |  | if ($current) {
454 |  |  |  |  | unless (${$current->{_aborted}}) {
455 |  |  |  |  | _canon_error($current, [$pkg, $file, $line, $sub, $depth])
456 |  |  |  |  | unless $current->{_is_canon};
457 |  |  |  |  |
458 |  |  |  |  | _depth_error($current, [$pkg, $file, $line, $sub, $depth])
459 |  |  |  |  | unless $depth_ok;
460 |  |  |  |  | }
461 |  |  |  |  |
462 |  |  |  |  | $current->release if $current->{_is_canon};
463 |  |  |  |  |
464 |  |  |  |  | delete $CONTEXTS->{$hid};
465 |  |  |  |  | }
466 |  |  |  |  |
467 |  |  |  |  | # Directly bless the object here, calling new is a noticeable performance
468 |  |  |  |  | # hit with how often this needs to be called.
469 |  |  |  |  | my $trace = bless(
470 |  |  |  |  | {
471 |  |  |  |  | frame => [$pkg, $file, $line, $sub],
472 |  |  |  |  | pid => $$,
473 |  |  |  |  | tid => get_tid(),
474 |  |  |  |  | cid => gen_uid(),
475 |  |  |  |  | hid => $hid,
476 |  |  |  |  | nested => $hub->{nested},
477 |  |  |  |  | buffered => $hub->{buffered},
478 |  |  |  |  |
479 |  |  |  |  | full_caller => [$pkg, $file, $line, $sub, @other],
480 |  |  |  |  |
481 |  |  |  |  | $INST->{trace_stamps} ? (stamp => time()) : (),
482 |  |  |  |  |
483 |  |  |  |  | $$UUID_VIA ? (
484 |  |  |  |  | huuid => $hub->{uuid},
485 | 4 | 28µs | 4 | 10µs | uuid => ${$UUID_VIA}->('context'), # spent 10µs making 4 calls to Test2::Util::gen_uid, avg 2µs/call
486 |  |  |  |  | ) : (),
487 |  |  |  |  | },
488 |  |  |  |  | 'Test2::EventFacet::Trace'
489 |  |  |  |  | );
490 |  |  |  |  |
491 |  |  |  |  | # Directly bless the object here, calling new is a noticeable performance
492 |  |  |  |  | # hit with how often this needs to be called.
493 | 4 | 700ns |  |  | my $aborted = 0;
494 |  |  |  |  | $current = bless(
495 |  |  |  |  | {
496 |  |  |  |  | _aborted => \$aborted,
497 |  |  |  |  | stack => $stack,
498 |  |  |  |  | hub => $hub,
499 |  |  |  |  | trace => $trace,
500 |  |  |  |  | _is_canon => 1,
501 |  |  |  |  | _depth => $depth,
502 |  |  |  |  | errno => $errno,
503 |  |  |  |  | eval_error => $eval_error,
504 |  |  |  |  | child_error => $child_error,
505 | 4 | 11µs |  |  | $params{on_release} ? (_on_release => [$params{on_release}]) : (),
506 |  |  |  |  | },
507 |  |  |  |  | 'Test2::API::Context'
508 |  |  |  |  | );
509 |  |  |  |  |
510 | 4 | 2µs |  |  | $CONTEXTS->{$hid} = $current;
511 | 4 | 19µs | 4 | 5µs | weaken($CONTEXTS->{$hid}); # spent 5µs making 4 calls to Scalar::Util::weaken, avg 1µs/call
512 |  |  |  |  |
513 | 4 | 2µs |  |  | $_->($current) for @$INIT_CBS;
514 | 4 | 1µs |  |  | map $_->($current), @{$hub->{_context_init}} if $hub->{_context_init};
515 |  |  |  |  |
516 | 4 | 900ns |  |  | $params{on_init}->($current) if $params{on_init};
517 |  |  |  |  |
518 | 4 | 7µs |  |  | ($!, $@, $?, $^E) = ($errno, $eval_error, $child_error, $extended_error);
519 |  |  |  |  |
520 | 4 | 9µs |  |  | return $current;
521 |  |  |  |  | }
522 |  |  |  |  |
523 |  |  |  |  | sub _depth_error {
524 |  |  |  |  | _existing_error(@_, <<" EOT");
525 |  |  |  |  | context() was called to retrieve an existing context, however the existing
526 |  |  |  |  | context was created in a stack frame at the same, or deeper level. This usually
527 |  |  |  |  | means that a tool failed to release the context when it was finished.
528 |  |  |  |  | EOT
529 |  |  |  |  | }
530 |  |  |  |  |
531 |  |  |  |  | sub _canon_error {
532 |  |  |  |  | _existing_error(@_, <<" EOT");
533 |  |  |  |  | context() was called to retrieve an existing context, however the existing
534 |  |  |  |  | context has an invalid internal state (!_canon_count). This should not normally
535 |  |  |  |  | happen unless something is mucking about with internals...
536 |  |  |  |  | EOT
537 |  |  |  |  | }
538 |  |  |  |  |
539 |  |  |  |  | sub _existing_error {
540 |  |  |  |  | my ($ctx, $details, $msg) = @_;
541 |  |  |  |  | my ($pkg, $file, $line, $sub, $depth) = @$details;
542 |  |  |  |  |
543 |  |  |  |  | my $oldframe = $ctx->{trace}->frame;
544 |  |  |  |  | my $olddepth = $ctx->{_depth};
545 |  |  |  |  |
546 |  |  |  |  | # Older versions of Carp do not export longmess() function, so it needs to be called with package name
547 |  |  |  |  | my $mess = Carp::longmess();
548 |  |  |  |  |
549 |  |  |  |  | warn <<" EOT";
550 |  |  |  |  | $msg
551 |  |  |  |  | Old context details:
552 |  |  |  |  | File: $oldframe->[1]
553 |  |  |  |  | Line: $oldframe->[2]
554 |  |  |  |  | Tool: $oldframe->[3]
555 |  |  |  |  | Depth: $olddepth
556 |  |  |  |  |
557 |  |  |  |  | New context details:
558 |  |  |  |  | File: $file
559 |  |  |  |  | Line: $line
560 |  |  |  |  | Tool: $sub
561 |  |  |  |  | Depth: $depth
562 |  |  |  |  |
563 |  |  |  |  | Trace: $mess
564 |  |  |  |  |
565 |  |  |  |  | Removing the old context and creating a new one...
566 |  |  |  |  | EOT
567 |  |  |  |  | }
568 |  |  |  |  |
569 |  |  |  |  | # spent 18µs (7+10) within Test2::API::release which was called 3 times, avg 6µs/call: # once (2µs+5µs) by Test::Builder::done_testing at line 620 of Test/Builder.pm # once (3µs+3µs) by Test::Builder::current_test at line 1464 of Test/Builder.pm # once (2µs+2µs) by Test::Builder::use_numbers at line 1229 of Test/Builder.pm sub release($;$) {
570 | 3 | 2µs | 3 | 10µs | $_[0]->release; # spent 10µs making 3 calls to Test2::API::Context::release, avg 3µs/call
571 | 3 | 4µs |  |  | return $_[1];
572 |  |  |  |  | }
573 |  |  |  |  |
574 |  |  |  |  | sub intercept(&) {
575 |  |  |  |  | my $code = shift;
576 |  |  |  |  | my $ctx = context();
577 |  |  |  |  |
578 |  |  |  |  | my $events = _intercept($code, deep => 0);
579 |  |  |  |  |
580 |  |  |  |  | $ctx->release;
581 |  |  |  |  |
582 |  |  |  |  | return $events;
583 |  |  |  |  | }
584 |  |  |  |  |
585 |  |  |  |  | sub intercept_deep(&) {
586 |  |  |  |  | my $code = shift;
587 |  |  |  |  | my $ctx = context();
588 |  |  |  |  |
589 |  |  |  |  | my $events = _intercept($code, deep => 1);
590 |  |  |  |  |
591 |  |  |  |  | $ctx->release;
592 |  |  |  |  |
593 |  |  |  |  | return $events;
594 |  |  |  |  | }
595 |  |  |  |  |
596 |  |  |  |  | sub _intercept {
597 |  |  |  |  | my $code = shift;
598 |  |  |  |  | my %params = @_;
599 |  |  |  |  | my $ctx = context();
600 |  |  |  |  |
601 |  |  |  |  | my $ipc;
602 |  |  |  |  | if (my $global_ipc = test2_ipc()) {
603 |  |  |  |  | my $driver = blessed($global_ipc);
604 |  |  |  |  | $ipc = $driver->new;
605 |  |  |  |  | }
606 |  |  |  |  |
607 |  |  |  |  | my $hub = Test2::Hub::Interceptor->new(
608 |  |  |  |  | ipc => $ipc,
609 |  |  |  |  | no_ending => 1,
610 |  |  |  |  | );
611 |  |  |  |  |
612 |  |  |  |  | my @events;
613 |  |  |  |  | $hub->listen(sub { push @events => $_[1] }, inherit => $params{deep});
614 |  |  |  |  |
615 |  |  |  |  | $ctx->stack->top; # Make sure there is a top hub before we begin.
616 |  |  |  |  | $ctx->stack->push($hub);
617 |  |  |  |  |
618 |  |  |  |  | my $trace = $ctx->trace;
619 |  |  |  |  | my $state = {};
620 |  |  |  |  | $hub->clean_inherited(trace => $trace, state => $state);
621 |  |  |  |  |
622 |  |  |  |  | my ($ok, $err) = (1, undef);
623 |  |  |  |  | T2_SUBTEST_WRAPPER: {
624 |  |  |  |  | # Do not use 'try' cause it localizes __DIE__
625 |  |  |  |  | $ok = eval { $code->(hub => $hub, context => $ctx->snapshot); 1 };
626 |  |  |  |  | $err = $@;
627 |  |  |  |  |
628 |  |  |  |  | # They might have done 'BEGIN { skip_all => "whatever" }'
629 |  |  |  |  | if (!$ok && $err =~ m/Label not found for "last T2_SUBTEST_WRAPPER"/ || (blessed($err) && $err->isa('Test2::Hub::Interceptor::Terminator'))) {
630 |  |  |  |  | $ok = 1;
631 |  |  |  |  | $err = undef;
632 |  |  |  |  | }
633 |  |  |  |  | }
634 |  |  |  |  |
635 |  |  |  |  | $hub->cull;
636 |  |  |  |  | $ctx->stack->pop($hub);
637 |  |  |  |  |
638 |  |  |  |  | $hub->restore_inherited(trace => $trace, state => $state);
639 |  |  |  |  |
640 |  |  |  |  | $ctx->release;
641 |  |  |  |  |
642 |  |  |  |  | die $err unless $ok;
643 |  |  |  |  |
644 |  |  |  |  | $hub->finalize($trace, 1)
645 |  |  |  |  | if $ok
646 |  |  |  |  | && !$hub->no_ending
647 |  |  |  |  | && !$hub->ended;
648 |  |  |  |  |
649 |  |  |  |  | require Test2::API::InterceptResult;
650 |  |  |  |  | return Test2::API::InterceptResult->new_from_ref(\@events);
651 |  |  |  |  | }
652 |  |  |  |  |
653 |  |  |  |  | sub run_subtest {
654 |  |  |  |  | my ($name, $code, $params, @args) = @_;
655 |  |  |  |  |
656 |  |  |  |  | $_->($name,$code,@args)
657 |  |  |  |  | for Test2::API::test2_list_pre_subtest_callbacks();
658 |  |  |  |  |
659 |  |  |  |  | $params = {buffered => $params} unless ref $params;
660 |  |  |  |  | my $inherit_trace = delete $params->{inherit_trace};
661 |  |  |  |  |
662 |  |  |  |  | my $ctx = context();
663 |  |  |  |  |
664 |  |  |  |  | my $parent = $ctx->hub;
665 |  |  |  |  |
666 |  |  |  |  | # If a parent is buffered then the child must be as well.
667 |  |  |  |  | my $buffered = $params->{buffered} || $parent->{buffered};
668 |  |  |  |  |
669 |  |  |  |  | $ctx->note($name) unless $buffered;
670 |  |  |  |  |
671 |  |  |  |  | my $stack = $ctx->stack || $STACK;
672 |  |  |  |  | my $hub = $stack->new_hub(
673 |  |  |  |  | class => 'Test2::Hub::Subtest',
674 |  |  |  |  | %$params,
675 |  |  |  |  | buffered => $buffered,
676 |  |  |  |  | );
677 |  |  |  |  |
678 |  |  |  |  | my @events;
679 |  |  |  |  | $hub->listen(sub { push @events => $_[1] });
680 |  |  |  |  |
681 |  |  |  |  | if ($buffered) {
682 |  |  |  |  | if (my $format = $hub->format) {
683 |  |  |  |  | my $hide = $format->can('hide_buffered') ? $format->hide_buffered : 1;
684 |  |  |  |  | $hub->format(undef) if $hide;
685 |  |  |  |  | }
686 |  |  |  |  | }
687 |  |  |  |  |
688 |  |  |  |  | if ($inherit_trace) {
689 |  |  |  |  | my $orig = $code;
690 |  |  |  |  | $code = sub {
691 |  |  |  |  | my $base_trace = $ctx->trace;
692 |  |  |  |  | my $trace = $base_trace->snapshot(nested => 1 + $base_trace->nested);
693 |  |  |  |  | my $st_ctx = Test2::API::Context->new(
694 |  |  |  |  | trace => $trace,
695 |  |  |  |  | hub => $hub,
696 |  |  |  |  | );
697 |  |  |  |  | $st_ctx->do_in_context($orig, @args);
698 |  |  |  |  | };
699 |  |  |  |  | }
700 |  |  |  |  |
701 |  |  |  |  | my $start_stamp = time;
702 |  |  |  |  |
703 |  |  |  |  | my ($ok, $err, $finished);
704 |  |  |  |  | T2_SUBTEST_WRAPPER: {
705 |  |  |  |  | # Do not use 'try' cause it localizes __DIE__
706 |  |  |  |  | $ok = eval { $code->(@args); 1 };
707 |  |  |  |  | $err = $@;
708 |  |  |  |  |
709 |  |  |  |  | # They might have done 'BEGIN { skip_all => "whatever" }'
710 |  |  |  |  | if (!$ok && $err =~ m/Label not found for "last T2_SUBTEST_WRAPPER"/ || (blessed($err) && blessed($err) eq 'Test::Builder::Exception')) {
711 |  |  |  |  | $ok = undef;
712 |  |  |  |  | $err = undef;
713 |  |  |  |  | }
714 |  |  |  |  | else {
715 |  |  |  |  | $finished = 1;
716 |  |  |  |  | }
717 |  |  |  |  | }
718 |  |  |  |  |
719 |  |  |  |  | my $stop_stamp = time;
720 |  |  |  |  |
721 |  |  |  |  | if ($params->{no_fork}) {
722 |  |  |  |  | if ($$ != $ctx->trace->pid) {
723 |  |  |  |  | warn $ok ? "Forked inside subtest, but subtest never finished!\n" : $err;
724 |  |  |  |  | exit 255;
725 |  |  |  |  | }
726 |  |  |  |  |
727 |  |  |  |  | if (get_tid() != $ctx->trace->tid) {
728 |  |  |  |  | warn $ok ? "Started new thread inside subtest, but thread never finished!\n" : $err;
729 |  |  |  |  | exit 255;
730 |  |  |  |  | }
731 |  |  |  |  | }
732 |  |  |  |  | elsif (!$parent->is_local && !$parent->ipc) {
733 |  |  |  |  | warn $ok ? "A new process or thread was started inside subtest, but IPC is not enabled!\n" : $err;
734 |  |  |  |  | exit 255;
735 |  |  |  |  | }
736 |  |  |  |  |
737 |  |  |  |  | $stack->pop($hub);
738 |  |  |  |  |
739 |  |  |  |  | my $trace = $ctx->trace;
740 |  |  |  |  |
741 |  |  |  |  | my $bailed = $hub->bailed_out;
742 |  |  |  |  |
743 |  |  |  |  | if (!$finished) {
744 |  |  |  |  | if ($bailed && !$buffered) {
745 |  |  |  |  | $ctx->bail($bailed->reason);
746 |  |  |  |  | }
747 |  |  |  |  | elsif ($bailed && $buffered) {
748 |  |  |  |  | $ok = 1;
749 |  |  |  |  | }
750 |  |  |  |  | else {
751 |  |  |  |  | my $code = $hub->exit_code;
752 |  |  |  |  | $ok = !$code;
753 |  |  |  |  | $err = "Subtest ended with exit code $code" if $code;
754 |  |  |  |  | }
755 |  |  |  |  | }
756 |  |  |  |  |
757 |  |  |  |  | $hub->finalize($trace->snapshot(huuid => $hub->uuid, hid => $hub->hid, nested => $hub->nested, buffered => $buffered), 1)
758 |  |  |  |  | if $ok
759 |  |  |  |  | && !$hub->no_ending
760 |  |  |  |  | && !$hub->ended;
761 |  |  |  |  |
762 |  |  |  |  | my $pass = $ok && $hub->is_passing;
763 |  |  |  |  | my $e = $ctx->build_event(
764 |  |  |  |  | 'Subtest',
765 |  |  |  |  | pass => $pass,
766 |  |  |  |  | name => $name,
767 |  |  |  |  | subtest_id => $hub->id,
768 |  |  |  |  | subtest_uuid => $hub->uuid,
769 |  |  |  |  | buffered => $buffered,
770 |  |  |  |  | subevents => \@events,
771 |  |  |  |  | start_stamp => $start_stamp,
772 |  |  |  |  | stop_stamp => $stop_stamp,
773 |  |  |  |  | );
774 |  |  |  |  |
775 |  |  |  |  | my $plan_ok = $hub->check_plan;
776 |  |  |  |  |
777 |  |  |  |  | $ctx->hub->send($e);
778 |  |  |  |  |
779 |  |  |  |  | $ctx->failure_diag($e) unless $e->pass;
780 |  |  |  |  |
781 |  |  |  |  | $ctx->diag("Caught exception in subtest: $err") unless $ok;
782 |  |  |  |  |
783 |  |  |  |  | $ctx->diag("Bad subtest plan, expected " . $hub->plan . " but ran " . $hub->count)
784 |  |  |  |  | if defined($plan_ok) && !$plan_ok;
785 |  |  |  |  |
786 |  |  |  |  | $ctx->bail($bailed->reason) if $bailed && $buffered;
787 |  |  |  |  |
788 |  |  |  |  | $ctx->release;
789 |  |  |  |  | return $pass;
790 |  |  |  |  | }
791 |  |  |  |  |
792 |  |  |  |  | # There is a use-cycle between API and API/Context. Context needs to use some
793 |  |  |  |  | # API functions as the package is compiling. Test2::API::context() needs
794 |  |  |  |  | # Test2::API::Context to be loaded, but we cannot 'require' the module there as
795 |  |  |  |  | # it causes a very noticeable performance impact with how often context() is
796 |  |  |  |  | # called.
797 | 1 | 82µs |  |  | require Test2::API::Context;
798 |  |  |  |  |
799 | 1 | 6µs |  |  | 1;
800 |  |  |  |  |
801 |  |  |  |  | __END__