Anonymous avatar Anonymous committed a5f4f6c

Update test infrastructure and ae2cvs utility to latest. Fix runtest.py's swallowing of interrupts. Update various tests.

Comments (0)

Files changed (11)

 revbuilder = Builder(action = Action(SCons_revision,
                                      varlist=['COPYRIGHT', 'VERSION']))
 
+# When copying local files from a Repository (Aegis),
+# just make copies, don't symlink them.
+SetOption('duplicate', 'copy')
+
 env = Environment(
                    ENV                 = ENV,
 
 #! /usr/bin/env perl
+
+$revision = "src/ae2cvs.pl 0.04.D001 2005/08/14 15:13:36 knight";
+
+$copyright = "Copyright 2001, 2002, 2003, 2004, 2005 Steven Knight.";
+
 #
-# Copyright 2001, 2002, 2003 Steven Knight.  All rights reserved.  This program
-# is free software; you can redistribute and/or modify under the
-# same terms as Perl itself.
+# All rights reserved.  This program is free software; you can
+# redistribute and/or modify under the same terms as Perl itself.
 #
 
-$revision = "src/ae2cvs.pl 0.D002 2001/10/03 09:36:49 software";
-
 use strict;
 use File::Find;
 use File::Spec;
 use vars qw( @add_list @args @cleanup @copy_list @libraries
 	     @mkdir_list @remove_list
 	     %seen_dir
-	     $ae_copy $aedir $aedist $cnum $commit $common $cvsmod
+	     $ae_copy $aedir $aedist
+	     $cnum $comment $commit $common $copyright
+	     $cvs_command $cvsmod $cvsroot
 	     $delta $description $exec $help $indent $infile
-	     $proj $pwd $quiet
+	     $proj $pwd $quiet $revision
 	     $summary $usedir $usepath );
 
 $aedist = 1;
+$cvsroot = undef;
 $exec = undef;
 $indent = "";
 
+sub version {
+   	print "ae2cvs: $revision\n";
+   	print "$copyright\n";
+	exit 0;
+}
+
 {
     use Getopt::Long;
 
 	"aedist" => sub { $aedist = 1 },
 	"aegis" => sub { $aedist = 0 },
 	"change=i" => \$cnum,
+	"d=s" => \$cvsroot,
 	"file=s" => \$infile,
 	"help|?" => \$help,
 	"library=s" => \@libraries,
 	"project=s" => \$proj,
 	"quiet" => \$quiet,
 	"usedir=s" => \$usedir,
+	"v|version" => \&version,
 	"x|execute" => sub { $exec++ if ! defined $exec || $exec != 0 },
 	"X|EXECUTE" => sub { $exec = 2 if ! defined $exec || $exec != 0 },
     );
     $exec = 0 if ! defined $exec;
 }
 
+$cvs_command = $cvsroot ? "cvs -d $cvsroot -Q" : "cvs -Q";
+
 #
 # Wrap up the $quiet logic in one place.
 #
 }
 
 #
+# Parse a change description, in both 'aegis -l cd" and "aedist" formats.
+#
+# Returns an array containing the project name, the change number
+# (if any), the delta number (if any), the SUMMARY, the DESCRIPTION
+# and the lines describing the files in the change.
+#
+sub parse_change {
+    my $output = shift;
+
+    my ($p, $c, $d, $c_or_d, $sum, $desc, $filesection, @flines);
+
+    # The project name line comes after NAME in "aegis -l cd" format,
+    # and PROJECT in "aedist" format.  In both cases, the project name
+    # and the change/delta name are separated a comma.
+    ($p = $output) =~ s/(?:NAME|PROJECT)\n([^\n]*)\n.*/$1/ms;
+    ($p, $c_or_d) = (split(/,/, $p));
+
+    # In "aegis -l cd" format, the project name actually comes after
+    # the string "Project" and is itself enclosed in double quotes.
+    $p =~ s/Project "([^"]*)"/$1/;
+
+    # The change or delta string was the right-hand side of the comma.
+    # "aegis -l cd" format spells it "Change 123." or "Delta 123." while
+    # "aedist" format spells it "change 123."
+    if ($c_or_d =~ /\s*[Cc]hange (\d+).*/) { $c = $1 };
+    if ($c_or_d =~ /\s*[Dd]elta (\d+).*/) { $d = $1 };
+
+    # The SUMMARY line is always followed the DESCRIPTION section.
+    # It seems to always be a single line, but we grab everything in
+    # between just in case.
+    ($sum = $output) =~ s/.*\nSUMMARY\n//ms;
+    $sum =~ s/\nDESCRIPTION\n.*//ms;
+
+    # The DESCRIPTION section is followed ARCHITECTURE in "aegis -l cd"
+    # format and by CAUSE in "aedist" format.  Explicitly under it if the
+    # string is only "none," which means they didn't supply a description.
+    ($desc = $output) =~ s/.*\nDESCRIPTION\n//ms;
+    $desc =~ s/\n(ARCHITECTURE|CAUSE)\n.*//ms;
+    chomp($desc);
+    if ($desc eq "none" || $desc eq "none\n") { $desc = undef }
+
+    # The FILES section is followed by HISTORY in "aegis -l cd" format.
+    # It seems to be the last section in "aedist" format, but stripping
+    # a non-existent HISTORY section doesn't hurt.
+    ($filesection = $output) =~ s/.*\nFILES\n//ms;
+    $filesection =~ s/\nHISTORY\n.*//ms;
+
+    @flines = split(/\n/, $filesection);
+
+    ($p, $c, $d, $sum, $desc, \@flines)
+}
+
+#
 #
 #
 $pwd = Cwd::cwd();
     }
 
     my $output = filter("aedist -l -unf", $contents);
