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