1Test2::Harness::Runner:U:sPerrelCooandt(r3i)buted Perl DToecsutm2e:n:tHaatrinoenss::Runner::Preload(3)
2
3
4
6 Test2::Harness::Runner::Preload - DSL for building complex stage-based
7 preload tools.
8
10 Test2::Harness allows you to preload libraries for a performance boost.
11 This module provides tools that let you go beyond that and build a more
12 complex preload. In addition you can build multiple preload stages,
13 each stage will be its own process and tests can run from a specific
14 stage. This allows for multiple different preload states from which to
15 run tests.
16
18 USING YOUR PRELOAD
19 The "-P" or "--preload" options work for custom preload modules just as
20 they do regular modules. Yath will know the difference and act
21 accordingly.
22
23 yath test -PMy::Preload
24
25 WRITING YOUR PRELOAD
26 package My::Preload;
27 use strict;
28 use warnings;
29
30 # This imports several useful tools, and puts the necessary meta-data in
31 # your package to identify it as a special preload.
32 use Test2::Harness::Runner::Preload;
33
34 # You must specify at least one stage.
35 stage Moose => sub {
36 # Preload can be called multiple times, and can load multiple modules
37 # per call. Order is preserved.
38 preload 'Moose', 'Moose::Role';
39 preload 'Scalar::Util', 'List::Util';
40
41 # preload can also be given a sub if you have some custom code to run
42 # at a specific point in the load order
43 preload sub {
44 # Do something before loading Try::Tiny
45 ...
46 };
47
48 preload 'Try::Tiny';
49
50 # Tell the runner to watch this file for changes, if it does change run
51 # the sub instead of the usual reload process. This lets you reload
52 # configs and other non-perl files, or allows you to use a custom
53 # reload sub for perl files.
54 watch 'path/to/file' => sub { ... };
55
56 # You can also use watch inside preload subs:
57 preload sub {
58 watch 'path/to/file' => sub { ... };
59 };
60
61 # In app code you can add watches dynamically when applicable:
62 preload sub {
63 ... # inside app code
64
65 if ($INC{'Test2/Harness/Runner/DepTracer.pm'}) {
66 if (my $active = Test2::Harness::Runner::DepTracer->ACTIVE) {
67 $active->add_callback('path/to/file' => sub { ... });
68 }
69 }
70
71 ...
72 };
73
74 # Eager means tests from nested stages can be run in this stage as
75 # well, this is useful if the nested stage takes a long time to load as
76 # it allows yath to start running tests sooner instead of waiting for
77 # the stage to finish loading. Once the nested stage is loaded tests
78 # intended for it will start running from it instead.
79 eager();
80
81 # default means this stage is the one to use if the test does not
82 # specify a stage.
83 default();
84
85 # These are hooks that let you run arbitrary code at specific points in
86 # the process. pre_fork happens just before forking to run a test.
87 # post_fork happens just after forking for a test. pre_launch happens
88 # as late as possible before the test starts executing (post fork,
89 # after $0 and other special state are reset).
90 pre_fork sub { ... };
91 post_fork sub { ... };
92 pre_launch sub { ... };
93
94 # Stages can be nested, nested ones build off the previous stage, but
95 # are in a forked process to avoid contaminating the parent.
96 stage Types => sub {
97 preload 'MooseX::Types';
98 };
99 };
100
101 # Alternative stage that loads Moo instead of Moose
102 stage Moo => sub {
103 preload 'Moo';
104
105 ...
106 };
107
108 HARNESS DIRECTIVES IN PRELOADS
109 If you use a staged preload, and the --reload option, you can add
110 'CHURN' directives to files in order to only reload sections you are
111 working on. This is particularly useful when a file cannot be reloaded
112 in full, or when doing so is expensive. You can wrap subroutines in the
113 churn directives to have yath reload only those subroutines.
114
115 sub do_not_reload_this { ... {
116
117 # HARNESS-CHURN-START
118
119 sub reload_this_one {
120 ...
121 }
122
123 sub reload_this_one_too {
124 ...
125 }
126
127 # HARNESS-CHURN-STOP
128
129 sub this_is_not_reloaded { ... }
130
131 You can put as many churn sections you want in as many preloaded
132 modules as you want. If a change is detected then only the churn
133 sections will be reloaded. The churn sections are reloaded by taking
134 the source between the start and stop markers, and running them in an
135 eval like this:
136
137 eval <<EOT
138 package MODULE_FROM_FILENAME;
139 use strict;
140 use warnings;
141 no warnings 'redefine';
142 #line $line_number $file
143 $YOUR_CODE
144 ;1;
145 EOT
146
147 In most cases this is sufficient to replace the old sub with the new
148 one. If the automatically determined package is not correct you can add
149 a "package FOO;" statement inside the markers. If the strict/warnings
150 settings are not to your specifications you can add overrides inside
151 the markers. Any valid perl code can go into the markers.
152
153 CAVEATS: Be aware they do not have their original scope, and that can
154 lead to problems if you are not paying attention. Variables outside
155 your markers are not accessible, and lexical variables put inside your
156 markers will be "new" on each reload, this can cause confusion if you
157 have lexicals used by multiple subs where some are inside churn blocks
158 and others are not, so best not to do that. Package variables work a
159 bit better, but any assignment lines are re-run. So "our $FOO;" is
160 fine (it does not change the value if it is set) but "our $FOO = ..."
161 will reset the var on each reload.
162
164 $meta = TEST2_HARNESS_PRELOAD()
165 $meta = $class->TEST2_HARNESS_PRELOAD()
166 This export provides the meta object, which is an instance of this
167 class. This method being present is how Test2::Harness
168 differentiates between a regular module and a special preload
169 library.
170
171 stage NAME => sub { ... }
172 This creates a new stage with the given "NAME", and then runs the
173 coderef with the new stage set as the active one upon which the
174 other function here will operate. Once the coderef returns the
175 active stage is cleared.
176
177 You may nest stages by calling this function again inside the
178 codeblock.
179
180 NOTE: stage names ARE case sensitive. This can be confusing when
181 you consider that most harness directives are all-caps. In the
182 following case the stage requested by the test and the stage
183 defined in the library are NOT the same.
184
185 In a test file:
186
187 # HARNESS-STAGE-FOO
188
189 In a preload library:
190
191 stage foo { ... }
192
193 Harness directives are all-caps, however the user data portion need
194 not be, this is fine:
195
196 # HARNESS-STAGE-foo
197
198 However it is very easy to make the mistake of thinking it is case
199 insensitive. It is also easy to assume the 'foo' part of the
200 harness directive must be all caps. In many cases it is smart to
201 make your stage names all-caps.
202
203 preload $module_name
204 preload @module_names
205 preload sub { ... }
206 This MUST be called inside a stage() builder coderef.
207
208 This adds modules to the list of libraries to preload. Order is
209 preserved. You can also add coderefs to execute arbitrary code
210 between module loads.
211
212 The coderef is called with no arguments, and its return is ignored.
213
214 eager()
215 This MUST be called inside a stage() builder coderef.
216
217 This marks the active stage as being eager. An eager stage will
218 start running tests for nested stages if it finds itself with no
219 tests of its own to run before the nested stage can finish loading.
220 The idea here is to avoid unused test slots when possible allowing
221 for tests to complete sooner.
222
223 default()
224 This MUST be called inside a stage() builder coderef.
225
226 This MUST be called only once across "ALL" stages in a given
227 library.
228
229 If multiple preload libraries are loaded then the first default set
230 (based on load order) will be the default, others will notbe
231 honored.
232
233 $stage_name = file_stage($test_file)
234 This is optional. If defined this callback will have a chance to
235 look at all files that are going to be run and assign them a stage.
236 This may return undef or an empty list if it does not have a stage
237 to assign.
238
239 If multiple preload libraries define file_stage callbacks they will
240 be called in order, the first one to return a stage name will win.
241
242 If no file_stage callbacks provide a stage for a file then any
243 harness directives declaring a stage will be honored. If no stage
244 is ever assigned then the test will be run int he default stage.
245
246 pre_fork sub { ... }
247 This MUST be called inside a stage() builder coderef.
248
249 Add a callback to be run just before the preload-stage process
250 forks to run the test. Note that any state changes here can effect
251 future tests to be run.
252
253 post_fork sub { ... }
254 This MUST be called inside a stage() builder coderef.
255
256 Add a callback to be run just after the preload-stage process forks
257 to run the test. This is run as early as possible, things like $0
258 may not be set properly yet.
259
260 pre_launch sub { ... }
261 This MUST be called inside a stage() builder coderef.
262
263 Add a callback to be run just before control of the test process is
264 turned over to the test file itself. This is run as late as
265 possible, so things like $0 should be set properly.
266
268 This class is also the meta-object used to construct a preload library.
269 The methods are left undocumented as this is an implementation detail
270 and you are not intended to directly use this object.
271
273 The source code repository for Test2-Harness can be found at
274 http://github.com/Test-More/Test2-Harness/.
275
277 Chad Granum <exodist@cpan.org>
278
280 Chad Granum <exodist@cpan.org>
281
283 Copyright 2020 Chad Granum <exodist7@gmail.com>.
284
285 This program is free software; you can redistribute it and/or modify it
286 under the same terms as Perl itself.
287
288 See http://dev.perl.org/licenses/
289
290
291
292perl v5.36.1 2023-10-04Test2::Harness::Runner::Preload(3)