Changeset 206934 in webkit
- Timestamp:
- Oct 7, 2016 2:06:43 PM (8 years ago)
- Location:
- trunk/Tools
- Files:
-
- 2 added
- 10 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/Tools/ChangeLog
r206929 r206934 1 2016-10-07 Jonathan Bedard <jbedard@apple.com> 2 3 Move functionality common to Darwin ports into a base class 4 https://bugs.webkit.org/show_bug.cgi?id=160709 5 6 Reviewed by Darin Adler. 7 8 * Scripts/webkitpy/port/apple.py: 9 (ApplePort.determine_full_port_name): Specific iOS port check. 10 (ApplePort.__init__): Move leak detector to DarwinPort. 11 (ApplePort._make_leak_detector): Moved to DarwinPort. 12 (ApplePort.supports_per_test_timeout): Moved to Port. 13 (ApplePort.check_for_leaks): Moved to DarwinPort. 14 (ApplePort.print_leaks_summary): Moved to DarwinPort. 15 (ApplePort._path_to_webcore_library): Moved to DarwinPort. 16 (ApplePort.show_results_html_file): Moved to DarwinPort. 17 (ApplePort._merge_crash_logs): Moved to DarwinPort. 18 (ApplePort._look_for_all_crash_logs_in_log_dir): Moved to DarwinPort. 19 (ApplePort._get_crash_log): Moved to DarwinPort. 20 (ApplePort.look_for_new_crash_logs): Moved to DarwinPort. 21 (ApplePort.sample_process): Moved to DarwinPort. 22 (ApplePort.sample_file_path): Moved to DarwinPort. 23 (ApplePort.look_for_new_samples): Moved to DarwinPort. 24 * Scripts/webkitpy/port/base.py: 25 (Port.supports_per_test_timeout): Return true for all ports. 26 * Scripts/webkitpy/port/darwin.py: Added. 27 (DarwinPort): Shared iOS and Mac functions. 28 * Scripts/webkitpy/port/darwin_testcase.py: Added. 29 (DarwinTest): Shared iOS and Mac testing. 30 * Scripts/webkitpy/port/efl.py: 31 (EflPort): 32 (EflPort.supports_per_test_timeout): Moved to Port. 33 * Scripts/webkitpy/port/gtk.py: 34 (GtkPort._driver_class): 35 (GtkPort): 36 (GtkPort.supports_per_test_timeout): Moved to Port. 37 * Scripts/webkitpy/port/ios.py: 38 (IOSPort): 39 (IOSPort.operating_system): 40 (IOSSimulatorPort): 41 (IOSSimulatorPort.__init__): Inherits from DarwinPort. 42 (IOSSimulatorPort._port_specific_expectations_files): Moved to DarwinPort. 43 (IOSSimulatorPort._get_crash_log): Deleted. 44 (IOSSimulatorPort.xcrun_find): Deleted. 45 * Scripts/webkitpy/port/ios_unittest.py: Added. 46 (iosTest): Unit tests for the iOS port. 47 * Scripts/webkitpy/port/mac.py: 48 (MacPort): 49 (MacPort.__init__): Inherits from DarwinPort. 50 (MacPort._port_specific_expectations_files): Moved to DarwinPort. 51 (MacPort.make_command): Moved to DarwinPort. 52 (MacPort._get_crash_log): Moved to DarwinPort. 53 (MacPort.nm_command): Moved to DarwinPort. 54 * Scripts/webkitpy/port/mac_unittest.py: 55 (MacTest): 56 (MacTest.test_sdk_name): Added test. 57 (MacTest.test_xcrun): Added test. 58 (MacTest.assert_skipped_file_search_paths): Moved to DarwinTest. 59 (MacTest.test_default_timeout_ms): Moved to DarwinTest. 60 (MacTest.assert_name): Moved to DarwinTest. 61 (MacTest.test_helper_starts): Moved to DarwinTest. 62 (MacTest.test_helper_fails_to_start): Moved to DarwinTest. 63 (MacTest.test_helper_fails_to_stop): Moved to DarwinTest. 64 (MacTest.test_spindump): Moved to DarwinTest. 65 (MacTest.test_sample_process): Moved to DarwinTest. 66 (MacTest.test_sample_process_exception): Moved to DarwinTest. 67 * Scripts/webkitpy/port/port_testcase.py: 68 (PortTestCase): 69 (PortTestCase.test_diff_image): Added is_simulator flag. 70 (PortTestCase.test_diff_image): Skip test if on a simulator. 71 (PortTestCase.test_diff_image_crashed): Skip test if on a simulator. 72 * Scripts/webkitpy/port/win.py: 73 (WinPort): 74 (WinPort.look_for_new_samples): Used default, ApplePort no longer implements. 75 (WinPort.sample_process): Ditto. 76 (WinPort._make_leak_detector): Ditto. 77 (WinPort.check_for_leaks): Ditto. 78 (WinPort.print_leaks_summary): Ditto. 79 (WinPort._path_to_webcore_library): Ditto. 80 1 81 2016-10-07 Anders Carlsson <andersca@apple.com> 2 82 -
trunk/Tools/Scripts/webkitpy/port/apple.py
r205351 r206934 34 34 from webkitpy.port.base import Port 35 35 from webkitpy.layout_tests.models.test_configuration import TestConfiguration 36 from webkitpy.port.leakdetector import LeakDetector37 36 38 37 … … 62 61 options = options or {} 63 62 if port_name in (cls.port_name, cls.port_name + '-wk2'): 63 64 # Since IOS simulator run on mac, they need a special check 65 if host.platform.os_name == 'mac' and 'ios-simulator' in port_name: 66 return port_name 67 64 68 # If the port_name matches the (badly named) cls.port_name, that 65 69 # means that they passed 'mac' or 'win' and didn't specify a version. … … 90 94 self._version = self._strip_port_name_prefix(port_name) 91 95 92 self._leak_detector = self._make_leak_detector()93 if self.get_option("leaks"):94 # DumpRenderTree slows down noticably if we run more than about 1000 tests in a batch95 # with MallocStackLogging enabled.96 self.set_option_default("batch_size", 1000)97 98 def _make_leak_detector(self):99 return LeakDetector(self)100 101 96 def default_timeout_ms(self): 102 97 if self.get_option('guard_malloc'): 103 98 return 350 * 1000 104 99 return super(ApplePort, self).default_timeout_ms() 105 106 def supports_per_test_timeout(self):107 return True108 100 109 101 def should_retry_crashes(self): … … 130 122 return configurations 131 123 132 def check_for_leaks(self, process_name, process_pid):133 if not self.get_option('leaks'):134 return135 # We could use http://code.google.com/p/psutil/ to get the process_name from the pid.136 self._leak_detector.check_for_leaks(process_name, process_pid)137 138 def print_leaks_summary(self):139 if not self.get_option('leaks'):140 return141 # We're in the manager process, so the leak detector will not have a valid list of leak files.142 # FIXME: This is a hack, but we don't have a better way to get this information from the workers yet.143 # FIXME: This will include too many leaks in subsequent runs until the results directory is cleared!144 leaks_files = self._leak_detector.leaks_files_in_directory(self.results_directory())145 if not leaks_files:146 return147 total_bytes_string, unique_leaks = self._leak_detector.count_total_bytes_and_unique_leaks(leaks_files)148 total_leaks = self._leak_detector.count_total_leaks(leaks_files)149 _log.info("%s total leaks found for a total of %s." % (total_leaks, total_bytes_string))150 _log.info("%s unique leaks found." % unique_leaks)151 152 def _path_to_webcore_library(self):153 return self._build_path('WebCore.framework/Versions/A/WebCore')154 155 def show_results_html_file(self, results_filename):156 # We don't use self._run_script() because we don't want to wait for the script157 # to exit and we want the output to show up on stdout in case there are errors158 # launching the browser.159 self._executive.popen([self.path_to_script('run-safari')] + self._arguments_for_configuration() + ['--no-saved-state', '-NSOpen', results_filename],160 cwd=self.webkit_base(), stdout=file(os.devnull), stderr=file(os.devnull))161 162 def _merge_crash_logs(self, logs, new_logs, crashed_processes):163 for test, crash_log in new_logs.iteritems():164 try:165 process_name = test.split("-")[0]166 pid = int(test.split("-")[1])167 except IndexError:168 continue169 if not any(entry[1] == process_name and entry[2] == pid for entry in crashed_processes):170 # if this is a new crash, then append the logs171 logs[test] = crash_log172 return logs173 174 def _look_for_all_crash_logs_in_log_dir(self, newer_than):175 crash_log = CrashLogs(self.host)176 return crash_log.find_all_logs(include_errors=True, newer_than=newer_than)177 178 def _get_crash_log(self, name, pid, stdout, stderr, newer_than, time_fn, sleep_fn, wait_for_log):179 return None180 181 def look_for_new_crash_logs(self, crashed_processes, start_time):182 """Since crash logs can take a long time to be written out if the system is183 under stress do a second pass at the end of the test run.184 185 crashes: test_name -> pid, process_name tuple of crashed process186 start_time: time the tests started at. We're looking for crash187 logs after that time.188 """189 crash_logs = {}190 for (test_name, process_name, pid) in crashed_processes:191 # Passing None for output. This is a second pass after the test finished so192 # if the output had any logging we would have already collected it.193 crash_log = self._get_crash_log(process_name, pid, None, None, start_time, wait_for_log=False)[1]194 if not crash_log:195 continue196 crash_logs[test_name] = crash_log197 all_crash_log = self._look_for_all_crash_logs_in_log_dir(start_time)198 return self._merge_crash_logs(crash_logs, all_crash_log, crashed_processes)199 200 def sample_process(self, name, pid):201 exit_status = self._executive.run_command([202 "/usr/bin/sudo",203 "-n",204 "/usr/sbin/spindump",205 pid,206 10,207 10,208 "-file",209 self.spindump_file_path(name, pid),210 ], return_exit_code=True)211 if exit_status:212 try:213 self._executive.run_command([214 "/usr/bin/sample",215 pid,216 10,217 10,218 "-file",219 self.sample_file_path(name, pid),220 ])221 except ScriptError as e:222 _log.warning('Unable to sample process:' + str(e))223 224 def sample_file_path(self, name, pid):225 return self._filesystem.join(self.results_directory(), "{0}-{1}-sample.txt".format(name, pid))226 227 def spindump_file_path(self, name, pid):228 return self._filesystem.join(self.results_directory(), "{0}-{1}-spindump.txt".format(name, pid))229 230 def look_for_new_samples(self, unresponsive_processes, start_time):231 sample_files = {}232 for (test_name, process_name, pid) in unresponsive_processes:233 sample_file = self.sample_file_path(process_name, pid)234 if not self._filesystem.isfile(sample_file):235 continue236 sample_files[test_name] = sample_file237 return sample_files238 239 124 def _path_to_helper(self): 240 125 binary_name = 'LayoutTestHelper' -
trunk/Tools/Scripts/webkitpy/port/base.py
r205399 r206934 154 154 155 155 def supports_per_test_timeout(self): 156 # FIXME: Make per-test timeouts unconditional once all ports' DumpRenderTrees support that. 157 # Windows DumpRenderTree may be the only one remaining to be fixed at this time. 158 return False 156 return True 159 157 160 158 def default_pixel_tests(self): -
trunk/Tools/Scripts/webkitpy/port/darwin.py
r206932 r206934 1 # Copyright (C) 201 1 Google Inc. All rights reserved.1 # Copyright (C) 2014-2016 Apple Inc. All rights reserved. 2 2 # 3 3 # Redistribution and use in source and binary forms, with or without 4 # modification, are permitted provided that the following conditions are 5 # met: 4 # modification, are permitted provided that the following conditions 5 # are met: 6 # 1. Redistributions of source code must retain the above copyright 7 # notice, this list of conditions and the following disclaimer. 8 # 2. Redistributions in binary form must reproduce the above copyright 9 # notice, this list of conditions and the following disclaimer in the 10 # documentation and/or other materials provided with the distribution. 6 11 # 7 # * Redistributions of source code must retain the above copyright 8 # notice, this list of conditions and the following disclaimer. 9 # * Redistributions in binary form must reproduce the above 10 # copyright notice, this list of conditions and the following disclaimer 11 # in the documentation and/or other materials provided with the 12 # distribution. 13 # * Neither the Google name nor the names of its 14 # contributors may be used to endorse or promote products derived from 15 # this software without specific prior written permission. 16 # 17 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 12 # THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND 13 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 14 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 15 # DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR 16 # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 17 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 18 # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 19 # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 20 # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 21 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 22 29 23 import logging 30 24 import os 25 import time 31 26 32 27 from webkitpy.common.system.crashlogs import CrashLogs 33 28 from webkitpy.common.system.executive import ScriptError 34 from webkitpy.port.base import Port 35 from webkitpy.layout_tests.models.test_configuration import TestConfiguration 29 from webkitpy.port.apple import ApplePort 36 30 from webkitpy.port.leakdetector import LeakDetector 37 31 … … 40 34 41 35 42 class ApplePort(Port): 43 """Shared logic between all of Apple's ports.""" 36 class DarwinPort(ApplePort): 44 37 45 # This is used to represent the version of an operating system 46 # corresponding to the "mac" or "win" base LayoutTests/platform 47 # directory. I'm not sure this concept is very useful, 48 # but it gives us a way to refer to fallback paths *only* including 49 # the base directory. 50 # This is mostly done because TestConfiguration assumes that self.version() 51 # will never return None. (None would be another way to represent this concept.) 52 # Apple supposedly has explicit "future" results which are kept in an internal repository. 53 # It's possible that Apple would want to fix this code to work better with those results. 54 FUTURE_VERSION = 'future' # FIXME: This whole 'future' thing feels like a hack. 55 56 # overridden in subclasses 57 VERSION_FALLBACK_ORDER = [] 58 ARCHITECTURES = [] 59 60 @classmethod 61 def determine_full_port_name(cls, host, options, port_name): 62 options = options or {} 63 if port_name in (cls.port_name, cls.port_name + '-wk2'): 64 # If the port_name matches the (badly named) cls.port_name, that 65 # means that they passed 'mac' or 'win' and didn't specify a version. 66 # That convention means that we're supposed to use the version currently 67 # being run, so this won't work if you're not on mac or win (respectively). 68 # If you're not on the o/s in question, you must specify a full version or -future (cf. above). 69 if port_name == cls.port_name and not getattr(options, 'webkit_test_runner', False): 70 port_name = cls.port_name + '-' + host.platform.os_version 71 else: 72 port_name = cls.port_name + '-' + host.platform.os_version + '-wk2' 73 elif getattr(options, 'webkit_test_runner', False) and '-wk2' not in port_name: 74 port_name += '-wk2' 75 76 return port_name 77 78 def _strip_port_name_prefix(self, port_name): 79 # Callers treat this return value as the "version", which only works 80 # because Apple ports use a simple name-version port_name scheme. 81 # FIXME: This parsing wouldn't be needed if port_name handling was moved to factory.py 82 # instead of the individual port constructors. 83 return port_name[len(self.port_name + '-'):] 38 SDK = None 84 39 85 40 def __init__(self, host, port_name, **kwargs): 86 super(ApplePort, self).__init__(host, port_name, **kwargs)41 ApplePort.__init__(self, host, port_name, **kwargs) 87 42 88 allowed_port_names = self.VERSION_FALLBACK_ORDER + [self.operating_system() + "-future"] 89 port_name = port_name.replace('-wk2', '') 90 self._version = self._strip_port_name_prefix(port_name) 91 92 self._leak_detector = self._make_leak_detector() 43 self._leak_detector = LeakDetector(self) 93 44 if self.get_option("leaks"): 94 45 # DumpRenderTree slows down noticably if we run more than about 1000 tests in a batch … … 96 47 self.set_option_default("batch_size", 1000) 97 48 98 def _make_leak_detector(self):99 return LeakDetector(self)100 101 49 def default_timeout_ms(self): 102 50 if self.get_option('guard_malloc'): 103 51 return 350 * 1000 104 return super( ApplePort, self).default_timeout_ms()52 return super(DarwinPort, self).default_timeout_ms() 105 53 106 def supports_per_test_timeout(self): 107 return True 108 109 def should_retry_crashes(self): 110 return True 111 112 def _skipped_file_search_paths(self): 113 # We don't have a dedicated Skipped file for the most recent version of the port; 114 # we just use the one in platform/{mac,win} 115 most_recent_name = self.VERSION_FALLBACK_ORDER[-1] 116 return set(filter(lambda name: name != most_recent_name, super(ApplePort, self)._skipped_file_search_paths())) 117 118 # FIXME: A more sophisticated version of this function should move to WebKitPort and replace all calls to name(). 119 # This is also a misleading name, since 'mac-future' gets remapped to 'mac'. 120 def _port_name_with_version(self): 121 return self.name().replace('-future', '').replace('-wk2', '') 122 123 def _generate_all_test_configurations(self): 124 configurations = [] 125 allowed_port_names = self.VERSION_FALLBACK_ORDER + [self.operating_system() + "-future"] 126 for port_name in allowed_port_names: 127 for build_type in self.ALL_BUILD_TYPES: 128 for architecture in self.ARCHITECTURES: 129 configurations.append(TestConfiguration(version=self._strip_port_name_prefix(port_name), architecture=architecture, build_type=build_type)) 130 return configurations 54 def _port_specific_expectations_files(self): 55 return list(reversed([self._filesystem.join(self._webkit_baseline_path(p), 'TestExpectations') for p in self.baseline_search_path()])) 131 56 132 57 def check_for_leaks(self, process_name, process_pid): … … 176 101 return crash_log.find_all_logs(include_errors=True, newer_than=newer_than) 177 102 178 def _get_crash_log(self, name, pid, stdout, stderr, newer_than, time_fn , sleep_fn, wait_for_log):103 def _get_crash_log(self, name, pid, stdout, stderr, newer_than, time_fn=None, sleep_fn=None, wait_for_log=True): 179 104 return None 180 105 … … 237 162 return sample_files 238 163 239 def _path_to_helper(self): 240 binary_name = 'LayoutTestHelper' 241 return self._build_path(binary_name) 164 def make_command(self): 165 return self.xcrun_find('make', '/usr/bin/make') 166 167 def nm_command(self): 168 return self.xcrun_find('nm', 'nm') 169 170 def xcrun_find(self, command, fallback=None): 171 fallback = fallback or command 172 try: 173 return self._executive.run_command(['xcrun', '--sdk', self.SDK, '-find', command]).rstrip() 174 except ScriptError: 175 _log.warn("xcrun failed; falling back to '%s'." % fallback) 176 return fallback -
trunk/Tools/Scripts/webkitpy/port/efl.py
r204727 r206934 81 81 return env 82 82 83 def supports_per_test_timeout(self):84 return True85 86 83 def default_timeout_ms(self): 87 84 # Tests run considerably slower under gdb -
trunk/Tools/Scripts/webkitpy/port/gtk.py
r205014 r206934 87 87 return XvfbDriver 88 88 89 def supports_per_test_timeout(self):90 return True91 92 89 def default_timeout_ms(self): 93 90 # Starting an application under Valgrind takes a lot longer than normal -
trunk/Tools/Scripts/webkitpy/port/ios.py
r205884 r206934 30 30 31 31 from webkitpy.common.memoized import memoized 32 from webkitpy.common.system.crashlogs import CrashLogs33 32 from webkitpy.common.system.executive import ScriptError 34 33 from webkitpy.layout_tests.models.test_configuration import TestConfiguration 35 34 from webkitpy.port import config as port_config 36 35 from webkitpy.port import driver, image_diff 37 from webkitpy.port.apple import ApplePort 38 from webkitpy.port.base import Port 36 from webkitpy.port.darwin import DarwinPort 39 37 from webkitpy.xcode.simulator import Simulator, Runtime, DeviceType 38 from webkitpy.common.system.crashlogs import CrashLogs 40 39 41 40 … … 43 42 44 43 45 class IOSPort( ApplePort):44 class IOSPort(DarwinPort): 46 45 port_name = "ios" 47 46 … … 68 67 69 68 70 class IOSSimulatorPort( ApplePort):69 class IOSSimulatorPort(DarwinPort): 71 70 port_name = "ios-simulator" 72 71 … … 77 76 DEFAULT_DEVICE_CLASS = 'iphone' 78 77 CUSTOM_DEVICE_CLASSES = ['ipad'] 78 SDK = 'iphonesimulator' 79 79 80 80 SIMULATOR_BUNDLE_ID = 'com.apple.iphonesimulator' … … 96 96 97 97 def __init__(self, host, port_name, **kwargs): 98 super(IOSSimulatorPort, self).__init__(host, port_name, **kwargs)98 DarwinPort.__init__(self, host, port_name, **kwargs) 99 99 100 100 optional_device_class = self.get_option('device_class') … … 228 228 229 229 return map(self._webkit_baseline_path, fallback_names) 230 231 def _port_specific_expectations_files(self):232 return list(reversed([self._filesystem.join(self._webkit_baseline_path(p), 'TestExpectations') for p in self.baseline_search_path()]))233 230 234 231 def _set_device_class(self, device_class): … … 344 341 SUBPROCESS_CRASH_REGEX = re.compile('#CRASHED - (?P<subprocess_name>\S+) \(pid (?P<subprocess_pid>\d+)\)') 345 342 346 def _get_crash_log(self, name, pid, stdout, stderr, newer_than, time_fn=time.time, sleep_fn=time.sleep, wait_for_log=True):347 time_fn = time_fn or time.time348 sleep_fn = sleep_fn or time.sleep349 350 # FIXME: We should collect the actual crash log for DumpRenderTree.app because it includes more351 # information (e.g. exception codes) than is available in the stack trace written to standard error.352 stderr_lines = []353 crashed_subprocess_name_and_pid = None # e.g. ('DumpRenderTree.app', 1234)354 for line in (stderr or '').splitlines():355 if not crashed_subprocess_name_and_pid:356 match = self.SUBPROCESS_CRASH_REGEX.match(line)357 if match:358 crashed_subprocess_name_and_pid = (match.group('subprocess_name'), int(match.group('subprocess_pid')))359 continue360 stderr_lines.append(line)361 362 if crashed_subprocess_name_and_pid:363 return self._get_crash_log(crashed_subprocess_name_and_pid[0], crashed_subprocess_name_and_pid[1], stdout,364 '\n'.join(stderr_lines), newer_than, time_fn, sleep_fn, wait_for_log)365 366 # LayoutTestRelay crashed367 _log.debug('looking for crash log for %s:%s' % (name, str(pid)))368 crash_log = ''369 crash_logs = CrashLogs(self.host)370 now = time_fn()371 deadline = now + 5 * int(self.get_option('child_processes', 1))372 while not crash_log and now <= deadline:373 crash_log = crash_logs.find_newest_log(name, pid, include_errors=True, newer_than=newer_than)374 if not wait_for_log:375 break376 if not crash_log or not [line for line in crash_log.splitlines() if not line.startswith('ERROR')]:377 sleep_fn(0.1)378 now = time_fn()379 380 if not crash_log:381 return stderr, None382 return stderr, crash_log383 384 343 def _create_device(self, number): 385 344 return Simulator.create_device(number, self.simulator_device_type(), self.simulator_runtime) … … 420 379 return self.xcrun_find('nm') 421 380 422 def xcrun_find(self, command, fallback=None):423 fallback = fallback or command424 try:425 return self._executive.run_command(['xcrun', '--sdk', 'iphonesimulator', '-find', command]).rstrip()426 except ScriptError:427 _log.warn("xcrun failed; falling back to '%s'." % fallback)428 return fallback429 430 381 @property 431 382 @memoized -
trunk/Tools/Scripts/webkitpy/port/mac.py
r204271 r206934 35 35 from webkitpy.common.system.crashlogs import CrashLogs 36 36 from webkitpy.common.system.executive import ScriptError 37 from webkitpy.port. apple import ApplePort37 from webkitpy.port.darwin import DarwinPort 38 38 39 39 _log = logging.getLogger(__name__) 40 40 41 41 42 class MacPort( ApplePort):42 class MacPort(DarwinPort): 43 43 port_name = "mac" 44 44 45 45 VERSION_FALLBACK_ORDER = ['mac-snowleopard', 'mac-lion', 'mac-mountainlion', 'mac-mavericks', 'mac-yosemite', 'mac-elcapitan', 'mac-sierra'] 46 SDK = 'macosx' 46 47 47 48 ARCHITECTURES = ['x86_64', 'x86'] … … 50 51 51 52 def __init__(self, host, port_name, **kwargs): 52 super(MacPort, self).__init__(host, port_name, **kwargs)53 DarwinPort.__init__(self, host, port_name, **kwargs) 53 54 54 55 def _build_driver_flags(self): … … 66 67 fallback_names = [self._wk2_port_name(), 'wk2'] + fallback_names 67 68 return map(self._webkit_baseline_path, fallback_names) 68 69 def _port_specific_expectations_files(self):70 return list(reversed([self._filesystem.join(self._webkit_baseline_path(p), 'TestExpectations') for p in self.baseline_search_path()]))71 69 72 70 def configuration_specifier_macros(self): … … 153 151 return min(supportable_instances, default_count) 154 152 155 def make_command(self):156 return self.xcrun_find('make', '/usr/bin/make')157 158 153 def _build_java_test_support(self): 159 154 # FIXME: This is unused. Remove. … … 167 162 def _check_port_build(self): 168 163 return not self.get_option('java') or self._build_java_test_support() 169 170 def _get_crash_log(self, name, pid, stdout, stderr, newer_than, time_fn=None, sleep_fn=None, wait_for_log=True):171 # Note that we do slow-spin here and wait, since it appears the time172 # ReportCrash takes to actually write and flush the file varies when there are173 # lots of simultaneous crashes going on.174 # FIXME: Should most of this be moved into CrashLogs()?175 time_fn = time_fn or time.time176 sleep_fn = sleep_fn or time.sleep177 crash_log = ''178 crash_logs = CrashLogs(self.host)179 now = time_fn()180 # FIXME: delete this after we're sure this code is working ...181 _log.debug('looking for crash log for %s:%s' % (name, str(pid)))182 deadline = now + 5 * int(self.get_option('child_processes', 1))183 while not crash_log and now <= deadline:184 crash_log = crash_logs.find_newest_log(name, pid, include_errors=True, newer_than=newer_than)185 if not wait_for_log:186 break187 if not crash_log or not [line for line in crash_log.splitlines() if not line.startswith('ERROR')]:188 sleep_fn(0.1)189 now = time_fn()190 191 if not crash_log:192 return (stderr, None)193 return (stderr, crash_log)194 164 195 165 def start_helper(self, pixel_tests=False): … … 230 200 self._helper = None 231 201 232 def nm_command(self):233 return self.xcrun_find('nm', 'nm')234 235 def xcrun_find(self, command, fallback):236 try:237 return self._executive.run_command(['xcrun', '-find', command]).rstrip()238 except ScriptError:239 _log.warn("xcrun failed; falling back to '%s'." % fallback)240 return fallback241 242 202 def logging_patterns_to_strip(self): 243 203 # FIXME: Remove this after <rdar://problem/15605007> is fixed -
trunk/Tools/Scripts/webkitpy/port/mac_unittest.py
r205351 r206934 1 1 # Copyright (C) 2010 Google Inc. All rights reserved. 2 # Copyright (C) 2014-2016 Apple Inc. All rights reserved. 2 3 # 3 4 # Redistribution and use in source and binary forms, with or without … … 27 28 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 29 30 import time 31 29 32 from webkitpy.port.mac import MacPort 30 from webkitpy.port import port_testcase33 from webkitpy.port import darwin_testcase 31 34 from webkitpy.common.system.filesystem_mock import MockFileSystem 32 35 from webkitpy.common.system.outputcapture import OutputCapture … … 36 39 37 40 38 class MacTest( port_testcase.PortTestCase):41 class MacTest(darwin_testcase.DarwinTest): 39 42 os_name = 'mac' 40 43 os_version = 'lion' 41 44 port_name = 'mac-lion' 42 45 port_maker = MacPort 43 44 def assert_skipped_file_search_paths(self, port_name, expected_paths, use_webkit2=False):45 port = self.make_port(port_name=port_name, options=MockOptions(webkit_test_runner=use_webkit2))46 self.assertEqual(port._skipped_file_search_paths(), expected_paths)47 48 def test_default_timeout_ms(self):49 super(MacTest, self).test_default_timeout_ms()50 self.assertEqual(self.make_port(options=MockOptions(guard_malloc=True)).default_timeout_ms(), 350000)51 52 def assert_name(self, port_name, os_version_string, expected):53 host = MockSystemHost(os_name='mac', os_version=os_version_string)54 port = self.make_port(host=host, port_name=port_name)55 self.assertEqual(expected, port.name())56 46 57 47 def test_tests_for_other_platforms(self): … … 158 148 return lambda: times.pop(0) 159 149 port = self.make_port(port_name='mac-snowleopard') 160 port._get_crash_log('DumpRenderTree', 1234, '', '', 0, 161 time_fn=fake_time_cb(), sleep_fn=lambda delay: None) 162 163 def test_helper_starts(self): 164 host = MockSystemHost(MockExecutive()) 165 port = self.make_port(host) 166 oc = OutputCapture() 167 oc.capture_output() 168 host.executive._proc = MockProcess('ready\n') 169 port.start_helper() 170 port.stop_helper() 171 oc.restore_output() 172 173 # make sure trying to stop the helper twice is safe. 174 port.stop_helper() 175 176 def test_helper_fails_to_start(self): 177 host = MockSystemHost(MockExecutive()) 178 port = self.make_port(host) 179 oc = OutputCapture() 180 oc.capture_output() 181 port.start_helper() 182 port.stop_helper() 183 oc.restore_output() 184 185 def test_helper_fails_to_stop(self): 186 host = MockSystemHost(MockExecutive()) 187 host.executive._proc = MockProcess() 188 189 def bad_waiter(): 190 raise IOError('failed to wait') 191 host.executive._proc.wait = bad_waiter 192 193 port = self.make_port(host) 194 oc = OutputCapture() 195 oc.capture_output() 196 port.start_helper() 197 port.stop_helper() 198 oc.restore_output() 199 200 def test_spindump(self): 201 202 def logging_run_command(args): 203 print args 204 205 port = self.make_port() 206 port._executive = MockExecutive2(run_command_fn=logging_run_command) 207 expected_stdout = "['/usr/bin/sudo', '-n', '/usr/sbin/spindump', 42, 10, 10, '-file', '/mock-build/layout-test-results/test-42-spindump.txt']\n" 208 OutputCapture().assert_outputs(self, port.sample_process, args=['test', 42], expected_stdout=expected_stdout) 209 210 def test_sample_process(self): 211 212 def logging_run_command(args): 213 if args[0] == '/usr/bin/sudo': 214 return 1 215 print args 216 return 0 217 218 port = self.make_port() 219 port._executive = MockExecutive2(run_command_fn=logging_run_command) 220 expected_stdout = "['/usr/bin/sample', 42, 10, 10, '-file', '/mock-build/layout-test-results/test-42-sample.txt']\n" 221 OutputCapture().assert_outputs(self, port.sample_process, args=['test', 42], expected_stdout=expected_stdout) 222 223 def test_sample_process_exception(self): 224 def throwing_run_command(args): 225 if args[0] == '/usr/bin/sudo': 226 return 1 227 raise ScriptError("MOCK script error") 228 229 port = self.make_port() 230 port._executive = MockExecutive2(run_command_fn=throwing_run_command) 231 OutputCapture().assert_outputs(self, port.sample_process, args=['test', 42]) 150 port._get_crash_log('DumpRenderTree', 1234, None, None, time.time(), wait_for_log=False) 232 151 233 152 def test_32bit(self): … … 253 172 port._build_driver() 254 173 self.assertEqual(self.args, []) 174 175 def test_sdk_name(self): 176 port = self.make_port() 177 self.assertEqual(port.SDK, 'macosx') 178 179 def test_xcrun(self): 180 def throwing_run_command(args): 181 print args 182 raise ScriptError("MOCK script error") 183 184 port = self.make_port() 185 port._executive = MockExecutive2(run_command_fn=throwing_run_command) 186 expected_stdout = "['xcrun', '--sdk', 'macosx', '-find', 'test']\n" 187 OutputCapture().assert_outputs(self, port.xcrun_find, args=['test', 'falling'], expected_stdout=expected_stdout) -
trunk/Tools/Scripts/webkitpy/port/port_testcase.py
r204680 r206934 1 1 # Copyright (C) 2010 Google Inc. All rights reserved. 2 # Copyright (C) 2014-2016 Apple Inc. All rights reserved. 2 3 # 3 4 # Redistribution and use in source and binary forms, with or without … … 82 83 port_maker = TestWebKitPort 83 84 port_name = None 85 is_simulator = False 84 86 85 87 def make_port(self, host=None, port_name=None, options=None, os_name=None, os_version=None, **kwargs): … … 251 253 return self.proc 252 254 255 # FIXME: Can't pretend to run a simulator's setup, so just skip this test. 256 if self.is_simulator: 257 return 258 253 259 port._server_process_constructor = make_proc 254 260 port.setup_test_run() … … 273 279 self.proc = MockServerProcess(port, nm, cmd, env, crashed=True) 274 280 return self.proc 281 282 # FIXME: Can't pretend to run a simulator's setup, so just skip this test. 283 if self.is_simulator: 284 return 275 285 276 286 port._server_process_constructor = make_proc -
trunk/Tools/Scripts/webkitpy/port/win.py
r206144 r206934 405 405 return crash_logs 406 406 407 def look_for_new_samples(self, unresponsive_processes, start_time):408 # No sampling on Windows.409 pass410 411 def sample_process(self, name, pid):412 # No sampling on Windows.413 pass414 415 def _make_leak_detector(self):416 return None417 418 def check_for_leaks(self, process_name, process_pid):419 # No leak checking on Windows.420 pass421 422 def print_leaks_summary(self):423 # No leak checking on Windows.424 pass425 426 def _path_to_webcore_library(self):427 return None428 429 407 def find_system_pid(self, name, pid): 430 408 system_pid = int(pid)
Note: See TracChangeset
for help on using the changeset viewer.