# Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
#
# Licensed under the OpenSSL license (the "License").  You may not use
# this file except in compliance with the License.  You can obtain a copy
# in the file LICENSE in the source distribution or at
# https://www.openssl.org/source/license.html

package OpenSSL::Test;

use strict;
use warnings;

use Test::More 0.96;

use Exporter;
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
$VERSION = "0.8";
@ISA = qw(Exporter);
@EXPORT = (@Test::More::EXPORT, qw(setup run indir cmd app fuzz test
                                   perlapp perltest));
@EXPORT_OK = (@Test::More::EXPORT_OK, qw(bldtop_dir bldtop_file
                                         srctop_dir srctop_file
                                         pipe with cmdstr quotify));

=head1 NAME

OpenSSL::Test - a private extension of Test::More

=head1 SYNOPSIS

  use OpenSSL::Test;

  setup("my_test_name");

  ok(run(app(["openssl", "version"])), "check for openssl presence");

  indir "subdir" => sub {
    ok(run(test(["sometest", "arg1"], stdout => "foo.txt")),
       "run sometest with output to foo.txt");
  };

=head1 DESCRIPTION

This module is a private extension of L<Test::More> for testing OpenSSL.
In addition to the Test::More functions, it also provides functions that
easily find the diverse programs within a OpenSSL build tree, as well as
some other useful functions.

This module I<depends> on the environment variables C<$TOP> or C<$SRCTOP>
and C<$BLDTOP>.  Without one of the combinations it refuses to work.
See L</ENVIRONMENT> below.

=cut

use File::Copy;
use File::Spec::Functions qw/file_name_is_absolute curdir canonpath splitdir
                             catdir catfile splitpath catpath devnull abs2rel
                             rel2abs/;
use File::Path 2.00 qw/rmtree mkpath/;


# The name of the test.  This is set by setup() and is used in the other
# functions to verify that setup() has been used.
my $test_name = undef;

# Directories we want to keep track of TOP, APPS, TEST and RESULTS are the
# ones we're interested in, corresponding to the environment variables TOP
# (mandatory), BIN_D, TEST_D, UTIL_D and RESULT_D.
my %directories = ();

# The environment variables that gave us the contents in %directories.  These
# get modified whenever we change directories, so that subprocesses can use
# the values of those environment variables as well
my @direnv = ();

# A bool saying if we shall stop all testing if the current recipe has failing
# tests or not.  This is set by setup() if the environment variable STOPTEST
# is defined with a non-empty value.
my $end_with_bailout = 0;

# A set of hooks that is affected by with() and may be used in diverse places.
# All hooks are expected to be CODE references.
my %hooks = (

    # exit_checker is used by run() directly after completion of a command.
    # it receives the exit code from that command and is expected to return
    # 1 (for success) or 0 (for failure).  This is the value that will be
    # returned by run().
    # NOTE: When run() gets the option 'capture => 1', this hook is ignored.
    exit_checker => sub { return shift == 0 ? 1 : 0 },

    );

# Debug flag, to be set manually when needed
my $debug = 0;

=head2 Main functions

The following functions are exported by default when using C<OpenSSL::Test>.

=cut

=over 4

=item B<setup "NAME">

C<setup> is used for initial setup, and it is mandatory that it's used.
If it's not used in a OpenSSL test recipe, the rest of the recipe will
most likely refuse to run.

C<setup> checks for environment variables (see L</ENVIRONMENT> below),
checks that C<$TOP/Configure> or C<$SRCTOP/Configure> exists, C<chdir>
into the results directory (defined by the C<$RESULT_D> environment
variable if defined, otherwise C<$BLDTOP/test> or C<$TOP/test>, whichever
is defined).

=back

=cut

sub setup {
    my $old_test_name = $test_name;
    $test_name = shift;

    BAIL_OUT("setup() must receive a name") unless $test_name;
    warn "setup() detected test name change.  Innocuous, so we continue...\n"
        if $old_test_name && $old_test_name ne $test_name;

    return if $old_test_name;

    BAIL_OUT("setup() needs \$TOP or \$SRCTOP and \$BLDTOP to be defined")
        unless $ENV{TOP} || ($ENV{SRCTOP} && $ENV{BLDTOP});
    BAIL_OUT("setup() found both \$TOP and \$SRCTOP or \$BLDTOP...")
        if $ENV{TOP} && ($ENV{SRCTOP} || $ENV{BLDTOP});

    __env();

    BAIL_OUT("setup() expects the file Configure in the source top directory")
        unless -f srctop_file("Configure");

    __cwd($directories{RESULTS});
}

