###############################################################################
#use strict;
-use 5.010;
-use feature 'state'; # included in 5.010
+use v5.10.1;
use warnings;
+use if $^V >= v5.19.11, experimental => 'smartmatch';
use Errno;
use FileHandle;
use lib "$RealBin/lib";
use Exim::Runtest;
+use Exim::Utils qw(uniq numerically);
-use if $ENV{DEBUG} && $ENV{DEBUG} =~ /\bruntest\b/ => ('Smart::Comments' => '####');
+use if $ENV{DEBUG} && scalar($ENV{DEBUG} =~ /\bruntest\b/) => 'Smart::Comments' => '####';
+use if $ENV{DEBUG} && scalar($ENV{DEBUG} =~ /\bruntest\b/) => 'Data::Dumper';
use constant TEST_TOP => 8999;
use constant TEST_SPECIAL_TOP => 9999;
my $have_ipv6 = 1;
my $have_largefiles = 0;
-my $test_start = 1;
-my $test_end = TEST_TOP;
-
my @test_list = ();
# options are passed on to Exim calls within the tests. Typically, this is used
# to turn on Exim debugging while setting up a test.
+Getopt::Long::Configure qw(no_getopt_compat);
GetOptions(
'debug' => sub { $debug = 1; $cr = "\n" },
'diff' => sub { $cf = 'diff -u' },
'keep' => \$save_output,
'slow' => \$slow,
'valgrind' => \$valgrind,
- 'flavor|flavour=s' => \$flavour,
+ 'range=s{2}' => \my @range_wanted,
+ 'test=i@' => \my @tests_wanted,
+ 'flavor|flavour=s' => $flavour,
'help' => sub { pod2usage(-exit => 0) },
'man' => sub {
pod2usage(
($parm_exim, @ARGV) = Exim::Runtest::exim_binary(@ARGV);
print "Exim binary is `$parm_exim'\n" if defined $parm_exim;
-# Any subsequent arguments are a range of test numbers.
-if (@ARGV)
- {
- $test_end = $test_start = shift;
- $test_end = shift if @ARGV;
- $test_end = ($test_start >= 9000)? TEST_SPECIAL_TOP : TEST_TOP
- if $test_end eq '+';
- die "** Test numbers out of order\n" if ($test_end < $test_start);
- }
+my @wanted = sort numerically uniq
+ @tests_wanted ? @tests_wanted : (),
+ @range_wanted ? $range_wanted[0] .. $range_wanted[1] : (),
+ @ARGV ? @ARGV == 1 ? $ARGV[0] :
+ $ARGV[1] eq '+' ? $ARGV[0]..($ARGV[0] >= 9000 ? TEST_SPECIAL_TOP : TEST_TOP) :
+ 0+$ARGV[0]..0+$ARGV[1] # add 0 to cope with test numbers starting with zero
+ : ();
+@wanted = 1..TEST_TOP if not @wanted;
##################################################
# Check for sudo access to root #
# If $parm_exim is still empty, ask the caller
-if ($parm_exim eq '')
+if (not $parm_exim)
{
print "** Did not find an Exim binary to test\n";
for ($i = 0; $i < 5; $i++)
# because the current binary does not support the right facilities, and also
# those that are outside the numerical range selected.
-print "\nTest range is $test_start to $test_end (flavour $flavour)\n";
+printf "\nWill run %d tests between %d and %d for flavour %s\n",
+ scalar(@wanted), $wanted[0], $wanted[-1], $flavour;
+
print "Omitting \${dlfunc expansion tests (loadable module not present)\n"
if $dlfunc_deleted;
print "Omitting dbm tests (unable to copy exim_dbmbuild)\n"
or die tests_exit(-1, "Failed to find test scripts in 'scripts/*`: $!");
# Scan for relevant tests
-
-DIR: for ($i = 0; $i < @test_dirs; $i++)
+# HS12: Needs to be reworked.
+DIR: for (my $i = 0; $i < @test_dirs; $i++)
{
my($testdir) = $test_dirs[$i];
my($wantthis) = 1;
# test in the next directory.
next DIR if ($i < @test_dirs - 1) &&
- ($test_start >= substr($test_dirs[$i+1], 0, 4));
+ ($wanted[0] >= substr($test_dirs[$i+1], 0, 4));
# No need to carry on if the end test is less than the first test in this
# subdirectory.
- last DIR if $test_end < substr($testdir, 0, 4);
+ last DIR if $wanted[-1] < substr($testdir, 0, 4);
# Check requirements, if any.
# We want the tests from this subdirectory, provided they are in the
# range that was selected.
- @testlist = map { basename $_ } glob "scripts/$testdir/*";
+ @testlist = grep { $_ ~~ @wanted } grep { /^\d+(?:\.\d+)?$/ } map { basename $_ } glob "scripts/$testdir/*";
tests_exit(-1, "Failed to read test scripts from `scripts/$testdir/*': $!")
if not @testlist;
foreach $test (@testlist)
{
- next if ($test !~ /^\d{4}(?:\.\d+)?$/);
- if (!$wantthis || $test < $test_start || $test > $test_end)
+ if (!$wantthis)
{
log_test($log_summary_filename, $test, '.');
}
}
}
-print ">>Test List: @test_list\n", if $debug;
+print ">>Test List:\n", join "\n", @test_list, '' if $debug;
##################################################
=head1 SYNOPSIS
- runtest [options] [test0 [test1]]
+ runtest [exim-path] [options] [test0 [test1]]
=head1 DESCRIPTION
=over
+=item B<--continue>
+
+Do not stop for user interaction or on errors. (default: off)
+
=item B<--debug>
This option enables the output of debug information when running the
=item B<--diff>
Use C<diff -u> for comparing the expected output with the produced
-output. (default: use a built-in comparation routine)
-
-=item B<--continue>
-
-Do not stop for user interaction or on errors. (default: off)
+output. (default: use a built-in routine)
-=item B<--update>
+=item B<--flavor>|B<--flavour> I<flavour>
-Automatically update the recorded (expected) data on mismatch. (default: off)
+Override the expected results for results for a specific (OS) flavour.
+(default: unused)
=item B<--[no]ipv4>
Keep the various output files produced during a test run. (default: don't keep)
+=item B<--range> I<n0> I<n1>
+
+Run tests between (including) I<n0> and I<n1>. A "+" may be used to specify the "last
+test available".
+
=item B<--slow>
-Insert some delays to compensate for a slow system. (default: off)
+Insert some delays to compensate for a slow host system. (default: off)
-=item B<--valgrind>
+=item B<--test> I<n>
-Start Exim wrapped by I<valgrind>. (default: don't use valgrind)
+Run the specified test. This option may used multiple times.
-=item B<--flavor>|B<--flavour> I<flavour>
+=item B<--update>
-Override the expected results for results for a specific (OS) flavour.
-(default: unused)
+Automatically update the recorded (expected) data on mismatch. (default: off)
+
+=item B<--valgrind>
+
+Start Exim wrapped by I<valgrind>. (default: don't use valgrind)
=back