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"""VTS Tradefed test runner class.""" 16 17import copy 18import logging 19from typing import Any, Dict, List 20 21from atest import atest_utils 22from atest import constants 23from atest.atest_enum import ExitCode 24from atest.test_finders import test_info 25from atest.test_runners import atest_tf_test_runner 26 27 28class VtsTradefedTestRunner(atest_tf_test_runner.AtestTradefedTestRunner): 29 """TradeFed Test Runner class.""" 30 31 NAME = 'VtsTradefedTestRunner' 32 EXECUTABLE = 'vts10-tradefed' 33 _RUN_CMD = '{exe} run commandAndExit {plan} -m {test} {args}' 34 _BUILD_REQ = {'vts10-tradefed-standalone'} 35 _DEFAULT_ARGS = [ 36 '--skip-all-system-status-check', 37 '--skip-preconditions', 38 '--primary-abi-only', 39 ] 40 41 def __init__(self, results_dir: str, extra_args: Dict[str, Any], **kwargs): 42 """Init stuff for vts10 tradefed runner class.""" 43 super().__init__(results_dir, extra_args, **kwargs) 44 self.run_cmd_dict = {'exe': self.EXECUTABLE, 'test': '', 'args': ''} 45 46 def get_test_runner_build_reqs(self, test_infos: List[test_info.TestInfo]): 47 """Return the build requirements. 48 49 Args: 50 test_infos: List of TestInfo. 51 52 Returns: 53 Set of build targets. 54 """ 55 build_req = self._BUILD_REQ 56 build_req |= super().get_test_runner_build_reqs(test_infos) 57 return build_req 58 59 def run_tests(self, test_infos, extra_args, reporter): 60 """Run the list of test_infos. 61 62 Args: 63 test_infos: List of TestInfo. 64 extra_args: Dict of extra args to add to test run. 65 reporter: An instance of result_report.ResultReporter. 66 67 Returns: 68 Return code of the process for running tests. 69 """ 70 ret_code = ExitCode.SUCCESS 71 reporter.register_unsupported_runner(self.NAME) 72 run_cmds = self.generate_run_commands(test_infos, extra_args) 73 for run_cmd in run_cmds: 74 proc = super().run(run_cmd, output_to_stdout=True) 75 ret_code |= self.wait_for_subprocess(proc) 76 return ret_code 77 78 # pylint: disable=arguments-differ 79 def _parse_extra_args(self, extra_args): 80 """Convert the extra args into something vts10-tf can understand. 81 82 We want to transform the top-level args from atest into specific args 83 that vts10-tradefed supports. The only arg we take as is is EXTRA_ARG 84 since that is what the user intentionally wants to pass to the test 85 runner. 86 87 Args: 88 extra_args: Dict of args 89 90 Returns: 91 List of args to append. 92 """ 93 args_to_append = [] 94 args_not_supported = [] 95 for arg in extra_args: 96 if constants.SERIAL == arg: 97 args_to_append.append('--serial') 98 args_to_append.append(extra_args[arg]) 99 continue 100 if constants.CUSTOM_ARGS == arg: 101 args_to_append.extend(extra_args[arg]) 102 continue 103 if constants.DRY_RUN == arg: 104 continue 105 args_not_supported.append(arg) 106 if args_not_supported: 107 atest_utils.print_and_log_info( 108 '%s does not support the following args: %s', 109 self.EXECUTABLE, 110 args_not_supported, 111 ) 112 return args_to_append 113 114 # pylint: disable=arguments-differ 115 def generate_run_commands(self, test_infos, extra_args): 116 """Generate a list of run commands from TestInfos. 117 118 Args: 119 test_infos: List of TestInfo tests to run. 120 extra_args: Dict of extra args to add to test run. 121 122 Returns: 123 A List of strings that contains the vts10-tradefed run command. 124 """ 125 cmds = [] 126 args = self._DEFAULT_ARGS 127 args.extend(self._parse_extra_args(extra_args)) 128 args.extend(atest_utils.get_result_server_args()) 129 for test_info in test_infos: 130 cmd_dict = copy.deepcopy(self.run_cmd_dict) 131 cmd_dict['plan'] = constants.VTS_STAGING_PLAN 132 cmd_dict['test'] = test_info.test_name 133 cmd_dict['args'] = ' '.join(args) 134 cmds.append(self._RUN_CMD.format(**cmd_dict)) 135 return cmds 136