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"""
16Aggregates test runners, groups tests by test runners and kicks off tests.
17"""
18
19import itertools
20
21import atest_error
22from test_runners import atest_tf_test_runner
23from test_runners import robolectric_test_runner
24from test_runners import vts_tf_test_runner
25
26# pylint: disable=line-too-long
27_TEST_RUNNERS = {
28    atest_tf_test_runner.AtestTradefedTestRunner.NAME: atest_tf_test_runner.AtestTradefedTestRunner,
29    robolectric_test_runner.RobolectricTestRunner.NAME: robolectric_test_runner.RobolectricTestRunner,
30    vts_tf_test_runner.VtsTradefedTestRunner.NAME: vts_tf_test_runner.VtsTradefedTestRunner,
31}
32
33
34def _get_test_runners():
35    """Returns the test runners.
36
37    If external test runners are defined outside atest, they can be try-except
38    imported into here.
39
40    Returns:
41        Dict of test runner name to test runner class.
42    """
43    test_runners_dict = _TEST_RUNNERS
44    # Example import of example test runner:
45    try:
46        # pylint: disable=line-too-long
47        from test_runners import example_test_runner
48        test_runners_dict[example_test_runner.ExampleTestRunner.NAME] = example_test_runner.ExampleTestRunner
49    except ImportError:
50        pass
51    return test_runners_dict
52
53
54def _group_tests_by_test_runners(test_infos):
55    """Group the test_infos by test runners
56
57    Args:
58        test_infos: List of TestInfo.
59
60    Returns:
61        List of tuples (test runner, tests).
62    """
63    tests_by_test_runner = []
64    test_runner_dict = _get_test_runners()
65    key = lambda x: x.test_runner
66    sorted_test_infos = sorted(list(test_infos), key=key)
67    for test_runner, tests in itertools.groupby(sorted_test_infos, key):
68        # groupby returns a grouper object, we want to operate on a list.
69        tests = list(tests)
70        test_runner_class = test_runner_dict.get(test_runner)
71        if test_runner_class is None:
72            raise atest_error.UnknownTestRunnerError('Unknown Test Runner %s' %
73                                                     test_runner)
74        tests_by_test_runner.append((test_runner_class, tests))
75    return tests_by_test_runner
76
77
78def get_test_runner_reqs(module_info, test_infos):
79    """Returns the requirements for all test runners specified in the tests.
80
81    Args:
82        module_info: ModuleInfo object.
83        test_infos: List of TestInfo.
84
85    Returns:
86        Set of build targets required by the test runners.
87    """
88    dummy_result_dir = ''
89    test_runner_build_req = set()
90    for test_runner, _ in _group_tests_by_test_runners(test_infos):
91        test_runner_build_req |= test_runner(
92            dummy_result_dir,
93            module_info=module_info).get_test_runner_build_reqs()
94    return test_runner_build_req
95
96
97def run_all_tests(results_dir, test_infos, extra_args):
98    """Run the given tests.
99
100    Args:
101        test_infos: List of TestInfo.
102        extra_args: Dict of extra args for test runners to use.
103    """
104    for test_runner, tests in _group_tests_by_test_runners(test_infos):
105        test_runner(results_dir).run_tests(tests, extra_args)
106