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