webkitpy: Refactor port code for devices
authorjbedard@apple.com <jbedard@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 14 Nov 2018 16:24:59 +0000 (16:24 +0000)
committerjbedard@apple.com <jbedard@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 14 Nov 2018 16:24:59 +0000 (16:24 +0000)
https://bugs.webkit.org/show_bug.cgi?id=191568
<rdar://problem/46005821>

Reviewed by Alex Christensen.

watchOS and iOS device ports share many characteristics in testing, mostly due
to the fact that both are devices.

* Scripts/webkitpy/port/device_port.py: Added.
(DevicePort): Add base class that all simulated/physical device ports share.
(DevicePort.__init__):
(DevicePort.driver_cmd_line_for_logging): Moved from iOS port.
(DevicePort._generate_all_test_configurations): Ditto.
(DevicePort.child_processes): Ditto.
(DevicePort.driver_name): Ditto.
(DevicePort.target_host): Generalize worker access to attached devices and
simulated devices based on the device manager.
(DevicePort.devices): Return a list of all devices associated with this port.
(DevicePort._create_devices):
(DevicePort._build_driver_flags): Moved from iOSSimulatorPort/iOSDevicePort.
(DevicePort._install): Moved from iOS port.
(DevicePort.setup_test_run): Ditto.
(DevicePort.clean_up_test_run): Ditto.
(DevicePort.did_spawn_worker): Ditto.
(DevicePort.setup_environ_for_server): Ditto.
* Scripts/webkitpy/port/ios.py:
(IOSPort):
(IOSPort._device_for_worker_number_map): Replaced by DevicePort.devices().
(IOSPort.driver_cmd_line_for_logging): Moved to DevicePort.
(IOSPort.driver_name): Ditto.
(IOSPort._generate_all_test_configurations): Ditto.
(IOSPort.child_processes): Ditto.
(IOSPort._testing_device): Ditto.
(IOSPort.target_host): Ditto.
(IOSPort._create_devices): Ditto.
(IOSPort.setup_test_run): Ditto.
(IOSPort.clean_up_test_run): Ditto.
(IOSPort.did_spawn_worker): Ditto.
* Scripts/webkitpy/port/ios_device.py:
(IOSDevicePort): IOSDevicePort uses a device manager from apple_additions.
(IOSDevicePort._look_for_all_crash_logs_in_log_dir): Use DevicePort.devices().
(IOSDevicePort._get_crash_log): Ditto.
(IOSDevicePort.ios_version): Ditto.
(IOSDevicePort._create_devices): Ditto.
(IOSDevicePort._device_for_worker_number_map): Replaced by DevicePort.devices().
(IOSSimulatorPort._build_driver_flags): Moved to DevicePort.
* Scripts/webkitpy/port/ios_device_unittest.py:
(IOSDeviceTest.test_get_crash_log):
* Scripts/webkitpy/port/ios_simulator.py:
(IOSSimulatorPort): IOSSimulatorPort uses the SimulatedDeviceManager.
(IOSSimulatorPort._create_devices): Clean up logging statement.
(IOSSimulatorPort.setup_environ_for_server): Some of environment set-up is shared
across all devices.
(IOSSimulatorPort._device_for_worker_number_map): Replaced by DevicePort.devices().
(IOSSimulatorPort._build_driver_flags): Moved to DevicePort.
* Scripts/webkitpy/port/ios_simulator_unittest.py:
(IOSSimulatorTest.test_32bit):
(IOSSimulatorTest.test_64bit):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@238177 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Tools/ChangeLog
Tools/Scripts/webkitpy/port/device_port.py [new file with mode: 0644]
Tools/Scripts/webkitpy/port/ios.py
Tools/Scripts/webkitpy/port/ios_device.py
Tools/Scripts/webkitpy/port/ios_device_unittest.py
Tools/Scripts/webkitpy/port/ios_simulator.py
Tools/Scripts/webkitpy/port/ios_simulator_unittest.py

