diff options
Diffstat (limited to 'lib/libc_r/test/verify')
| -rwxr-xr-x | lib/libc_r/test/verify | 474 | 
1 files changed, 474 insertions, 0 deletions
| diff --git a/lib/libc_r/test/verify b/lib/libc_r/test/verify new file mode 100755 index 000000000000..2863e5c3fa0c --- /dev/null +++ b/lib/libc_r/test/verify @@ -0,0 +1,474 @@ +#!/usr/bin/perl -w +#-*-mode:perl-*- +############################################################################# +# +# Copyright (C) 1999-2001 Jason Evans <jasone@freebsd.org>. +# All rights reserved. +#  +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +#    notice(s), this list of conditions and the following disclaimer as +#    the first lines of this file unmodified other than the possible +#    addition of one or more copyright notices. +# 2. Redistributions in binary form must reproduce the above copyright +#    notice(s), this list of conditions and the following disclaimer in +#    the documentation and/or other materials provided with the +#    distribution. +#  +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY +# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +# BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +# EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +############################################################################# +# +# Test harness. +# +# $FreeBSD$ +# +############################################################################# + +# Shut off buffering. +select(STDOUT); +$| = 1; + +# +# Parse command-line arguments. +# +use Getopt::Long; +Getopt::Long::config("bundling"); # Allow -hv rather than forcing -h -v. + +# Set option defaults for optional arguments. +$opt_help = 0; +$opt_verbose = 0; +$opt_quiet = 0; +$opt_srcdir = "."; +$opt_objdir = "."; +$opt_ustats = 0; +$opt_zero = 0; + +$opt_retval = +&GetOptions("h|help" => \$opt_help, +	    "v|verbose" => \$opt_verbose, +	    "q|quiet" => \$opt_quiet, +	    "s|srcdir=s" => \$opt_srcdir, +            "o|objdir=s" => \$opt_objdir, +	    "u|ustats" => \$opt_ustats, +	    "z|zero" => \$opt_zero +	    ); + +if ($opt_help) +{ +    &usage(); +    exit(0); +} + +if ($opt_retval == 0) +{ +    &usage(); +    exit 1; +} + +if ($opt_verbose && $opt_quiet) +{ +    print STDERR "-v and -q are incompatible\n"; +    &usage(); +    exit 1; +} + +if ($#ARGV + 1 == 0) +{ +    print STDERR "No tests specified\n"; +    &usage(); +    exit 1; +} + +if ($opt_verbose) +{ +    print STDERR "Option values: h:$opt_help, v:$opt_verbose, " +	. "s:\"$opt_srcdir\", o:\"$opt_objdir\" " +	. "q:$opt_quiet, u:$opt_ustats, z:$opt_zero\n"; +    printf STDERR "Tests (%d total): @ARGV\n", $#ARGV + 1; +} + +# +# Create and print header. +# +@TSTATS = +( + "--------------------------------------------------------------------------\n", + "Test                                      c_user c_system c_total     chng\n", + " passed/FAILED                            h_user h_system h_total   %% chng\n" + ); + +if (!$opt_quiet) +{ +    foreach $line (@TSTATS) +    { +	printf STDOUT "$line"; +    } +} + +# +# Run sequence test(s). +# +$total_utime = 0.0; # Total user time. +$total_stime = 0.0; # Total system time. +$total_hutime = 0.0; # Total historical user time. +$total_hstime = 0.0; # Total historical system time. +$total_ntime = 0.0; # Total time for tests that have historical data. + +foreach $test (@ARGV) +{ +    # Strip out any whitespace in $test. +    $test =~ s/^\s*(.*)\s*$/$1/; + +    $okay = 1; + +    if (-e "$opt_srcdir/$test.exp") +    { +	# Diff mode. + +	($okay, $utime, $stime) = &run_test($test); + +	if (-e "$opt_objdir/$test.out") +	{ +	    `diff $opt_srcdir/$test.exp $opt_objdir/$test.out > $opt_objdir/$test.diff 2>&1`; +	    if ($?) +	    { +		# diff returns non-zero if there is a difference. +		$okay = 0; +	    } +	} +	else +	{ +	    $okay = 0; +	    if ($opt_verbose) +	    { +		print STDERR +		    "Nonexistent output file \"$opt_objdir/$test.out\"\n"; +	    } +	} + +	($hutime, $hstime) = &print_stats($test, $okay, 0, 0, $utime, $stime); +    } +    else +    { +	# Sequence mode. + +	($okay, $utime, $stime) = &run_test($test); + +	if (open (STEST_OUT, "<$opt_objdir/$test.out")) +	{ +	    $num_subtests = 0; +	    $num_failed_subtests = 0; + +	    while (defined($line = <STEST_OUT>)) +	    { +		if ($line =~ /1\.\.(\d+)/) +		{ +		    $num_subtests = $1; +		    last; +		} +	    } +	    if ($num_subtests == 0) +	    { +		$okay = 0; +		if ($opt_verbose) +		{ +		    print STDERR "Malformed or missing 1..n line\n"; +		} +	    } +	    else +	    { +		for ($subtest = 1; $subtest <= $num_subtests; $subtest++) +		{ +		    while (defined($line = <STEST_OUT>)) +		    { +			if ($line =~ /^not\s+ok\s+(\d+)?/) +			{ +			    $not = 1; +			    $test_num = $1; +			    last; +			} +			elsif ($line =~ /^ok\s+(\d+)?/) +			{ +			    $not = 0; +			    $test_num = $1; +			    last; +			} +		    } +		    if (defined($line)) +		    { +			if (defined($test_num) && ($test_num != $subtest)) +			{ +			    # There was no output printed for one or more tests. +			    for (; $subtest < $test_num; $subtest++) +			    { +				$num_failed_subtests++; +			    } +			} +			if ($not) +			{ +			    $num_failed_subtests++; +			} +		    } +		    else +		    { +			for (; $subtest <= $num_subtests; $subtest++) +			{ +			    $num_failed_subtests++; +			} +		    } +		} + +		if (0 < $num_failed_subtests) +		{ +		    $okay = 0; +		} +	    } +	} +	else +	{ +	    if (!$opt_quiet) +	    { +		print STDERR "Cannot open output file \"$opt_objdir/$test.out\"\n"; +	    } +	    exit 1; +	} + +	($hutime, $hstime) = &print_stats($test, $okay, +					  $num_failed_subtests, $num_subtests, +					  $utime, $stime); +    } + +    $total_hutime += $hutime; +    $total_hstime += $hstime; + +    if ($okay) +    { +	$total_utime += $utime; +	$total_stime += $stime; +    } +    else +    { +	@FAILED_TESTS = (@FAILED_TESTS, $test); +    } + +    # If there were historical data, add the run time to the total time to  +    # compare against the historical run time. +    if (0 < ($hutime + $hstime)) +    { +	$total_ntime += $utime + $stime; +    } +} + +# Print summary stats. +$tt_str = sprintf ("%d / %d passed (%5.2f%%%%)", +		   ($#ARGV + 1) - ($#FAILED_TESTS + 1), +		   $#ARGV + 1, +		   (($#ARGV + 1) - ($#FAILED_TESTS + 1)) +		   / ($#ARGV + 1) * 100); + +$t_str = sprintf ("Totals                                   %7.2f  %7.2f %7.2f" +                  . "  %7.2f\n" +		  . " %s %7.2f  %7.2f %7.2f %7.2f%%%%\n", +		  $total_utime, $total_stime, $total_utime + $total_stime, +		  ($total_ntime - ($total_hutime + $total_hstime)), +		  $tt_str . ' ' x (40 - length($tt_str)), +		  $total_hutime, $total_hstime, $total_hutime + $total_hstime, +		  ($total_hutime + $total_hstime == 0.0) ? 0.0 : +		  (($total_ntime +		    - ($total_hutime + $total_hstime)) +		   / ($total_hutime + $total_hstime) * 100)); + +@TSTATS = ("--------------------------------------------------------------------------\n", +	   $t_str, +	   "--------------------------------------------------------------------------\n" +	   ); +if (!$opt_quiet) +{ +    foreach $line (@TSTATS) +    { +	printf STDOUT "$line"; +    } +} + +if ($#FAILED_TESTS >= 0) +{ +    # One or more tests failed, so return an error. +    exit 1; +} +# End of main execution. + +sub run_test +{ +    my ($test) = @_; +    my ($okay) = 1; +    my ($tutime, $tstime); +    my ($utime, $stime, $cutime, $cstime); +    my (@TSTATS, @TPATH); +    my ($t_str); +    my ($srcdir, $objdir); + +    # Get the path component of $test, if any. +    @TPATH = split(/\//, $test); +    pop(@TPATH); +    $srcdir = join('/', ($opt_srcdir, @TPATH)); +    $objdir = join('/', ($opt_objdir, @TPATH)); + +    @TSTATS = ("--------------------------------------------------------------------------\n"); + +    $t_str = sprintf ("%s%s", $test, ' ' x (40 - length($test))); +    @TSTATS = (@TSTATS, $t_str); +    @STATS = (@STATS, @TSTATS); +    if (!$opt_quiet) +    { +	foreach $line (@TSTATS) +	{ +	    printf STDOUT "$line"; +	} +    } + +    ($utime, $stime, $cutime, $cstime) = times; +    `$opt_objdir/$test $srcdir $objdir > $opt_objdir/$test.out 2>&1`; +    ($utime, $stime, $tutime, $tstime) = times; + +    # Subtract the before time from the after time. +    $tutime -= $cutime; +    $tstime -= $cstime; + +    if ($opt_zero) +    { +	if ($?) +	{ +	    $okay = 0; +	    if ($opt_verbose) +	    { +		print STDERR +		    "\"$opt_objdir/$test > $opt_objdir/$test.out 2>&1\" returned $?\n"; +	    } +	} +    } + +    return ($okay, $tutime, $tstime); +} + +sub print_stats +{ +    my ($test, $okay, $failed_subtests, $subtests, $utime, $stime) = @_; +    my ($hutime, $hstime); +#    my (TEST_PERF); +    my (@TSTATS); +    my ($t_str, $pass_str); + +    $pass_str = $okay ? "passed" : "*** FAILED ***"; +    if ((0 != $subtests) && (!$okay)) +    { +	$pass_str = $pass_str . " ($failed_subtests/$subtests failed)"; +    } +    $pass_str = $pass_str . ' ' x (39 - length($pass_str)); +     +    if (-r "$test.perf") +    { +	if (!open (TEST_PERF, "<$opt_objdir/$test.perf")) +	{ +	    print STDERR "Unable to open \"$opt_objdir/$test.perf\"\n"; +	    exit 1; +	} +	$_ = <TEST_PERF>; + +	($hutime, $hstime) = split; +	close TEST_PERF; + +	$t_str = sprintf (" %7.2f  %7.2f %7.2f  %7.2f\n" +			  . " %s %7.2f  %7.2f %7.2f %7.2f%%%%\n", +			  $utime, $stime, $utime + $stime, +			  ($utime + $stime) - ($hutime + $hstime), +			  $pass_str, +			  $hutime, $hstime, $hutime + $hstime, +			  (($hutime + $hstime) == 0.0) ? 0.0 : +			  ((($utime + $stime) - ($hutime + $hstime)) +			   / ($hutime + $hstime) * 100)); +    } +    else +    { +	$hutime = 0.0; +	$hstime = 0.0; + +	$t_str = sprintf (" %7.2f  %7.2f %7.2f        \n" +			  . " %s\n", +			  $utime, $stime, $utime + $stime, +			  $pass_str); +    } +    @TSTATS = ($t_str); +    if (!$opt_quiet) +    { +	foreach $line (@TSTATS) +	{ +	    printf STDOUT "$line"; +	} +    } + +    if ($okay && $opt_ustats) +    { +	if (!open (TEST_PERF, ">$opt_objdir/$test.perf")) +	{ +	    if (!$opt_quiet) +	    { +		print STDERR "Unable to update \"$opt_objdir/$test.perf\"\n"; +	    } +	} +	else +	{ +	    print TEST_PERF "$utime $stime\n"; +	    close TEST_PERF; +	} +    } + +    return ($hutime, $hstime); +} + +sub usage +{ +    print <<EOF; +$0 usage: +    $0 [<options>] <test>+ + +    Option        | Description +    --------------+------------------------------------------------------------- +    -h --help     | Print usage and exit. +    -v --verbose  | Verbose (incompatible with quiet). +    -q --quiet    | Quiet (incompatible with verbose). +    -s --srcdir   | Path to source tree (default is "."). +    -o --objdir   | Path to object tree (default is "."). +    -u --ustats   | Update historical statistics (stored in "<test>.perf". +    -z --zero     | Consider non-zero exit code to be an error. +    --------------+------------------------------------------------------------- + +    If <test>.exp exists, <test>'s output is diff'ed with <test>.exp.  Any +    difference is considered failure. + +    If <test>.exp does not exist, output to stdout of the following form is +    expected: + +        1..<n> +        {not }ok[ 1] +        {not }ok[ 2] +        ... +        {not }ok[ n] + +    1 <= <n> < 2^31 + +    Lines which do not match the patterns shown above are ignored. +EOF +} | 
