From e3fb1f5762e96cc339a2e34a91d45671aa76be4e Mon Sep 17 00:00:00 2001 From: stevenknight Date: Wed, 17 Aug 2005 19:00:39 +0000 Subject: [PATCH] Update test infrastructure and ae2cvs utility to latest. Fix runtest.py's swallowing of interrupts. Update various tests. git-svn-id: http://scons.tigris.org/svn/scons/trunk@1336 fdb21ef1-2011-0410-befe-b5e4ea1792b1 --- SConstruct | 4 + bin/ae2cvs | 166 +++++++++++++++++++++++--------- etc/TestCmd.py | 174 ++++++++++++++++++++++++++-------- etc/TestCommon.py | 8 +- runtest.py | 52 ++++++---- test/Fortran/F90PATH.py | 1 + test/Options.py | 18 ++-- test/Options/PackageOption.py | 2 +- test/Options/PathOption.py | 36 +++---- test/Perforce/Perforce.py | 30 +++--- test/RCS/diskcheck.py | 4 +- 11 files changed, 349 insertions(+), 146 deletions(-) diff --git a/SConstruct b/SConstruct index be557ef5..c4c99b35 100644 --- a/SConstruct +++ b/SConstruct @@ -247,6 +247,10 @@ def SCons_revision(target, source, env): 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, diff --git a/bin/ae2cvs b/bin/ae2cvs index fd40b414..e7cb22b2 100644 --- a/bin/ae2cvs +++ b/bin/ae2cvs @@ -1,12 +1,14 @@ #! /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; @@ -15,15 +17,24 @@ use Pod::Usage (); 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; @@ -33,6 +44,7 @@ $indent = ""; "aedist" => sub { $aedist = 1 }, "aegis" => sub { $aedist = 0 }, "change=i" => \$cnum, + "d=s" => \$cvsroot, "file=s" => \$infile, "help|?" => \$help, "library=s" => \@libraries, @@ -41,6 +53,7 @@ $indent = ""; "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 }, ); @@ -50,6 +63,8 @@ $indent = ""; $exec = 0 if ! defined $exec; } +$cvs_command = $cvsroot ? "cvs -d $cvsroot -Q" : "cvs -Q"; + # # Wrap up the $quiet logic in one place. # @@ -115,6 +130,59 @@ sub filter { return $output; } +# +# 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) +} + # # # @@ -144,15 +212,12 @@ if ($aedist) { } 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), @@ -181,9 +246,10 @@ if ($aedist) { } $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; @@ -192,24 +258,21 @@ if ($aedist) { $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 @_)); } } @@ -229,7 +292,7 @@ if (! File::Spec->file_name_is_absolute($usepath)) { 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); @@ -288,7 +351,7 @@ if (@mkdir_list) { $indent = " "; } _mkdir($_); - execute(qq(cvs -Q add $_)); + execute(qq($cvs_command add $_)); if (! $exec) { $indent = ""; printit qq(fi\n); @@ -300,21 +363,21 @@ if (@mkdir_list) { } # 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); @@ -352,12 +415,13 @@ ae2cvs - convert an Aegis change set to CVS commands =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 @@ -365,6 +429,7 @@ ae2cvs [-aedist|-aegis] [-c change] [-f file] [-l lib] -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 @@ -408,6 +473,14 @@ Specify the Aegis change number to be used. The value of the C 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 command. +The default behavior is to omit any C<-d> options +and let the executed C commands use the +C environment variable as they normally would. + =item -f file Reads the aedist change set from the specified C, @@ -447,6 +520,10 @@ Use the already checked-out CVS tree that exists at C 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, @@ -489,16 +566,13 @@ the time, though, so this needs more investigation. =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 diff --git a/etc/TestCmd.py b/etc/TestCmd.py index e12aa4c5..79ec8dc4 100644 --- a/etc/TestCmd.py +++ b/etc/TestCmd.py @@ -175,8 +175,8 @@ version. # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. __author__ = "Steven Knight " -__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 @@ -241,14 +241,21 @@ _Cleanup = [] 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 = [] @@ -417,7 +424,7 @@ else: 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 @@ -634,25 +641,27 @@ class TestCmd: 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: @@ -748,7 +757,7 @@ class TestCmd: new = os.path.join(self.workdir, sub) try: os.mkdir(new) - except: + except OSError: pass else: count = count + 1 @@ -837,37 +846,124 @@ class TestCmd: """ 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 diff --git a/etc/TestCommon.py b/etc/TestCommon.py index ae57f0cf..af3c8a83 100644 --- a/etc/TestCommon.py +++ b/etc/TestCommon.py @@ -80,8 +80,8 @@ The TestCommon module also provides the following variables # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. __author__ = "Steven Knight " -__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 @@ -262,6 +262,8 @@ class TestCommon(TestCmd): 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 ======" @@ -338,6 +340,8 @@ class TestCommon(TestCmd): match = self.match try: apply(TestCmd.run, [self], kw) + except KeyboardInterrupt: + raise except: print "STDOUT ============" print self.stdout() diff --git a/runtest.py b/runtest.py index 7f364793..b409ce55 100644 --- a/runtest.py +++ b/runtest.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# Copyright (c) 2001, 2002, 2003, 2004 The SCons Foundation # # runtest.py - wrapper script for running SCons tests # @@ -206,6 +206,31 @@ else: 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 @@ -220,9 +245,7 @@ class Base: 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) @@ -232,7 +255,7 @@ try: 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() @@ -243,7 +266,7 @@ except AttributeError: 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() @@ -264,7 +287,7 @@ class XML(PopenExecutor): def write(self, f): f.write(' \n') f.write(' %s\n' % self.path) - f.write(' %s\n' % self.command) + f.write(' %s\n' % self.command_str) f.write(' %s\n' % self.status) f.write(' %s\n' % self.stdout) f.write(' %s\n' % self.stderr) @@ -468,17 +491,14 @@ class Unbuffered: 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) diff --git a/test/Fortran/F90PATH.py b/test/Fortran/F90PATH.py index 87ddda13..f1fac469 100644 --- a/test/Fortran/F90PATH.py +++ b/test/Fortran/F90PATH.py @@ -26,6 +26,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" import os import os.path +import string import sys import TestSCons diff --git a/test/Options.py b/test/Options.py index ecd9aa4e..bd827d1e 100644 --- a/test/Options.py +++ b/test/Options.py @@ -114,19 +114,19 @@ def check(expect): 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', """ @@ -137,7 +137,7 @@ RELEASE_BUILD=1 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', @@ -217,7 +217,7 @@ check(['1','0']) 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}) @@ -265,12 +265,12 @@ check(['0','1']) 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'}) diff --git a/test/Options/PackageOption.py b/test/Options/PackageOption.py index ca8944d2..cc520f78 100644 --- a/test/Options/PackageOption.py +++ b/test/Options/PackageOption.py @@ -62,7 +62,7 @@ test.run() 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 = """ diff --git a/test/Options/PathOption.py b/test/Options/PathOption.py index 55f95c53..d15f39bc 100644 --- a/test/Options/PathOption.py +++ b/test/Options/PathOption.py @@ -74,27 +74,27 @@ check([qtpath, os.path.join('$qtdir', 'lib'), libpath]) 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 ? @@ -132,16 +132,16 @@ Default(env.Alias('dummy', None)) 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) @@ -173,17 +173,17 @@ test.write(default_file, "default_file\n") 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 @@ -216,17 +216,17 @@ test.subdir(default_subdir) 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 @@ -251,17 +251,17 @@ Default(env.Alias('dummy', None)) 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) diff --git a/test/Perforce/Perforce.py b/test/Perforce/Perforce.py index 891acc3c..5d41f8f0 100644 --- a/test/Perforce/Perforce.py +++ b/test/Perforce/Perforce.py @@ -59,7 +59,8 @@ except TestSCons.TestFailed: 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 @@ -74,13 +75,14 @@ Type: local 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 @@ -104,13 +106,11 @@ clientspec1 = clientspec % ("testclient1", user, host, test.workpath('import'), "//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") @@ -130,11 +130,13 @@ test.write(['import', 'sub', 'fff.in'], "import/sub/fff.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 @@ -154,9 +156,11 @@ Files: //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): diff --git a/test/RCS/diskcheck.py b/test/RCS/diskcheck.py index 4a93edf7..8af2545d 100644 --- a/test/RCS/diskcheck.py +++ b/test/RCS/diskcheck.py @@ -117,10 +117,10 @@ test.write(['sub', 'eee.in'], "checked-out sub/eee.in\n") 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) -- 2.26.2