Modified: trunk/Tools/ChangeLog (179711 => 179712)
--- trunk/Tools/ChangeLog 2015-02-05 22:35:48 UTC (rev 179711)
+++ trunk/Tools/ChangeLog 2015-02-05 22:46:30 UTC (rev 179712)
@@ -1,3 +1,44 @@
+2015-02-05 Daniel Bates <[email protected]>
+
+ LayoutTestRelay does not install DumpRenderTree.app/WebKitTestRunnerApp.app
+ https://bugs.webkit.org/show_bug.cgi?id=139746
+ <rdar://problem/19283658>
+
+ Reviewed by Alexey Proskuryakov.
+
+ Fixes an issues where LayoutTestRelay may fail to install DumpRenderTree.app/WebKitTestRunnerApp.app
+ if the simulator device is not in state Booted.
+
+ Currently run-webkit-test --ios-sim executes LayoutTestRelay immediately after
+ launching/relaunching the iOS Simulator app and a simulator app can only be installed
+ on a device that is in the Booted state. LayoutTestRelay may run before the
+ device is booted and hence fail to install DumpRenderTree.app/WebKitTestRunnerApp.app.
+ We should defer executing LayoutTestRelay until the simulator device booted by
+ iOS Simulator is in the Booted state.
+
+ * Scripts/webkitpy/port/ios.py: Import webkitpy.xcode.simulator.Simulator to avoid prefixing
+ Simulator methods with the module name, simulator.
+ (IOSSimulatorPort.setup_test_run): Wait for the simulator device to be in the Booted state
+ after launching iOS Simulator. Also, wait until the simulator device is in the Shutdown state
+ before launching iOS Simulator to boot it.
+ (IOSSimulatorPort.testing_device): Fix up caller since we now import webkitpy.xcode.simulator.Simulator.
+ (IOSSimulatorPort.simulator_path): Deleted; moved this function to class Simulator and renamed to device_directory().
+ * Scripts/webkitpy/xcode/simulator.py:
+ (Device.__init__): Remove parameter state and an instance variable of the same name, which represented
+ the state of the device when we created this object as part of parsing the output of `simctl list`. Callers
+ interested in the state of the device are more likely interested in the current state of the device as
+ opposed to the state of the device when the Device object was created.
+ (Device.state): Added; turn around and call Simulator.device_state() for the current state of the device.
+ (Device.path): Extracted implementation into Simulator.device_directory() so that it can be called
+ from both this function and Simulator.device_state().
+ (Device.create): Use Simulator.wait_until_device_is_in_state() to simplify the implementation of this function.
+ (Simulator.DeviceState): Added; class of constants.
+ (Simulator.wait_until_device_is_in_state): Added; this function does not return until the specified
+ device is in the specified state.
+ (Simulator.device_state): Added; parses the state of the device from the appropriate CoreSimulator device.plist file.
+ (Simulator.device_directory): Added.
+ (Simulator._parse_devices): Do not pass argument state to Device constructor as it no longer accepts it.
+
2015-02-05 Alexey Proskuryakov <[email protected]>
Disable retries on Mac debug testers
Modified: trunk/Tools/Scripts/webkitpy/port/ios.py (179711 => 179712)
--- trunk/Tools/Scripts/webkitpy/port/ios.py 2015-02-05 22:35:48 UTC (rev 179711)
+++ trunk/Tools/Scripts/webkitpy/port/ios.py 2015-02-05 22:46:30 UTC (rev 179712)
@@ -36,7 +36,7 @@
from webkitpy.port.base import Port
from webkitpy.port.leakdetector import LeakDetector
from webkitpy.port import config as port_config
-from webkitpy.xcode import simulator
+from webkitpy.xcode.simulator import Simulator
_log = logging.getLogger(__name__)
@@ -179,10 +179,12 @@
def setup_test_run(self):
self._executive.run_command(['osascript', '-e', 'tell application "iOS Simulator" to quit'])
- time.sleep(2)
+ device_udid = self.testing_device.udid
+ Simulator.wait_until_device_is_in_state(device_udid, Simulator.DeviceState.SHUTDOWN)
self._executive.run_command([
'open', '-a', os.path.join(self.developer_dir, 'Applications', 'iOS Simulator.app'),
- '--args', '-CurrentDeviceUDID', self.testing_device.udid])
+ '--args', '-CurrentDeviceUDID', device_udid])
+ Simulator.wait_until_device_is_in_state(device_udid, Simulator.DeviceState.BOOTED)
def clean_up_test_run(self):
super(IOSSimulatorPort, self).clean_up_test_run()
@@ -287,13 +289,9 @@
device_type = self.get_option('device_type')
runtime = self.get_option('runtime')
- self._testing_device = simulator.Simulator().lookup_or_create_device(device_type.name + ' WebKit Tester', device_type, runtime)
+ self._testing_device = Simulator().lookup_or_create_device(device_type.name + ' WebKit Tester', device_type, runtime)
return self.testing_device
- def simulator_path(self, udid):
- if udid:
- return os.path.realpath(os.path.expanduser(os.path.join('~/Library/Developer/CoreSimulator/Devices', udid)))
-
def look_for_new_crash_logs(self, crashed_processes, start_time):
crash_logs = {}
for (test_name, process_name, pid) in crashed_processes:
Modified: trunk/Tools/Scripts/webkitpy/xcode/simulator.py (179711 => 179712)
--- trunk/Tools/Scripts/webkitpy/xcode/simulator.py 2015-02-05 22:35:48 UTC (rev 179711)
+++ trunk/Tools/Scripts/webkitpy/xcode/simulator.py 2015-02-05 22:46:30 UTC (rev 179712)
@@ -1,6 +1,7 @@
import itertools
import logging
import os
+import plistlib
import re
import subprocess
import time
@@ -14,7 +15,6 @@
Do not use PyObjC to dlopen the framework.
"""
-
class DeviceType(object):
"""
Represents a CoreSimulator device type.
@@ -140,14 +140,12 @@
Represents a CoreSimulator device underneath a runtime
"""
- def __init__(self, name, udid, state, available, runtime):
+ def __init__(self, name, udid, available, runtime):
"""
:param name: The device name
:type name: str
:param udid: The device UDID (a UUID string)
:type udid: str
- :param state: The last known device state
- :type state: str
:param available: Whether the device is available for use.
:type available: bool
:param runtime: The iOS Simulator runtime that hosts this device
@@ -155,19 +153,24 @@
"""
self.name = name
self.udid = udid
- self.state = state
self.available = available
self.runtime = runtime
@property
+ def state(self):
+ """
+ :returns: The current state of the device.
+ :rtype: Simulator.DeviceState
+ """
+ return Simulator.device_state(self.udid)
+
+ @property
def path(self):
"""
:returns: The filesystem path that contains the simulator device's data.
:rtype: str
"""
- return os.path.realpath(
- os.path.expanduser(
- os.path.join('~/Library/Developer/CoreSimulator/Devices', self.udid)))
+ return Simulator.device_directory(self.udid)
@classmethod
def create(cls, name, device_type, runtime):
@@ -182,16 +185,9 @@
:return: The new device or raises a CalledProcessError if ``simctl create`` failed.
:rtype: Device
"""
- sim = Simulator()
device_udid = subprocess.check_output(['xcrun', 'simctl', 'create', name, device_type.identifier, runtime.identifier]).rstrip()
- assert(device_udid)
- while True:
- sim.refresh()
- device = sim.find_device_by_udid(device_udid)
- if not device or device.state == 'Creating':
- time.sleep(2)
- continue
- return device
+ Simulator.wait_until_device_is_in_state(device_udid, Simulator.DeviceState.SHUTDOWN)
+ return Simulator().find_device_by_udid(device_udid)
def __eq__(self, other):
return self.udid == other.udid
@@ -228,6 +224,32 @@
self.device_types = []
self.refresh()
+ # Keep these constants synchronized with the SimDeviceState constants in CoreSimulator/SimDevice.h.
+ class DeviceState:
+ DOES_NOT_EXIST = -1
+ CREATING = 0
+ SHUTDOWN = 1
+ BOOTING = 2
+ BOOTED = 3
+ SHUTTING_DOWN = 4
+
+ @staticmethod
+ def wait_until_device_is_in_state(udid, wait_until_state):
+ # FIXME: Implement support for a timed wait.
+ while (Simulator.device_state(udid) != wait_until_state):
+ time.sleep(0.5)
+
+ @staticmethod
+ def device_state(udid):
+ device_plist = os.path.join(Simulator.device_directory(udid), 'device.plist')
+ if not os.path.isfile(device_plist):
+ return Simulator.DeviceState.DOES_NOT_EXIST
+ return plistlib.readPlist(device_plist)['state']
+
+ @staticmethod
+ def device_directory(udid):
+ return os.path.realpath(os.path.expanduser(os.path.join('~/Library/Developer/CoreSimulator/Devices', udid)))
+
def refresh(self):
"""
Refresh runtime and device type information from ``simctl list``.
@@ -305,7 +327,6 @@
raise RuntimeError('Expected an iOS Simulator device line, got "{}"'.format(line))
device = Device(name=device_match.group('name').rstrip(),
udid=device_match.group('udid'),
- state=device_match.group('state'),
available=device_match.group('availability') is None,
runtime=current_runtime)
current_runtime.devices.append(device)