def add_companion(self, companion: CompanionInfo) -> None: self._udid_companion_map[companion.udid] = companion self._logger.info(f"Added a companion: {companion}") if companion.udid in self._udid_target_map: target = self._udid_target_map[companion.udid] self._udid_target_map[companion.udid] = TargetDescription( udid=target.udid, name=target.name, state=target.state, target_type=target.target_type, os_version=target.os_version, architecture=target.architecture, companion_info=companion, screen_dimensions=target.screen_dimensions, ) self._logger.info( f"Assigned the companion to target: {companion.udid}") else: self._udid_target_map[companion.udid] = TargetDescription( udid=companion.udid, name="", state=None, target_type=None, os_version=None, architecture=None, companion_info=companion, screen_dimensions=None, )
async def _read_stream(self, stream: StreamReader) -> None: while True: line = await stream.readline() if line: update = json.loads(line.decode()) if "initial_state_ended" in update: end_of_initial_state = update["initial_state_ended"] if end_of_initial_state: logging.debug(f"Initial state received from notifier") break else: raise CompanionTailerException( "Unexpected output from companion") self.companion_manager.update_target( TargetDescription( udid=update["udid"], name=update["name"], state=update["state"], target_type=update["type"], os_version=update["os_version"], architecture=update["architecture"], companion_info=None, screen_dimensions=None, )) else: break
def target_description_from_dictionary(parsed: Dict[str, Any]) -> TargetDescription: return TargetDescription( udid=parsed["udid"], name=parsed["name"], model=parsed.get("model"), state=parsed.get("state"), target_type=parsed.get("type"), os_version=parsed.get("os_version"), architecture=parsed.get("architecture"), companion_info=None, screen_dimensions=None, device=parsed.get("device"), )
def target_to_py(target: GrpcTargetDescription, companion: CompanionInfo) -> TargetDescription: return TargetDescription( udid=target.udid, name=target.name, screen_dimensions=(screen_dimensions_to_py(target.screen_dimensions) if target.screen_dimensions else None), state=target.state, target_type=target.target_type, os_version=target.os_version, architecture=target.architecture, companion_info=companion, )
def targets(self) -> List[TargetDescription]: return [ TargetDescription( udid=target.udid, state=target.state, target_type=target.target_type, name=target.name or "", os_version=target.os_version, architecture=target.architecture, companion_info=target.companion_info, screen_dimensions=None, ) for target in self._udid_target_map.values() ]
def target_to_py(target: GrpcTargetDescription, companion_info: Optional[CompanionInfo]) -> TargetDescription: grpc_companion_info = target.companion_info return TargetDescription( udid=target.udid, name=target.name, screen_dimensions=(screen_dimensions_to_py(target.screen_dimensions) if target.screen_dimensions else None), state=target.state, target_type=target.target_type, os_version=target.os_version, architecture=target.architecture, companion_info=(companion_info if companion_info else companion_to_py( grpc_companion_info) if grpc_companion_info else None), )
def target_to_py(target: GrpcTargetDescription, companion: CompanionInfo) -> TargetDescription: return TargetDescription( udid=target.udid, name=target.name, screen_dimensions=(screen_dimensions_to_py(target.screen_dimensions) if target.screen_dimensions else None), state=target.state, target_type=target.target_type, os_version=target.os_version, architecture=target.architecture, companion_info=companion, extended=(json.loads(target.extended.decode()) if len(target.extended) else {}), diagnostics=(json.loads(target.diagnostics.decode()) if len(target.diagnostics) else {}), )
async def test_add_companion_assigns_to_target(self) -> None: companion_manager = CompanionManager(logger=mock.MagicMock()) companion_manager.update_target( TargetDescription( udid="asdasda", name="iPhone", state="Booted", target_type="simulator", os_version="iOS 11.4", architecture="x86_64", companion_info=None, screen_dimensions=None, )) companion_manager.add_companion( CompanionInfo(udid="asdasda", host="foohost", port=123, is_local=False)) assert companion_manager._udid_target_map["asdasda"].companion_info
def mock_target( udid: str = "udid", name: str = "name", screen_dimensions: None = None, state: str = "state", target_type: str = "type", os_version: str = "os_version", architecture: str = "arch", companion_info: None = None, ) -> TargetDescription: return TargetDescription( udid=udid, name=name, screen_dimensions=screen_dimensions, state=state, target_type=target_type, os_version=os_version, architecture=architecture, companion_info=companion_info, )
async def test_read_stream(self) -> None: class StreamMock: i = 0 lines: List[bytes] = [ json.dumps({ "udid": "udid", "state": "state", "type": "type", "name": "name", "os_version": "os_version", "architecture": "architecture", }).encode("utf-8"), json.dumps({ "initial_state_ended": True }).encode("utf-8"), ] async def readline(self) -> bytes: result = self.lines[self.i] self.i += 1 return result manager = CompanionManager(mock.MagicMock()) tailer = CompanionTailer("idb_path", manager) await tailer._read_stream(StreamMock()) # pyre-ignore self.assertEqual( manager._udid_target_map, { "udid": TargetDescription( udid="udid", name="name", state="state", target_type="type", os_version="os_version", architecture="architecture", companion_info=None, screen_dimensions=None, ) }, )
def target_description_from_dictionary( parsed: Dict[str, Any]) -> TargetDescription: companion_info_fields = ["host", "port", "is_local", "udid"] companion_info = None if all((field in parsed for field in companion_info_fields)): companion_info = CompanionInfo( host=parsed["host"], port=parsed["port"], is_local=parsed["is_local"], udid=parsed["udid"], ) return TargetDescription( name=parsed["name"], udid=parsed["udid"], state=parsed["state"], target_type=parsed["type"], os_version=parsed["os_version"], architecture=parsed["architecture"], companion_info=companion_info, screen_dimensions=None, )
def target_description_from_json(data: str) -> TargetDescription: parsed = json.loads(data) companion_info_fields = ["host", "port", "is_local", "grpc_port", "udid"] companion_info = None if all((field in parsed for field in companion_info_fields)): companion_info = CompanionInfo( host=parsed["host"], port=parsed["port"], is_local=parsed["is_local"], grpc_port=parsed["grpc_port"], udid=parsed["udid"], ) return TargetDescription( name=parsed["name"], udid=parsed["udid"], state=parsed["state"], target_type=parsed["type"], os_version=parsed["os_version"], architecture=parsed["architecture"], companion_info=companion_info, screen_dimensions=None, )
def test_merge_connected_targets(self) -> None: merged_targets = merge_connected_targets( local_targets=[ TargetDescription( udid="a", name="aa", state=None, target_type=None, os_version=None, architecture=None, companion_info=None, screen_dimensions=None, ), TargetDescription( udid="b", name="bb", state=None, target_type=None, os_version=None, architecture=None, companion_info=None, screen_dimensions=None, ), TargetDescription( udid="c", name="cc", state=None, target_type=None, os_version=None, architecture=None, companion_info=None, screen_dimensions=None, ), ], connected_targets=[ TargetDescription( udid="a", name="aa", state=None, target_type=None, os_version=None, architecture=None, companion_info=CompanionInfo( udid="a", address=TCPAddress(host="remotehost", port=1), is_local=False, ), screen_dimensions=None, ), TargetDescription( udid="d", name="dd", state=None, target_type=None, os_version=None, architecture=None, companion_info=CompanionInfo( udid="d", address=TCPAddress(host="remotehost", port=2), is_local=False, ), screen_dimensions=None, ), ], ) self.assertEqual( merged_targets, [ TargetDescription( udid="a", name="aa", state=None, target_type=None, os_version=None, architecture=None, companion_info=CompanionInfo( udid="a", address=TCPAddress(host="remotehost", port=1), is_local=False, ), screen_dimensions=None, ), TargetDescription( udid="b", name="bb", state=None, target_type=None, os_version=None, architecture=None, companion_info=None, screen_dimensions=None, ), TargetDescription( udid="c", name="cc", state=None, target_type=None, os_version=None, architecture=None, companion_info=None, screen_dimensions=None, ), TargetDescription( udid="d", name="dd", state=None, target_type=None, os_version=None, architecture=None, companion_info=CompanionInfo( udid="d", address=TCPAddress(host="remotehost", port=2), is_local=False, ), screen_dimensions=None, ), ], )
INSTALLED_APP_INFO_FIXTURE = InstalledAppInfo( bundle_id="MyBundleId", name="MyName", architectures={"ArchA", "ArchB"}, install_type="System", process_state=AppProcessState.RUNNING, debuggable=True, ) COMPANION_INFO_FIXTURE = CompanionInfo( udid="MyUdid", host="ThisMac", port=1234, is_local=False, grpc_port=9 ) TARGET_DESCRIPTION_FIXTURE = TargetDescription( udid="MyUdid", name="MyName", state="Started?", target_type="iOS", os_version="1", architecture="arm89", companion_info=None, screen_dimensions=None, ) INSTALLED_TEST_INFO = InstalledTestInfo( bundle_id="MyBundleID", name="MyName", architectures={"ArchA", "ArchB"} ) class FormattingTests(TestCase): def test_test_info_no_optional_fields(self) -> None: self.assertEqual( TEST_RUN_INFO_FIXTURE, test_info_from_json(json_format_test_info(TEST_RUN_INFO_FIXTURE)), )