# Copyright (C) 2014-2019 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 webkitcorepy import Version from webkitpy.common.memoized import memoized from webkitpy.common.system.crashlogs import CrashLogs from webkitpy.port.config import apple_additions from webkitpy.port.ios import IOSPort _log = logging.getLogger(__name__) class IOSDevicePort(IOSPort): port_name = 'ios-device' 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 in this configuration' NO_DEVICE_MANAGER = NO_ON_DEVICE_TESTING def _driver_class(self): if apple_additions(): return apple_additions().device_driver() return super(IOSDevicePort, self)._driver_class() @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(cls.SDK) if not iphoneos_sdk_version: raise Exception("Please install the iOS SDK.") port_name = port_name + '-' + str(iphoneos_sdk_version.major) return port_name def path_to_crash_logs(self): if not apple_additions(): raise RuntimeError(self.NO_ON_DEVICE_TESTING) return apple_additions().device_crash_log_path() def _look_for_all_crash_logs_in_log_dir(self, newer_than): log_list = {} 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(newer_than=newer_than)) return log_list def _get_crash_log(self, name, pid, stdout, stderr, newer_than, time_fn=None, sleep_fn=None, wait_for_log=True, target_host=None): if target_host: 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.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) return (stderr, None) def supports_layout_tests(self): return self.DEVICE_MANAGER is not None @memoized def device_version(self): if self.get_option('version'): return Version.from_string(self.get_option('version')) if not self.DEVICE_MANAGER: raise RuntimeError(self.NO_ON_DEVICE_TESTING) if not self.DEVICE_MANAGER.available_devices(host=self.host): raise RuntimeError('No devices are available') version = None for device in self.DEVICE_MANAGER.available_devices(host=self.host): if not device.platform.is_ios(): continue if not version: version = device.platform.os_version else: if device.platform.os_version != version: raise RuntimeError('Multiple connected devices have different iOS versions') return version # FIXME: These need device implementations . def check_for_leaks(self, process_name, process_id): pass def operating_system(self): return 'ios-device' def clean_up_test_run(self): super(IOSDevicePort, self).clean_up_test_run() apple_additions().device_clean_up_test_run(self, self._path_to_driver(), self._build_path())