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