• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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"""
16TestInfo class.
17"""
18
19from collections import namedtuple
20
21# pylint: disable=import-error
22import constants
23
24
25TestFilterBase = namedtuple('TestFilter', ['class_name', 'methods'])
26
27
28class TestInfo(object):
29    """Information needed to identify and run a test."""
30
31    # pylint: disable=too-many-arguments
32    def __init__(self, test_name, test_runner, build_targets, data=None,
33                 suite=None, module_class=None, install_locations=None):
34        """Init for TestInfo.
35
36        Args:
37            test_name: String of test name.
38            test_runner: String of test runner.
39            build_targets: Set of build targets.
40            data: Dict of data for test runners to use.
41            suite: Suite for test runners to use.
42            module_class: A list of test classes. It's a snippet of class
43                        in module_info. e.g. ["EXECUTABLES",  "NATIVE_TESTS"]
44            install_locations: Set of install locations.
45                        e.g. set(['host', 'device'])
46        """
47        self.test_name = test_name
48        self.test_runner = test_runner
49        self.build_targets = build_targets
50        self.data = data if data else {}
51        self.suite = suite
52        self.module_class = module_class if module_class else []
53        self.install_locations = (install_locations if install_locations
54                                  else set())
55        # True if the TestInfo is built from a test configured in TEST_MAPPING.
56        self.from_test_mapping = False
57        # True if the test should run on host and require no device. The
58        # attribute is only set through TEST_MAPPING file.
59        self.host = False
60
61    def __str__(self):
62        host_info = (' - runs on host without device required.' if self.host
63                     else '')
64        return ('test_name: %s - test_runner:%s - build_targets:%s - data:%s - '
65                'suite:%s - module_class: %s - install_locations:%s%s' % (
66                    self.test_name, self.test_runner, self.build_targets,
67                    self.data, self.suite, self.module_class,
68                    self.install_locations, host_info))
69
70    def get_supported_exec_mode(self):
71        """Get the supported execution mode of the test.
72
73        Determine the test supports which execution mode by strategy:
74        Robolectric/JAVA_LIBRARIES --> 'both'
75        Not native tests or installed only in out/target --> 'device'
76        Installed only in out/host --> 'both'
77        Installed under host and target --> 'both'
78
79        Return:
80            String of execution mode.
81        """
82        install_path = self.install_locations
83        if not self.module_class:
84            return constants.DEVICE_TEST
85        # Let Robolectric test support both.
86        if constants.MODULE_CLASS_ROBOLECTRIC in self.module_class:
87            return constants.BOTH_TEST
88        # Let JAVA_LIBRARIES support both.
89        if constants.MODULE_CLASS_JAVA_LIBRARIES in self.module_class:
90            return constants.BOTH_TEST
91        if not install_path:
92            return constants.DEVICE_TEST
93        # Non-Native test runs on device-only.
94        if constants.MODULE_CLASS_NATIVE_TESTS not in self.module_class:
95            return constants.DEVICE_TEST
96        # Native test with install path as host should be treated as both.
97        # Otherwise, return device test.
98        if len(install_path) == 1 and constants.DEVICE_TEST in install_path:
99            return constants.DEVICE_TEST
100        return constants.BOTH_TEST
101
102
103class TestFilter(TestFilterBase):
104    """Information needed to filter a test in Tradefed"""
105
106    def to_set_of_tf_strings(self):
107        """Return TestFilter as set of strings in TradeFed filter format."""
108        if self.methods:
109            return {'%s#%s' % (self.class_name, m) for m in self.methods}
110        return {self.class_name}
111