#!/usr/bin/env perl $TCPDUMP = "./tcpdump" if (!($TCPDUMP = $ENV{TCPDUMP_BIN})); use File::Basename; use POSIX qw( WEXITSTATUS WIFEXITED); use Cwd qw(abs_path getcwd); use File::Path qw(mkpath); # mkpath works with ancient perl, as well as newer perl use Data::Dumper; # for debugging. # these are created in the directory where we are run, which might be # a build directory. my $newdir = "tests/NEW"; my $diffdir= "tests/DIFF"; mkpath($newdir); mkpath($diffdir); my $origdir = getcwd(); my $srcdir = $ENV{'srcdir'} || "."; # # Force UTC, so time stamps are printed in a standard time zone, and # tests don't have to be run in the time zone in which the output # file was generated. # $ENV{'TZ'}='GMT0'; # # Get the tests directory from $0. # my $testsdir = dirname($0); # # Convert it to an absolute path, so it works even after we do a cd. # $testsdir = abs_path($testsdir); print "Running tests from ${testsdir}\n"; unshift(@INC, $testsdir); require 'testfuncs.pm'; $passedcount = 0; $failedcount = 0; # # XXX - create files used by shell scripts; we can remove this once we # no longer use shell scripts in tests. # open(PASSEDCOUNT, ">", "tests/.passed"); print PASSEDCOUNT "${passedcount}\n"; close(PASSEDCOUNT); open(FAILEDCOUNT, ">", "tests/.failed"); print FAILEDCOUNT "${failedcount}\n"; close(FAILEDCOUNT); my $failureoutput=$origdir . "/tests/failure-outputs.txt"; # truncate the output file open(FAILUREOUTPUT, ">" . $failureoutput); close(FAILUREOUTPUT); sub runShellTests { my @files = glob( $testsdir . '/*.sh' ); foreach $file (@files) { if($file =~ /TEST.*\.sh/) { print "File $file, skipped\n"; next; } print "Running $file\n"; system("cd tests && sh $file ${srcdir}") } # have to update passed/failed here } $confighhash = undef; sub loadconfighash { if(defined($confighhash)) { return $confighhash; } $main::confighhash = {}; # this could be loaded once perhaps. open(CONFIG_H, "config.h") || die "Can not open config.h: $!\n"; while() { chomp; if(/^\#define (.*) 1/) { #print "Setting $1\n"; $main::confighhash->{$1} = 1; } } close(CONFIG_H); #print Dumper($main::confighhash); # also grovel Makefile for some things and pretend they are config options. open(MAKEFILE, "Makefile") || die "can not open Makefile: $!\n"; while() { chomp; #print "Processing $_\n"; if(/^CC\s*=.*gcc.*/) { #print "GCC FOUND\n"; $main::confighhash->{'USING_GCC'} = 1; } } close(MAKEFILE); return $main::confighhash; } sub runOneComplexTest { local($testconfig) = @_; my $output = $testconfig->{output}; my $input = $testconfig->{input}; my $name = $testconfig->{name}; my $options= $testconfig->{args}; my $foundit = 1; my $unfoundit=1; my $configset = $testconfig->{config_set}; my $configunset = $testconfig->{config_unset}; my $ch = loadconfighash(); #print Dumper($ch); if(defined($configset)) { $foundit = ($ch->{$configset} == 1); } if(defined($configunset)) { $unfoundit=($ch->{$configunset} != 1); } if(!$foundit) { print "${name} ... skipped, no ${configset}\n"; return 0; } if(!$unfoundit) { print "${name} ... skipped, ${configunset} is set\n"; return 0; } #use Data::Dumper; #print Dumper($testconfig); # EXPAND any occurances of @TESTDIR@ to $testsdir $options =~ s/\@TESTDIR\@/$testsdir/; my $result = runtest($name, $testsdir . "/" . $input, $testsdir . "/" . $output, $options); if($result == 0) { $passedcount++; } else { $failedcount++; } } # *.tests files are PERL hash definitions. They should create an array of hashes # one per test, and place it into the variable @testlist. sub runComplexTests { my @files = glob( $testsdir . '/*.tests' ); foreach $file (@files) { my @testlist = undef; my $definitions; print "FILE: ${file}\n"; open(FILE, "<".$file) || die "can not open $file: $!"; { local $/ = undef; $definitions = ; } close(FILE); #print "STUFF: ${definitions}\n"; eval $definitions; if(defined($testlist)) { #use Data::Dumper; #print Dumper($testlist); foreach $test (@$testlist) { runOneComplexTest($test); } } else { warn "File: ${file} could not be loaded as PERL: $!"; } } } sub runSimpleTests { local($only)=@_; open(TESTLIST, "<" . "${testsdir}/TESTLIST") || die "no ${testsdir}/TESTFILE: $!\n"; while() { next if /^\#/; next if /^$/; unlink("core"); ($name, $input, $output, @options) = split; #print "processing ${only} vs ${name}\n"; next if(defined($only) && $only ne $name); my $options = join(" ", @options); #print "@{options} becomes ${options}\n"; my $hash = { name => $name, input=> $input, output=>$output, args => $options }; runOneComplexTest($hash); } } if(scalar(@ARGV) == 0) { #runShellTests(); #runSimpleTests(); runComplexTests(); } else { runSimpleTests($ARGV[0]); } # # XXX - read files used by shell scripts, and add the passed and failed # counts reported therein to our own passed and failed counts; we can # remove this once we no longer use shell scripts in tests. # open(PASSEDCOUNT, "<", "tests/.passed"); $passedcount += ; close(PASSEDCOUNT); open(FAILEDCOUNT, ">", "tests/.failed"); $failedcount += ; close(FAILEDCOUNT); # exit with number of failing tests. print "------------------------------------------------\n"; printf("%4u tests failed\n",$failedcount); printf("%4u tests passed\n",$passedcount); system("cat ${failureoutput}"); exit $failedcount;