Profile of Test2/Hub.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/Hub.pm
Statements | Executed 221 statements in 2.09ms

Subroutines
Calls | P | F | Exclusive Time | Inclusive Time | Subroutine
--- | --- | --- | --- | --- | ---
1 | 1 | 1 | 364µs | 463µs | Test2::Hub::::BEGIN@14Test2::Hub::BEGIN@14
3 | 1 | 1 | 45µs | 257µs | Test2::Hub::::processTest2::Hub::process
3 | 3 | 3 | 42µs | 332µs | Test2::Hub::::sendTest2::Hub::send
1 | 1 | 1 | 32µs | 186µs | Test2::Hub::::finalizeTest2::Hub::finalize
3 | 3 | 3 | 13µs | 16µs | Test2::Hub::::is_passingTest2::Hub::is_passing
1 | 1 | 1 | 10µs | 11µs | Test2::Hub::::BEGIN@2Test2::Hub::BEGIN@2
1 | 1 | 1 | 9µs | 62µs | Test2::Hub::::BEGIN@12Test2::Hub::BEGIN@12
1 | 1 | 1 | 9µs | 13µs | Test2::Hub::::initTest2::Hub::init
6 | 6 | 2 | 9µs | 10µs | Test2::Hub::::planTest2::Hub::plan
1 | 1 | 1 | 6µs | 301µs | Test2::Hub::::BEGIN@15Test2::Hub::BEGIN@15
5 | 4 | 2 | 5µs | 5µs | Test2::Hub::::formatTest2::Hub::format
1 | 1 | 1 | 4µs | 4µs | Test2::Hub::::pre_filterTest2::Hub::pre_filter
1 | 1 | 1 | 4µs | 26µs | Test2::Hub::::BEGIN@8Test2::Hub::BEGIN@8
1 | 1 | 1 | 4µs | 30µs | Test2::Hub::::BEGIN@9Test2::Hub::BEGIN@9
1 | 1 | 1 | 3µs | 13µs | Test2::Hub::::BEGIN@11Test2::Hub::BEGIN@11
1 | 1 | 1 | 3µs | 20µs | Test2::Hub::::BEGIN@3Test2::Hub::BEGIN@3
1 | 1 | 1 | 2µs | 2µs | Test2::Hub::::cullTest2::Hub::cull
1 | 1 | 1 | 900ns | 900ns | Test2::Hub::::is_subtestTest2::Hub::is_subtest
0 | 0 | 0 | 0s | 0s | Test2::Hub::::DESTROYTest2::Hub::DESTROY
0 | 0 | 0 | 0s | 0s | Test2::Hub::::_tb_resetTest2::Hub::_tb_reset
0 | 0 | 0 | 0s | 0s | Test2::Hub::::add_context_acquireTest2::Hub::add_context_acquire
0 | 0 | 0 | 0s | 0s | Test2::Hub::::add_context_initTest2::Hub::add_context_init
0 | 0 | 0 | 0s | 0s | Test2::Hub::::add_context_releaseTest2::Hub::add_context_release
0 | 0 | 0 | 0s | 0s | Test2::Hub::::check_planTest2::Hub::check_plan
0 | 0 | 0 | 0s | 0s | Test2::Hub::::filterTest2::Hub::filter
0 | 0 | 0 | 0s | 0s | Test2::Hub::::follow_upTest2::Hub::follow_up
0 | 0 | 0 | 0s | 0s | Test2::Hub::::inheritTest2::Hub::inherit
0 | 0 | 0 | 0s | 0s | Test2::Hub::::is_localTest2::Hub::is_local
0 | 0 | 0 | 0s | 0s | Test2::Hub::::listenTest2::Hub::listen
0 | 0 | 0 | 0s | 0s | Test2::Hub::::pre_unfilterTest2::Hub::pre_unfilter
0 | 0 | 0 | 0s | 0s | Test2::Hub::::remove_context_acquireTest2::Hub::remove_context_acquire
0 | 0 | 0 | 0s | 0s | Test2::Hub::::remove_context_initTest2::Hub::remove_context_init
0 | 0 | 0 | 0s | 0s | Test2::Hub::::remove_context_releaseTest2::Hub::remove_context_release
0 | 0 | 0 | 0s | 0s | Test2::Hub::::reset_stateTest2::Hub::reset_state
0 | 0 | 0 | 0s | 0s | Test2::Hub::::terminateTest2::Hub::terminate
0 | 0 | 0 | 0s | 0s | Test2::Hub::::unfilterTest2::Hub::unfilter
0 | 0 | 0 | 0s | 0s | Test2::Hub::::unlistenTest2::Hub::unlisten

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::Hub;
2 | 2 | 22µs | 2 | 13µs | # spent 11µs (10+1) within Test2::Hub::BEGIN@2 which was called: # once (10µs+1µs) by Test2::API::Stack::BEGIN@8 at line 2 use strict; # spent 11µs making 1 call to Test2::Hub::BEGIN@2 # spent 2µs making 1 call to strict::import
3 | 2 | 24µs | 2 | 36µs | # spent 20µs (3+16) within Test2::Hub::BEGIN@3 which was called: # once (3µs+16µs) by Test2::API::Stack::BEGIN@8 at line 3 use warnings; # spent 20µs making 1 call to Test2::Hub::BEGIN@3 # spent 16µs making 1 call to warnings::import
4 |  |  |  |  |
5 | 1 | 300ns |  |  | our $VERSION = '1.302198';
6 |  |  |  |  |
7 |  |  |  |  |
8 | 2 | 21µs | 2 | 49µs | # spent 26µs (4+23) within Test2::Hub::BEGIN@8 which was called: # once (4µs+23µs) by Test2::API::Stack::BEGIN@8 at line 8 use Carp qw/carp croak confess/; # spent 26µs making 1 call to Test2::Hub::BEGIN@8 # spent 23µs making 1 call to Exporter::import
9 | 2 | 16µs | 2 | 56µs | # spent 30µs (4+26) within Test2::Hub::BEGIN@9 which was called: # once (4µs+26µs) by Test2::API::Stack::BEGIN@8 at line 9 use Test2::Util qw/get_tid gen_uid/; # spent 30µs making 1 call to Test2::Hub::BEGIN@9 # spent 26µs making 1 call to Exporter::import
10 |  |  |  |  |
11 | 2 | 13µs | 2 | 23µs | # spent 13µs (3+10) within Test2::Hub::BEGIN@11 which was called: # once (3µs+10µs) by Test2::API::Stack::BEGIN@8 at line 11 use Scalar::Util qw/weaken/; # spent 13µs making 1 call to Test2::Hub::BEGIN@11 # spent 10µs making 1 call to Exporter::import
12 | 2 | 18µs | 2 | 66µs | # spent 62µs (9+53) within Test2::Hub::BEGIN@12 which was called: # once (9µs+53µs) by Test2::API::Stack::BEGIN@8 at line 12 use List::Util qw/first/; # spent 62µs making 1 call to Test2::Hub::BEGIN@12 # spent 4µs making 1 call to List::Util::import
13 |  |  |  |  |
14 | 2 | 102µs | 2 | 505µs | # spent 463µs (364+99) within Test2::Hub::BEGIN@14 which was called: # once (364µs+99µs) by Test2::API::Stack::BEGIN@8 at line 14 use Test2::Util::ExternalMeta qw/meta get_meta set_meta delete_meta/; # spent 463µs making 1 call to Test2::Hub::BEGIN@14 # spent 43µs making 1 call to Exporter::import
15 | 1 | 3µs | 1 | 295µs | # spent 301µs (6+295) within Test2::Hub::BEGIN@15 which was called: # once (6µs+295µs) by Test2::API::Stack::BEGIN@8 at line 37 use Test2::Util::HashBase qw{ # spent 295µs making 1 call to Test2::Util::HashBase::import
16 |  |  |  |  | pid tid hid ipc
17 |  |  |  |  | nested buffered
18 |  |  |  |  | no_ending
19 |  |  |  |  | _filters
20 |  |  |  |  | _pre_filters
21 |  |  |  |  | _listeners
22 |  |  |  |  | _follow_ups
23 |  |  |  |  | _formatter
24 |  |  |  |  | _context_acquire
25 |  |  |  |  | _context_init
26 |  |  |  |  | _context_release
27 |  |  |  |  |
28 |  |  |  |  | uuid
29 |  |  |  |  | active
30 |  |  |  |  | count
31 |  |  |  |  | failed
32 |  |  |  |  | ended
33 |  |  |  |  | bailed_out
34 |  |  |  |  | _passing
35 |  |  |  |  | _plan
36 |  |  |  |  | skip_reason
37 | 1 | 1.70ms | 1 | 301µs | }; # spent 301µs making 1 call to Test2::Hub::BEGIN@15
38 |  |  |  |  |
39 | 1 | 200ns |  |  | my $UUID_VIA;
40 |  |  |  |  |
41 |  |  |  |  | # spent 13µs (9+4) within Test2::Hub::init which was called: # once (9µs+4µs) by Test2::Util::HashBase::_new at line 155 of Test2/Util/HashBase.pm sub init {
42 | 1 | 100ns |  |  | my $self = shift;
43 |  |  |  |  |
44 | 1 | 2µs |  |  | $self->{+PID} = $$;
45 | 1 | 300ns |  |  | $self->{+TID} = get_tid();
46 | 1 | 1µs | 1 | 3µs | $self->{+HID} = gen_uid(); # spent 3µs making 1 call to Test2::Util::gen_uid
47 |  |  |  |  |
48 | 1 | 700ns | 1 | 700ns | $UUID_VIA ||= Test2::API::_add_uuid_via_ref(); # spent 700ns making 1 call to Test2::API::_add_uuid_via_ref
49 | 1 | 300ns |  |  | $self->{+UUID} = ${$UUID_VIA}->('hub') if $$UUID_VIA;
50 |  |  |  |  |
51 | 1 | 500ns |  |  | $self->{+NESTED} = 0 unless defined $self->{+NESTED};
52 | 1 | 400ns |  |  | $self->{+BUFFERED} = 0 unless defined $self->{+BUFFERED};
53 |  |  |  |  |
54 | 1 | 200ns |  |  | $self->{+COUNT} = 0;
55 | 1 | 200ns |  |  | $self->{+FAILED} = 0;
56 | 1 | 700ns |  |  | $self->{+_PASSING} = 1;
57 |  |  |  |  |
58 | 1 | 400ns |  |  | if (my $formatter = delete $self->{formatter}) {
59 |  |  |  |  | $self->format($formatter);
60 |  |  |  |  | }
61 |  |  |  |  |
62 | 1 | 2µs |  |  | if (my $ipc = $self->{+IPC}) {
63 |  |  |  |  | $ipc->add_hub($self->{+HID});
64 |  |  |  |  | }
65 |  |  |  |  | }
66 |  |  |  |  |
67 | 1 | 2µs |  |  | # spent 900ns within Test2::Hub::is_subtest which was called: # once (900ns+0s) by Test2::Hub::finalize at line 461 sub is_subtest { 0 }
68 |  |  |  |  |
69 |  |  |  |  | sub _tb_reset {
70 |  |  |  |  | my $self = shift;
71 |  |  |  |  |
72 |  |  |  |  | # Nothing to do
73 |  |  |  |  | return if $self->{+PID} == $$ && $self->{+TID} == get_tid();
74 |  |  |  |  |
75 |  |  |  |  | $self->{+PID} = $$;
76 |  |  |  |  | $self->{+TID} = get_tid();
77 |  |  |  |  | $self->{+HID} = gen_uid();
78 |  |  |  |  |
79 |  |  |  |  | if (my $ipc = $self->{+IPC}) {
80 |  |  |  |  | $ipc->add_hub($self->{+HID});
81 |  |  |  |  | }
82 |  |  |  |  | }
83 |  |  |  |  |
84 |  |  |  |  | sub reset_state {
85 |  |  |  |  | my $self = shift;
86 |  |  |  |  |
87 |  |  |  |  | $self->{+COUNT} = 0;
88 |  |  |  |  | $self->{+FAILED} = 0;
89 |  |  |  |  | $self->{+_PASSING} = 1;
90 |  |  |  |  |
91 |  |  |  |  | delete $self->{+_PLAN};
92 |  |  |  |  | delete $self->{+ENDED};
93 |  |  |  |  | delete $self->{+BAILED_OUT};
94 |  |  |  |  | delete $self->{+SKIP_REASON};
95 |  |  |  |  | }
96 |  |  |  |  |
97 |  |  |  |  | sub inherit {
98 |  |  |  |  | my $self = shift;
99 |  |  |  |  | my ($from, %params) = @_;
100 |  |  |  |  |
101 |  |  |  |  | $self->{+NESTED} ||= 0;
102 |  |  |  |  |
103 |  |  |  |  | $self->{+_FORMATTER} = $from->{+_FORMATTER}
104 |  |  |  |  | unless $self->{+_FORMATTER} || exists($params{formatter});
105 |  |  |  |  |
106 |  |  |  |  | if ($from->{+IPC} && !$self->{+IPC} && !exists($params{ipc})) {
107 |  |  |  |  | my $ipc = $from->{+IPC};
108 |  |  |  |  | $self->{+IPC} = $ipc;
109 |  |  |  |  | $ipc->add_hub($self->{+HID});
110 |  |  |  |  | }
111 |  |  |  |  |
112 |  |  |  |  | if (my $ls = $from->{+_LISTENERS}) {
113 |  |  |  |  | push @{$self->{+_LISTENERS}} => grep { $_->{inherit} } @$ls;
114 |  |  |  |  | }
115 |  |  |  |  |
116 |  |  |  |  | if (my $pfs = $from->{+_PRE_FILTERS}) {
117 |  |  |  |  | push @{$self->{+_PRE_FILTERS}} => grep { $_->{inherit} } @$pfs;
118 |  |  |  |  | }
119 |  |  |  |  |
120 |  |  |  |  | if (my $fs = $from->{+_FILTERS}) {
121 |  |  |  |  | push @{$self->{+_FILTERS}} => grep { $_->{inherit} } @$fs;
122 |  |  |  |  | }
123 |  |  |  |  | }
124 |  |  |  |  |
125 |  |  |  |  | # spent 5µs within Test2::Hub::format which was called 5 times, avg 1µs/call: # 2 times (3µs+0s) by Test2::API::Stack::new_hub at line 31 of Test2/API/Stack.pm, avg 1µs/call # once (1µs+0s) by Test::Builder::reset at line 468 of Test/Builder.pm # once (800ns+0s) by Test::Builder::use_numbers at line 1221 of Test/Builder.pm # once (700ns+0s) by Test::Builder::reset_outputs at line 1410 of Test/Builder.pm sub format {
126 | 5 | 400ns |  |  | my $self = shift;
127 |  |  |  |  |
128 | 5 | 900ns |  |  | my $old = $self->{+_FORMATTER};
129 | 5 | 1µs |  |  | ($self->{+_FORMATTER}) = @_ if @_;
130 |  |  |  |  |
131 | 5 | 5µs |  |  | return $old;
132 |  |  |  |  | }
133 |  |  |  |  |
134 |  |  |  |  | sub is_local {
135 |  |  |  |  | my $self = shift;
136 |  |  |  |  | return $$ == $self->{+PID}
137 |  |  |  |  | && get_tid() == $self->{+TID};
138 |  |  |  |  | }
139 |  |  |  |  |
140 |  |  |  |  | sub listen {
141 |  |  |  |  | my $self = shift;
142 |  |  |  |  | my ($sub, %params) = @_;
143 |  |  |  |  |
144 |  |  |  |  | carp "Useless addition of a listener in a child process or thread!"
145 |  |  |  |  | if $$ != $self->{+PID} || get_tid() != $self->{+TID};
146 |  |  |  |  |
147 |  |  |  |  | croak "listen only takes coderefs for arguments, got '$sub'"
148 |  |  |  |  | unless ref $sub && ref $sub eq 'CODE';
149 |  |  |  |  |
150 |  |  |  |  | push @{$self->{+_LISTENERS}} => { %params, code => $sub };
151 |  |  |  |  |
152 |  |  |  |  | $sub; # Intentional return.
153 |  |  |  |  | }
154 |  |  |  |  |
155 |  |  |  |  | sub unlisten {
156 |  |  |  |  | my $self = shift;
157 |  |  |  |  |
158 |  |  |  |  | carp "Useless removal of a listener in a child process or thread!"
159 |  |  |  |  | if $$ != $self->{+PID} || get_tid() != $self->{+TID};
160 |  |  |  |  |
161 |  |  |  |  | my %subs = map {$_ => $_} @_;
162 |  |  |  |  |
163 |  |  |  |  | @{$self->{+_LISTENERS}} = grep { !$subs{$_->{code}} } @{$self->{+_LISTENERS}};
164 |  |  |  |  | }
165 |  |  |  |  |
166 |  |  |  |  | sub filter {
167 |  |  |  |  | my $self = shift;
168 |  |  |  |  | my ($sub, %params) = @_;
169 |  |  |  |  |
170 |  |  |  |  | carp "Useless addition of a filter in a child process or thread!"
171 |  |  |  |  | if $$ != $self->{+PID} || get_tid() != $self->{+TID};
172 |  |  |  |  |
173 |  |  |  |  | croak "filter only takes coderefs for arguments, got '$sub'"
174 |  |  |  |  | unless ref $sub && ref $sub eq 'CODE';
175 |  |  |  |  |
176 |  |  |  |  | push @{$self->{+_FILTERS}} => { %params, code => $sub };
177 |  |  |  |  |
178 |  |  |  |  | $sub; # Intentional Return
179 |  |  |  |  | }
180 |  |  |  |  |
181 |  |  |  |  | sub unfilter {
182 |  |  |  |  | my $self = shift;
183 |  |  |  |  | carp "Useless removal of a filter in a child process or thread!"
184 |  |  |  |  | if $$ != $self->{+PID} || get_tid() != $self->{+TID};
185 |  |  |  |  | my %subs = map {$_ => $_} @_;
186 |  |  |  |  | @{$self->{+_FILTERS}} = grep { !$subs{$_->{code}} } @{$self->{+_FILTERS}};
187 |  |  |  |  | }
188 |  |  |  |  |
189 |  |  |  |  | # spent 4µs within Test2::Hub::pre_filter which was called: # once (4µs+0s) by Test::Builder::_add_ts_hooks at line 127 of Test/Builder.pm sub pre_filter {
190 | 1 | 100ns |  |  | my $self = shift;
191 | 1 | 900ns |  |  | my ($sub, %params) = @_;
192 |  |  |  |  |
193 | 1 | 800ns |  |  | croak "pre_filter only takes coderefs for arguments, got '$sub'"
194 |  |  |  |  | unless ref $sub && ref $sub eq 'CODE';
195 |  |  |  |  |
196 | 1 | 2µs |  |  | push @{$self->{+_PRE_FILTERS}} => { %params, code => $sub };
197 |  |  |  |  |
198 | 1 | 2µs |  |  | $sub; # Intentional Return
199 |  |  |  |  | }
200 |  |  |  |  |
201 |  |  |  |  | sub pre_unfilter {
202 |  |  |  |  | my $self = shift;
203 |  |  |  |  | my %subs = map {$_ => $_} @_;
204 |  |  |  |  | @{$self->{+_PRE_FILTERS}} = grep { !$subs{$_->{code}} } @{$self->{+_PRE_FILTERS}};
205 |  |  |  |  | }
206 |  |  |  |  |
207 |  |  |  |  | sub follow_up {
208 |  |  |  |  | my $self = shift;
209 |  |  |  |  | my ($sub) = @_;
210 |  |  |  |  |
211 |  |  |  |  | carp "Useless addition of a follow-up in a child process or thread!"
212 |  |  |  |  | if $$ != $self->{+PID} || get_tid() != $self->{+TID};
213 |  |  |  |  |
214 |  |  |  |  | croak "follow_up only takes coderefs for arguments, got '$sub'"
215 |  |  |  |  | unless ref $sub && ref $sub eq 'CODE';
216 |  |  |  |  |
217 |  |  |  |  | push @{$self->{+_FOLLOW_UPS}} => $sub;
218 |  |  |  |  | }
219 |  |  |  |  |
220 | 1 | 1µs |  |  | *add_context_aquire = \&add_context_acquire;
221 |  |  |  |  | sub add_context_acquire {
222 |  |  |  |  | my $self = shift;
223 |  |  |  |  | my ($sub) = @_;
224 |  |  |  |  |
225 |  |  |  |  | croak "add_context_acquire only takes coderefs for arguments, got '$sub'"
226 |  |  |  |  | unless ref $sub && ref $sub eq 'CODE';
227 |  |  |  |  |
228 |  |  |  |  | push @{$self->{+_CONTEXT_ACQUIRE}} => $sub;
229 |  |  |  |  |
230 |  |  |  |  | $sub; # Intentional return.
231 |  |  |  |  | }
232 |  |  |  |  |
233 | 1 | 200ns |  |  | *remove_context_aquire = \&remove_context_acquire;
234 |  |  |  |  | sub remove_context_acquire {
235 |  |  |  |  | my $self = shift;
236 |  |  |  |  | my %subs = map {$_ => $_} @_;
237 |  |  |  |  | @{$self->{+_CONTEXT_ACQUIRE}} = grep { !$subs{$_} == $_ } @{$self->{+_CONTEXT_ACQUIRE}};
238 |  |  |  |  | }
239 |  |  |  |  |
240 |  |  |  |  | sub add_context_init {
241 |  |  |  |  | my $self = shift;
242 |  |  |  |  | my ($sub) = @_;
243 |  |  |  |  |
244 |  |  |  |  | croak "add_context_init only takes coderefs for arguments, got '$sub'"
245 |  |  |  |  | unless ref $sub && ref $sub eq 'CODE';
246 |  |  |  |  |
247 |  |  |  |  | push @{$self->{+_CONTEXT_INIT}} => $sub;
248 |  |  |  |  |
249 |  |  |  |  | $sub; # Intentional return.
250 |  |  |  |  | }
251 |  |  |  |  |
252 |  |  |  |  | sub remove_context_init {
253 |  |  |  |  | my $self = shift;
254 |  |  |  |  | my %subs = map {$_ => $_} @_;
255 |  |  |  |  | @{$self->{+_CONTEXT_INIT}} = grep { !$subs{$_} == $_ } @{$self->{+_CONTEXT_INIT}};
256 |  |  |  |  | }
257 |  |  |  |  |
258 |  |  |  |  | sub add_context_release {
259 |  |  |  |  | my $self = shift;
260 |  |  |  |  | my ($sub) = @_;
261 |  |  |  |  |
262 |  |  |  |  | croak "add_context_release only takes coderefs for arguments, got '$sub'"
263 |  |  |  |  | unless ref $sub && ref $sub eq 'CODE';
264 |  |  |  |  |
265 |  |  |  |  | push @{$self->{+_CONTEXT_RELEASE}} => $sub;
266 |  |  |  |  |
267 |  |  |  |  | $sub; # Intentional return.
268 |  |  |  |  | }
269 |  |  |  |  |
270 |  |  |  |  | sub remove_context_release {
271 |  |  |  |  | my $self = shift;
272 |  |  |  |  | my %subs = map {$_ => $_} @_;
273 |  |  |  |  | @{$self->{+_CONTEXT_RELEASE}} = grep { !$subs{$_} == $_ } @{$self->{+_CONTEXT_RELEASE}};
274 |  |  |  |  | }
275 |  |  |  |  |
276 |  |  |  |  | # spent 332µs (42+290) within Test2::Hub::send which was called 3 times, avg 110µs/call: # once (21µs+118µs) by Test::Builder::ok at line 729 of Test/Builder.pm # once (10µs+101µs) by Test2::Hub::finalize at line 435 # once (11µs+71µs) by Test2::API::Context::send_ev2 at line 232 of Test2/API/Context.pm sub send {
277 | 3 | 500ns |  |  | my $self = shift;
278 | 3 | 900ns |  |  | my ($e) = @_;
279 |  |  |  |  |
280 | 3 | 7µs | 3 | 14µs | $e->eid; # spent 14µs making 3 calls to Test2::Event::eid, avg 5µs/call
281 |  |  |  |  |
282 |  |  |  |  | $e->add_hub(
283 |  |  |  |  | {
284 |  |  |  |  | details => ref($self),
285 |  |  |  |  |
286 |  |  |  |  | buffered => $self->{+BUFFERED},
287 |  |  |  |  | hid => $self->{+HID},
288 |  |  |  |  | nested => $self->{+NESTED},
289 |  |  |  |  | pid => $self->{+PID},
290 |  |  |  |  | tid => $self->{+TID},
291 |  |  |  |  | uuid => $self->{+UUID},
292 |  |  |  |  |
293 | 3 | 13µs | 3 | 6µs | ipc => $self->{+IPC} ? 1 : 0, # spent 6µs making 3 calls to Test2::Event::add_hub, avg 2µs/call
294 |  |  |  |  | }
295 |  |  |  |  | );
296 |  |  |  |  |
297 | 3 | 600ns |  |  | $e->set_uuid(${$UUID_VIA}->('event')) if $$UUID_VIA;
298 |  |  |  |  |
299 | 3 | 1µs |  |  | if ($self->{+_PRE_FILTERS}) {
300 | 3 | 2µs |  |  | for (@{$self->{+_PRE_FILTERS}}) {
301 | 3 | 3µs | 3 | 14µs | $e = $_->{code}->($self, $e); # spent 14µs making 3 calls to Test::Builder::__ANON__[Test/Builder.pm:88], avg 5µs/call
302 | 3 | 1µs |  |  | return unless $e;
303 |  |  |  |  | }
304 |  |  |  |  | }
305 |  |  |  |  |
306 | 3 | 8µs | 3 | 257µs | my $ipc = $self->{+IPC} || return $self->process($e); # spent 257µs making 3 calls to Test2::Hub::process, avg 86µs/call
307 |  |  |  |  |
308 |  |  |  |  | if($e->global) {
309 |  |  |  |  | $ipc->send($self->{+HID}, $e, 'GLOBAL');
310 |  |  |  |  | return $self->process($e);
311 |  |  |  |  | }
312 |  |  |  |  |
313 |  |  |  |  | return $ipc->send($self->{+HID}, $e)
314 |  |  |  |  | if $$ != $self->{+PID} || get_tid() != $self->{+TID};
315 |  |  |  |  |
316 |  |  |  |  | $self->process($e);
317 |  |  |  |  | }
318 |  |  |  |  |
319 |  |  |  |  | # spent 257µs (45+212) within Test2::Hub::process which was called 3 times, avg 86µs/call: # 3 times (45µs+212µs) by Test2::Hub::send at line 306, avg 86µs/call sub process {
320 | 3 | 400ns |  |  | my $self = shift;
321 | 3 | 500ns |  |  | my ($e) = @_;
322 |  |  |  |  |
323 | 3 | 600ns |  |  | if ($self->{+_FILTERS}) {
324 |  |  |  |  | for (@{$self->{+_FILTERS}}) {
325 |  |  |  |  | $e = $_->{code}->($self, $e);
326 |  |  |  |  | return unless $e;
327 |  |  |  |  | }
328 |  |  |  |  | }
329 |  |  |  |  |
330 |  |  |  |  | # Optimize the most common case
331 | 3 | 900ns |  |  | my $type = ref($e);
332 | 3 | 12µs |  |  | if ($type eq 'Test2::Event::Pass' || ($type eq 'Test2::Event::Ok' && $e->{pass})) {
333 | 1 | 300ns |  |  | my $count = ++($self->{+COUNT});
334 | 1 | 5µs | 1 | 93µs | $self->{+_FORMATTER}->write($e, $count) if $self->{+_FORMATTER}; # spent 93µs making 1 call to Test2::Formatter::TAP::write
335 |  |  |  |  |
336 | 1 | 300ns |  |  | if ($self->{+_LISTENERS}) {
337 |  |  |  |  | $_->{code}->($self, $e, $count) for @{$self->{+_LISTENERS}};
338 |  |  |  |  | }
339 |  |  |  |  |
340 | 1 | 2µs |  |  | return $e;
341 |  |  |  |  | }
342 |  |  |  |  |
343 | 2 | 4µs | 2 | 62µs | my $f = $e->facet_data; # spent 34µs making 1 call to Test2::Event::Plan::facet_data # spent 28µs making 1 call to Test2::Event::V2::facet_data
344 |  |  |  |  |
345 | 2 | 400ns |  |  | my $fail = 0;
346 | 2 | 600ns |  |  | $fail = 1 if $f->{assert} && !$f->{assert}->{pass};
347 | 2 | 500ns |  |  | $fail = 1 if $f->{errors} && grep { $_->{fail} } @{$f->{errors}};
348 | 2 | 400ns |  |  | $fail = 0 if $f->{amnesty};
349 |  |  |  |  |
350 | 2 | 300ns |  |  | $self->{+COUNT}++ if $f->{assert};
351 | 2 | 400ns |  |  | $self->{+FAILED}++ if $fail && $f->{assert};
352 | 2 | 400ns |  |  | $self->{+_PASSING} = 0 if $fail;
353 |  |  |  |  |
354 | 2 | 1µs |  |  | my $code = $f->{control} ? $f->{control}->{terminate} : undef;
355 | 2 | 400ns |  |  | my $count = $self->{+COUNT};
356 |  |  |  |  |
357 | 2 | 600ns |  |  | if (my $plan = $f->{plan}) {
358 | 1 | 700ns |  |  | if ($plan->{skip}) {
359 |  |  |  |  | $self->plan('SKIP');
360 |  |  |  |  | $self->set_skip_reason($plan->{details} || 1);
361 |  |  |  |  | $code ||= 0;
362 |  |  |  |  | }
363 |  |  |  |  | elsif ($plan->{none}) {
364 |  |  |  |  | $self->plan('NO PLAN');
365 |  |  |  |  | }
366 |  |  |  |  | else {
367 | 1 | 900ns | 1 | 6µs | $self->plan($plan->{count}); # spent 6µs making 1 call to Test2::Hub::plan
368 |  |  |  |  | }
369 |  |  |  |  | }
370 |  |  |  |  |
371 | 2 | 1µs |  |  | $e->callback($self) if $f->{control} && $f->{control}->{has_callback};
372 |  |  |  |  |
373 | 2 | 3µs | 2 | 51µs | $self->{+_FORMATTER}->write($e, $count, $f) if $self->{+_FORMATTER}; # spent 51µs making 2 calls to Test2::Formatter::TAP::write, avg 26µs/call
374 |  |  |  |  |
375 | 2 | 500ns |  |  | if ($self->{+_LISTENERS}) {
376 |  |  |  |  | $_->{code}->($self, $e, $count, $f) for @{$self->{+_LISTENERS}};
377 |  |  |  |  | }
378 |  |  |  |  |
379 | 2 | 700ns |  |  | if ($f->{control} && $f->{control}->{halt}) {
380 |  |  |  |  | $code ||= 255;
381 |  |  |  |  | $self->set_bailed_out($e);
382 |  |  |  |  | }
383 |  |  |  |  |
384 | 2 | 700ns |  |  | if (defined $code) {
385 |  |  |  |  | $self->{+_FORMATTER}->terminate($e, $f) if $self->{+_FORMATTER};
386 |  |  |  |  | $self->terminate($code, $e, $f);
387 |  |  |  |  | }
388 |  |  |  |  |
389 | 2 | 5µs |  |  | return $e;
390 |  |  |  |  | }
391 |  |  |  |  |
392 |  |  |  |  | sub terminate {
393 |  |  |  |  | my $self = shift;
394 |  |  |  |  | my ($code) = @_;
395 |  |  |  |  | exit($code);
396 |  |  |  |  | }
397 |  |  |  |  |
398 |  |  |  |  | # spent 2µs within Test2::Hub::cull which was called: # once (2µs+0s) by Test2::Hub::finalize at line 412 sub cull {
399 | 1 | 300ns |  |  | my $self = shift;
400 |  |  |  |  |
401 | 1 | 2µs |  |  | my $ipc = $self->{+IPC} || return;
402 |  |  |  |  | return if $self->{+PID} != $$ || $self->{+TID} != get_tid();
403 |  |  |  |  |
404 |  |  |  |  | # No need to do IPC checks on culled events
405 |  |  |  |  | $self->process($_) for $ipc->cull($self->{+HID});
406 |  |  |  |  | }
407 |  |  |  |  |
408 |  |  |  |  | # spent 186µs (32+154) within Test2::Hub::finalize which was called: # once (32µs+154µs) by Test::Builder::done_testing at line 618 of Test/Builder.pm sub finalize {
409 | 1 | 200ns |  |  | my $self = shift;
410 | 1 | 300ns |  |  | my ($trace, $do_plan) = @_;
411 |  |  |  |  |
412 | 1 | 2µs | 1 | 2µs | $self->cull(); # spent 2µs making 1 call to Test2::Hub::cull
413 |  |  |  |  |
414 | 1 | 400ns |  |  | my $plan = $self->{+_PLAN};
415 | 1 | 300ns |  |  | my $count = $self->{+COUNT};
416 | 1 | 400ns |  |  | my $failed = $self->{+FAILED};
417 | 1 | 300ns |  |  | my $active = $self->{+ACTIVE};
418 |  |  |  |  |
419 |  |  |  |  | # return if NOTHING was done.
420 | 1 | 600ns |  |  | unless ($active || $do_plan || defined($plan) || $count || $failed) {
421 |  |  |  |  | $self->{+_FORMATTER}->finalize($plan, $count, $failed, 0, $self->is_subtest) if $self->{+_FORMATTER};
422 |  |  |  |  | return;
423 |  |  |  |  | }
424 |  |  |  |  |
425 | 1 | 600ns |  |  | unless ($self->{+ENDED}) {
426 | 1 | 500ns |  |  | if ($self->{+_FOLLOW_UPS}) {
427 |  |  |  |  | $_->($trace, $self) for reverse @{$self->{+_FOLLOW_UPS}};
428 |  |  |  |  | }
429 |  |  |  |  |
430 |  |  |  |  | # These need to be refreshed now
431 | 1 | 200ns |  |  | $plan = $self->{+_PLAN};
432 | 1 | 200ns |  |  | $count = $self->{+COUNT};
433 | 1 | 200ns |  |  | $failed = $self->{+FAILED};
434 |  |  |  |  |
435 | 1 | 9µs | 2 | 141µs | if ((defined($plan) && $plan eq 'NO PLAN') || ($do_plan && !defined($plan))) { # spent 111µs making 1 call to Test2::Hub::send # spent 30µs making 1 call to Test2::Util::HashBase::_new
436 |  |  |  |  | $self->send(
437 |  |  |  |  | Test2::Event::Plan->new(
438 |  |  |  |  | trace => $trace,
439 |  |  |  |  | max => $count,
440 |  |  |  |  | )
441 |  |  |  |  | );
442 |  |  |  |  | }
443 | 1 | 700ns |  |  | $plan = $self->{+_PLAN};
444 |  |  |  |  | }
445 |  |  |  |  |
446 | 1 | 2µs | 1 | 1µs | my $frame = $trace->frame; # spent 1µs making 1 call to Test2::Util::HashBase::__ANON__[Test2/Util/HashBase.pm:84]
447 | 1 | 300ns |  |  | if($self->{+ENDED}) {
448 |  |  |  |  | my (undef, $ffile, $fline) = @{$self->{+ENDED}};
449 |  |  |  |  | my (undef, $sfile, $sline) = @$frame;
450 |  |  |  |  |
451 |  |  |  |  | die <<" EOT"
452 |  |  |  |  | Test already ended!
453 |  |  |  |  | First End: $ffile line $fline
454 |  |  |  |  | Second End: $sfile line $sline
455 |  |  |  |  | EOT
456 |  |  |  |  | }
457 |  |  |  |  |
458 | 1 | 500ns |  |  | $self->{+ENDED} = $frame;
459 | 1 | 2µs | 1 | 9µs | my $pass = $self->is_passing(); # Generate the final boolean. # spent 9µs making 1 call to Test2::Hub::is_passing
460 |  |  |  |  |
461 | 1 | 5µs | 2 | 2µs | $self->{+_FORMATTER}->finalize($plan, $count, $failed, $pass, $self->is_subtest) if $self->{+_FORMATTER}; # spent 900ns making 1 call to Test2::Hub::is_subtest # spent 700ns making 1 call to Test2::Formatter::finalize
462 |  |  |  |  |
463 | 1 | 2µs |  |  | return $pass;
464 |  |  |  |  | }
465 |  |  |  |  |
466 |  |  |  |  | # spent 16µs (13+3) within Test2::Hub::is_passing which was called 3 times, avg 5µs/call: # once (7µs+1µs) by Test2::Hub::finalize at line 459 # once (3µs+2µs) by Test::Builder::_ending at line 1669 of Test/Builder.pm # once (2µs+400ns) by Test2::API::Instance::set_exit at line 556 of Test2/API/Instance.pm sub is_passing {
467 | 3 | 400ns |  |  | my $self = shift;
468 |  |  |  |  |
469 | 3 | 600ns |  |  | ($self->{+_PASSING}) = @_ if @_;
470 |  |  |  |  |
471 |  |  |  |  | # If we already failed just return 0.
472 | 3 | 1µs |  |  | my $pass = $self->{+_PASSING} or return 0;
473 | 3 | 500ns |  |  | return $self->{+_PASSING} = 0 if $self->{+FAILED};
474 |  |  |  |  |
475 | 3 | 600ns |  |  | my $count = $self->{+COUNT};
476 | 3 | 400ns |  |  | my $ended = $self->{+ENDED};
477 | 3 | 700ns |  |  | my $plan = $self->{+_PLAN};
478 |  |  |  |  |
479 | 3 | 600ns |  |  | return $pass if !$count && $plan && $plan =~ m/^SKIP$/;
480 |  |  |  |  |
481 | 3 | 1µs |  |  | return $self->{+_PASSING} = 0
482 |  |  |  |  | if $ended && (!$count || !$plan);
483 |  |  |  |  |
484 | 3 | 7µs | 3 | 3µs | return $pass unless $plan && $plan =~ m/^\d+$/; # spent 3µs making 3 calls to CORE::match, avg 1µs/call
485 |  |  |  |  |
486 | 3 | 900ns |  |  | if ($ended) {
487 |  |  |  |  | return $self->{+_PASSING} = 0 if $count != $plan;
488 |  |  |  |  | }
489 |  |  |  |  | else {
490 |  |  |  |  | return $self->{+_PASSING} = 0 if $count > $plan;
491 |  |  |  |  | }
492 |  |  |  |  |
493 | 3 | 4µs |  |  | return $pass;
494 |  |  |  |  | }
495 |  |  |  |  |
496 |  |  |  |  | # spent 10µs (9+1) within Test2::Hub::plan which was called 6 times, avg 2µs/call: # once (5µs+1µs) by Test2::Hub::process at line 367 # once (2µs+0s) by Test::Builder::done_testing at line 597 of Test/Builder.pm # once (900ns+0s) by Test::Builder::_ending at line 1666 of Test/Builder.pm # once (700ns+0s) by Test::Builder::expected_tests at line 555 of Test/Builder.pm # once (500ns+0s) by Test::Builder::_ending at line 1673 of Test/Builder.pm # once (400ns+0s) by Test::Builder::done_testing at line 616 of Test/Builder.pm sub plan {
497 | 6 | 700ns |  |  | my $self = shift;
498 |  |  |  |  |
499 | 6 | 10µs |  |  | return $self->{+_PLAN} unless @_;
500 |  |  |  |  |
501 | 1 | 400ns |  |  | my ($plan) = @_;
502 |  |  |  |  |
503 | 1 | 200ns |  |  | confess "You cannot unset the plan"
504 |  |  |  |  | unless defined $plan;
505 |  |  |  |  |
506 |  |  |  |  | confess "You cannot change the plan"
507 | 1 | 300ns |  |  | if $self->{+_PLAN} && $self->{+_PLAN} !~ m/^NO PLAN$/;
508 |  |  |  |  |
509 | 1 | 3µs | 1 | 1µs | confess "'$plan' is not a valid plan! Plan must be an integer greater than 0, 'NO PLAN', or 'SKIP'" # spent 1µs making 1 call to CORE::match
510 |  |  |  |  | unless $plan =~ m/^(\d+|NO PLAN|SKIP)$/;
511 |  |  |  |  |
512 | 1 | 2µs |  |  | $self->{+_PLAN} = $plan;
513 |  |  |  |  | }
514 |  |  |  |  |
515 |  |  |  |  | sub check_plan {
516 |  |  |  |  | my $self = shift;
517 |  |  |  |  |
518 |  |  |  |  | return undef unless $self->{+ENDED};
519 |  |  |  |  | my $plan = $self->{+_PLAN} || return undef;
520 |  |  |  |  |
521 |  |  |  |  | return 1 if $plan !~ m/^\d+$/;
522 |  |  |  |  |
523 |  |  |  |  | return 1 if $plan == $self->{+COUNT};
524 |  |  |  |  | return 0;
525 |  |  |  |  | }
526 |  |  |  |  |
527 |  |  |  |  | sub DESTROY {
528 |  |  |  |  | my $self = shift;
529 |  |  |  |  | my $ipc = $self->{+IPC} || return;
530 |  |  |  |  | return unless $$ == $self->{+PID};
531 |  |  |  |  | return unless get_tid() == $self->{+TID};
532 |  |  |  |  | $ipc->drop_hub($self->{+HID});
533 |  |  |  |  | }
534 |  |  |  |  |
535 | 1 | 3µs |  |  | 1;
536 |  |  |  |  |
537 |  |  |  |  | __END__