cvs commit: smoke README mkovz.pl mktest.pl smoke.sh

[email protected] ("H.Merijn Brand") Wed, 26 Sep 2001 09:52:45 -0700
Newsgroups perl.qa.cvs
Message-ID <[email protected]>
hmbrand     01/09/26 09:52:45

  Modified:    .        README mkovz.pl mktest.pl smoke.sh
  Log:
  First try
  
  Revision  Changes    Path
  1.2       +133 -17   smoke/README
  
  Index: README
  ===================================================================
  RCS file: /cvsroot/perl-qa/smoke/README,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -w -r1.1 -r1.2
  --- README	2001/08/21 01:43:35	1.1
  +++ README	2001/09/26 16:52:45	1.2
  @@ -1,26 +1,142 @@
  +=head1 NAME
   
  -What:  Test the bleading edge Perl on your platform.
  +Perl Core Smoke Test Suite
   
  -How:   Get the test tools from sourceforge.
  -       http://sourceforge.net/cvs/?group_id=33231
  +=head1 SYNOPSIS
   
  -       cvs -d:pserver:[email protected]:/cvsroot/perl-qa login
  -       cvs -z3 -d:pserver:[email protected]:/cvsroot/perl-qa co smoke
  +  # at 22:25
  +  sh smoke.sh [/usr/CPAN/perl-current [smoke.cfg]]
  +  #
   
  -       Then edit smoke.sh (line 6) and mkovz.pl (line 5) to reflect
  -       the location (directory) of your smoking pit
  +  or for the brave and trustworthy
   
  -Where: In your smoking pit
  +  # perl Makefile.PL
   
  -When:  Whenever you set cron to execute smoke.sh (be sure it can find
  -       mktest.pl in your path.
  +=head1 DESCRIPTION
   
  -       When the smoking is done, call mkovz.pl, which creates an
  -       overview and mails it to getpwuid ($<). If you want to mail it
  -       somewhere else (e.g.  [email protected]), change the
  -       last line of mkovz.pl
  +The perl core smoke test suite is a set of simple scripts that try to
  +run the perl core tests on as many configurations as possible and combine
  +that into a easy to parse report.
   
  -Why:   1. it's fun
  -       2. p5p would love to see tons of 'O's appear in your report
  -       3. we look for a large covarage of systems
  +The perl source tree is refreshed using rsync to the latest level of the
  +perl development branche before the smoke tests start. Note that rsync in
  +the smoke uses --delete, which <b>removes</b> any existing files on that
  +directory that are not part of the perl source tree.
   
  +=head1 INSTALLATION
  +
  +Create an empty directory where the perl source tree is to be placed when
  +smoking (e.g. /usr/3gl/CPAN/perl-current).
  +
  +Create or use a location to put the three scripts needed for the smoke
  +(e.g. /usr/3gl/CPAN/smoke), and put the files from the distribution there.
  +Probably you already did so, because you are reading this file.
  +
  +Edit smoke.sh and change the PC= definition to reflect the location you
  +just chose in the first step of the initialisation. Theoretically you are
  +now ready to go, just follow the SYNOPSIS to give it a first shot for
  +tonight.
  +
  +Optionally delete lines from config.sh (or a local copy with a different
  +name) for which you are certail your system doesn't support it (like
  +threading or 64bit configurations)
  +
  +If you happen to try the smoke on a Win32/MSVC5/dmake configuration (which
  +should be supported), create an empty folder 'win32' in the smoke source
  +dir (where the mktest.pl resides).
  +
  +If something useful happens, do it every night using cron instead of at.
  +
  +=head1 Slow Systems
  +
  +It can happen that your system is not able to persue all the tests, either
  +because it is too slow or because some of the configurations are not
  +supported by the system. At first, don't worry, they are detected by the
  +report creation script and shown as such.
  +
  +After the first run gave you some idea of how long the smoke will run on
  +your system,  you can create your own copy of smoke.cfg where you either
  +add new combinations and/or test levels, or delete lines to speed up the
  +run time of smoke.
  +
  +At the moment there are no guidelines of how to change the configuration
  +best to fit the needs of perl5-porters while still getting as much smoke
  +out of the test as possible, simply because the needs of perl5-porters
  +change over time :)
  +
  +If the test captures too many cycles of your CPU to continue production
  +work, just kill the "mktest.pl" process and the report will be generated
  +over the results captured untill then.
  +
  +=head1 Availability and references
  +
  +=head2 Distribution
  +
  +  http://home.hccnet.nl/h.m.brand/Test-Smoke-1.09.tgz
  +  $CPAN/authors/id/H/HM/HMBRAND/Test-Smoke-1.09.tgz
  +  SourceForge project "perl-qa"
  +
  +=head2 Mailing lists
  +
  +  CORE smokers:    [email protected]
  +  Perl general QA: [email protected]
  +  Smoke reports:   [email protected]
  +
  +=head2 Archives and web
  +
  +  http://qa.perl.org
  +  http://archives.develooper.com/[email protected]/ and/or
  +  news://nntp.perl.org/perl.daily-build
  +
  +=head1 COPYRIGHT and LICENCE
  +
  +Copyright (C) 2001 H.Merijn Brand
  +
  +This suite is free software; you can redistribute it and/or modify it
  +under the same terms as Perl itself, without consulting the author.
  +
  +=head1 AUTHOR
  +
  +H.Merijn Brand <[email protected]> in dialogue and consultation with
  +Michael Schwern <[email protected]>, the Perl QA pumpkin.
  +
  +Contributors and/or co-authors:
  +
  +    Configurations and
  +      nuts and bolts	Nicholas Clark <[email protected]>
  +    Portability issues	Will Coleda - IMG <[email protected]>
  +    Safety		Richard Soderberg <[email protected]>
  +    Win32/MSC5/dmake	Mattia Barbon <[email protected]>
  +    Sharing issues	Blair Zajac <[email protected]>
  +
  +and all the people having useful suggestions and nits, starting at
  +YAPC::Europe-2.0.01, where Michael talked me into simplifying my own
  +test-suite.
  +
  +=head1 Misc
  +
  +As always, have the appropriate amount of fun
  +
  +=head1 TODO
  +
  +=over 4
  +
  +=item Win32
  +
  +Windows configurations are not as easy as Unix, but require make
  +fiddling. Windows2000 however supports long names and <i>might</i>
  +just pick up the current way of going around without any hassle.
  +
  +=item Initialisation and installation
  +
  +Though I've tried to make Makefile.PL do what's neccasary, there's
  +probably still some issues to be fixed for non-unix operating systems
  +
  +=item Parrot
  +
  +Ask the user at setup if he's willing to test Parrot along the way,
  +and implement/integrate these tests
  +
  +=back
  +
  +=cut
  
  
  
  1.2       +61 -9     smoke/mkovz.pl
  
  Index: mkovz.pl
  ===================================================================
  RCS file: /cvsroot/perl-qa/smoke/mkovz.pl,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -w -r1.1 -r1.2
  --- mkovz.pl	2001/08/21 01:25:04	1.1
  +++ mkovz.pl	2001/09/26 16:52:45	1.2
  @@ -1,9 +1,19 @@
   #!/usr/bin/perl -w
   
  -use Config;
  +# Create matrix for smoke test results
  +# (c)'01 H.Merijn Brand [27 August 2001]
  +
  +# mkovz.pl [ e-mail [ folder ]]
  +
  +use strict;
   
  -my $testd = "/usr/3gl/CPAN/perl-current";
  -my (%rpt, @confs, %confs);
  +use vars qw($VERSION);
  +$VERSION = "1.09";
  +
  +use Config;
  +my $email = shift || getpwuid $<;
  +my $testd = shift || "/usr/3gl/CPAN/perl-current";
  +my (%rpt, @confs, %confs, @manifest);
   
   open RPT, "> $testd/mktest.rpt" or die "mktest.rpt: $!";
   select RPT;
  @@ -12,15 +22,25 @@
   my $conf   = "";
   my $debug  = "";
   $rpt{patch} = "?";
  -my $out = "$testd/mktest.out";
  -open OUT, "<$out" or next;
  +my ($out, @out) = ("$testd/mktest.out", 1 .. 5);
  +open OUT, "<$out" or die "Can't open $out: $!";
   for (<OUT>) {
       m/^\s*$/ and next;
       m/^-+$/  and next;
  +
  +    # Buffer for broken lines (Win32, VMS)
  +    pop @out;
  +    unshift @out, $_;
  +    chomp $out[0];
  +
       if (m/^\s*Smoking patch (\d+)/) {
   	$rpt{patch} = $1;
   	next;
   	}
  +    if (m/^MANIFEST /) {
  +	push @manifest, $_;
  +	next;
  +	}
       if (s/^Configuration:\s*//) {
   	# Unable to build in previous conf was hidden by crash junk?
   	exists $rpt{$conf}{$debug}{stdio}  or $rpt{$conf}{$debug}{stdio}  = "-";
  @@ -43,7 +63,7 @@
   	next;
   	}
       if (m/^\s*Skipped this configuration/) {
  -	if ($os =~ m/^HP/) {
  +	if ($^O =~ m/^(?: hpux | freebsd )$/x) {
   	    (my $dup = $conf) =~ s/ -Duselongdouble//;
   	    if (exists $rpt{$dup}{$debug}{stdio}) {
   		@{$rpt{$conf}{$debug}}{qw(stdio perlio)} =
  @@ -72,7 +92,18 @@
   	$rpt{$conf}{$debug}{perlio} = $1;
   	next;
   	}
  +    # /Fix/ broken lines
  +    if (m/^\s*FAILED/ || m/^\s*DIED/) {
  +	foreach my $out (@out) {
  +	    $out =~ m/\.\./ or next;
  +	    push @{$rpt{$conf}{$debug}{$perlio}}, $out . substr $_, 3;
  +	    last;                
  +	    }
  +	next;
  +	}
       if (m/FAILED/) {
  +	ref $rpt{$conf}{$debug}{$perlio} or
  +	    $rpt{$conf}{$debug}{$perlio} = [];	# Clean up sparse garbage
   	push @{$rpt{$conf}{$debug}{$perlio}}, $_;
   	next;
   	}
  @@ -81,7 +112,7 @@
   my $ccv = $Config{ccversion}||$Config{gccversion};
   print <<EOH;
   Automated smoke report for patch $rpt{patch}
  -                        on $^O using $Config{cc} version $ccv
  +          v$VERSION         on $^O using $Config{cc} version $ccv
   O = OK
   F = Failure(s), extended report at the bottom
   ? = still running or test results not (yet) available
  @@ -127,7 +158,7 @@
   @fail and print "\nFailures:\n\n";
   for my $i (0 .. $#fail) {
       my $ref = $fail[$i];
  -    printf "%-12s %-16s %s\n", $os, @{$ref}[0,1];
  +    printf "%-12s %-16s %s\n", $^O, @{$ref}[0,1];
       if ($i < $#fail) {	# More squeezing
   	my $nref = $fail[$i + 1];
   	$ref->[0] eq $nref->[0] and
  @@ -135,6 +166,27 @@
   	}
       print @{$ref->[-1]}, "\n";
       }
  +
  +@manifest and print RPT "\n\n", @manifest;
  +
   close RPT;
   select STDOUT;
  -system "mailx -s 'Report $testd' ". getpwuid ($<) ." < $testd/mktest.rpt";
  +
  +my $mailer = "mailx";
  +my $subject = "Smoke $rpt{patch} $Config{osname} $Config{osvers} $testd";
  +if ($mailer =~ m/sendmail/) {
  +    local (*MAIL, *BODY, $/);
  +    open  BODY, "< $testd/mktest.rpt";
  +    open  MAIL, "| $mailer -i -t";
  +    print MAIL join "\n",
  +	"To: $email",
  +	"From: ...",
  +	"Subject: $subject",
  +	"",
  +	<BODY>;
  +    close BODY;
  +    close MAIL;
  +    }
  +else {
  +    system "$mailer -s '$subject' $email < $testd/mktest.rpt";
  +    }
  
  
  
  1.2       +439 -216  smoke/mktest.pl
  
  Index: mktest.pl
  ===================================================================
  RCS file: /cvsroot/perl-qa/smoke/mktest.pl,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -w -r1.1 -r1.2
  --- mktest.pl	2001/08/21 01:25:04	1.1
  +++ mktest.pl	2001/09/26 16:52:45	1.2
  @@ -1,22 +1,163 @@
   #!/usr/bin/perl -w
   
   # Smoke test for perl-current
  -# (c)'01 H.Merijn Brand [18 August 2001]
  +# (c)'01 H.Merijn Brand [27 August 2001]
  +#    and Nicholas Clark
   
   use strict;
   
  -our $VERSION = "1.01";
  +sub usage ()
  +{
  +    print STDERR "usage: mktest.pl [<smoke.cfg>]\n";
  +    exit 1;
  +    } # usage
  +
  +@ARGV == 1 and $ARGV[0] eq "-?" || $ARGV[0] =~ m/^-+help$/ and usage;
  +
  +use Config;
  +use Cwd;
  +use Getopt::Long;
  +use File::Find;
  +
  +my $norun   = 0;
  +my $verbose = 0;
  +GetOptions (
  +    "n|norun|dry-run" => \$norun,
  +    "v|verbose:i"     => \$verbose,	# NYI
  +    ) or usage;
  +my $config_file = shift;
   
  -my $io    = 1;	# Test perlio vs. stdio
  -my $thr   = 1;	# Test threads
  -
   open TTY,    ">&STDERR";	select ((select (TTY),    $| = 1)[0]);
   open STDERR, ">&1";		select ((select (STDERR), $| = 1)[0]);
   open LOG,    "> mktest.out";	select ((select (LOG),    $| = 1)[0]);
   				select ((select (STDOUT), $| = 1)[0]);
  -chomp (my $testdir = `pwd`);
  -unlink qw(perl.ok perl.nok);
   
  +sub is_win32 ()
  +{
  +    $^O eq "MSWin32";
  +    } # is_win32
  +
  +# Run a system command or a perl subroutine, unless -n was flagged.
  +sub run ($;$)
  +{
  +    my ($command, $sub) = @_;
  +    $norun       and
  +	return print TTY "$command\n";
  +
  +    defined $sub and
  +	return &$sub ($command);
  +
  +    return qx($command);
  +    } # run
  +
  +sub make ($)
  +{
  +    my $cmd = shift;
  +
  +    is_win32 or return run "make $cmd";
  +
  +    my $kill_err;
  +    # don't capture STDERR
  +    $cmd =~ s{2\s*>\s*/dev/null\s*$}{} and $kill_err = 1;
  +    # Better detection of make vs. nmake vs. dmake required here
  +    # dmake + MSVC5, make + DJGPP, make + Cygwin
  +    $cmd = "dmake -f smoke.mk $cmd";
  +    chdir "win32" or die "unable to chdir () into 'win32'";
  +    run ($kill_err ? qq{$^X -e "close STDERR; system '$cmd'"} : $cmd);
  +    chdir ".." or die "unable to chdir() out of 'win32'";
  +    } #make
  +
  +sub ttylog (@)
  +{
  +    print TTY @_;
  +    print LOG @_;
  +    } # ttylog
  +
  +my @config;
  +unless (defined $config_file) {
  +    -s "smoke.cfg" and $config_file = "smoke.cfg";
  +    }
  +if (defined $config_file) {
  +    open CONF, "< $config_file" or die "Can't open '$config_file': $!";
  +    my @conf;
  +    my @target;
  +    # Cheat. Force a break marker as a line after the last line.
  +    foreach (<CONF>, "=") {
  +	m/^#/ and next;
  +	s/\s+$// if m/\s/;	# Blanks, new-lines and carriage returns. M$
  +	if (m:^/:) {
  +	    m:^/(.*)/$:;
  +	    defined $1 or die "Policy target line didn't end with '/': '$_'";
  +	    push @target, $1;
  +	    next;
  +	    }
  +
  +	if (!m/^=/) {
  +	    # Not a break marker
  +	    push @conf, $_;
  +	    next;
  +	    }
  +
  +	# Break marker, so process the lines we have.
  +	if (@target > 1) {
  +	    warn "Multiple policy target lines " .
  +		join (", ", map {"'$_'"} @target) . " - will use first";
  +	    }
  +	my %conf = map { $_ => 1 } @conf;
  +	if (keys %conf == 1 and exists $conf{""} and !@target) {
  +	    # There are only blank lines - treat it as if there were no lines
  +	    # (Lets people have blank sections in configuration files without
  +	    #  warnings.)
  +	    # Unless there is a policy target.  (substituting ''  in place of
  +	    # target is a valid thing to do.)
  +	    @conf = ();
  +	    }
  +	unless (@conf) {
  +	    # They have no target lines
  +	    @target and
  +		warn "Policy target '$target[0]' has no configuration lines, ".
  +		     "so it will not be used";
  +	    @target = ();
  +	    next;
  +	    }
  +
  +	while (my ($key, $val) = each %conf) {
  +	    $val > 1 and warn "Configuration line '$key' duplicated $val times";
  +	    }
  +	my $args = [@conf];
  +	@conf = ();
  +	if (@target) {
  +	    push @config, { policy_target => $target[0], args => $args };
  +	    @target = ();
  +	    next;
  +	    }
  +
  +	push @config, $args;
  +	}
  +    }
  +else {
  +    @config = (
  +	[ "",
  +	  "-Dusethreads -Duseithreads"
  +	  ],
  +	[ "-Uuseperlio",
  +	  "-Duseperlio",
  +	  "-Duseperlio -Duse64bitint",
  +	  "-Duseperlio -Duse64bitall",
  +	  "-Duseperlio -Duselongdouble",
  +	  "-Duseperlio -Dusemorebits",
  +	  "-Duseperlio -Duse64bitall -Duselongdouble"
  +	  ],
  +	[ "", "-Duselongdouble"
  +	  ],
  +	{ policy_target =>       "-DDEBUGGING",
  +	  args          => [ "", "-DDEBUGGING" ]
  +	  },
  +	);
  +    }
  +
  +my $testdir = getcwd;
  +
   my $patch;
   if (open OK, "<.patch") {
       chomp ($patch = <OK>);
  @@ -24,81 +165,152 @@
       print LOG "Smoking patch $patch\n\n";
       }
   
  +if (open MANIFEST, "< MANIFEST") {
  +    # I've done no tests yet, and I've been started after the rsync --delete
  +    # Now check if I'm in sync
  +    my %MANIFEST = ( ".patch" => 1, map { s/\s.*//s; $_ => 1 } <MANIFEST>);
  +    find (sub {
  +	-d and return;
  +	m/^mktest\.(log|out)$/ and return;
  +	my $f = $File::Find::name;
  +	$f =~ s:^$testdir/?::;
  +	if (exists $MANIFEST{$f}) {
  +	    delete $MANIFEST{$f};
  +	    return;
  +	    }
  +	$MANIFEST{$f} = 0;
  +	}, $testdir);
  +    foreach my $f (sort keys %MANIFEST) {
  +	ttylog "MANIFEST ",
  +	    ($MANIFEST{$f} ? "still has" : "did not declare"), " $f\n";
  +	}
  +    }
  +
   my $Policy = -f "../Policy.sh" && -r _
       ? do {
  -	local $/ = undef;
  -	open my $pol, "<../Policy.sh" or die "../Policy.sh: $!";
  -	<$pol>;
  +	local ($/, *POL);
  +	open POL, "<../Policy.sh" or die "../Policy.sh: $!";
  +	<POL>;
   	}
       : join "", <DATA>;
  +
   my @p_conf = ("", "");
  -foreach my $tconf (
  -	"",
  -	"-Dusethreads -Duseithreads -Dusereentrant ",
  -	) {
  -foreach my $conf (
  -	"-Uuseperlio",
  -	"-Duseperlio",
  -	"-Duseperlio -Duse64bitint",
  -	"-Duseperlio -Duse64bitall",
  -	"-Duseperlio -Duselongdouble",
  -	"-Duseperlio -Dusemorebits",
  -	"-Duseperlio -Duse64bitall -Duselongdouble",
  -	) {
  -foreach my $dconf (
  -	"",
  -	"-DDEBUGGING ",
  -	) {
  -    my $uconf  = "";	# Room for -U...
  -    my $s_conf = join "\n" =>
  -	"", "Configuration: $dconf-Dusedevel $conf $tconf$uconf", "-" x 78, "";
  -    print TTY $s_conf;
  -    print LOG $s_conf;
   
  +run_tests (\@p_conf, $Policy, "-Dusedevel", [], @config);
  +
  +close LOG;
  +
  +sub run_tests
  +{
  +    # policy.sh
  +    # configuration command line built up so far
  +    # hash of substitutions in Policy.sh (mostly cflags)
  +    # array of things still to test (in @_ ?)
  +
  +    my ($p_conf, $policy, $old_config_args, $substs, $this_test, @tests) = @_;
  +
  +    # $this_test is either
  +    # [ "", "-Dthing" ]
  +    # or
  +    # { policy_target => "-DDEBUGGING", args => [ "", "-DDEBUGGING" ] }
  +
  +    my $policy_target;
  +    if (ref $this_test eq "HASH") {
  +	$policy_target = $this_test->{policy_target};
  +	$this_test     = $this_test->{args};
  +	}
  +
  +    foreach my $conf (@$this_test) {
  +	my $config_args = $old_config_args;
  +	# Try not to add spurious spaces as it confuses mkovz.pl
  +	length $conf and $config_args .= " $conf";
  +	my @substs = @$substs;
  +	if (defined $policy_target) {
  +	    # This set of permutations also need to subst inside Policy.sh
  +	    # somewhere.
  +	    push @substs, [$policy_target, $conf];
  +	    }
  +
  +	if (@tests) {
  +	    # Another level of tests
  +	    run_tests ($p_conf, $policy, $config_args, \@substs, @tests);
  +	    next;
  +	    }
  +
  +	# No more levels to expand
  +	my $s_conf = join "\n" => "", "Configuration: $config_args",
  +				  "-" x 78, "";
  +	ttylog $s_conf;
  +
       # You can put some optimizations (skipping configurations) here
  -    if ($^O eq "hpux" && $conf =~ m/longdouble|morebits/) {
  -	# longdouble is turned off in Configure for hpux, and since morebits
  -	# is the same as 64bitint + longdouble, these have already been tested
  -	print TTY " Skipped this configuration for this OS (duplicate test)\n";
  -	print LOG " Skipped this configuration for this OS (duplicate test)\n";
  +	if ( $^O =~ m/^(?: hpux | freebsd )$/x &&
  +	     $conf =~ m/longdouble|morebits/) {
  +	    # longdouble is turned off in Configure for hpux, and since
  +	    # morebits is the same as 64bitint + longdouble, these have
  +	    # already been tested. FreeBSD does not support longdoubles
  +	    # well enough for perl (eg no sqrtl)
  +	    ttylog " Skipped this configuration for this OS (duplicate test)\n";
   	next;
   	}
   
       print TTY "Make distclean ...";
  -    qx "make -i distclean 2>/dev/null";
  +	make "-i distclean 2>/dev/null";
   
       print TTY "\nCopy Policy.sh ...";
  -    {   my $Pol = $Policy;
  -	$dconf or $Pol =~ s/-DDEBUGGING\s*//g;
  +
  +	# Turn the array of instructions on what to substitute into one or
  +	# more regexps. Initially we have a list of target/value pairs.
  +	my %substs;
  +	# First group all the values by target.
  +	foreach (@substs) {
  +	    push @{$substs{$_->[0]}}, $_->[1];
  +	    }
  +	# use Data::Dumper; print Dumper (\@substs, \%substs);
  +	# Then for each target do the substitution.
  +	# If more than 1 value wishes to substitute, join them with spaces
  +	my $this_policy = $policy;
  +	while (my ($target, $values) = each %substs) {
  +	    unless ($this_policy =~ s/$target/join " ", @$values/seg) {
  +		warn "Policy target '$target' failed to match";
  +		}
  +	    }
  +
  +	if ($norun) {
  +	    print TTY $this_policy;
  +	    }
  +	else {
   	unlink "Policy.sh";
  -	open my $pol, "> Policy.sh";
  -	print $pol $Pol;
  -	close $pol;
  +	    local *POL;
  +	    open   POL, "> Policy.sh";
  +	    print  POL $this_policy;
  +	    close  POL;
   	}
   
       print TTY "\nConfigure ...";
  -    qx "Configure -Dusedevel $conf $tconf $uconf -des";
  +	run "./Configure $config_args -des", is_win32 ? \&Configure : undef;
   
  -    unless (-f "Makefile" && -s "config.sh") {
  -	print TTY " Unable to configure perl in this configuration\n";
  -	print LOG " Unable to configure perl in this configuration\n";
  +	unless ($norun or (is_win32 ? -f "win32/smoke.mk"
  +				    : -f "Makefile" && -s "config.sh")) {
  +	    ttylog " Unable to configure perl in this configuration\n";
   	next;
   	}
   
  +	print TTY "\nMake headers ...";
  +	make "regen_headers";
  +
       print TTY "\nMake ...";
  -    qx "make 2>&1";
  +	make " ";
   
  -    unless (-s "perl" && -x _) {
  -	print TTY " Unable to make perl in this configuration\n";
  -	print LOG " Unable to make perl in this configuration\n";
  +	my $perl = "perl$Config{_exe}";
  +	unless ($norun or (-s $perl && -x _)) {
  +	    ttylog " Unable to make perl in this configuration\n";
   	next;
   	}
   
  -    unlink "t/perl";
  -    qx "make test-prep";
  -    unless (-l "t/perl") {
  -	print TTY " Unable to test perl in this configuration\n";
  -	print LOG " Unable to test perl in this configuration\n";
  +	$norun or unlink "t/$perl";
  +	make "test-prep";
  +	unless ($norun or is_win32 ? -f "t/$perl" : -l "t/$perl") {
  +	    ttylog " Unable to test perl in this configuration\n";
   	next;
   	}
   
  @@ -106,10 +318,24 @@
   
       foreach my $perlio (qw(stdio perlio)) {
   	$ENV{PERLIO} = $perlio;
  -	print TTY "PERLIO = $perlio\t";
  -	print LOG "PERLIO = $perlio\t";
  +	    ttylog "PERLIO = $perlio\t";
   
  +	    if ($norun) {
  +		ttylog "\n";
  +		next;
  +		}
  +
  +	    #FIXME kludge
  +	    if (is_win32) {
  +		chdir "win32" or die "unable to chdir () into 'win32'";
  +		# Same as in make ()
  +		open TST, "dmake -f smoke.mk test |";
  +		chdir ".." or die "unable to chdir () out of 'win32'";
  +		}
  +	    else {
   	open TST, "make test |";
  +		}
  +
   	my @nok = ();
   	select ((select (TST), $| = 1)[0]);
   	while (<TST>) {
  @@ -121,6 +347,7 @@
   	    m,^	Making , ||
   	    m,^make\[[12], ||
   	    m,make( TEST_ARGS=)? (_test|TESTFILE=), ||
  +		m,^\s+make\s+lib/, ||
   	    m,^ *cd t &&, ||
   	    m,^if \(true, ||
   	    m,^else \\, ||
  @@ -135,8 +362,9 @@
   	    m,File \S+ not changed, ||
   	    # Don't know why BSD's make does this
   	    m,^Extracting .*with variable substitutions, ||
  -	    # Or this:
  +		# Or these
   	    m,cc\s+-o\s+perl.*perlmain.o\s+lib/auto/DynaLoader/DynaLoader\.a\s+libperl\.a, ||
  +		m,^\S+ is up to date, ||
   	    m,^   ### , and next;
   	    if (m/^u=.*tests=/) {
   		s/(\d\.\d*) /sprintf "%.2f ", $1/ge;
  @@ -144,109 +372,104 @@
   		}
   	    else {
   		push @nok, $_;
  -		};
  +		    }
   	    print;
   	    }
   	print LOG map { "    $_" } @nok;
  -	if (grep m,^All tests successful, @nok) {
  +	    if (grep m/^All tests successful/, @nok) {
   	    print TTY "\nOK, archive results ...";
   	    $patch and $nok[0] =~ s/\./ for .patch = $patch./;
  -	    # make {,n}okfile now, cause a failure might not be able to
  -	    -f "perl.ok"  or qx "make okfile";
  -	    qx "cp perl.ok perl.nok";
  -	    open  OK, ">> perl.ok.$$";
  -	    print OK $p_conf[0] eq $s_conf ? "\n" : ($p_conf[0] = $s_conf);
  -	    print OK "PERLIO = $perlio\n", @nok;
  -	    close OK;
   	    }
   	else {
  -	    print TTY "\nExtending failures with Harness\n";
   	    my @harness;
   	    for (@nok) {
   		m:^(\w+/[-\w/]+).*: or next;
  -		push @harness, "../$1.t";
  +		    # Remeber, we chdir into t, so -f is false for op/*.t etc
  +		    push @harness, (-f "$1.t") ? "../$1.t" : "$1.t";
   		}
  -	    push @nok, "\n",
  +		if (@harness) {
  +		    local $ENV{PERL_SKIP_TTY_TEST} = 1;
  +		    print TTY "\nExtending failures with Harness\n";
  +		    my $harness = is_win32 ?
  +			join " ", map { s{^\.\.[/\\]}{};
  +					m/^(?:lib|ext)/ and $_ = "../$_";
  +					$_ } @harness :
  +			"@harness";
  +		    ttylog "\n",
   		grep !m:\bFAILED tests\b: &&
  -		     !m:% okay$: => qx "./perl t/harness @harness";
  -
  -	    open  NOK, ">> perl.nok.$$";
  -	    print NOK $p_conf[1] eq $s_conf ? "\n" : ($p_conf[1] = $s_conf);
  -	    print NOK "PERLIO = $perlio\n", @nok;
  -	    close NOK;
  -	    }
  -	print TTY "\n";
  -	$io or last;
  +			    !m:% okay$: => run "./perl t/harness $harness";
   	}
       }
  +	    print TTY "\n";
       }
  -    $thr or last;
       }
  -close LOG;
  +    } # run_tests
   
  -if (-s "perl.ok.$$") {
  -    print TTY "\nOK file ...";
  -    open OK, -s "perl.nok.$$" ? "< perl.ok.$$" : "< mktest.out";
  -    my @nok = <OK>;
  -    close OK;
  -    unlink "perl.ok.$$";
  -    open  OK, "< perl.ok";
  -    my @ok = <OK>;
  -    close OK;
  -    shift @ok;
  -    $ok[0] =~ s/Subject:\s+//;
  -    $patch and $ok[0] =~ s/\+DEVEL\d+/+DEVEL$patch/;
  -    $ok[0] =~ s/-stdio//;
  -    splice @ok, 1, 2;
  -    splice @ok, 8, 2, map { "    $_\n" } (
  -	    "category=dailybuild",
  -	    "category=install",
  -	    "osname=$^O",
  -	    "severity=none",
  -	    "status=ok",
  -	    "ack=no");
  -    splice @ok, 6, 0, "\n", @nok, "\n";
  -    open  OK, "> perl.ok";
  -    print OK @ok;
  -    close OK;
  -    }
  -else {	# Let's hope not!
  -    unlink "perl.ok";
  +sub Configure
  +{
  +    my $command = shift;
  +
  +    local $_;
  +    my %opt_map = (
  +	"-Dusethreads"		=> "USE_ITHREADS",
  +	"-Duseithreads"		=> "USE_ITHREADS",
  +	"-Duseperlio"		=> "USE_PERLIO",
  +	"-Dusemultiplicity"	=> "USE_MULTI",
  +	"-DDEBUGGING"		=> "USE_DEBUGGING",
  +	);
  +    my %opts = (
  +	USE_MULTI	=> 0,
  +	USE_ITHREADS	=> 0,
  +	USE_IMP_SYS	=> 0,
  +	USE_PERLIO	=> 0,
  +	USE_DEBUGGIMG	=> 0,
  +	);
  +
  +    ttylog $command;
  +    $command =~ m{^\s*\./Configure\s+(.*)} or die "unable to parse command";
  +    foreach (split " ", $1) {
  +	m/^-[des]{1,3}$/ and next;
  +	m/^-Dusedevel$/  and next;
  +	die "invalid option '$_'" unless exists $opt_map{$_};
  +	$opts{$opt_map{$_}} = 1;
  +	}
  +
  +    local (*IN, *OUT);
  +    my $in =  "win32/makefile.mk";
  +    my $out = "win32/smoke.mk";
  +
  +    open IN,  "< $in"  or die "unable to open '$in'";
  +    open OUT, "> $out" or die "unable to open '$out'";
  +    while (<IN>) {
  +	if    (m/^\s*#?\s*(USE_\w+)(\s*\*?=\s*define)$/) {
  +	    $_ = ($opts{$1} ? "" : "#") . $1 . $2 . "\n";
  +	    }
  +	elsif (m/^\s*#?\s*(CFG\s*\*?=\s*Debug)$/) {
  +	    $_ = ($opts{USE_DEBUGGING} ? "" : "#") . $1 . "\n";
  +	    }
  +	elsif (m/^\s*#?\s*(CCTYPE\s*\*?=\s*)(\w+)$/) {
  +	    $_ = ($2 eq "MSVC" ? "" : "#" ) . $1 . $2 . "\n";
  +	    }
  +	elsif (m/^\s*CC\s*=\s*cl$/) {
  +	    chomp;
  +	    $_ .= " -nologo\n";
  +	    # These two ( CC = .. and CCTYPE = ... ), along with
  +	    # CCHOME, BCCOLD, BCCVCL, IS_WIN95, are related to
  +	    # the tester's environment; The options I see are
  +	    # * add some fake flags ( -cc=... -cctype=, etc )
  +	    #   This make easy to smoke with various compilers at one time
  +	    # * put these in some config file ( a new section in
  +	    #   smoke.cfg, o a new environment.cfg )
  +	    # * pass them on the command line
  +	    #   perl mktext.pl CC=xxx CCTYPE=yyy smoke.cfg
       }
   
  -if (-s "perl.nok.$$") {
  -    print TTY "\nNot OK file ...";
  -    open NOK, "< perl.nok";
  -    my @nok = <NOK>;
  -    close NOK;
  -    shift @nok;
  -    $nok[0] =~ s/Subject:\s+//;
  -    $nok[0] =~ s/OK/Not OK/;
  -    $patch and $nok[0] =~ s/\+DEVEL\d+/+DEVEL$patch/;
  -    $nok[0] =~ s/-stdio//;
  -    splice @nok, 1, 2;
  -    $nok[2] =~ s/success/build failure/;
  -    splice @nok, 8, 2, map { "    $_\n" } (
  -	    "category=dailybuild",
  -	    "category=install",
  -	    "osname=$^O",
  -	    "severity=none",
  -	    "status=open",
  -	    "ack=no");
  -    open NOK, "< perl.nok.$$";
  -    splice @nok, 5, 1, (<NOK>);
  -    close NOK;
  -    unlink "perl.nok.$$";
  -    open  NOK, "> perl.nok";
  -    print NOK @nok;
  -    close NOK;
  -    }
  -else {
  -    unlink "perl.nok";
  +	print OUT $_;
       }
  +    } # Configure
   
   __END__
  -#!/usr/bin/sh
  +#!/bin/sh
   
   # Default Policy.sh
   
  
  
  
  1.2       +13 -5     smoke/smoke.sh
  
  Index: smoke.sh
  ===================================================================
  RCS file: /cvsroot/perl-qa/smoke/smoke.sh,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -w -r1.1 -r1.2
  --- smoke.sh	2001/08/21 01:25:04	1.1
  +++ smoke.sh	2001/09/26 16:52:45	1.2
  @@ -1,16 +1,24 @@
  -#!/usr/bin/sh
  +#!/bin/sh
   
   # This should be run with cron
   
   # Change your base dir here
  -export PC=/usr/3gl/CPAN/perl-current
  -# Set environmental values here
  +export PC
  +PC=${1:-/usr/CPAN/perl-current}
  +CF=${2:-smoke.cfg}
   
  +# Set other environmental values here
  +
  +export PATH
  +PATH=`pwd`:$PATH
  +
   echo "Smoke $PC"
   umask 0
   
  -cd $PC
  +cd $PC || exit 1
   make -i distclean > /dev/null 2>&1
   rsync -avz --delete rsync://ftp.linux.activestate.com/perl-current/ .
  +
  +(mktest.pl $CF 2>&1) >mktest.log      || echo mktest.pl exited with exit code $?
   
  -(mktest.pl 2>&1) >mktest.log
  +mkovz.pl [email protected] $PC || echo mkovz.pl  exited with exit code $?