]> git.ipfire.org Git - thirdparty/openssl.git/blame - util/perl/OpenSSL/Test.pm
OpenSSL::Test::quotify: put quotes around empty arguments
[thirdparty/openssl.git] / util / perl / OpenSSL / Test.pm
CommitLineData
71bb86f0 1# Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
ac3d0e13
RS
2#
3# Licensed under the OpenSSL license (the "License"). You may not use
4# this file except in compliance with the License. You can obtain a copy
5# in the file LICENSE in the source distribution or at
6# https://www.openssl.org/source/license.html
7
aec27d4d
RL
8package OpenSSL::Test;
9
10use strict;
11use warnings;
12
fd99c6b5
RL
13use Test::More 0.96;
14
aec27d4d
RL
15use Exporter;
16use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
42e0ccdf 17$VERSION = "0.8";
aec27d4d 18@ISA = qw(Exporter);
9ddf67f3 19@EXPORT = (@Test::More::EXPORT, qw(setup run indir cmd app fuzz test
208d721a 20 perlapp perltest subtest));
42e0ccdf
RL
21@EXPORT_OK = (@Test::More::EXPORT_OK, qw(bldtop_dir bldtop_file
22 srctop_dir srctop_file
6c6a2ae6 23 data_file
42e0ccdf 24 pipe with cmdstr quotify));
aec27d4d 25
f5098edb 26=head1 NAME
aec27d4d 27
f5098edb 28OpenSSL::Test - a private extension of Test::More
aec27d4d 29
f5098edb 30=head1 SYNOPSIS
aec27d4d 31
f5098edb 32 use OpenSSL::Test;
aec27d4d 33
f5098edb 34 setup("my_test_name");
aec27d4d 35
f5098edb 36 ok(run(app(["openssl", "version"])), "check for openssl presence");
caadc543 37
f5098edb
RL
38 indir "subdir" => sub {
39 ok(run(test(["sometest", "arg1"], stdout => "foo.txt")),
40 "run sometest with output to foo.txt");
41 };
aec27d4d 42
f5098edb 43=head1 DESCRIPTION
aec27d4d 44
f5098edb
RL
45This module is a private extension of L<Test::More> for testing OpenSSL.
46In addition to the Test::More functions, it also provides functions that
47easily find the diverse programs within a OpenSSL build tree, as well as
48some other useful functions.
aec27d4d 49
42e0ccdf
RL
50This module I<depends> on the environment variables C<$TOP> or C<$SRCTOP>
51and C<$BLDTOP>. Without one of the combinations it refuses to work.
52See L</ENVIRONMENT> below.
aec27d4d 53
6c6a2ae6
RL
54With each test recipe, a parallel data directory with (almost) the same name
55as the recipe is possible in the source directory tree. For example, for a
56recipe C<$SRCTOP/test/recipes/99-foo.t>, there could be a directory
57C<$SRCTOP/test/recipes/99-foo_data/>.
58
f5098edb 59=cut
aec27d4d 60
f5098edb
RL
61use File::Copy;
62use File::Spec::Functions qw/file_name_is_absolute curdir canonpath splitdir
63 catdir catfile splitpath catpath devnull abs2rel
64 rel2abs/;
4500a4cd 65use File::Path 2.00 qw/rmtree mkpath/;
6c6a2ae6 66use File::Basename;
aec27d4d 67
208d721a 68my $level = 0;
aec27d4d 69
f5098edb
RL
70# The name of the test. This is set by setup() and is used in the other
71# functions to verify that setup() has been used.
72my $test_name = undef;
aec27d4d 73
f5098edb
RL
74# Directories we want to keep track of TOP, APPS, TEST and RESULTS are the
75# ones we're interested in, corresponding to the environment variables TOP
42e0ccdf 76# (mandatory), BIN_D, TEST_D, UTIL_D and RESULT_D.
f5098edb 77my %directories = ();
aec27d4d 78
d1094383
RL
79# The environment variables that gave us the contents in %directories. These
80# get modified whenever we change directories, so that subprocesses can use
81# the values of those environment variables as well
82my @direnv = ();
83
f5098edb
RL
84# A bool saying if we shall stop all testing if the current recipe has failing
85# tests or not. This is set by setup() if the environment variable STOPTEST
86# is defined with a non-empty value.
87my $end_with_bailout = 0;
aec27d4d 88
f5098edb
RL
89# A set of hooks that is affected by with() and may be used in diverse places.
90# All hooks are expected to be CODE references.
91my %hooks = (
aec27d4d 92
f5098edb
RL
93 # exit_checker is used by run() directly after completion of a command.
94 # it receives the exit code from that command and is expected to return
089a45c5 95 # 1 (for success) or 0 (for failure). This is the status value that run()
46f4e1be 96 # will give back (through the |statusvar| reference and as returned value
089a45c5 97 # when capture => 1 doesn't apply).
f5098edb 98 exit_checker => sub { return shift == 0 ? 1 : 0 },
aec27d4d 99
f5098edb 100 );
aec27d4d 101
a00c84f6
RL
102# Debug flag, to be set manually when needed
103my $debug = 0;
104
f5098edb 105=head2 Main functions
aec27d4d 106
f5098edb 107The following functions are exported by default when using C<OpenSSL::Test>.
aec27d4d 108
f5098edb 109=cut
aec27d4d 110
f5098edb 111=over 4
aec27d4d 112
f5098edb 113=item B<setup "NAME">
aec27d4d 114
f5098edb
RL
115C<setup> is used for initial setup, and it is mandatory that it's used.
116If it's not used in a OpenSSL test recipe, the rest of the recipe will
117most likely refuse to run.
118
119C<setup> checks for environment variables (see L</ENVIRONMENT> below),
42e0ccdf
RL
120checks that C<$TOP/Configure> or C<$SRCTOP/Configure> exists, C<chdir>
121into the results directory (defined by the C<$RESULT_D> environment
122variable if defined, otherwise C<$BLDTOP/test> or C<$TOP/test>, whichever
123is defined).
f5098edb
RL
124
125=back
126
127=cut
aec27d4d
RL
128
129sub setup {
fa657fc8 130 my $old_test_name = $test_name;
aec27d4d
RL
131 $test_name = shift;
132
133 BAIL_OUT("setup() must receive a name") unless $test_name;
fa657fc8
RL
134 warn "setup() detected test name change. Innocuous, so we continue...\n"
135 if $old_test_name && $old_test_name ne $test_name;
136
137 return if $old_test_name;
138
42e0ccdf
RL
139 BAIL_OUT("setup() needs \$TOP or \$SRCTOP and \$BLDTOP to be defined")
140 unless $ENV{TOP} || ($ENV{SRCTOP} && $ENV{BLDTOP});
141 BAIL_OUT("setup() found both \$TOP and \$SRCTOP or \$BLDTOP...")
142 if $ENV{TOP} && ($ENV{SRCTOP} || $ENV{BLDTOP});
aec27d4d 143
f5098edb 144 __env();
caadc543 145
fa657fc8
RL
146 BAIL_OUT("setup() expects the file Configure in the source top directory")
147 unless -f srctop_file("Configure");
aec27d4d
RL
148
149 __cwd($directories{RESULTS});
aec27d4d
RL
150}
151
f5098edb
RL
152=over 4
153
154=item B<indir "SUBDIR" =E<gt> sub BLOCK, OPTS>
155
156C<indir> is used to run a part of the recipe in a different directory than
157the one C<setup> moved into, usually a subdirectory, given by SUBDIR.
158The part of the recipe that's run there is given by the codeblock BLOCK.
159
160C<indir> takes some additional options OPTS that affect the subdirectory:
161
162=over 4
163
164=item B<create =E<gt> 0|1>
165
166When set to 1 (or any value that perl preceives as true), the subdirectory
167will be created if it doesn't already exist. This happens before BLOCK
168is executed.
169
170=item B<cleanup =E<gt> 0|1>
171
172When set to 1 (or any value that perl preceives as true), the subdirectory
173will be cleaned out and removed. This happens both before and after BLOCK
174is executed.
175
176=back
177
178An example:
179
180 indir "foo" => sub {
181 ok(run(app(["openssl", "version"]), stdout => "foo.txt"));
182 if (ok(open(RESULT, "foo.txt"), "reading foo.txt")) {
183 my $line = <RESULT>;
184 close RESULT;
185 is($line, qr/^OpenSSL 1\./,
186 "check that we're using OpenSSL 1.x.x");
187 }
188 }, create => 1, cleanup => 1;
189
190=back
191
192=cut
193
aec27d4d
RL
194sub indir {
195 my $subdir = shift;
196 my $codeblock = shift;
197 my %opts = @_;
198
199 my $reverse = __cwd($subdir,%opts);
200 BAIL_OUT("FAILURE: indir, \"$subdir\" wasn't possible to move into")
201 unless $reverse;
202
203 $codeblock->();
204
205 __cwd($reverse);
206
207 if ($opts{cleanup}) {
4500a4cd 208 rmtree($subdir, { safe => 0 });
aec27d4d
RL
209 }
210}
211
f5098edb 212=over 4
aec27d4d 213
9ddf67f3 214=item B<cmd ARRAYREF, OPTS>
aec27d4d 215
9ddf67f3
RL
216This functions build up a platform dependent command based on the
217input. It takes a reference to a list that is the executable or
218script and its arguments, and some additional options (described
28e0f6eb
RL
219further on). Where necessary, the command will be wrapped in a
220suitable environment to make sure the correct shared libraries are
221used (currently only on Unix).
aec27d4d 222
9ddf67f3 223It returns a CODEREF to be used by C<run>, C<pipe> or C<cmdstr>.
aec27d4d 224
9ddf67f3 225The options that C<cmd> can take are in the form of hash values:
aec27d4d 226
f5098edb 227=over 4
aec27d4d 228
f5098edb 229=item B<stdin =E<gt> PATH>
aec27d4d 230
f5098edb 231=item B<stdout =E<gt> PATH>
aec27d4d 232
f5098edb 233=item B<stderr =E<gt> PATH>
aec27d4d 234
f5098edb
RL
235In all three cases, the corresponding standard input, output or error is
236redirected from (for stdin) or to (for the others) a file given by the
237string PATH, I<or>, if the value is C<undef>, C</dev/null> or similar.
aec27d4d 238
f5098edb 239=back
aec27d4d 240
9ddf67f3
RL
241=item B<app ARRAYREF, OPTS>
242
243=item B<test ARRAYREF, OPTS>
244
245Both of these are specific applications of C<cmd>, with just a couple
246of small difference:
247
248C<app> expects to find the given command (the first item in the given list
249reference) as an executable in C<$BIN_D> (if defined, otherwise C<$TOP/apps>
250or C<$BLDTOP/apps>).
251
252C<test> expects to find the given command (the first item in the given list
253reference) as an executable in C<$TEST_D> (if defined, otherwise C<$TOP/test>
254or C<$BLDTOP/test>).
255
256Also, for both C<app> and C<test>, the command may be prefixed with
257the content of the environment variable C<$EXE_SHELL>, which is useful
258in case OpenSSL has been cross compiled.
259
a00c84f6
RL
260=item B<perlapp ARRAYREF, OPTS>
261
262=item B<perltest ARRAYREF, OPTS>
263
9ddf67f3
RL
264These are also specific applications of C<cmd>, where the interpreter
265is predefined to be C<perl>, and they expect the script to be
266interpreted to reside in the same location as C<app> and C<test>.
267
268C<perlapp> and C<perltest> will also take the following option:
b8fcd4f0
RL
269
270=over 4
271
272=item B<interpreter_args =E<gt> ARRAYref>
273
9ddf67f3
RL
274The array reference is a set of arguments for the interpreter rather
275than the script. Take care so that none of them can be seen as a
276script! Flags and their eventual arguments only!
b8fcd4f0
RL
277
278=back
279
280An example:
281
282 ok(run(perlapp(["foo.pl", "arg1"],
283 interpreter_args => [ "-I", srctop_dir("test") ])));
a00c84f6 284
f5098edb 285=back
aec27d4d 286
9ddf67f3
RL
287=begin comment
288
289One might wonder over the complexity of C<apps>, C<fuzz>, C<test>, ...
290with all the lazy evaluations and all that. The reason for this is that
291we want to make sure the directory in which those programs are found are
292correct at the time these commands are used. Consider the following code
293snippet:
294
295 my $cmd = app(["openssl", ...]);
296
297 indir "foo", sub {
298 ok(run($cmd), "Testing foo")
299 };
300
301If there wasn't this lazy evaluation, the directory where C<openssl> is
302found would be incorrect at the time C<run> is called, because it was
303calculated before we moved into the directory "foo".
304
305=end comment
306
f5098edb 307=cut
aec27d4d 308
9ddf67f3
RL
309sub cmd {
310 my $cmd = shift;
311 my %opts = @_;
312 return sub {
313 my $num = shift;
314 # Make a copy to not destroy the caller's array
315 my @cmdargs = ( @$cmd );
316 my @prog = __wrap_cmd(shift @cmdargs, $opts{exe_shell} // ());
317
318 return __decorate_cmd($num, [ @prog, quotify(@cmdargs) ],
319 %opts);
320 }
321}
322
aec27d4d
RL
323sub app {
324 my $cmd = shift;
325 my %opts = @_;
9ddf67f3
RL
326 return sub {
327 my @cmdargs = ( @{$cmd} );
328 my @prog = __fixup_prg(__apps_file(shift @cmdargs, __exeext()));
329 return cmd([ @prog, @cmdargs ],
330 exe_shell => $ENV{EXE_SHELL}, %opts) -> (shift);
331 }
aec27d4d
RL
332}
333
90d28f05
BL
334sub fuzz {
335 my $cmd = shift;
336 my %opts = @_;
9ddf67f3
RL
337 return sub {
338 my @cmdargs = ( @{$cmd} );
339 my @prog = __fixup_prg(__fuzz_file(shift @cmdargs, __exeext()));
340 return cmd([ @prog, @cmdargs ],
341 exe_shell => $ENV{EXE_SHELL}, %opts) -> (shift);
342 }
90d28f05
BL
343}
344
aec27d4d
RL
345sub test {
346 my $cmd = shift;
347 my %opts = @_;
9ddf67f3
RL
348 return sub {
349 my @cmdargs = ( @{$cmd} );
350 my @prog = __fixup_prg(__test_file(shift @cmdargs, __exeext()));
351 return cmd([ @prog, @cmdargs ],
352 exe_shell => $ENV{EXE_SHELL}, %opts) -> (shift);
353 }
aec27d4d
RL
354}
355
a00c84f6
RL
356sub perlapp {
357 my $cmd = shift;
358 my %opts = @_;
9ddf67f3
RL
359 return sub {
360 my @interpreter_args = defined $opts{interpreter_args} ?
361 @{$opts{interpreter_args}} : ();
362 my @interpreter = __fixup_prg($^X);
363 my @cmdargs = ( @{$cmd} );
364 my @prog = __apps_file(shift @cmdargs, undef);
365 return cmd([ @interpreter, @interpreter_args,
366 @prog, @cmdargs ], %opts) -> (shift);
367 }
a00c84f6
RL
368}
369
370sub perltest {
371 my $cmd = shift;
372 my %opts = @_;
9ddf67f3
RL
373 return sub {
374 my @interpreter_args = defined $opts{interpreter_args} ?
375 @{$opts{interpreter_args}} : ();
376 my @interpreter = __fixup_prg($^X);
377 my @cmdargs = ( @{$cmd} );
378 my @prog = __test_file(shift @cmdargs, undef);
379 return cmd([ @interpreter, @interpreter_args,
380 @prog, @cmdargs ], %opts) -> (shift);
381 }
a00c84f6
RL
382}
383
f5098edb 384=over 4
aec27d4d 385
f5098edb
RL
386=item B<run CODEREF, OPTS>
387
9ddf67f3
RL
388CODEREF is expected to be the value return by C<cmd> or any of its
389derivatives, anything else will most likely cause an error unless you
390know what you're doing.
f5098edb
RL
391
392C<run> executes the command returned by CODEREF and return either the
9ddf67f3
RL
393resulting output (if the option C<capture> is set true) or a boolean
394indicating if the command succeeded or not.
f5098edb
RL
395
396The options that C<run> can take are in the form of hash values:
397
398=over 4
399
400=item B<capture =E<gt> 0|1>
401
402If true, the command will be executed with a perl backtick, and C<run> will
403return the resulting output as an array of lines. If false or not given,
404the command will be executed with C<system()>, and C<run> will return 1 if
405the command was successful or 0 if it wasn't.
406
f75f007c
RL
407=item B<prefix =E<gt> EXPR>
408
409If specified, EXPR will be used as a string to prefix the output from the
410command. This is useful if the output contains lines starting with C<ok >
411or C<not ok > that can disturb Test::Harness.
412
34a6a9b1
RL
413=item B<statusvar =E<gt> VARREF>
414
415If used, B<VARREF> must be a reference to a scalar variable. It will be
416assigned a boolean indicating if the command succeeded or not. This is
417particularly useful together with B<capture>.
418
f5098edb
RL
419=back
420
421For further discussion on what is considered a successful command or not, see
422the function C<with> further down.
423
424=back
425
426=cut
aec27d4d
RL
427
428sub run {
b843cdb1 429 my ($cmd, $display_cmd) = shift->(0);
aec27d4d
RL
430 my %opts = @_;
431
432 return () if !$cmd;
433
434 my $prefix = "";
435 if ( $^O eq "VMS" ) { # VMS
436 $prefix = "pipe ";
aec27d4d
RL
437 }
438
439 my @r = ();
440 my $r = 0;
441 my $e = 0;
2ef157af 442
34a6a9b1
RL
443 die "OpenSSL::Test::run(): statusvar value not a scalar reference"
444 if $opts{statusvar} && ref($opts{statusvar}) ne "SCALAR";
445
78e91586
RL
446 # In non-verbose, we want to shut up the command interpreter, in case
447 # it has something to complain about. On VMS, it might complain both
448 # on stdout and stderr
81b538e5
RL
449 my $save_STDOUT;
450 my $save_STDERR;
78e91586 451 if ($ENV{HARNESS_ACTIVE} && !$ENV{HARNESS_VERBOSE}) {
81b538e5
RL
452 open $save_STDOUT, '>&', \*STDOUT or die "Can't dup STDOUT: $!";
453 open $save_STDERR, '>&', \*STDERR or die "Can't dup STDERR: $!";
78e91586
RL
454 open STDOUT, ">", devnull();
455 open STDERR, ">", devnull();
456 }
457
208d721a
RL
458 $ENV{HARNESS_OSSL_LEVEL} = $level + 1;
459
2ef157af
RL
460 # The dance we do with $? is the same dance the Unix shells appear to
461 # do. For example, a program that gets aborted (and therefore signals
462 # SIGABRT = 6) will appear to exit with the code 134. We mimic this
463 # to make it easier to compare with a manual run of the command.
f75f007c
RL
464 if ($opts{capture} || defined($opts{prefix})) {
465 my $pipe;
93f725a3 466 local $_;
f75f007c
RL
467
468 open($pipe, '-|', "$prefix$cmd") or die "Can't start command: $!";
469 while(<$pipe>) {
470 my $l = ($opts{prefix} // "") . $_;
471 if ($opts{capture}) {
472 push @r, $l;
473 } else {
474 print STDOUT $l;
475 }
476 }
477 close $pipe;
aec27d4d 478 } else {
71bb86f0 479 $ENV{HARNESS_OSSL_PREFIX} = "# ";
aec27d4d 480 system("$prefix$cmd");
71bb86f0 481 delete $ENV{HARNESS_OSSL_PREFIX};
34a6a9b1
RL
482 }
483 $e = ($? & 0x7f) ? ($? & 0x7f)|0x80 : ($? >> 8);
484 $r = $hooks{exit_checker}->($e);
485 if ($opts{statusvar}) {
486 ${$opts{statusvar}} = $r;
aec27d4d
RL
487 }
488
78e91586
RL
489 if ($ENV{HARNESS_ACTIVE} && !$ENV{HARNESS_VERBOSE}) {
490 close STDOUT;
491 close STDERR;
81b538e5
RL
492 open STDOUT, '>&', $save_STDOUT or die "Can't restore STDOUT: $!";
493 open STDERR, '>&', $save_STDERR or die "Can't restore STDERR: $!";
78e91586 494 }
78e91586 495
349232d1 496 print STDERR "$prefix$display_cmd => $e\n"
3eefcea1
RL
497 if !$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE};
498
aec27d4d
RL
499 # At this point, $? stops being interesting, and unfortunately,
500 # there are Test::More versions that get picky if we leave it
501 # non-zero.
502 $? = 0;
503
aec27d4d
RL
504 if ($opts{capture}) {
505 return @r;
506 } else {
507 return $r;
508 }
509}
510
f5098edb
RL
511END {
512 my $tb = Test::More->builder;
513 my $failure = scalar(grep { $_ == 0; } $tb->summary);
514 if ($failure && $end_with_bailout) {
515 BAIL_OUT("Stoptest!");
516 }
517}
518
519=head2 Utility functions
520
521The following functions are exported on request when using C<OpenSSL::Test>.
522
42e0ccdf
RL
523 # To only get the bldtop_file and srctop_file functions.
524 use OpenSSL::Test qw/bldtop_file srctop_file/;
f5098edb 525
42e0ccdf
RL
526 # To only get the bldtop_file function in addition to the default ones.
527 use OpenSSL::Test qw/:DEFAULT bldtop_file/;
f5098edb
RL
528
529=cut
530
531# Utility functions, exported on request
532
533=over 4
534
42e0ccdf 535=item B<bldtop_dir LIST>
f5098edb
RL
536
537LIST is a list of directories that make up a path from the top of the OpenSSL
42e0ccdf
RL
538build directory (as indicated by the environment variable C<$TOP> or
539C<$BLDTOP>).
540C<bldtop_dir> returns the resulting directory as a string, adapted to the local
f5098edb
RL
541operating system.
542
543=back
544
545=cut
546
42e0ccdf
RL
547sub bldtop_dir {
548 return __bldtop_dir(@_); # This caters for operating systems that have
f5098edb
RL
549 # a very distinct syntax for directories.
550}
551
552=over 4
553
42e0ccdf 554=item B<bldtop_file LIST, FILENAME>
f5098edb
RL
555
556LIST is a list of directories that make up a path from the top of the OpenSSL
42e0ccdf
RL
557build directory (as indicated by the environment variable C<$TOP> or
558C<$BLDTOP>) and FILENAME is the name of a file located in that directory path.
559C<bldtop_file> returns the resulting file path as a string, adapted to the local
f5098edb
RL
560operating system.
561
562=back
563
564=cut
565
42e0ccdf
RL
566sub bldtop_file {
567 return __bldtop_file(@_);
568}
569
570=over 4
571
572=item B<srctop_dir LIST>
573
574LIST is a list of directories that make up a path from the top of the OpenSSL
575source directory (as indicated by the environment variable C<$TOP> or
576C<$SRCTOP>).
577C<srctop_dir> returns the resulting directory as a string, adapted to the local
578operating system.
579
580=back
581
582=cut
583
584sub srctop_dir {
585 return __srctop_dir(@_); # This caters for operating systems that have
586 # a very distinct syntax for directories.
587}
588
589=over 4
590
591=item B<srctop_file LIST, FILENAME>
592
593LIST is a list of directories that make up a path from the top of the OpenSSL
594source directory (as indicated by the environment variable C<$TOP> or
595C<$SRCTOP>) and FILENAME is the name of a file located in that directory path.
596C<srctop_file> returns the resulting file path as a string, adapted to the local
597operating system.
598
599=back
600
601=cut
602
603sub srctop_file {
604 return __srctop_file(@_);
f5098edb
RL
605}
606
607=over 4
608
6c6a2ae6
RL
609=item B<data_file LIST, FILENAME>
610
611LIST is a list of directories that make up a path from the data directory
612associated with the test (see L</DESCRIPTION> above) and FILENAME is the name
613of a file located in that directory path. C<data_file> returns the resulting
614file path as a string, adapted to the local operating system.
615
616=back
617
618=cut
619
620sub data_file {
621 return __data_file(@_);
622}
623
624=over 4
625
f5098edb
RL
626=item B<pipe LIST>
627
628LIST is a list of CODEREFs returned by C<app> or C<test>, from which C<pipe>
629creates a new command composed of all the given commands put together in a
630pipe. C<pipe> returns a new CODEREF in the same manner as C<app> or C<test>,
631to be passed to C<run> for execution.
632
633=back
634
635=cut
636
aec27d4d
RL
637sub pipe {
638 my @cmds = @_;
639 return
640 sub {
641 my @cs = ();
642 my @dcs = ();
643 my @els = ();
644 my $counter = 0;
645 foreach (@cmds) {
646 my ($c, $dc, @el) = $_->(++$counter);
647
648 return () if !$c;
649
650 push @cs, $c;
651 push @dcs, $dc;
652 push @els, @el;
653 }
654 return (
655 join(" | ", @cs),
656 join(" | ", @dcs),
657 @els
658 );
659 };
660}
661
f5098edb
RL
662=over 4
663
664=item B<with HASHREF, CODEREF>
665
46f4e1be 666C<with> will temporarily install hooks given by the HASHREF and then execute
f5098edb
RL
667the given CODEREF. Hooks are usually expected to have a coderef as value.
668
669The currently available hoosk are:
670
671=over 4
672
673=item B<exit_checker =E<gt> CODEREF>
674
675This hook is executed after C<run> has performed its given command. The
676CODEREF receives the exit code as only argument and is expected to return
6771 (if the exit code indicated success) or 0 (if the exit code indicated
678failure).
679
680=back
681
682=back
683
684=cut
685
686sub with {
687 my $opts = shift;
688 my %opts = %{$opts};
689 my $codeblock = shift;
690
691 my %saved_hooks = ();
692
693 foreach (keys %opts) {
694 $saved_hooks{$_} = $hooks{$_} if exists($hooks{$_});
695 $hooks{$_} = $opts{$_};
696 }
697
698 $codeblock->();
699
700 foreach (keys %saved_hooks) {
701 $hooks{$_} = $saved_hooks{$_};
702 }
703}
704
705=over 4
706
cb2ceb18 707=item B<cmdstr CODEREF, OPTS>
f5098edb
RL
708
709C<cmdstr> takes a CODEREF from C<app> or C<test> and simply returns the
710command as a string.
711
46f4e1be 712C<cmdstr> takes some additional options OPTS that affect the string returned:
cb2ceb18
RL
713
714=over 4
715
716=item B<display =E<gt> 0|1>
717
718When set to 0, the returned string will be with all decorations, such as a
719possible redirect of stderr to the null device. This is suitable if the
720string is to be used directly in a recipe.
721
722When set to 1, the returned string will be without extra decorations. This
723is suitable for display if that is desired (doesn't confuse people with all
724internal stuff), or if it's used to pass a command down to a subprocess.
725
726Default: 0
727
728=back
729
f5098edb
RL
730=back
731
732=cut
733
734sub cmdstr {
b843cdb1 735 my ($cmd, $display_cmd) = shift->(0);
cb2ceb18 736 my %opts = @_;
f5098edb 737
cb2ceb18
RL
738 if ($opts{display}) {
739 return $display_cmd;
740 } else {
741 return $cmd;
742 }
f5098edb
RL
743}
744
745=over 4
746
747=item B<quotify LIST>
748
749LIST is a list of strings that are going to be used as arguments for a
750command, and makes sure to inject quotes and escapes as necessary depending
751on the content of each string.
752
753This can also be used to put quotes around the executable of a command.
754I<This must never ever be done on VMS.>
755
756=back
757
758=cut
aec27d4d
RL
759
760sub quotify {
761 # Unix setup (default if nothing else is mentioned)
762 my $arg_formatter =
5845f7de
RL
763 sub { $_ = shift;
764 ($_ eq '' || /\s|[\{\}\\\$\[\]\*\?\|\&:;<>]/) ? "'$_'" : $_ };
aec27d4d
RL
765
766 if ( $^O eq "VMS") { # VMS setup
767 $arg_formatter = sub {
768 $_ = shift;
5845f7de 769 if ($_ eq '' || /\s|["[:upper:]]/) {
aec27d4d
RL
770 s/"/""/g;
771 '"'.$_.'"';
772 } else {
773 $_;
774 }
775 };
776 } elsif ( $^O eq "MSWin32") { # MSWin setup
777 $arg_formatter = sub {
778 $_ = shift;
5845f7de 779 if ($_ eq '' || /\s|["\|\&\*\;<>]/) {
aec27d4d
RL
780 s/(["\\])/\\$1/g;
781 '"'.$_.'"';
782 } else {
783 $_;
784 }
785 };
786 }
787
788 return map { $arg_formatter->($_) } @_;
789}
790
f5098edb
RL
791######################################################################
792# private functions. These are never exported.
793
794=head1 ENVIRONMENT
795
796OpenSSL::Test depends on some environment variables.
797
798=over 4
799
800=item B<TOP>
801
802This environment variable is mandatory. C<setup> will check that it's
803defined and that it's a directory that contains the file C<Configure>.
804If this isn't so, C<setup> will C<BAIL_OUT>.
805
806=item B<BIN_D>
807
808If defined, its value should be the directory where the openssl application
809is located. Defaults to C<$TOP/apps> (adapted to the operating system).
810
811=item B<TEST_D>
812
813If defined, its value should be the directory where the test applications
814are located. Defaults to C<$TOP/test> (adapted to the operating system).
815
f5098edb
RL
816=item B<STOPTEST>
817
818If defined, it puts testing in a different mode, where a recipe with
819failures will result in a C<BAIL_OUT> at the end of its run.
820
821=back
822
823=cut
824
825sub __env {
6c6a2ae6
RL
826 (my $recipe_datadir = basename($0)) =~ s/\.t$/_data/i;
827
42e0ccdf
RL
828 $directories{SRCTOP} = $ENV{SRCTOP} || $ENV{TOP};
829 $directories{BLDTOP} = $ENV{BLDTOP} || $ENV{TOP};
fbd361ea
RL
830 $directories{BLDAPPS} = $ENV{BIN_D} || __bldtop_dir("apps");
831 $directories{SRCAPPS} = __srctop_dir("apps");
90d28f05
BL
832 $directories{BLDFUZZ} = __bldtop_dir("fuzz");
833 $directories{SRCFUZZ} = __srctop_dir("fuzz");
fbd361ea
RL
834 $directories{BLDTEST} = $ENV{TEST_D} || __bldtop_dir("test");
835 $directories{SRCTEST} = __srctop_dir("test");
6c6a2ae6
RL
836 $directories{SRCDATA} = __srctop_dir("test", "recipes",
837 $recipe_datadir);
fbd361ea 838 $directories{RESULTS} = $ENV{RESULT_D} || $directories{BLDTEST};
f5098edb 839
d1094383
RL
840 push @direnv, "TOP" if $ENV{TOP};
841 push @direnv, "SRCTOP" if $ENV{SRCTOP};
842 push @direnv, "BLDTOP" if $ENV{BLDTOP};
843 push @direnv, "BIN_D" if $ENV{BIN_D};
844 push @direnv, "TEST_D" if $ENV{TEST_D};
845 push @direnv, "RESULT_D" if $ENV{RESULT_D};
846
f5098edb
RL
847 $end_with_bailout = $ENV{STOPTEST} ? 1 : 0;
848};
849
28e0f6eb
RL
850# __srctop_file and __srctop_dir are helpers to build file and directory
851# names on top of the source directory. They depend on $SRCTOP, and
852# therefore on the proper use of setup() and when needed, indir().
853# __bldtop_file and __bldtop_dir do the same thing but relative to $BLDTOP.
854# __srctop_file and __bldtop_file take the same kind of argument as
855# File::Spec::Functions::catfile.
856# Similarly, __srctop_dir and __bldtop_dir take the same kind of argument
857# as File::Spec::Functions::catdir
42e0ccdf
RL
858sub __srctop_file {
859 BAIL_OUT("Must run setup() first") if (! $test_name);
860
861 my $f = pop;
862 return catfile($directories{SRCTOP},@_,$f);
863}
864
865sub __srctop_dir {
866 BAIL_OUT("Must run setup() first") if (! $test_name);
867
868 return catdir($directories{SRCTOP},@_);
869}
870
871sub __bldtop_file {
f5098edb
RL
872 BAIL_OUT("Must run setup() first") if (! $test_name);
873
874 my $f = pop;
42e0ccdf 875 return catfile($directories{BLDTOP},@_,$f);
f5098edb
RL
876}
877
42e0ccdf 878sub __bldtop_dir {
4ada8be2
AP
879 BAIL_OUT("Must run setup() first") if (! $test_name);
880
42e0ccdf 881 return catdir($directories{BLDTOP},@_);
4ada8be2
AP
882}
883
28e0f6eb
RL
884# __exeext is a function that returns the platform dependent file extension
885# for executable binaries, or the value of the environment variable $EXE_EXT
886# if that one is defined.
d8a52304
RL
887sub __exeext {
888 my $ext = "";
889 if ($^O eq "VMS" ) { # VMS
890 $ext = ".exe";
891 } elsif ($^O eq "MSWin32") { # Windows
892 $ext = ".exe";
893 }
894 return $ENV{"EXE_EXT"} || $ext;
895}
896
28e0f6eb
RL
897# __test_file, __apps_file and __fuzz_file return the full path to a file
898# relative to the test/, apps/ or fuzz/ directory in the build tree or the
899# source tree, depending on where the file is found. Note that when looking
900# in the build tree, the file name with an added extension is looked for, if
901# an extension is given. The intent is to look for executable binaries (in
902# the build tree) or possibly scripts (in the source tree).
903# These functions all take the same arguments as File::Spec::Functions::catfile,
904# *plus* a mandatory extension argument. This extension argument can be undef,
905# and is ignored in such a case.
f5098edb
RL
906sub __test_file {
907 BAIL_OUT("Must run setup() first") if (! $test_name);
908
9ddf67f3 909 my $e = pop || "";
3732f12c 910 my $f = pop;
9b9a8a71
RL
911 my $out = catfile($directories{BLDTEST},@_,$f . $e);
912 $out = catfile($directories{SRCTEST},@_,$f) unless -f $out;
913 return $out;
a00c84f6
RL
914}
915
f5098edb
RL
916sub __apps_file {
917 BAIL_OUT("Must run setup() first") if (! $test_name);
918
9ddf67f3 919 my $e = pop || "";
3732f12c 920 my $f = pop;
9b9a8a71
RL
921 my $out = catfile($directories{BLDAPPS},@_,$f . $e);
922 $out = catfile($directories{SRCAPPS},@_,$f) unless -f $out;
923 return $out;
f5098edb
RL
924}
925
90d28f05
BL
926sub __fuzz_file {
927 BAIL_OUT("Must run setup() first") if (! $test_name);
928
9ddf67f3 929 my $e = pop || "";
90d28f05 930 my $f = pop;
9b9a8a71
RL
931 my $out = catfile($directories{BLDFUZZ},@_,$f . $e);
932 $out = catfile($directories{SRCFUZZ},@_,$f) unless -f $out;
933 return $out;
90d28f05
BL
934}
935
6c6a2ae6
RL
936sub __data_file {
937 BAIL_OUT("Must run setup() first") if (! $test_name);
938
939 my $f = pop;
940 return catfile($directories{SRCDATA},@_,$f);
941}
942
f5098edb
RL
943sub __results_file {
944 BAIL_OUT("Must run setup() first") if (! $test_name);
945
946 my $f = pop;
947 return catfile($directories{RESULTS},@_,$f);
948}
949
28e0f6eb
RL
950# __cwd DIR
951# __cwd DIR, OPTS
952#
953# __cwd changes directory to DIR (string) and changes all the relative
954# entries in %directories accordingly. OPTS is an optional series of
955# hash style arguments to alter __cwd's behavior:
956#
957# create = 0|1 The directory we move to is created if 1, not if 0.
958# cleanup = 0|1 The directory we move from is removed if 1, not if 0.
959
f5098edb 960sub __cwd {
11b3313c 961 my $dir = catdir(shift);
f5098edb
RL
962 my %opts = @_;
963 my $abscurdir = rel2abs(curdir());
964 my $absdir = rel2abs($dir);
965 my $reverse = abs2rel($abscurdir, $absdir);
966
967 # PARANOIA: if we're not moving anywhere, we do nothing more
968 if ($abscurdir eq $absdir) {
969 return $reverse;
970 }
971
972 # Do not support a move to a different volume for now. Maybe later.
973 BAIL_OUT("FAILURE: \"$dir\" moves to a different volume, not supported")
974 if $reverse eq $abscurdir;
975
976 # If someone happened to give a directory that leads back to the current,
977 # it's extremely silly to do anything more, so just simulate that we did
978 # move.
979 # In this case, we won't even clean it out, for safety's sake.
980 return "." if $reverse eq "";
981
982 $dir = canonpath($dir);
983 if ($opts{create}) {
984 mkpath($dir);
985 }
986
3da9eeb1
RL
987 # We are recalculating the directories we keep track of, but need to save
988 # away the result for after having moved into the new directory.
989 my %tmp_directories = ();
990 my %tmp_ENV = ();
f5098edb
RL
991
992 # For each of these directory variables, figure out where they are relative
993 # to the directory we want to move to if they aren't absolute (if they are,
994 # they don't change!)
42e0ccdf 995 my @dirtags = sort keys %directories;
f5098edb
RL
996 foreach (@dirtags) {
997 if (!file_name_is_absolute($directories{$_})) {
998 my $newpath = abs2rel(rel2abs($directories{$_}), rel2abs($dir));
3da9eeb1 999 $tmp_directories{$_} = $newpath;
f5098edb
RL
1000 }
1001 }
1002
d1094383
RL
1003 # Treat each environment variable that was used to get us the values in
1004 # %directories the same was as the paths in %directories, so any sub
1005 # process can use their values properly as well
1006 foreach (@direnv) {
1007 if (!file_name_is_absolute($ENV{$_})) {
1008 my $newpath = abs2rel(rel2abs($ENV{$_}), rel2abs($dir));
3da9eeb1 1009 $tmp_ENV{$_} = $newpath;
d1094383
RL
1010 }
1011 }
1012
3da9eeb1
RL
1013 # Should we just bail out here as well? I'm unsure.
1014 return undef unless chdir($dir);
1015
1016 if ($opts{cleanup}) {
1017 rmtree(".", { safe => 0, keep_root => 1 });
1018 }
1019
768a3eca 1020 # We put back new values carefully. Doing the obvious
46f4e1be 1021 # %directories = ( %tmp_directories )
768a3eca
RL
1022 # will clear out any value that happens to be an absolute path
1023 foreach (keys %tmp_directories) {
1024 $directories{$_} = $tmp_directories{$_};
1025 }
3da9eeb1
RL
1026 foreach (keys %tmp_ENV) {
1027 $ENV{$_} = $tmp_ENV{$_};
1028 }
1029
a00c84f6 1030 if ($debug) {
f5098edb 1031 print STDERR "DEBUG: __cwd(), directories and files:\n";
fbd361ea
RL
1032 print STDERR " \$directories{BLDTEST} = \"$directories{BLDTEST}\"\n";
1033 print STDERR " \$directories{SRCTEST} = \"$directories{SRCTEST}\"\n";
6c6a2ae6 1034 print STDERR " \$directories{SRCDATA} = \"$directories{SRCDATA}\"\n";
f5098edb 1035 print STDERR " \$directories{RESULTS} = \"$directories{RESULTS}\"\n";
fbd361ea
RL
1036 print STDERR " \$directories{BLDAPPS} = \"$directories{BLDAPPS}\"\n";
1037 print STDERR " \$directories{SRCAPPS} = \"$directories{SRCAPPS}\"\n";
42e0ccdf
RL
1038 print STDERR " \$directories{SRCTOP} = \"$directories{SRCTOP}\"\n";
1039 print STDERR " \$directories{BLDTOP} = \"$directories{BLDTOP}\"\n";
f5098edb
RL
1040 print STDERR "\n";
1041 print STDERR " current directory is \"",curdir(),"\"\n";
1042 print STDERR " the way back is \"$reverse\"\n";
1043 }
1044
1045 return $reverse;
1046}
1047
9ddf67f3
RL
1048# __wrap_cmd CMD
1049# __wrap_cmd CMD, EXE_SHELL
1050#
1051# __wrap_cmd "wraps" CMD (string) with a beginning command that makes sure
1052# the command gets executed with an appropriate environment. If EXE_SHELL
1053# is given, it is used as the beginning command.
1054#
1055# __wrap_cmd returns a list that should be used to build up a larger list
1056# of command tokens, or be joined together like this:
1057#
1058# join(" ", __wrap_cmd($cmd))
1059sub __wrap_cmd {
1060 my $cmd = shift;
ec307bcc 1061 my $exe_shell = shift;
f5098edb 1062
9ddf67f3 1063 my @prefix = ( __bldtop_file("util", "shlib_wrap.sh") );
f5098edb 1064
9ddf67f3
RL
1065 if(defined($exe_shell)) {
1066 @prefix = ( $exe_shell );
1067 } elsif ($^O eq "VMS" || $^O eq "MSWin32") {
1068 # VMS and Windows don't use any wrapper script for the moment
1069 @prefix = ();
1070 }
1071
1072 return (@prefix, $cmd);
1073}
1074
1075# __fixup_prg PROG
1076#
1077# __fixup_prg does whatever fixup is needed to execute an executable binary
1078# given by PROG (string).
1079#
1080# __fixup_prg returns a string with the possibly prefixed program path spec.
1081sub __fixup_prg {
1082 my $prog = shift;
1083
1084 my $prefix = "";
1085
1086 if ($^O eq "VMS" ) {
c10d1bc8 1087 $prefix = ($prog =~ /^(?:[\$a-z0-9_]+:)?[<\[]/i ? "mcr " : "mcr []");
f5098edb
RL
1088 }
1089
a00c84f6
RL
1090 if (defined($prog)) {
1091 # Make sure to quotify the program file on platforms that may
1092 # have spaces or similar in their path name.
1093 # To our knowledge, VMS is the exception where quotifying should
69687aa8 1094 # never happen.
a00c84f6
RL
1095 ($prog) = quotify($prog) unless $^O eq "VMS";
1096 return $prefix.$prog;
f5098edb
RL
1097 }
1098
1099 print STDERR "$prog not found\n";
1100 return undef;
1101}
1102
28e0f6eb
RL
1103# __decorate_cmd NUM, CMDARRAYREF
1104#
1105# __decorate_cmd takes a command number NUM and a command token array
1106# CMDARRAYREF, builds up a command string from them and decorates it
1107# with necessary redirections.
1108# __decorate_cmd returns a list of two strings, one with the command
1109# string to actually be used, the other to be displayed for the user.
1110# The reason these strings might differ is that we redirect stderr to
1111# the null device unless we're verbose and unless the user has
1112# explicitly specified a stderr redirection.
9ddf67f3 1113sub __decorate_cmd {
f5098edb
RL
1114 BAIL_OUT("Must run setup() first") if (! $test_name);
1115
1116 my $num = shift;
9ddf67f3 1117 my $cmd = shift;
b8fcd4f0 1118 my %opts = @_;
a00c84f6 1119
9ddf67f3 1120 my $cmdstr = join(" ", @$cmd);
f5098edb 1121 my $null = devnull();
f5098edb
RL
1122 my $fileornull = sub { $_[0] ? $_[0] : $null; };
1123 my $stdin = "";
1124 my $stdout = "";
1125 my $stderr = "";
1126 my $saved_stderr = undef;
1127 $stdin = " < ".$fileornull->($opts{stdin}) if exists($opts{stdin});
1128 $stdout= " > ".$fileornull->($opts{stdout}) if exists($opts{stdout});
1129 $stderr=" 2> ".$fileornull->($opts{stderr}) if exists($opts{stderr});
1130
9ddf67f3 1131 my $display_cmd = "$cmdstr$stdin$stdout$stderr";
b843cdb1
RL
1132
1133 $stderr=" 2> ".$null
1134 unless $stderr || !$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE};
1135
9ddf67f3 1136 $cmdstr .= "$stdin$stdout$stderr";
f5098edb 1137
a00c84f6 1138 if ($debug) {
9ddf67f3
RL
1139 print STDERR "DEBUG[__decorate_cmd]: \$cmdstr = \"$cmdstr\"\n";
1140 print STDERR "DEBUG[__decorate_cmd]: \$display_cmd = \"$display_cmd\"\n";
a00c84f6
RL
1141 }
1142
9ddf67f3 1143 return ($cmdstr, $display_cmd);
f5098edb
RL
1144}
1145
1146=head1 SEE ALSO
1147
1148L<Test::More>, L<Test::Harness>
1149
1150=head1 AUTHORS
1151
e3713c36 1152Richard Levitte E<lt>levitte@openssl.orgE<gt> with assistance and
f5098edb
RL
1153inspiration from Andy Polyakov E<lt>appro@openssl.org<gt>.
1154
1155=cut
1156
208d721a
RL
1157no warnings 'redefine';
1158sub subtest {
1159 $level++;
1160
1161 Test::More::subtest @_;
1162
1163 $level--;
1164};
1165
aec27d4d 11661;