webkitpy: Refactor port code for devices
[WebKit-https.git] / Tools / Scripts / webkitpy / port / ios_simulator.py
1 # Copyright (C) 2014-2018 Apple Inc. All rights reserved.
2 #
3 # Redistribution and use in source and binary forms, with or without
4 # modification, are permitted provided that the following conditions
5 # are met:
6 # 1.  Redistributions of source code must retain the above copyright
7 #     notice, this list of conditions and the following disclaimer.
8 # 2.  Redistributions in binary form must reproduce the above copyright
9 #     notice, this list of conditions and the following disclaimer in the
10 #     documentation and/or other materials provided with the distribution.
11 #
12 # THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND
13 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
14 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
15 # DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR
16 # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
17 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
18 # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
19 # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
20 # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
21 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22
23 import logging
24
25 from webkitpy.common.memoized import memoized
26 from webkitpy.common.version import Version
27 from webkitpy.port.config import apple_additions
28 from webkitpy.port.ios import IOSPort
29 from webkitpy.xcode.device_type import DeviceType
30 from webkitpy.xcode.simulated_device import DeviceRequest, SimulatedDeviceManager
31
32
33 _log = logging.getLogger(__name__)
34
35
36 class IOSSimulatorPort(IOSPort):
37     port_name = "ios-simulator"
38
39     FUTURE_VERSION = 'future'
40     ARCHITECTURES = ['x86_64', 'i386']
41     DEFAULT_ARCHITECTURE = 'x86_64'
42
43     DEVICE_MANAGER = SimulatedDeviceManager
44
45     DEFAULT_DEVICE_CLASS = 'iPhone SE'
46     CUSTOM_DEVICE_CLASSES = ['iPad', 'iPhone 7']
47     SDK = apple_additions().get_sdk('iphonesimulator') if apple_additions() else 'iphonesimulator'
48
49     def __init__(self, host, port_name, **kwargs):
50         super(IOSSimulatorPort, self).__init__(host, port_name, **kwargs)
51
52         optional_device_class = self.get_option('device_class')
53         self._device_class = optional_device_class if optional_device_class else self.DEFAULT_DEVICE_CLASS
54         _log.debug('IOSSimulatorPort _device_class is %s', self._device_class)
55
56     @staticmethod
57     def _version_from_name(name):
58         if len(name.split('-')) > 2 and name.split('-')[2].isdigit():
59             return Version.from_string(name.split('-')[2])
60         return None
61
62     @memoized
63     def ios_version(self):
64         if self.get_option('version'):
65             return Version.from_string(self.get_option('version'))
66         return IOSSimulatorPort._version_from_name(self._name) if IOSSimulatorPort._version_from_name(self._name) else self.host.platform.xcode_sdk_version('iphonesimulator')
67
68     @memoized
69     def default_child_processes(self):
70         def booted_ios_devices_filter(device):
71             if not device.platform_device.is_booted_or_booting():
72                 return False
73             return device.platform_device.device_type in DeviceType(software_variant='iOS',
74                                                                     software_version=self.ios_version())
75
76         if not self.get_option('dedicated_simulators', False):
77             num_booted_sims = len(SimulatedDeviceManager.device_by_filter(booted_ios_devices_filter, host=self.host))
78             if num_booted_sims:
79                 return num_booted_sims
80         return SimulatedDeviceManager.max_supported_simulators(self.host)
81
82     def _set_device_class(self, device_class):
83         self._device_class = device_class if device_class else self.DEFAULT_DEVICE_CLASS
84
85     def _create_devices(self, device_class):
86         self._set_device_class(device_class)
87         device_type = DeviceType.from_string(self._device_class, self.ios_version())
88
89         _log.debug('\nCreating devices for {}'.format(device_type))
90
91         request = DeviceRequest(
92             device_type,
93             use_booted_simulator=not self.get_option('dedicated_simulators', False),
94             use_existing_simulator=False,
95             allow_incomplete_match=True,
96         )
97         SimulatedDeviceManager.initialize_devices([request] * self.child_processes(), self.host)
98
99     def clean_up_test_run(self):
100         super(IOSSimulatorPort, self).clean_up_test_run()
101         _log.debug("clean_up_test_run")
102
103         SimulatedDeviceManager.tear_down(self.host)
104
105     def environment_for_api_tests(self):
106         no_prefix = super(IOSSimulatorPort, self).environment_for_api_tests()
107         result = {}
108         SIMCTL_ENV_PREFIX = 'SIMCTL_CHILD_'
109         for value in no_prefix:
110             if not value.startswith(SIMCTL_ENV_PREFIX):
111                 result[SIMCTL_ENV_PREFIX + value] = no_prefix[value]
112             else:
113                 result[value] = no_prefix[value]
114         return result
115
116     def setup_environ_for_server(self, server_name=None):
117         _log.debug("setup_environ_for_server")
118         env = super(IOSSimulatorPort, self).setup_environ_for_server(server_name)
119         if server_name == self.driver_name():
120             if self.get_option('leaks'):
121                 env['MallocStackLogging'] = '1'
122                 env['__XPC_MallocStackLogging'] = '1'
123                 env['MallocScribble'] = '1'
124                 env['__XPC_MallocScribble'] = '1'
125         return env
126
127     def operating_system(self):
128         return 'ios-simulator'
129
130     def check_sys_deps(self):
131         target_device_type = DeviceType(software_variant='iOS', software_version=self.ios_version())
132         for device in SimulatedDeviceManager.available_devices(self.host):
133             if device.platform_device.device_type in target_device_type:
134                 return super(IOSSimulatorPort, self).check_sys_deps()
135         _log.error('No Simulated device matching "{}" defined in Xcode iOS SDK'.format(str(target_device_type)))
136         return False
137
138     def reset_preferences(self):
139         _log.debug("reset_preferences")
140         SimulatedDeviceManager.tear_down(self.host)
141
142     def nm_command(self):
143         return self.xcrun_find('nm')
144
145     @property
146     @memoized
147     def developer_dir(self):
148         return self._executive.run_command(['xcode-select', '--print-path']).rstrip()
149
150     def logging_patterns_to_strip(self):
151         return []
152
153     def stderr_patterns_to_strip(self):
154         return []