index 3005fc5..a8c2c1a 100644 (file)
@@ -1,3 +1,65 @@
+2018-11-14  Jonathan Bedard  <jbedard@apple.com>
+
+        webkitpy: Refactor port code for devices
+        https://bugs.webkit.org/show_bug.cgi?id=191568
+        <rdar://problem/46005821>
+
+        Reviewed by Alex Christensen.
+
+        watchOS and iOS device ports share many characteristics in testing, mostly due
+        to the fact that both are devices.
+
+        * Scripts/webkitpy/port/device_port.py: Added.
+        (DevicePort): Add base class that all simulated/physical device ports share.
+        (DevicePort.__init__):
+        (DevicePort.driver_cmd_line_for_logging): Moved from iOS port.
+        (DevicePort._generate_all_test_configurations): Ditto.
+        (DevicePort.child_processes): Ditto.
+        (DevicePort.driver_name): Ditto.
+        (DevicePort.target_host): Generalize worker access to attached devices and
+        simulated devices based on the device manager.
+        (DevicePort.devices): Return a list of all devices associated with this port.
+        (DevicePort._create_devices):
+        (DevicePort._build_driver_flags): Moved from iOSSimulatorPort/iOSDevicePort.
+        (DevicePort._install): Moved from iOS port.
+        (DevicePort.setup_test_run): Ditto.
+        (DevicePort.clean_up_test_run): Ditto.
+        (DevicePort.did_spawn_worker): Ditto.
+        (DevicePort.setup_environ_for_server): Ditto.
+        * Scripts/webkitpy/port/ios.py:
+        (IOSPort):
+        (IOSPort._device_for_worker_number_map): Replaced by DevicePort.devices().
+        (IOSPort.driver_cmd_line_for_logging): Moved to DevicePort.
+        (IOSPort.driver_name): Ditto.
+        (IOSPort._generate_all_test_configurations): Ditto.
+        (IOSPort.child_processes): Ditto.
+        (IOSPort._testing_device): Ditto.
+        (IOSPort.target_host): Ditto.
+        (IOSPort._create_devices): Ditto.
+        (IOSPort.setup_test_run): Ditto.
+        (IOSPort.clean_up_test_run): Ditto.
+        (IOSPort.did_spawn_worker): Ditto.
+        * Scripts/webkitpy/port/ios_device.py:
+        (IOSDevicePort): IOSDevicePort uses a device manager from apple_additions.
+        (IOSDevicePort._look_for_all_crash_logs_in_log_dir): Use DevicePort.devices().
+        (IOSDevicePort._get_crash_log): Ditto.
+        (IOSDevicePort.ios_version): Ditto.
+        (IOSDevicePort._create_devices): Ditto.
+        (IOSDevicePort._device_for_worker_number_map): Replaced by DevicePort.devices().
+        (IOSSimulatorPort._build_driver_flags): Moved to DevicePort.
+        * Scripts/webkitpy/port/ios_device_unittest.py:
+        (IOSDeviceTest.test_get_crash_log):
+        * Scripts/webkitpy/port/ios_simulator.py:
+        (IOSSimulatorPort): IOSSimulatorPort uses the SimulatedDeviceManager.
+        (IOSSimulatorPort._create_devices): Clean up logging statement.
+        (IOSSimulatorPort.setup_environ_for_server): Some of environment set-up is shared
+        across all devices.
+        (IOSSimulatorPort._device_for_worker_number_map): Replaced by DevicePort.devices().
+        (IOSSimulatorPort._build_driver_flags): Moved to DevicePort.
+        * Scripts/webkitpy/port/ios_simulator_unittest.py:
+        (IOSSimulatorTest.test_32bit):
+        (IOSSimulatorTest.test_64bit):
+
 2018-11-14  Chris Dumez  <cdumez@apple.com>
 
         WebKit.WKHTTPCookieStoreWithoutProcessPool API test is failing with process prewarming is enabled
