# Copyright (C) 2017-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 socket class Device(object): def __init__(self, platform_device): self.platform_device = platform_device self.listening_socket = None def listening_port(self): if not self.listening_socket: return None return self.listening_socket.getsockname()[1] def install_app(self, app_path, env=None): return self.platform_device.install_app(app_path, env) def install_dylibs(self, path_to_dylibs): if hasattr(self.platform_device, 'install_dylibs'): return self.platform_device.install_dylibs(path_to_dylibs=path_to_dylibs) return True def launch_app(self, bundle_id, args, env=None): return self.platform_device.launch_app(bundle_id, args, env) def prepare_for_testing(self, ports_to_forward, test_app_bundle_id, layout_test_directory): if not self.listening_socket: self.listening_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.listening_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self.listening_socket.bind(('127.0.0.1', 0)) if hasattr(self.platform_device, 'prepare_for_testing'): self.platform_device.prepare_for_testing( ports_to_forward=ports_to_forward + [self.listening_port()], test_app_bundle_id=test_app_bundle_id, layout_test_directory=layout_test_directory, ) def finished_testing(self): if hasattr(self.platform_device, 'finished_testing'): self.platform_device.finished_testing() self.listening_socket = None def symbolicate_crash_log_if_needed(self, path): if hasattr(self.platform_device, 'symbolicate_crash_log_if_needed'): return self.platform_device.symbolicate_crash_log_if_needed(path) return self.filesystem.read_text_file(path) def release_worker_resources(self): if hasattr(self.platform_device, 'release_worker_resources'): return self.platform_device.release_worker_resources() return None @property def executive(self): return self.platform_device.executive @property def filesystem(self): return self.platform_device.filesystem @property def user(self): return self.platform_device.user @property def platform(self): return self.platform_device.platform @property def workspace(self): return self.platform_device.workspace @property def udid(self): return self.platform_device.udid @property def device_type(self): return self.platform_device.device_type @property def build_version(self): return self.platform_device.build_version def __nonzero__(self): return self.platform_device is not None def __eq__(self, other): return self.udid == other.udid def __ne__(self, other): return not self.__eq__(other) def __repr__(self): return u'{}'.format(self.platform_device) def __hash__(self): return hash(self.udid)