android_ACTS.py revision 285d39497ec10cc71ca3541fbefaaad94d683159
1# Copyright 2015 The Chromium OS Authors. All rights reserved. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5import os 6import logging 7import re 8 9import common 10from autotest_lib.client.common_lib import error 11from autotest_lib.client.common_lib import global_config 12from autotest_lib.client.common_lib.cros import dev_server 13from autotest_lib.server import test 14from autotest_lib.server.hosts import adb_host 15from autotest_lib.site_utils import acts_lib 16 17 18CONFIG = global_config.global_config 19 20CONFIG_FOLDER_LOCATION = global_config.global_config.get_config_value( 21 'ACTS', 'acts_config_folder', default='') 22 23TEST_CONFIG_FILE_FOLDER = os.path.join(CONFIG_FOLDER_LOCATION, 24 'autotest_config') 25 26TEST_CAMPAIGN_FILE_FOLDER = os.path.join(CONFIG_FOLDER_LOCATION, 27 'autotest_campaign') 28DEFAULT_TEST_RELATIVE_LOG_PATH = 'results/logs' 29 30def get_global_config_value_regex(section, regex): 31 """Get config values from global config based on regex of the key. 32 33 @param section: Section of the config, e.g., CLIENT. 34 @param regex: Regular expression of the key pattern. 35 36 @return: A dictionary of all config values matching the regex. Value is 37 assumed to be comma separated, and is converted to a list. 38 """ 39 configs = CONFIG.get_config_value_regex(section, regex) 40 result = {} 41 for key, value in configs.items(): 42 match = re.match(regex, key) 43 result[match.group(1)] = [v.strip() for v in value.split(',') 44 if v.strip()] 45 return result 46 47 48class android_ACTS(test.test): 49 """Run an Android CTS test case. 50 51 Component relationship: 52 Workstation ----(ssh)---> TestStation -----(adb)-----> Android DUT 53 This code runs on Workstation. 54 """ 55 version = 1 56 57 BRANCH_ALIAS_PATTERN = 'acts_branch_alias_(.*)' 58 aliases_map = get_global_config_value_regex('ACTS', BRANCH_ALIAS_PATTERN) 59 60 def run_once(self, 61 testbed=None, 62 config_file=None, 63 testbed_name=None, 64 test_case=None, 65 test_file=None, 66 additional_configs=[], 67 additional_apks=[], 68 override_build_url=None, 69 override_build=None, 70 override_acts_zip=None, 71 override_internal_acts_dir=None, 72 override_python_bin='python', 73 acts_timeout=7200, 74 perma_path=None, 75 additional_cmd_line_params=None, 76 branch_mappings = {}, 77 testtracker_project_id=None, 78 testtracker_extra_env=None, 79 testtracker_owner=None): 80 """Runs an acts test case. 81 82 @param testbed: The testbed to test on. 83 @config_file: The main config file to use for running the test. This 84 should be relative to the autotest_config folder. 85 @param test_case: The test case to run. Should be None when test_file 86 is given. 87 @param test_file: The campaign file to run. Should be None when 88 test_case is given. This should be relative to the 89 autotest_campaign folder. If multiple are given, 90 multiple test cases will be run. 91 @param additional_configs: Any additional config files to use. 92 These should be relative to the 93 autotest_config folder. 94 @param additional_apks: An array of apk info dictionaries. 95 apk = Name of the apk (eg. sl4a.apk) 96 package = Name of the package (eg. test.tools) 97 artifact = Name of the artifact, if not given 98 package is used. 99 @param override_build_url: Deprecated, use override_build instead. 100 @param override_build: The android build to fetch test artifacts from. 101 If not provided a default is selected from one 102 of the devices. 103 @param override_acts_zip: If given a zip file on the drone is used 104 rather than pulling a build. 105 @param override_internal_acts_dir: The directory within the artifact 106 where the acts framework folder 107 lives. 108 @param override_python_bin: Overrides the default python binary that 109 is used. 110 @param acts_timeout: How long to wait for acts to finish. 111 @param perma_path: If given a permantent path will be used rather than 112 a temp path. 113 @para branch_mappings: A dictionary of branch names to branch names. 114 When pulling test resources, if the current 115 branch is found in the mapping it will use 116 the mapped branch instead. 117 @param testtracker_project_id: ID to use for test tracker project. 118 @param testtracker_extra_env: Extra environment info to publish 119 with the results. 120 """ 121 if not override_build: 122 override_build = override_build_url 123 124 host = next(v for v in testbed.get_adb_devices().values()) 125 126 if not host: 127 raise error.TestError('No hosts defined for this test, cannot' 128 ' determine build to grab artifact from.') 129 130 info = host.host_info_store.get() 131 job_repo_url = info.attributes.get(host.job_repo_url_attribute, '') 132 test_station = testbed.teststation 133 if not perma_path: 134 ts_tempfolder = test_station.get_tmp_dir() 135 else: 136 test_station.run('rm -fr "%s"' % perma_path) 137 test_station.run('mkdir "%s"' % perma_path) 138 ts_tempfolder = perma_path 139 target_zip = os.path.join(ts_tempfolder, 'acts.zip') 140 141 if override_build: 142 build_pieces = override_build.split('/') 143 job_build_branch = build_pieces[0] 144 job_build_target = build_pieces[1] 145 job_build_id = build_pieces[2] 146 else: 147 job_build_info = adb_host.ADBHost.get_build_info_from_build_url( 148 job_repo_url) 149 job_build_branch = job_build_info['branch'] 150 job_build_target = job_build_info['target'] 151 job_build_id = job_build_info['build_id'] 152 153 154 if job_build_branch in branch_mappings: 155 logging.info('Replacing branch %s -> %s', 156 job_build_branch, 157 branch_mappings[job_build_branch].strip()) 158 job_build_branch = branch_mappings[job_build_branch].strip() 159 job_build_id = "LATEST" 160 elif job_build_branch in self.aliases_map: 161 logging.info('Replacing branch %s -> %s', 162 job_build_branch, 163 self.aliases_map[job_build_branch][0].strip()) 164 job_build_branch = self.aliases_map[job_build_branch][0].strip() 165 job_build_id = "LATEST" 166 167 build_name = '%s/%s/%s' % (job_build_branch, 168 job_build_target, 169 job_build_id) 170 devserver = dev_server.AndroidBuildServer.resolve(build_name, 171 host.hostname) 172 build_name = devserver.translate(build_name) 173 build_branch, build_target, build_id = build_name.split('/') 174 175 logging.info('Using build info BRANCH:%s, TARGET:%s, BUILD_ID:%s', 176 build_branch, build_target, build_id) 177 178 if override_acts_zip: 179 package = acts_lib.create_acts_package_from_zip( 180 test_station, override_acts_zip, target_zip) 181 else: 182 package = acts_lib.create_acts_package_from_artifact( 183 test_station, build_branch, build_target, build_id, devserver, 184 target_zip) 185 186 test_env = package.create_enviroment( 187 testbed=testbed, 188 container_directory=ts_tempfolder, 189 testbed_name=testbed_name, 190 internal_acts_directory=override_internal_acts_dir) 191 192 test_env.install_sl4a_apk() 193 194 for apk in additional_apks: 195 test_env.install_apk(apk) 196 197 test_env.setup_enviroment(python_bin=override_python_bin) 198 199 test_env.upload_config(config_file) 200 201 if additional_configs: 202 for additional_config in additional_configs: 203 test_env.upload_config(additional_config) 204 205 if test_file: 206 test_env.upload_campaign(test_file) 207 208 results = test_env.run_test( 209 config_file, 210 campaign=test_file, 211 test_case=test_case, 212 python_bin=override_python_bin, 213 timeout=acts_timeout, 214 additional_cmd_line_params=additional_cmd_line_params) 215 216 results.log_output() 217 results.report_to_autotest(self) 218 results.save_test_info(self) 219 results.rethrow_exception() 220