diff --git a/Tools/Scripts/webkitpy/port/device_port.py b/Tools/Scripts/webkitpy/port/device_port.py
new file mode 100644 (file)
index 0000000..a2b2076
--- /dev/null
@@ -0,0 +1,162 @@
+# Copyright (C) 2018 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 traceback
+
+from webkitpy.common.memoized import memoized
+from webkitpy.layout_tests.models.test_configuration import TestConfiguration
+from webkitpy.port.darwin import DarwinPort
+from webkitpy.port.simulator_process import SimulatorProcess
+
+
+_log = logging.getLogger(__name__)
+
+
+class DevicePort(DarwinPort):
+
+    DEVICE_MANAGER = None
+
+    def __init__(self, *args, **kwargs):
+        super(DevicePort, self).__init__(*args, **kwargs)
+        self._test_runner_process_constructor = SimulatorProcess
+        self._printing_cmd_line = False
+
+    def driver_cmd_line_for_logging(self):
+        # Avoid creating/connecting to devices just for command line logging.
+        self._printing_cmd_line = True
+        result = super(DevicePort, self).driver_cmd_line_for_logging()
+        self._printing_cmd_line = False
+        return result
+
+    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_name(), architecture=architecture, build_type=build_type))
+        return configurations
+
+    @memoized
+    def child_processes(self):
+        return int(self.get_option('child_processes'))
+
+    def driver_name(self):
+        if self.get_option('driver_name'):
+            return self.get_option('driver_name')
+        if self.get_option('webkit_test_runner'):
+            return 'WebKitTestRunnerApp.app'
+        return 'DumpRenderTree.app'
+
+    # A device is the target host for a specific worker number.
+    def target_host(self, worker_number=None):
+        if self._printing_cmd_line or worker_number is None:
+            return self.host
+        if self.DEVICE_MANAGER is None:
+            raise RuntimeError('No device manager for specified port')
+        if self.DEVICE_MANAGER.INITIALIZED_DEVICES is None:
+            raise RuntimeError('No initialized devices for testing')
+        return self.DEVICE_MANAGER.INITIALIZED_DEVICES[worker_number]
+
+    def devices(self):
+        if self.DEVICE_MANAGER is None:
+            return []
+        if self.DEVICE_MANAGER.INITIALIZED_DEVICES is None:
+            return []
+        return self.DEVICE_MANAGER.INITIALIZED_DEVICES
+
+    def _create_devices(self, device_class):
+        raise NotImplementedError
+
+    # Despite their names, these flags do not actually get passed all the way down to webkit-build.
+    def _build_driver_flags(self):
+        return ['--sdk', self.SDK] + (['ARCHS=%s' % self.architecture()] if self.architecture() else [])
+
+    def _install(self):
+        if not self.get_option('install'):
+            _log.debug('Skipping installation')
+            return
+
+        for i in xrange(self.child_processes()):
+            device = self.target_host(i)
+            _log.debug('Installing to {}'.format(device))
+            # Without passing DYLD_LIBRARY_PATH, libWebCoreTestSupport cannot be loaded and DRT/WKTR will crash pre-launch,
+            # leaving a crash log which will be picked up in results. DYLD_FRAMEWORK_PATH is needed to prevent an early crash.
+            if not device.install_app(self._path_to_driver(), {'DYLD_LIBRARY_PATH': self._build_path(), 'DYLD_FRAMEWORK_PATH': self._build_path()}):
+                raise RuntimeError('Failed to install app {} on device {}'.format(self._path_to_driver(), device.udid))
+            if not device.install_dylibs(self._build_path()):
+                raise RuntimeError('Failed to install dylibs at {} on device {}'.format(self._build_path(), device.udid))
+
+    def setup_test_run(self, device_class=None):
+        self._create_devices(device_class)
+        self._install()
+
+        for i in xrange(self.child_processes()):
+            host = self.target_host(i)
+            host.prepare_for_testing(
+                self.ports_to_forward(),
+                self.app_identifier_from_bundle(self._path_to_driver()),
+                self.layout_tests_dir(),
+            )
+            self._crash_logs_to_skip_for_host[host] = host.filesystem.files_under(self.path_to_crash_logs())
+
+    def clean_up_test_run(self):
+        super(DevicePort, self).clean_up_test_run()
+
+        # Best effort to let every device teardown before throwing any exceptions here.
+        # Failure to teardown devices can leave things in a bad state.
+        exception_list = []
+        for i in xrange(self.child_processes()):
+            device = self.target_host(i)
+            if not device:
+                continue
+            try:
+                device.finished_testing()
+            except BaseException as e:
+                trace = traceback.format_exc()
+                if isinstance(e, Exception):
+                    exception_list.append([e, trace])
+                else:
+                    exception_list.append([Exception('Exception while tearing down {}'.format(device)), trace])
+
+        if len(exception_list) == 1:
+            raise
+        if len(exception_list) > 1:
+            print('\n')
+            for exception in exception_list:
+                _log.error('{} raised: {}'.format(exception[0].__class__.__name__, exception[0]))
+                _log.error(exception[1])
+                _log.error('--------------------------------------------------')
+
+            raise RuntimeError('Multiple failures when teardown devices')
+
+    def did_spawn_worker(self, worker_number):
+        super(DevicePort, self).did_spawn_worker(worker_number)
+
+        self.target_host(worker_number).release_worker_resources()
+
+    def setup_environ_for_server(self, server_name=None):
+        env = super(DevicePort, self).setup_environ_for_server(server_name)
+        if server_name == self.driver_name() and 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
index 7291c94..19a5e6a 100644 (file)
@@ -28,13 +28,13 @@ from webkitpy.common.version import Version
 from webkitpy.common.version_name_map import VersionNameMap, INTERNAL_TABLE
 from webkitpy.layout_tests.models.test_configuration import TestConfiguration
 from webkitpy.port.config import apple_additions
