Update Test{Cmd,Common}.py from upstream, with a new
authorstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Tue, 12 Jan 2010 07:14:49 +0000 (07:14 +0000)
committerstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Tue, 12 Jan 2010 07:14:49 +0000 (07:14 +0000)
TestCommon.must_not_contain() method, new-style classes (inherit
from object), and a fix for a Windows race by only opening up a
pipe to stdin if we have something to write to it.

git-svn-id: http://scons.tigris.org/svn/scons/trunk@4611 fdb21ef1-2011-0410-befe-b5e4ea1792b1

QMTest/TestCmd.py
QMTest/TestCommon.py
QMTest/TestSCons.py

index bce7ebba0d44dcc839fdb15ae228fb9b269b72cd..029c1d05f7c7119e0e621d438080bebe58206c0c 100644 (file)
@@ -198,7 +198,7 @@ version.
     TestCmd.where_is('foo', 'PATH1;PATH2', '.suffix3;.suffix4')
 """
 
-# Copyright 2000, 2001, 2002, 2003, 2004 Steven Knight
+# Copyright 2000-2010 Steven Knight
 # This module is free software, and you may redistribute it and/or modify
 # it under the same terms as Python itself, so long as this copyright message
 # and disclaimer are retained in their original form.
@@ -215,8 +215,8 @@ version.
 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 
 __author__ = "Steven Knight <knight at baldmt dot com>"
-__revision__ = "TestCmd.py 0.36.D001 2009/07/24 08:45:26 knight"
-__version__ = "0.36"
+__revision__ = "TestCmd.py 0.37.D001 2010/01/11 16:55:50 knight"
+__version__ = "0.37"
 
 import errno
 import os
@@ -828,7 +828,15 @@ def send_all(p, data):
 
 
 
-class TestCmd:
+try:
+    object
+except NameError:
+    class object:
+        pass
+
+
+
+class TestCmd(object):
     """Class TestCmd
     """
 
@@ -989,13 +997,13 @@ class TestCmd:
                            interpreter = None,
                            arguments = None):
         if program:
-            if type(program) is type('') and not os.path.isabs(program):
+            if type(program) == type('') and not os.path.isabs(program):
                 program = os.path.join(self._cwd, program)
         else:
             program = self.program
             if not interpreter:
                 interpreter = self.interpreter
-        if type(program) not in [type([]), type(())]:
+        if not type(program) in [type([]), type(())]:
             program = [program]
         cmd = list(program)
         if interpreter:
@@ -1003,7 +1011,7 @@ class TestCmd:
                 interpreter = [interpreter]
             cmd = list(interpreter) + cmd
         if arguments:
-            if type(arguments) is type(''):
+            if type(arguments) == type(''):
                 arguments = string.split(arguments)
             cmd.extend(arguments)
         return cmd
@@ -1147,6 +1155,14 @@ class TestCmd:
         if universal_newlines is None:
             universal_newlines = self.universal_newlines
 
+        # On Windows, if we make stdin a pipe when we plan to send 
+        # no input, and the test program exits before
+        # Popen calls msvcrt.open_osfhandle, that call will fail.
+        # So don't use a pipe for stdin if we don't need one.
+        stdin = kw.get('stdin', None)
+        if stdin is not None:
+            stdin = subprocess.PIPE
+
         combine = kw.get('combine', self.combine)
         if combine:
             stderr_value = subprocess.STDOUT
@@ -1154,7 +1170,7 @@ class TestCmd:
             stderr_value = subprocess.PIPE
 
         return Popen(cmd,
-                     stdin=subprocess.PIPE,
+                     stdin=stdin,
                      stdout=subprocess.PIPE,
                      stderr=stderr_value,
                      universal_newlines=universal_newlines)
@@ -1196,14 +1212,18 @@ class TestCmd:
             if self.verbose:
                 sys.stderr.write("chdir(" + chdir + ")\n")
             os.chdir(chdir)
-        p = self.start(program, interpreter, arguments, universal_newlines)
+        p = self.start(program,
+                       interpreter,
+                       arguments,
+                       universal_newlines,
+                       stdin=stdin)
         if stdin:
             if is_List(stdin):
                 for line in stdin:
                     p.stdin.write(line)
             else:
                 p.stdin.write(stdin)
-        p.stdin.close()
+            p.stdin.close()
 
         out = p.stdout.read()
         if p.stderr is None:
index 5356facbdd9ff8f9679f8d581754c3d7ad0accf6..4aa7185a2ffeb23db12ab2c86340ff14fdf8f10f 100644 (file)
@@ -46,6 +46,8 @@ provided by the TestCommon class:
 
     test.must_not_be_writable('file1', ['file2', ...])
 
+    test.must_not_contain('file', 'banned text\n')
+
     test.must_not_contain_any_line(output, lines, ['title', find])
 
     test.must_not_exist('file1', ['file2', ...])
@@ -70,7 +72,7 @@ The TestCommon module also provides the following variables
 
 """
 
-# Copyright 2000, 2001, 2002, 2003, 2004 Steven Knight
+# Copyright 2000-2010 Steven Knight
 # This module is free software, and you may redistribute it and/or modify
 # it under the same terms as Python itself, so long as this copyright message
 # and disclaimer are retained in their original form.
@@ -87,8 +89,8 @@ The TestCommon module also provides the following variables
 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 
 __author__ = "Steven Knight <knight at baldmt dot com>"
-__revision__ = "TestCommon.py 0.36.D001 2009/07/24 08:45:26 knight"
-__version__ = "0.36"
+__revision__ = "TestCommon.py 0.37.D001 2010/01/11 16:55:50 knight"
+__version__ = "0.37"
 
 import copy
 import os
@@ -333,6 +335,19 @@ class TestCommon(TestCmd):
             self.diff(expect, file_contents, 'contents ')
             raise
 
+    def must_not_contain(self, file, banned, mode = 'rb'):
+        """Ensures that the specified file doesn't contain the banned text.
+        """
+        file_contents = self.read(file, mode)
+        contains = (string.find(file_contents, banned) != -1)
+        if contains:
+            print "File `%s' contains banned string." % file
+            print self.banner('Banned string ')
+            print banned
+            print self.banner('%s contents ' % file)
+            print file_contents
+            self.fail_test(contains)
+
     def must_not_contain_any_line(self, output, lines, title=None, find=None):
         """Ensures that the specified output string (first argument)
         does not contain any of the specified lines (second argument).
index bc1ba034a69f049db7fc3df2e81c84766769d8a3..ce0117413f7388807d96e4931986b519129899b3 100644 (file)
@@ -959,6 +959,18 @@ print py_ver
 
         return [python] + string.split(string.strip(self.stdout()), '\n')
 
+    def start(self, *args, **kw):
+        """
+        Starts SCons in the test environment.
+
+        This method exists to tell Test{Cmd,Common} that we're going to
+        use standard input without forcing every .start() call in the
+        individual tests to do so explicitly.
+        """
+        if not kw.has_key('stdin'):
+            kw['stdin'] = True
+        return apply(TestCommon.start, (self,) + args, kw)
+
     def wait_for(self, fname, timeout=10.0, popen=None):
         """
         Waits for the specified file name to exist.