]> git.ipfire.org Git - thirdparty/openssl.git/blame - util/perl/OpenSSL/Test.pm
lhash.c: Replace Unicode EN DASH with the ASCII char '-'.
[thirdparty/openssl.git] / util / perl / OpenSSL / Test.pm
CommitLineData
ac3d0e13
RS
1# Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
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
RL
95 # 1 (for success) or 0 (for failure). This is the status value that run()
96 # will give back (through the |statusvar| referens and as returned value
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
RL
478 } else {
479 system("$prefix$cmd");
34a6a9b1
RL
480 }
481 $e = ($? & 0x7f) ? ($? & 0x7f)|0x80 : ($? >> 8);
482 $r = $hooks{exit_checker}->($e);
483 if ($opts{statusvar}) {
484 ${$opts{statusvar}} = $r;
aec27d4d
RL
485 }
486
78e91586
RL
487 if ($ENV{HARNESS_ACTIVE} && !$ENV{HARNESS_VERBOSE}) {
488 close STDOUT;
489 close STDERR;
81b538e5
RL
490 open STDOUT, '>&', $save_STDOUT or die "Can't restore STDOUT: $!";
491 open STDERR, '>&', $save_STDERR or die "Can't restore STDERR: $!";
78e91586 492 }
78e91586 493
349232d1 494 print STDERR "$prefix$display_cmd => $e\n"
3eefcea1
RL
495 if !$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE};
496
aec27d4d
RL
497 # At this point, $? stops being interesting, and unfortunately,
498 # there are Test::More versions that get picky if we leave it
499 # non-zero.
500 $? = 0;
501
aec27d4d
RL
502 if ($opts{capture}) {
503 return @r;
504 } else {
505 return $r;
506 }
507}
508
f5098edb
RL
509END {
510 my $tb = Test::More->builder;
511 my $failure = scalar(grep { $_ == 0; } $tb->summary);
512 if ($failure && $end_with_bailout) {
513 BAIL_OUT("Stoptest!");
514 }
515}
516
517=head2 Utility functions
518
519The following functions are exported on request when using C<OpenSSL::Test>.
520
42e0ccdf
RL
521 # To only get the bldtop_file and srctop_file functions.
522 use OpenSSL::Test qw/bldtop_file srctop_file/;
f5098edb 523
42e0ccdf
RL
524 # To only get the bldtop_file function in addition to the default ones.
525 use OpenSSL::Test qw/:DEFAULT bldtop_file/;
f5098edb
RL
526
527=cut
528
529# Utility functions, exported on request
530
531=over 4
532
42e0ccdf 533=item B<bldtop_dir LIST>
f5098edb
RL
534
535LIST is a list of directories that make up a path from the top of the OpenSSL
42e0ccdf
RL
536build directory (as indicated by the environment variable C<$TOP> or
537C<$BLDTOP>).
538C<bldtop_dir> returns the resulting directory as a string, adapted to the local
f5098edb
RL
539operating system.
540
541=back
542
543=cut
544
42e0ccdf
RL
545sub bldtop_dir {
546 return __bldtop_dir(@_); # This caters for operating systems that have
f5098edb
RL
547 # a very distinct syntax for directories.
548}
549
550=over 4
551
42e0ccdf 552=item B<bldtop_file LIST, FILENAME>
f5098edb
RL
553
554LIST is a list of directories that make up a path from the top of the OpenSSL
42e0ccdf
RL
555build directory (as indicated by the environment variable C<$TOP> or
556C<$BLDTOP>) and FILENAME is the name of a file located in that directory path.
557C<bldtop_file> returns the resulting file path as a string, adapted to the local
f5098edb
RL
558operating system.
559
560=back
561
562=cut
563
42e0ccdf
RL
564sub bldtop_file {
565 return __bldtop_file(@_);
566}
567
568=over 4
569
570=item B<srctop_dir LIST>
571
572LIST is a list of directories that make up a path from the top of the OpenSSL
573source directory (as indicated by the environment variable C<$TOP> or
574C<$SRCTOP>).
575C<srctop_dir> returns the resulting directory as a string, adapted to the local
576operating system.
577
578=back
579
580=cut
581
582sub srctop_dir {
583 return __srctop_dir(@_); # This caters for operating systems that have
584 # a very distinct syntax for directories.
585}
586
587=over 4
588
589=item B<srctop_file LIST, FILENAME>
590
591LIST is a list of directories that make up a path from the top of the OpenSSL
592source directory (as indicated by the environment variable C<$TOP> or
593C<$SRCTOP>) and FILENAME is the name of a file located in that directory path.
594C<srctop_file> returns the resulting file path as a string, adapted to the local
595operating system.
596
597=back
598
599=cut
600
601sub srctop_file {
602 return __srctop_file(@_);
f5098edb
RL
603}
604
605=over 4
606
6c6a2ae6
RL
607=item B<data_file LIST, FILENAME>
608
609LIST is a list of directories that make up a path from the data directory
610associated with the test (see L</DESCRIPTION> above) and FILENAME is the name
611of a file located in that directory path. C<data_file> returns the resulting
612file path as a string, adapted to the local operating system.
613
614=back
615
616=cut
617
618sub data_file {
619 return __data_file(@_);
620}
621
622=over 4
623
f5098edb
RL
624=item B<pipe LIST>
625
626LIST is a list of CODEREFs returned by C<app> or C<test>, from which C<pipe>
627creates a new command composed of all the given commands put together in a
628pipe. C<pipe> returns a new CODEREF in the same manner as C<app> or C<test>,
629to be passed to C<run> for execution.
630
631=back
632
633=cut
634
aec27d4d
RL
635sub pipe {
636 my @cmds = @_;
637 return
638 sub {
639 my @cs = ();
640 my @dcs = ();
641 my @els = ();
642 my $counter = 0;
643 foreach (@cmds) {
644 my ($c, $dc, @el) = $_->(++$counter);
645
646 return () if !$c;
647
648 push @cs, $c;
649 push @dcs, $dc;
650 push @els, @el;
651 }
652 return (
653 join(" | ", @cs),
654 join(" | ", @dcs),
655 @els
656 );
657 };
658}
659
f5098edb
RL
660=over 4
661
662=item B<with HASHREF, CODEREF>
663
664C<with> will temporarly install hooks given by the HASHREF and then execute
665the given CODEREF. Hooks are usually expected to have a coderef as value.
666
667The currently available hoosk are:
668
669=over 4
670
671=item B<exit_checker =E<gt> CODEREF>
672
673This hook is executed after C<run> has performed its given command. The
674CODEREF receives the exit code as only argument and is expected to return
6751 (if the exit code indicated success) or 0 (if the exit code indicated
676failure).
677
678=back
679
680=back
681
682=cut
683
684sub with {
685 my $opts = shift;
686 my %opts = %{$opts};
687 my $codeblock = shift;
688
689 my %saved_hooks = ();
690
691 foreach (keys %opts) {
692 $saved_hooks{$_} = $hooks{$_} if exists($hooks{$_});
693 $hooks{$_} = $opts{$_};
694 }
695
696 $codeblock->();
697
698 foreach (keys %saved_hooks) {
699 $hooks{$_} = $saved_hooks{$_};
700 }
701}
702
703=over 4
704
cb2ceb18 705=item B<cmdstr CODEREF, OPTS>
f5098edb
RL
706
707C<cmdstr> takes a CODEREF from C<app> or C<test> and simply returns the
708command as a string.
709
cb2ceb18
RL
710C<cmdstr> takes some additiona options OPTS that affect the string returned:
711
712=over 4
713
714=item B<display =E<gt> 0|1>
715
716When set to 0, the returned string will be with all decorations, such as a
717possible redirect of stderr to the null device. This is suitable if the
718string is to be used directly in a recipe.
719
720When set to 1, the returned string will be without extra decorations. This
721is suitable for display if that is desired (doesn't confuse people with all
722internal stuff), or if it's used to pass a command down to a subprocess.
723
724Default: 0
725
726=back
727
f5098edb
RL
728=back
729
730=cut
731
732sub cmdstr {
b843cdb1 733 my ($cmd, $display_cmd) = shift->(0);
cb2ceb18 734 my %opts = @_;
f5098edb 735
cb2ceb18
RL
736 if ($opts{display}) {
737 return $display_cmd;
738 } else {
739 return $cmd;
740 }
f5098edb
RL
741}
742
743=over 4
744
745=item B<quotify LIST>
746
747LIST is a list of strings that are going to be used as arguments for a
748command, and makes sure to inject quotes and escapes as necessary depending
749on the content of each string.
750
751This can also be used to put quotes around the executable of a command.
752I<This must never ever be done on VMS.>
753
754=back
755
756=cut
aec27d4d
RL
757
758sub quotify {
759 # Unix setup (default if nothing else is mentioned)
760 my $arg_formatter =
761 sub { $_ = shift; /\s|[\{\}\\\$\[\]\*\?\|\&:;<>]/ ? "'$_'" : $_ };
762
763 if ( $^O eq "VMS") { # VMS setup
764 $arg_formatter = sub {
765 $_ = shift;
766 if (/\s|["[:upper:]]/) {
767 s/"/""/g;
768 '"'.$_.'"';
769 } else {
770 $_;
771 }
772 };
773 } elsif ( $^O eq "MSWin32") { # MSWin setup
774 $arg_formatter = sub {
775 $_ = shift;
776 if (/\s|["\|\&\*\;<>]/) {
777 s/(["\\])/\\$1/g;
778 '"'.$_.'"';
779 } else {
780 $_;
781 }
782 };
783 }
784
785 return map { $arg_formatter->($_) } @_;
786}
787
f5098edb
RL
788######################################################################
789# private functions. These are never exported.
790
791=head1 ENVIRONMENT
792
793OpenSSL::Test depends on some environment variables.
794
795=over 4
796
797=item B<TOP>
798
799This environment variable is mandatory. C<setup> will check that it's
800defined and that it's a directory that contains the file C<Configure>.
801If this isn't so, C<setup> will C<BAIL_OUT>.
802
803=item B<BIN_D>
804
805If defined, its value should be the directory where the openssl application
806is located. Defaults to C<$TOP/apps> (adapted to the operating system).
807
808=item B<TEST_D>
809
810If defined, its value should be the directory where the test applications
811are located. Defaults to C<$TOP/test> (adapted to the operating system).
812
f5098edb
RL
813=item B<STOPTEST>
814
815If defined, it puts testing in a different mode, where a recipe with
816failures will result in a C<BAIL_OUT> at the end of its run.
817
818=back
819
820=cut
821
822sub __env {
6c6a2ae6
RL
823 (my $recipe_datadir = basename($0)) =~ s/\.t$/_data/i;
824
42e0ccdf
RL
825 $directories{SRCTOP} = $ENV{SRCTOP} || $ENV{TOP};
826 $directories{BLDTOP} = $ENV{BLDTOP} || $ENV{TOP};
fbd361ea
RL
827 $directories{BLDAPPS} = $ENV{BIN_D} || __bldtop_dir("apps");
828 $directories{SRCAPPS} = __srctop_dir("apps");
90d28f05
BL
829 $directories{BLDFUZZ} = __bldtop_dir("fuzz");
830 $directories{SRCFUZZ} = __srctop_dir("fuzz");
fbd361ea
RL
831 $directories{BLDTEST} = $ENV{TEST_D} || __bldtop_dir("test");
832 $directories{SRCTEST} = __srctop_dir("test");
6c6a2ae6
RL
833 $directories{SRCDATA} = __srctop_dir("test", "recipes",
834 $recipe_datadir);
fbd361ea 835 $directories{RESULTS} = $ENV{RESULT_D} || $directories{BLDTEST};
f5098edb 836
d1094383
RL
837 push @direnv, "TOP" if $ENV{TOP};
838 push @direnv, "SRCTOP" if $ENV{SRCTOP};
839 push @direnv, "BLDTOP" if $ENV{BLDTOP};
840 push @direnv, "BIN_D" if $ENV{BIN_D};
841 push @direnv, "TEST_D" if $ENV{TEST_D};
842 push @direnv, "RESULT_D" if $ENV{RESULT_D};
843
f5098edb
RL
844 $end_with_bailout = $ENV{STOPTEST} ? 1 : 0;
845};
846
28e0f6eb
RL
847# __srctop_file and __srctop_dir are helpers to build file and directory
848# names on top of the source directory. They depend on $SRCTOP, and
849# therefore on the proper use of setup() and when needed, indir().
850# __bldtop_file and __bldtop_dir do the same thing but relative to $BLDTOP.
851# __srctop_file and __bldtop_file take the same kind of argument as
852# File::Spec::Functions::catfile.
853# Similarly, __srctop_dir and __bldtop_dir take the same kind of argument
854# as File::Spec::Functions::catdir
42e0ccdf
RL
855sub __srctop_file {
856 BAIL_OUT("Must run setup() first") if (! $test_name);
857
858 my $f = pop;
859 return catfile($directories{SRCTOP},@_,$f);
860}
861
862sub __srctop_dir {
863 BAIL_OUT("Must run setup() first") if (! $test_name);
864
865 return catdir($directories{SRCTOP},@_);
866}
867
868sub __bldtop_file {
f5098edb
RL
869 BAIL_OUT("Must run setup() first") if (! $test_name);
870
871 my $f = pop;
42e0ccdf 872 return catfile($directories{BLDTOP},@_,$f);
f5098edb
RL
873}
874
42e0ccdf 875sub __bldtop_dir {
4ada8be2
AP
876 BAIL_OUT("Must run setup() first") if (! $test_name);
877
42e0ccdf 878 return catdir($directories{BLDTOP},@_);
4ada8be2
AP
879}
880
28e0f6eb
RL
881# __exeext is a function that returns the platform dependent file extension
882# for executable binaries, or the value of the environment variable $EXE_EXT
883# if that one is defined.
d8a52304
RL
884sub __exeext {
885 my $ext = "";
886 if ($^O eq "VMS" ) { # VMS
887 $ext = ".exe";
888 } elsif ($^O eq "MSWin32") { # Windows
889 $ext = ".exe";
890 }
891 return $ENV{"EXE_EXT"} || $ext;
892}
893
28e0f6eb
RL
894# __test_file, __apps_file and __fuzz_file return the full path to a file
895# relative to the test/, apps/ or fuzz/ directory in the build tree or the
896# source tree, depending on where the file is found. Note that when looking
897# in the build tree, the file name with an added extension is looked for, if
898# an extension is given. The intent is to look for executable binaries (in
899# the build tree) or possibly scripts (in the source tree).
900# These functions all take the same arguments as File::Spec::Functions::catfile,
901# *plus* a mandatory extension argument. This extension argument can be undef,
902# and is ignored in such a case.
f5098edb
RL
903sub __test_file {
904 BAIL_OUT("Must run setup() first") if (! $test_name);
905
9ddf67f3 906 my $e = pop || "";
3732f12c 907 my $f = pop;
9b9a8a71
RL
908 my $out = catfile($directories{BLDTEST},@_,$f . $e);
909 $out = catfile($directories{SRCTEST},@_,$f) unless -f $out;
910 return $out;
a00c84f6
RL
911}
912
f5098edb
RL
913sub __apps_file {
914 BAIL_OUT("Must run setup() first") if (! $test_name);
915
9ddf67f3 916 my $e = pop || "";
3732f12c 917 my $f = pop;
9b9a8a71
RL
918 my $out = catfile($directories{BLDAPPS},@_,$f . $e);
919 $out = catfile($directories{SRCAPPS},@_,$f) unless -f $out;
920 return $out;
f5098edb
RL
921}
922
90d28f05
BL
923sub __fuzz_file {
924 BAIL_OUT("Must run setup() first") if (! $test_name);
925
9ddf67f3 926 my $e = pop || "";
90d28f05 927 my $f = pop;
9b9a8a71
RL
928 my $out = catfile($directories{BLDFUZZ},@_,$f . $e);
929 $out = catfile($directories{SRCFUZZ},@_,$f) unless -f $out;
930 return $out;
90d28f05
BL
931}
932
6c6a2ae6
RL
933sub __data_file {
934 BAIL_OUT("Must run setup() first") if (! $test_name);
935
936 my $f = pop;
937 return catfile($directories{SRCDATA},@_,$f);
938}
939
f5098edb
RL
940sub __results_file {
941 BAIL_OUT("Must run setup() first") if (! $test_name);
942
943 my $f = pop;
944 return catfile($directories{RESULTS},@_,$f);
945}
946
28e0f6eb
RL
947# __cwd DIR
948# __cwd DIR, OPTS
949#
950# __cwd changes directory to DIR (string) and changes all the relative
951# entries in %directories accordingly. OPTS is an optional series of
952# hash style arguments to alter __cwd's behavior:
953#
954# create = 0|1 The directory we move to is created if 1, not if 0.
955# cleanup = 0|1 The directory we move from is removed if 1, not if 0.
956
f5098edb 957sub __cwd {
11b3313c 958 my $dir = catdir(shift);
f5098edb
RL
959 my %opts = @_;
960 my $abscurdir = rel2abs(curdir());
961 my $absdir = rel2abs($dir);
962 my $reverse = abs2rel($abscurdir, $absdir);
963
964 # PARANOIA: if we're not moving anywhere, we do nothing more
965 if ($abscurdir eq $absdir) {
966 return $reverse;
967 }
968
969 # Do not support a move to a different volume for now. Maybe later.
970 BAIL_OUT("FAILURE: \"$dir\" moves to a different volume, not supported")
971 if $reverse eq $abscurdir;
972
973 # If someone happened to give a directory that leads back to the current,
974 # it's extremely silly to do anything more, so just simulate that we did
975 # move.
976 # In this case, we won't even clean it out, for safety's sake.
977 return "." if $reverse eq "";
978
979 $dir = canonpath($dir);
980 if ($opts{create}) {
981 mkpath($dir);
982 }
983
3da9eeb1
RL
984 # We are recalculating the directories we keep track of, but need to save
985 # away the result for after having moved into the new directory.
986 my %tmp_directories = ();
987 my %tmp_ENV = ();
f5098edb
RL
988
989 # For each of these directory variables, figure out where they are relative
990 # to the directory we want to move to if they aren't absolute (if they are,
991 # they don't change!)
42e0ccdf 992 my @dirtags = sort keys %directories;
f5098edb
RL
993 foreach (@dirtags) {
994 if (!file_name_is_absolute($directories{$_})) {
995 my $newpath = abs2rel(rel2abs($directories{$_}), rel2abs($dir));
3da9eeb1 996 $tmp_directories{$_} = $newpath;
f5098edb
RL
997 }
998 }
999
d1094383
RL
1000 # Treat each environment variable that was used to get us the values in
1001 # %directories the same was as the paths in %directories, so any sub
1002 # process can use their values properly as well
1003 foreach (@direnv) {
1004 if (!file_name_is_absolute($ENV{$_})) {
1005 my $newpath = abs2rel(rel2abs($ENV{$_}), rel2abs($dir));
3da9eeb1 1006 $tmp_ENV{$_} = $newpath;
d1094383
RL
1007 }
1008 }
1009
3da9eeb1
RL
1010 # Should we just bail out here as well? I'm unsure.
1011 return undef unless chdir($dir);
1012
1013 if ($opts{cleanup}) {
1014 rmtree(".", { safe => 0, keep_root => 1 });
1015 }
1016
768a3eca
RL
1017 # We put back new values carefully. Doing the obvious
1018 # %directories = ( %tmp_irectories )
1019 # will clear out any value that happens to be an absolute path
1020 foreach (keys %tmp_directories) {
1021 $directories{$_} = $tmp_directories{$_};
1022 }
3da9eeb1
RL
1023 foreach (keys %tmp_ENV) {
1024 $ENV{$_} = $tmp_ENV{$_};
1025 }
1026
a00c84f6 1027 if ($debug) {
f5098edb 1028 print STDERR "DEBUG: __cwd(), directories and files:\n";
fbd361ea
RL
1029 print STDERR " \$directories{BLDTEST} = \"$directories{BLDTEST}\"\n";
1030 print STDERR " \$directories{SRCTEST} = \"$directories{SRCTEST}\"\n";
6c6a2ae6 1031 print STDERR " \$directories{SRCDATA} = \"$directories{SRCDATA}\"\n";
f5098edb 1032 print STDERR " \$directories{RESULTS} = \"$directories{RESULTS}\"\n";
fbd361ea
RL
1033 print STDERR " \$directories{BLDAPPS} = \"$directories{BLDAPPS}\"\n";
1034 print STDERR " \$directories{SRCAPPS} = \"$directories{SRCAPPS}\"\n";
42e0ccdf
RL
1035 print STDERR " \$directories{SRCTOP} = \"$directories{SRCTOP}\"\n";
1036 print STDERR " \$directories{BLDTOP} = \"$directories{BLDTOP}\"\n";
f5098edb
RL
1037 print STDERR "\n";
1038 print STDERR " current directory is \"",curdir(),"\"\n";
1039 print STDERR " the way back is \"$reverse\"\n";
1040 }
1041
1042 return $reverse;
1043}
1044
9ddf67f3
RL
1045# __wrap_cmd CMD
1046# __wrap_cmd CMD, EXE_SHELL
1047#
1048# __wrap_cmd "wraps" CMD (string) with a beginning command that makes sure
1049# the command gets executed with an appropriate environment. If EXE_SHELL
1050# is given, it is used as the beginning command.
1051#
1052# __wrap_cmd returns a list that should be used to build up a larger list
1053# of command tokens, or be joined together like this:
1054#
1055# join(" ", __wrap_cmd($cmd))
1056sub __wrap_cmd {
1057 my $cmd = shift;
ec307bcc 1058 my $exe_shell = shift;
f5098edb 1059
9ddf67f3 1060 my @prefix = ( __bldtop_file("util", "shlib_wrap.sh") );
f5098edb 1061
9ddf67f3
RL
1062 if(defined($exe_shell)) {
1063 @prefix = ( $exe_shell );
1064 } elsif ($^O eq "VMS" || $^O eq "MSWin32") {
1065 # VMS and Windows don't use any wrapper script for the moment
1066 @prefix = ();
1067 }
1068
1069 return (@prefix, $cmd);
1070}
1071
1072# __fixup_prg PROG
1073#
1074# __fixup_prg does whatever fixup is needed to execute an executable binary
1075# given by PROG (string).
1076#
1077# __fixup_prg returns a string with the possibly prefixed program path spec.
1078sub __fixup_prg {
1079 my $prog = shift;
1080
1081 my $prefix = "";
1082
1083 if ($^O eq "VMS" ) {
c10d1bc8 1084 $prefix = ($prog =~ /^(?:[\$a-z0-9_]+:)?[<\[]/i ? "mcr " : "mcr []");
f5098edb
RL
1085 }
1086
a00c84f6
RL
1087 if (defined($prog)) {
1088 # Make sure to quotify the program file on platforms that may
1089 # have spaces or similar in their path name.
1090 # To our knowledge, VMS is the exception where quotifying should
69687aa8 1091 # never happen.
a00c84f6
RL
1092 ($prog) = quotify($prog) unless $^O eq "VMS";
1093 return $prefix.$prog;
f5098edb
RL
1094 }
1095
1096 print STDERR "$prog not found\n";
1097 return undef;
1098}
1099
28e0f6eb
RL
1100# __decorate_cmd NUM, CMDARRAYREF
1101#
1102# __decorate_cmd takes a command number NUM and a command token array
1103# CMDARRAYREF, builds up a command string from them and decorates it
1104# with necessary redirections.
1105# __decorate_cmd returns a list of two strings, one with the command
1106# string to actually be used, the other to be displayed for the user.
1107# The reason these strings might differ is that we redirect stderr to
1108# the null device unless we're verbose and unless the user has
1109# explicitly specified a stderr redirection.
9ddf67f3 1110sub __decorate_cmd {
f5098edb
RL
1111 BAIL_OUT("Must run setup() first") if (! $test_name);
1112
1113 my $num = shift;
9ddf67f3 1114 my $cmd = shift;
b8fcd4f0 1115 my %opts = @_;
a00c84f6 1116
9ddf67f3 1117 my $cmdstr = join(" ", @$cmd);
f5098edb 1118 my $null = devnull();
f5098edb
RL
1119 my $fileornull = sub { $_[0] ? $_[0] : $null; };
1120 my $stdin = "";
1121 my $stdout = "";
1122 my $stderr = "";
1123 my $saved_stderr = undef;
1124 $stdin = " < ".$fileornull->($opts{stdin}) if exists($opts{stdin});
1125 $stdout= " > ".$fileornull->($opts{stdout}) if exists($opts{stdout});
1126 $stderr=" 2> ".$fileornull->($opts{stderr}) if exists($opts{stderr});
1127
9ddf67f3 1128 my $display_cmd = "$cmdstr$stdin$stdout$stderr";
b843cdb1
RL
1129
1130 $stderr=" 2> ".$null
1131 unless $stderr || !$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE};
1132
9ddf67f3 1133 $cmdstr .= "$stdin$stdout$stderr";
f5098edb 1134
a00c84f6 1135 if ($debug) {
9ddf67f3
RL
1136 print STDERR "DEBUG[__decorate_cmd]: \$cmdstr = \"$cmdstr\"\n";
1137 print STDERR "DEBUG[__decorate_cmd]: \$display_cmd = \"$display_cmd\"\n";
a00c84f6
RL
1138 }
1139
9ddf67f3 1140 return ($cmdstr, $display_cmd);
f5098edb
RL
1141}
1142
1143=head1 SEE ALSO
1144
1145L<Test::More>, L<Test::Harness>
1146
1147=head1 AUTHORS
1148
e3713c36 1149Richard Levitte E<lt>levitte@openssl.orgE<gt> with assistance and
f5098edb
RL
1150inspiration from Andy Polyakov E<lt>appro@openssl.org<gt>.
1151
1152=cut
1153
208d721a
RL
1154no warnings 'redefine';
1155sub subtest {
1156 $level++;
1157
1158 Test::More::subtest @_;
1159
1160 $level--;
1161};
1162
aec27d4d 11631;