[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc

aroben at apple.com aroben at apple.com
Wed Dec 22 15:34:50 UTC 2010


The following commit has been merged in the debian/experimental branch:
commit c28c0b0a13157f2acde96aa7ac048b0ebe9e83cd
Author: aroben at apple.com <aroben at apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Mon Nov 8 19:12:44 2010 +0000

    Make webkitpy.common.system.executive_unittest pass when running under Win32 Python
    
    Fixes <http://webkit.org/b/49033>.
    
    Reviewed by Dave Levin and Eric Seidel.
    
    * Scripts/webkitpy/common/system/executive.py:
    (Executive._run_command_with_teed_output): Pass the arguments through
    encode_argument_if_needed rather than using Cygwin-specific code here.
    (Executive.run_and_throw_if_fail): Use child_process_encoding to decode
    the output.
    (Executive.run_command): Use encode_argument_if_needed to encode the
    arguments and child_process_encoding to decode the output.
    (Executive._child_process_encoding): Returns the encoding that should be
    used when communicating with child processes. On Windows we use mbcs,
    which maps to the current code page. On all other platforms we use
    UTF-8.
    (Executive._should_encode_child_process_arguments): Returns True if
    arguments to child processes need to be encoded. This is currently
    only needed on Cygwin and Win32 Python 2.x.
    (Executive._encode_argument_if_needed): Encode the argument using
    child_process_encoding if we need to encode arguments to child
    processes on this platform.
    
    * Scripts/webkitpy/common/system/executive_unittest.py:
    (never_ending_command): Added. Returns arguments to run a command that
    will not quit until we kill it. On Windows we use wmic, on other
    platforms we use yes.
    (ExecutiveTest.test_run_command_with_unicode): Changed to expect the
    mbcs encoding to be used and for output from the child processes to
    have been roundtripped through encode/decode on Win32 Python. When
    UTF-8 is the encoding the roundtripping is undetectable, but with mbcs
    it's possible that some characters will not be able to be converted
    and will be replaced by question marks; the round-tripping allows us
    to expect this result.
    
    (ExecutiveTest.test_kill_process):
    (ExecutiveTest.test_kill_all):
    Use never_ending_command instead of invoking "yes" directly. Expect an
    exit code of 1 when using Win32 Python, as that's what seems to happen.
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@71547 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebKitTools/ChangeLog b/WebKitTools/ChangeLog
index a07d295..a5e6893 100644
--- a/WebKitTools/ChangeLog
+++ b/WebKitTools/ChangeLog
@@ -1,3 +1,47 @@
+2010-11-05  Adam Roben  <aroben at apple.com>
+
+        Make webkitpy.common.system.executive_unittest pass when running under
+        Win32 Python
+
+        Fixes <http://webkit.org/b/49033>.
+
+        Reviewed by Dave Levin and Eric Seidel.
+
+        * Scripts/webkitpy/common/system/executive.py:
+        (Executive._run_command_with_teed_output): Pass the arguments through
+        encode_argument_if_needed rather than using Cygwin-specific code here.
+        (Executive.run_and_throw_if_fail): Use child_process_encoding to decode
+        the output.
+        (Executive.run_command): Use encode_argument_if_needed to encode the
+        arguments and child_process_encoding to decode the output.
+        (Executive._child_process_encoding): Returns the encoding that should be
+        used when communicating with child processes. On Windows we use mbcs,
+        which maps to the current code page. On all other platforms we use
+        UTF-8.
+        (Executive._should_encode_child_process_arguments): Returns True if
+        arguments to child processes need to be encoded. This is currently
+        only needed on Cygwin and Win32 Python 2.x.
+        (Executive._encode_argument_if_needed): Encode the argument using
+        child_process_encoding if we need to encode arguments to child
+        processes on this platform.
+
+        * Scripts/webkitpy/common/system/executive_unittest.py:
+        (never_ending_command): Added. Returns arguments to run a command that
+        will not quit until we kill it. On Windows we use wmic, on other
+        platforms we use yes.
+        (ExecutiveTest.test_run_command_with_unicode): Changed to expect the
+        mbcs encoding to be used and for output from the child processes to
+        have been roundtripped through encode/decode on Win32 Python. When
+        UTF-8 is the encoding the roundtripping is undetectable, but with mbcs
+        it's possible that some characters will not be able to be converted
+        and will be replaced by question marks; the round-tripping allows us
+        to expect this result.
+
+        (ExecutiveTest.test_kill_process):
+        (ExecutiveTest.test_kill_all):
+        Use never_ending_command instead of invoking "yes" directly. Expect an
+        exit code of 1 when using Win32 Python, as that's what seems to happen.
+
 2010-11-08  Adam Roben  <aroben at apple.com>
 
         Roll out r71532
diff --git a/WebKitTools/Scripts/webkitpy/common/system/executive.py b/WebKitTools/Scripts/webkitpy/common/system/executive.py
index 7321ce9..37f4e53 100644
--- a/WebKitTools/Scripts/webkitpy/common/system/executive.py
+++ b/WebKitTools/Scripts/webkitpy/common/system/executive.py
@@ -45,6 +45,7 @@ import sys
 import time
 
 from webkitpy.common.system.deprecated_logging import tee
+from webkitpy.python24 import versioning
 
 
 _log = logging.getLogger("webkitpy.common.system")
@@ -104,13 +105,8 @@ class Executive(object):
 
     def _run_command_with_teed_output(self, args, teed_output):
         args = map(unicode, args)  # Popen will throw an exception if args are non-strings (like int())
-        if sys.platform == 'cygwin':
-            # Cygwin's Python's os.execv doesn't support unicode command
-            # arguments, and neither does Cygwin's execv itself.
-            # FIXME: Using UTF-8 here will confuse Windows-native commands
-            # which will expect arguments to be encoded using the current code
-            # page.
-            args = [arg.encode('utf-8') for arg in args]
+        args = map(self._encode_argument_if_needed, args)
+
         child_process = subprocess.Popen(args,
                                          stdout=subprocess.PIPE,
                                          stderr=subprocess.STDOUT,
@@ -149,9 +145,8 @@ class Executive(object):
         child_output = child_out_file.getvalue()
         child_out_file.close()
 
-        # We assume the child process output utf-8
         if decode_output:
-            child_output = child_output.decode("utf-8")
+            child_output = child_output.decode(self._child_process_encoding())
 
         if exit_code:
             raise ScriptError(script_args=args,
@@ -310,7 +305,7 @@ class Executive(object):
         # for an example of a regresion caused by passing a unicode string directly.
         # FIXME: We may need to encode differently on different platforms.
         if isinstance(input, unicode):
-            input = input.encode("utf-8")
+            input = input.encode(self._child_process_encoding())
         return (subprocess.PIPE, input)
 
     def _command_for_printing(self, args):
@@ -338,13 +333,8 @@ class Executive(object):
         assert(isinstance(args, list) or isinstance(args, tuple))
         start_time = time.time()
         args = map(unicode, args)  # Popen will throw an exception if args are non-strings (like int())
-        if sys.platform == 'cygwin':
-            # Cygwin's Python's os.execv doesn't support unicode command
-            # arguments, and neither does Cygwin's execv itself.
-            # FIXME: Using UTF-8 here will confuse Windows-native commands
-            # which will expect arguments to be encoded using the current code
-            # page.
-            args = [arg.encode('utf-8') for arg in args]
+        args = map(self._encode_argument_if_needed, args)
+
         stdin, string_to_communicate = self._compute_stdin(input)
         stderr = subprocess.STDOUT if return_stderr else None
 
@@ -355,9 +345,11 @@ class Executive(object):
                                    cwd=cwd,
                                    close_fds=self._should_close_fds())
         output = process.communicate(string_to_communicate)[0]
+
         # run_command automatically decodes to unicode() unless explicitly told not to.
         if decode_output:
-            output = output.decode("utf-8")
+            output = output.decode(self._child_process_encoding())
+
         # wait() is not threadsafe and can throw OSError due to:
         # http://bugs.python.org/issue1731717
         exit_code = process.wait()
@@ -374,3 +366,34 @@ class Executive(object):
                                        cwd=cwd)
             (error_handler or self.default_error_handler)(script_error)
         return output
+
+    def _child_process_encoding(self):
+        # Win32 Python 2.x uses CreateProcessA rather than CreateProcessW
+        # to launch subprocesses, so we have to encode arguments using the
+        # current code page.
+        if sys.platform == 'win32' and versioning.compare_version(sys, '3.0')[0] < 0:
+            return 'mbcs'
+        # All other platforms use UTF-8.
+        # FIXME: Using UTF-8 on Cygwin will confuse Windows-native commands
+        # which will expect arguments to be encoded using the current code
+        # page.
+        return 'utf-8'
+
+    def _should_encode_child_process_arguments(self):
+        # Cygwin's Python's os.execv doesn't support unicode command
+        # arguments, and neither does Cygwin's execv itself.
+        if sys.platform == 'cygwin':
+            return True
+
+        # Win32 Python 2.x uses CreateProcessA rather than CreateProcessW
+        # to launch subprocesses, so we have to encode arguments using the
+        # current code page.
+        if sys.platform == 'win32' and versioning.compare_version(sys, '3.0')[0] < 0:
+            return True
+
+        return False
+
+    def _encode_argument_if_needed(self, argument):
+        if not self._should_encode_child_process_arguments():
+            return argument
+        return argument.encode(self._child_process_encoding())
diff --git a/WebKitTools/Scripts/webkitpy/common/system/executive_unittest.py b/WebKitTools/Scripts/webkitpy/common/system/executive_unittest.py
index af2b45e..b8fd82e 100644
--- a/WebKitTools/Scripts/webkitpy/common/system/executive_unittest.py
+++ b/WebKitTools/Scripts/webkitpy/common/system/executive_unittest.py
@@ -37,6 +37,15 @@ from webkitpy.common.system.executive import Executive, run_command, ScriptError
 from webkitpy.test import cat, echo
 
 
+def never_ending_command():
+    """Arguments for a command that will never end (useful for testing process
+    killing). It should be a process that is unlikely to already be running
+    because all instances will be killed."""
+    if sys.platform == 'win32':
+        return ['wmic']
+    return ['yes']
+
+
 class ExecutiveTest(unittest.TestCase):
 
     def test_run_command_with_bad_command(self):
@@ -55,39 +64,49 @@ class ExecutiveTest(unittest.TestCase):
         """Validate that it is safe to pass unicode() objects
         to Executive.run* methods, and they will return unicode()
         objects by default unless decode_output=False"""
+        unicode_tor_input = u"WebKit \u2661 Tor Arne Vestb\u00F8!"
+        if sys.platform == 'win32':
+            encoding = 'mbcs'
+        else:
+            encoding = 'utf-8'
+        encoded_tor = unicode_tor_input.encode(encoding)
+        # On Windows, we expect the unicode->mbcs->unicode roundtrip to be
+        # lossy. On other platforms, we expect a lossless roundtrip.
+        if sys.platform == 'win32':
+            unicode_tor_output = encoded_tor.decode(encoding)
+        else:
+            unicode_tor_output = unicode_tor_input
+
         executive = Executive()
-        unicode_tor = u"WebKit \u2661 Tor Arne Vestb\u00F8!"
-        utf8_tor = unicode_tor.encode("utf-8")
 
-        output = executive.run_command(cat.command_arguments(), input=unicode_tor)
-        self.assertEquals(output, unicode_tor)
+        output = executive.run_command(cat.command_arguments(), input=unicode_tor_input)
+        self.assertEquals(output, unicode_tor_output)
 
-        output = executive.run_command(echo.command_arguments("-n", unicode_tor))
-        self.assertEquals(output, unicode_tor)
+        output = executive.run_command(echo.command_arguments("-n", unicode_tor_input))
+        self.assertEquals(output, unicode_tor_output)
 
-        output = executive.run_command(echo.command_arguments("-n", unicode_tor), decode_output=False)
-        self.assertEquals(output, utf8_tor)
+        output = executive.run_command(echo.command_arguments("-n", unicode_tor_input), decode_output=False)
+        self.assertEquals(output, encoded_tor)
 
         # Make sure that str() input also works.
-        output = executive.run_command(cat.command_arguments(), input=utf8_tor, decode_output=False)
-        self.assertEquals(output, utf8_tor)
+        output = executive.run_command(cat.command_arguments(), input=encoded_tor, decode_output=False)
+        self.assertEquals(output, encoded_tor)
 
         # FIXME: We should only have one run* method to test
-        output = executive.run_and_throw_if_fail(echo.command_arguments("-n", unicode_tor), quiet=True)
-        self.assertEquals(output, unicode_tor)
+        output = executive.run_and_throw_if_fail(echo.command_arguments("-n", unicode_tor_input), quiet=True)
+        self.assertEquals(output, unicode_tor_output)
 
-        output = executive.run_and_throw_if_fail(echo.command_arguments("-n", unicode_tor), quiet=True, decode_output=False)
-        self.assertEquals(output, utf8_tor)
+        output = executive.run_and_throw_if_fail(echo.command_arguments("-n", unicode_tor_input), quiet=True, decode_output=False)
+        self.assertEquals(output, encoded_tor)
 
     def test_kill_process(self):
         executive = Executive()
-        # We use "yes" because it loops forever.
-        process = subprocess.Popen(["yes"], stdout=subprocess.PIPE)
+        process = subprocess.Popen(never_ending_command(), stdout=subprocess.PIPE)
         self.assertEqual(process.poll(), None)  # Process is running
         executive.kill_process(process.pid)
         # Note: Can't use a ternary since signal.SIGKILL is undefined for sys.platform == "win32"
         if sys.platform == "win32":
-            expected_exit_code = 0  # taskkill.exe results in exit(0)
+            expected_exit_code = 1
         else:
             expected_exit_code = -signal.SIGKILL
         self.assertEqual(process.wait(), expected_exit_code)
@@ -111,17 +130,19 @@ class ExecutiveTest(unittest.TestCase):
     def test_kill_all(self):
         executive = Executive()
         # We use "yes" because it loops forever.
-        process = subprocess.Popen(["yes"], stdout=subprocess.PIPE)
+        process = subprocess.Popen(never_ending_command(), stdout=subprocess.PIPE)
         self.assertEqual(process.poll(), None)  # Process is running
-        executive.kill_all("yes")
+        executive.kill_all(never_ending_command()[0])
         # Note: Can't use a ternary since signal.SIGTERM is undefined for sys.platform == "win32"
-        if sys.platform in ("win32", "cygwin"):
-            expected_exit_code = 0  # taskkill.exe results in exit(0)
+        if sys.platform == "cygwin":
+            expected_exit_code = 0  # os.kill results in exit(0) for this process.
+        elif sys.platform == "win32":
+            expected_exit_code = 1
         else:
             expected_exit_code = -signal.SIGTERM
         self.assertEqual(process.wait(), expected_exit_code)
         # Killing again should fail silently.
-        executive.kill_all("yes")
+        executive.kill_all(never_ending_command()[0])
 
     def test_check_running_pid(self):
         executive = Executive()

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list