=over 4

=item B<indir "SUBDIR" =E<gt> sub BLOCK, OPTS>

C<indir> is used to run a part of the recipe in a different directory than
the one C<setup> moved into, usually a subdirectory, given by SUBDIR.
The part of the recipe that's run there is given by the codeblock BLOCK.

C<indir> takes some additional options OPTS that affect the subdirectory:

=over 4

=item B<create =E<gt> 0|1>

When set to 1 (or any value that perl preceives as true), the subdirectory
will be created if it doesn't already exist.  This happens before BLOCK
is executed.

=item B<cleanup =E<gt> 0|1>

When set to 1 (or any value that perl preceives as true), the subdirectory
will be cleaned out and removed.  This happens both before and after BLOCK
is executed.

=back

An example:

  indir "foo" => sub {
      ok(run(app(["openssl", "version"]), stdout => "foo.txt"));
      if (ok(open(RESULT, "foo.txt"), "reading foo.txt")) {
          my $line = <RESULT>;
          close RESULT;
          is($line, qr/^OpenSSL 1\./,
             "check that we're using OpenSSL 1.x.x");
      }
  }, create => 1, cleanup => 1;

=back

=cut

sub indir {
    my $subdir = shift;
    my $codeblock = shift;
    my %opts = @_;

    my $reverse = __cwd($subdir,%opts);
    BAIL_OUT("FAILURE: indir, \"$subdir\" wasn't possible to move into")
	unless $reverse;

    $codeblock->();

    __cwd($reverse);

    if ($opts{cleanup}) {
	rmtree($subdir, { safe => 0 });
    }
}

=over 4

=item B<cmd ARRAYREF, OPTS>

This functions build up a platform dependent command based on the
input.  It takes a reference to a list that is the executable or
script and its arguments, and some additional options (described
further on).  Where necessary, the command will be wrapped in a
suitable environment to make sure the correct shared libraries are
used (currently only on Unix).

It returns a CODEREF to be used by C<run>, C<pipe> or C<cmdstr>.

The options that C<cmd> can take are in the form of hash values:

=over 4

=item B<stdin =E<gt> PATH>

=item B<stdout =E<gt> PATH>

=item B<stderr =E<gt> PATH>

In all three cases, the corresponding standard input, output or error is
redirected from (for stdin) or to (for the others) a file given by the
string PATH, I<or>, if the value is C<undef>, C</dev/null> or similar.

=back

=item B<app ARRAYREF, OPTS>

=item B<test ARRAYREF, OPTS>

Both of these are specific applications of C<cmd>, with just a couple
of small difference:

C<app> expects to find the given command (the first item in the given list
reference) as an executable in C<$BIN_D> (if defined, otherwise C<$TOP/apps>
or C<$BLDTOP/apps>).

C<test> expects to find the given command (the first item in the given list
reference) as an executable in C<$TEST_D> (if defined, otherwise C<$TOP/test>
or C<$BLDTOP/test>).

Also, for both C<app> and C<test>, the command may be prefixed with
the content of the environment variable C<$EXE_SHELL>, which is useful
in case OpenSSL has been cross compiled.

=item B<perlapp ARRAYREF, OPTS>

=item B<perltest ARRAYREF, OPTS>

These are also specific applications of C<cmd>, where the interpreter
is predefined to be C<perl>, and they expect the script to be
interpreted to reside in the same location as C<app> and C<test>.

C<perlapp> and C<perltest> will also take the following option:

=over 4

=item B<interpreter_args =E<gt> ARRAYref>

The array reference is a set of arguments for the interpreter rather
than the script.  Take care so that none of them can be seen as a
script!  Flags and their eventual arguments only!

=back

An example:

  ok(run(perlapp(["foo.pl", "arg1"],
                 interpreter_args => [ "-I", srctop_dir("test") ])));

