Re: patch

[email protected] (Nicholas Clark)
Newsgroups perl.daily-build
Message-ID <[email protected]>
On Fri, Aug 24, 2001 at 05:17:00PM +0200, H . Merijn Brand wrote:
> Are you volunteering to work out my external conf idea?

Something like the attached?

[sorry, I've re-indented bits I edited with cperl's default indent style]
smoke.sh will need changing to pass in the config file as the first
argument. The default config I've attached isn't the same as your default.
Maybe we should supply several variations of config files, eg with and without
-Duse64bitall as I believe that's only relevant on platforms with 64 bit
pointers. (Does anyone other than Jarkko know if I'm correct in my belief?)

Nicholas Clark
mktest.pl (application/x-perl, 10.7 KB)
#!/usr/bin/perl -w

# Smoke test for perl-current
# (c)'01 H.Merijn Brand [23 August 2001]

use strict;

use vars qw ($VERSION $norun);
$VERSION = "1.02";

use Cwd;
use Getopt::Std;

my %opts;
getopts('n', \%opts);
$norun = $opts{n};
my $config_file = shift;

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]);

# Run a system command or a perl subroutine, unless -n was flagged.
sub run {
  my ($command, $sub) = @_;
  if ($norun) {
    return print TTY "$command\n";
  } elsif (defined $sub) {
    return &$sub ($command);
  } else {
    return  `$command`;
  }
}

my @config;
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>, "=") {
    chomp;
    next if m/^#/;
    if (m!^/!) {
      m!^/(.*)/$!;
      die "Policy target line didn't end with '/': '$_'"
        unless defined $1;
      push @target, $1;
    } elsif (!/^=/) {
      # Not a break marker
      push @conf, $_;
    } else {
      # Break marker, so process the lines we have.
      if (@target > 1) {
        warn "Multiple policy target lines "
          . join (", ", map {"'$_'"} @target) . " - will use first";
      }
      my %conf;
      $conf{$_}++ foreach @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 = ();
      }
      if (!@conf) {
        # They have no target lines
        warn "Policy target '$target[0]' has no configuration lines so it will not be used"
          if @target;
        @target = ();
      } else {
        while (my ($key,$val) = each %conf) {
          warn "Configuration line '$key' duplicated $val times" if $val > 1;
        }
        my $args = [@conf];
        @conf = ();
        if (@target) {
          push @config, {policy_target=>$target[0], args=>$args};
          @target = ();
        } else {
          push @config, $args;
        }
      }
    }
  }
} else {
  @config = ( ["", "-Dusethreads -Duseithreads -Dusereentrant"],
              ["", "-Duse64bitint"],
              ["", "-Duselongdouble"],
              {policy_target=>"-DDEBUGGING", args=>["", "-DDEBUGGING"]},
            );
}
#use Data::Dumper; print Dumper (@config); exit;

my $testdir = cwd;

run ("unlink qw(perl.ok perl.nok)", sub {unlink qw(perl.ok perl.nok)});

my $patch;
if (open OK, "<.patch") {
    chomp ($patch = <OK>);
    close OK;
    print LOG "Smoking patch $patch\n\n";
    }

my $Policy = -f "../Policy.sh" && -r _
    ? do {
	local (*POL, $/);
	open POL, "<../Policy.sh" or die "../Policy.sh: $!";
	<POL>;
	}
    : join "", <DATA>;

my @p_conf = ("", "");

run_tests (\@p_conf, $Policy, "-Dusedevel", [], @config);

