1# Copyright 2018, The Android Open Source Project 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14 15""" 16VTS Tradefed test runner class. 17""" 18 19import copy 20import logging 21 22# pylint: disable=import-error 23from test_runners import atest_tf_test_runner 24import atest_utils 25import constants 26 27 28class VtsTradefedTestRunner(atest_tf_test_runner.AtestTradefedTestRunner): 29 """TradeFed Test Runner class.""" 30 NAME = 'VtsTradefedTestRunner' 31 EXECUTABLE = 'vts-tradefed' 32 _RUN_CMD = ('{exe} run commandAndExit {plan} -m {test} {args}') 33 _BUILD_REQ = {'vts-tradefed-standalone'} 34 _DEFAULT_ARGS = ['--skip-all-system-status-check', 35 '--skip-preconditions', 36 '--primary-abi-only'] 37 38 def __init__(self, results_dir, **kwargs): 39 """Init stuff for vts tradefed runner class.""" 40 super(VtsTradefedTestRunner, self).__init__(results_dir, **kwargs) 41 self.run_cmd_dict = {'exe': self.EXECUTABLE, 42 'test': '', 43 'args': ''} 44 45 def get_test_runner_build_reqs(self): 46 """Return the build requirements. 47 48 Returns: 49 Set of build targets. 50 """ 51 build_req = self._BUILD_REQ 52 build_req |= super(VtsTradefedTestRunner, 53 self).get_test_runner_build_reqs() 54 return build_req 55 56 def run_tests(self, test_infos, extra_args, reporter): 57 """Run the list of test_infos. 58 59 Args: 60 test_infos: List of TestInfo. 61 extra_args: Dict of extra args to add to test run. 62 reporter: An instance of result_report.ResultReporter. 63 64 Returns: 65 Return code of the process for running tests. 66 """ 67 ret_code = constants.EXIT_CODE_SUCCESS 68 reporter.register_unsupported_runner(self.NAME) 69 run_cmds = self.generate_run_commands(test_infos, extra_args) 70 for run_cmd in run_cmds: 71 proc = super(VtsTradefedTestRunner, self).run(run_cmd, 72 output_to_stdout=True) 73 ret_code |= self.wait_for_subprocess(proc) 74 return ret_code 75 76 def _parse_extra_args(self, extra_args): 77 """Convert the extra args into something vts-tf can understand. 78 79 We want to transform the top-level args from atest into specific args 80 that vts-tradefed supports. The only arg we take as is is EXTRA_ARG 81 since that is what the user intentionally wants to pass to the test 82 runner. 83 84 Args: 85 extra_args: Dict of args 86 87 Returns: 88 List of args to append. 89 """ 90 args_to_append = [] 91 args_not_supported = [] 92 for arg in extra_args: 93 if constants.SERIAL == arg: 94 args_to_append.append('--serial') 95 args_to_append.append(extra_args[arg]) 96 continue 97 if constants.CUSTOM_ARGS == arg: 98 args_to_append.extend(extra_args[arg]) 99 continue 100 if constants.DRY_RUN == arg: 101 continue 102 args_not_supported.append(arg) 103 if args_not_supported: 104 logging.info('%s does not support the following args: %s', 105 self.EXECUTABLE, args_not_supported) 106 return args_to_append 107 108 # pylint: disable=arguments-differ 109 def generate_run_commands(self, test_infos, extra_args): 110 """Generate a list of run commands from TestInfos. 111 112 Args: 113 test_infos: List of TestInfo tests to run. 114 extra_args: Dict of extra args to add to test run. 115 116 Returns: 117 A List of strings that contains the vts-tradefed run command. 118 """ 119 cmds = [] 120 args = self._DEFAULT_ARGS 121 args.extend(self._parse_extra_args(extra_args)) 122 args.extend(atest_utils.get_result_server_args()) 123 for test_info in test_infos: 124 cmd_dict = copy.deepcopy(self.run_cmd_dict) 125 cmd_dict['plan'] = constants.VTS_STAGING_PLAN 126 cmd_dict['test'] = test_info.test_name 127 cmd_dict['args'] = ' '.join(args) 128 cmds.append(self._RUN_CMD.format(**cmd_dict)) 129 return cmds 130