+    my ($p, $c, $d, $s, $desc, $fl) = parse_change($output);
 
-    my $filesection;
-    if (! defined $proj) {
-	($proj = $output) =~ s/PROJECT\n([^\n]*)\n.*/$1/ms;
-    }
-    ($summary = $output) =~ s/.*\nSUMMARY\n([^\n]*)\n.*/$1/ms;
-    ($description = $output) =~ s/.*\nDESCRIPTION\n([^\n]*)\nCAUSE\n.*/$1/ms;
-    ($filesection = $output) =~ s/.*\nFILES\n//ms;
-    @filelines = split(/\n/, $filesection);
+    $proj = $p if ! defined $proj;
+    $summary = $s;
+    $description = $desc;
+    @filelines = @$fl;
 
     if (! $exec) {
 	printit qq(MYTMP="/tmp/ae2cvs-ae.\$\$"\n),
     }
 
     $ae_copy = sub {
-	my $dest = shift;
-	my $source = File::Spec->catfile($aedir, "src", $dest);
-	execute(qq(cp $source $dest));
+	foreach my $dest (@_) {
+	    my $source = File::Spec->catfile($aedir, "src", $dest);
+	    execute(qq(cp $source $dest));
+	}
     }
 } else {
     $cnum = $ENV{AEGIS_CHANGE} if ! defined $cnum;
     $common = "-lib " . join(" -lib ", @libraries) if @libraries;
     $common = "$common -proj $proj" if $proj;
 
-    foreach (`aegis -l ph -unf $common`) {
-	chomp;
-	if (/^(\d+) .{24} $cnum\s*(.*)/) {
-	    $delta = $1;
-	    $summary = $2;
-	    last;
-	}
-    }
+    my $output = `aegis -l cd $cnum -unf $common`;
+    my ($p, $c, $d, $s, $desc, $fl) = parse_change($output);
+
+    $delta = $d;
+    $summary = $s;
+    $description = $desc;
+    @filelines = @$fl;
+
     if (! $delta) {
-	print STDERR "ae2cvs:  No change $cnum for project $proj.\n";
-	exit 1;
+        print STDERR "ae2cvs:  No delta number, exiting.\n";
+        exit 1;
     }
 
-    @filelines = `aegis -l cf -unf -c $cnum $common`;
-
     $ae_copy = sub {
-	my $file = shift;
-	execute(qq(aegis -cp -ind -delta $delta $common $file));
+	execute(qq(aegis -cp -ind -delta $delta $common @_));
     }
 }
 
 if (! -d File::Spec->catfile($usedir, "CVS")) {
     $cvsmod = (split(/\./, $proj))[0] if ! defined $cvsmod;
 
-    execute(qq(cvs -Q co $cvsmod));
+    execute(qq($cvs_command co $cvsmod));
 
     _chdir($cvsmod);
 
 	    $indent = "  ";
 	}
 	_mkdir($_);
-	execute(qq(cvs -Q add $_));
+	execute(qq($cvs_command add $_));
 	if (! $exec) {
 	    $indent = "";
 	    printit qq(fi\n);
 }
 
 # Copy in any files in the change, before we try to "cvs add" them.
