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