|
NAMETest2::Harness::Runner::Preload - DSL for building complex stage-based preload tools.DESCRIPTIONTest2::Harness allows you to preload libraries for a performance boost. This module provides tools that let you go beyond that and build a more complex preload. In addition you can build multiple preload stages, each stage will be its own process and tests can run from a specific stage. This allows for multiple different preload states from which to run tests.SYNOPSISUSING YOUR PRELOADThe "-P" or "--preload" options work for custom preload modules just as they do regular modules. Yath will know the difference and act accordingly.yath test -PMy::Preload WRITING YOUR PRELOADpackage My::Preload; use strict; use warnings; # This imports several useful tools, and puts the necessary meta-data in # your package to identify it as a special preload. use Test2::Harness::Runner::Preload; # You must specify at least one stage. stage Moose => sub { # Preload can be called multiple times, and can load multiple modules # per call. Order is preserved. preload 'Moose', 'Moose::Role'; preload 'Scalar::Util', 'List::Util'; # preload can also be given a sub if you have some custom code to run # at a specific point in the load order preload sub { # Do something before loading Try::Tiny ... }; preload 'Try::Tiny'; # Tell the runner to watch this file for changes, if it does change run # the sub instead of the usual reload process. This lets you reload # configs and other non-perl files, or allows you to use a custom # reload sub for perl files. watch 'path/to/file' => sub { ... }; # You can also use watch inside preload subs: preload sub { watch 'path/to/file' => sub { ... }; }; # In app code you can add watches dynamically when applicable: preload sub { ... # inside app code if ($INC{'Test2/Harness/Runner/DepTracer.pm'}) { if (my $active = Test2::Harness::Runner::DepTracer->ACTIVE) { $active->add_callback('path/to/file' => sub { ... }); } } ... }; # Eager means tests from nested stages can be run in this stage as # well, this is useful if the nested stage takes a long time to load as # it allows yath to start running tests sooner instead of waiting for # the stage to finish loading. Once the nested stage is loaded tests # intended for it will start running from it instead. eager(); # default means this stage is the one to use if the test does not # specify a stage. default(); # These are hooks that let you run arbitrary code at specific points in # the process. pre_fork happens just before forking to run a test. # post_fork happens just after forking for a test. pre_launch happens # as late as possible before the test starts executing (post fork, # after $0 and other special state are reset). pre_fork sub { ... }; post_fork sub { ... }; pre_launch sub { ... }; # Stages can be nested, nested ones build off the previous stage, but # are in a forked process to avoid contaminating the parent. stage Types => sub { preload 'MooseX::Types'; }; }; # Alternative stage that loads Moo instead of Moose stage Moo => sub { preload 'Moo'; ... }; HARNESS DIRECTIVES IN PRELOADSIf you use a staged preload, and the --reload option, you can add 'CHURN' directives to files in order to only reload sections you are working on. This is particularly useful when a file cannot be reloaded in full, or when doing so is expensive. You can wrap subroutines in the churn directives to have yath reload only those subroutines.sub do_not_reload_this { ... { # HARNESS-CHURN-START sub reload_this_one { ... } sub reload_this_one_too { ... } # HARNESS-CHURN-STOP sub this_is_not_reloaded { ... } You can put as many churn sections you want in as many preloaded modules as you want. If a change is detected then only the churn sections will be reloaded. The churn sections are reloaded by taking the source between the start and stop markers, and running them in an eval like this: eval <<EOT package MODULE_FROM_FILENAME; use strict; use warnings; no warnings 'redefine'; #line $line_number $file $YOUR_CODE ;1; EOT In most cases this is sufficient to replace the old sub with the new one. If the automatically determined package is not correct you can add a "package FOO;" statement inside the markers. If the strict/warnings settings are not to your specifications you can add overrides inside the markers. Any valid perl code can go into the markers. CAVEATS: Be aware they do not have their original scope, and that can lead to problems if you are not paying attention. Variables outside your markers are not accessible, and lexical variables put inside your markers will be "new" on each reload, this can cause confusion if you have lexicals used by multiple subs where some are inside churn blocks and others are not, so best not to do that. Package variables work a bit better, but any assignment lines are re-run. So "our $FOO;" is fine (it does not change the value if it is set) but "our $FOO = ..." will reset the var on each reload. EXPORTS
META-OBJECTThis class is also the meta-object used to construct a preload library. The methods are left undocumented as this is an implementation detail and you are not intended to directly use this object.SOURCEThe source code repository for Test2-Harness can be found at http://github.com/Test-More/Test2-Harness/.MAINTAINERS
AUTHORS
COPYRIGHTCopyright 2020 Chad Granum <exodist7@gmail.com>.This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See http://dev.perl.org/licenses/
Visit the GSP FreeBSD Man Page Interface. |