| # Copyright 2017, The Android Open Source Project |
| # |
| # Licensed under the Apache License, Version 2.0 (the "License"); |
| # you may not use this file except in compliance with the License. |
| # You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| # See the License for the specific language governing permissions and |
| # limitations under the License. |
| |
| """Aggregates test runners, groups tests by test runners and kicks off tests.""" |
| |
| # pylint: disable=import-outside-toplevel |
| |
| from __future__ import annotations |
| |
| import itertools |
| from typing import Any, Dict, List |
| |
| from atest import atest_error |
| from atest import bazel_mode |
| from atest import module_info |
| from atest.test_finders import test_info |
| from atest.test_runner_invocation import TestRunnerInvocation |
| from atest.test_runners import atest_tf_test_runner |
| from atest.test_runners import mobly_test_runner |
| from atest.test_runners import robolectric_test_runner |
| from atest.test_runners import suite_plan_test_runner |
| from atest.test_runners import test_runner_base |
| from atest.test_runners import vts_tf_test_runner |
| |
| _TEST_RUNNERS = { |
| atest_tf_test_runner.AtestTradefedTestRunner.NAME: ( |
| atest_tf_test_runner.AtestTradefedTestRunner |
| ), |
| mobly_test_runner.MoblyTestRunner.NAME: mobly_test_runner.MoblyTestRunner, |
| robolectric_test_runner.RobolectricTestRunner.NAME: ( |
| robolectric_test_runner.RobolectricTestRunner |
| ), |
| suite_plan_test_runner.SuitePlanTestRunner.NAME: ( |
| suite_plan_test_runner.SuitePlanTestRunner |
| ), |
| vts_tf_test_runner.VtsTradefedTestRunner.NAME: ( |
| vts_tf_test_runner.VtsTradefedTestRunner |
| ), |
| bazel_mode.BazelTestRunner.NAME: bazel_mode.BazelTestRunner, |
| } |
| |
| |
| def _get_test_runners(): |
| """Returns the test runners. |
| |
| If external test runners are defined outside atest, they can be try-except |
| imported into here. |
| |
| Returns: |
| Dict of test runner name to test runner class. |
| """ |
| test_runners_dict = _TEST_RUNNERS |
| # Example import of example test runner: |
| try: |
| from test_runners import example_test_runner |
| |
| test_runners_dict[example_test_runner.ExampleTestRunner.NAME] = ( |
| example_test_runner.ExampleTestRunner |
| ) |
| except ImportError: |
| pass |
| return test_runners_dict |
| |
| |
| def group_tests_by_test_runners(test_infos): |
| """Group the test_infos by test runners |
| |
| Args: |
| test_infos: List of TestInfo. |
| |
| Returns: |
| List of tuples (test runner, tests). |
| """ |
| tests_by_test_runner = [] |
| test_runner_dict = _get_test_runners() |
| key = lambda x: x.test_runner |
| sorted_test_infos = sorted(list(test_infos), key=key) |
| for test_runner, tests in itertools.groupby(sorted_test_infos, key): |
| # groupby returns a grouper object, we want to operate on a list. |
| tests = list(tests) |
| test_runner_class = test_runner_dict.get(test_runner) |
| if test_runner_class is None: |
| raise atest_error.UnknownTestRunnerError( |
| 'Unknown Test Runner %s' % test_runner |
| ) |
| tests_by_test_runner.append((test_runner_class, tests)) |
| return tests_by_test_runner |
| |
| |
| def create_test_runner_invocations( |
| *, |
| test_infos: List[test_info.TestInfo], |
| results_dir: str, |
| mod_info: module_info.ModuleInfo, |
| extra_args: Dict[str, Any], |
| minimal_build: bool, |
| ) -> List[TestRunnerInvocation]: |
| """Creates TestRunnerInvocation instances. |
| |
| Args: |
| test_infos: A list of instances of TestInfo. |
| results_dir: A directory which stores the ATest execution information. |
| mod_info: An instance of ModuleInfo. |
| extra_args: A dict of arguments for the test runner to utilize. |
| minimal_build: A boolean setting whether or not this invocation will |
| minimize the build target set. |
| |
| Returns: |
| A list of TestRunnerInvocation instances. |
| """ |
| |
| test_runner_invocations = [] |
| for test_runner_class, tests in group_tests_by_test_runners(test_infos): |
| test_runner = test_runner_class( |
| results_dir, |
| mod_info=mod_info, |
| extra_args=extra_args, |
| minimal_build=minimal_build, |
| ) |
| |
| test_runner_invocations.extend( |
| test_runner.create_invocations(extra_args=extra_args, test_infos=tests) |
| ) |
| |
| return test_runner_invocations |