=back

=begin comment

One might wonder over the complexity of C<apps>, C<fuzz>, C<test>, ...
with all the lazy evaluations and all that.  The reason for this is that
we want to make sure the directory in which those programs are found are
correct at the time these commands are used.  Consider the following code
snippet:

  my $cmd = app(["openssl", ...]);

  indir "foo", sub {
      ok(run($cmd), "Testing foo")
  };

If there wasn't this lazy evaluation, the directory where C<openssl> is
found would be incorrect at the time C<run> is called, because it was
calculated before we moved into the directory "foo".

=end comment

=cut

sub cmd {
    my $cmd = shift;
    my %opts = @_;
    return sub {
        my $num = shift;
        # Make a copy to not destroy the caller's array
        my @cmdargs = ( @$cmd );
        my @prog = __wrap_cmd(shift @cmdargs, $opts{exe_shell} // ());

        return __decorate_cmd($num, [ @prog, quotify(@cmdargs) ],
                              %opts);
    }
}

sub app {
    my $cmd = shift;
    my %opts = @_;
    return sub {
        my @cmdargs = ( @{$cmd} );
        my @prog = __fixup_prg(__apps_file(shift @cmdargs, __exeext()));
        return cmd([ @prog, @cmdargs ],
                   exe_shell => $ENV{EXE_SHELL}, %opts) -> (shift);
    }
}

sub fuzz {
    my $cmd = shift;
    my %opts = @_;
    return sub {
        my @cmdargs = ( @{$cmd} );
        my @prog = __fixup_prg(__fuzz_file(shift @cmdargs, __exeext()));
        return cmd([ @prog, @cmdargs ],
                   exe_shell => $ENV{EXE_SHELL}, %opts) -> (shift);
    }
}

sub test {
    my $cmd = shift;
    my %opts = @_;
    return sub {
        my @cmdargs = ( @{$cmd} );
        my @prog = __fixup_prg(__test_file(shift @cmdargs, __exeext()));
        return cmd([ @prog, @cmdargs ],
                   exe_shell => $ENV{EXE_SHELL}, %opts) -> (shift);
    }
}

sub perlapp {
    my $cmd = shift;
    my %opts = @_;
    return sub {
        my @interpreter_args = defined $opts{interpreter_args} ?
            @{$opts{interpreter_args}} : ();
        my @interpreter = __fixup_prg($^X);
        my @cmdargs = ( @{$cmd} );
        my @prog = __apps_file(shift @cmdargs, undef);
        return cmd([ @interpreter, @interpreter_args,
                     @prog, @cmdargs ], %opts) -> (shift);
    }
}

sub perltest {
    my $cmd = shift;
    my %opts = @_;
    return sub {
        my @interpreter_args = defined $opts{interpreter_args} ?
            @{$opts{interpreter_args}} : ();
        my @interpreter = __fixup_prg($^X);
        my @cmdargs = ( @{$cmd} );
        my @prog = __test_file(shift @cmdargs, undef);
        return cmd([ @interpreter, @interpreter_args,
                     @prog, @cmdargs ], %opts) -> (shift);
    }
}

=over 4

=item B<run CODEREF, OPTS>

CODEREF is expected to be the value return by C<cmd> or any of its
derivatives, anything else will most likely cause an error unless you
know what you're doing.

C<run> executes the command returned by CODEREF and return either the
resulting output (if the option C<capture> is set true) or a boolean
indicating if the command succeeded or not.

The options that C<run> can take are in the form of hash values:

=over 4

=item B<capture =E<gt> 0|1>

If true, the command will be executed with a perl backtick, and C<run> will
return the resulting output as an array of lines.  If false or not given,
the command will be executed with C<system()>, and C<run> will return 1 if
the command was successful or 0 if it wasn't.

=back

For further discussion on what is considered a successful command or not, see
the function C<with> further down.

=back

=cut

sub run {
    my ($cmd, $display_cmd) = shift->(0);
    my %opts = @_;

    return () if !$cmd;

    my $prefix = "";
    if ( $^O eq "VMS" ) {	# VMS
	$prefix = "pipe ";
    }

    my @r = ();
    my $r = 0;
    my $e = 0;

    # In non-verbose, we want to shut up the command interpreter, in case
    # it has something to complain about.  On VMS, it might complain both
    # on stdout and stderr
    my $save_STDOUT;
    my $save_STDERR;
    if ($ENV{HARNESS_ACTIVE} && !$ENV{HARNESS_VERBOSE}) {
        open $save_STDOUT, '>&', \*STDOUT or die "Can't dup STDOUT: $!";
        open $save_STDERR, '>&', \*STDERR or die "Can't dup STDERR: $!";
        open STDOUT, ">", devnull();
        open STDERR, ">", devnull();
    }

    # The dance we do with $? is the same dance the Unix shells appear to
    # do.  For example, a program that gets aborted (and therefore signals
    # SIGABRT = 6) will appear to exit with the code 134.  We mimic this
    # to make it easier to compare with a manual run of the command.
    if ($opts{capture}) {
	@r = `$prefix$cmd`;
	$e = ($? & 0x7f) ? ($? & 0x7f)|0x80 : ($? >> 8);
    } else {
	system("$prefix$cmd");
	$e = ($? & 0x7f) ? ($? & 0x7f)|0x80 : ($? >> 8);
	$r = $hooks{exit_checker}->($e);
    }

    if ($ENV{HARNESS_ACTIVE} && !$ENV{HARNESS_VERBOSE}) {
        close STDOUT;
        close STDERR;
        open STDOUT, '>&', $save_STDOUT or die "Can't restore STDOUT: $!";
        open STDERR, '>&', $save_STDERR or die "Can't restore STDERR: $!";
    }

    print STDERR "$prefix$display_cmd => $e\n"
        if !$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE};

    # At this point, $? stops being interesting, and unfortunately,
    # there are Test::More versions that get picky if we leave it
    # non-zero.
    $? = 0;

    if ($opts{capture}) {
	return @r;
    } else {
	return $r;
    }
}

