Title: [192944] trunk/Tools
Revision
192944
Author
bfulg...@apple.com
Date
2015-12-02 08:53:12 -0800 (Wed, 02 Dec 2015)

Log Message

[Win] Run non-http tests without Cygwin
https://bugs.webkit.org/show_bug.cgi?id=151721

Reviewed by Andy Estes.

Support native 32-bit and 64-bit Python (and Perl) builds
for running tests:

1. Use "startswith('win')", rather than "== 'win32'" to support
various Windows build types.
2. Supply full path for some native Windows utilities, since the
path environment does not always have the specified, and they are
guaranteed to exist in those specific locations.
3. Make sure native Windows Python test runs pass proper environment
variables to run programs.
4. Append 'exe' suffix when running Windows executables.
5. Use the _winreg Python module on Windows, since the Cygwin 'regtool'
command doesn't exist.
        
* Scripts/update-webkit: Use Perl $^X command to refer to the path of
the current Perl executable, rather than requiring a new path search.
* Scripts/webkitpy/common/find_files_unittest.py:
(TestWinNormalize.test_win): Use startswith('win').
* Scripts/webkitpy/common/prettypatch_unittest.py:
(test_pretty_diff_encodings): Ditto.
* Scripts/webkitpy/common/system/executive.py:
(Executive._should_close_fds): Ditto.
(Executive.shell_command_for_script): Use startswith('win').
(Executive.kill_process): Use full path to killall executable.
(Executive.check_running_pid): Use startswith('win').
(Executive.running_pids): Ditto.
(Executive.kill_all): Ditto. Also use path to 'killall' executable when
running under native Windows Python.
(Executive._child_process_encoding): Use startswith('win').
(Executive._should_encode_child_process_arguments): Ditto.
(Executive.popen): Recognize proper script engine on Windows, since it
does not support the shebang syntax.
(Executive.run_in_parallel): Use startswith('win').
* Scripts/webkitpy/common/system/executive_unittest.py:
(never_ending_command): Ditto.
(ExecutiveTest.test_run_command_with_unicode): Ditto.
(ExecutiveTest.serial_test_kill_process): Ditto.
(ExecutiveTest.serial_test_kill_all): Ditto.
(ExecutiveTest.serial_test_check_running_pid): Ditto.
(ExecutiveTest.serial_test_run_in_parallel): Ditto.
(main): Ditto.
* Scripts/webkitpy/common/system/file_lock.py:
(FileLock._create_lock): Ditto.
(FileLock._remove_lock): Ditto.
* Scripts/webkitpy/common/system/filesystem_unittest.py:
(RealFileSystemTest.test_chdir): Ditto.
(RealFileSystemTest.test_chdir__notexists): Ditto.
(RealFileSystemTest.test_maybe_make_directory__failure): Ditto.
* Scripts/webkitpy/common/system/path_unittest.py:
(AbspathTest.test_abspath_to_uri_win): Ditto.
* Scripts/webkitpy/common/system/platforminfo.py:
(PlatformInfo._determine_os_name): Ditto.
* Scripts/webkitpy/common/system/user.py: Ditto.
* Scripts/webkitpy/layout_tests/controllers/manager_unittest.py:
(ManagerTest.integration_test_needs_servers): Ditto.
* Scripts/webkitpy/layout_tests/servers/apache_http_server.py:
(LayoutTestApacheHttpd.__init__): Handle upper and lower-case
driver letters.
(LayoutTestApacheHttpd._get_apache_config_file_path): Ditto.
* Scripts/webkitpy/layout_tests/servers/apache_http_server_unittest.py:
(TestLayoutTestApacheHttpd.test_start_cmd): Ditto.
* Scripts/webkitpy/layout_tests/servers/http_server_base.py:
(HttpServerBase._check_that_all_ports_are_available): Ditto.
* Scripts/webkitpy/layout_tests/servers/http_server_unittest.py:
(TestHttpServer.test_start_cmd): Ditto.
* Scripts/webkitpy/port/base.py:
(Port.to.setup_environ_for_server): Include 'COMSPEC', 'SYSTEMDRIVE',
and 'SYSTEMROOT' in environment passed to test runners.
(Port._apache_config_file_name_for_platform): Use startswith('win').
(Port._build_path): Ditto.
(Port._path_to_driver): Include 'exe' suffix when running under native
Windows.
* Scripts/webkitpy/port/driver.py:
(Driver._setup_environ_for_driver): Explicitly make some environment
variables strings.
* Scripts/webkitpy/port/server_process.py:
(ServerProcess.__init__): Use startswith('win').
* Scripts/webkitpy/port/win.py:
(WinPort): Use the win32 registry utilities on Windows, and appropriate
registry key formats.
(WinPort._ntsd_location): Revise tool search paths for Windows 10.
(WinPort.read_registry_value): Revise to use _winreg library on Windows,
and regtool on Cygwin.
(WinPort.write_registry_value): Ditto.
(WinPort.setup_crash_log_saving): Ditto.
(WinPort.restore_crash_log_saving): Ditto.
(WinPort.prevent_error_dialogs): Ditto.
(WinPort.allow_error_dialogs): Ditto.
(WinPort.find_system_pid): Revise to use Windows management
infrastructure on native Windows, continue using 'ps' on Cygwin.
(WinPort.read_registry_string): Deleted.
(WinPort.write_registry_string): Deleted.
* Scripts/webkitpy/test/main.py:
(main): Use startswith('win').
(Tester._parse_args): Ditto.

Modified Paths

Diff

Modified: trunk/Tools/ChangeLog (192943 => 192944)


