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