END {
    my $tb = Test::More->builder;
    my $failure = scalar(grep { $_ == 0; } $tb->summary);
    if ($failure && $end_with_bailout) {
	BAIL_OUT("Stoptest!");
    }
}

=head2 Utility functions

The following functions are exported on request when using C<OpenSSL::Test>.

  # To only get the bldtop_file and srctop_file functions.
  use OpenSSL::Test qw/bldtop_file srctop_file/;

  # To only get the bldtop_file function in addition to the default ones.
  use OpenSSL::Test qw/:DEFAULT bldtop_file/;

=cut

# Utility functions, exported on request

=over 4

=item B<bldtop_dir LIST>

LIST is a list of directories that make up a path from the top of the OpenSSL
build directory (as indicated by the environment variable C<$TOP> or
C<$BLDTOP>).
C<bldtop_dir> returns the resulting directory as a string, adapted to the local
operating system.

=back

=cut

sub bldtop_dir {
    return __bldtop_dir(@_);	# This caters for operating systems that have
				# a very distinct syntax for directories.
}

=over 4

=item B<bldtop_file LIST, FILENAME>

LIST is a list of directories that make up a path from the top of the OpenSSL
build directory (as indicated by the environment variable C<$TOP> or
C<$BLDTOP>) and FILENAME is the name of a file located in that directory path.
C<bldtop_file> returns the resulting file path as a string, adapted to the local
operating system.

=back

=cut

sub bldtop_file {
    return __bldtop_file(@_);
}

=over 4

=item B<srctop_dir LIST>

LIST is a list of directories that make up a path from the top of the OpenSSL
source directory (as indicated by the environment variable C<$TOP> or
C<$SRCTOP>).
C<srctop_dir> returns the resulting directory as a string, adapted to the local
operating system.

=back

=cut

sub srctop_dir {
    return __srctop_dir(@_);	# This caters for operating systems that have
				# a very distinct syntax for directories.
}

=over 4

=item B<srctop_file LIST, FILENAME>

LIST is a list of directories that make up a path from the top of the OpenSSL
source directory (as indicated by the environment variable C<$TOP> or
C<$SRCTOP>) and FILENAME is the name of a file located in that directory path.
C<srctop_file> returns the resulting file path as a string, adapted to the local
operating system.

=back

=cut

