diff options
Diffstat (limited to 'Tools/Scripts/webkitpy/port/win.py')
-rw-r--r-- | Tools/Scripts/webkitpy/port/win.py | 284 |
1 files changed, 0 insertions, 284 deletions
diff --git a/Tools/Scripts/webkitpy/port/win.py b/Tools/Scripts/webkitpy/port/win.py deleted file mode 100644 index 18175d60b..000000000 --- a/Tools/Scripts/webkitpy/port/win.py +++ /dev/null @@ -1,284 +0,0 @@ -# Copyright (C) 2010 Google Inc. All rights reserved. -# Copyright (C) 2013 Apple Inc. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the Google name nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -import atexit -import os -import logging -import re -import sys -import time - -from webkitpy.common.system.crashlogs import CrashLogs -from webkitpy.common.system.systemhost import SystemHost -from webkitpy.common.system.executive import ScriptError, Executive -from webkitpy.common.system.path import abspath_to_uri, cygpath -from webkitpy.port.apple import ApplePort - - -_log = logging.getLogger(__name__) - - -class WinPort(ApplePort): - port_name = "win" - - VERSION_FALLBACK_ORDER = ["win-xp", "win-vista", "win-7sp0", "win"] - - ARCHITECTURES = ['x86'] - - CRASH_LOG_PREFIX = "CrashLog" - - POST_MORTEM_DEBUGGER_KEY = "/HKLM/SOFTWARE/Microsoft/Windows NT/CurrentVersion/AeDebug/%s" - - previous_debugger_values = {} - - def do_text_results_differ(self, expected_text, actual_text): - # Sanity was restored in WK2, so we don't need this hack there. - if self.get_option('webkit_test_runner'): - return ApplePort.do_text_results_differ(self, expected_text, actual_text) - - # This is a hack (which dates back to ORWT). - # Windows does not have an EDITING DELEGATE, so we strip any EDITING DELEGATE - # messages to make more of the tests pass. - # It's possible more of the ports might want this and this could move down into WebKitPort. - delegate_regexp = re.compile("^EDITING DELEGATE: .*?\n", re.MULTILINE) - expected_text = delegate_regexp.sub("", expected_text) - actual_text = delegate_regexp.sub("", actual_text) - return expected_text != actual_text - - def default_baseline_search_path(self): - name = self._name.replace('-wk2', '') - if name.endswith(self.FUTURE_VERSION): - fallback_names = [self.port_name] - else: - fallback_names = self.VERSION_FALLBACK_ORDER[self.VERSION_FALLBACK_ORDER.index(name):-1] + [self.port_name] - # FIXME: The AppleWin port falls back to AppleMac for some results. Eventually we'll have a shared 'apple' port. - if self.get_option('webkit_test_runner'): - fallback_names.insert(0, 'win-wk2') - fallback_names.append('mac-wk2') - # Note we do not add 'wk2' here, even though it's included in _skipped_search_paths(). - # FIXME: Perhaps we should get this list from MacPort? - fallback_names.extend(['mac-lion', 'mac']) - return map(self._webkit_baseline_path, fallback_names) - - def operating_system(self): - return 'win' - - def show_results_html_file(self, results_filename): - self._run_script('run-safari', [abspath_to_uri(SystemHost().platform, results_filename)]) - - # FIXME: webkitperl/httpd.pm installs /usr/lib/apache/libphp4.dll on cycwin automatically - # as part of running old-run-webkit-tests. That's bad design, but we may need some similar hack. - # We might use setup_environ_for_server for such a hack (or modify apache_http_server.py). - - def _runtime_feature_list(self): - supported_features_command = [self._path_to_driver(), '--print-supported-features'] - try: - output = self._executive.run_command(supported_features_command, error_handler=Executive.ignore_error) - except OSError, e: - _log.warn("Exception running driver: %s, %s. Driver must be built before calling WebKitPort.test_expectations()." % (supported_features_command, e)) - return None - - # Note: win/DumpRenderTree.cpp does not print a leading space before the features_string. - match_object = re.match("SupportedFeatures:\s*(?P<features_string>.*)\s*", output) - if not match_object: - return None - return match_object.group('features_string').split(' ') - - # Note: These are based on the stock Cygwin locations for these files. - def _uses_apache(self): - return False - - def _path_to_lighttpd(self): - return "/usr/sbin/lighttpd" - - def _path_to_lighttpd_modules(self): - return "/usr/lib/lighttpd" - - def _path_to_lighttpd_php(self): - return "/usr/bin/php-cgi" - - def _driver_tempdir_for_environment(self): - return cygpath(self._driver_tempdir()) - - def test_search_path(self): - test_fallback_names = [path for path in self.baseline_search_path() if not path.startswith(self._webkit_baseline_path('mac'))] - return map(self._webkit_baseline_path, test_fallback_names) - - def _ntsd_location(self): - possible_paths = [self._filesystem.join(os.environ['PROGRAMFILES'], "Windows Kits", "8.0", "Debuggers", "x86", "ntsd.exe"), - self._filesystem.join(os.environ['PROGRAMFILES'], "Windows Kits", "8.0", "Debuggers", "x64", "ntsd.exe"), - self._filesystem.join(os.environ['PROGRAMFILES'], "Debugging Tools for Windows (x86)", "ntsd.exe"), - self._filesystem.join(os.environ['ProgramW6432'], "Debugging Tools for Windows (x64)", "ntsd.exe"), - self._filesystem.join(os.environ['SYSTEMROOT'], "system32", "ntsd.exe")] - for path in possible_paths: - expanded_path = self._filesystem.expanduser(path) - if self._filesystem.exists(expanded_path): - _log.debug("Using ntsd located in '%s'" % path) - return expanded_path - return None - - def create_debugger_command_file(self): - debugger_temp_directory = str(self._filesystem.mkdtemp()) - command_file = self._filesystem.join(debugger_temp_directory, "debugger-commands.txt") - commands = ''.join(['.logopen /t "%s\\%s.txt"\n' % (cygpath(self.results_directory()), self.CRASH_LOG_PREFIX), - '.srcpath "%s"\n' % cygpath(self._webkit_finder.webkit_base()), - '!analyze -vv\n', - '~*kpn\n', - 'q\n']) - self._filesystem.write_text_file(command_file, commands) - return command_file - - def read_registry_string(self, key): - registry_key = self.POST_MORTEM_DEBUGGER_KEY % key - read_registry_command = ["regtool", "--wow32", "get", registry_key] - value = self._executive.run_command(read_registry_command, error_handler=Executive.ignore_error) - return value.rstrip() - - def write_registry_string(self, key, value): - registry_key = self.POST_MORTEM_DEBUGGER_KEY % key - set_reg_value_command = ["regtool", "--wow32", "set", "-s", 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", "--wow32", "add", "-s", 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 key: %s to value %s. Error=%ld." % (key, value, rc)) - 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(key) != value: - _log.warn("Regtool reported success, but value of key %s did not change." % key) - return False - - return True - - 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. Crash logs will not be saved.") - return None - ntsd_path = self._ntsd_location() - if not ntsd_path: - _log.warning("Can't find ntsd.exe. Crash logs will not be saved.") - return None - # If we used -c (instead of -cf) we could pass the commands directly on the command line. But - # when the commands include multiple quoted paths (e.g., for .logopen and .srcpath), Windows - # fails to invoke the post-mortem debugger at all (perhaps due to a bug in Windows's command - # line parsing). So we save the commands to a file instead and tell the debugger to execute them - # using -cf. - command_file = self.create_debugger_command_file() - 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: - self.previous_debugger_values[key] = self.read_registry_string(key) - self.write_registry_string(key, registry_settings[key]) - - def restore_crash_log_saving(self): - for key in self.previous_debugger_values: - self.write_registry_string(key, self.previous_debugger_values[key]) - - def setup_test_run(self): - atexit.register(self.restore_crash_log_saving) - self.setup_crash_log_saving() - super(WinPort, self).setup_test_run() - - def clean_up_test_run(self): - self.restore_crash_log_saving() - super(WinPort, self).clean_up_test_run() - - def _get_crash_log(self, name, pid, stdout, stderr, newer_than, time_fn=None, sleep_fn=None, wait_for_log=True): - # Note that we do slow-spin here and wait, since it appears the time - # ReportCrash takes to actually write and flush the file varies when there are - # lots of simultaneous crashes going on. - # FIXME: Should most of this be moved into CrashLogs()? - time_fn = time_fn or time.time - sleep_fn = sleep_fn or time.sleep - crash_log = '' - crash_logs = CrashLogs(self.host, self.results_directory()) - now = time_fn() - # FIXME: delete this after we're sure this code is working ... - _log.debug('looking for crash log for %s:%s' % (name, str(pid))) - deadline = now + 5 * int(self.get_option('child_processes', 1)) - while not crash_log and now <= deadline: - # If the system_pid hasn't been determined yet, just try with the passed in pid. We'll be checking again later - system_pid = self._executive.pid_to_system_pid.get(pid) - if system_pid == None: - break # We haven't mapped cygwin pid->win pid yet - crash_log = crash_logs.find_newest_log(name, system_pid, include_errors=True, newer_than=newer_than) - if not wait_for_log: - break - if not crash_log or not [line for line in crash_log.splitlines() if line.startswith('quit:')]: - sleep_fn(0.1) - now = time_fn() - - if not crash_log: - return (stderr, None) - return (stderr, crash_log) - - def look_for_new_crash_logs(self, crashed_processes, start_time): - """Since crash logs can take a long time to be written out if the system is - under stress do a second pass at the end of the test run. - - crashes: test_name -> pid, process_name tuple of crashed process - start_time: time the tests started at. We're looking for crash - logs after that time. - """ - crash_logs = {} - for (test_name, process_name, pid) in crashed_processes: - # Passing None for output. This is a second pass after the test finished so - # if the output had any logging we would have already collected it. - crash_log = self._get_crash_log(process_name, pid, None, None, start_time, wait_for_log=False)[1] - if crash_log: - crash_logs[test_name] = crash_log - return crash_logs - - 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 - - return system_pid |