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 8 package OpenSSL::Test; 9 10 use strict; 11 use warnings; 12 13 use Test::More 0.96; 14 15 use Exporter; 16 use 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 29 OpenSSL::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 46 This module is a private extension of L<Test::More> for testing OpenSSL. 47 In addition to the Test::More functions, it also provides functions that 48 easily find the diverse programs within a OpenSSL build tree, as well as 49 some other useful functions. 50 51 This module I<depends> on the environment variables C<$TOP> or C<$SRCTOP> 52 and C<$BLDTOP>. Without one of the combinations it refuses to work. 53 See L</ENVIRONMENT> below. 54 55 With each test recipe, a parallel data directory with (almost) the same name 56 as the recipe is possible in the source directory tree. For example, for a 57 recipe C<$SRCTOP/test/recipes/99-foo.t>, there could be a directory 58 C<$SRCTOP/test/recipes/99-foo_data/>. 59 60 =cut 61 62 use File::Copy; 63 use File::Spec::Functions qw/file_name_is_absolute curdir canonpath splitdir 64 catdir catfile splitpath catpath devnull abs2rel 65 rel2abs/; 66 use File::Path 2.00 qw/rmtree mkpath/; 67 use File::Basename; 68 use Cwd qw/getcwd abs_path/; 69 70 my $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. 74 my $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. 79 my %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 84 my @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. 89 my $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. 93 my %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 105 my $debug = 0; 106 107 =head2 Main functions 108 109 The 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 117 C<setup> is used for initial setup, and it is mandatory that it's used. 118 If it's not used in a OpenSSL test recipe, the rest of the recipe will 119 most likely refuse to run. 120 121 C<setup> checks for environment variables (see L</ENVIRONMENT> below), 122 checks that C<$TOP/Configure> or C<$SRCTOP/Configure> exists, C<chdir> 123 into the results directory (defined by the C<$RESULT_D> environment 124 variable if defined, otherwise C<$BLDTOP/test> or C<$TOP/test>, whichever 125 is defined). 126 127 =back 128 129 =cut 130 131 sub 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 158 C<indir> is used to run a part of the recipe in a different directory than 159 the one C<setup> moved into, usually a subdirectory, given by SUBDIR. 160 The part of the recipe that's run there is given by the codeblock BLOCK. 161 162 C<indir> takes some additional options OPTS that affect the subdirectory: 163 164 =over 4 165 166 =item B<create =E<gt> 0|1> 167 168 When set to 1 (or any value that perl perceives as true), the subdirectory 169 will be created if it doesn't already exist. This happens before BLOCK 170 is executed. 171 172 =item B<cleanup =E<gt> 0|1> 173 174 When set to 1 (or any value that perl perceives as true), the subdirectory 175 will be cleaned out and removed. This happens both before and after BLOCK 176 is executed. 177 178 =back 179 180 An 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 196 sub 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 218 This functions build up a platform dependent command based on the 219 input. It takes a reference to a list that is the executable or 220 script and its arguments, and some additional options (described 221 further on). Where necessary, the command will be wrapped in a 222 suitable environment to make sure the correct shared libraries are 223 used (currently only on Unix). 224 225 It returns a CODEREF to be used by C<run>, C<pipe> or C<cmdstr>. 226 227 The 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 237 In all three cases, the corresponding standard input, output or error is 238 redirected from (for stdin) or to (for the others) a file given by the 239 string 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 247 Both of these are specific applications of C<cmd>, with just a couple 248 of small difference: 249 250 C<app> expects to find the given command (the first item in the given list 251 reference) as an executable in C<$BIN_D> (if defined, otherwise C<$TOP/apps> 252 or C<$BLDTOP/apps>). 253 254 C<test> expects to find the given command (the first item in the given list 255 reference) as an executable in C<$TEST_D> (if defined, otherwise C<$TOP/test> 256 or C<$BLDTOP/test>). 257 258 Also, for both C<app> and C<test>, the command may be prefixed with 259 the content of the environment variable C<$EXE_SHELL>, which is useful 260 in case OpenSSL has been cross compiled. 261 262 =item B<perlapp ARRAYREF, OPTS> 263 264 =item B<perltest ARRAYREF, OPTS> 265 266 These are also specific applications of C<cmd>, where the interpreter 267 is predefined to be C<perl>, and they expect the script to be 268 interpreted to reside in the same location as C<app> and C<test>. 269 270 C<perlapp> and C<perltest> will also take the following option: 271 272 =over 4 273 274 =item B<interpreter_args =E<gt> ARRAYref> 275 276 The array reference is a set of arguments for the interpreter rather 277 than the script. Take care so that none of them can be seen as a 278 script! Flags and their eventual arguments only! 279 280 =back 281 282 An example: 283 284 ok(run(perlapp(["foo.pl", "arg1"], 285 interpreter_args => [ "-I", srctop_dir("test") ]))); 286 287 =back 288 289 =begin comment 290 291 One might wonder over the complexity of C<apps>, C<fuzz>, C<test>, ... 292 with all the lazy evaluations and all that. The reason for this is that 293 we want to make sure the directory in which those programs are found are 294 correct at the time these commands are used. Consider the following code 295 snippet: 296 297 my $cmd = app(["openssl", ...]); 298 299 indir "foo", sub { 300 ok(run($cmd), "Testing foo") 301 }; 302 303 If there wasn't this lazy evaluation, the directory where C<openssl> is 304 found would be incorrect at the time C<run> is called, because it was 305 calculated before we moved into the directory "foo". 306 307 =end comment 308 309 =cut 310 311 sub 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 325 sub 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 336 sub 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 347 sub 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 358 sub 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 372 sub 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 390 CODEREF is expected to be the value return by C<cmd> or any of its 391 derivatives, anything else will most likely cause an error unless you 392 know what you're doing. 393 394 C<run> executes the command returned by CODEREF and return either the 395 resulting output (if the option C<capture> is set true) or a boolean 396 indicating if the command succeeded or not. 397 398 The 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 404 If true, the command will be executed with a perl backtick, and C<run> will 405 return the resulting output as an array of lines. If false or not given, 406 the command will be executed with C<system()>, and C<run> will return 1 if 407 the command was successful or 0 if it wasn't. 408 409 =item B<prefix =E<gt> EXPR> 410 411 If specified, EXPR will be used as a string to prefix the output from the 412 command. This is useful if the output contains lines starting with C<ok > 413 or C<not ok > that can disturb Test::Harness. 414 415 =item B<statusvar =E<gt> VARREF> 416 417 If used, B<VARREF> must be a reference to a scalar variable. It will be 418 assigned a boolean indicating if the command succeeded or not. This is 419 particularly useful together with B<capture>. 420 421 =back 422 423 For further discussion on what is considered a successful command or not, see 424 the function C<with> further down. 425 426 =back 427 428 =cut 429 430 sub 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 513 END { 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 523 The 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 539 LIST is a list of directories that make up a path from the top of the OpenSSL 540 build directory (as indicated by the environment variable C<$TOP> or 541 C<$BLDTOP>). 542 C<bldtop_dir> returns the resulting directory as a string, adapted to the local 543 operating system. 544 545 =back 546 547 =cut 548 549 sub 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 558 LIST is a list of directories that make up a path from the top of the OpenSSL 559 build directory (as indicated by the environment variable C<$TOP> or 560 C<$BLDTOP>) and FILENAME is the name of a file located in that directory path. 561 C<bldtop_file> returns the resulting file path as a string, adapted to the local 562 operating system. 563 564 =back 565 566 =cut 567 568 sub bldtop_file { 569 return __bldtop_file(@_); 570 } 571 572 =over 4 573 574 =item B<srctop_dir LIST> 575 576 LIST is a list of directories that make up a path from the top of the OpenSSL 577 source directory (as indicated by the environment variable C<$TOP> or 578 C<$SRCTOP>). 579 C<srctop_dir> returns the resulting directory as a string, adapted to the local 580 operating system. 581 582 =back 583 584 =cut 585 586 sub 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 595 LIST is a list of directories that make up a path from the top of the OpenSSL 596 source directory (as indicated by the environment variable C<$TOP> or 597 C<$SRCTOP>) and FILENAME is the name of a file located in that directory path. 598 C<srctop_file> returns the resulting file path as a string, adapted to the local 599 operating system. 600 601 =back 602 603 =cut 604 605 sub srctop_file { 606 return __srctop_file(@_); 607 } 608 609 =over 4 610 611 =item B<data_dir LIST> 612 613 LIST is a list of directories that make up a path from the data directory 614 associated with the test (see L</DESCRIPTION> above). 615 C<data_dir> returns the resulting directory as a string, adapted to the local 616 operating system. 617 618 =back 619 620 =cut 621 622 sub data_dir { 623 return __data_dir(@_); 624 } 625 626 =over 4 627 628 =item B<data_file LIST, FILENAME> 629 630 LIST is a list of directories that make up a path from the data directory 631 associated with the test (see L</DESCRIPTION> above) and FILENAME is the name 632 of a file located in that directory path. C<data_file> returns the resulting 633 file path as a string, adapted to the local operating system. 634 635 =back 636 637 =cut 638 639 sub data_file { 640 return __data_file(@_); 641 } 642 643 =over 4 644 645 =item B<pipe LIST> 646 647 LIST is a list of CODEREFs returned by C<app> or C<test>, from which C<pipe> 648 creates a new command composed of all the given commands put together in a 649 pipe. C<pipe> returns a new CODEREF in the same manner as C<app> or C<test>, 650 to be passed to C<run> for execution. 651 652 =back 653 654 =cut 655 656 sub 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 685 C<with> will temporarily install hooks given by the HASHREF and then execute 686 the given CODEREF. Hooks are usually expected to have a coderef as value. 687 688 The currently available hoosk are: 689 690 =over 4 691 692 =item B<exit_checker =E<gt> CODEREF> 693 694 This hook is executed after C<run> has performed its given command. The 695 CODEREF receives the exit code as only argument and is expected to return 696 1 (if the exit code indicated success) or 0 (if the exit code indicated 697 failure). 698 699 =back 700 701 =back 702 703 =cut 704 705 sub 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 728 C<cmdstr> takes a CODEREF from C<app> or C<test> and simply returns the 729 command as a string. 730 731 C<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 737 When set to 0, the returned string will be with all decorations, such as a 738 possible redirect of stderr to the null device. This is suitable if the 739 string is to be used directly in a recipe. 740 741 When set to 1, the returned string will be without extra decorations. This 742 is suitable for display if that is desired (doesn't confuse people with all 743 internal stuff), or if it's used to pass a command down to a subprocess. 744 745 Default: 0 746 747 =back 748 749 =back 750 751 =cut 752 753 sub 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 768 LIST is a list of strings that are going to be used as arguments for a 769 command, and makes sure to inject quotes and escapes as necessary depending 770 on the content of each string. 771 772 This can also be used to put quotes around the executable of a command. 773 I<This must never ever be done on VMS.> 774 775 =back 776 777 =cut 778 779 sub 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 814 Returns a list of two numbers, the first representing the build version, 815 the second representing the library version. See opensslv.h for more 816 information on those numbers. 817 818 =back 819 820 =cut 821 822 my @versions = (); 823 sub 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 841 OpenSSL::Test depends on some environment variables. 842 843 =over 4 844 845 =item B<TOP> 846 847 This environment variable is mandatory. C<setup> will check that it's 848 defined and that it's a directory that contains the file C<Configure>. 849 If this isn't so, C<setup> will C<BAIL_OUT>. 850 851 =item B<BIN_D> 852 853 If defined, its value should be the directory where the openssl application 854 is located. Defaults to C<$TOP/apps> (adapted to the operating system). 855 856 =item B<TEST_D> 857 858 If defined, its value should be the directory where the test applications 859 are located. Defaults to C<$TOP/test> (adapted to the operating system). 860 861 =item B<STOPTEST> 862 863 If defined, it puts testing in a different mode, where a recipe with 864 failures will result in a C<BAIL_OUT> at the end of its run. 865 866 =back 867 868 =cut 869 870 sub __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 903 sub __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 910 sub __srctop_dir { 911 BAIL_OUT("Must run setup() first") if (! $test_name); 912 913 return abs2rel(catdir($directories{SRCTOP},@_), getcwd); 914 } 915 916 sub __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 923 sub __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. 932 sub __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. 951 sub __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 961 sub __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 971 sub __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 981 sub __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 988 sub __data_dir { 989 BAIL_OUT("Must run setup() first") if (! $test_name); 990 991 return catdir($directories{SRCDATA},@_); 992 } 993 994 sub __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 1011 sub __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)) 1110 sub __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. 1132 sub __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. 1164 sub __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 1199 L<Test::More>, L<Test::Harness> 1200 1201 =head1 AUTHORS 1202 1203 Richard Levitte E<lt>levitte@openssl.orgE<gt> with assistance and 1204 inspiration from Andy Polyakov E<lt>appro@openssl.org<gt>. 1205 1206 =cut 1207 1208 no warnings 'redefine'; 1209 sub subtest { 1210 $level++; 1211 1212 Test::More::subtest @_; 1213 1214 $level--; 1215 }; 1216 1217 1; 1218