--- trunk/Tools/ChangeLog	2015-12-02 12:08:36 UTC (rev 192943)
+++ trunk/Tools/ChangeLog	2015-12-02 16:53:12 UTC (rev 192944)
@@ -1,3 +1,106 @@
+2015-12-02  Brent Fulgham  <bfulg...@apple.com>
+
+        [Win] Run non-http tests without Cygwin
+        https://bugs.webkit.org/show_bug.cgi?id=151721
+
+        Reviewed by Andy Estes.
+
+        Support native 32-bit and 64-bit Python (and Perl) builds
+        for running tests:
+
+        1. Use "startswith('win')", rather than "== 'win32'" to support
+        various Windows build types.
+        2. Supply full path for some native Windows utilities, since the
+        path environment does not always have the specified, and they are
+        guaranteed to exist in those specific locations.
+        3. Make sure native Windows Python test runs pass proper environment
+        variables to run programs.
+        4. Append 'exe' suffix when running Windows executables.
+        5. Use the _winreg Python module on Windows, since the Cygwin 'regtool'
+        command doesn't exist.
+        
+        * Scripts/update-webkit: Use Perl $^X command to refer to the path of
+        the current Perl executable, rather than requiring a new path search.
+        * Scripts/webkitpy/common/find_files_unittest.py:
+        (TestWinNormalize.test_win): Use startswith('win').
+        * Scripts/webkitpy/common/prettypatch_unittest.py:
+        (test_pretty_diff_encodings): Ditto.
+        * Scripts/webkitpy/common/system/executive.py:
+        (Executive._should_close_fds): Ditto.
+        (Executive.shell_command_for_script): Use startswith('win').
+        (Executive.kill_process): Use full path to killall executable.
+        (Executive.check_running_pid): Use startswith('win').
+        (Executive.running_pids): Ditto.
+        (Executive.kill_all): Ditto. Also use path to 'killall' executable when
+        running under native Windows Python.
+        (Executive._child_process_encoding): Use startswith('win').
+        (Executive._should_encode_child_process_arguments): Ditto.
+        (Executive.popen): Recognize proper script engine on Windows, since it
+        does not support the shebang syntax.
+        (Executive.run_in_parallel): Use startswith('win').
+        * Scripts/webkitpy/common/system/executive_unittest.py:
+        (never_ending_command): Ditto.
+        (ExecutiveTest.test_run_command_with_unicode): Ditto.
+        (ExecutiveTest.serial_test_kill_process): Ditto.
+        (ExecutiveTest.serial_test_kill_all): Ditto.
+        (ExecutiveTest.serial_test_check_running_pid): Ditto.
+        (ExecutiveTest.serial_test_run_in_parallel): Ditto.
+        (main): Ditto.
+        * Scripts/webkitpy/common/system/file_lock.py:
+        (FileLock._create_lock): Ditto.
+        (FileLock._remove_lock): Ditto.
+        * Scripts/webkitpy/common/system/filesystem_unittest.py:
+        (RealFileSystemTest.test_chdir): Ditto.
+        (RealFileSystemTest.test_chdir__notexists): Ditto.
+        (RealFileSystemTest.test_maybe_make_directory__failure): Ditto.
+        * Scripts/webkitpy/common/system/path_unittest.py:
+        (AbspathTest.test_abspath_to_uri_win): Ditto.
+        * Scripts/webkitpy/common/system/platforminfo.py:
+        (PlatformInfo._determine_os_name): Ditto.
+        * Scripts/webkitpy/common/system/user.py: Ditto.
+        * Scripts/webkitpy/layout_tests/controllers/manager_unittest.py:
+        (ManagerTest.integration_test_needs_servers): Ditto.
+        * Scripts/webkitpy/layout_tests/servers/apache_http_server.py:
+        (LayoutTestApacheHttpd.__init__): Handle upper and lower-case
+        driver letters.
+        (LayoutTestApacheHttpd._get_apache_config_file_path): Ditto.
+        * Scripts/webkitpy/layout_tests/servers/apache_http_server_unittest.py:
+        (TestLayoutTestApacheHttpd.test_start_cmd): Ditto.
+        * Scripts/webkitpy/layout_tests/servers/http_server_base.py:
+        (HttpServerBase._check_that_all_ports_are_available): Ditto.
+        * Scripts/webkitpy/layout_tests/servers/http_server_unittest.py:
+        (TestHttpServer.test_start_cmd): Ditto.
+        * Scripts/webkitpy/port/base.py:
+        (Port.to.setup_environ_for_server): Include 'COMSPEC', 'SYSTEMDRIVE',
+        and 'SYSTEMROOT' in environment passed to test runners.
+        (Port._apache_config_file_name_for_platform): Use startswith('win').
+        (Port._build_path): Ditto.
+        (Port._path_to_driver): Include 'exe' suffix when running under native
+        Windows.
+        * Scripts/webkitpy/port/driver.py:
+        (Driver._setup_environ_for_driver): Explicitly make some environment
+        variables strings.
+        * Scripts/webkitpy/port/server_process.py:
+        (ServerProcess.__init__): Use startswith('win').
+        * Scripts/webkitpy/port/win.py:
+        (WinPort): Use the win32 registry utilities on Windows, and appropriate
+        registry key formats.
+        (WinPort._ntsd_location): Revise tool search paths for Windows 10.
+        (WinPort.read_registry_value): Revise to use _winreg library on Windows,
+        and regtool on Cygwin.
+        (WinPort.write_registry_value): Ditto.
+        (WinPort.setup_crash_log_saving): Ditto.
+        (WinPort.restore_crash_log_saving): Ditto.
+        (WinPort.prevent_error_dialogs): Ditto.
+        (WinPort.allow_error_dialogs): Ditto.
+        (WinPort.find_system_pid): Revise to use Windows management
+        infrastructure on native Windows, continue using 'ps' on Cygwin.
+        (WinPort.read_registry_string): Deleted.
+        (WinPort.write_registry_string): Deleted.
+        * Scripts/webkitpy/test/main.py:
+        (main): Use startswith('win').
+        (Tester._parse_args): Ditto.
+
 2015-12-01  Yusuke Suzuki  <utatane....@gmail.com>
 
         [ES6] Implement LLInt/Baseline Support for ES6 Generators and enable this feature

Modified: trunk/Tools/Scripts/update-webkit (192943 => 192944)


--- trunk/Tools/Scripts/update-webkit	2015-12-02 12:08:36 UTC (rev 192943)
+++ trunk/Tools/Scripts/update-webkit	2015-12-02 16:53:12 UTC (rev 192944)
@@ -76,10 +76,10 @@
 runGitUpdate() if isGit();
 
 if (isAppleWinWebKit() && $auxiliaryLibs) {
-    system("perl", "Tools/Scripts/update-webkit-auxiliary-libs") == 0 or die;
+    system($^X, File::Spec->catfile("Tools", "Scripts", "update-webkit-auxiliary-libs")) == 0 or die;
     if (isWinCairo()) {
         # WinCairo shares the auxiliary libs from the Apple port.
-        system("perl", "Tools/Scripts/update-webkit-wincairo-libs") == 0 or die;
+        system($^X, File::Spec->catfile("Tools", "Scripts", "update-webkit-wincairo-libs")) == 0 or die;
     }
 }
 

Modified: trunk/Tools/Scripts/webkitpy/common/find_files_unittest.py (192943 => 192944)


--- trunk/Tools/Scripts/webkitpy/common/find_files_unittest.py	2015-12-02 12:08:36 UTC (rev 192943)
+++ trunk/Tools/Scripts/webkitpy/common/find_files_unittest.py	2015-12-02 16:53:12 UTC (rev 192944)
@@ -56,6 +56,6 @@
     def test_win(self):
         # This tests the actual windows platform, to ensure we get the same
         # results that we get in test_mocked_win().
-        if sys.platform != 'win32':
+        if not sys.platform.startswith('win'):
             return
         self.assert_filesystem_normalizes(FileSystem())

Modified: trunk/Tools/Scripts/webkitpy/common/prettypatch_unittest.py (192943 => 192944)


--- trunk/Tools/Scripts/webkitpy/common/prettypatch_unittest.py	2015-12-02 12:08:36 UTC (rev 192943)
+++ trunk/Tools/Scripts/webkitpy/common/prettypatch_unittest.py	2015-12-02 16:53:12 UTC (rev 192944)
@@ -70,7 +70,7 @@
         if not self.check_ruby():
             return
 
-        if sys.platform == 'win32':
+        if sys.platform.startswith('win'):
             # FIXME: disabled due to https://bugs.webkit.org/show_bug.cgi?id=93192
             return
 

Modified: trunk/Tools/Scripts/webkitpy/common/system/executive.py (192943 => 192944)


--- trunk/Tools/Scripts/webkitpy/common/system/executive.py	2015-12-02 12:08:36 UTC (rev 192943)
+++ trunk/Tools/Scripts/webkitpy/common/system/executive.py	2015-12-02 16:53:12 UTC (rev 192944)
@@ -93,7 +93,7 @@
         # multiple threads). See http://bugs.python.org/issue2320 .
         # Note that close_fds isn't supported on Windows, but this bug only
         # shows up on Mac and Linux.
