Title: [213236] trunk/Tools
Revision
213236
Author
jbed...@apple.com
Date
2017-03-01 11:47:21 -0800 (Wed, 01 Mar 2017)

Log Message

webkitpy: Move some device management from iOSSimulatorPort to iOSPort class
https://bugs.webkit.org/show_bug.cgi?id=168681

Reviewed by Daniel Bates.

This patch moves high-level device management into iOSPort and adds a new iOSDevicePort class
which inherits from iOSPort.  Additionally, this change renames device_id_for_worker_number to
device_for_worker_number and manages devices by object instead of by UDID.

* Scripts/webkitpy/port/factory.py:
(PortFactory): Correct import path for IOSSimulatorPort and IOSDevicePort.
* Scripts/webkitpy/port/ios.py:
(IOSPort.__init__): Define variables shared between iOS ports.
(IOSPort.driver_cmd_line_for_logging): From IOSSimulatorPort.
(IOSPort.driver_name): From IOSSimulatorPort.
(IOSPort.using_multiple_devices): Check if this port supports multiple devices.
(IOSPort._testing_device): Map worker number to device.
(IOSPort.device_for_worker_number): Return _testing_device() or _current_device based on using_multiple_devices.
(IOSSimulatorPort): Moved to ios_simulator.py
* Scripts/webkitpy/port/ios_device.py: Added.
(IOSDevicePort): Moved functionality from IOSPort.
(IOSDevicePort.determine_full_port_name): Moved from IOSPort.
(IOSDevicePort._build_driver_flags): Ditto.
(IOSDevicePort.operating_system): Ditto.
* Scripts/webkitpy/port/ios_simulator.py: Added.
(IOSSimulatorPort): Moved from ios.py.
(IOSSimulatorPort.__init__): Init parent class, setup device map.
(IOSSimulatorPort._create_simulators): Use object over unbound methods.
(IOSSimulatorPort.setup_test_run): Ditto.
(IOSSimulatorPort.using_multiple_devices): True if we are managing the simulators.
(IOSSimulatorPort._create_device): Use object over unbound methods.
(IOSSimulatorPort._remove_device): Ditto.
(IOSSimulatorPort.driver_name): Moved to parent class.
(IOSSimulatorPort.driver_cmd_line_for_logging): Ditto.
(IOSSimulatorPort.child_processes): Ditto.
(IOSSimulatorPort._testing_device): Ditto.
(IOSSimulatorPort.device_id_for_worker_number): Renamed as device_for_worker_number.
(SimulatorProcess.__init__): Call find_device_by_udid, device_id_for_worker_number has been removed.
* Scripts/webkitpy/xcode/simulator.py:
(Simulator): Make _managed_devices public.
(Simulator.create_device): Ditto.
(Simulator.remove_device): Ditto.
(Simulator.device_number): Ditto.

Modified Paths

Added Paths

Diff

Modified: trunk/Tools/ChangeLog (213235 => 213236)


--- trunk/Tools/ChangeLog	2017-03-01 19:41:56 UTC (rev 213235)
+++ trunk/Tools/ChangeLog	2017-03-01 19:47:21 UTC (rev 213236)
@@ -1,3 +1,49 @@
+2017-03-01  Jonathan Bedard  <jbed...@apple.com>
+
+        webkitpy: Move some device management from iOSSimulatorPort to iOSPort class
+        https://bugs.webkit.org/show_bug.cgi?id=168681
+
+        Reviewed by Daniel Bates.
+
+        This patch moves high-level device management into iOSPort and adds a new iOSDevicePort class
+        which inherits from iOSPort.  Additionally, this change renames device_id_for_worker_number to
+        device_for_worker_number and manages devices by object instead of by UDID.
+
+        * Scripts/webkitpy/port/factory.py:
+        (PortFactory): Correct import path for IOSSimulatorPort and IOSDevicePort.
+        * Scripts/webkitpy/port/ios.py:
+        (IOSPort.__init__): Define variables shared between iOS ports.
+        (IOSPort.driver_cmd_line_for_logging): From IOSSimulatorPort.
+        (IOSPort.driver_name): From IOSSimulatorPort.
+        (IOSPort.using_multiple_devices): Check if this port supports multiple devices.
+        (IOSPort._testing_device): Map worker number to device.
+        (IOSPort.device_for_worker_number): Return _testing_device() or _current_device based on using_multiple_devices. 
+        (IOSSimulatorPort): Moved to ios_simulator.py
+        * Scripts/webkitpy/port/ios_device.py: Added.
+        (IOSDevicePort): Moved functionality from IOSPort.
+        (IOSDevicePort.determine_full_port_name): Moved from IOSPort.
+        (IOSDevicePort._build_driver_flags): Ditto.
+        (IOSDevicePort.operating_system): Ditto.
+        * Scripts/webkitpy/port/ios_simulator.py: Added.
+        (IOSSimulatorPort): Moved from ios.py.
+        (IOSSimulatorPort.__init__): Init parent class, setup device map.
+        (IOSSimulatorPort._create_simulators): Use object over unbound methods.
+        (IOSSimulatorPort.setup_test_run): Ditto.
+        (IOSSimulatorPort.using_multiple_devices): True if we are managing the simulators.
+        (IOSSimulatorPort._create_device): Use object over unbound methods.
+        (IOSSimulatorPort._remove_device): Ditto.
+        (IOSSimulatorPort.driver_name): Moved to parent class.
+        (IOSSimulatorPort.driver_cmd_line_for_logging): Ditto.
+        (IOSSimulatorPort.child_processes): Ditto.
+        (IOSSimulatorPort._testing_device): Ditto.
+        (IOSSimulatorPort.device_id_for_worker_number): Renamed as device_for_worker_number.
+        (SimulatorProcess.__init__): Call find_device_by_udid, device_id_for_worker_number has been removed.
+        * Scripts/webkitpy/xcode/simulator.py:
+        (Simulator): Make _managed_devices public.
+        (Simulator.create_device): Ditto.
+        (Simulator.remove_device): Ditto.
+        (Simulator.device_number): Ditto.
+
 2017-03-01  Alexey Proskuryakov  <a...@apple.com>
 
         IndexedDB.IndexedDBMultiProcess is a flaky timeout

