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