-from webkitpy.port.darwin import DarwinPort
+from webkitpy.port.device_port import DevicePort
 from webkitpy.port.simulator_process import SimulatorProcess
 
 _log = logging.getLogger(__name__)
 
 
-class IOSPort(DarwinPort):
+class IOSPort(DevicePort):
     port_name = "ios"
 
     CURRENT_VERSION = Version(12)
@@ -44,50 +44,11 @@ class IOSPort(DarwinPort):
         self._test_runner_process_constructor = SimulatorProcess
         self._printing_cmd_line = False
 
-    def _device_for_worker_number_map(self):
-        raise NotImplementedError
-
     def version_name(self):
         if self._os_version is None:
             return None
         return VersionNameMap.map(self.host.platform).to_name(self._os_version, platform=IOSPort.port_name)
 
-    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
-        return result
-
-    def driver_name(self):
-        if self.get_option('driver_name'):
-            return self.get_option('driver_name')
-        if self.get_option('webkit_test_runner'):
-            return 'WebKitTestRunnerApp.app'
-        return 'DumpRenderTree.app'
-
-    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_name(), architecture=architecture, build_type=build_type))
-        return configurations
-
-    def child_processes(self):
-        return int(self.get_option('child_processes'))
-
-    def _testing_device(self, number):
-        device = self._device_for_worker_number_map()[number]
-        if not device:
-            raise RuntimeError('Device at {} could not be found'.format(number))
-        return device
-
-    # A device is the target host for a specific worker number.
-    def target_host(self, worker_number=None):
-        if self._printing_cmd_line or worker_number is None:
-            return self.host
-        return self._testing_device(worker_number)
-
     @memoized
     def default_baseline_search_path(self):
         wk_string = 'wk1'
@@ -151,64 +112,3 @@ class IOSPort(DarwinPort):
 
     def ios_version(self):
         raise NotImplementedError
-
-    def _create_devices(self, device_class):
-        raise NotImplementedError
-
-    def setup_test_run(self, device_class=None):
-        self._create_devices(device_class)
-
-        if self.get_option('install'):
-            for i in xrange(self.child_processes()):
-                device = self.target_host(i)
-                _log.debug('Installing to {}'.format(device))
-                # Without passing DYLD_LIBRARY_PATH, libWebCoreTestSupport cannot be loaded and DRT/WKTR will crash pre-launch,
-                # leaving a crash log which will be picked up in results. DYLD_FRAMEWORK_PATH is needed to prevent an early crash.
-                if not device.install_app(self._path_to_driver(), {'DYLD_LIBRARY_PATH': self._build_path(), 'DYLD_FRAMEWORK_PATH': self._build_path()}):
-                    raise RuntimeError('Failed to install app {} on device {}'.format(self._path_to_driver(), device.udid))
-                if not device.install_dylibs(self._build_path()):
-                    raise RuntimeError('Failed to install dylibs at {} on device {}'.format(self._build_path(), device.udid))
-        else:
-            _log.debug('Skipping installation')
-
-        for i in xrange(self.child_processes()):
-            host = self.target_host(i)
-            host.prepare_for_testing(
-                self.ports_to_forward(),
-                self.app_identifier_from_bundle(self._path_to_driver()),
-                self.layout_tests_dir(),
-            )
-            self._crash_logs_to_skip_for_host[host] = host.filesystem.files_under(self.path_to_crash_logs())
-
-    def clean_up_test_run(self):
-        super(IOSPort, self).clean_up_test_run()
-
-        # Best effort to let every device teardown before throwing any exceptions here.
-        # Failure to teardown devices can leave things in a bad state.
-        exception_list = []
-        for i in xrange(self.child_processes()):
-            device = self.target_host(i)
-            try:
-                if device:
-                    device.finished_testing()
-            except BaseException as e:
-                trace = traceback.format_exc()
-                if isinstance(e, Exception):
-                    exception_list.append([e, trace])
-                else:
-                    exception_list.append([Exception('Exception tearing down {}'.format(device)), trace])
-        if len(exception_list) == 1:
-            raise
-        elif len(exception_list) > 1:
-            print('\n')
-            for exception in exception_list:
-                _log.error('{} raised: {}'.format(exception[0].__class__.__name__, exception[0]))
-                _log.error(exception[1])
-                _log.error('--------------------------------------------------')
-
-            raise RuntimeError('Multiple failures when teardown devices')
-
-    def did_spawn_worker(self, worker_number):
-        super(IOSPort, self).did_spawn_worker(worker_number)
-
-        self.target_host(worker_number).release_worker_resources()
index 67bc5d1..641215a 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2014-2017 Apple Inc. All rights reserved.
+# Copyright (C) 2014-2018 Apple Inc. All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
 # modification, are permitted provided that the following conditions
