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