-        return sys.platform not in ('win32', 'cygwin')
+        return not (sys.platform == 'cygwin' or sys.platform.startswith('win'))
 
     def _run_command_with_teed_output(self, args, teed_output, **kwargs):
         child_process = self.popen(args,
@@ -174,7 +174,7 @@
     def shell_command_for_script(script_path, fs=None):
         fs = fs or FileSystem()
         # Win32 does not support shebang. We need to detect the interpreter ourself.
-        if sys.platform == 'win32':
+        if sys.platform.startswith('win'):
             interpreter = Executive.interpreter_for_script(script_path, fs)
             if interpreter:
                 return [interpreter, script_path]
@@ -183,11 +183,12 @@
     def kill_process(self, pid):
         """Attempts to kill the given pid.
         Will fail silently if pid does not exist or insufficient permisssions."""
-        if sys.platform == "win32":
+        if sys.platform.startswith('win32'):
             # We only use taskkill.exe on windows (not cygwin) because subprocess.pid
             # is a CYGWIN pid and taskkill.exe expects a windows pid.
             # Thankfully os.kill on CYGWIN handles either pid type.
-            command = ["taskkill.exe", "/f", "/t", "/pid", pid]
+            task_kill_executable = os.path.join('C:', os.sep, 'WINDOWS', 'system32', 'taskkill.exe')
+            command = [task_kill_executable, "/f", "/t", "/pid", pid]
             # taskkill will exit 128 if the process is not found.  We should log.
             self.run_command(command, error_handler=self.ignore_error)
             return
@@ -264,7 +265,7 @@
 
     def check_running_pid(self, pid):
         """Return True if pid is alive, otherwise return False."""
-        if sys.platform == 'win32':
+        if sys.platform.startswith('win'):
             return self._win32_check_running_pid(pid)
 
         try:
@@ -274,7 +275,7 @@
             return False
 
     def running_pids(self, process_name_filter=None):
-        if sys.platform == "win32":
+        if sys.platform.startswith('win'):
             # FIXME: running_pids isn't implemented on native Windows yet...
             return []
 
@@ -349,9 +350,12 @@
     def kill_all(self, process_name):
         """Attempts to kill processes matching process_name.
         Will fail silently if no process are found."""
-        if sys.platform in ("win32", "cygwin"):
+        if sys.platform == 'cygwin' or sys.platform.startswith('win'):
             image_name = self._windows_image_name(process_name)
-            command = ["taskkill.exe", "/f", "/im", image_name]
+            killCommmand = 'taskkill.exe'
+            if sys.platform.startswith('win'):
+                killCommand = os.path.join('C:', os.sep, 'WINDOWS', 'system32', 'taskkill.exe')
+            command = [killCommmand, "/f", "/im", image_name]
             # taskkill will exit 128 if the process is not found.  We should log.
             self.run_command(command, error_handler=self.ignore_error)
             return
@@ -460,7 +464,7 @@
         # 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 sys.version < '3':
+        if sys.platform.startswith('win') and sys.version < '3':
             return 'mbcs'
         # All other platforms use UTF-8.
         # FIXME: Using UTF-8 on Cygwin will confuse Windows-native commands
@@ -477,7 +481,7 @@
         # 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 sys.version < '3':
+        if sys.platform.startswith('win') and sys.version < '3':
             return True
 
         return False
@@ -493,8 +497,27 @@
         # The Windows implementation of Popen cannot handle unicode strings. :(
         return map(self._encode_argument_if_needed, string_args)
 
-    # The only required arugment to popen is named "args", the rest are optional keyword arguments.
+    def _needs_interpreter_check(self, argument):
+        return not argument.endswith(('perl', 'python', 'ruby', 'taskkill.exe', 'git', 'svn'))
+
+    # The only required argument to popen is named "args", the rest are optional keyword arguments.
     def popen(self, args, **kwargs):
+        if sys.platform.startswith('win'):
+            _log.debug("Looking at {0}".format(args))
+            # Must include proper interpreter
+            if self._needs_interpreter_check(args[0]):
+                try:
+                    with open(args[0], 'r') as f:
+                        line = f.readline()
+                        if "perl" in line:
+                            args.insert(0, "perl")
+                        elif "python" in line:
+                            args.insert(0, "python")
+                        elif "ruby" in line:
+                            args.insert(0, "ruby")
+                except IOError:
+                    pass
+
         # FIXME: We should always be stringifying the args, but callers who pass shell=True
         # expect that the exact bytes passed will get passed to the shell (even if they're wrongly encoded).
         # shell=True is wrong for many other reasons, and we should remove this
@@ -509,7 +532,7 @@
         """Runs a list of (cmd_line list, cwd string) tuples in parallel and returns a list of (retcode, stdout, stderr) tuples."""
         assert len(command_lines_and_cwds)
 
-        if sys.platform in ('cygwin', 'win32'):
+        if sys.platform == 'cygwin' or sys.platform.startswith('win'):
             return map(_run_command_thunk, command_lines_and_cwds)
         pool = multiprocessing.Pool(processes=processes)
         results = pool.map(_run_command_thunk, command_lines_and_cwds)

Modified: trunk/Tools/Scripts/webkitpy/common/system/executive_unittest.py (192943 => 192944)


--- trunk/Tools/Scripts/webkitpy/common/system/executive_unittest.py	2015-12-02 12:08:36 UTC (rev 192943)
+++ trunk/Tools/Scripts/webkitpy/common/system/executive_unittest.py	2015-12-02 16:53:12 UTC (rev 192944)
@@ -67,7 +67,7 @@
     """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':
+    if sys.platform.startswith('win'):
         return ['wmic']
     return ['yes']
 
@@ -130,14 +130,14 @@
         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':
+        if sys.platform.startswith('win'):
             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':
+        if sys.platform.startswith('win'):
             unicode_tor_output = encoded_tor.decode(encoding)
         else:
             unicode_tor_output = unicode_tor_input
@@ -170,7 +170,7 @@
         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":
+        if sys.platform.startswith('win'):
             # FIXME: https://bugs.webkit.org/show_bug.cgi?id=54790
             # We seem to get either 0 or 1 here for some reason.
             self.assertIn(process.wait(), (0, 1))
@@ -195,7 +195,7 @@
         if sys.platform == "cygwin":
             expected_exit_code = 0  # os.kill results in exit(0) for this process.
             self.assertEqual(process.wait(), expected_exit_code)
-        elif sys.platform == "win32":
+        elif sys.platform.startswith('win'):
             # FIXME: https://bugs.webkit.org/show_bug.cgi?id=54790
             # We seem to get either 0 or 1 here for some reason.
             self.assertIn(process.wait(), (0, 1))
@@ -226,7 +226,7 @@
         self.assertFalse(executive.check_running_pid(100000))
 
     def serial_test_running_pids(self):
-        if sys.platform in ("win32", "cygwin"):
+        if sys.platform.startswith('win') or sys.platform == "cygwin":
             return  # This function isn't implemented on Windows yet.
 
         executive = Executive()
@@ -236,7 +236,7 @@
     def serial_test_run_in_parallel(self):
         # We run this test serially to avoid overloading the machine and throwing off the timing.
 
-        if sys.platform in ("win32", "cygwin"):
+        if sys.platform.startswith('win') or sys.platform == "cygwin":
             return  # This function isn't implemented properly on windows yet.
         import multiprocessing
 
@@ -257,7 +257,7 @@
 
 
 def main(platform, stdin, stdout, cmd, args):
-    if platform == 'win32' and hasattr(stdout, 'fileno'):
+    if sys.platform.startswith('win') and hasattr(stdout, 'fileno'):
         import msvcrt
         msvcrt.setmode(stdout.fileno(), os.O_BINARY)
     if cmd == '--cat':

Modified: trunk/Tools/Scripts/webkitpy/common/system/file_lock.py (192943 => 192944)


--- trunk/Tools/Scripts/webkitpy/common/system/file_lock.py	2015-12-02 12:08:36 UTC (rev 192943)
+++ trunk/Tools/Scripts/webkitpy/common/system/file_lock.py	2015-12-02 16:53:12 UTC (rev 192944)
@@ -42,7 +42,7 @@
         self._max_wait_time_sec = max_wait_time_sec
 
     def _create_lock(self):
-        if sys.platform == 'win32':
+        if sys.platform.startswith('win'):
             import msvcrt
             msvcrt.locking(self._lock_file_descriptor, msvcrt.LK_NBLCK, 32)
         else:
@@ -50,7 +50,7 @@
             fcntl.flock(self._lock_file_descriptor, fcntl.LOCK_EX | fcntl.LOCK_NB)
 
     def _remove_lock(self):
-        if sys.platform == 'win32':
+        if sys.platform.startswith('win'):
             import msvcrt
             msvcrt.locking(self._lock_file_descriptor, msvcrt.LK_UNLCK, 32)
         else:

Modified: trunk/Tools/Scripts/webkitpy/common/system/filesystem_unittest.py (192943 => 192944)


--- trunk/Tools/Scripts/webkitpy/common/system/filesystem_unittest.py	2015-12-02 12:08:36 UTC (rev 192943)
+++ trunk/Tools/Scripts/webkitpy/common/system/filesystem_unittest.py	2015-12-02 16:53:12 UTC (rev 192944)
@@ -91,7 +91,7 @@
         fs = FileSystem()
         cwd = fs.getcwd()
         newdir = '/'
-        if sys.platform == 'win32':
+        if sys.platform.startswith('win'):
             newdir = 'c:\\'
         fs.chdir(newdir)
         self.assertEqual(fs.getcwd(), newdir)
@@ -100,7 +100,7 @@
     def test_chdir__notexists(self):
         fs = FileSystem()
         newdir = '/dirdoesnotexist'
-        if sys.platform == 'win32':
+        if sys.platform.startswith('win'):
             newdir = 'c:\\dirdoesnotexist'
         self.assertRaises(OSError, fs.chdir, newdir)
 
@@ -164,7 +164,7 @@
     def test_maybe_make_directory__failure(self):
         # FIXME: os.chmod() doesn't work on Windows to set directories
         # as readonly, so we skip this test for now.
-        if sys.platform in ('win32', 'cygwin'):
+        if sys.platform.startswith('win') or sys.platform == 'cygwin':
             return
 
         fs = FileSystem()

Modified: trunk/Tools/Scripts/webkitpy/common/system/path_unittest.py (192943 => 192944)


--- trunk/Tools/Scripts/webkitpy/common/system/path_unittest.py	2015-12-02 12:08:36 UTC (rev 192943)
+++ trunk/Tools/Scripts/webkitpy/common/system/path_unittest.py	2015-12-02 16:53:12 UTC (rev 192944)
@@ -49,7 +49,7 @@
                           'file:///foo/bar.html')
 
     def test_abspath_to_uri_win(self):
-        if sys.platform != 'win32':
+        if not sys.platform.startswith('win'):
             return
         self.assertEqual(path.abspath_to_uri(self.platforminfo(), 'c:\\foo\\bar.html'),
                          'file:///c:/foo/bar.html')

Modified: trunk/Tools/Scripts/webkitpy/common/system/platforminfo.py (192943 => 192944)


--- trunk/Tools/Scripts/webkitpy/common/system/platforminfo.py	2015-12-02 12:08:36 UTC (rev 192943)
+++ trunk/Tools/Scripts/webkitpy/common/system/platforminfo.py	2015-12-02 16:53:12 UTC (rev 192944)
@@ -137,7 +137,7 @@
             return 'mac'
         if sys_platform.startswith('linux'):
             return 'linux'
-        if sys_platform in ('win32', 'cygwin'):
+        if sys_platform.startswith('win') or sys_platform == 'cygwin':
             return 'win'
         if sys_platform.startswith('freebsd'):
             return 'freebsd'

Modified: trunk/Tools/Scripts/webkitpy/common/system/user.py (192943 => 192944)


--- trunk/Tools/Scripts/webkitpy/common/system/user.py	2015-12-02 12:08:36 UTC (rev 192943)
+++ trunk/Tools/Scripts/webkitpy/common/system/user.py	2015-12-02 16:53:12 UTC (rev 192944)
@@ -46,7 +46,7 @@
 try:
     import readline
 except ImportError:
-    if sys.platform != "win32":
+    if not sys.platform.startswith('win32'):
         # There is no readline module for win32, not much to do except cry.
         _log.warn("Unable to import readline.")
 

Modified: trunk/Tools/Scripts/webkitpy/layout_tests/controllers/manager_unittest.py (192943 => 192944)


--- trunk/Tools/Scripts/webkitpy/layout_tests/controllers/manager_unittest.py	2015-12-02 12:08:36 UTC (rev 192943)
+++ trunk/Tools/Scripts/webkitpy/layout_tests/controllers/manager_unittest.py	2015-12-02 16:53:12 UTC (rev 192944)
@@ -78,7 +78,7 @@
         manager = get_manager()
         self.assertTrue(manager.needs_servers(['http/tests/mime']))
 
-        if sys.platform == 'win32':
+        if sys.platform.startswith('win'):
             manager = get_manager()
             self.assertFalse(manager.needs_servers(['fast\\html']))
 

Modified: trunk/Tools/Scripts/webkitpy/layout_tests/servers/apache_http_server.py (192943 => 192944)


--- trunk/Tools/Scripts/webkitpy/layout_tests/servers/apache_http_server.py	2015-12-02 12:08:36 UTC (rev 192943)
+++ trunk/Tools/Scripts/webkitpy/layout_tests/servers/apache_http_server.py	2015-12-02 16:53:12 UTC (rev 192944)
@@ -65,7 +65,7 @@
         if port_obj.host.platform.is_win():
             # Convert to MSDOS file naming:
             precompiledBuildbot = re.compile('^/home/buildbot')
-            precompiledDrive = re.compile('^/cygdrive/c')
+            precompiledDrive = re.compile('^/cygdrive/[cC]')
             output_dir = precompiledBuildbot.sub("C:/cygwin/home/buildbot", output_dir)
             output_dir = precompiledDrive.sub("C:", output_dir)
             test_dir = precompiledBuildbot.sub("C:/cygwin/home/buildbot", test_dir)
@@ -157,7 +157,7 @@
 
         if self._port_obj.host.platform.is_win():
             # Convert to MSDOS file naming:
-            precompiledDrive = re.compile('^/cygdrive/c')
+            precompiledDrive = re.compile('^/cygdrive/[cC]')
             httpd_config_copy = precompiledDrive.sub("C:", httpd_config_copy)
             precompiledBuildbot = re.compile('^/home/buildbot')
             httpd_config_copy = precompiledBuildbot.sub("C:/cygwin/home/buildbot", httpd_config_copy)

Modified: trunk/Tools/Scripts/webkitpy/layout_tests/servers/apache_http_server_unittest.py (192943 => 192944)


--- trunk/Tools/Scripts/webkitpy/layout_tests/servers/apache_http_server_unittest.py	2015-12-02 12:08:36 UTC (rev 192943)
+++ trunk/Tools/Scripts/webkitpy/layout_tests/servers/apache_http_server_unittest.py	2015-12-02 16:53:12 UTC (rev 192944)
@@ -41,7 +41,7 @@
 class TestLayoutTestApacheHttpd(unittest.TestCase):
     def test_start_cmd(self):
         # Fails on win - see https://bugs.webkit.org/show_bug.cgi?id=84726
-        if sys.platform in ('cygwin', 'win32'):
+        if sys.platform.startswith('win') or sys.platform == 'cygwin':
             return
 
         def fake_pid(_):

Modified: trunk/Tools/Scripts/webkitpy/layout_tests/servers/http_server_base.py (192943 => 192944)


--- trunk/Tools/Scripts/webkitpy/layout_tests/servers/http_server_base.py	2015-12-02 12:08:36 UTC (rev 192943)
+++ trunk/Tools/Scripts/webkitpy/layout_tests/servers/http_server_base.py	2015-12-02 16:53:12 UTC (rev 192944)
@@ -208,7 +208,7 @@
             except IOError, e:
                 if e.errno in (errno.EALREADY, errno.EADDRINUSE):
                     raise ServerError('Port %d is already in use.' % port)
-                elif sys.platform == 'win32' and e.errno in (errno.WSAEACCES,):  # pylint: disable=E1101
+                elif sys.platform.startswith('win') and e.errno in (errno.WSAEACCES,):  # pylint: disable=E1101
                     raise ServerError('Port %d is already in use.' % port)
                 else:
                     raise

Modified: trunk/Tools/Scripts/webkitpy/layout_tests/servers/http_server_unittest.py (192943 => 192944)


--- trunk/Tools/Scripts/webkitpy/layout_tests/servers/http_server_unittest.py	2015-12-02 12:08:36 UTC (rev 192943)
+++ trunk/Tools/Scripts/webkitpy/layout_tests/servers/http_server_unittest.py	2015-12-02 16:53:12 UTC (rev 192944)
@@ -39,7 +39,7 @@
 class TestHttpServer(unittest.TestCase):
     def test_start_cmd(self):
         # Fails on win - see https://bugs.webkit.org/show_bug.cgi?id=84726
-        if sys.platform in ('cygwin', 'win32'):
+        if sys.platform.startswith('win') or sys.platform == 'cygwin':
             return
 
         host = MockHost()

Modified: trunk/Tools/Scripts/webkitpy/port/base.py (192943 => 192944)


--- trunk/Tools/Scripts/webkitpy/port/base.py	2015-12-02 12:08:36 UTC (rev 192943)
+++ trunk/Tools/Scripts/webkitpy/port/base.py	2015-12-02 16:53:12 UTC (rev 192944)
@@ -834,7 +834,10 @@
             '_NT_SYMBOL_PATH',
 
             # Windows:
+            'COMSPEC',
             'PATH',
+            'SYSTEMDRIVE',
+            'SYSTEMROOT',
 
             # Most ports (?):
             'WEBKIT_TESTFONTS',
@@ -1104,7 +1107,7 @@
 
     # We pass sys_platform into this method to make it easy to unit test.
     def _apache_config_file_name_for_platform(self, sys_platform):
-        if sys_platform == 'cygwin' or sys_platform == 'win32':
+        if sys_platform == 'cygwin' or sys_platform.startswith('win'):
             return 'apache' + self._apache_version() + '-httpd-win.conf'
         if sys_platform.startswith('linux'):
             if self._is_redhat_based():
@@ -1150,14 +1153,18 @@
             # the options list.
             self.set_option('_cached_root', root_directory)
 
-        if sys.platform in ('cygwin', 'win32'):
+        if sys.platform.startswith('win') or sys.platform == 'cygwin':
             return self._filesystem.join(root_directory, *comps)
 
         return self._filesystem.join(self._filesystem.abspath(root_directory), *comps)
 
     def _path_to_driver(self, configuration=None):
         """Returns the full path to the test driver (DumpRenderTree)."""
-        return self._build_path(self.driver_name())
+        local_driver_path = self._build_path(self.driver_name())
+        if sys.platform.startswith('win'):
+            base = os.path.splitext(local_driver_path)[0]
+            local_driver_path = base + ".exe"
+        return local_driver_path
 
     def _driver_tempdir(self):
         return self._filesystem.mkdtemp(prefix='%s-' % self.driver_name())

Modified: trunk/Tools/Scripts/webkitpy/port/driver.py (192943 => 192944)


--- trunk/Tools/Scripts/webkitpy/port/driver.py	2015-12-02 12:08:36 UTC (rev 192943)
+++ trunk/Tools/Scripts/webkitpy/port/driver.py	2015-12-02 16:53:12 UTC (rev 192944)
@@ -312,15 +312,15 @@
             self._run_post_start_tasks()
 
     def _setup_environ_for_driver(self, environment):
-        environment['DYLD_LIBRARY_PATH'] = self._port._build_path()
-        environment['DYLD_FRAMEWORK_PATH'] = self._port._build_path()
+        environment['DYLD_LIBRARY_PATH'] = str(self._port._build_path())
+        environment['DYLD_FRAMEWORK_PATH'] = str(self._port._build_path())
         # Use an isolated temp directory that can be deleted after testing (especially important on Mac, as
         # CoreMedia disk cache is in the temp directory).
         environment['TMPDIR'] = str(self._driver_tempdir)
-        environment['DIRHELPER_USER_DIR_SUFFIX'] = os.path.basename(str(self._driver_tempdir))
+        environment['DIRHELPER_USER_DIR_SUFFIX'] = str(os.path.basename(str(self._driver_tempdir)))
         # Put certain normally persistent files into the temp directory (e.g. IndexedDB storage).
         environment['DUMPRENDERTREE_TEMP'] = str(self._driver_tempdir)
-        environment['LOCAL_RESOURCE_ROOT'] = self._port.layout_tests_dir()
+        environment['LOCAL_RESOURCE_ROOT'] = str(self._port.layout_tests_dir())
         environment['ASAN_OPTIONS'] = "allocator_may_return_null=1"
         if 'WEBKIT_OUTPUTDIR' in os.environ:
             environment['WEBKIT_OUTPUTDIR'] = os.environ['WEBKIT_OUTPUTDIR']

Modified: trunk/Tools/Scripts/webkitpy/port/driver_unittest.py (192943 => 192944)


--- trunk/Tools/Scripts/webkitpy/port/driver_unittest.py	2015-12-02 12:08:36 UTC (rev 192943)
+++ trunk/Tools/Scripts/webkitpy/port/driver_unittest.py	2015-12-02 16:53:12 UTC (rev 192944)
@@ -38,6 +38,7 @@
 
 from webkitpy.tool.mocktool import MockOptions
 
+import sys
 
 class DriverOutputTest(unittest.TestCase):
     def test_strip_metrics(self):
@@ -178,7 +179,10 @@
         port = TestWebKitPort()
         port._config.build_directory = lambda configuration: '/mock-build'
         driver = Driver(port, 0, pixel_tests=True, no_timeout=True)
-        self.assertEqual(driver.cmd_line(True, []), ['/mock-build/DumpRenderTree', '--no-timeout', '-'])
+        if sys.platform.startswith('win'):
+            self.assertEqual(driver.cmd_line(True, []), ['/mock-build/DumpRenderTree.exe', '--no-timeout', '-'])
+        else:
+            self.assertEqual(driver.cmd_line(True, []), ['/mock-build/DumpRenderTree', '--no-timeout', '-'])
 
     def test_check_for_driver_crash(self):
         port = TestWebKitPort()

Modified: trunk/Tools/Scripts/webkitpy/port/linux_get_crash_log_unittest.py (192943 => 192944)


--- trunk/Tools/Scripts/webkitpy/port/linux_get_crash_log_unittest.py	2015-12-02 12:08:36 UTC (rev 192943)
+++ trunk/Tools/Scripts/webkitpy/port/linux_get_crash_log_unittest.py	2015-12-02 16:53:12 UTC (rev 192944)
@@ -28,6 +28,7 @@
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 import os
+import sys
 import unittest
 
 from webkitpy.port.linux_get_crash_log import GDBCrashLogGenerator
@@ -37,6 +38,9 @@
 class GDBCrashLogGeneratorTest(unittest.TestCase):
 
     def test_generate_crash_log(self):
+        if sys.platform.startswith('win'):
+            return
+
         generator = GDBCrashLogGenerator('DumpRenderTree', 28529, newer_than=None, filesystem=MockFileSystem({'/path/to/coredumps': ''}), path_to_driver=None)
 
         core_directory = os.environ.get('WEBKIT_CORE_DUMPS_DIRECTORY', '/path/to/coredumps')

Modified: trunk/Tools/Scripts/webkitpy/port/port_testcase.py (192943 => 192944)


--- trunk/Tools/Scripts/webkitpy/port/port_testcase.py	2015-12-02 12:08:36 UTC (rev 192943)
+++ trunk/Tools/Scripts/webkitpy/port/port_testcase.py	2015-12-02 16:53:12 UTC (rev 192944)
@@ -475,7 +475,10 @@
     def test_root_option(self):
         port = TestWebKitPort()
         port._options = MockOptions(root='/foo')
-        self.assertEqual(port._path_to_driver(), "/foo/DumpRenderTree")
+        if sys.platform.startswith('win'):
+            self.assertEqual(port._path_to_driver(), "/foo/DumpRenderTree.exe")
+        else:
+            self.assertEqual(port._path_to_driver(), "/foo/DumpRenderTree")
 
     def test_test_expectations(self):
         # Check that we read the expectations file

Modified: trunk/Tools/Scripts/webkitpy/port/server_process.py (192943 => 192944)


--- trunk/Tools/Scripts/webkitpy/port/server_process.py	2015-12-02 12:08:36 UTC (rev 192943)
+++ trunk/Tools/Scripts/webkitpy/port/server_process.py	2015-12-02 16:53:12 UTC (rev 192944)
@@ -37,7 +37,7 @@
 # Note that although win32 python does provide an implementation of
 # the win32 select API, it only works on sockets, and not on the named pipes
 # used by subprocess, so we have to use the native APIs directly.
-if sys.platform == 'win32':
+if sys.platform.startswith('win'):
     import msvcrt
     import win32pipe
     import win32file
@@ -74,7 +74,7 @@
 
         # See comment in imports for why we need the win32 APIs and can't just use select.
         # FIXME: there should be a way to get win32 vs. cygwin from platforminfo.
-        self._use_win32_apis = sys.platform == 'win32'
+        self._use_win32_apis = sys.platform.startswith('win')
 
     def name(self):
         return self._name

Modified: trunk/Tools/Scripts/webkitpy/port/server_process_unittest.py (192943 => 192944)


--- trunk/Tools/Scripts/webkitpy/port/server_process_unittest.py	2015-12-02 12:08:36 UTC (rev 192943)
+++ trunk/Tools/Scripts/webkitpy/port/server_process_unittest.py	2015-12-02 16:53:12 UTC (rev 192944)
@@ -108,7 +108,10 @@
         proc = server_process.ServerProcess(port, 'python', cmd)
         proc.write('')
 
-        self.assertEqual(proc.poll(), None)
+        if sys.platform.startswith('win'):
+            self.assertEqual(proc.poll(), 0)
+        else:
+            self.assertEqual(proc.poll(), None)
         self.assertFalse(proc.has_crashed())
 
         # check that doing a read after an expired deadline returns

Modified: trunk/Tools/Scripts/webkitpy/port/win.py (192943 => 192944)


--- trunk/Tools/Scripts/webkitpy/port/win.py	2015-12-02 12:08:36 UTC (rev 192943)
+++ trunk/Tools/Scripts/webkitpy/port/win.py	2015-12-02 16:53:12 UTC (rev 192944)
@@ -44,6 +44,12 @@
 _log = logging.getLogger(__name__)
 
 
+try:
+    import _winreg
+    import win32com.client
+except ImportError:
+    _log.warn("Not running on native Windows.")
+
 class WinPort(ApplePort):
     port_name = "win"
 
@@ -53,13 +59,30 @@
 
     CRASH_LOG_PREFIX = "CrashLog"
 
-    POST_MORTEM_DEBUGGER_KEY = "/%s/SOFTWARE/Microsoft/Windows NT/CurrentVersion/AeDebug/%s"
+    if sys.platform.startswith('win'):
+        POST_MORTEM_DEBUGGER_KEY = r'SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug'
+        WOW64_POST_MORTEM_DEBUGGER_KEY = r'SOFTWARE\Wow6432Node\Microsoft\Windows NT\CurrentVersion\AeDebug'
+        WINDOWS_ERROR_REPORTING_KEY = r'SOFTWARE\Microsoft\Windows\Windows Error Reporting'
+        WOW64_WINDOWS_ERROR_REPORTING_KEY = r'SOFTWARE\Wow6432Node\Microsoft\Windows\Windows Error Reporting'
+        _HKLM = _winreg.HKEY_LOCAL_MACHINE
+        _HKCU = _winreg.HKEY_CURRENT_USER
+        _REG_DWORD = _winreg.REG_DWORD
+        _REG_SZ = _winreg.REG_SZ
+    else:
+        POST_MORTEM_DEBUGGER_KEY = "/%s/SOFTWARE/Microsoft/Windows NT/CurrentVersion/AeDebug/%s"
+        WOW64_POST_MORTEM_DEBUGGER_KEY = "/%s/SOFTWARE/Wow6432Node/Microsoft/Windows NT/CurrentVersion/AeDebug/%s"
+        WINDOWS_ERROR_REPORTING_KEY = "/%s/SOFTWARE/Microsoft/Windows/Windows Error Reporting/%s"
+        WOW64_WINDOWS_ERROR_REPORTING_KEY = "/%s/SOFTWARE/Wow6432Node/Microsoft/Windows/Windows Error Reporting/%s"
+        _HKLM = "HKLM"
+        _HKCU = "HKCU"
+        _REG_DWORD = "-d"
+        _REG_SZ = "-s"
 
-    WINDOWS_ERROR_REPORTING_KEY = "/%s/SOFTWARE/Microsoft/Windows/Windows Error Reporting/%s"
-
     previous_debugger_values = {}
+    previous_wow64_debugger_values = {}
 
     previous_error_reporting_values = {}
+    previous_wow64_error_reporting_values = {}
 
     def do_text_results_differ(self, expected_text, actual_text):
         # Sanity was restored in WK2, so we don't need this hack there.
@@ -163,20 +186,25 @@
     def _ntsd_location(self):
         if 'PROGRAMFILES' not in os.environ:
             return None
+        possible_paths = [self._filesystem.join(os.environ['PROGRAMFILES'], "Windows Kits", "10", "Debuggers", "x64", "ntsd.exe"),
+            self._filesystem.join(os.environ['PROGRAMFILES'], "Windows Kits", "8.1", "Debuggers", "x64", "ntsd.exe"),
+            self._filesystem.join(os.environ['PROGRAMFILES'], "Windows Kits", "8.0", "Debuggers", "x64", "ntsd.exe")]
         if self.get_option('architecture') == 'x86_64':
-            possible_paths = [self._filesystem.join(os.environ['PROGRAMFILES'], "Windows Kits", "10", "Debuggers", "x64", "ntsd.exe"),
-                self._filesystem.join(os.environ['PROGRAMFILES'], "Windows Kits", "8.1", "Debuggers", "x64", "ntsd.exe"),
-                self._filesystem.join(os.environ['PROGRAMFILES'], "Windows Kits", "8.0", "Debuggers", "x64", "ntsd.exe")]
+            possible_paths.append(self._filesystem.join("{0} (x86)".format(os.environ['PROGRAMFILES']), "Windows Kits", "10", "Debuggers", "x64", "ntsd.exe"))
+            possible_paths.append(self._filesystem.join("{0} (x86)".format(os.environ['PROGRAMFILES']), "Windows Kits", "8.1", "Debuggers", "x64", "ntsd.exe"))
+            possible_paths.append(self._filesystem.join("{0} (x86)".format(os.environ['PROGRAMFILES']), "Windows Kits", "8.0", "Debuggers", "x64", "ntsd.exe"))
+            possible_paths.append(self._filesystem.join("{0} (x86)".format(os.environ['PROGRAMFILES']), "Debugging Tools for Windows (x64)", "ntsd.exe"))
         else:
-            possible_paths = [self._filesystem.join(os.environ['PROGRAMFILES'], "Windows Kits", "10", "Debuggers", "x86", "ntsd.exe"),
-                self._filesystem.join(os.environ['PROGRAMFILES'], "Windows Kits", "8.1", "Debuggers", "x86", "ntsd.exe"),
-                self._filesystem.join(os.environ['PROGRAMFILES'], "Windows Kits", "8.0", "Debuggers", "x86", "ntsd.exe"),
-                self._filesystem.join(os.environ['PROGRAMFILES'], "Debugging Tools for Windows (x86)", "ntsd.exe")]
+            possible_paths.append(self._filesystem.join(os.environ['PROGRAMFILES'], "Debugging Tools for Windows (x86)", "ntsd.exe"))
         possible_paths.append(self._filesystem.join(os.environ['SYSTEMROOT'], "system32", "ntsd.exe"))
         if 'ProgramW6432' in os.environ:
+            possible_paths.append(self._filesystem.join(os.environ['ProgramW6432'], "Windows Kits", "10", "Debuggers", "x64", "ntsd.exe"))
+            possible_paths.append(self._filesystem.join(os.environ['ProgramW6432'], "Windows Kits", "8.1", "Debuggers", "x64", "ntsd.exe"))
+            possible_paths.append(self._filesystem.join(os.environ['ProgramW6432'], "Windows Kits", "8.0", "Debuggers", "x64", "ntsd.exe"))
             possible_paths.append(self._filesystem.join(os.environ['ProgramW6432'], "Debugging Tools for Windows (x64)", "ntsd.exe"))
         for path in possible_paths:
             expanded_path = self._filesystem.expanduser(path)
+            _log.debug("Considering '%s'" % expanded_path)
             if self._filesystem.exists(expanded_path):
                 _log.debug("Using ntsd located in '%s'" % path)
                 return expanded_path
@@ -193,42 +221,79 @@
         self._filesystem.write_text_file(command_file, commands)
         return command_file
 
-    def read_registry_string(self, reg_path, arch, root, key):
-        registry_key = reg_path % (root, key)
-        read_registry_command = ["regtool", arch, "get", registry_key]
-        value = self._executive.run_command(read_registry_command, error_handler=Executive.ignore_error)
-        return value.rstrip()
+    def read_registry_value(self, reg_path, arch, root, key):
+        if sys.platform.startswith('win'):
+            _log.debug("Trying to read %s\\%s" % (reg_path, key))
+            try:
+                registry_key = _winreg.OpenKey(root, reg_path)
+                value = _winreg.QueryValueEx(registry_key, key)
+                _winreg.CloseKey(registry_key)
+            except WindowsError as ex:
+                _log.debug("Unable to read %s\\%s: %s" % (reg_path, key, str(ex)))
+                return ['', self._REG_SZ]
+        else:
+            registry_key = reg_path % (root, key)
+            _log.debug("Reading %s" % (registry_key))
+            read_registry_command = ["regtool", arch, "get", registry_key]
+            int_value = self._executive.run_command(read_registry_command, error_handler=Executive.ignore_error)
+            # regtool doesn't return the type of the entry, so need this ugly hack:
+            if reg_path in (self.WINDOWS_ERROR_REPORTING_KEY, self.WOW64_WINDOWS_ERROR_REPORTING_KEY):
+                _log.debug("I got {0}".format(int_value))
+                try:
+                    value = [int(int_value), self._REG_DWORD]
+                except:
+                    value = [0, self._REG_DWORD]
+            else:
+                value = [int_value.rstrip(), self._REG_SZ]
 
+        _log.debug("I got back ({0}) of type ({1})".format(value[0], value[1]))
+        return value
+
     def write_registry_value(self, reg_path, arch, root, key, regType, value):
-        registry_key = reg_path % (root, key)
+        if sys.platform.startswith('win'):
+            _log.debug("Trying to write %s\\%s = %s" % (reg_path, key, value))
+            try:
+                registry_key = _winreg.OpenKey(root, reg_path, 0, _winreg.KEY_WRITE)
+            except WindowsError:
+                try:
+                    _log.debug("Key doesn't exist -- must create it.")
+                    registry_key = _winreg.CreateKeyEx(root, reg_path, 0, _winreg.KEY_WRITE)
+                except WindowsError as ex:
+                    _log.error("Error setting (%s) %s\key: %s to value: %s.  Error=%s." % (arch, root, key, value, str(ex)))
+                    _log.error("You many need to adjust permissions on the %s\\%s key." % (reg_path, key))
+                    return False
 
-        _log.debug("Writing to %s" % registry_key)
+            _log.debug("Writing {0} of type {1} to {2}\\{3}".format(value, regType, registry_key, key))
+            _winreg.SetValueEx(registry_key, key, 0, regType, value)
+            _winreg.CloseKey(registry_key)
+        else:
+            registry_key = reg_path % (root, key)
+            _log.debug("Writing to %s" % registry_key)
 
-        set_reg_value_command = ["regtool", arch, "set", regType, str(registry_key), str(value)]
-        rc = self._executive.run_command(set_reg_value_command, return_exit_code=True)
-        if rc == 2:
-            add_reg_value_command = ["regtool", arch, "add", regType, str(registry_key)]
-            rc = self._executive.run_command(add_reg_value_command, return_exit_code=True)
-            if rc == 0:
-                rc = self._executive.run_command(set_reg_value_command, return_exit_code=True)
-        if rc:
-            _log.warn("Error setting (%s) %s\key: %s to value: %s.  Error=%s." % (arch, root, key, value, str(rc)))
-            _log.warn("You many need to adjust permissions on the %s key." % registry_key)
-            return False
+            set_reg_value_command = ["regtool", arch, "set", regType, str(registry_key), str(value)]
+            rc = self._executive.run_command(set_reg_value_command, return_exit_code=True)
+            if rc == 2:
+                add_reg_value_command = ["regtool", arch, "add", regType, str(registry_key)]
+                rc = self._executive.run_command(add_reg_value_command, return_exit_code=True)
+                if rc == 0:
+                    rc = self._executive.run_command(set_reg_value_command, return_exit_code=True)
+            if rc:
+                _log.warn("Error setting (%s) %s\key: %s to value: %s.  Error=%s." % (arch, root, key, value, str(rc)))
+                _log.warn("You many need to adjust permissions on the %s key." % registry_key)
+                return False
 
         # On Windows Vista/7 with UAC enabled, regtool will fail to modify the registry, but will still
         # return a successful exit code. So we double-check here that the value we tried to write to the
         # registry was really written.
-        if self.read_registry_string(reg_path, arch, root, key) != str(value):
-            _log.warn("Regtool reported success, but value of key %s did not change." % key)
-            _log.warn("You many need to adjust permissions on the %s key." % registry_key)
+        check_value = self.read_registry_value(reg_path, arch, root, key)
+        if check_value[0] != value or check_value[1] != regType:
+            _log.warn("Reg update reported success, but value of key %s did not change." % key)
+            _log.warn("Wanted to set it to ({0}, {1}), but got {2})".format(value, regType, check_value))
+            _log.warn("You many need to adjust permissions on the %s\\%s key." % (reg_path, key))
             return False
 
         return True
 
-    def write_registry_string(self, reg_path, arch, root, key, value):
-        return self.write_registry_value(reg_path, arch, root, key, "-s", value)
-
     def setup_crash_log_saving(self):
         if '_NT_SYMBOL_PATH' not in os.environ:
             _log.warning("The _NT_SYMBOL_PATH environment variable is not set. Using Microsoft Symbol Server.")
@@ -246,27 +311,35 @@
         if not command_file:
             return None
         debugger_options = '"{0}" -p %ld -e %ld -g -noio -lines -cf "{1}"'.format(cygpath(ntsd_path), cygpath(command_file))
-        registry_settings = {'Debugger': debugger_options, 'Auto': "1"}
-        for key in registry_settings:
+        registry_settings = {'Debugger': [debugger_options, self._REG_SZ], 'Auto': ["1", self._REG_SZ]}
+        for key, value in registry_settings.iteritems():
             for arch in ["--wow32", "--wow64"]:
-                self.previous_debugger_values[(arch, "HKLM", key)] = self.read_registry_string(self.POST_MORTEM_DEBUGGER_KEY, arch, "HKLM", key)
-                self.write_registry_string(self.POST_MORTEM_DEBUGGER_KEY, arch, "HKLM", key, registry_settings[key])
+                self.previous_debugger_values[(arch, self._HKLM, key)] = self.read_registry_value(self.POST_MORTEM_DEBUGGER_KEY, arch, self._HKLM, key)
+                self.previous_wow64_debugger_values[(arch, self._HKLM, key)] = self.read_registry_value(self.WOW64_POST_MORTEM_DEBUGGER_KEY, arch, self._HKLM, key)
+                self.write_registry_value(self.POST_MORTEM_DEBUGGER_KEY, arch, self._HKLM, key, value[1], value[0])
+                self.write_registry_value(self.WOW64_POST_MORTEM_DEBUGGER_KEY, arch, self._HKLM, key, value[1], value[0])
 
     def restore_crash_log_saving(self):
-        for key in self.previous_debugger_values:
-            self.write_registry_string(self.POST_MORTEM_DEBUGGER_KEY, key[0], key[1], key[2], self.previous_debugger_values[key])
+        for key, value in self.previous_debugger_values.iteritems():
+            self.write_registry_value(self.POST_MORTEM_DEBUGGER_KEY, key[0], key[1], key[2], value[1], value[0])
+        for key, value in self.previous_wow64_debugger_values.iteritems():
+            self.write_registry_value(self.WOW64_POST_MORTEM_DEBUGGER_KEY, key[0], key[1], key[2], value[1], value[0])
 
     def prevent_error_dialogs(self):
-        registry_settings = {'DontShowUI': 1, 'Disabled': 1}
-        for key in registry_settings:
-            for root in ["HKLM", "HKCU"]:
+        registry_settings = {'DontShowUI': [1, self._REG_DWORD], 'Disabled': [1, self._REG_DWORD]}
+        for key, value in registry_settings.iteritems():
+            for root in [self._HKLM, self._HKCU]:
                 for arch in ["--wow32", "--wow64"]:
-                    self.previous_error_reporting_values[(arch, root, key)] = self.read_registry_string(self.WINDOWS_ERROR_REPORTING_KEY, arch, root, key)
-                    self.write_registry_value(self.WINDOWS_ERROR_REPORTING_KEY, arch, root, key, "-d", registry_settings[key])
+                    self.previous_error_reporting_values[(arch, root, key)] = self.read_registry_value(self.WINDOWS_ERROR_REPORTING_KEY, arch, root, key)
+                    self.previous_wow64_error_reporting_values[(arch, root, key)] = self.read_registry_value(self.WOW64_WINDOWS_ERROR_REPORTING_KEY, arch, root, key)
+                    self.write_registry_value(self.WINDOWS_ERROR_REPORTING_KEY, arch, root, key, value[1], value[0])
+                    self.write_registry_value(self.WOW64_WINDOWS_ERROR_REPORTING_KEY, arch, root, key, value[1], value[0])
 
     def allow_error_dialogs(self):
-        for key in self.previous_error_reporting_values:
-            self.write_registry_value(self.WINDOWS_ERROR_REPORTING_KEY, key[0], key[1], key[2], "-d", self.previous_error_reporting_values[key])
+        for key, value in self.previous_error_reporting_values.iteritems():
+            self.write_registry_value(self.WINDOWS_ERROR_REPORTING_KEY, key[0], key[1], key[2], value[1], value[0])
+        for key, value in self.previous_wow64_error_reporting_values.iteritems():
+            self.write_registry_value(self.WOW64_WINDOWS_ERROR_REPORTING_KEY, key[0], key[1], key[2], value[1], value[0])
 
     def delete_sem_locks(self):
         os.system("rm -rf /dev/shm/sem.*")
@@ -331,22 +404,34 @@
 
     def find_system_pid(self, name, pid):
         system_pid = int(pid)
-        # Windows and Cygwin PIDs are not the same.  We need to find the Windows
-        # PID for our Cygwin process so we can match it later to any crash
-        # files we end up creating (which will be tagged with the Windows PID)
-        ps_process = self._executive.run_command(['ps', '-e'], error_handler=Executive.ignore_error)
-        for line in ps_process.splitlines():
-            tokens = line.strip().split()
-            try:
-                cpid, ppid, pgid, winpid, tty, uid, stime, process_name = tokens
-                if process_name.endswith(name):
-                    self._executive.pid_to_system_pid[int(cpid)] = int(winpid)
-                    if int(pid) == int(cpid):
-                        system_pid = int(winpid)
-                    break
-            except ValueError, e:
-                pass
 
+        if sys.platform == "cygwin":
+            # Windows and Cygwin PIDs are not the same.  We need to find the Windows
+            # PID for our Cygwin process so we can match it later to any crash
+            # files we end up creating (which will be tagged with the Windows PID)
+            ps_process = self._executive.run_command(['ps', '-e'], error_handler=Executive.ignore_error)
+            for line in ps_process.splitlines():
+                tokens = line.strip().split()
+                try:
+                    cpid, ppid, pgid, winpid, tty, uid, stime, process_name = tokens
+                    if process_name.endswith(name):
+                        self._executive.pid_to_system_pid[int(cpid)] = int(winpid)
+                        if int(pid) == int(cpid):
+                            system_pid = int(winpid)
+                        break
+                except ValueError, e:
+                    pass
+        else:
+            wmi = win32com.client.GetObject('winmgmts:')
+            _log.debug('Querying WMI with "%{0}%"'.format(name))
+            procs = wmi.ExecQuery('Select * from win32_process where name like "%{0}%"'.format(name))
+            for proc in procs:
+                self._executive.pid_to_system_pid[int(proc.ProcessId)] = int(proc.ProcessId)
+                _log.debug("I see {0}: {1}".format(proc.Name, proc.ProcessId))
+                if int(pid) == int(proc.ProcessId):
+                    system_pid = int(proc.ProcessId)
+                break
+
         return system_pid
 
 

Modified: trunk/Tools/Scripts/webkitpy/test/main.py (192943 => 192944)


--- trunk/Tools/Scripts/webkitpy/test/main.py	2015-12-02 12:08:36 UTC (rev 192943)
+++ trunk/Tools/Scripts/webkitpy/test/main.py	2015-12-02 16:53:12 UTC (rev 192944)
@@ -52,11 +52,11 @@
     tester.add_tree(os.path.join(webkit_root, 'Tools', 'Scripts'), 'webkitpy')
 
     # There is no WebKit2 on Windows, so we don't need to run WebKit2 unittests on it.
-    if not sys.platform in ('cygwin', 'win32'):
+    if not (sys.platform.startswith('win') or sys.platform == 'cygwin'):
         tester.add_tree(os.path.join(webkit_root, 'Source', 'WebKit2', 'Scripts'), 'webkit2')
 
     tester.skip(('webkitpy.common.checkout.scm.scm_unittest',), 'are really, really, slow', 31818)
-    if sys.platform == 'win32':
+    if sys.platform.startswith('win'):
         tester.skip(('webkitpy.common.checkout', 'webkitpy.common.config', 'webkitpy.tool'), 'fail horribly on win32', 54526)
 
     # This only needs to run on Unix, so don't worry about win32 for now.
@@ -106,7 +106,7 @@
                           help='generate code coverage info (requires http://pypi.python.org/pypi/coverage)')
         parser.add_option('-i', '--integration-tests', action='', default=False,
                           help='run integration tests as well as unit tests'),
-        parser.add_option('-j', '--child-processes', action='', type='int', default=(1 if sys.platform == 'win32' else multiprocessing.cpu_count()),
+        parser.add_option('-j', '--child-processes', action='', type='int', default=(1 if sys.platform.startswith('win') else multiprocessing.cpu_count()),
                           help='number of tests to run in parallel (default=%default)')
         parser.add_option('-p', '--pass-through', action='', default=False,
                           help='be debugger friendly by passing captured output through to the system')
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to