@@ -25,7 +25,6 @@ import logging
 from webkitpy.common.memoized import memoized
 from webkitpy.common.system.crashlogs import CrashLogs
 from webkitpy.common.version import Version
-from webkitpy.common.version_name_map import VersionNameMap
 from webkitpy.port.config import apple_additions
 from webkitpy.port.ios import IOSPort
 
@@ -38,6 +37,9 @@ class IOSDevicePort(IOSPort):
     ARCHITECTURES = ['armv7', 'armv7s', 'arm64']
     DEFAULT_ARCHITECTURE = 'arm64'
     VERSION_FALLBACK_ORDER = ['ios-7', 'ios-8', 'ios-9', 'ios-10']
+
+    DEVICE_MANAGER = apple_additions().device_manager() if apple_additions() else None
+
     SDK = apple_additions().get_sdk('iphoneos') if apple_additions() else 'iphoneos'
     NO_ON_DEVICE_TESTING = 'On-device testing is not supported on this machine'
 
@@ -47,11 +49,6 @@ class IOSDevicePort(IOSPort):
             return apple_additions().ios_device_default_child_processes(self)
         return 1
 
-    def _device_for_worker_number_map(self):
-        if not apple_additions():
-            raise RuntimeError(self.NO_ON_DEVICE_TESTING)
-        return apple_additions().ios_device_for_worker_number_map(self)
-
     def _driver_class(self):
         if apple_additions():
             return apple_additions().ios_device_driver()
@@ -73,7 +70,7 @@ class IOSDevicePort(IOSPort):
 
     def _look_for_all_crash_logs_in_log_dir(self, newer_than):
         log_list = {}
-        for device in self._device_for_worker_number_map():
+        for device in self.devices():
             crash_log = CrashLogs(device, self.path_to_crash_logs(), crash_logs_to_skip=self._crash_logs_to_skip_for_host.get(device, []))
             log_list.update(crash_log.find_all_logs(include_errors=True, newer_than=newer_than))
         return log_list
@@ -83,7 +80,7 @@ class IOSDevicePort(IOSPort):
             return super(IOSDevicePort, self)._get_crash_log(name, pid, stdout, stderr, newer_than, time_fn=time_fn, sleep_fn=sleep_fn, wait_for_log=wait_for_log, target_host=target_host)
 
         # We need to search every device since one was not specified.
-        for device in self._device_for_worker_number_map():
+        for device in self.devices():
             stderr_out, crashlog = super(IOSDevicePort, self)._get_crash_log(name, pid, stdout, stderr, newer_than, time_fn=time_fn, sleep_fn=sleep_fn, wait_for_log=False, target_host=device)
             if crashlog:
                 return (stderr, crashlog)
@@ -97,10 +94,10 @@ class IOSDevicePort(IOSPort):
         if not apple_additions():
             raise RuntimeError(self.NO_ON_DEVICE_TESTING)
 
-        if not self._device_for_worker_number_map():
+        if not self.devices():
             raise RuntimeError('No devices are available')
         version = None
-        for device in self._device_for_worker_number_map():
+        for device in self.devices():
             if not version:
                 version = device.platform.os_version
             else:
@@ -112,17 +109,13 @@ class IOSDevicePort(IOSPort):
     def check_for_leaks(self, process_name, process_pid):
         pass
 
-    # Despite their names, these flags do not actually get passed all the way down to webkit-build.
-    def _build_driver_flags(self):
-        return ['--sdk', self.SDK] + (['ARCHS=%s' % self.architecture()] if self.architecture() else [])
-
     def operating_system(self):
         return 'ios-device'
 
     def _create_devices(self, device_class):
         if not apple_additions():
             raise RuntimeError(self.NO_ON_DEVICE_TESTING)
