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