1# Copyright 2016 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 5# repohooks/pre-upload.py currently does not run pylint. But for developers who 6# want to check their code manually we disable several harmless pylint warnings 7# which just distract from more serious remaining issues. 8# 9# The instance variable _android_cts is not defined in __init__(). 10# pylint: disable=attribute-defined-outside-init 11# 12# Many short variable names don't follow the naming convention. 13# pylint: disable=invalid-name 14 15import logging 16import os 17 18from autotest_lib.client.common_lib import error 19from autotest_lib.server import hosts 20from autotest_lib.server import utils 21from autotest_lib.server.cros import camerabox_utils 22from autotest_lib.server.cros import tradefed_constants as constants 23from autotest_lib.server.cros import tradefed_test 24 25# Maximum default time allowed for each individual CTS module. 26_CTS_TIMEOUT_SECONDS = 3600 27 28# Public download locations for android cts bundles. 29_DL_CTS = 'https://dl.google.com/dl/android/cts/' 30_CTS_URI = { 31 'arm': _DL_CTS + 'android-cts-7.1_r26-linux_x86-arm.zip', 32 'x86': _DL_CTS + 'android-cts-7.1_r26-linux_x86-x86.zip', 33 'media': _DL_CTS + 'android-cts-media-1.4.zip', 34} 35 36 37class cheets_CTS_N(tradefed_test.TradefedTest): 38 """Sets up tradefed to run CTS tests.""" 39 version = 1 40 41 _BRANCH_DEFAULT_RETRY = [(0, 10)] # dev=beta=stable=10 42 _BRANCH_MAX_RETRY = [(0, 10), # dev=beta=10, stable=99 43 (constants.APPROXIMATE_STABLE_BRANCH_NUMBER, 99)] 44 _SHARD_CMD = '--shards' 45 # TODO(pwang): b/110966363, remove it once scarlet is fixed. 46 _NEED_DEVICE_INFO_BOARDS = ['scarlet', 'veyron_tiger'] 47 _SCENE_URI = ('https://storage.googleapis.com' 48 '/chromiumos-test-assets-public/camerabox/scene.pdf') 49 50 def _tradefed_retry_command(self, template, session_id): 51 """Build tradefed 'retry' command from template.""" 52 cmd = [] 53 for arg in template: 54 if (arg == '--skip-device-info' and 55 self._get_board_name() in self._NEED_DEVICE_INFO_BOARDS): 56 continue 57 cmd.append(arg.format(session_id=session_id)) 58 return cmd 59 60 def _tradefed_run_command(self, template): 61 """Build tradefed 'run' command from template.""" 62 cmd = [] 63 for arg in template: 64 if (arg == '--skip-device-info' and 65 self._get_board_name() in self._NEED_DEVICE_INFO_BOARDS): 66 continue 67 cmd.append(arg) 68 # If we are running outside of the lab we can collect more data. 69 if not utils.is_in_container(): 70 logging.info('Running outside of lab, adding extra debug options.') 71 cmd.append('--log-level-display=DEBUG') 72 cmd.append('--screenshot-on-failure') 73 # TODO(ihf): Add log collection once b/28333587 fixed. 74 # cmd.append('--collect-deqp-logs') 75 return cmd 76 77 def _get_default_bundle_url(self, bundle): 78 return _CTS_URI[bundle] 79 80 def _get_tradefed_base_dir(self): 81 return 'android-cts' 82 83 def _run_tradefed(self, commands): 84 """Kick off CTS. 85 86 @param commands: the command(s) to pass to CTS. 87 @param datetime_id: For 'continue' datetime of previous run is known. 88 @return: The result object from utils.run. 89 """ 90 cts_tradefed = os.path.join(self._repository, 'tools', 'cts-tradefed') 91 with tradefed_test.adb_keepalive(self._get_adb_targets(), 92 self._install_paths): 93 for command in commands: 94 logging.info('RUN: ./cts-tradefed %s', ' '.join(command)) 95 output = self._run( 96 cts_tradefed, 97 args=tuple(command), 98 timeout=self._timeout * self._timeout_factor, 99 verbose=True, 100 ignore_status=False, 101 # Make sure to tee tradefed stdout/stderr to autotest logs 102 # continuously during the test run. 103 stdout_tee=utils.TEE_TO_LOGS, 104 stderr_tee=utils.TEE_TO_LOGS) 105 logging.info('END: ./cts-tradefed %s\n', ' '.join(command)) 106 return output 107 108 def _should_skip_test(self, bundle): 109 """Some tests are expected to fail and are skipped.""" 110 # novato* are x86 VMs without binary translation. Skip the ARM tests. 111 no_ARM_ABI_test_boards = ('novato', 'novato-arc64') 112 if self._get_board_name() in no_ARM_ABI_test_boards and bundle == 'arm': 113 return True 114 return False 115 116 def initialize_camerabox(self, camera_facing, cmdline_args): 117 """Configure DUT and chart running in camerabox environment. 118 @param camera_facing: the facing of the DUT used in testing 119 (e.g. 'front', 'back'). 120 """ 121 chart_address = camerabox_utils.get_chart_address( 122 [h.hostname for h in self._hosts], cmdline_args) 123 if chart_address is None: 124 raise error.TestFail( 125 'Error: missing option --args="chart=<CHART IP>"') 126 chart_hosts = [hosts.create_host(ip) for ip in chart_address] 127 128 self.chart_fixtures = [ 129 camerabox_utils.ChartFixture(h, self._SCENE_URI) 130 for h in chart_hosts 131 ] 132 self.dut_fixtures = [ 133 camerabox_utils.DUTFixture(self, h, camera_facing) 134 for h in self._hosts 135 ] 136 137 for chart in self.chart_fixtures: 138 chart.initialize() 139 140 for dut in self.dut_fixtures: 141 dut.initialize() 142 143 def initialize(self, 144 camera_facing=None, 145 bundle=None, 146 uri=None, 147 host=None, 148 hosts=None, 149 max_retry=None, 150 load_waivers=True, 151 retry_manual_tests=False, 152 warn_on_test_retry=True, 153 cmdline_args=None, 154 hard_reboot_on_failure=False): 155 super(cheets_CTS_N, self).initialize( 156 bundle=bundle, 157 uri=uri, 158 host=host, 159 hosts=hosts, 160 max_retry=max_retry, 161 load_waivers=load_waivers, 162 retry_manual_tests=retry_manual_tests, 163 warn_on_test_retry=warn_on_test_retry, 164 hard_reboot_on_failure=hard_reboot_on_failure) 165 if camera_facing: 166 self.initialize_camerabox(camera_facing, cmdline_args) 167 168 def run_once(self, 169 test_name, 170 run_template, 171 retry_template=None, 172 target_module=None, 173 target_plan=None, 174 target_class=None, 175 target_method=None, 176 needs_push_media=False, 177 bundle=None, 178 precondition_commands=[], 179 login_precondition_commands=[], 180 timeout=_CTS_TIMEOUT_SECONDS): 181 """Runs the specified CTS once, but with several retries. 182 183 Run an arbitrary tradefed command. 184 185 @param test_name: the name of test. Used for logging. 186 @param run_template: the template to construct the run command. 187 Example: ['run', 'commandAndExit', 'cts', 188 '--skip-media-download'] 189 @param retry_template: the template to construct the retry command. 190 Example: ['run', 'commandAndExit', 'retry', 191 '--skip-media-download', '--retry', 192 '{session_id}'] 193 @param target_module: the name of test module to run. 194 @param target_plan: the name of the test plan to run. 195 @param target_class: the name of the class to be tested. 196 @param target_method: the name of the method to be tested. 197 @param needs_push_media: need to push test media streams. 198 @param bundle: the type of the CTS bundle: 'arm' or 'x86' 199 @param precondition_commands: a list of scripts to be run on the 200 dut before the test is run, the scripts must already be installed. 201 @param login_precondition_commands: a list of scripts to be run on the 202 dut before the log-in for the test is performed. 203 @param timeout: time after which tradefed can be interrupted. 204 """ 205 self._run_tradefed_with_retries( 206 test_name=test_name, 207 run_template=run_template, 208 retry_template=retry_template, 209 timeout=timeout, 210 target_module=target_module, 211 target_plan=target_plan, 212 needs_push_media=needs_push_media, 213 bundle=bundle, 214 cts_uri=_CTS_URI, 215 login_precondition_commands=login_precondition_commands, 216 precondition_commands=precondition_commands) 217 218 def cleanup_camerabox(self): 219 """Cleanup configuration on DUT and chart tablet for running in 220 camerabox environment. 221 """ 222 for dut in self.dut_fixtures: 223 dut.cleanup() 224 225 for chart in self.chart_fixtures: 226 chart.cleanup() 227 228 def cleanup(self): 229 if hasattr(self, 'dut_fixtures'): 230 self.cleanup_camerabox() 231 232 super(cheets_CTS_N, self).cleanup() 233