-for (@copy_list) {
-    $ae_copy->($_);
-}
+$ae_copy->(@copy_list) if @copy_list;
 
 if (@add_list) {
-    execute(qq(cvs -Q add @add_list));
+    execute(qq($cvs_command add @add_list));
 }
 
 if (@remove_list) {
     execute(qq(rm -f @remove_list));
-    execute(qq(cvs -Q remove @remove_list));
+    execute(qq($cvs_command remove @remove_list));
 }
 
 # Last, commit the whole bunch.
-$commit = qq(cvs -Q commit -m "$summary" .);
+$comment = $summary;
+$comment .= "\n" . $description if $description;
+$commit = qq($cvs_command commit -m '$comment' .);
 if ($exec == 1) {
     printit qq(# Execute the following to commit the changes:\n),
 	    qq(# $commit\n);
 
 =head1 SYNOPSIS
 
-ae2cvs [-aedist|-aegis] [-c change] [-f file] [-l lib]
-	[-m module] [-n] [-p proj] [-q] [-u dir] [-x] [-X]
+ae2cvs [-aedist|-aegis] [-c change] [-d cvs_root] [-f file] [-l lib]
+	[-m module] [-n] [-p proj] [-q] [-u dir] [-v] [-x] [-X]
 
 	-aedist		use aedist format from input (default)
 	-aegis		query aegis repository directly
 	-c change	change number
+	-d cvs_root	CVS root directory
 	-f file		read aedist from file ('-' == stdin)
 	-l lib		Aegis library directory
 	-m module	CVS module
 	-p proj		project name
 	-q		quiet, don't print commands
 	-u dir		use dir for CVS checkin
+	-v		print version string and exit
 	-x		execute the commands, but don't commit;
 			two or more -x options commit changes
 	-X		execute the commands and commit changes
 The value of the C<AEGIS_CHANGE> environment variable
 is used by default.
 
+=item -d cvsroot
+
+Specify the CVS root directory to be used.
+This option is passed explicitly to each executed C<cvs> command.
+The default behavior is to omit any C<-d> options
+and let the executed C<cvs> commands use the
+C<CVSROOT> environment variable as they normally would.
+
 =item -f file
 
 Reads the aedist change set from the specified C<file>,
 for the checkins and commits.
 The default is to use a separately-created temporary directory.
 
+=item -v
+
+Print the version string and exit.
+
 =item -x
 
 Execute the commands to bring the CVS repository up to date,
 
 =head1 TODO
 
-Add support for the CVS -d option to allow use of a specified
-CVS repository.
-
 Add an explicit test for using ae2cvs in the Aegis
 integrate_pass_notify_command field to support fully keeping a
 repository in sync automatically.
 
 =head1 COPYRIGHT
 
-Copyright 2001, 2002, 2003 Steven Knight.
+Copyright 2001, 2002, 2003, 2004, 2005 Steven Knight.
 
 =head1 SEE ALSO
 
 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 
 __author__ = "Steven Knight <knight at baldmt dot com>"
-__revision__ = "TestCmd.py 0.13.D002 2004/11/20 08:34:16 knight"
-__version__ = "0.13"
+__revision__ = "TestCmd.py 0.15.D001 2005/08/16 17:14:33 knight"
+__version__ = "0.15"
 
 import os
 import os.path
 
 def _clean():
     global _Cleanup
-    list = _Cleanup[:]
-    _Cleanup = []
-    list.reverse()
-    for test in list:
+    cleanlist = filter(None, _Cleanup)
+    del _Cleanup[:]
+    cleanlist.reverse()
+    for test in cleanlist:
         test.cleanup()
 
 sys.exitfunc = _clean
 
+class Collector:
+    def __init__(self, top):
+        self.entries = [top]
+    def __call__(self, arg, dirname, names):
+        pathjoin = lambda n, d=dirname: os.path.join(d, n)
+        self.entries.extend(map(pathjoin, names))
+
 def _caller(tblist, skip):
     string = ""
     arr = []
             if os.path.isfile(f):
                 try:
                     st = os.stat(f)
-                except:
+                except OSError:
                     continue
                 if stat.S_IMODE(st[stat.ST_MODE]) & 0111:
                     return f
             if self.verbose:
                 sys.stderr.write("chdir(" + chdir + ")\n")
             os.chdir(chdir)
-        cmd = None
         if program:
             if not os.path.isabs(program):
                 program = os.path.join(self._cwd, program)
-            cmd = escape_cmd(program)
-            if interpreter:
-                cmd = interpreter + " " + cmd
         else:
-            cmd = escape_cmd(self.program)
-            if self.interpreter:
-                cmd =  self.interpreter + " " + cmd
+            program = self.program
+            if not interpreter:
+                interpreter = self.interpreter
+        cmd = [program]
+        if interpreter:
+            cmd = [interpreter] + cmd
         if arguments:
-            cmd = cmd + " " + arguments
+            if type(arguments) == type(''):
+                arguments = string.split(arguments)
+            cmd.extend(arguments)
+        cmd_string = string.join(cmd, ' ')
         if self.verbose:
-            sys.stderr.write(cmd + "\n")
+            sys.stderr.write(cmd_string + "\n")
         try:
             p = popen2.Popen3(cmd, 1)
         except AttributeError:
-            (tochild, fromchild, childerr) = os.popen3(cmd)
+            (tochild, fromchild, childerr) = os.popen3(cmd_string)
             if stdin:
                 if is_List(stdin):
                     for line in stdin:
             new = os.path.join(self.workdir, sub)
             try:
                 os.mkdir(new)
-            except:
+            except OSError:
                 pass
             else:
                 count = count + 1
         """
         return apply(os.path.join, (self.workdir,) + tuple(args))
 
-    def writable(self, top, write):
+    def readable(self, top, read=1):
+        """Make the specified directory tree readable (read == 1)
+        or not (read == None).
+        """
+
+        if read:
+            def do_chmod(fname):
+                try: st = os.stat(fname)
+                except OSError: pass
+                else: os.chmod(fname, stat.S_IMODE(st[stat.ST_MODE]|0400))
+        else:
+            def do_chmod(fname):
+                try: st = os.stat(fname)
+                except OSError: pass
+                else: os.chmod(fname, stat.S_IMODE(st[stat.ST_MODE]&~0400))
+
+        if os.path.isfile(top):
+            # If it's a file, that's easy, just chmod it.
+            do_chmod(top)
+        elif read:
+            # It's a directory and we're trying to turn on read
+            # permission, so it's also pretty easy, just chmod the
+            # directory and then chmod every entry on our walk down the
+            # tree.  Because os.path.walk() is top-down, we'll enable
+            # read permission on any directories that have it disabled
+            # before os.path.walk() tries to list their contents.
+            do_chmod(top)
+
+            def chmod_entries(arg, dirname, names, do_chmod=do_chmod):
+                pathnames = map(lambda n, d=dirname: os.path.join(d, n),
+                                names)
+                map(lambda p, do=do_chmod: do(p), pathnames)
+
+            os.path.walk(top, chmod_entries, None)
+        else:
+            # It's a directory and we're trying to turn off read
+            # permission, which means we have to chmod the directoreis
+            # in the tree bottom-up, lest disabling read permission from
+            # the top down get in the way of being able to get at lower
+            # parts of the tree.  But os.path.walk() visits things top
+            # down, so we just use an object to collect a list of all
+            # of the entries in the tree, reverse the list, and then
+            # chmod the reversed (bottom-up) list.
+            col = Collector(top)
+            os.path.walk(top, col, None)
+            col.entries.reverse()
+            map(lambda d, do=do_chmod: do(d), col.entries)
+
+    def writable(self, top, write=1):
         """Make the specified directory tree writable (write == 1)
         or not (write == None).
         """
 
-        def _walk_chmod(arg, dirname, names):
-            st = os.stat(dirname)
-            os.chmod(dirname, arg(st[stat.ST_MODE]))
-            for name in names:
-                n = os.path.join(dirname, name)
-                st = os.stat(n)
-                os.chmod(n, arg(st[stat.ST_MODE]))
+        if write:
+            def do_chmod(fname):
+                try: st = os.stat(fname)
+                except OSError: pass
+                else: os.chmod(fname, stat.S_IMODE(st[stat.ST_MODE]|0200))
+        else:
+            def do_chmod(fname):
+                try: st = os.stat(fname)
+                except OSError: pass
+                else: os.chmod(fname, stat.S_IMODE(st[stat.ST_MODE]&~0200))
 
-        def _mode_writable(mode):
-            return stat.S_IMODE(mode|0200)
+        if os.path.isfile(top):
+            do_chmod(top)
+        else:
+            col = Collector(top)
+            os.path.walk(top, col, None)
+            map(lambda d, do=do_chmod: do(d), col.entries)
 
-        def _mode_non_writable(mode):
-            return stat.S_IMODE(mode&~0200)
+    def executable(self, top, execute=1):
+        """Make the specified directory tree executable (execute == 1)
+        or not (execute == None).
+        """
 
-        if write:
-            f = _mode_writable
+        if execute:
+            def do_chmod(fname):
+                try: st = os.stat(fname)
+                except OSError: pass
+                else: os.chmod(fname, stat.S_IMODE(st[stat.ST_MODE]|0100))
         else:
-            f = _mode_non_writable
+            def do_chmod(fname):
+                try: st = os.stat(fname)
+                except OSError: pass
+                else: os.chmod(fname, stat.S_IMODE(st[stat.ST_MODE]&~0100))
+
         if os.path.isfile(top):
-            st = os.stat(top)
-            os.chmod(top, f(st[stat.ST_MODE]))
+            # If it's a file, that's easy, just chmod it.
+            do_chmod(top)
+        elif execute:
+            # It's a directory and we're trying to turn on execute
+            # permission, so it's also pretty easy, just chmod the
+            # directory and then chmod every entry on our walk down the
+            # tree.  Because os.path.walk() is top-down, we'll enable
+            # execute permission on any directories that have it disabled
+            # before os.path.walk() tries to list their contents.
+            do_chmod(top)
+
+            def chmod_entries(arg, dirname, names, do_chmod=do_chmod):
+                pathnames = map(lambda n, d=dirname: os.path.join(d, n),
+                                names)
+                map(lambda p, do=do_chmod: do(p), pathnames)
+
+            os.path.walk(top, chmod_entries, None)
         else:
-            try:
-                os.path.walk(top, _walk_chmod, f)
-            except:
-                pass # ignore any problems changing modes
+            # It's a directory and we're trying to turn off execute
+            # permission, which means we have to chmod the directories
+            # in the tree bottom-up, lest disabling execute permission from
+            # the top down get in the way of being able to get at lower
+            # parts of the tree.  But os.path.walk() visits things top
+            # down, so we just use an object to collect a list of all
+            # of the entries in the tree, reverse the list, and then
+            # chmod the reversed (bottom-up) list.
+            col = Collector(top)
+            os.path.walk(top, col, None)
+            col.entries.reverse()
+            map(lambda d, do=do_chmod: do(d), col.entries)
 
     def write(self, file, content, mode = 'wb'):
         """Writes the specified content text (second argument) to the

etc/TestCommon.py

 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 
 __author__ = "Steven Knight <knight at baldmt dot com>"
-__revision__ = "TestCommon.py 0.13.D001 2004/11/20 08:30:40 knight"
-__version__ = "0.13"
+__revision__ = "TestCommon.py 0.14.D001 2005/08/15 23:02:35 knight"
+__version__ = "0.14"
 
 import os
 import os.path
         file_contents = self.read(file, mode)
         try:
             self.fail_test(not self.match(file_contents, expect))
+        except KeyboardInterrupt:
+            raise
         except:
             print "Unexpected contents of `%s'" % file
             print "EXPECTED contents ======"
             match = self.match
         try:
             apply(TestCmd.run, [self], kw)
+        except KeyboardInterrupt:
+            raise
         except:
             print "STDOUT ============"
             print self.stdout()
 #!/usr/bin/env python
 #
-# __COPYRIGHT__
+# Copyright (c) 2001, 2002, 2003, 2004 The SCons Foundation
 #
 # runtest.py - wrapper script for running SCons tests
 #
 
 sp.append(cwd)
 
+#
+_ws = re.compile('\s')
+
+def escape(s):
+    if _ws.search(s):
+        s = '"' + s + '"'
+    return s
+
+# Set up lowest-common-denominator spawning of a process on both Windows
+# and non-Windows systems that works all the way back to Python 1.5.2.
+try:
+    os.spawnv
+except AttributeError:
+    def spawn_it(command_args):
+        pid = os.fork()
+        if pid == 0:
+            os.execv(command_args[0], command_args)
+        else:
+            pid, status = os.waitpid(pid, 0)
+            return status >> 8
+else:
+    def spawn_it(command_args):
+	command_args = map(escape, command_args)
+        return os.spawnv(os.P_WAIT, command_args[0], command_args)
+
 class Base:
     def __init__(self, path, spe=None):
         self.path = path
 
 class SystemExecutor(Base):
     def execute(self):
-        s = os.system(self.command)
-        if s >= 256:
-            s = s / 256
+        s = spawn_it(self.command_args)
         self.status = s
         if s < 0 or s > 2:
             sys.stdout.write("Unexpected exit status %d\n" % s)
 except AttributeError:
     class PopenExecutor(Base):
         def execute(self):
-            (tochild, fromchild, childerr) = os.popen3(self.command)
+            (tochild, fromchild, childerr) = os.popen3(self.command_str)
             tochild.close()
             self.stdout = fromchild.read()
             self.stderr = childerr.read()
 else:
     class PopenExecutor(Base):
         def execute(self):
-            p = popen2.Popen3(self.command, 1)
+            p = popen2.Popen3(self.command_str, 1)
             p.tochild.close()
             self.stdout = p.fromchild.read()
             self.stderr = p.childerr.read()
     def write(self, f):
         f.write('    <test>\n')
         f.write('      <file_name>%s</file_name>\n' % self.path)
-        f.write('      <command_line>%s</command_line>\n' % self.command)
+        f.write('      <command_line>%s</command_line>\n' % self.command_str)
         f.write('      <exit_status>%s</exit_status>\n' % self.status)
         f.write('      <stdout>%s</stdout>\n' % self.stdout)
         f.write('      <stderr>%s</stderr>\n' % self.stderr)
 
 sys.stdout = Unbuffered(sys.stdout)
 
-_ws = re.compile('\s')
-
-def escape(s):
-    if _ws.search(s):
-        s = '"' + s + '"'
-    return s
-
 for t in tests:
-    t.command = string.join(map(escape, [python, debug, t.abspath]), " ")
+    t.command_args = [python]
+    if debug:
+        t.command_args.append(debug)
+    t.command_args.append(t.abspath)
+    t.command_str = string.join(map(escape, t.command_args), " ")
     if printcommand:
-        sys.stdout.write(t.command + "\n")
+        sys.stdout.write(t.command_str + "\n")
     t.execute()
 
 passed = filter(lambda t: t.status == 0, tests)

test/Fortran/F90PATH.py

 
 import os
 import os.path
+import string
 import sys
 import TestSCons
 
 test.run()
 check(['0', '1', cc, string.strip(ccflags + ' -g'), 'v', 'v'])
 
-test.run(arguments='"RELEASE_BUILD=1"')
+test.run(arguments='RELEASE_BUILD=1')
 check(['1', '1', cc, string.strip(ccflags + ' -O -g'), 'v', 'v'])
 
-test.run(arguments='"RELEASE_BUILD=1" "DEBUG_BUILD=0"')
+test.run(arguments='RELEASE_BUILD=1 DEBUG_BUILD=0')
 check(['1', '0', cc, string.strip(ccflags + ' -O'), 'v', 'v'])
 
-test.run(arguments='"CC=not_a_c_compiler"')
+test.run(arguments='CC=not_a_c_compiler')
 check(['0', '1', 'not_a_c_compiler', string.strip(ccflags + ' -g'), 'v', 'v'])
 
-test.run(arguments='"UNDECLARED=foo"')
+test.run(arguments='UNDECLARED=foo')
 check(['0', '1', cc, string.strip(ccflags + ' -g'), 'v', 'v'])
 
-test.run(arguments='"CCFLAGS=--taco"')
+test.run(arguments='CCFLAGS=--taco')
 check(['0', '1', cc, string.strip(ccflags + ' -g'), 'v', 'v'])
 
 test.write('custom.py', """
 test.run()
 check(['1', '0', cc, string.strip(ccflags + ' -O'), 'v', 'v'])
 
-test.run(arguments='"DEBUG_BUILD=1"')
+test.run(arguments='DEBUG_BUILD=1')
 check(['1', '1', cc, string.strip(ccflags + ' -O -g'), 'v', 'v'])
 
 test.run(arguments='-h',
 checkSave('options.saved', { 'RELEASE_BUILD':1, 'DEBUG_BUILD':0})
 
 # Override with command line arguments
-test.run(arguments='"DEBUG_BUILD=3"')
+test.run(arguments='DEBUG_BUILD=3')
 check(['1','3'])
 checkSave('options.saved', {'RELEASE_BUILD':1, 'DEBUG_BUILD':3})
 
 checkSave('options.saved', {})
 
 # Now specify one option the same as default and make sure it doesn't write out
-test.run(arguments='"DEBUG_BUILD=1"')
+test.run(arguments='DEBUG_BUILD=1')
 check(['0','1'])
 checkSave('options.saved', {})
 
 # Now specify same option non-default and make sure only it is written out
-test.run(arguments='"DEBUG_BUILD=0" "LISTOPTION_TEST=a,b"')
+test.run(arguments='DEBUG_BUILD=0 LISTOPTION_TEST=a,b')
 check(['0','0'])
 checkSave('options.saved',{'DEBUG_BUILD':0, 'LISTOPTION_TEST':'a,b'})
 

test/Options/PackageOption.py

 check(['1'])
 test.run(arguments='x11=no'); check(['0'])
 test.run(arguments='x11=0'); check(['0'])
-test.run(arguments='"x11=%s"' % test.workpath()); check([test.workpath()])
+test.run(arguments=['x11=%s' % test.workpath()]); check([test.workpath()])
 
 test.run(arguments='x11=/non/existing/path/',
          stderr = """

test/Options/PathOption.py

 
 qtpath = os.path.join(workpath, 'qt')
 libpath = os.path.join(qtpath, 'lib')
-test.run(arguments='"qtdir=%s"' % qtpath)
+test.run(arguments=['qtdir=%s' % qtpath])
 check([qtpath, os.path.join('$qtdir', 'lib'), libpath])
 
 qtpath = workpath
 libpath = os.path.join(qtpath, 'nolib')
-test.run(arguments='"qt_libraries=%s"' % libpath)
+test.run(arguments=['qt_libraries=%s' % libpath])
 check([qtpath, libpath, libpath])
 
 qtpath = os.path.join(workpath, 'qt')
 libpath = os.path.join(workpath, 'nolib')
-test.run(arguments='"qtdir=%s" "qt_libraries=%s"' % (qtpath, libpath))
+test.run(arguments=['qtdir=%s' % qtpath, 'qt_libraries=%s' % libpath])
 check([qtpath, libpath, libpath])
 
 qtpath = os.path.join(workpath, 'non', 'existing', 'path')
-test.run(arguments='"qtdir=%s"' % qtpath,
+test.run(arguments=['qtdir=%s' % qtpath],
          stderr = """
 scons: *** Path for option qtdir does not exist: %s
 File "SConstruct", line 12, in ?
 """ % qtpath, status=2)
 
-test.run(arguments='"qt_libraries=%s"' % qtpath,
+test.run(arguments=['qt_libraries=%s' % qtpath],
          stderr = """
 scons: *** Path for option qt_libraries does not exist: %s
 File "SConstruct", line 12, in ?
 test.run()
 check([default_subdir])
 
-test.run(arguments='"X=%s"' % existing_file)
+test.run(arguments=['X=%s' % existing_file])
 check([existing_file])
 
-test.run(arguments='"X=%s"' % non_existing_file)
+test.run(arguments=['X=%s' % non_existing_file])
 check([non_existing_file])
 
-test.run(arguments='"X=%s"' % existing_subdir)
+test.run(arguments=['X=%s' % existing_subdir])
 check([existing_subdir])
 
-test.run(arguments='"X=%s"' % non_existing_subdir)
+test.run(arguments=['X=%s' % non_existing_subdir])
 check([non_existing_subdir])
 
 test.must_not_exist(non_existing_file)
 test.run()
 check([default_file])
 
-test.run(arguments='"X=%s"' % existing_subdir,
+test.run(arguments=['X=%s' % existing_subdir],
          status=2,
          stderr="""
 scons: *** File path for option X is a directory: %s
 File "SConstruct", line 6, in ?
 """ % existing_subdir)
 
-test.run(arguments='"X=%s"' % existing_file)
+test.run(arguments=['X=%s' % existing_file])
 check([existing_file])
 
-test.run(arguments='"X=%s"' % non_existing_file,
+test.run(arguments=['X=%s' % non_existing_file],
          status=2,
          stderr="""
 scons: *** File path for option X does not exist: %s
 test.run()
 check([default_subdir])
 
-test.run(arguments='"X=%s"' % existing_file,
+test.run(arguments=['X=%s' % existing_file],
          status=2,
          stderr="""
 scons: *** Directory path for option X is a file: %s
 File "SConstruct", line 6, in ?
 """ % existing_file)
 
-test.run(arguments='"X=%s"' % existing_subdir)
+test.run(arguments=['X=%s' % existing_subdir])
 check([existing_subdir])
 
-test.run(arguments='"X=%s"' % non_existing_subdir,
+test.run(arguments=['X=%s' % non_existing_subdir],
          status=2,
          stderr="""
 scons: *** Directory path for option X does not exist: %s
 test.run()
 check([default_subdir])
 
-test.run(arguments='"X=%s"' % existing_file,
+test.run(arguments=['X=%s' % existing_file],
          status=2,
          stderr="""
 scons: *** Path for option X is a file, not a directory: %s
 File "SConstruct", line 6, in ?
 """ % existing_file)
 
-test.run(arguments='"X=%s"' % existing_subdir)
+test.run(arguments=['X=%s' % existing_subdir])
 check([existing_subdir])
 
-test.run(arguments='"X=%s"' % non_existing_subdir)
+test.run(arguments=['X=%s' % non_existing_subdir])
 check([non_existing_subdir])
 
 test.must_exist(non_existing_subdir)

test/Perforce/Perforce.py

     pass # it's okay if this fails...it will fail if the depot is clear already.
 
 # Set up a perforce depot for testing.
-test.write("depotspec","""# A Perforce Depot Specification.
+depotspec = """\
+# A Perforce Depot Specification.
 Depot:	testme
 
 Owner:	%s
 Address:	subdir
 
 Map:	testme/...
-""" % user)
+""" % user
 
-test.run(program=p4, arguments='-p 1666 depot -i < depotspec')
+test.run(program=p4, arguments='-p 1666 depot -i', stdin = depotspec)
 
 # Now set up 2 clients, one to check in some files, and one to
 # do the building.
-clientspec = """# A Perforce Client Specification.
+clientspec = """\
+# A Perforce Client Specification.
 Client:	%s
 
 Owner:	%s
                             "//testme/foo/...", "testclient1")
 clientspec2 = clientspec % ("testclient2", user, host, test.workpath('work'),
                             "//testme/...", "testclient2")
-test.write("testclient1", clientspec1)
-test.write("testclient2", clientspec2)
 
 test.subdir('import', ['import', 'sub'], 'work')
 
-test.run(program=p4, arguments = '-p 1666 client -i < testclient1')
-test.run(program=p4, arguments = '-p 1666 client -i < testclient2')
+test.run(program=p4, arguments = '-p 1666 client -i', stdin=clientspec1)
+test.run(program=p4, arguments = '-p 1666 client -i', stdin=clientspec2)
 
 test.write(['import', 'aaa.in'], "import/aaa.in\n")
 test.write(['import', 'bbb.in'], "import/bbb.in\n")
 
 # Perforce uses the PWD environment variable in preference to the actual cwd
 os.environ["PWD"] = test.workpath('import')
-paths = map(os.path.normpath, [ 'sub/ddd.in', 'sub/eee.in', 'sub/fff.in', 'sub/SConscript' ])
-args = '-p 1666 -c testclient1 add -t binary *.in %s' % string.join(paths)
+paths = [ 'aaa.in', 'bbb.in', 'ccc.in',
+          'sub/ddd.in', 'sub/eee.in', 'sub/fff.in', 'sub/SConscript' ]
+paths = map(os.path.normpath, paths)
+args = '-p 1666 -c testclient1 add -t binary %s' % string.join(paths)
 test.run(program=p4, chdir='import', arguments=args)
 
-test.write('changespec', """
+changespec = """
 Change:	new
 
 Client:	testclient1
 	//testme/foo/sub/ddd.in	# add
 	//testme/foo/sub/eee.in	# add
 	//testme/foo/sub/fff.in	# add
-""" % user)
+""" % user
 
-test.run(program=p4, arguments='-p 1666 -c testclient1 submit -i < changespec')
+test.run(program=p4,
+         arguments='-p 1666 -c testclient1 submit -i',
+         stdin=changespec)
 
 test.write(['work', 'SConstruct'], """
 def cat(env, source, target):

test/RCS/diskcheck.py

 
 expect = """\
 
-scons: warning: Ignoring missing SConscript 'sub/SConscript'
+scons: warning: Ignoring missing SConscript '%s'
 File "SConstruct", line 23, in ?
 scons: *** Source `aaa.in' not found, needed by target `aaa.out'.  Stop.
-"""
+""" % os.path.join('sub', 'SConscript')
 
 test.run(status=2, stderr=expect)
 
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.