1package App::Yath::Options::Run;
2use strict;
3use warnings;
4
5our $VERSION = '1.000082';
6
7use Test2::Harness::Util::UUID qw/gen_uuid/;
8
9use App::Yath::Options;
10
11option_group {prefix => 'run', category => "Run Options", builds => 'Test2::Harness::Run'} => sub {
12    post \&post_process;
13
14    option link => (
15        field => 'links',
16        type => 'm',
17        long_examples  => [
18            " 'https://travis.work/builds/42'",
19            " 'https://jenkins.work/job/42'",
20            " 'https://buildbot.work/builders/foo/builds/42'",
21        ],
22        description => "Provide one or more links people can follow to see more about this run."
23    );
24
25    option test_args => (
26        type => 'm',
27        description => 'Arguments to pass in as @ARGV for all tests that are run. These can be provided easier using the \'::\' argument separator.'
28    );
29
30    option input => (
31        type        => 's',
32        description => 'Input string to be used as standard input for ALL tests. See also: --input-file',
33    );
34
35    option input_file => (
36        type        => 's',
37        description => 'Use the specified file as standard input to ALL tests',
38        action      => sub {
39            my ($prefix, $field, $raw, $norm, $slot, $settings, $handler) = @_;
40
41            die "Input file not found: $norm\n" unless -f $norm;
42            if ($settings->run->input) {
43                warn "Input file is overriding another source of input.\n";
44                $settings->run->field(input => undef);
45            }
46
47            $handler->($slot, $norm);
48        },
49    );
50
51    option dbi_profiling => (
52        type => 'b',
53        description => "Use Test2::Plugin::DBIProfile to collect database profiling data",
54    );
55
56    option author_testing => (
57        short        => 'A',
58        description  => 'This will set the AUTHOR_TESTING environment to true',
59    );
60
61    option use_stream => (
62        name        => 'stream',
63        description => "Use the stream formatter (default is on)",
64        default     => 1,
65    );
66
67    option tap => (
68        field       => 'use_stream',
69        alt         => ['TAP', '--no-stream'],
70        normalize   => sub { $_[0] ? 0 : 1 },
71        description => "The TAP format is lossy and clunky. Test2::Harness normally uses a newer streaming format to receive test results. There are old/legacy tests where this causes problems, in which case setting --TAP or --no-stream can help."
72    );
73
74    option fields => (
75        type           => 'm',
76        short          => 'f',
77        long_examples  => [' name:details', ' JSON_STRING'],
78        short_examples => [' name:details', ' JSON_STRING'],
79        description    => "Add custom data to the harness run",
80        action         => \&fields_action,
81    );
82
83    option env_var => (
84        field          => 'env_vars',
85        short          => 'E',
86        type           => 'h',
87        long_examples  => [' VAR=VAL'],
88        short_examples => ['VAR=VAL', ' VAR=VAL'],
89        description    => 'Set environment variables to set when each test is run.',
90    );
91
92    option run_id => (
93        alt         => ['id'],
94        description => 'Set a specific run-id. (Default: a UUID)',
95        default     => \&gen_uuid,
96    );
97
98    option load => (
99        type        => 'm',
100        short       => 'm',
101        alt         => ['load-module'],
102        description => 'Load a module in each test (after fork). The "import" method is not called.',
103    );
104
105    option load_import => (
106        type  => 'H',
107        short => 'M',
108        alt   => ['loadim'],
109
110        long_examples  => [' Module', ' Module=import_arg1,arg2,...'],
111        short_examples => [' Module', ' Module=import_arg1,arg2,...'],
112
113        description => 'Load a module in each test (after fork). Import is called.',
114    );
115
116    option event_uuids => (
117        default => 1,
118        alt => ['uuids'],
119        description => 'Use Test2::Plugin::UUID inside tests (default: on)',
120    );
121
122    option mem_usage => (
123        default => 1,
124        description => 'Use Test2::Plugin::MemUsage inside tests (default: on)',
125    );
126
127    option io_events => (
128        default => 0,
129        description => 'Use Test2::Plugin::IOEvents inside tests to turn all prints into test2 events (default: off)',
130    );
131
132    option retry => (
133        default => 0,
134        short => 'r',
135        type => 's',
136        description => 'Run any jobs that failed a second time. NOTE: --retry=1 means failing tests will be attempted twice!',
137    );
138
139    option retry_isolated => (
140        default => 0,
141        alt => ['retry-iso'],
142        type => 'b',
143        description => 'If true then any job retries will be done in isolation (as though -j1 was set)',
144    );
145};
146
147sub post_process {
148    my %params   = @_;
149    my $settings = $params{settings};
150
151    $settings->run->env_vars->{AUTHOR_TESTING} = 1 if $settings->run->author_testing;
152
153    if ($settings->run->dbi_profiling) {
154        eval { require Test2::Plugin::DBIProfile; 1 } or die "Could not enable DBI profiling, could not load 'Test2::Plugin::DBIProfile': $@";
155        push @{$settings->run->load_import->{'@'}} => 'Test2::Plugin::DBIProfile';
156        $settings->run->load_import->{'Test2::Plugin::DBIProfile'} = [];
157    }
158}
159
160sub fields_action {
161    my ($prefix, $field, $raw, $norm, $slot, $settings) = @_;
162
163    my $fields = ${$slot} //= [];
164
165    if ($norm =~ m/^{/) {
166        my $field = {};
167        my $ok    = eval { $field = Test2::Harness::Util::JSON::decode_json($norm); 1 };
168        chomp(my $error = $@ // '');
169
170        die "Error parsing field specification '$field': $error\n" unless $ok;
171        die "Fields must have a 'name' key (error in '$raw')\n"    unless $field->{name};
172        die "Fields must habe a 'details' key (error in '$raw')\n" unless $field->{details};
173
174        return push @$fields => $field;
175    }
176    elsif ($norm =~ m/([^:]+):([^:]+)/) {
177        return push @$fields => {name => $1, details => $2};
178    }
179
180    die "'$raw' is not a valid field specification.\n";
181}
182
1831;
184
185__END__
186
187=pod
188
189=encoding UTF-8
190
191=head1 NAME
192
193App::Yath::Options::Run - Run options for Yath.
194
195=head1 DESCRIPTION
196
197This is where command lines options for a single test run are defined.
198
199=head1 PROVIDED OPTIONS
200
201=head2 COMMAND OPTIONS
202
203=head3 Run Options
204
205=over 4
206
207=item --author-testing
208
209=item -A
210
211=item --no-author-testing
212
213This will set the AUTHOR_TESTING environment to true
214
215
216=item --dbi-profiling
217
218=item --no-dbi-profiling
219
220Use Test2::Plugin::DBIProfile to collect database profiling data
221
222
223=item --env-var VAR=VAL
224
225=item -EVAR=VAL
226
227=item -E VAR=VAL
228
229=item --no-env-var
230
231Set environment variables to set when each test is run.
232
233Can be specified multiple times
234
235
236=item --event-uuids
237
238=item --uuids
239
240=item --no-event-uuids
241
242Use Test2::Plugin::UUID inside tests (default: on)
243
244
245=item --fields name:details
246
247=item --fields JSON_STRING
248
249=item -f name:details
250
251=item -f JSON_STRING
252
253=item --no-fields
254
255Add custom data to the harness run
256
257Can be specified multiple times
258
259
260=item --input ARG
261
262=item --input=ARG
263
264=item --no-input
265
266Input string to be used as standard input for ALL tests. See also: --input-file
267
268
269=item --input-file ARG
270
271=item --input-file=ARG
272
273=item --no-input-file
274
275Use the specified file as standard input to ALL tests
276
277
278=item --io-events
279
280=item --no-io-events
281
282Use Test2::Plugin::IOEvents inside tests to turn all prints into test2 events (default: off)
283
284
285=item --link 'https://travis.work/builds/42'
286
287=item --link 'https://jenkins.work/job/42'
288
289=item --link 'https://buildbot.work/builders/foo/builds/42'
290
291=item --no-link
292
293Provide one or more links people can follow to see more about this run.
294
295Can be specified multiple times
296
297
298=item --load ARG
299
300=item --load=ARG
301
302=item --load-module ARG
303
304=item --load-module=ARG
305
306=item -m ARG
307
308=item -m=ARG
309
310=item --no-load
311
312Load a module in each test (after fork). The "import" method is not called.
313
314Can be specified multiple times
315
316
317=item --load-import Module
318
319=item --load-import Module=import_arg1,arg2,...
320
321=item --loadim Module
322
323=item --loadim Module=import_arg1,arg2,...
324
325=item -M Module
326
327=item -M Module=import_arg1,arg2,...
328
329=item --no-load-import
330
331Load a module in each test (after fork). Import is called.
332
333Can be specified multiple times. If the same key is listed multiple times the value lists will be appended together.
334
335
336=item --mem-usage
337
338=item --no-mem-usage
339
340Use Test2::Plugin::MemUsage inside tests (default: on)
341
342
343=item --retry ARG
344
345=item --retry=ARG
346
347=item -r ARG
348
349=item -r=ARG
350
351=item --no-retry
352
353Run any jobs that failed a second time. NOTE: --retry=1 means failing tests will be attempted twice!
354
355
356=item --retry-isolated
357
358=item --retry-iso
359
360=item --no-retry-isolated
361
362If true then any job retries will be done in isolation (as though -j1 was set)
363
364
365=item --run-id
366
367=item --id
368
369=item --no-run-id
370
371Set a specific run-id. (Default: a UUID)
372
373
374=item --test-args ARG
375
376=item --test-args=ARG
377
378=item --no-test-args
379
380Arguments to pass in as @ARGV for all tests that are run. These can be provided easier using the '::' argument separator.
381
382Can be specified multiple times
383
384
385=item --stream
386
387=item --no-stream
388
389Use the stream formatter (default is on)
390
391
392=item --tap
393
394=item --TAP
395
396=item ----no-stream
397
398=item --no-tap
399
400The TAP format is lossy and clunky. Test2::Harness normally uses a newer streaming format to receive test results. There are old/legacy tests where this causes problems, in which case setting --TAP or --no-stream can help.
401
402
403=back
404
405=head1 SOURCE
406
407The source code repository for Test2-Harness can be found at
408F<http://github.com/Test-More/Test2-Harness/>.
409
410=head1 MAINTAINERS
411
412=over 4
413
414=item Chad Granum E<lt>exodist@cpan.orgE<gt>
415
416=back
417
418=head1 AUTHORS
419
420=over 4
421
422=item Chad Granum E<lt>exodist@cpan.orgE<gt>
423
424=back
425
426=head1 COPYRIGHT
427
428Copyright 2020 Chad Granum E<lt>exodist7@gmail.comE<gt>.
429
430This program is free software; you can redistribute it and/or
431modify it under the same terms as Perl itself.
432
433See F<http://dev.perl.org/licenses/>
434
435=cut
436