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