Changeset 220483 in webkit
- Timestamp:
- Aug 9, 2017, 2:58:18 PM (9 years ago)
- Location:
- trunk/Tools
- Files:
-
- 2 added
- 5 edited
-
ChangeLog (modified) (1 diff)
-
Scripts/webkitpy/benchmark_runner/utils.py (modified) (2 diffs)
-
Scripts/webkitpy/common/timeout_context.py (added)
-
Scripts/webkitpy/common/timeout_context_unittest.py (added)
-
Scripts/webkitpy/port/simulator_process.py (modified) (2 diffs)
-
Scripts/webkitpy/xcode/simulated_device.py (modified) (2 diffs)
-
Scripts/webkitpy/xcode/simulator.py (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Tools/ChangeLog
r220473 r220483 1 2017-08-09 Jonathan Bedard <jbedard@apple.com> 2 3 Allow nested timeouts in webkitpy 4 https://bugs.webkit.org/show_bug.cgi?id=175390 5 <rdar://problem/33803003> 6 7 Reviewed by David Kilzer. 8 9 We need to be able to nest timeouts in webkitpy. In particular, we have a few cases where functions 10 which use timeouts also call the executive. For on-device testing, we need to have timeouts inside 11 the executive to detect and recover from any issues connecting with devices. 12 13 * Scripts/webkitpy/benchmark_runner/utils.py: 14 (TimeoutError): Deleted. 15 (timeout): Deleted. 16 * Scripts/webkitpy/common/timeout_context.py: Added. 17 (Timeout): A timeout context designed to be nested. 18 (Timeout.TimeoutData): The data required to construct an alarm for a given timeout. 19 (Timeout.TimeoutData.__init__): 20 (Timeout.default_handler): Timeout handler used if none is specified. 21 (Timeout.current): Access data about the most urgent timeout. 22 (Timeout.__init__): Construct a Timeout object with seconds and an optional handler. 23 (Timeout._bind_timeout_data_to_alarm): Given data about a timeout, initialize an alarm for that timeout. 24 (Timeout.__enter__): Un-bind all alarms. Add data for this timeout to the ordered list and bind the most 25 urgent timeout data. 26 (Timeout.__exit__): Un-bind all alarms. Remove data for this timeout from the ordered list and bind the 27 most urgent timeout data, if such data exists. 28 * Scripts/webkitpy/common/timeout_context_unittest.py: Added. 29 (TimeoutContextTests): 30 (TimeoutContextTests.test_current_timeout): Test that accessing the nearest timeout works as expected. 31 (TimeoutContextTests.test_invalid_timeout): Test a timeout of 0. 32 (TimeoutContextTests.test_timeout_data): Confirm that timeouts are constructed correctly. 33 (TimeoutContextTests.test_nested_inner_precedence): Check that a more urgent inner timeout takes precedence 34 over a less urgent outer timeout. 35 (TimeoutContextTests.test_nested_outer_precedence): Check that a more urgent outer timeout takes precedence 36 over a less urgent inner timeout. 37 (TimeoutContextTests.test_no_timeout): Test a block of code without a timeout. 38 (TimeoutContextTests.test_basic_timeout): Test a block of code expected to timeout. 39 (TimeoutContextTests.test_exception_constructor_timeout): Test a timeout where the handler is an exception. 40 (TimeoutContextTests.test_nested_inner_timeout): Confirm that a more urgent inner timeout is triggered. 41 (TimeoutContextTests.test_nested_outer_timeout): Confirm that a more urgent outer timeout is triggered. 42 * Scripts/webkitpy/port/simulator_process.py: 43 (SimulatorProcess._start): Use Timeout class. 44 * Scripts/webkitpy/xcode/simulated_device.py: 45 (SimulatedDevice.launch_app._log_debug_error): Use Timeout class. 46 (SimulatedDevice.launch_app): Ditto. 47 (SimulatedDevice.launch_app._install_timeout): Deleted. 48 * Scripts/webkitpy/xcode/simulator.py: 49 (Simulator.wait_until_device_is_booted):Use Timeout class. 50 (Simulator.wait_until_device_is_in_state): Ditto. 51 1 52 2017-08-09 Wenson Hsieh <wenson_hsieh@apple.com> 2 53 -
trunk/Tools/Scripts/webkitpy/benchmark_runner/utils.py
r219853 r220483 5 5 import logging 6 6 import os 7 import signal8 7 import shutil 9 import sys10 8 11 9 from webkitpy.common.memoized import memoized … … 78 76 defaults.synchronize() 79 77 return True 80 81 82 # Borrow this code from83 # 'http://stackoverflow.com/questions/2281850/timeout-function-if-it-takes-too-long-to-finish'84 class TimeoutError(Exception):85 pass86 87 88 class timeout:89 90 def __init__(self, seconds=1, error_message='Timeout'):91 self.seconds = seconds92 self.error_message = error_message93 94 def handle_timeout(self, signum, frame):95 raise TimeoutError(self.error_message)96 97 def __enter__(self):98 signal.signal(signal.SIGALRM, self.handle_timeout)99 signal.alarm(self.seconds)100 101 def __exit__(self, type, value, traceback):102 signal.alarm(0) -
trunk/Tools/Scripts/webkitpy/port/simulator_process.py
r217856 r220483 23 23 24 24 import os 25 import signal26 25 import time 27 26 27 from webkitpy.common.timeout_context import Timeout 28 28 from webkitpy.port.server_process import ServerProcess 29 30 29 31 30 class SimulatorProcess(ServerProcess): … … 96 95 self._pid = self._target_host.launch_app(self._bundle_id, self._cmd[1:], env=self._env) 97 96 98 def handler(signum, frame): 99 assert signum == signal.SIGALRM 100 raise RuntimeError('Timed out waiting for pid {} to connect at port {}'.format(self._pid, self._target_host.listening_port())) 101 signal.signal(signal.SIGALRM, handler) 102 signal.alarm(6) # In seconds 103 104 stdin = None 105 stdout = None 106 stderr = None 107 try: 108 # This order matches the client side connections in Tools/TestRunnerShared/IOSLayoutTestCommunication.cpp setUpIOSLayoutTestCommunication() 109 stdin = SimulatorProcess._accept_connection_create_file(self._target_host.listening_socket, 'w') 110 stdout = SimulatorProcess._accept_connection_create_file(self._target_host.listening_socket, 'rb') 111 stderr = SimulatorProcess._accept_connection_create_file(self._target_host.listening_socket, 'rb') 112 except: 113 # We set self._proc as _reset() and _kill() depend on it. 114 self._proc = SimulatorProcess.Popen(self._pid, stdin, stdout, stderr, self._target_host) 115 if self._proc.poll() is not None: 97 with Timeout(6, RuntimeError('Timed out waiting for pid {} to connect at port {}'.format(self._pid, self._target_host.listening_port()))): 98 stdin = None 99 stdout = None 100 stderr = None 101 try: 102 # This order matches the client side connections in Tools/TestRunnerShared/IOSLayoutTestCommunication.cpp setUpIOSLayoutTestCommunication() 103 stdin = SimulatorProcess._accept_connection_create_file(self._target_host.listening_socket, 'w') 104 stdout = SimulatorProcess._accept_connection_create_file(self._target_host.listening_socket, 'rb') 105 stderr = SimulatorProcess._accept_connection_create_file(self._target_host.listening_socket, 'rb') 106 except: 107 # We set self._proc as _reset() and _kill() depend on it. 108 self._proc = SimulatorProcess.Popen(self._pid, stdin, stdout, stderr, self._target_host) 109 if self._proc.poll() is not None: 110 self._reset() 111 raise Exception('App {} with pid {} crashed before stdin could be attached'.format(os.path.basename(self._cmd[0]), self._pid)) 112 self._kill() 116 113 self._reset() 117 raise Exception('App {} with pid {} crashed before stdin could be attached'.format(os.path.basename(self._cmd[0]), self._pid)) 118 self._kill() 119 self._reset() 120 raise 121 signal.alarm(0) # Cancel alarm 114 raise 122 115 123 116 self._proc = SimulatorProcess.Popen(self._pid, stdin, stdout, stderr, self._target_host) -
trunk/Tools/Scripts/webkitpy/xcode/simulated_device.py
r219534 r220483 23 23 import logging 24 24 import re 25 import signal26 25 import subprocess 27 26 27 from webkitpy.common.host import Host 28 28 from webkitpy.common.system.executive import ScriptError 29 from webkitpy.common.timeout_context import Timeout 29 30 from webkitpy.xcode.simulator import Simulator 30 from webkitpy.common.host import Host31 31 32 32 _log = logging.getLogger(__name__) … … 171 171 _log.debug(error.message_with_output()) 172 172 173 def _install_timeout(signum, frame):174 assert signum == signal.SIGALRM175 raise RuntimeError('Timed out waiting for process to open {} on {}'.format(bundle_id, self.udid))176 177 173 output = None 178 signal.signal(signal.SIGALRM, _install_timeout) 179 signal.alarm(timeout) # In seconds 180 while True: 181 output = self._host.executive.run_command( 182 ['xcrun', 'simctl', 'launch', self.udid, bundle_id] + args, 183 env=environment_to_use, 184 error_handler=_log_debug_error, 185 ) 186 match = re.match(r'(?P<bundle>[^:]+): (?P<pid>\d+)\n', output) 187 # FIXME: We shouldn't need to check the PID <rdar://problem/31154075>. 188 if match and self.executive.check_running_pid(int(match.group('pid'))): 189 break 190 if match: 191 _log.debug('simctl launch reported pid {}, but this process is not running'.format(match.group('pid'))) 192 else: 193 _log.debug('simctl launch did not report a pid') 194 195 signal.alarm(0) # Cancel alarm 174 175 with Timeout(timeout, RuntimeError('Timed out waiting for process to open {} on {}'.format(bundle_id, self.udid))): 176 while True: 177 output = self._host.executive.run_command( 178 ['xcrun', 'simctl', 'launch', self.udid, bundle_id] + args, 179 env=environment_to_use, 180 error_handler=_log_debug_error, 181 ) 182 match = re.match(r'(?P<bundle>[^:]+): (?P<pid>\d+)\n', output) 183 # FIXME: We shouldn't need to check the PID <rdar://problem/31154075>. 184 if match and self.executive.check_running_pid(int(match.group('pid'))): 185 break 186 if match: 187 _log.debug('simctl launch reported pid {}, but this process is not running'.format(match.group('pid'))) 188 else: 189 _log.debug('simctl launch did not report a pid') 196 190 197 191 if match.group('bundle') != bundle_id: -
trunk/Tools/Scripts/webkitpy/xcode/simulator.py
r216899 r220483 29 29 import time 30 30 31 from webkitpy. benchmark_runner.utils import timeout31 from webkitpy.common.timeout_context import Timeout 32 32 from webkitpy.common.host import Host 33 33 … … 243 243 def wait_until_device_is_booted(udid, timeout_seconds=60 * 15): 244 244 Simulator.wait_until_device_is_in_state(udid, Simulator.DeviceState.BOOTED, timeout_seconds) 245 with timeout(seconds=timeout_seconds):245 with Timeout(seconds=timeout_seconds): 246 246 while True: 247 247 try: … … 261 261 def wait_until_device_is_in_state(udid, wait_until_state, timeout_seconds=60 * 15): 262 262 _log.debug('waiting for device %s to enter state %s with timeout %s', udid, Simulator.device_state_description(wait_until_state), timeout_seconds) 263 with timeout(seconds=timeout_seconds):263 with Timeout(seconds=timeout_seconds): 264 264 device_state = Simulator.device_state(udid) 265 265 while (device_state != wait_until_state):
Note:
See TracChangeset
for help on using the changeset viewer.