1*6777b538SAndroid Build Coastguard Worker# Copyright 2022 The Chromium Authors 2*6777b538SAndroid Build Coastguard Worker# Use of this source code is governed by a BSD-style license that can be 3*6777b538SAndroid Build Coastguard Worker# found in the LICENSE file. 4*6777b538SAndroid Build Coastguard Worker"""Functions used in both v1 and v2 scripts.""" 5*6777b538SAndroid Build Coastguard Worker 6*6777b538SAndroid Build Coastguard Workerimport json 7*6777b538SAndroid Build Coastguard Workerimport os 8*6777b538SAndroid Build Coastguard Workerimport platform 9*6777b538SAndroid Build Coastguard Workerimport stat 10*6777b538SAndroid Build Coastguard Worker 11*6777b538SAndroid Build Coastguard Workerfrom typing import Iterable, List, Tuple 12*6777b538SAndroid Build Coastguard Worker 13*6777b538SAndroid Build Coastguard Worker 14*6777b538SAndroid Build Coastguard Worker_FILTER_DIR = 'testing/buildbot/filters' 15*6777b538SAndroid Build Coastguard Worker_SSH_KEYS = os.path.expanduser('~/.ssh/fuchsia_authorized_keys') 16*6777b538SAndroid Build Coastguard Worker 17*6777b538SAndroid Build Coastguard Worker 18*6777b538SAndroid Build Coastguard Workerclass VersionNotFoundError(Exception): 19*6777b538SAndroid Build Coastguard Worker """Thrown when version info cannot be retrieved from device.""" 20*6777b538SAndroid Build Coastguard Worker 21*6777b538SAndroid Build Coastguard Worker 22*6777b538SAndroid Build Coastguard Workerdef get_ssh_keys() -> str: 23*6777b538SAndroid Build Coastguard Worker """Returns path of Fuchsia ssh keys.""" 24*6777b538SAndroid Build Coastguard Worker 25*6777b538SAndroid Build Coastguard Worker return _SSH_KEYS 26*6777b538SAndroid Build Coastguard Worker 27*6777b538SAndroid Build Coastguard Worker 28*6777b538SAndroid Build Coastguard Workerdef running_unattended() -> bool: 29*6777b538SAndroid Build Coastguard Worker """Returns true if running non-interactively. 30*6777b538SAndroid Build Coastguard Worker 31*6777b538SAndroid Build Coastguard Worker When running unattended, confirmation prompts and the like are suppressed. 32*6777b538SAndroid Build Coastguard Worker """ 33*6777b538SAndroid Build Coastguard Worker 34*6777b538SAndroid Build Coastguard Worker # TODO(crbug/1401387): Change to mixin based approach. 35*6777b538SAndroid Build Coastguard Worker return 'SWARMING_SERVER' in os.environ 36*6777b538SAndroid Build Coastguard Worker 37*6777b538SAndroid Build Coastguard Worker 38*6777b538SAndroid Build Coastguard Workerdef get_host_arch() -> str: 39*6777b538SAndroid Build Coastguard Worker """Retrieve CPU architecture of the host machine. """ 40*6777b538SAndroid Build Coastguard Worker host_arch = platform.machine() 41*6777b538SAndroid Build Coastguard Worker # platform.machine() returns AMD64 on 64-bit Windows. 42*6777b538SAndroid Build Coastguard Worker if host_arch in ['x86_64', 'AMD64']: 43*6777b538SAndroid Build Coastguard Worker return 'x64' 44*6777b538SAndroid Build Coastguard Worker if host_arch in ['aarch64', 'arm64']: 45*6777b538SAndroid Build Coastguard Worker return 'arm64' 46*6777b538SAndroid Build Coastguard Worker raise NotImplementedError('Unsupported host architecture: %s' % host_arch) 47*6777b538SAndroid Build Coastguard Worker 48*6777b538SAndroid Build Coastguard Worker 49*6777b538SAndroid Build Coastguard Workerdef add_exec_to_file(file: str) -> None: 50*6777b538SAndroid Build Coastguard Worker """Add execution bits to a file. 51*6777b538SAndroid Build Coastguard Worker 52*6777b538SAndroid Build Coastguard Worker Args: 53*6777b538SAndroid Build Coastguard Worker file: path to the file. 54*6777b538SAndroid Build Coastguard Worker """ 55*6777b538SAndroid Build Coastguard Worker file_stat = os.stat(file) 56*6777b538SAndroid Build Coastguard Worker os.chmod(file, file_stat.st_mode | stat.S_IXUSR) 57*6777b538SAndroid Build Coastguard Worker 58*6777b538SAndroid Build Coastguard Worker 59*6777b538SAndroid Build Coastguard Workerdef parse_host_port(host_port_pair: str) -> Tuple[str, int]: 60*6777b538SAndroid Build Coastguard Worker """Parses a host name or IP address and a port number from a string of 61*6777b538SAndroid Build Coastguard Worker any of the following forms: 62*6777b538SAndroid Build Coastguard Worker - hostname:port 63*6777b538SAndroid Build Coastguard Worker - IPv4addy:port 64*6777b538SAndroid Build Coastguard Worker - [IPv6addy]:port 65*6777b538SAndroid Build Coastguard Worker 66*6777b538SAndroid Build Coastguard Worker Returns: 67*6777b538SAndroid Build Coastguard Worker A tuple of the string host name/address and integer port number. 68*6777b538SAndroid Build Coastguard Worker 69*6777b538SAndroid Build Coastguard Worker Raises: 70*6777b538SAndroid Build Coastguard Worker ValueError if `host_port_pair` does not contain a colon or if the 71*6777b538SAndroid Build Coastguard Worker substring following the last colon cannot be converted to an int. 72*6777b538SAndroid Build Coastguard Worker """ 73*6777b538SAndroid Build Coastguard Worker 74*6777b538SAndroid Build Coastguard Worker host, port = host_port_pair.rsplit(':', 1) 75*6777b538SAndroid Build Coastguard Worker 76*6777b538SAndroid Build Coastguard Worker # Strip the brackets if the host looks like an IPv6 address. 77*6777b538SAndroid Build Coastguard Worker if len(host) >= 4 and host[0] == '[' and host[-1] == ']': 78*6777b538SAndroid Build Coastguard Worker host = host[1:-1] 79*6777b538SAndroid Build Coastguard Worker return (host, int(port)) 80*6777b538SAndroid Build Coastguard Worker 81*6777b538SAndroid Build Coastguard Worker 82*6777b538SAndroid Build Coastguard Workerdef get_ssh_prefix(host_port_pair: str) -> List[str]: 83*6777b538SAndroid Build Coastguard Worker """Get the prefix of a barebone ssh command.""" 84*6777b538SAndroid Build Coastguard Worker 85*6777b538SAndroid Build Coastguard Worker ssh_addr, ssh_port = parse_host_port(host_port_pair) 86*6777b538SAndroid Build Coastguard Worker sshconfig = os.path.join(os.path.dirname(__file__), 'sshconfig') 87*6777b538SAndroid Build Coastguard Worker return ['ssh', '-F', sshconfig, ssh_addr, '-p', str(ssh_port)] 88*6777b538SAndroid Build Coastguard Worker 89*6777b538SAndroid Build Coastguard Worker 90*6777b538SAndroid Build Coastguard Workerdef install_symbols(package_paths: Iterable[str], 91*6777b538SAndroid Build Coastguard Worker fuchsia_out_dir: str) -> None: 92*6777b538SAndroid Build Coastguard Worker """Installs debug symbols for a package into the GDB-standard symbol 93*6777b538SAndroid Build Coastguard Worker directory located in fuchsia_out_dir.""" 94*6777b538SAndroid Build Coastguard Worker 95*6777b538SAndroid Build Coastguard Worker symbol_root = os.path.join(fuchsia_out_dir, '.build-id') 96*6777b538SAndroid Build Coastguard Worker for path in package_paths: 97*6777b538SAndroid Build Coastguard Worker package_dir = os.path.dirname(path) 98*6777b538SAndroid Build Coastguard Worker ids_txt_path = os.path.join(package_dir, 'ids.txt') 99*6777b538SAndroid Build Coastguard Worker with open(ids_txt_path, 'r') as f: 100*6777b538SAndroid Build Coastguard Worker for entry in f: 101*6777b538SAndroid Build Coastguard Worker build_id, binary_relpath = entry.strip().split(' ') 102*6777b538SAndroid Build Coastguard Worker binary_abspath = os.path.abspath( 103*6777b538SAndroid Build Coastguard Worker os.path.join(package_dir, binary_relpath)) 104*6777b538SAndroid Build Coastguard Worker symbol_dir = os.path.join(symbol_root, build_id[:2]) 105*6777b538SAndroid Build Coastguard Worker symbol_file = os.path.join(symbol_dir, build_id[2:] + '.debug') 106*6777b538SAndroid Build Coastguard Worker if not os.path.exists(symbol_dir): 107*6777b538SAndroid Build Coastguard Worker os.makedirs(symbol_dir) 108*6777b538SAndroid Build Coastguard Worker 109*6777b538SAndroid Build Coastguard Worker if os.path.islink(symbol_file) or os.path.exists(symbol_file): 110*6777b538SAndroid Build Coastguard Worker # Clobber the existing entry to ensure that the symlink's 111*6777b538SAndroid Build Coastguard Worker # target is up to date. 112*6777b538SAndroid Build Coastguard Worker os.unlink(symbol_file) 113*6777b538SAndroid Build Coastguard Worker os.symlink(os.path.relpath(binary_abspath, symbol_dir), 114*6777b538SAndroid Build Coastguard Worker symbol_file) 115*6777b538SAndroid Build Coastguard Worker 116*6777b538SAndroid Build Coastguard Worker 117*6777b538SAndroid Build Coastguard Worker# TODO(crbug.com/1279803): Until one can send files to the device when running 118*6777b538SAndroid Build Coastguard Worker# a test, filter files must be read from the test package. 119*6777b538SAndroid Build Coastguard Workerdef map_filter_file_to_package_file(filter_file: str) -> str: 120*6777b538SAndroid Build Coastguard Worker """Returns the path to |filter_file| within the test component's package.""" 121*6777b538SAndroid Build Coastguard Worker 122*6777b538SAndroid Build Coastguard Worker if not _FILTER_DIR in filter_file: 123*6777b538SAndroid Build Coastguard Worker raise ValueError('CFv2 tests only support registered filter files ' 124*6777b538SAndroid Build Coastguard Worker 'present in the test package') 125*6777b538SAndroid Build Coastguard Worker return '/pkg/' + filter_file[filter_file.index(_FILTER_DIR):] 126*6777b538SAndroid Build Coastguard Worker 127*6777b538SAndroid Build Coastguard Worker 128*6777b538SAndroid Build Coastguard Worker# TODO(crbug.com/1496426): Rename to get_product_version. 129*6777b538SAndroid Build Coastguard Workerdef get_sdk_hash(system_image_dir: str) -> Tuple[str, str]: 130*6777b538SAndroid Build Coastguard Worker """Read version of hash in pre-installed package directory. 131*6777b538SAndroid Build Coastguard Worker Returns: 132*6777b538SAndroid Build Coastguard Worker Tuple of (product, version) of image to be installed. 133*6777b538SAndroid Build Coastguard Worker """ 134*6777b538SAndroid Build Coastguard Worker 135*6777b538SAndroid Build Coastguard Worker with open(os.path.join(system_image_dir, 136*6777b538SAndroid Build Coastguard Worker 'product_bundle.json')) as product: 137*6777b538SAndroid Build Coastguard Worker # The product_name in the json file does not match the name of the image 138*6777b538SAndroid Build Coastguard Worker # flashed to the device. 139*6777b538SAndroid Build Coastguard Worker return (os.path.basename(os.path.normpath(system_image_dir)), 140*6777b538SAndroid Build Coastguard Worker json.load(product)['product_version']) 141