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