Modified: trunk/Tools/Scripts/webkitpy/port/factory.py (213235 => 213236)


--- trunk/Tools/Scripts/webkitpy/port/factory.py	2017-03-01 19:41:56 UTC (rev 213235)
+++ trunk/Tools/Scripts/webkitpy/port/factory.py	2017-03-01 19:47:21 UTC (rev 213236)
@@ -80,17 +80,17 @@
 class PortFactory(object):
     # Order matters.  For port classes that have a port_name with a
     # common prefix, the more specific port class should be listed
-    # first.  For example, 'ios.IOSSimulatorPort' (port_name='ios-simulator')
-    # should be listed before 'ios.IOSPort' (port_name='ios').  If this
+    # first.  For example, 'ios_simulator.IOSSimulatorPort' (port_name='ios-simulator')
+    # should be listed before 'ios_device.IOSDevicePort' (port_name='ios').  If this
     # rule is not followed, then `webkit-patch --ios-simulator` will try
-    # to use IOSPort instead of IOSSimulatorPort because 'ios'
-    # (IOSPort.port_name) is a prefix of 'ios-simulator' (port_name
+    # to use IOSDevicePort instead of IOSSimulatorPort because 'ios'
+    # (IOSDevicePort.port_name) is a prefix of 'ios-simulator' (port_name
     # derived from '--ios-simulator' command-line switch), for example.
     PORT_CLASSES = (
         'efl.EflPort',
         'gtk.GtkPort',
-        'ios.IOSSimulatorPort',
-        'ios.IOSPort',
+        'ios_simulator.IOSSimulatorPort',
+        'ios_device.IOSDevicePort',
         'mac.MacPort',
         'mock_drt.MockDRTPort',
         'test.TestPort',

Modified: trunk/Tools/Scripts/webkitpy/port/ios.py (213235 => 213236)


--- trunk/Tools/Scripts/webkitpy/port/ios.py	2017-03-01 19:41:56 UTC (rev 213235)
+++ trunk/Tools/Scripts/webkitpy/port/ios.py	2017-03-01 19:47:21 UTC (rev 213236)
@@ -1,4 +1,4 @@
-# Copyright (C) 2014-2016 Apple Inc. All rights reserved.
+# Copyright (C) 2014-2017 Apple Inc. All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
 # modification, are permitted provided that the following conditions
@@ -20,25 +20,12 @@
 # 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 itertools
 import logging
-import os
-import re
-import shutil
-import subprocess
-import time
 
 from webkitpy.common.memoized import memoized
-from webkitpy.common.system.executive import ScriptError
-from webkitpy.layout_tests.models.test_configuration import TestConfiguration
-from webkitpy.port import config as port_config
-from webkitpy.port import driver, image_diff
 from webkitpy.port.darwin import DarwinPort
 from webkitpy.port.simulator_process import SimulatorProcess
-from webkitpy.xcode.simulator import Simulator, Runtime, DeviceType
-from webkitpy.common.system.crashlogs import CrashLogs
 
-
 _log = logging.getLogger(__name__)
 
 
@@ -45,73 +32,22 @@
 class IOSPort(DarwinPort):
     port_name = "ios"
 
-    ARCHITECTURES = ['armv7', 'armv7s', 'arm64']
-    DEFAULT_ARCHITECTURE = 'arm64'
-    VERSION_FALLBACK_ORDER = ['ios-7', 'ios-8', 'ios-9', 'ios-10']
-
-    @classmethod
-    def determine_full_port_name(cls, host, options, port_name):
-        if port_name == cls.port_name:
-            iphoneos_sdk_version = host.platform.xcode_sdk_version('iphoneos')
-            if not iphoneos_sdk_version:
-                raise Exception("Please install the iOS SDK.")
-            major_version_number = iphoneos_sdk_version.split('.')[0]
-            port_name = port_name + '-' + major_version_number
-        return port_name
-
-    # Despite their names, these flags do not actually get passed all the way down to webkit-build.
-    def _build_driver_flags(self):
-        return ['--sdk', 'iphoneos'] + (['ARCHS=%s' % self.architecture()] if self.architecture() else [])
-
-    def operating_system(self):
-        return 'ios'
-
-
-class IOSSimulatorPort(DarwinPort):
-    port_name = "ios-simulator"
-
-    FUTURE_VERSION = 'future'
-    ARCHITECTURES = ['x86_64', 'x86']
-    DEFAULT_ARCHITECTURE = 'x86_64'
-
-    DEFAULT_DEVICE_CLASS = 'iphone'
-    CUSTOM_DEVICE_CLASSES = ['ipad', 'iphone7']
-    SDK = 'iphonesimulator'
-
-    SIMULATOR_BUNDLE_ID = 'com.apple.iphonesimulator'
-    SIMULATOR_DIRECTORY = "/tmp/WebKitTestingSimulators/"
-    LSREGISTER_PATH = "/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Versions/Current/Support/lsregister"
-    PROCESS_COUNT_ESTIMATE_PER_SIMULATOR_INSTANCE = 100
-
-    DEVICE_CLASS_MAP = {
-        'x86_64': {
-            'iphone': 'iPhone 5s',
-            'iphone7': 'iPhone 7',
-            'ipad': 'iPad Air'
-        },
-        'x86': {
-            'iphone': 'iPhone 5',
-            'ipad': 'iPad Retina'
-        },
-    }
-
     def __init__(self, host, port_name, **kwargs):
-        DarwinPort.__init__(self, host, port_name, **kwargs)
+        super(IOSPort, self).__init__(host, port_name, **kwargs)
         self._test_runner_process_constructor = SimulatorProcess
+        self._printing_cmd_line = False
+        self._current_device = None
 
-        optional_device_class = self.get_option('device_class')
+    def _device_for_worker_number_map(self):
+        raise NotImplementedError
+
+    def driver_cmd_line_for_logging(self):
+        # Avoid creating/connecting to devices just for logging the commandline.
+        self._printing_cmd_line = True
+        result = super(IOSPort, self).driver_cmd_line_for_logging()
         self._printing_cmd_line = False
-        self._device_class = optional_device_class if optional_device_class else self.DEFAULT_DEVICE_CLASS
-        _log.debug('IOSSimulatorPort _device_class is %s', self._device_class)
+        return result
 
-        self._current_device = Simulator(host).current_device()
-        if not self._current_device:
-            self.set_option('dedicated_simulators', True)
-        if not self.get_option('dedicated_simulators'):
-            if self.get_option('child_processes') > 1:
-                _log.warn('Cannot have more than one child process when using a running simulator.  Setting child_processes to 1.')
-            self.set_option('child_processes', 1)
-
     def driver_name(self):
         if self.get_option('driver_name'):
             return self.get_option('driver_name')
@@ -119,315 +55,24 @@
             return 'WebKitTestRunnerApp.app'
         return 'DumpRenderTree.app'
 
-    def driver_cmd_line_for_logging(self):
-        # Avoid spinning up devices just for logging the commandline.
-        self._printing_cmd_line = True
-        result = super(IOSSimulatorPort, self).driver_cmd_line_for_logging()
-        self._printing_cmd_line = False
-        return result
-
-    @property
     @memoized
-    def simulator_runtime(self):
-        runtime_identifier = self.get_option('runtime')
-        if runtime_identifier:
-            runtime = Runtime.from_identifier(runtime_identifier)
-        else:
-            runtime = Runtime.from_version_string(self.host.platform.xcode_sdk_version('iphonesimulator'))
-        return runtime
-
-    def simulator_device_type(self):
-        device_type_identifier = self.get_option('device_type')
-        if device_type_identifier:
-            _log.debug('simulator_device_type for device identifier %s', device_type_identifier)
-            device_type = DeviceType.from_identifier(device_type_identifier)
-        else:
-            _log.debug('simulator_device_type for device %s', self._device_class)
-            device_name = self.DEVICE_CLASS_MAP[self.architecture()][self._device_class]
-            if not device_name:
-                raise Exception('Failed to find device for architecture {} and device class {}'.format(self.architecture()), self._device_class)
-            device_type = DeviceType.from_name(device_name)
-        return device_type
-
-    @memoized
     def child_processes(self):
         return int(self.get_option('child_processes'))
 
-    @memoized
-    def default_child_processes(self):
-        """Return the number of Simulators instances to use for this port."""
-        best_child_process_count_for_cpu = self._executive.cpu_count() / 2
-        system_process_count_limit = int(subprocess.check_output(["ulimit", "-u"]).strip())
-        current_process_count = len(subprocess.check_output(["ps", "aux"]).strip().split('\n'))
-        _log.debug('Process limit: %d, current #processes: %d' % (system_process_count_limit, current_process_count))
-        maximum_simulator_count_on_this_system = (system_process_count_limit - current_process_count) // self.PROCESS_COUNT_ESTIMATE_PER_SIMULATOR_INSTANCE
-        # FIXME: We should also take into account the available RAM.
+    def using_multiple_devices(self):
+        return False
 
-        if (maximum_simulator_count_on_this_system < best_child_process_count_for_cpu):
-            _log.warn("This machine could support %s simulators, but is only configured for %s."
-                % (best_child_process_count_for_cpu, maximum_simulator_count_on_this_system))
-            _log.warn('Please see <https://trac.webkit.org/wiki/IncreasingKernelLimits>.')
-
-        if maximum_simulator_count_on_this_system == 0:
-            maximum_simulator_count_on_this_system = 1
-
-        return min(maximum_simulator_count_on_this_system, best_child_process_count_for_cpu)
-
-    def _get_crash_log(self, name, pid, stdout, stderr, newer_than, time_fn=time.time, sleep_fn=time.sleep, wait_for_log=True):
-        time_fn = time_fn or time.time
-        sleep_fn = sleep_fn or time.sleep
-
-        # FIXME: We should collect the actual crash log for DumpRenderTree.app because it includes more
-        # information (e.g. exception codes) than is available in the stack trace written to standard error.
-        stderr_lines = []
-        crashed_subprocess_name_and_pid = None  # e.g. ('DumpRenderTree.app', 1234)
-        for line in (stderr or '').splitlines():
-            if not crashed_subprocess_name_and_pid:
-                match = self.SUBPROCESS_CRASH_REGEX.match(line)
-                if match:
-                    crashed_subprocess_name_and_pid = (match.group('subprocess_name'), int(match.group('subprocess_pid')))
-                    continue
-            stderr_lines.append(line)
-
-        if crashed_subprocess_name_and_pid:
-            return self._get_crash_log(crashed_subprocess_name_and_pid[0], crashed_subprocess_name_and_pid[1], stdout,
-                '\n'.join(stderr_lines), newer_than, time_fn, sleep_fn, wait_for_log)
-
-        # App crashed
-        _log.debug('looking for crash log for %s:%s' % (name, str(pid)))
-        crash_log = ''
-        crash_logs = CrashLogs(self.host)
-        now = time_fn()
-        deadline = now + 5 * int(self.get_option('child_processes', 1))
-        while not crash_log and now <= deadline:
-            crash_log = crash_logs.find_newest_log(name, 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 not line.startswith('ERROR')]:
-                sleep_fn(0.1)
-                now = time_fn()
-
-        if not crash_log:
-            return stderr, None
-        return stderr, crash_log
-
-    def _build_driver_flags(self):
-        archs = ['ARCHS=i386'] if self.architecture() == 'x86' else []
-        sdk = ['--sdk', 'iphonesimulator']
-        return archs + sdk
-
-    def _generate_all_test_configurations(self):
-        configurations = []
-        for build_type in self.ALL_BUILD_TYPES:
-            for architecture in self.ARCHITECTURES:
-                configurations.append(TestConfiguration(version=self._version, architecture=architecture, build_type=build_type))
-        return configurations
-
-    def default_baseline_search_path(self):
-        if self.get_option('webkit_test_runner'):
-            fallback_names = [self._wk2_port_name()] + [self.port_name] + ['wk2']
-        else:
-            fallback_names = [self.port_name + '-wk1'] + [self.port_name]
-
-        return map(self._webkit_baseline_path, fallback_names)
-
-    def _set_device_class(self, device_class):
-        self._device_class = device_class if device_class else self.DEFAULT_DEVICE_CLASS
-
-    def _create_simulators(self):
-        if (self.default_child_processes() < self.child_processes()):
-            _log.warn('You have specified very high value({0}) for --child-processes'.format(self.child_processes()))
-            _log.warn('maximum child-processes which can be supported on this system are: {0}'.format(self.default_child_processes()))
-            _log.warn('This is very likely to fail.')
-
-        if self._using_dedicated_simulators():
-            self._createSimulatorApps()
-
-            for i in xrange(self.child_processes()):
-                self._create_device(i)
-
-            for i in xrange(self.child_processes()):
-                device_udid = self._testing_device(i).udid
-                Simulator.wait_until_device_is_in_state(device_udid, Simulator.DeviceState.SHUTDOWN)
-                Simulator.reset_device(device_udid)
-        else:
-            assert(self._current_device)
-            if self._current_device.name != self.simulator_device_type().name:
-                _log.warn("Expected simulator of type '" + self.simulator_device_type().name + "' but found simulator of type '" + self._current_device.name + "'")
-                _log.warn('The next block of tests may fail due to device mis-match')
-
-    def setup_test_run(self, device_class=None):
-        mac_os_version = self.host.platform.os_version
-
-        self._set_device_class(device_class)
-
-        _log.debug('')
-        _log.debug('setup_test_run for %s', self._device_class)
-
-        self._create_simulators()
-
-        if not self._using_dedicated_simulators():
-            return
-
-        for i in xrange(self.child_processes()):
-            device_udid = self._testing_device(i).udid
-            _log.debug('testing device %s has udid %s', i, device_udid)
-
-            # FIXME: <rdar://problem/20916140> Switch to using CoreSimulator.framework for launching and quitting iOS Simulator
-            self._executive.run_command([
-                'open', '-g', '-b', self.SIMULATOR_BUNDLE_ID + str(i),
-                '--args', '-CurrentDeviceUDID', device_udid])
-
-            if mac_os_version in ['elcapitan', 'yosemite', 'mavericks']:
-                time.sleep(2.5)
-
-        _log.info('Waiting for all iOS Simulators to finish booting.')
-        for i in xrange(self.child_processes()):
-            Simulator.wait_until_device_is_booted(self._testing_device(i).udid)
-
-    def _quit_ios_simulator(self):
-        if not self._using_dedicated_simulators():
-            return
-        _log.debug("_quit_ios_simulator killing all Simulator processes")
-        # FIXME: We should kill only the Simulators we started.
-        subprocess.call(["killall", "-9", "-m", "Simulator"])
-
-    def clean_up_test_run(self):
-        super(IOSSimulatorPort, self).clean_up_test_run()
-        _log.debug("clean_up_test_run")
-        self._quit_ios_simulator()
-        fifos = [path for path in os.listdir('/tmp') if re.search('org.webkit.(DumpRenderTree|WebKitTestRunner).*_(IN|OUT|ERROR)', path)]
-        for fifo in fifos:
-            try:
-                os.remove(os.path.join('/tmp', fifo))
-            except OSError:
-                _log.warning('Unable to remove ' + fifo)
-                pass
-
-        if not self._using_dedicated_simulators():
-            return
-
-        for i in xrange(self.child_processes()):
-            simulator_path = self.get_simulator_path(i)
-            device_udid = self._testing_device(i).udid
-            self._remove_device(i)
-
-            if not os.path.exists(simulator_path):
-                continue
-            try:
-                self._executive.run_command([self.LSREGISTER_PATH, "-u", simulator_path])
-
-                _log.debug('rmtree %s', simulator_path)
-                self._filesystem.rmtree(simulator_path)
-
-                logs_path = self._filesystem.join(self._filesystem.expanduser("~"), "Library/Logs/CoreSimulator/", device_udid)
-                _log.debug('rmtree %s', logs_path)
-                self._filesystem.rmtree(logs_path)
-
-                saved_state_path = self._filesystem.join(self._filesystem.expanduser("~"), "Library/Saved Application State/", self.SIMULATOR_BUNDLE_ID + str(i) + ".savedState")
-                _log.debug('rmtree %s', saved_state_path)
-                self._filesystem.rmtree(saved_state_path)
-
-            except:
-                _log.warning('Unable to remove Simulator' + str(i))
-
-    def setup_environ_for_server(self, server_name=None):
-        _log.debug("setup_environ_for_server")
-        env = super(IOSSimulatorPort, self).setup_environ_for_server(server_name)
-        if server_name == self.driver_name():
-            if self.get_option('leaks'):
-                env['MallocStackLogging'] = '1'
-                env['__XPC_MallocStackLogging'] = '1'
-                env['MallocScribble'] = '1'
-                env['__XPC_MallocScribble'] = '1'
-            if self.get_option('guard_malloc'):
-                self._append_value_colon_separated(env, 'DYLD_INSERT_LIBRARIES', '/usr/lib/libgmalloc.dylib')
-                self._append_value_colon_separated(env, '__XPC_DYLD_INSERT_LIBRARIES', '/usr/lib/libgmalloc.dylib')
-        env['XML_CATALOG_FILES'] = ''  # work around missing /etc/catalog <rdar://problem/4292995>
-        return env
-
-    def operating_system(self):
-        return 'ios-simulator'
-
-    def check_sys_deps(self, needs_http):
-        if not self.simulator_runtime.available:
-            _log.error('The iOS Simulator runtime with identifier "{0}" cannot be used because it is unavailable.'.format(self.simulator_runtime.identifier))
-            return False
-        return super(IOSSimulatorPort, self).check_sys_deps(needs_http)
-
-    SUBPROCESS_CRASH_REGEX = re.compile('#CRASHED - (?P<subprocess_name>\S+) \(pid (?P<subprocess_pid>\d+)\)')
-
-    def _using_dedicated_simulators(self):
-        return self.get_option('dedicated_simulators')
-
-    def _create_device(self, number):
-        return Simulator.create_device(number, self.simulator_device_type(), self.simulator_runtime)
-
-    def _remove_device(self, number):
-        Simulator.remove_device(number)
-
     def _testing_device(self, number):
-        return Simulator.device_number(number)
+        device = self._device_for_worker_number_map()[number]
+        if not device:
+            raise RuntimeError('Device at {} could not be found'.format(number))
+        return device
 
     # FIXME: This is only exposed so that SimulatorProcess can use it.
-    def device_id_for_worker_number(self, number):
+    def device_for_worker_number(self, number):
         if self._printing_cmd_line:
-            return '<dummy id>'
-        if self._using_dedicated_simulators():
-            return self._testing_device(number).udid
-        return self._current_device.udid
-
-    def get_simulator_path(self, suffix=""):
-        return os.path.join(self.SIMULATOR_DIRECTORY, "Simulator" + str(suffix) + ".app")
-
-    def diff_image(self, expected_contents, actual_contents, tolerance=None):
-        if not actual_contents and not expected_contents:
-            return (None, 0, None)
-        if not actual_contents or not expected_contents:
-            return (True, 0, None)
-        if not self._image_differ:
-            self._image_differ = image_diff.IOSSimulatorImageDiffer(self)
-        self.set_option_default('tolerance', 0.1)
-        if tolerance is None:
-            tolerance = self.get_option('tolerance')
-        return self._image_differ.diff_image(expected_contents, actual_contents, tolerance)
-
-    def reset_preferences(self):
-        _log.debug("reset_preferences")
-        self._quit_ios_simulator()
-        # Maybe this should delete all devices that we've created?
-
-    def nm_command(self):
-        return self.xcrun_find('nm')
-
-    @property
-    @memoized
-    def developer_dir(self):
-        return self._executive.run_command(['xcode-select', '--print-path']).rstrip()
-
-    def logging_patterns_to_strip(self):
-        return []
-
-    def stderr_patterns_to_strip(self):
-        return []
-
-    def _createSimulatorApps(self):
-        for i in xrange(self.child_processes()):
-            self._createSimulatorApp(i)
-
-    def _createSimulatorApp(self, suffix):
-        destination = self.get_simulator_path(suffix)
-        _log.info("Creating app:" + destination)
-        if os.path.exists(destination):
-            shutil.rmtree(destination, ignore_errors=True)
-        simulator_app_path = self.developer_dir + "/Applications/Simulator.app"
-        shutil.copytree(simulator_app_path, destination)
-
-        # Update app's package-name inside plist and re-code-sign it
-        plist_path = destination + "/Contents/Info.plist"
-        command = "Set CFBundleIdentifier com.apple.iphonesimulator" + str(suffix)
-        subprocess.check_output(["/usr/libexec/PlistBuddy", "-c", command, plist_path])
-        subprocess.check_output(["install_name_tool", "-add_rpath", self.developer_dir + "/Library/PrivateFrameworks/", destination + "/Contents/MacOS/Simulator"])
-        subprocess.check_output(["install_name_tool", "-add_rpath", self.developer_dir + "/../Frameworks/", destination + "/Contents/MacOS/Simulator"])
-        subprocess.check_output(["codesign", "-fs", "-", destination])
-        subprocess.check_output([self.LSREGISTER_PATH, "-f", destination])
+            return None
+        # When using simulated devices, this means webkitpy is managing the devices.
+        if self.using_multiple_devices():
+            return self._testing_device(number)
+        return self._current_device

Added: trunk/Tools/Scripts/webkitpy/port/ios_device.py (0 => 213236)


--- trunk/Tools/Scripts/webkitpy/port/ios_device.py	                        (rev 0)
+++ trunk/Tools/Scripts/webkitpy/port/ios_device.py	2017-03-01 19:47:21 UTC (rev 213236)
@@ -0,0 +1,52 @@
+# Copyright (C) 2014-2017 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:
+# 1.  Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+# 2.  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.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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 logging
+
+from webkitpy.port.ios import IOSPort
+
+_log = logging.getLogger(__name__)
+
+
+class IOSDevicePort(IOSPort):
+    port_name = 'ios'
+
+    ARCHITECTURES = ['armv7', 'armv7s', 'arm64']
+    DEFAULT_ARCHITECTURE = 'arm64'
+    VERSION_FALLBACK_ORDER = ['ios-7', 'ios-8', 'ios-9', 'ios-10']
+
+    @classmethod
+    def determine_full_port_name(cls, host, options, port_name):
+        if port_name == cls.port_name:
+            iphoneos_sdk_version = host.platform.xcode_sdk_version('iphoneos')
+            if not iphoneos_sdk_version:
+                raise Exception("Please install the iOS SDK.")
+            major_version_number = iphoneos_sdk_version.split('.')[0]
+            port_name = port_name + '-' + major_version_number
+        return port_name
+
+    # Despite their names, these flags do not actually get passed all the way down to webkit-build.
+    def _build_driver_flags(self):
+        return ['--sdk', 'iphoneos'] + (['ARCHS=%s' % self.architecture()] if self.architecture() else [])
+
+    def operating_system(self):
+        return 'ios'

Copied: trunk/Tools/Scripts/webkitpy/port/ios_simulator.py (from rev 213235, trunk/Tools/Scripts/webkitpy/port/ios.py) (0 => 213236)


--- trunk/Tools/Scripts/webkitpy/port/ios_simulator.py	                        (rev 0)
+++ trunk/Tools/Scripts/webkitpy/port/ios_simulator.py	2017-03-01 19:47:21 UTC (rev 213236)
@@ -0,0 +1,379 @@
+# Copyright (C) 2014-2017 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:
+# 1.  Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+# 2.  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.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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 logging
+import os
+import re
+import shutil
+import subprocess
+import time
+
+from webkitpy.common.memoized import memoized
+from webkitpy.layout_tests.models.test_configuration import TestConfiguration
+from webkitpy.port import image_diff
+from webkitpy.port.ios import IOSPort
+from webkitpy.xcode.simulator import Simulator, Runtime, DeviceType
+from webkitpy.common.system.crashlogs import CrashLogs
+
+
+_log = logging.getLogger(__name__)
+
+
+class IOSSimulatorPort(IOSPort):
+    port_name = "ios-simulator"
+
+    FUTURE_VERSION = 'future'
+    ARCHITECTURES = ['x86_64', 'x86']
+    DEFAULT_ARCHITECTURE = 'x86_64'
+
+    DEFAULT_DEVICE_CLASS = 'iphone'
+    CUSTOM_DEVICE_CLASSES = ['ipad', 'iphone7']
+    SDK = 'iphonesimulator'
+
+    SIMULATOR_BUNDLE_ID = 'com.apple.iphonesimulator'
+    SIMULATOR_DIRECTORY = "/tmp/WebKitTestingSimulators/"
+    LSREGISTER_PATH = "/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Versions/Current/Support/lsregister"
+    PROCESS_COUNT_ESTIMATE_PER_SIMULATOR_INSTANCE = 100
+
+    DEVICE_CLASS_MAP = {
+        'x86_64': {
+            'iphone': 'iPhone 5s',
+            'iphone7': 'iPhone 7',
+            'ipad': 'iPad Air',
+        },
+        'x86': {
+            'iphone': 'iPhone 5',
+            'ipad': 'iPad Retina',
+        },
+    }
+
+    def __init__(self, host, port_name, **kwargs):
+        super(IOSSimulatorPort, self).__init__(host, port_name, **kwargs)
+
+        optional_device_class = self.get_option('device_class')
+        self._device_class = optional_device_class if optional_device_class else self.DEFAULT_DEVICE_CLASS
+        _log.debug('IOSSimulatorPort _device_class is %s', self._device_class)
+
+        self._current_device = Simulator(host).current_device()
+        if not self._current_device:
+            self.set_option('dedicated_simulators', True)
+        if not self.get_option('dedicated_simulators'):
+            if self.get_option('child_processes') > 1:
+                _log.warn('Cannot have more than one child process when using a running simulator.  Setting child_processes to 1.')
+            self.set_option('child_processes', 1)
+
+    def _device_for_worker_number_map(self):
+        return Simulator.managed_devices
+
+    @property
+    @memoized
+    def simulator_runtime(self):
+        runtime_identifier = self.get_option('runtime')
+        if runtime_identifier:
+            runtime = Runtime.from_identifier(runtime_identifier)
+        else:
+            runtime = Runtime.from_version_string(self.host.platform.xcode_sdk_version('iphonesimulator'))
+        return runtime
+
+    def simulator_device_type(self):
+        device_type_identifier = self.get_option('device_type')
+        if device_type_identifier:
+            _log.debug('simulator_device_type for device identifier %s', device_type_identifier)
+            device_type = DeviceType.from_identifier(device_type_identifier)
+        else:
+            _log.debug('simulator_device_type for device %s', self._device_class)
+            device_name = self.DEVICE_CLASS_MAP[self.architecture()][self._device_class]
+            if not device_name:
+                raise Exception('Failed to find device for architecture {} and device class {}'.format(self.architecture()), self._device_class)
+            device_type = DeviceType.from_name(device_name)
+        return device_type
+
+    @memoized
+    def default_child_processes(self):
+        """Return the number of Simulators instances to use for this port."""
+        best_child_process_count_for_cpu = self._executive.cpu_count() / 2
+        system_process_count_limit = int(subprocess.check_output(["ulimit", "-u"]).strip())
+        current_process_count = len(subprocess.check_output(["ps", "aux"]).strip().split('\n'))
+        _log.debug('Process limit: %d, current #processes: %d' % (system_process_count_limit, current_process_count))
+        maximum_simulator_count_on_this_system = (system_process_count_limit - current_process_count) // self.PROCESS_COUNT_ESTIMATE_PER_SIMULATOR_INSTANCE
+        # FIXME: We should also take into account the available RAM.
+
+        if (maximum_simulator_count_on_this_system < best_child_process_count_for_cpu):
+            _log.warn("This machine could support %s simulators, but is only configured for %s."
+                % (best_child_process_count_for_cpu, maximum_simulator_count_on_this_system))
+            _log.warn('Please see <https://trac.webkit.org/wiki/IncreasingKernelLimits>.')
+
+        if maximum_simulator_count_on_this_system == 0:
+            maximum_simulator_count_on_this_system = 1
+
+        return min(maximum_simulator_count_on_this_system, best_child_process_count_for_cpu)
+
+    def _get_crash_log(self, name, pid, stdout, stderr, newer_than, time_fn=time.time, sleep_fn=time.sleep, wait_for_log=True):
+        time_fn = time_fn or time.time
+        sleep_fn = sleep_fn or time.sleep
+
+        # FIXME: We should collect the actual crash log for DumpRenderTree.app because it includes more
+        # information (e.g. exception codes) than is available in the stack trace written to standard error.
+        stderr_lines = []
+        crashed_subprocess_name_and_pid = None  # e.g. ('DumpRenderTree.app', 1234)
+        for line in (stderr or '').splitlines():
+            if not crashed_subprocess_name_and_pid:
+                match = self.SUBPROCESS_CRASH_REGEX.match(line)
+                if match:
+                    crashed_subprocess_name_and_pid = (match.group('subprocess_name'), int(match.group('subprocess_pid')))
+                    continue
+            stderr_lines.append(line)
+
+        if crashed_subprocess_name_and_pid:
+            return self._get_crash_log(crashed_subprocess_name_and_pid[0], crashed_subprocess_name_and_pid[1], stdout,
+                '\n'.join(stderr_lines), newer_than, time_fn, sleep_fn, wait_for_log)
+
+        # App crashed
+        _log.debug('looking for crash log for %s:%s' % (name, str(pid)))
+        crash_log = ''
+        crash_logs = CrashLogs(self.host)
+        now = time_fn()
+        deadline = now + 5 * int(self.get_option('child_processes', 1))
+        while not crash_log and now <= deadline:
+            crash_log = crash_logs.find_newest_log(name, 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 not line.startswith('ERROR')]:
+                sleep_fn(0.1)
+                now = time_fn()
+
+        if not crash_log:
+            return stderr, None
+        return stderr, crash_log
+
+    def _build_driver_flags(self):
+        archs = ['ARCHS=i386'] if self.architecture() == 'x86' else []
+        sdk = ['--sdk', 'iphonesimulator']
+        return archs + sdk
+
+    def _generate_all_test_configurations(self):
+        configurations = []
+        for build_type in self.ALL_BUILD_TYPES:
+            for architecture in self.ARCHITECTURES:
+                configurations.append(TestConfiguration(version=self._version, architecture=architecture, build_type=build_type))
+        return configurations
+
+    def default_baseline_search_path(self):
+        if self.get_option('webkit_test_runner'):
+            fallback_names = [self._wk2_port_name()] + [self.port_name] + ['wk2']
+        else:
+            fallback_names = [self.port_name + '-wk1'] + [self.port_name]
+
+        return map(self._webkit_baseline_path, fallback_names)
+
+    def _set_device_class(self, device_class):
+        self._device_class = device_class if device_class else self.DEFAULT_DEVICE_CLASS
+
+    def _create_simulators(self):
+        if (self.default_child_processes() < self.child_processes()):
+            _log.warn('You have specified very high value({0}) for --child-processes'.format(self.child_processes()))
+            _log.warn('maximum child-processes which can be supported on this system are: {0}'.format(self.default_child_processes()))
+            _log.warn('This is very likely to fail.')
+
+        if self._using_dedicated_simulators():
+            self._createSimulatorApps()
+
+            for i in xrange(self.child_processes()):
+                self._create_device(i)
+
+            for i in xrange(self.child_processes()):
+                device_udid = self._testing_device(i).udid
+                Simulator.wait_until_device_is_in_state(device_udid, Simulator.DeviceState.SHUTDOWN)
+                Simulator.reset_device(device_udid)
+        else:
+            assert(self._current_device)
+            if self._current_device.name != self.simulator_device_type().name:
+                _log.warn("Expected simulator of type '" + self.simulator_device_type().name + "' but found simulator of type '" + self._current_device.name + "'")
+                _log.warn('The next block of tests may fail due to device mis-match')
+
+    def setup_test_run(self, device_class=None):
+        mac_os_version = self.host.platform.os_version
+
+        self._set_device_class(device_class)
+
+        _log.debug('')
+        _log.debug('setup_test_run for %s', self._device_class)
+
+        self._create_simulators()
+
+        if not self._using_dedicated_simulators():
+            return
+
+        for i in xrange(self.child_processes()):
+            device_udid = self._testing_device(i).udid
+            _log.debug('testing device %s has udid %s', i, device_udid)
+
+            # FIXME: <rdar://problem/20916140> Switch to using CoreSimulator.framework for launching and quitting iOS Simulator
+            self._executive.run_command([
+                'open', '-g', '-b', self.SIMULATOR_BUNDLE_ID + str(i),
+                '--args', '-CurrentDeviceUDID', device_udid])
+
+            if mac_os_version in ['elcapitan', 'yosemite', 'mavericks']:
+                time.sleep(2.5)
+
+        _log.info('Waiting for all iOS Simulators to finish booting.')
+        for i in xrange(self.child_processes()):
+            Simulator.wait_until_device_is_booted(self._testing_device(i).udid)
+
+    def _quit_ios_simulator(self):
+        if not self._using_dedicated_simulators():
+            return
+        _log.debug("_quit_ios_simulator killing all Simulator processes")
+        # FIXME: We should kill only the Simulators we started.
+        subprocess.call(["killall", "-9", "-m", "Simulator"])
+
+    def clean_up_test_run(self):
+        super(IOSSimulatorPort, self).clean_up_test_run()
+        _log.debug("clean_up_test_run")
+        self._quit_ios_simulator()
+        fifos = [path for path in os.listdir('/tmp') if re.search('org.webkit.(DumpRenderTree|WebKitTestRunner).*_(IN|OUT|ERROR)', path)]
+        for fifo in fifos:
+            try:
+                os.remove(os.path.join('/tmp', fifo))
+            except OSError:
+                _log.warning('Unable to remove ' + fifo)
+                pass
+
+        if not self._using_dedicated_simulators():
+            return
+
+        for i in xrange(self.child_processes()):
+            simulator_path = self.get_simulator_path(i)
+            device_udid = self._testing_device(i).udid
+            self._remove_device(i)
+
+            if not os.path.exists(simulator_path):
+                continue
+            try:
+                self._executive.run_command([self.LSREGISTER_PATH, "-u", simulator_path])
+
+                _log.debug('rmtree %s', simulator_path)
+                self._filesystem.rmtree(simulator_path)
+
+                logs_path = self._filesystem.join(self._filesystem.expanduser("~"), "Library/Logs/CoreSimulator/", device_udid)
+                _log.debug('rmtree %s', logs_path)
+                self._filesystem.rmtree(logs_path)
+
+                saved_state_path = self._filesystem.join(self._filesystem.expanduser("~"), "Library/Saved Application State/", self.SIMULATOR_BUNDLE_ID + str(i) + ".savedState")
+                _log.debug('rmtree %s', saved_state_path)
+                self._filesystem.rmtree(saved_state_path)
+
+            except:
+                _log.warning('Unable to remove Simulator' + str(i))
+
+    def setup_environ_for_server(self, server_name=None):
+        _log.debug("setup_environ_for_server")
+        env = super(IOSSimulatorPort, self).setup_environ_for_server(server_name)
+        if server_name == self.driver_name():
+            if self.get_option('leaks'):
+                env['MallocStackLogging'] = '1'
+                env['__XPC_MallocStackLogging'] = '1'
+                env['MallocScribble'] = '1'
+                env['__XPC_MallocScribble'] = '1'
+            if self.get_option('guard_malloc'):
+                self._append_value_colon_separated(env, 'DYLD_INSERT_LIBRARIES', '/usr/lib/libgmalloc.dylib')
+                self._append_value_colon_separated(env, '__XPC_DYLD_INSERT_LIBRARIES', '/usr/lib/libgmalloc.dylib')
+        env['XML_CATALOG_FILES'] = ''  # work around missing /etc/catalog <rdar://problem/4292995>
+        return env
+
+    def operating_system(self):
+        return 'ios-simulator'
+
+    def check_sys_deps(self, needs_http):
+        if not self.simulator_runtime.available:
+            _log.error('The iOS Simulator runtime with identifier "{0}" cannot be used because it is unavailable.'.format(self.simulator_runtime.identifier))
+            return False
+        return super(IOSSimulatorPort, self).check_sys_deps(needs_http)
+
+    SUBPROCESS_CRASH_REGEX = re.compile('#CRASHED - (?P<subprocess_name>\S+) \(pid (?P<subprocess_pid>\d+)\)')
+
+    def _using_dedicated_simulators(self):
+        return self.get_option('dedicated_simulators')
+
+    def using_multiple_devices(self):
+        return self._using_dedicated_simulators()
+
+    def _create_device(self, number):
+        return Simulator.create_device(number, self.simulator_device_type(), self.simulator_runtime)
+
+    def _remove_device(self, number):
+        Simulator.remove_device(number)
+
+    def get_simulator_path(self, suffix=""):
+        return os.path.join(self.SIMULATOR_DIRECTORY, "Simulator" + str(suffix) + ".app")
+
+    def diff_image(self, expected_contents, actual_contents, tolerance=None):
+        if not actual_contents and not expected_contents:
+            return (None, 0, None)
+        if not actual_contents or not expected_contents:
+            return (True, 0, None)
+        if not self._image_differ:
+            self._image_differ = image_diff.IOSSimulatorImageDiffer(self)
+        self.set_option_default('tolerance', 0.1)
+        if tolerance is None:
+            tolerance = self.get_option('tolerance')
+        return self._image_differ.diff_image(expected_contents, actual_contents, tolerance)
+
+    def reset_preferences(self):
+        _log.debug("reset_preferences")
+        self._quit_ios_simulator()
+        # Maybe this should delete all devices that we've created?
+
+    def nm_command(self):
+        return self.xcrun_find('nm')
+
+    @property
+    @memoized
+    def developer_dir(self):
+        return self._executive.run_command(['xcode-select', '--print-path']).rstrip()
+
+    def logging_patterns_to_strip(self):
+        return []
+
+    def stderr_patterns_to_strip(self):
+        return []
+
+    def _createSimulatorApps(self):
+        for i in xrange(self.child_processes()):
+            self._createSimulatorApp(i)
+
+    def _createSimulatorApp(self, suffix):
+        destination = self.get_simulator_path(suffix)
+        _log.info("Creating app:" + destination)
+        if os.path.exists(destination):
+            shutil.rmtree(destination, ignore_errors=True)
+        simulator_app_path = self.developer_dir + "/Applications/Simulator.app"
+        shutil.copytree(simulator_app_path, destination)
+
+        # Update app's package-name inside plist and re-code-sign it
+        plist_path = destination + "/Contents/Info.plist"
+        command = "Set CFBundleIdentifier com.apple.iphonesimulator" + str(suffix)
+        subprocess.check_output(["/usr/libexec/PlistBuddy", "-c", command, plist_path])
+        subprocess.check_output(["install_name_tool", "-add_rpath", self.developer_dir + "/Library/PrivateFrameworks/", destination + "/Contents/MacOS/Simulator"])
+        subprocess.check_output(["install_name_tool", "-add_rpath", self.developer_dir + "/../Frameworks/", destination + "/Contents/MacOS/Simulator"])
+        subprocess.check_output(["codesign", "-fs", "-", destination])
+        subprocess.check_output([self.LSREGISTER_PATH, "-f", destination])

Modified: trunk/Tools/Scripts/webkitpy/port/ios_unittest.py (213235 => 213236)


--- trunk/Tools/Scripts/webkitpy/port/ios_unittest.py	2017-03-01 19:41:56 UTC (rev 213235)
+++ trunk/Tools/Scripts/webkitpy/port/ios_unittest.py	2017-03-01 19:47:21 UTC (rev 213236)
@@ -22,7 +22,7 @@
 
 import time
 
-from webkitpy.port.ios import IOSSimulatorPort
+from webkitpy.port.ios_simulator import IOSSimulatorPort
 from webkitpy.port import darwin_testcase
 from webkitpy.common.system.filesystem_mock import MockFileSystem
 from webkitpy.common.system.outputcapture import OutputCapture

Modified: trunk/Tools/Scripts/webkitpy/port/simulator_process.py (213235 => 213236)


--- trunk/Tools/Scripts/webkitpy/port/simulator_process.py	2017-03-01 19:41:56 UTC (rev 213235)
+++ trunk/Tools/Scripts/webkitpy/port/simulator_process.py	2017-03-01 19:47:21 UTC (rev 213236)
@@ -58,7 +58,7 @@
 
     def __init__(self, port_obj, name, cmd, env=None, universal_newlines=False, treat_no_data_as_crash=False, worker_number=None):
         self._bundle_id = port_obj.app_identifier_from_bundle(cmd[0])
-        self._device = Simulator(port_obj.host).find_device_by_udid(port_obj.device_id_for_worker_number(worker_number))
+        self._device = port_obj.device_for_worker_number(worker_number)
         if not self._device.install_app(cmd[0], env):
             raise RuntimeError('Failed to install app {} on simulator device {}'.format(cmd[0], self._device.udid))
         env['IPC_IDENTIFIER'] = self._bundle_id + '-' + self._device.udid

Modified: trunk/Tools/Scripts/webkitpy/xcode/simulator.py (213235 => 213236)


--- trunk/Tools/Scripts/webkitpy/xcode/simulator.py	2017-03-01 19:41:56 UTC (rev 213235)
+++ trunk/Tools/Scripts/webkitpy/xcode/simulator.py	2017-03-01 19:47:21 UTC (rev 213236)
@@ -181,7 +181,7 @@
     devices_re = re.compile(
         '\s*(?P<name>.+) \((?P<udid>[^)]+)\) \((?P<state>[^)]+)\)( \((?P<availability>[^)]+)\))?')
 
-    _managed_devices = {}
+    managed_devices = {}
     Device = None
 
     def __init__(self, host=None):
@@ -216,21 +216,21 @@
     def create_device(number, device_type, runtime):
         device = Simulator().lookup_or_create_device(device_type.name + ' WebKit Tester' + str(number), device_type, runtime)
         _log.debug('created device {} {}'.format(number, device))
-        assert(len(Simulator._managed_devices) == number)
-        Simulator._managed_devices[number] = device
+        assert(len(Simulator.managed_devices) == number)
+        Simulator.managed_devices[number] = device
 
     @staticmethod
     def remove_device(number):
-        if not Simulator._managed_devices[number]:
+        if not Simulator.managed_devices[number]:
             return
-        device_udid = Simulator._managed_devices[number].udid
+        device_udid = Simulator.managed_devices[number].udid
         _log.debug('removing device {} {}'.format(number, device_udid))
-        del Simulator._managed_devices[number]
+        del Simulator.managed_devices[number]
         Simulator.delete_device(device_udid)
 
     @staticmethod
     def device_number(number):
-        return Simulator._managed_devices[number]
+        return Simulator.managed_devices[number]
 
     @staticmethod
     def device_state_description(state):
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to