sub srctop_file {
    return __srctop_file(@_);
}

=over 4

=item B<pipe LIST>

LIST is a list of CODEREFs returned by C<app> or C<test>, from which C<pipe>
creates a new command composed of all the given commands put together in a
pipe.  C<pipe> returns a new CODEREF in the same manner as C<app> or C<test>,
to be passed to C<run> for execution.

=back

=cut

sub pipe {
    my @cmds = @_;
    return
	sub {
	    my @cs  = ();
	    my @dcs = ();
	    my @els = ();
	    my $counter = 0;
	    foreach (@cmds) {
		my ($c, $dc, @el) = $_->(++$counter);

		return () if !$c;

		push @cs, $c;
		push @dcs, $dc;
		push @els, @el;
	    }
	    return (
		join(" | ", @cs),
		join(" | ", @dcs),
		@els
		);
    };
}

=over 4

=item B<with HASHREF, CODEREF>

C<with> will temporarly install hooks given by the HASHREF and then execute
the given CODEREF.  Hooks are usually expected to have a coderef as value.

The currently available hoosk are:

=over 4

=item B<exit_checker =E<gt> CODEREF>

This hook is executed after C<run> has performed its given command.  The
CODEREF receives the exit code as only argument and is expected to return
1 (if the exit code indicated success) or 0 (if the exit code indicated
failure).

=back

=back

=cut

sub with {
    my $opts = shift;
    my %opts = %{$opts};
    my $codeblock = shift;

    my %saved_hooks = ();

    foreach (keys %opts) {
	$saved_hooks{$_} = $hooks{$_}	if exists($hooks{$_});
	$hooks{$_} = $opts{$_};
    }

    $codeblock->();

    foreach (keys %saved_hooks) {
	$hooks{$_} = $saved_hooks{$_};
    }
}

=over 4

=item B<cmdstr CODEREF, OPTS>

C<cmdstr> takes a CODEREF from C<app> or C<test> and simply returns the
command as a string.

C<cmdstr> takes some additiona options OPTS that affect the string returned:

=over 4

=item B<display =E<gt> 0|1>

When set to 0, the returned string will be with all decorations, such as a
possible redirect of stderr to the null device.  This is suitable if the
string is to be used directly in a recipe.

When set to 1, the returned string will be without extra decorations.  This
is suitable for display if that is desired (doesn't confuse people with all
internal stuff), or if it's used to pass a command down to a subprocess.

Default: 0

=back

=back

=cut

sub cmdstr {
    my ($cmd, $display_cmd) = shift->(0);
    my %opts = @_;

    if ($opts{display}) {
        return $display_cmd;
    } else {
        return $cmd;
    }
}

=over 4

=item B<quotify LIST>

LIST is a list of strings that are going to be used as arguments for a
command, and makes sure to inject quotes and escapes as necessary depending
on the content of each string.

This can also be used to put quotes around the executable of a command.
I<This must never ever be done on VMS.>

=back

=cut