close LOG;

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";
    }

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";
    }

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
    $config_args .= " $conf" if length $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);
    } else {
      # No more levels to expand

      my $s_conf = join "\n" =>
        "", "Configuration: $config_args", "-" x 78, "";
      print TTY $s_conf;
      print LOG $s_conf;

      # You can put some optimizations (skipping configurations) here
      if (($^O eq "hpux" || $^O eq "freebsd")
          && $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";
        next;
      }

      print TTY "Make distclean ...";
      run ("make -i distclean 2>/dev/null");

      print TTY "\nCopy Policy.sh ...";

      # 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";
	local *POL;
	open POL, "> Policy.sh";
	print POL $this_policy;
	close POL;
      }

      print TTY "\nConfigure ...";
      run ("./Configure $config_args -des");

      unless ($norun or (-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";
	next;
      }

      print TTY "\nMake ...";
      run ("make 2>&1");

      unless ($norun or (-s "perl" && -x _)) {
	print TTY " Unable to make perl in this configuration\n";
	print LOG " Unable to make perl in this configuration\n";
	next;
      }

      unlink "t/perl" unless $norun;
      run ("make test-prep");
      unless ($norun or -l "t/perl") {
	print TTY " Unable to test perl in this configuration\n";
	print LOG " Unable to test perl in this configuration\n";
	next;
      }

      print TTY "\n Tests start here:\n";

      foreach my $perlio (qw(stdio perlio)) {
        $ENV{PERLIO} = $perlio;
	print TTY "PERLIO = $perlio\t";
	print LOG "PERLIO = $perlio\t";

        if ($norun) {
          print TTY "\n";
          print LOG "\n";
          next;
        }

	open TST, "make test |";
	my @nok = ();
	select ((select (TST), $| = 1)[0]);
	while (<TST>) {
          # Still to be extended
          m,^ *$, ||
	  m,^	AutoSplitting, ||
          m,^\./miniperl , ||
          m,^autosplit_lib, ||
          m,^	Making , ||
	  m,^make\[[12], ||
	  m,make( TEST_ARGS=)? (_test|TESTFILE=), ||
	  m,^ *cd t &&, ||
	  m,^if \(true, ||
	  m,^else \\, ||
	  m,^fi$, ||
	  m,^lib/ftmp-security....File::Temp::_gettemp: Parent directory \((\.|/tmp/)\) is not safe, ||
	  m,^File::Temp::_gettemp: Parent directory \((\.|/tmp/)\) is not safe, ||
	  m,^ok$, ||
	  m,^[-a-zA-Z0-9_/]+\.*(ok|skipping test on this platform)$, ||
	  m,^(xlc|cc_r) -c , ||
	  m,^\s+$testdir/, ||
	  m,^sh mv-if-diff\b, ||
	  m,File \S+ not changed, ||
	  # Don't know why BSD's make does this
	  m,^Extracting .*with variable substitutions, ||
	  # Or this:
	  m,cc\s+-o\s+perl.*perlmain.o\s+lib/auto/DynaLoader/DynaLoader\.a\s+libperl\.a, ||
          # or this
          m,^`lib/re\.pm' is up to date, ||
	  m,^   ### , and next;
          if (m/^u=.*tests=/) {
            s/(\d\.\d*) /sprintf "%.2f ", $1/ge;
            print LOG;
          }
          else {
            push @nok, $_;
          };
          print;
        }
	print LOG map { "    $_" } @nok;
	if (grep /^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";
          local $ENV{PERL_SKIP_TTY_TEST} = 1;
          my @harness;
          for (@nok) {
          m:^(\w+/[-\w/]+).*: or next;
            push @harness, "../$1.t";
          }
          push @nok, "\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";
      }
    }
  }
}
__END__
#!/usr/bin/sh

# Default Policy.sh

# Be sure to define -DDEBUGGING by default, it's easier to remove
# it from Policy.sh than it is to add it in on the correct places

ccflags='-DDEBUGGING'
config (text/plain, 2.1 KB)
# This is a configuration file for the smoke tester.
# Lines starting with # are comments.
# Lines starting with = are section breaks. The rest of the line will be ignored
# Lines starting with / signify a pattern to substitute for in Policy.sh
# They don't count as a normal line

# This happens to be a section, but because it's *all* just blank lines
# (comments are ignored) this whole section will be ingored.

# Each normal line of a section defines a command line argument to Configure
# A blank line in a normal section means an argument of ""
# Each line from the first section is tried with each line of the second section
# with each line of the third section ...
# As this default configuration file has 4 sections each with 2 lines defining
# Configure arguments it will build 16 variations of perl.
==

-Dusethreads -Duseithreads -Dusereentrant
==

-Duse64bitint
==

-Duselongdouble
==
# The pattern must have leading and trailing '/' characters in this
# configuration file. The smoke tester will globally substitute this pattern
# with each Congfigure argument in this section (as well as passing them on
# the command line to Configure)
# This is usually used with the cflags parameter in Policy.sh, which defines
# flags to pass to the C compiler. The default Policy.sh contains the line
# "ccflags='-DDEBUGGING'" and this pattern will cause the value in the '' to
#  be replaced with an empty string and then -DDEBUGGING.
# (It may seem a bit convaluted making a system to replace -DDEBUGGING with
# the same string -DDEBUGGING, but it means that a site's valid Policy.sh can
# be used for smoke testing)
#
# Hopefully it will not be a problem that the arguments are both substituted
# into cflags and passed on the commandline to Configure, as Configure will
# ignore arguments starting -D that it does not recognise.
#
# You can specify the same pattern in more than one section. In this case
# the substitution replacement will be all Configure arguments joined with
# spaces. This lets you have one section testing ("", "-DDEBUGGING"), a
# second testing ("", "-DCRIPPLED_CC") and have cflags set correctly for the
# 4 combinations.
/-DDEBUGGING/

-DDEBUGGING
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.