xref: /aosp_15_r20/tools/asuite/atest/test_runner_invocation.py (revision c2e18aaa1096c836b086f94603d04f4eb9cf37f5)
1*c2e18aaaSAndroid Build Coastguard Worker# Copyright 2024, The Android Open Source Project
2*c2e18aaaSAndroid Build Coastguard Worker#
3*c2e18aaaSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License");
4*c2e18aaaSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License.
5*c2e18aaaSAndroid Build Coastguard Worker# You may obtain a copy of the License at
6*c2e18aaaSAndroid Build Coastguard Worker#
7*c2e18aaaSAndroid Build Coastguard Worker#     http://www.apache.org/licenses/LICENSE-2.0
8*c2e18aaaSAndroid Build Coastguard Worker#
9*c2e18aaaSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software
10*c2e18aaaSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS,
11*c2e18aaaSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*c2e18aaaSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and
13*c2e18aaaSAndroid Build Coastguard Worker# limitations under the License.
14*c2e18aaaSAndroid Build Coastguard Worker
15*c2e18aaaSAndroid Build Coastguard Worker"""Test runner invocation class."""
16*c2e18aaaSAndroid Build Coastguard Worker
17*c2e18aaaSAndroid Build Coastguard Workerfrom __future__ import annotations
18*c2e18aaaSAndroid Build Coastguard Worker
19*c2e18aaaSAndroid Build Coastguard Workerimport time
20*c2e18aaaSAndroid Build Coastguard Workerimport traceback
21*c2e18aaaSAndroid Build Coastguard Workerfrom typing import Any, Dict, List, Set
22*c2e18aaaSAndroid Build Coastguard Worker
23*c2e18aaaSAndroid Build Coastguard Workerfrom atest import result_reporter
24*c2e18aaaSAndroid Build Coastguard Workerfrom atest.atest_enum import ExitCode
25*c2e18aaaSAndroid Build Coastguard Workerfrom atest.metrics import metrics
26*c2e18aaaSAndroid Build Coastguard Workerfrom atest.metrics import metrics_utils
27*c2e18aaaSAndroid Build Coastguard Workerfrom atest.test_finders import test_info
28*c2e18aaaSAndroid Build Coastguard Workerfrom atest.test_runners import test_runner_base
29*c2e18aaaSAndroid Build Coastguard Worker
30*c2e18aaaSAndroid Build Coastguard Worker
31*c2e18aaaSAndroid Build Coastguard Workerclass TestRunnerInvocation:
32*c2e18aaaSAndroid Build Coastguard Worker  """An invocation executing tests based on given arguments."""
33*c2e18aaaSAndroid Build Coastguard Worker
34*c2e18aaaSAndroid Build Coastguard Worker  def __init__(
35*c2e18aaaSAndroid Build Coastguard Worker      self,
36*c2e18aaaSAndroid Build Coastguard Worker      *,
37*c2e18aaaSAndroid Build Coastguard Worker      test_runner: test_runner_base.TestRunnerBase,
38*c2e18aaaSAndroid Build Coastguard Worker      extra_args: Dict[str, Any],
39*c2e18aaaSAndroid Build Coastguard Worker      test_infos: List[test_info.TestInfo],
40*c2e18aaaSAndroid Build Coastguard Worker  ):
41*c2e18aaaSAndroid Build Coastguard Worker    self._extra_args = extra_args
42*c2e18aaaSAndroid Build Coastguard Worker    self._test_infos = test_infos
43*c2e18aaaSAndroid Build Coastguard Worker    self._test_runner = test_runner
44*c2e18aaaSAndroid Build Coastguard Worker
45*c2e18aaaSAndroid Build Coastguard Worker  @property
46*c2e18aaaSAndroid Build Coastguard Worker  def test_infos(self):
47*c2e18aaaSAndroid Build Coastguard Worker    return self._test_infos
48*c2e18aaaSAndroid Build Coastguard Worker
49*c2e18aaaSAndroid Build Coastguard Worker  def __eq__(self, other):
50*c2e18aaaSAndroid Build Coastguard Worker    return self.__dict__ == other.__dict__
51*c2e18aaaSAndroid Build Coastguard Worker
52*c2e18aaaSAndroid Build Coastguard Worker  def requires_device_update(self):
53*c2e18aaaSAndroid Build Coastguard Worker    """Checks whether this invocation requires device update."""
54*c2e18aaaSAndroid Build Coastguard Worker    return self._test_runner.requires_device_update(self._test_infos)
55*c2e18aaaSAndroid Build Coastguard Worker
56*c2e18aaaSAndroid Build Coastguard Worker  def get_test_runner_reqs(self) -> Set[str]:
57*c2e18aaaSAndroid Build Coastguard Worker    """Returns the required build targets for this test runner invocation."""
58*c2e18aaaSAndroid Build Coastguard Worker    return self._test_runner.get_test_runner_build_reqs(self._test_infos)
59*c2e18aaaSAndroid Build Coastguard Worker
60*c2e18aaaSAndroid Build Coastguard Worker  # pylint: disable=too-many-locals
61*c2e18aaaSAndroid Build Coastguard Worker  def run_all_tests(self, reporter: result_reporter.ResultReporter) -> ExitCode:
62*c2e18aaaSAndroid Build Coastguard Worker    """Runs all tests."""
63*c2e18aaaSAndroid Build Coastguard Worker
64*c2e18aaaSAndroid Build Coastguard Worker    test_start = time.time()
65*c2e18aaaSAndroid Build Coastguard Worker    is_success = True
66*c2e18aaaSAndroid Build Coastguard Worker    err_msg = None
67*c2e18aaaSAndroid Build Coastguard Worker    try:
68*c2e18aaaSAndroid Build Coastguard Worker      tests_ret_code = self._test_runner.run_tests(
69*c2e18aaaSAndroid Build Coastguard Worker          self._test_infos, self._extra_args, reporter
70*c2e18aaaSAndroid Build Coastguard Worker      )
71*c2e18aaaSAndroid Build Coastguard Worker    except Exception:  # pylint: disable=broad-except
72*c2e18aaaSAndroid Build Coastguard Worker      is_success = False
73*c2e18aaaSAndroid Build Coastguard Worker      err_msg = traceback.format_exc()
74*c2e18aaaSAndroid Build Coastguard Worker
75*c2e18aaaSAndroid Build Coastguard Worker    if not is_success:
76*c2e18aaaSAndroid Build Coastguard Worker      reporter.runner_failure(self._test_runner.NAME, err_msg)
77*c2e18aaaSAndroid Build Coastguard Worker      tests_ret_code = ExitCode.TEST_FAILURE
78*c2e18aaaSAndroid Build Coastguard Worker
79*c2e18aaaSAndroid Build Coastguard Worker    run_time = metrics_utils.convert_duration(time.time() - test_start)
80*c2e18aaaSAndroid Build Coastguard Worker    tests = []
81*c2e18aaaSAndroid Build Coastguard Worker    for test in reporter.get_test_results_by_runner(self._test_runner.NAME):
82*c2e18aaaSAndroid Build Coastguard Worker      # group_name is module name with abi(for example,
83*c2e18aaaSAndroid Build Coastguard Worker      # 'x86_64 CtsSampleDeviceTestCases').
84*c2e18aaaSAndroid Build Coastguard Worker      # Filtering abi in group_name.
85*c2e18aaaSAndroid Build Coastguard Worker      test_group = test.group_name
86*c2e18aaaSAndroid Build Coastguard Worker      # Withdraw module name only when the test result has reported.
87*c2e18aaaSAndroid Build Coastguard Worker      module_name = test_group
88*c2e18aaaSAndroid Build Coastguard Worker      if test_group and ' ' in test_group:
89*c2e18aaaSAndroid Build Coastguard Worker        _, module_name = test_group.split()
90*c2e18aaaSAndroid Build Coastguard Worker      testcase_name = '%s:%s' % (module_name, test.test_name)
91*c2e18aaaSAndroid Build Coastguard Worker      result = test_runner_base.RESULT_CODE[test.status]
92*c2e18aaaSAndroid Build Coastguard Worker      tests.append(
93*c2e18aaaSAndroid Build Coastguard Worker          {'name': testcase_name, 'result': result, 'stacktrace': test.details}
94*c2e18aaaSAndroid Build Coastguard Worker      )
95*c2e18aaaSAndroid Build Coastguard Worker    metrics.RunnerFinishEvent(
96*c2e18aaaSAndroid Build Coastguard Worker        duration=run_time,
97*c2e18aaaSAndroid Build Coastguard Worker        success=is_success,
98*c2e18aaaSAndroid Build Coastguard Worker        runner_name=self._test_runner.NAME,
99*c2e18aaaSAndroid Build Coastguard Worker        test=tests,
100*c2e18aaaSAndroid Build Coastguard Worker    )
101*c2e18aaaSAndroid Build Coastguard Worker
102*c2e18aaaSAndroid Build Coastguard Worker    return tests_ret_code
103