sub quotify {
    # Unix setup (default if nothing else is mentioned)
    my $arg_formatter =
	sub { $_ = shift; /\s|[\{\}\\\$\[\]\*\?\|\&:;<>]/ ? "'$_'" : $_ };

    if ( $^O eq "VMS") {	# VMS setup
	$arg_formatter = sub {
	    $_ = shift;
	    if (/\s|["[:upper:]]/) {
		s/"/""/g;
		'"'.$_.'"';
	    } else {
		$_;
	    }
	};
    } elsif ( $^O eq "MSWin32") { # MSWin setup
	$arg_formatter = sub {
	    $_ = shift;
	    if (/\s|["\|\&\*\;<>]/) {
		s/(["\\])/\\$1/g;
		'"'.$_.'"';
	    } else {
		$_;
	    }
	};
    }

    return map { $arg_formatter->($_) } @_;
}

######################################################################
# private functions.  These are never exported.

=head1 ENVIRONMENT

OpenSSL::Test depends on some environment variables.

=over 4

=item B<TOP>

This environment variable is mandatory.  C<setup> will check that it's
defined and that it's a directory that contains the file C<Configure>.
If this isn't so, C<setup> will C<BAIL_OUT>.

=item B<BIN_D>

If defined, its value should be the directory where the openssl application
is located.  Defaults to C<$TOP/apps> (adapted to the operating system).

=item B<TEST_D>

If defined, its value should be the directory where the test applications
are located.  Defaults to C<$TOP/test> (adapted to the operating system).

=item B<STOPTEST>

If defined, it puts testing in a different mode, where a recipe with
failures will result in a C<BAIL_OUT> at the end of its run.

=back

=cut

sub __env {
    $directories{SRCTOP}  = $ENV{SRCTOP} || $ENV{TOP};
    $directories{BLDTOP}  = $ENV{BLDTOP} || $ENV{TOP};
    $directories{BLDAPPS} = $ENV{BIN_D}  || __bldtop_dir("apps");
    $directories{SRCAPPS} =                 __srctop_dir("apps");
    $directories{BLDFUZZ} =                 __bldtop_dir("fuzz");
    $directories{SRCFUZZ} =                 __srctop_dir("fuzz");
    $directories{BLDTEST} = $ENV{TEST_D} || __bldtop_dir("test");
    $directories{SRCTEST} =                 __srctop_dir("test");
    $directories{RESULTS} = $ENV{RESULT_D} || $directories{BLDTEST};

    push @direnv, "TOP"       if $ENV{TOP};
    push @direnv, "SRCTOP"    if $ENV{SRCTOP};
    push @direnv, "BLDTOP"    if $ENV{BLDTOP};
    push @direnv, "BIN_D"     if $ENV{BIN_D};
    push @direnv, "TEST_D"    if $ENV{TEST_D};
    push @direnv, "RESULT_D"  if $ENV{RESULT_D};

    $end_with_bailout	  = $ENV{STOPTEST} ? 1 : 0;
};

# __srctop_file and __srctop_dir are helpers to build file and directory
# names on top of the source directory.  They depend on $SRCTOP, and
# therefore on the proper use of setup() and when needed, indir().
# __bldtop_file and __bldtop_dir do the same thing but relative to $BLDTOP.
# __srctop_file and __bldtop_file take the same kind of argument as
# File::Spec::Functions::catfile.
# Similarly, __srctop_dir and __bldtop_dir take the same kind of argument
# as File::Spec::Functions::catdir
sub __srctop_file {
    BAIL_OUT("Must run setup() first") if (! $test_name);

    my $f = pop;
    return catfile($directories{SRCTOP},@_,$f);
}

sub __srctop_dir {
    BAIL_OUT("Must run setup() first") if (! $test_name);

    return catdir($directories{SRCTOP},@_);
}

sub __bldtop_file {
    BAIL_OUT("Must run setup() first") if (! $test_name);

    my $f = pop;
    return catfile($directories{BLDTOP},@_,$f);
}

sub __bldtop_dir {
    BAIL_OUT("Must run setup() first") if (! $test_name);

    return catdir($directories{BLDTOP},@_);
}

# __exeext is a function that returns the platform dependent file extension
# for executable binaries, or the value of the environment variable $EXE_EXT
# if that one is defined.
sub __exeext {
    my $ext = "";
    if ($^O eq "VMS" ) {	# VMS
	$ext = ".exe";
    } elsif ($^O eq "MSWin32") { # Windows
	$ext = ".exe";
    }
    return $ENV{"EXE_EXT"} || $ext;
}

# __test_file, __apps_file and __fuzz_file return the full path to a file
# relative to the test/, apps/ or fuzz/ directory in the build tree or the
# source tree, depending on where the file is found.  Note that when looking
# in the build tree, the file name with an added extension is looked for, if
# an extension is given.  The intent is to look for executable binaries (in
# the build tree) or possibly scripts (in the source tree).
# These functions all take the same arguments as File::Spec::Functions::catfile,
# *plus* a mandatory extension argument.  This extension argument can be undef,
# and is ignored in such a case.
sub __test_file {
    BAIL_OUT("Must run setup() first") if (! $test_name);

    my $e = pop || "";
    my $f = pop;
    $f = catfile($directories{BLDTEST},@_,$f . $e);
    $f = catfile($directories{SRCTEST},@_,$f) unless -f $f;
    return $f;
}

sub __apps_file {
    BAIL_OUT("Must run setup() first") if (! $test_name);

    my $e = pop || "";
    my $f = pop;
    $f = catfile($directories{BLDAPPS},@_,$f . $e);
    $f = catfile($directories{SRCAPPS},@_,$f) unless -f $f;
    return $f;
}

sub __fuzz_file {
    BAIL_OUT("Must run setup() first") if (! $test_name);

    my $e = pop || "";
    my $f = pop;
    $f = catfile($directories{BLDFUZZ},@_,$f . $e);
    $f = catfile($directories{SRCFUZZ},@_,$f) unless -f $f;
    return $f;
}

sub __results_file {
    BAIL_OUT("Must run setup() first") if (! $test_name);

    my $f = pop;
    return catfile($directories{RESULTS},@_,$f);
}

# __cwd DIR
# __cwd DIR, OPTS
#
# __cwd changes directory to DIR (string) and changes all the relative
# entries in %directories accordingly.  OPTS is an optional series of
# hash style arguments to alter __cwd's behavior:
#
#    create = 0|1       The directory we move to is created if 1, not if 0.
#    cleanup = 0|1      The directory we move from is removed if 1, not if 0.

sub __cwd {
    my $dir = catdir(shift);
    my %opts = @_;
    my $abscurdir = rel2abs(curdir());
    my $absdir = rel2abs($dir);
    my $reverse = abs2rel($abscurdir, $absdir);

    # PARANOIA: if we're not moving anywhere, we do nothing more
    if ($abscurdir eq $absdir) {
	return $reverse;
    }

    # Do not support a move to a different volume for now.  Maybe later.
    BAIL_OUT("FAILURE: \"$dir\" moves to a different volume, not supported")
	if $reverse eq $abscurdir;

    # If someone happened to give a directory that leads back to the current,
    # it's extremely silly to do anything more, so just simulate that we did
    # move.
    # In this case, we won't even clean it out, for safety's sake.
    return "." if $reverse eq "";

    $dir = canonpath($dir);
    if ($opts{create}) {
	mkpath($dir);
    }

    # We are recalculating the directories we keep track of, but need to save
    # away the result for after having moved into the new directory.
    my %tmp_directories = ();
    my %tmp_ENV = ();

    # For each of these directory variables, figure out where they are relative
    # to the directory we want to move to if they aren't absolute (if they are,
    # they don't change!)
    my @dirtags = sort keys %directories;
    foreach (@dirtags) {
	if (!file_name_is_absolute($directories{$_})) {
	    my $newpath = abs2rel(rel2abs($directories{$_}), rel2abs($dir));
	    $tmp_directories{$_} = $newpath;
	}
    }

    # Treat each environment variable that was used to get us the values in
    # %directories the same was as the paths in %directories, so any sub
    # process can use their values properly as well
    foreach (@direnv) {
	if (!file_name_is_absolute($ENV{$_})) {
	    my $newpath = abs2rel(rel2abs($ENV{$_}), rel2abs($dir));
	    $tmp_ENV{$_} = $newpath;
	}
    }

    # Should we just bail out here as well?  I'm unsure.
    return undef unless chdir($dir);

    if ($opts{cleanup}) {
	rmtree(".", { safe => 0, keep_root => 1 });
    }

    # We put back new values carefully.  Doing the obvious
    # %directories = ( %tmp_irectories )
    # will clear out any value that happens to be an absolute path
    foreach (keys %tmp_directories) {
        $directories{$_} = $tmp_directories{$_};
    }
    foreach (keys %tmp_ENV) {
        $ENV{$_} = $tmp_ENV{$_};
    }

    if ($debug) {
	print STDERR "DEBUG: __cwd(), directories and files:\n";
	print STDERR "  \$directories{BLDTEST} = \"$directories{BLDTEST}\"\n";
	print STDERR "  \$directories{SRCTEST} = \"$directories{SRCTEST}\"\n";
	print STDERR "  \$directories{RESULTS} = \"$directories{RESULTS}\"\n";
	print STDERR "  \$directories{BLDAPPS} = \"$directories{BLDAPPS}\"\n";
	print STDERR "  \$directories{SRCAPPS} = \"$directories{SRCAPPS}\"\n";
	print STDERR "  \$directories{SRCTOP}  = \"$directories{SRCTOP}\"\n";
	print STDERR "  \$directories{BLDTOP}  = \"$directories{BLDTOP}\"\n";
	print STDERR "\n";
	print STDERR "  current directory is \"",curdir(),"\"\n";
	print STDERR "  the way back is \"$reverse\"\n";
    }

    return $reverse;
}

# __wrap_cmd CMD
# __wrap_cmd CMD, EXE_SHELL
#
# __wrap_cmd "wraps" CMD (string) with a beginning command that makes sure
# the command gets executed with an appropriate environment.  If EXE_SHELL
# is given, it is used as the beginning command.
#
# __wrap_cmd returns a list that should be used to build up a larger list
# of command tokens, or be joined together like this:
#
#    join(" ", __wrap_cmd($cmd))
sub __wrap_cmd {
    my $cmd = shift;
    my $exe_shell = shift;

    my @prefix = ( __bldtop_file("util", "shlib_wrap.sh") );

    if(defined($exe_shell)) {
	@prefix = ( $exe_shell );
    } elsif ($^O eq "VMS" || $^O eq "MSWin32") {
	# VMS and Windows don't use any wrapper script for the moment
	@prefix = ();
    }

    return (@prefix, $cmd);
}

# __fixup_prg PROG
#
# __fixup_prg does whatever fixup is needed to execute an executable binary
# given by PROG (string).
#
# __fixup_prg returns a string with the possibly prefixed program path spec.
sub __fixup_prg {
    my $prog = shift;

    my $prefix = "";

    if ($^O eq "VMS" ) {
	$prefix = ($prog =~ /^(?:[\$a-z0-9_]+:)?[<\[]/i ? "mcr " : "mcr []");
    }

    # We test if the program to use exists.
    if ( ! -x $prog ) {
	$prog = undef;
    }

    if (defined($prog)) {
	# Make sure to quotify the program file on platforms that may
	# have spaces or similar in their path name.
	# To our knowledge, VMS is the exception where quotifying should
	# never happem.
	($prog) = quotify($prog) unless $^O eq "VMS";
	return $prefix.$prog;
    }

    print STDERR "$prog not found\n";
    return undef;
}

# __decorate_cmd NUM, CMDARRAYREF
#
# __decorate_cmd takes a command number NUM and a command token array
# CMDARRAYREF, builds up a command string from them and decorates it
# with necessary redirections.
# __decorate_cmd returns a list of two strings, one with the command
# string to actually be used, the other to be displayed for the user.
# The reason these strings might differ is that we redirect stderr to
# the null device unless we're verbose and unless the user has
# explicitly specified a stderr redirection.
sub __decorate_cmd {
    BAIL_OUT("Must run setup() first") if (! $test_name);

    my $num = shift;
    my $cmd = shift;
    my %opts = @_;

    my $cmdstr = join(" ", @$cmd);
    my $null = devnull();
    my $fileornull = sub { $_[0] ? $_[0] : $null; };
    my $stdin = "";
    my $stdout = "";
    my $stderr = "";
    my $saved_stderr = undef;
    $stdin = " < ".$fileornull->($opts{stdin})  if exists($opts{stdin});
    $stdout= " > ".$fileornull->($opts{stdout}) if exists($opts{stdout});
    $stderr=" 2> ".$fileornull->($opts{stderr}) if exists($opts{stderr});

    my $display_cmd = "$cmdstr$stdin$stdout$stderr";

    $stderr=" 2> ".$null
        unless $stderr || !$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE};

    $cmdstr .= "$stdin$stdout$stderr";

    if ($debug) {
	print STDERR "DEBUG[__decorate_cmd]: \$cmdstr = \"$cmdstr\"\n";
	print STDERR "DEBUG[__decorate_cmd]: \$display_cmd = \"$display_cmd\"\n";
    }

    return ($cmdstr, $display_cmd);
}

=head1 SEE ALSO

L<Test::More>, L<Test::Harness>

=head1 AUTHORS

Richard Levitte E<lt>levitte@openssl.orgE<gt> with assitance and
inspiration from Andy Polyakov E<lt>appro@openssl.org<gt>.

=cut

1;
