Title: [179712] trunk/Tools
Revision
179712
Author
[email protected]
Date
2015-02-05 14:46:30 -0800 (Thu, 05 Feb 2015)

Log Message

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.

Modified Paths

Diff

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)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to