• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2017, 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"""Aggregates test runners, groups tests by test runners and kicks off tests."""
16
17# pylint: disable=import-outside-toplevel
18
19from __future__ import annotations
20
21import itertools
22from typing import Any, Dict, List
23
24from atest import atest_error
25from atest import bazel_mode
26from atest import module_info
27from atest.test_finders import test_info
28from atest.test_runner_invocation import TestRunnerInvocation
29from atest.test_runners import atest_tf_test_runner
30from atest.test_runners import mobly_test_runner
31from atest.test_runners import robolectric_test_runner
32from atest.test_runners import suite_plan_test_runner
33from atest.test_runners import test_runner_base
34from atest.test_runners import vts_tf_test_runner
35
36_TEST_RUNNERS = {
37    atest_tf_test_runner.AtestTradefedTestRunner.NAME: (
38        atest_tf_test_runner.AtestTradefedTestRunner
39    ),
40    mobly_test_runner.MoblyTestRunner.NAME: mobly_test_runner.MoblyTestRunner,
41    robolectric_test_runner.RobolectricTestRunner.NAME: (
42        robolectric_test_runner.RobolectricTestRunner
43    ),
44    suite_plan_test_runner.SuitePlanTestRunner.NAME: (
45        suite_plan_test_runner.SuitePlanTestRunner
46    ),
47    vts_tf_test_runner.VtsTradefedTestRunner.NAME: (
48        vts_tf_test_runner.VtsTradefedTestRunner
49    ),
50    bazel_mode.BazelTestRunner.NAME: bazel_mode.BazelTestRunner,
51}
52
53
54def _get_test_runners():
55  """Returns the test runners.
56
57  If external test runners are defined outside atest, they can be try-except
58  imported into here.
59
60  Returns:
61      Dict of test runner name to test runner class.
62  """
63  test_runners_dict = _TEST_RUNNERS
64  # Example import of example test runner:
65  try:
66    from test_runners import example_test_runner
67
68    test_runners_dict[example_test_runner.ExampleTestRunner.NAME] = (
69        example_test_runner.ExampleTestRunner
70    )
71  except ImportError:
72    pass
73  return test_runners_dict
74
75
76def group_tests_by_test_runners(test_infos):
77  """Group the test_infos by test runners
78
79  Args:
80      test_infos: List of TestInfo.
81
82  Returns:
83      List of tuples (test runner, tests).
84  """
85  tests_by_test_runner = []
86  test_runner_dict = _get_test_runners()
87  key = lambda x: x.test_runner
88  sorted_test_infos = sorted(list(test_infos), key=key)
89  for test_runner, tests in itertools.groupby(sorted_test_infos, key):
90    # groupby returns a grouper object, we want to operate on a list.
91    tests = list(tests)
92    test_runner_class = test_runner_dict.get(test_runner)
93    if test_runner_class is None:
94      raise atest_error.UnknownTestRunnerError(
95          'Unknown Test Runner %s' % test_runner
96      )
97    tests_by_test_runner.append((test_runner_class, tests))
98  return tests_by_test_runner
99
100
101def create_test_runner_invocations(
102    *,
103    test_infos: List[test_info.TestInfo],
104    results_dir: str,
105    mod_info: module_info.ModuleInfo,
106    extra_args: Dict[str, Any],
107    minimal_build: bool,
108) -> List[TestRunnerInvocation]:
109  """Creates TestRunnerInvocation instances.
110
111  Args:
112      test_infos: A list of instances of TestInfo.
113      results_dir: A directory which stores the ATest execution information.
114      mod_info: An instance of ModuleInfo.
115      extra_args: A dict of arguments for the test runner to utilize.
116      minimal_build: A boolean setting whether or not this invocation will
117        minimize the build target set.
118
119  Returns:
120      A list of TestRunnerInvocation instances.
121  """
122
123  test_runner_invocations = []
124  for test_runner_class, tests in group_tests_by_test_runners(test_infos):
125    test_runner = test_runner_class(
126        results_dir,
127        mod_info=mod_info,
128        extra_args=extra_args,
129        minimal_build=minimal_build,
130    )
131
132    test_runner_invocations.extend(
133        test_runner.create_invocations(extra_args=extra_args, test_infos=tests)
134    )
135
136  return test_runner_invocations
137