-        if not self._device_for_worker_number_map():
+        if not self.devices():
             raise RuntimeError('No devices are available for testing')
 
         if self.default_child_processes() < self.child_processes():
index 67d7b7b..a3984b2 100644 (file)
@@ -83,8 +83,7 @@ class IOSDeviceTest(ios_testcase.IOSTest):
 
     def test_get_crash_log(self):
         port = self.make_port(port_name=self.port_name)
-        with self.assertRaises(RuntimeError):
-            port._get_crash_log('DumpRenderTree', 1234, None, None, time.time(), wait_for_log=False)
+        self.assertEqual((None, None), port._get_crash_log('DumpRenderTree', 1234, None, None, time.time(), wait_for_log=False))
 
     def test_layout_test_searchpath_with_apple_additions(self):
         with port_testcase.bind_mock_apple_additions():
index b803d9e..e8f63fe 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2014-2017 Apple Inc. All rights reserved.
+# Copyright (C) 2014-2018 Apple Inc. All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
 # modification, are permitted provided that the following conditions
@@ -37,9 +37,11 @@ class IOSSimulatorPort(IOSPort):
     port_name = "ios-simulator"
 
     FUTURE_VERSION = 'future'
-    ARCHITECTURES = ['x86_64', 'x86']
+    ARCHITECTURES = ['x86_64', 'i386']
     DEFAULT_ARCHITECTURE = 'x86_64'
 
+    DEVICE_MANAGER = SimulatedDeviceManager
+
     DEFAULT_DEVICE_CLASS = 'iPhone SE'
     CUSTOM_DEVICE_CLASSES = ['iPad', 'iPhone 7']
     SDK = apple_additions().get_sdk('iphonesimulator') if apple_additions() else 'iphonesimulator'
@@ -51,9 +53,6 @@ class IOSSimulatorPort(IOSPort):
         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)
 
-    def _device_for_worker_number_map(self):
-        return SimulatedDeviceManager.INITIALIZED_DEVICES
-
     @staticmethod
     def _version_from_name(name):
         if len(name.split('-')) > 2 and name.split('-')[2].isdigit():
@@ -80,11 +79,6 @@ class IOSSimulatorPort(IOSPort):
                 return num_booted_sims
         return SimulatedDeviceManager.max_supported_simulators(self.host)
 
-    def _build_driver_flags(self):
-        archs = ['ARCHS=i386'] if self.architecture() == 'x86' else []
-        sdk = ['--sdk', self.SDK]
-        return archs + sdk
-
     def _set_device_class(self, device_class):
         self._device_class = device_class if device_class else self.DEFAULT_DEVICE_CLASS
 
@@ -92,8 +86,7 @@ class IOSSimulatorPort(IOSPort):
         self._set_device_class(device_class)
         device_type = DeviceType.from_string(self._device_class, self.ios_version())
 
-        _log.debug('')
-        _log.debug('creating devices for {}'.format(device_type))
+        _log.debug('\nCreating devices for {}'.format(device_type))
 
         request = DeviceRequest(
             device_type,
@@ -129,10 +122,6 @@ class IOSSimulatorPort(IOSPort):
                 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):
index 60a43fd..f59ba46 100644 (file)
@@ -52,15 +52,15 @@ class IOSSimulatorTest(ios_testcase.IOSTest):
         self.assertEqual('ios-simulator', self.make_port().operating_system())
 
     def test_32bit(self):
-        port = self.make_port(options=MockOptions(architecture='x86'))
+        port = self.make_port(options=MockOptions(architecture='i386'))
 
         def run_script(script, args=None, env=None):
             self.args = args
 
         port._run_script = run_script
-        self.assertEqual(port.architecture(), 'x86')
+        self.assertEqual(port.architecture(), 'i386')
         port._build_driver()
-        self.assertEqual(self.args, ['ARCHS=i386', '--sdk', 'iphonesimulator'])
+        self.assertEqual(self.args, ['--sdk', 'iphonesimulator', 'ARCHS=i386'])
 
     def test_64bit(self):
         # Apple Mac port is 64-bit by default
@@ -72,7 +72,7 @@ class IOSSimulatorTest(ios_testcase.IOSTest):
 
         port._run_script = run_script
         port._build_driver()
-        self.assertEqual(self.args, ['--sdk', 'iphonesimulator'])
+        self.assertEqual(self.args, ['--sdk', 'iphonesimulator', 'ARCHS=x86_64'])
 
     def test_sdk_name(self):
         port = self.make_port()