• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python3
2#
3# Copyright 2018, The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9#     http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16
17"""Unittests for module_finder."""
18
19# pylint: disable=line-too-long
20# pylint: disable=too-many-lines
21# pylint: disable=unsubscriptable-object
22
23import copy
24import re
25import unittest
26import os
27
28from unittest import mock
29
30import atest_error
31import atest_configs
32import atest_utils
33import constants
34import module_info
35import unittest_constants as uc
36import unittest_utils
37
38from test_finders import module_finder
39from test_finders import test_finder_utils
40from test_finders import test_info
41from test_runners import atest_tf_test_runner as atf_tr
42
43MODULE_CLASS = '%s:%s' % (uc.MODULE_NAME, uc.CLASS_NAME)
44MODULE_PACKAGE = '%s:%s' % (uc.MODULE_NAME, uc.PACKAGE)
45CC_MODULE_CLASS = '%s:%s' % (uc.CC_MODULE_NAME, uc.CC_CLASS_NAME)
46KERNEL_TEST_CLASS = 'test_class_1'
47KERNEL_TEST_CONFIG = 'KernelTest.xml.data'
48KERNEL_MODULE_CLASS = '%s:%s' % (constants.REQUIRED_KERNEL_TEST_MODULES[0],
49                                 KERNEL_TEST_CLASS)
50KERNEL_CONFIG_FILE = os.path.join(uc.TEST_DATA_DIR, KERNEL_TEST_CONFIG)
51KERNEL_CLASS_FILTER = test_info.TestFilter(KERNEL_TEST_CLASS, frozenset())
52KERNEL_MODULE_CLASS_DATA = {constants.TI_REL_CONFIG: KERNEL_CONFIG_FILE,
53                            constants.TI_FILTER: frozenset([KERNEL_CLASS_FILTER])}
54KERNEL_MODULE_CLASS_INFO = test_info.TestInfo(
55    constants.REQUIRED_KERNEL_TEST_MODULES[0],
56    atf_tr.AtestTradefedTestRunner.NAME,
57    uc.CLASS_BUILD_TARGETS, KERNEL_MODULE_CLASS_DATA)
58FLAT_METHOD_INFO = test_info.TestInfo(
59    uc.MODULE_NAME,
60    atf_tr.AtestTradefedTestRunner.NAME,
61    uc.MODULE_BUILD_TARGETS,
62    data={constants.TI_FILTER: frozenset([uc.FLAT_METHOD_FILTER]),
63          constants.TI_REL_CONFIG: uc.CONFIG_FILE})
64MODULE_CLASS_METHOD = '%s#%s' % (MODULE_CLASS, uc.METHOD_NAME)
65CC_MODULE_CLASS_METHOD = '%s#%s' % (CC_MODULE_CLASS, uc.CC_METHOD_NAME)
66CLASS_INFO_MODULE_2 = test_info.TestInfo(
67    uc.MODULE2_NAME,
68    atf_tr.AtestTradefedTestRunner.NAME,
69    uc.CLASS_BUILD_TARGETS,
70    data={constants.TI_FILTER: frozenset([uc.CLASS_FILTER]),
71          constants.TI_REL_CONFIG: uc.CONFIG2_FILE})
72CC_CLASS_INFO_MODULE_2 = test_info.TestInfo(
73    uc.CC_MODULE2_NAME,
74    atf_tr.AtestTradefedTestRunner.NAME,
75    uc.CLASS_BUILD_TARGETS,
76    data={constants.TI_FILTER: frozenset([uc.CC_CLASS_FILTER]),
77          constants.TI_REL_CONFIG: uc.CC_CONFIG2_FILE})
78DEFAULT_INSTALL_PATH = ['/path/to/install']
79ROBO_MOD_PATH = ['/shared/robo/path']
80NON_RUN_ROBO_MOD_NAME = 'robo_mod'
81RUN_ROBO_MOD_NAME = 'run_robo_mod'
82NON_RUN_ROBO_MOD = {constants.MODULE_NAME: NON_RUN_ROBO_MOD_NAME,
83                    constants.MODULE_PATH: ROBO_MOD_PATH,
84                    constants.MODULE_CLASS: ['random_class']}
85RUN_ROBO_MOD = {constants.MODULE_NAME: RUN_ROBO_MOD_NAME,
86                constants.MODULE_PATH: ROBO_MOD_PATH,
87                constants.MODULE_CLASS: [constants.MODULE_CLASS_ROBOLECTRIC]}
88
89SEARCH_DIR_RE = re.compile(r'^find ([^ ]*).*$')
90
91#pylint: disable=unused-argument
92def classoutside_side_effect(find_cmd, shell=False):
93    """Mock the check output of a find cmd where class outside module path."""
94    search_dir = SEARCH_DIR_RE.match(find_cmd).group(1).strip()
95    if search_dir == uc.ROOT:
96        return uc.FIND_ONE
97    return None
98
99
100#pylint: disable=protected-access
101class ModuleFinderUnittests(unittest.TestCase):
102    """Unit tests for module_finder.py"""
103
104    def setUp(self):
105        """Set up stuff for testing."""
106        self.mod_finder = module_finder.ModuleFinder()
107        self.mod_finder.module_info = mock.Mock(spec=module_info.ModuleInfo)
108        self.mod_finder.module_info.path_to_module_info = {}
109        self.mod_finder.root_dir = uc.ROOT
110
111    def test_is_vts_module(self):
112        """Test _load_module_info_file regular operation."""
113        mod_name = 'mod'
114        is_vts_module_info = {'compatibility_suites': ['vts10', 'tests']}
115        self.mod_finder.module_info.get_module_info.return_value = is_vts_module_info
116        self.assertTrue(self.mod_finder._is_vts_module(mod_name))
117
118        is_not_vts_module = {'compatibility_suites': ['vts10', 'cts']}
119        self.mod_finder.module_info.get_module_info.return_value = is_not_vts_module
120        self.assertFalse(self.mod_finder._is_vts_module(mod_name))
121
122    # pylint: disable=unused-argument
123    @mock.patch.object(module_finder.ModuleFinder, '_get_build_targets',
124                       return_value=copy.deepcopy(uc.MODULE_BUILD_TARGETS))
125    def test_find_test_by_module_name(self, _get_targ):
126        """Test find_test_by_module_name."""
127        self.mod_finder.module_info.is_robolectric_test.return_value = False
128        self.mod_finder.module_info.has_test_config.return_value = True
129        mod_info = {'installed': ['/path/to/install'],
130                    'path': [uc.MODULE_DIR],
131                    constants.MODULE_CLASS: [],
132                    constants.MODULE_COMPATIBILITY_SUITES: []}
133        self.mod_finder.module_info.get_module_info.return_value = mod_info
134        self.mod_finder.module_info.get_robolectric_type.return_value = 0
135        t_infos = self.mod_finder.find_test_by_module_name(uc.MODULE_NAME)
136        unittest_utils.assert_equal_testinfos(
137            self,
138            t_infos[0],
139            uc.MODULE_INFO)
140        self.mod_finder.module_info.get_module_info.return_value = None
141        self.mod_finder.module_info.is_testable_module.return_value = False
142        self.assertIsNone(self.mod_finder.find_test_by_module_name('Not_Module'))
143
144    @mock.patch('builtins.input', return_value='1')
145    @mock.patch.object(module_finder.ModuleFinder, '_get_build_targets',
146                       return_value=copy.deepcopy(uc.MODULE_BUILD_TARGETS))
147    def test_find_test_by_module_name_w_multiple_config(
148            self, _get_targ, _mock_input):
149        """Test find_test_by_module_name."""
150        atest_configs.GLOBAL_ARGS = mock.Mock()
151        atest_configs.GLOBAL_ARGS.test_config_select = True
152        self.mod_finder.module_info.is_robolectric_test.return_value = False
153        self.mod_finder.module_info.has_test_config.return_value = True
154        mod_info = {'installed': ['/path/to/install'],
155                    'path': [uc.MODULE_DIR],
156                    constants.MODULE_CLASS: [],
157                    constants.MODULE_COMPATIBILITY_SUITES: [],
158                    constants.MODULE_TEST_CONFIG: [
159                        uc.CONFIG_FILE,
160                        uc.EXTRA_CONFIG_FILE]}
161        self.mod_finder.module_info.get_module_info.return_value = mod_info
162        self.mod_finder.module_info.get_robolectric_type.return_value = 0
163        t_infos = self.mod_finder.find_test_by_module_name(uc.MODULE_NAME)
164        # Only select one test
165        self.assertEqual(len(t_infos), 1)
166        # The t_info should be the EXTRA_CONFIG_FILE one.
167        unittest_utils.assert_equal_testinfos(
168            self, t_infos[0], uc.MODULE_INFO_W_CONFIG)
169
170    @mock.patch.object(module_finder.ModuleFinder, '_get_build_targets',
171                       return_value=copy.deepcopy(uc.MODULE_BUILD_TARGETS))
172    def test_find_test_by_module_name_w_multiple_config_all(
173            self, _get_targ,):
174        """Test find_test_by_module_name."""
175        atest_configs.GLOBAL_ARGS = mock.Mock()
176        atest_configs.GLOBAL_ARGS.test_config_select = False
177        self.mod_finder.module_info.is_robolectric_test.return_value = False
178        self.mod_finder.module_info.has_test_config.return_value = True
179        mod_info = {'installed': ['/path/to/install'],
180                    'path': [uc.MODULE_DIR],
181                    constants.MODULE_CLASS: [],
182                    constants.MODULE_COMPATIBILITY_SUITES: [],
183                    constants.MODULE_TEST_CONFIG: [
184                        uc.CONFIG_FILE,
185                        uc.EXTRA_CONFIG_FILE]}
186        self.mod_finder.module_info.get_module_info.return_value = mod_info
187        self.mod_finder.module_info.get_robolectric_type.return_value = 0
188        t_infos = self.mod_finder.find_test_by_module_name(uc.MODULE_NAME)
189        unittest_utils.assert_equal_testinfos(self, t_infos[0], uc.MODULE_INFO)
190        unittest_utils.assert_equal_testinfos(
191            self, t_infos[1], uc.MODULE_INFO_W_CONFIG)
192
193    @mock.patch.object(test_finder_utils, 'find_host_unit_tests',
194                       return_value=[])
195    @mock.patch.object(atest_utils, 'is_build_file', return_value=True)
196    @mock.patch.object(test_finder_utils, 'is_parameterized_java_class',
197                       return_value=False)
198    @mock.patch.object(test_finder_utils, 'has_method_in_file',
199                       return_value=True)
200    @mock.patch.object(module_finder.ModuleFinder, '_is_vts_module',
201                       return_value=False)
202    @mock.patch.object(module_finder.ModuleFinder, '_get_build_targets')
203    @mock.patch('subprocess.check_output', return_value=uc.FIND_ONE)
204    @mock.patch.object(test_finder_utils, 'get_fully_qualified_class_name',
205                       return_value=uc.FULL_CLASS_NAME)
206    @mock.patch('os.path.isfile', side_effect=unittest_utils.isfile_side_effect)
207    @mock.patch('os.path.isdir', return_value=True)
208    #pylint: disable=unused-argument
209    def test_find_test_by_class_name(self, _isdir, _isfile, _fqcn,
210                                     mock_checkoutput, mock_build,
211                                     _vts, _has_method_in_file,
212                                     _is_parameterized, _is_build_file,
213                                     _mock_unit_tests):
214        """Test find_test_by_class_name."""
215        mock_build.return_value = uc.CLASS_BUILD_TARGETS
216        self.mod_finder.module_info.is_auto_gen_test_config.return_value = False
217        self.mod_finder.module_info.is_robolectric_test.return_value = False
218        self.mod_finder.module_info.has_test_config.return_value = True
219        self.mod_finder.module_info.get_module_names.return_value = [uc.MODULE_NAME]
220        self.mod_finder.module_info.get_module_info.return_value = {
221            constants.MODULE_INSTALLED: DEFAULT_INSTALL_PATH,
222            constants.MODULE_NAME: uc.MODULE_NAME,
223            constants.MODULE_CLASS: [],
224            constants.MODULE_COMPATIBILITY_SUITES: []}
225        self.mod_finder.module_info.get_robolectric_type.return_value = 0
226        t_infos = self.mod_finder.find_test_by_class_name(uc.CLASS_NAME)
227        unittest_utils.assert_equal_testinfos(
228            self, t_infos[0], uc.CLASS_INFO)
229
230        # with method
231        mock_build.return_value = copy.deepcopy(uc.MODULE_BUILD_TARGETS)
232        class_with_method = '%s#%s' % (uc.CLASS_NAME, uc.METHOD_NAME)
233        t_infos = self.mod_finder.find_test_by_class_name(class_with_method)
234        unittest_utils.assert_equal_testinfos(
235            self, t_infos[0], uc.METHOD_INFO)
236        mock_build.return_value = copy.deepcopy(uc.MODULE_BUILD_TARGETS)
237        class_methods = '%s,%s' % (class_with_method, uc.METHOD2_NAME)
238        t_infos = self.mod_finder.find_test_by_class_name(class_methods)
239        unittest_utils.assert_equal_testinfos(
240            self, t_infos[0],
241            FLAT_METHOD_INFO)
242        # module and rel_config passed in
243        mock_build.return_value = uc.CLASS_BUILD_TARGETS
244        t_infos = self.mod_finder.find_test_by_class_name(
245            uc.CLASS_NAME, uc.MODULE_NAME, uc.CONFIG_FILE)
246        unittest_utils.assert_equal_testinfos(
247            self, t_infos[0], uc.CLASS_INFO)
248        # find output fails to find class file
249        mock_checkoutput.return_value = ''
250        self.assertIsNone(self.mod_finder.find_test_by_class_name('Not class'))
251        # class is outside given module path
252        mock_checkoutput.side_effect = classoutside_side_effect
253        t_infos = self.mod_finder.find_test_by_class_name(uc.CLASS_NAME,
254                                                          uc.MODULE2_NAME,
255                                                          uc.CONFIG2_FILE)
256        unittest_utils.assert_equal_testinfos(
257            self, t_infos[0],
258            CLASS_INFO_MODULE_2)
259
260    @mock.patch.object(test_finder_utils, 'is_parameterized_java_class',
261                       return_value=False)
262    @mock.patch.object(test_finder_utils, 'has_method_in_file',
263                       return_value=True)
264    @mock.patch.object(module_finder.ModuleFinder, '_is_vts_module',
265                       return_value=False)
266    @mock.patch.object(module_finder.ModuleFinder, '_get_build_targets')
267    @mock.patch('subprocess.check_output', return_value=uc.FIND_ONE)
268    @mock.patch.object(test_finder_utils, 'get_fully_qualified_class_name',
269                       return_value=uc.FULL_CLASS_NAME)
270    @mock.patch('os.path.isfile', side_effect=unittest_utils.isfile_side_effect)
271    #pylint: disable=unused-argument
272    def test_find_test_by_module_and_class(self, _isfile, _fqcn,
273                                           mock_checkoutput, mock_build,
274                                           _vts, _has_method_in_file,
275                                           _is_parameterized):
276        """Test find_test_by_module_and_class."""
277        # Native test was tested in test_find_test_by_cc_class_name().
278        self.mod_finder.module_info.is_native_test.return_value = False
279        self.mod_finder.module_info.is_auto_gen_test_config.return_value = False
280        self.mod_finder.module_info.is_robolectric_test.return_value = False
281        self.mod_finder.module_info.has_test_config.return_value = True
282        mock_build.return_value = uc.CLASS_BUILD_TARGETS
283        mod_info = {constants.MODULE_INSTALLED: DEFAULT_INSTALL_PATH,
284                    constants.MODULE_PATH: [uc.MODULE_DIR],
285                    constants.MODULE_CLASS: [],
286                    constants.MODULE_COMPATIBILITY_SUITES: []}
287        self.mod_finder.module_info.get_module_info.return_value = mod_info
288        self.mod_finder.module_info.get_robolectric_type.return_value = 0
289        t_infos = self.mod_finder.find_test_by_module_and_class(MODULE_CLASS)
290        unittest_utils.assert_equal_testinfos(self, t_infos[0], uc.CLASS_INFO)
291        # with method
292        mock_build.return_value = copy.deepcopy(uc.MODULE_BUILD_TARGETS)
293        t_infos = self.mod_finder.find_test_by_module_and_class(MODULE_CLASS_METHOD)
294        unittest_utils.assert_equal_testinfos(self, t_infos[0], uc.METHOD_INFO)
295        self.mod_finder.module_info.is_testable_module.return_value = False
296        # bad module, good class, returns None
297        bad_module = '%s:%s' % ('BadMod', uc.CLASS_NAME)
298        self.mod_finder.module_info.get_module_info.return_value = None
299        self.assertIsNone(self.mod_finder.find_test_by_module_and_class(bad_module))
300        # find output fails to find class file
301        mock_checkoutput.return_value = ''
302        bad_class = '%s:%s' % (uc.MODULE_NAME, 'Anything')
303        self.mod_finder.module_info.get_module_info.return_value = mod_info
304        self.assertIsNone(self.mod_finder.find_test_by_module_and_class(bad_class))
305
306    @mock.patch.object(module_finder.test_finder_utils, 'get_cc_class_info')
307    @mock.patch.object(module_finder.ModuleFinder, 'find_test_by_kernel_class_name',
308                       return_value=None)
309    @mock.patch.object(module_finder.ModuleFinder, '_is_vts_module',
310                       return_value=False)
311    @mock.patch.object(module_finder.ModuleFinder, '_get_build_targets')
312    @mock.patch('subprocess.check_output', return_value=uc.FIND_CC_ONE)
313    @mock.patch.object(test_finder_utils, 'find_class_file',
314                       side_effect=[None, None, '/'])
315    @mock.patch('os.path.isfile', side_effect=unittest_utils.isfile_side_effect)
316    #pylint: disable=unused-argument
317    def test_find_test_by_module_and_class_part_2(self, _isfile, mock_fcf,
318                                                  mock_checkoutput, mock_build,
319                                                  _vts, _find_kernel, _class_info):
320        """Test find_test_by_module_and_class for MODULE:CC_CLASS."""
321        # Native test was tested in test_find_test_by_cc_class_name()
322        self.mod_finder.module_info.is_native_test.return_value = False
323        self.mod_finder.module_info.is_auto_gen_test_config.return_value = False
324        self.mod_finder.module_info.is_robolectric_test.return_value = False
325        self.mod_finder.module_info.has_test_config.return_value = True
326        self.mod_finder.module_info.get_paths.return_value = []
327        mock_build.return_value = uc.CLASS_BUILD_TARGETS
328        mod_info = {constants.MODULE_INSTALLED: DEFAULT_INSTALL_PATH,
329                    constants.MODULE_PATH: [uc.CC_MODULE_DIR],
330                    constants.MODULE_CLASS: [],
331                    constants.MODULE_COMPATIBILITY_SUITES: []}
332        self.mod_finder.module_info.get_module_info.return_value = mod_info
333        _class_info.return_value = {'PFTest': {'methods':{'test1', 'test2'},
334                                               'prefixes': set(),
335                                               'typed': False}}
336        self.mod_finder.module_info.get_robolectric_type.return_value = 0
337        t_infos = self.mod_finder.find_test_by_module_and_class(CC_MODULE_CLASS)
338        unittest_utils.assert_equal_testinfos(self, t_infos[0], uc.CC_MODULE_CLASS_INFO)
339        # with method
340        mock_build.return_value = copy.deepcopy(uc.MODULE_BUILD_TARGETS)
341        mock_fcf.side_effect = [None, None, '/']
342        t_infos = self.mod_finder.find_test_by_module_and_class(CC_MODULE_CLASS_METHOD)
343        unittest_utils.assert_equal_testinfos(self, t_infos[0], uc.CC_METHOD3_INFO)
344        # bad module, good class, returns None
345        bad_module = '%s:%s' % ('BadMod', uc.CC_CLASS_NAME)
346        self.mod_finder.module_info.get_module_info.return_value = None
347        self.mod_finder.module_info.is_testable_module.return_value = False
348        self.assertIsNone(self.mod_finder.find_test_by_module_and_class(bad_module))
349
350    @mock.patch.object(module_finder.ModuleFinder, '_get_module_test_config',
351                       return_value=[KERNEL_CONFIG_FILE])
352    @mock.patch.object(module_finder.ModuleFinder, '_is_vts_module',
353                       return_value=False)
354    @mock.patch.object(module_finder.ModuleFinder, '_get_build_targets')
355    @mock.patch('subprocess.check_output', return_value=uc.FIND_CC_ONE)
356    @mock.patch.object(test_finder_utils, 'find_class_file',
357                       side_effect=[None, None, '/'])
358    @mock.patch('os.path.isfile', side_effect=unittest_utils.isfile_side_effect)
359    #pylint: disable=unused-argument
360    def test_find_test_by_module_and_class_for_kernel_test(
361            self, _isfile, mock_fcf, mock_checkoutput, mock_build, _vts,
362            _test_config):
363        """Test find_test_by_module_and_class for MODULE:CC_CLASS."""
364        # Kernel test was tested in find_test_by_kernel_class_name()
365        self.mod_finder.module_info.is_native_test.return_value = False
366        self.mod_finder.module_info.is_auto_gen_test_config.return_value = False
367        self.mod_finder.module_info.is_robolectric_test.return_value = False
368        self.mod_finder.module_info.has_test_config.return_value = True
369        self.mod_finder.module_info.get_paths.return_value = []
370        mock_build.return_value = uc.CLASS_BUILD_TARGETS
371        mod_info = {constants.MODULE_INSTALLED: DEFAULT_INSTALL_PATH,
372                    constants.MODULE_PATH: [uc.CC_MODULE_DIR],
373                    constants.MODULE_CLASS: [],
374                    constants.MODULE_COMPATIBILITY_SUITES: []}
375        self.mod_finder.module_info.get_module_info.return_value = mod_info
376        self.mod_finder.module_info.get_robolectric_type.return_value = 0
377        t_infos = self.mod_finder.find_test_by_module_and_class(KERNEL_MODULE_CLASS)
378        unittest_utils.assert_equal_testinfos(self, t_infos[0], KERNEL_MODULE_CLASS_INFO)
379
380    @mock.patch.object(test_finder_utils, 'find_host_unit_tests',
381                       return_value=[])
382    @mock.patch.object(module_finder.ModuleFinder, '_is_vts_module',
383                       return_value=False)
384    @mock.patch.object(module_finder.ModuleFinder, '_get_build_targets')
385    @mock.patch('subprocess.check_output', return_value=uc.FIND_PKG)
386    @mock.patch('os.path.isfile', side_effect=unittest_utils.isfile_side_effect)
387    @mock.patch('os.path.isdir', return_value=True)
388    #pylint: disable=unused-argument
389    def test_find_test_by_package_name(self, _isdir, _isfile, mock_checkoutput,
390                                       mock_build, _vts, _mock_unit_tests):
391        """Test find_test_by_package_name."""
392        self.mod_finder.module_info.is_auto_gen_test_config.return_value = False
393        self.mod_finder.module_info.is_robolectric_test.return_value = False
394        self.mod_finder.module_info.has_test_config.return_value = True
395        mock_build.return_value = uc.CLASS_BUILD_TARGETS
396        self.mod_finder.module_info.get_module_names.return_value = [uc.MODULE_NAME]
397        self.mod_finder.module_info.get_module_info.return_value = {
398            constants.MODULE_INSTALLED: DEFAULT_INSTALL_PATH,
399            constants.MODULE_NAME: uc.MODULE_NAME,
400            constants.MODULE_CLASS: [],
401            constants.MODULE_COMPATIBILITY_SUITES: []
402            }
403        self.mod_finder.module_info.get_robolectric_type.return_value = 0
404        t_infos = self.mod_finder.find_test_by_package_name(uc.PACKAGE)
405        unittest_utils.assert_equal_testinfos(
406            self, t_infos[0],
407            uc.PACKAGE_INFO)
408        # with method, should raise
409        pkg_with_method = '%s#%s' % (uc.PACKAGE, uc.METHOD_NAME)
410        self.assertRaises(atest_error.MethodWithoutClassError,
411                          self.mod_finder.find_test_by_package_name,
412                          pkg_with_method)
413        # module and rel_config passed in
414        t_infos = self.mod_finder.find_test_by_package_name(
415            uc.PACKAGE, uc.MODULE_NAME, uc.CONFIG_FILE)
416        unittest_utils.assert_equal_testinfos(
417            self, t_infos[0], uc.PACKAGE_INFO)
418        # find output fails to find class file
419        mock_checkoutput.return_value = ''
420        self.assertIsNone(self.mod_finder.find_test_by_package_name('Not pkg'))
421
422    @mock.patch('os.path.isdir', return_value=False)
423    @mock.patch.object(module_finder.ModuleFinder, '_is_vts_module',
424                       return_value=False)
425    @mock.patch.object(module_finder.ModuleFinder, '_get_build_targets')
426    @mock.patch('subprocess.check_output', return_value=uc.FIND_PKG)
427    @mock.patch('os.path.isfile', side_effect=unittest_utils.isfile_side_effect)
428    #pylint: disable=unused-argument
429    def test_find_test_by_module_and_package(self, _isfile, mock_checkoutput,
430                                             mock_build, _vts, _isdir):
431        """Test find_test_by_module_and_package."""
432        self.mod_finder.module_info.is_auto_gen_test_config.return_value = False
433        self.mod_finder.module_info.is_robolectric_test.return_value = False
434        self.mod_finder.module_info.has_test_config.return_value = True
435        self.mod_finder.module_info.get_paths.return_value = []
436        mock_build.return_value = uc.CLASS_BUILD_TARGETS
437        mod_info = {constants.MODULE_INSTALLED: DEFAULT_INSTALL_PATH,
438                    constants.MODULE_PATH: [uc.MODULE_DIR],
439                    constants.MODULE_CLASS: [],
440                    constants.MODULE_COMPATIBILITY_SUITES: []}
441        self.mod_finder.module_info.get_module_info.return_value = mod_info
442        t_infos = self.mod_finder.find_test_by_module_and_package(MODULE_PACKAGE)
443        self.assertEqual(t_infos, None)
444        _isdir.return_value = True
445        self.mod_finder.module_info.get_robolectric_type.return_value = 0
446        t_infos = self.mod_finder.find_test_by_module_and_package(MODULE_PACKAGE)
447        unittest_utils.assert_equal_testinfos(self, t_infos[0], uc.PACKAGE_INFO)
448
449        # with method, raises
450        module_pkg_with_method = '%s:%s#%s' % (uc.MODULE2_NAME, uc.PACKAGE,
451                                               uc.METHOD_NAME)
452        self.assertRaises(atest_error.MethodWithoutClassError,
453                          self.mod_finder.find_test_by_module_and_package,
454                          module_pkg_with_method)
455        # bad module, good pkg, returns None
456        self.mod_finder.module_info.is_testable_module.return_value = False
457        bad_module = '%s:%s' % ('BadMod', uc.PACKAGE)
458        self.mod_finder.module_info.get_module_info.return_value = None
459        self.assertIsNone(self.mod_finder.find_test_by_module_and_package(bad_module))
460        # find output fails to find package path
461        mock_checkoutput.return_value = ''
462        bad_pkg = '%s:%s' % (uc.MODULE_NAME, 'Anything')
463        self.mod_finder.module_info.get_module_info.return_value = mod_info
464        self.assertIsNone(self.mod_finder.find_test_by_module_and_package(bad_pkg))
465
466    @mock.patch.object(test_finder_utils, 'find_host_unit_tests',
467                       return_value=[])
468    @mock.patch.object(test_finder_utils, 'get_cc_class_info', return_value={})
469    @mock.patch.object(atest_utils, 'is_build_file', return_value=True)
470    @mock.patch.object(test_finder_utils, 'is_parameterized_java_class',
471                       return_value=False)
472    @mock.patch.object(test_finder_utils, 'has_method_in_file',
473                       return_value=True)
474    @mock.patch.object(test_finder_utils, 'has_cc_class',
475                       return_value=True)
476    @mock.patch.object(module_finder.ModuleFinder, '_get_build_targets')
477    @mock.patch.object(module_finder.ModuleFinder, '_is_vts_module',
478                       return_value=False)
479    @mock.patch.object(test_finder_utils, 'get_fully_qualified_class_name',
480                       return_value=uc.FULL_CLASS_NAME)
481    @mock.patch('os.path.realpath',
482                side_effect=unittest_utils.realpath_side_effect)
483    @mock.patch('os.path.isfile', side_effect=unittest_utils.isfile_side_effect)
484    @mock.patch.object(test_finder_utils, 'find_parent_module_dir')
485    @mock.patch('os.path.exists')
486    #pylint: disable=unused-argument
487    def test_find_test_by_path(
488            self, mock_pathexists, mock_dir, _isfile, _real, _fqcn, _vts,
489            mock_build, _has_cc_class, _has_method_in_file, _is_parameterized,
490            _is_build_file, _get_cc_class_info, _mock_unit_tests):
491        """Test find_test_by_path."""
492        self.mod_finder.module_info.is_robolectric_test.return_value = False
493        self.mod_finder.module_info.has_test_config.return_value = True
494        mock_build.return_value = set()
495        # Check that we don't return anything with invalid test references.
496        mock_pathexists.return_value = False
497        unittest_utils.assert_equal_testinfos(
498            self, None, self.mod_finder.find_test_by_path('bad/path'))
499        mock_pathexists.return_value = True
500        mock_dir.return_value = None
501        unittest_utils.assert_equal_testinfos(
502            self, None, self.mod_finder.find_test_by_path('no/module'))
503        self.mod_finder.module_info.get_module_names.return_value = [uc.MODULE_NAME]
504        self.mod_finder.module_info.get_module_info.return_value = {
505            constants.MODULE_INSTALLED: DEFAULT_INSTALL_PATH,
506            constants.MODULE_NAME: uc.MODULE_NAME,
507            constants.MODULE_CLASS: [],
508            constants.MODULE_COMPATIBILITY_SUITES: []}
509
510        # Happy path testing.
511        mock_dir.return_value = uc.MODULE_DIR
512
513        class_path = '%s.kt' % uc.CLASS_NAME
514        mock_build.return_value = uc.CLASS_BUILD_TARGETS
515        self.mod_finder.module_info.get_robolectric_type.return_value = 0
516        t_infos = self.mod_finder.find_test_by_path(class_path)
517        unittest_utils.assert_equal_testinfos(
518            self, uc.CLASS_INFO, t_infos[0])
519
520        class_with_method = '%s#%s' % (class_path, uc.METHOD_NAME)
521        mock_build.return_value = copy.deepcopy(uc.MODULE_BUILD_TARGETS)
522        t_infos = self.mod_finder.find_test_by_path(class_with_method)
523        unittest_utils.assert_equal_testinfos(
524            self, t_infos[0], uc.METHOD_INFO)
525
526        class_path = '%s.java' % uc.CLASS_NAME
527        mock_build.return_value = uc.CLASS_BUILD_TARGETS
528        t_infos = self.mod_finder.find_test_by_path(class_path)
529        unittest_utils.assert_equal_testinfos(
530            self, uc.CLASS_INFO, t_infos[0])
531
532        class_with_method = '%s#%s' % (class_path, uc.METHOD_NAME)
533        mock_build.return_value = copy.deepcopy(uc.MODULE_BUILD_TARGETS)
534        t_infos = self.mod_finder.find_test_by_path(class_with_method)
535        unittest_utils.assert_equal_testinfos(
536            self, t_infos[0], uc.METHOD_INFO)
537
538        class_with_methods = '%s,%s' % (class_with_method, uc.METHOD2_NAME)
539        mock_build.return_value = copy.deepcopy(uc.MODULE_BUILD_TARGETS)
540        t_infos = self.mod_finder.find_test_by_path(class_with_methods)
541        unittest_utils.assert_equal_testinfos(
542            self, t_infos[0],
543            FLAT_METHOD_INFO)
544
545        # Cc path testing.
546        self.mod_finder.module_info.get_module_names.return_value = [uc.CC_MODULE_NAME]
547        self.mod_finder.module_info.get_module_info.return_value = {
548            constants.MODULE_INSTALLED: DEFAULT_INSTALL_PATH,
549            constants.MODULE_NAME: uc.CC_MODULE_NAME,
550            constants.MODULE_CLASS: [],
551            constants.MODULE_COMPATIBILITY_SUITES: []}
552        mock_dir.return_value = uc.CC_MODULE_DIR
553        class_path = '%s' % uc.CC_PATH
554        mock_build.return_value = uc.CLASS_BUILD_TARGETS
555        t_infos = self.mod_finder.find_test_by_path(class_path)
556        unittest_utils.assert_equal_testinfos(
557            self, uc.CC_PATH_INFO2, t_infos[0])
558
559    @mock.patch.object(module_finder.ModuleFinder, '_get_build_targets',
560                       return_value=copy.deepcopy(uc.MODULE_BUILD_TARGETS))
561    @mock.patch.object(module_finder.ModuleFinder, '_is_vts_module',
562                       return_value=False)
563    @mock.patch.object(test_finder_utils, 'find_parent_module_dir',
564                       return_value=os.path.relpath(uc.TEST_DATA_DIR, uc.ROOT))
565    #pylint: disable=unused-argument
566    def test_find_test_by_path_part_2(self, _find_parent, _is_vts, _get_build):
567        """Test find_test_by_path for directories."""
568        self.mod_finder.module_info.is_auto_gen_test_config.return_value = False
569        self.mod_finder.module_info.is_robolectric_test.return_value = False
570        self.mod_finder.module_info.has_test_config.return_value = True
571        # Dir with java files in it, should run as package
572        class_dir = os.path.join(uc.TEST_DATA_DIR, 'path_testing')
573        self.mod_finder.module_info.get_module_names.return_value = [uc.MODULE_NAME]
574        self.mod_finder.module_info.get_module_info.return_value = {
575            constants.MODULE_INSTALLED: DEFAULT_INSTALL_PATH,
576            constants.MODULE_NAME: uc.MODULE_NAME,
577            constants.MODULE_CLASS: [],
578            constants.MODULE_COMPATIBILITY_SUITES: []}
579        self.mod_finder.module_info.get_robolectric_type.return_value = 0
580        t_infos = self.mod_finder.find_test_by_path(class_dir)
581        unittest_utils.assert_equal_testinfos(
582            self, uc.PATH_INFO, t_infos[0])
583        # Dir with no java files in it, should run whole module
584        empty_dir = os.path.join(uc.TEST_DATA_DIR, 'path_testing_empty')
585        t_infos = self.mod_finder.find_test_by_path(empty_dir)
586        unittest_utils.assert_equal_testinfos(
587            self, uc.EMPTY_PATH_INFO,
588            t_infos[0])
589        # Dir with cc files in it, should run as cc class
590        class_dir = os.path.join(uc.TEST_DATA_DIR, 'cc_path_testing')
591        self.mod_finder.module_info.get_module_names.return_value = [uc.CC_MODULE_NAME]
592        self.mod_finder.module_info.get_module_info.return_value = {
593            constants.MODULE_INSTALLED: DEFAULT_INSTALL_PATH,
594            constants.MODULE_NAME: uc.CC_MODULE_NAME,
595            constants.MODULE_CLASS: [],
596            constants.MODULE_COMPATIBILITY_SUITES: []}
597        t_infos = self.mod_finder.find_test_by_path(class_dir)
598        unittest_utils.assert_equal_testinfos(
599            self, uc.CC_PATH_INFO, t_infos[0])
600
601    @mock.patch.object(module_finder.test_finder_utils, 'get_cc_class_info')
602    @mock.patch.object(test_finder_utils, 'find_host_unit_tests',
603                       return_value=[])
604    @mock.patch.object(atest_utils, 'is_build_file', return_value=True)
605    @mock.patch.object(test_finder_utils, 'has_method_in_file',
606                       return_value=True)
607    @mock.patch.object(module_finder.ModuleFinder, '_is_vts_module',
608                       return_value=False)
609    @mock.patch.object(module_finder.ModuleFinder, '_get_build_targets')
610    @mock.patch('subprocess.check_output', return_value=uc.CC_FIND_ONE)
611    @mock.patch('os.path.isfile', side_effect=unittest_utils.isfile_side_effect)
612    @mock.patch('os.path.isdir', return_value=True)
613    #pylint: disable=unused-argument
614    def test_find_test_by_cc_class_name(self, _isdir, _isfile,
615                                        mock_checkoutput, mock_build,
616                                        _vts, _has_method, _is_build_file,
617                                       _mock_unit_tests, _class_info):
618        """Test find_test_by_cc_class_name."""
619        mock_build.return_value = uc.CLASS_BUILD_TARGETS
620        self.mod_finder.module_info.is_auto_gen_test_config.return_value = False
621        self.mod_finder.module_info.is_robolectric_test.return_value = False
622        self.mod_finder.module_info.has_test_config.return_value = True
623        self.mod_finder.module_info.get_module_names.return_value = [uc.CC_MODULE_NAME]
624        self.mod_finder.module_info.get_module_info.return_value = {
625            constants.MODULE_INSTALLED: DEFAULT_INSTALL_PATH,
626            constants.MODULE_NAME: uc.CC_MODULE_NAME,
627            constants.MODULE_CLASS: [],
628            constants.MODULE_COMPATIBILITY_SUITES: []}
629        self.mod_finder.module_info.get_robolectric_type.return_value = 0
630        _class_info.return_value = {'PFTest': {'methods': {'test1', 'test2'},
631                                               'prefixes': set(),
632                                               'typed': False}}
633        t_infos = self.mod_finder.find_test_by_cc_class_name(uc.CC_CLASS_NAME)
634        unittest_utils.assert_equal_testinfos(
635            self, t_infos[0], uc.CC_CLASS_INFO)
636
637        # with method
638        mock_build.return_value = copy.deepcopy(uc.MODULE_BUILD_TARGETS)
639        class_with_method = '%s#%s' % (uc.CC_CLASS_NAME, uc.CC_METHOD_NAME)
640        t_infos = self.mod_finder.find_test_by_cc_class_name(class_with_method)
641        unittest_utils.assert_equal_testinfos(
642            self,
643            t_infos[0],
644            uc.CC_METHOD_INFO)
645        mock_build.return_value = copy.deepcopy(uc.MODULE_BUILD_TARGETS)
646        class_methods = '%s,%s' % (class_with_method, uc.CC_METHOD2_NAME)
647        t_infos = self.mod_finder.find_test_by_cc_class_name(class_methods)
648        unittest_utils.assert_equal_testinfos(
649            self, t_infos[0],
650            uc.CC_METHOD2_INFO)
651        # module and rel_config passed in
652        mock_build.return_value = uc.CLASS_BUILD_TARGETS
653        t_infos = self.mod_finder.find_test_by_cc_class_name(
654            uc.CC_CLASS_NAME, uc.CC_MODULE_NAME, uc.CC_CONFIG_FILE)
655        unittest_utils.assert_equal_testinfos(
656            self, t_infos[0], uc.CC_CLASS_INFO)
657        # find output fails to find class file
658        mock_checkoutput.return_value = ''
659        self.assertIsNone(self.mod_finder.find_test_by_cc_class_name(
660            'Not class'))
661        # class is outside given module path
662        mock_checkoutput.return_value = uc.CC_FIND_ONE
663        t_infos = self.mod_finder.find_test_by_cc_class_name(
664            uc.CC_CLASS_NAME,
665            uc.CC_MODULE2_NAME,
666            uc.CC_CONFIG2_FILE)
667        unittest_utils.assert_equal_testinfos(
668            self, t_infos[0],
669            CC_CLASS_INFO_MODULE_2)
670
671    def test_get_testable_modules_with_ld(self):
672        """Test get_testable_modules_with_ld"""
673        self.mod_finder.module_info.get_testable_modules.return_value = [
674            uc.MODULE_NAME, uc.MODULE2_NAME]
675        # Without a misfit constraint
676        ld1 = self.mod_finder.get_testable_modules_with_ld(uc.TYPO_MODULE_NAME)
677        self.assertEqual([[16, uc.MODULE2_NAME], [1, uc.MODULE_NAME]], ld1)
678        # With a misfit constraint
679        ld2 = self.mod_finder.get_testable_modules_with_ld(uc.TYPO_MODULE_NAME, 2)
680        self.assertEqual([[1, uc.MODULE_NAME]], ld2)
681
682    def test_get_fuzzy_searching_modules(self):
683        """Test get_fuzzy_searching_modules"""
684        self.mod_finder.module_info.get_testable_modules.return_value = [
685            uc.MODULE_NAME, uc.MODULE2_NAME]
686        result = self.mod_finder.get_fuzzy_searching_results(uc.TYPO_MODULE_NAME)
687        self.assertEqual(uc.MODULE_NAME, result[0])
688
689    def test_get_build_targets_w_vts_core(self):
690        """Test _get_build_targets."""
691        self.mod_finder.module_info.is_auto_gen_test_config.return_value = True
692        self.mod_finder.module_info.get_paths.return_value = []
693        mod_info = {constants.MODULE_COMPATIBILITY_SUITES:
694                        [constants.VTS_CORE_SUITE]}
695        self.mod_finder.module_info.get_module_info.return_value = mod_info
696        self.assertEqual(self.mod_finder._get_build_targets('', ''),
697                         {constants.VTS_CORE_TF_MODULE})
698
699    def test_get_build_targets_w_mts(self):
700        """Test _get_build_targets if module belong to mts."""
701        self.mod_finder.module_info.is_auto_gen_test_config.return_value = True
702        self.mod_finder.module_info.get_paths.return_value = []
703        mod_info = {constants.MODULE_COMPATIBILITY_SUITES:
704                        [constants.MTS_SUITE]}
705        self.mod_finder.module_info.get_module_info.return_value = mod_info
706        self.assertEqual(self.mod_finder._get_build_targets('', ''),
707                         {constants.CTS_JAR})
708
709    @mock.patch.object(test_finder_utils, 'is_parameterized_java_class',
710                       return_value=False)
711    @mock.patch.object(module_finder.ModuleFinder, '_is_vts_module',
712                       return_value=False)
713    @mock.patch.object(module_finder.ModuleFinder, '_get_build_targets')
714    @mock.patch('subprocess.check_output', return_value='')
715    @mock.patch.object(test_finder_utils, 'get_fully_qualified_class_name',
716                       return_value=uc.FULL_CLASS_NAME)
717    @mock.patch('os.path.isfile', side_effect=unittest_utils.isfile_side_effect)
718    @mock.patch('os.path.isdir', return_value=True)
719    #pylint: disable=unused-argument
720    def test_find_test_by_class_name_w_module(self, _isdir, _isfile, _fqcn,
721                                              mock_checkoutput, mock_build,
722                                              _vts, _is_parameterized):
723        """Test test_find_test_by_class_name with module but without class found."""
724        mock_build.return_value = uc.CLASS_BUILD_TARGETS
725        self.mod_finder.module_info.is_auto_gen_test_config.return_value = False
726        self.mod_finder.module_info.is_robolectric_test.return_value = False
727        self.mod_finder.module_info.has_test_config.return_value = True
728        self.mod_finder.module_info.get_module_names.return_value = [uc.MODULE_NAME]
729        self.mod_finder.module_info.get_module_info.return_value = {
730            constants.MODULE_INSTALLED: DEFAULT_INSTALL_PATH,
731            constants.MODULE_NAME: uc.MODULE_NAME,
732            constants.MODULE_CLASS: [],
733            constants.MODULE_COMPATIBILITY_SUITES: []}
734        self.mod_finder.module_info.get_paths.return_value = [uc.TEST_DATA_CONFIG]
735        self.mod_finder.module_info.get_robolectric_type.return_value = 0
736        t_infos = self.mod_finder.find_test_by_class_name(
737            uc.FULL_CLASS_NAME, module_name=uc.MODULE_NAME,
738            rel_config=uc.CONFIG_FILE)
739        unittest_utils.assert_equal_testinfos(
740            self, t_infos[0], uc.CLASS_INFO)
741
742    @mock.patch.object(module_finder.ModuleFinder, '_is_vts_module',
743                       return_value=False)
744    @mock.patch.object(module_finder.ModuleFinder, '_get_build_targets')
745    @mock.patch('subprocess.check_output', return_value='')
746    @mock.patch('os.path.isfile', side_effect=unittest_utils.isfile_side_effect)
747    @mock.patch('os.path.isdir', return_value=True)
748    #pylint: disable=unused-argument
749    def test_find_test_by_package_name_w_module(self, _isdir, _isfile,
750                                                mock_checkoutput, mock_build,
751                                                _vts):
752        """Test find_test_by_package_name with module but without package found."""
753        self.mod_finder.module_info.is_auto_gen_test_config.return_value = False
754        self.mod_finder.module_info.is_robolectric_test.return_value = False
755        self.mod_finder.module_info.has_test_config.return_value = True
756        mock_build.return_value = uc.CLASS_BUILD_TARGETS
757        self.mod_finder.module_info.get_module_names.return_value = [uc.MODULE_NAME]
758        self.mod_finder.module_info.get_module_info.return_value = {
759            constants.MODULE_INSTALLED: DEFAULT_INSTALL_PATH,
760            constants.MODULE_NAME: uc.MODULE_NAME,
761            constants.MODULE_CLASS: [],
762            constants.MODULE_COMPATIBILITY_SUITES: []
763        }
764        self.mod_finder.module_info.get_paths.return_value = [uc.TEST_DATA_CONFIG]
765        self.mod_finder.module_info.get_robolectric_type.return_value = 0
766        t_infos = self.mod_finder.find_test_by_package_name(
767            uc.PACKAGE, module_name=uc.MODULE_NAME, rel_config=uc.CONFIG_FILE)
768        unittest_utils.assert_equal_testinfos(
769            self, t_infos[0],
770            uc.PACKAGE_INFO)
771
772    @mock.patch.object(atest_utils, 'is_build_file', return_value=True)
773    @mock.patch.object(test_finder_utils, 'is_parameterized_java_class',
774                       return_value=True)
775    @mock.patch.object(test_finder_utils, 'has_method_in_file',
776                       return_value=True)
777    @mock.patch.object(test_finder_utils, 'has_cc_class',
778                       return_value=True)
779    @mock.patch.object(module_finder.ModuleFinder, '_get_build_targets')
780    @mock.patch.object(module_finder.ModuleFinder, '_is_vts_module',
781                       return_value=False)
782    @mock.patch.object(test_finder_utils, 'get_fully_qualified_class_name',
783                       return_value=uc.FULL_CLASS_NAME)
784    @mock.patch('os.path.realpath',
785                side_effect=unittest_utils.realpath_side_effect)
786    @mock.patch('os.path.isfile', side_effect=unittest_utils.isfile_side_effect)
787    @mock.patch.object(test_finder_utils, 'find_parent_module_dir')
788    @mock.patch('os.path.exists')
789    #pylint: disable=unused-argument
790    def test_find_test_by_path_is_parameterized_java(
791            self, mock_pathexists, mock_dir, _isfile, _real, _fqcn, _vts,
792            mock_build, _has_cc_class, _has_method_in_file, _is_parameterized,
793            _is_build_file):
794        """Test find_test_by_path and input path is parameterized class."""
795        self.mod_finder.module_info.is_robolectric_test.return_value = False
796        self.mod_finder.module_info.has_test_config.return_value = True
797        mock_build.return_value = set()
798        mock_pathexists.return_value = True
799        self.mod_finder.module_info.get_module_names.return_value = [uc.MODULE_NAME]
800        self.mod_finder.module_info.get_module_info.return_value = {
801            constants.MODULE_INSTALLED: DEFAULT_INSTALL_PATH,
802            constants.MODULE_NAME: uc.MODULE_NAME,
803            constants.MODULE_CLASS: [],
804            constants.MODULE_COMPATIBILITY_SUITES: []}
805        self.mod_finder.module_info.get_robolectric_type.return_value = 0
806        # Happy path testing.
807        mock_dir.return_value = uc.MODULE_DIR
808        class_path = '%s.java' % uc.CLASS_NAME
809        # Input include only one method
810        class_with_method = '%s#%s' % (class_path, uc.METHOD_NAME)
811        mock_build.return_value = copy.deepcopy(uc.MODULE_BUILD_TARGETS)
812        t_infos = self.mod_finder.find_test_by_path(class_with_method)
813        unittest_utils.assert_equal_testinfos(
814            self, t_infos[0], uc.PARAMETERIZED_METHOD_INFO)
815        # Input include multiple methods
816        class_with_methods = '%s,%s' % (class_with_method, uc.METHOD2_NAME)
817        mock_build.return_value = copy.deepcopy(uc.MODULE_BUILD_TARGETS)
818        t_infos = self.mod_finder.find_test_by_path(class_with_methods)
819        unittest_utils.assert_equal_testinfos(
820            self, t_infos[0], uc.PARAMETERIZED_FLAT_METHOD_INFO)
821
822    @mock.patch.object(test_finder_utils, 'find_host_unit_tests',
823                           return_value=[])
824    @mock.patch.object(atest_utils, 'is_build_file', return_value=True)
825    @mock.patch.object(test_finder_utils, 'is_parameterized_java_class',
826                       return_value=True)
827    @mock.patch.object(test_finder_utils, 'has_method_in_file',
828                       return_value=True)
829    @mock.patch.object(module_finder.ModuleFinder, '_is_vts_module',
830                       return_value=False)
831    @mock.patch.object(module_finder.ModuleFinder, '_get_build_targets')
832    @mock.patch('subprocess.check_output', return_value=uc.FIND_ONE)
833    @mock.patch.object(test_finder_utils, 'get_fully_qualified_class_name',
834                       return_value=uc.FULL_CLASS_NAME)
835    @mock.patch('os.path.isfile', side_effect=unittest_utils.isfile_side_effect)
836    @mock.patch('os.path.isdir', return_value=True)
837    #pylint: disable=unused-argument
838    def test_find_test_by_class_name_is_parameterized(
839            self, _isdir, _isfile, _fqcn, mock_checkoutput, mock_build, _vts,
840            _has_method_in_file, _is_parameterized, _is_build_file,
841            _mock_unit_tests):
842        """Test find_test_by_class_name and the class is parameterized java."""
843        mock_build.return_value = uc.CLASS_BUILD_TARGETS
844        self.mod_finder.module_info.is_auto_gen_test_config.return_value = False
845        self.mod_finder.module_info.is_robolectric_test.return_value = False
846        self.mod_finder.module_info.has_test_config.return_value = True
847        self.mod_finder.module_info.get_module_names.return_value = [uc.MODULE_NAME]
848        self.mod_finder.module_info.get_module_info.return_value = {
849            constants.MODULE_INSTALLED: DEFAULT_INSTALL_PATH,
850            constants.MODULE_NAME: uc.MODULE_NAME,
851            constants.MODULE_CLASS: [],
852            constants.MODULE_COMPATIBILITY_SUITES: []}
853        # With method
854        mock_build.return_value = copy.deepcopy(uc.MODULE_BUILD_TARGETS)
855        self.mod_finder.module_info.get_robolectric_type.return_value = 0
856        class_with_method = '%s#%s' % (uc.CLASS_NAME, uc.METHOD_NAME)
857        t_infos = self.mod_finder.find_test_by_class_name(class_with_method)
858        unittest_utils.assert_equal_testinfos(
859            self, t_infos[0], uc.PARAMETERIZED_METHOD_INFO)
860        # With multiple method
861        mock_build.return_value = copy.deepcopy(uc.MODULE_BUILD_TARGETS)
862        class_methods = '%s,%s' % (class_with_method, uc.METHOD2_NAME)
863        t_infos = self.mod_finder.find_test_by_class_name(class_methods)
864        unittest_utils.assert_equal_testinfos(
865            self, t_infos[0], uc.PARAMETERIZED_FLAT_METHOD_INFO)
866
867    # pylint: disable=unused-argument
868    @mock.patch.object(module_finder.ModuleFinder, '_get_build_targets',
869                       return_value=copy.deepcopy(uc.MODULE_BUILD_TARGETS))
870    def test_find_test_by_config_name(self, _get_targ):
871        """Test find_test_by_config_name."""
872        self.mod_finder.module_info.is_robolectric_test.return_value = False
873        self.mod_finder.module_info.has_test_config.return_value = True
874
875        mod_info = {'installed': ['/path/to/install'],
876                    'path': [uc.MODULE_DIR],
877                    constants.MODULE_TEST_CONFIG: [uc.CONFIG_FILE,
878                                                   uc.EXTRA_CONFIG_FILE],
879                    constants.MODULE_CLASS: [],
880                    constants.MODULE_COMPATIBILITY_SUITES: []}
881        name_to_module_info = {uc.MODULE_NAME: mod_info}
882        self.mod_finder.module_info.name_to_module_info = name_to_module_info
883        t_infos = self.mod_finder.find_test_by_config_name(uc.MODULE_CONFIG_NAME)
884        unittest_utils.assert_equal_testinfos(
885            self,
886            t_infos[0],
887            uc.TEST_CONFIG_MODULE_INFO)
888
889    @mock.patch.object(test_finder_utils, 'is_parameterized_java_class',
890                       return_value=False)
891    @mock.patch.object(test_finder_utils, 'has_method_in_file',
892                       return_value=True)
893    @mock.patch.object(test_finder_utils, 'has_cc_class',
894                       return_value=True)
895    @mock.patch.object(module_finder.ModuleFinder, '_get_build_targets')
896    @mock.patch.object(module_finder.ModuleFinder, '_is_vts_module',
897                       return_value=False)
898    @mock.patch.object(test_finder_utils, 'get_fully_qualified_class_name',
899                       return_value=uc.FULL_CLASS_NAME)
900    @mock.patch('os.path.realpath',
901                side_effect=unittest_utils.realpath_side_effect)
902    @mock.patch('os.path.isfile', side_effect=unittest_utils.isfile_side_effect)
903    @mock.patch.object(test_finder_utils, 'find_parent_module_dir')
904    @mock.patch('os.path.exists')
905    #pylint: disable=unused-argument
906    def test_find_test_by_path_w_src_verify(
907            self, mock_pathexists, mock_dir, _isfile, _real, _fqcn, _vts,
908            mock_build, _has_cc_class, _has_method_in_file, _is_parameterized):
909        """Test find_test_by_path with src information."""
910        self.mod_finder.module_info.is_robolectric_test.return_value = False
911        self.mod_finder.module_info.has_test_config.return_value = True
912        self.mod_finder.module_info.get_module_names.return_value = [uc.MODULE_NAME]
913        mock_build.return_value = uc.CLASS_BUILD_TARGETS
914
915        # Happy path testing.
916        mock_dir.return_value = uc.MODULE_DIR
917        # Test path not in module's src list.
918        class_path = '%s.java' % uc.CLASS_NAME
919        self.mod_finder.module_info.get_module_info.return_value = {
920            constants.MODULE_INSTALLED: DEFAULT_INSTALL_PATH,
921            constants.MODULE_NAME: uc.MODULE_NAME,
922            constants.MODULE_CLASS: [],
923            constants.MODULE_COMPATIBILITY_SUITES: [],
924            constants.MODULE_SRCS: ['not_matched_%s' % class_path]}
925        t_infos = self.mod_finder.find_test_by_path(class_path)
926        self.assertEqual(0, len(t_infos))
927
928        # Test input file is in module's src list.
929        class_path = '%s.java' % uc.CLASS_NAME
930        self.mod_finder.module_info.get_module_info.return_value = {
931            constants.MODULE_INSTALLED: DEFAULT_INSTALL_PATH,
932            constants.MODULE_NAME: uc.MODULE_NAME,
933            constants.MODULE_CLASS: [],
934            constants.MODULE_COMPATIBILITY_SUITES: [],
935            constants.MODULE_SRCS: [class_path]}
936        self.mod_finder.module_info.get_robolectric_type.return_value = 0
937        t_infos = self.mod_finder.find_test_by_path(class_path)
938        unittest_utils.assert_equal_testinfos(self, uc.CLASS_INFO, t_infos[0])
939
940    @mock.patch.object(test_finder_utils, 'get_cc_class_info')
941    @mock.patch.object(atest_utils, 'is_build_file', return_value=True)
942    @mock.patch.object(test_finder_utils, 'is_parameterized_java_class',
943                       return_value=False)
944    @mock.patch.object(test_finder_utils, 'has_method_in_file',
945                       return_value=True)
946    @mock.patch.object(test_finder_utils, 'has_cc_class',
947                       return_value=True)
948    @mock.patch.object(module_finder.ModuleFinder, '_get_build_targets')
949    @mock.patch.object(module_finder.ModuleFinder, '_is_vts_module',
950                       return_value=False)
951    @mock.patch.object(test_finder_utils, 'get_fully_qualified_class_name',
952                       return_value=uc.FULL_CLASS_NAME)
953    @mock.patch('os.path.realpath',
954                side_effect=unittest_utils.realpath_side_effect)
955    @mock.patch('os.path.isfile', side_effect=unittest_utils.isfile_side_effect)
956    @mock.patch.object(test_finder_utils, 'find_parent_module_dir')
957    @mock.patch('os.path.exists')
958    #pylint: disable=unused-argument
959    def test_find_test_by_path_for_cc_file(self, mock_pathexists, mock_dir,
960        _isfile, _real, _fqcn, _vts, mock_build, _has_cc_class,
961        _has_method_in_file, _is_parameterized, _is_build_file,
962        _mock_cc_class_info):
963        """Test find_test_by_path for handling correct CC filter."""
964        self.mod_finder.module_info.is_robolectric_test.return_value = False
965        self.mod_finder.module_info.has_test_config.return_value = True
966        mock_build.return_value = set()
967        # Check that we don't return anything with invalid test references.
968        mock_pathexists.return_value = False
969        mock_pathexists.return_value = True
970        mock_dir.return_value = None
971        self.mod_finder.module_info.get_module_names.return_value = [uc.MODULE_NAME]
972        self.mod_finder.module_info.get_module_info.return_value = {
973            constants.MODULE_INSTALLED: DEFAULT_INSTALL_PATH,
974            constants.MODULE_NAME: uc.MODULE_NAME,
975            constants.MODULE_CLASS: [],
976            constants.MODULE_COMPATIBILITY_SUITES: []}
977        # Happy path testing.
978        mock_dir.return_value = uc.MODULE_DIR
979        # Cc path testing if get_cc_class_info found those information.
980        self.mod_finder.module_info.get_module_names.return_value = [uc.CC_MODULE_NAME]
981        self.mod_finder.module_info.get_module_info.return_value = {
982            constants.MODULE_INSTALLED: DEFAULT_INSTALL_PATH,
983            constants.MODULE_NAME: uc.CC_MODULE_NAME,
984            constants.MODULE_CLASS: [],
985            constants.MODULE_COMPATIBILITY_SUITES: []}
986        mock_dir.return_value = uc.CC_MODULE_DIR
987        class_path = '%s' % uc.CC_PATH
988        mock_build.return_value = uc.CLASS_BUILD_TARGETS
989        # Test without parameterized test
990        founded_classed = 'class1'
991        founded_methods = {'method1'}
992        founded_prefixes = set()
993        _mock_cc_class_info.return_value = {founded_classed: {
994                                              'methods': founded_methods,
995                                              'prefixes': founded_prefixes,
996                                              'typed': False}}
997        self.mod_finder.module_info.get_robolectric_type.return_value = 0
998        cc_path_data = {constants.TI_REL_CONFIG: uc.CC_CONFIG_FILE,
999                        constants.TI_FILTER: frozenset(
1000                            {test_info.TestFilter(class_name='class1.*',
1001                                                  methods=frozenset())})}
1002        cc_path_info = test_info.TestInfo(uc.CC_MODULE_NAME,
1003                                          atf_tr.AtestTradefedTestRunner.NAME,
1004                                          uc.CLASS_BUILD_TARGETS, cc_path_data)
1005        t_infos = self.mod_finder.find_test_by_path(class_path)
1006        unittest_utils.assert_equal_testinfos(self, cc_path_info, t_infos[0])
1007        # Test with paramertize test defined in input path
1008        founded_prefixes = {'class1'}
1009        _mock_cc_class_info.return_value = {founded_classed: {
1010                                              'methods': founded_methods,
1011                                              'prefixes': founded_prefixes,
1012                                              'typed': False}}
1013        cc_path_data = {constants.TI_REL_CONFIG: uc.CC_CONFIG_FILE,
1014                        constants.TI_FILTER: frozenset(
1015                            {test_info.TestFilter(class_name='*/class1.*',
1016                                                  methods=frozenset())})}
1017        cc_path_info = test_info.TestInfo(uc.CC_MODULE_NAME,
1018                                          atf_tr.AtestTradefedTestRunner.NAME,
1019                                          uc.CLASS_BUILD_TARGETS, cc_path_data)
1020        t_infos = self.mod_finder.find_test_by_path(class_path)
1021        unittest_utils.assert_equal_testinfos(self, cc_path_info, t_infos[0])
1022
1023    # pylint: disable=unused-argument
1024    @mock.patch.object(module_finder.ModuleFinder, '_is_vts_module',
1025                       return_value=False)
1026    @mock.patch.object(module_finder.ModuleFinder, '_get_build_targets',
1027                       return_value=copy.deepcopy(uc.MODULE_BUILD_TARGETS))
1028    def test_process_test_info(self, _get_targ, _is_vts):
1029        """Test _process_test_info."""
1030        mod_info = {'installed': ['/path/to/install'],
1031                    'path': [uc.MODULE_DIR],
1032                    constants.MODULE_CLASS: [
1033                        constants.MODULE_CLASS_JAVA_LIBRARIES],
1034                    constants.MODULE_COMPATIBILITY_SUITES: []}
1035        self.mod_finder.module_info.is_robolectric_test.return_value = False
1036        self.mod_finder.module_info.is_auto_gen_test_config.return_value = True
1037        self.mod_finder.module_info.get_robolectric_type.return_value = 0
1038        self.mod_finder.module_info.get_module_info.return_value = mod_info
1039        processed_info = self.mod_finder._process_test_info(
1040            copy.copy(uc.MODULE_INFO))
1041        unittest_utils.assert_equal_testinfos(
1042            self,
1043            processed_info,
1044            uc.MODULE_INFO_W_DALVIK)
1045
1046    @mock.patch.object(test_finder_utils, 'get_annotated_methods')
1047    def test_is_srcs_match_method_annotation_include_anno(
1048        self, _mock_get_anno_methods):
1049        """Test _is_srcs_match_method_annotation with include annotation."""
1050        annotation_dict = {constants.INCLUDE_ANNOTATION: 'includeAnnotation1'}
1051        input_method = 'my_input_method'
1052        input_srcs = ['src1']
1053        # Test if input method matched include annotation.
1054        _mock_get_anno_methods.return_value = {input_method,
1055                                               'not_my_input_method'}
1056
1057        is_matched = self.mod_finder._is_srcs_match_method_annotation(
1058            input_method, input_srcs, annotation_dict)
1059
1060        self.assertTrue(is_matched)
1061        # Test if input method not matched include annotation.
1062        _mock_get_anno_methods.return_value = {'not_my_input_method'}
1063
1064        is_matched = self.mod_finder._is_srcs_match_method_annotation(
1065            input_method, input_srcs, annotation_dict)
1066
1067        self.assertFalse(is_matched)
1068
1069    @mock.patch.object(test_finder_utils, 'get_annotated_methods')
1070    @mock.patch.object(test_finder_utils, 'get_java_methods')
1071    def test_is_srcs_match_method_exclude_anno(self, _mock_get_java_methods,
1072        _mock_get_exclude_anno_methods):
1073        """Test _is_srcs_match_method_annotation with exclude annotation."""
1074        annotation_dict = {constants.EXCLUDE_ANNOTATION: 'excludeAnnotation1'}
1075        input_method = 'my_input_method'
1076        input_srcs = ['src1']
1077        _mock_get_java_methods.return_value = {input_method,
1078                                               'method1',
1079                                               'method2'}
1080        # Test if input method matched exclude annotation.
1081        _mock_get_exclude_anno_methods.return_value = {input_method, 'method1'}
1082
1083        is_matched = self.mod_finder._is_srcs_match_method_annotation(
1084            input_method, input_srcs, annotation_dict)
1085
1086        self.assertFalse(is_matched)
1087
1088        # Test if input method not matched exclude annotation.
1089        _mock_get_exclude_anno_methods.return_value = {'method2'}
1090
1091        is_matched = self.mod_finder._is_srcs_match_method_annotation(
1092            input_method, input_srcs, annotation_dict)
1093
1094        self.assertTrue(is_matched)
1095
1096    @mock.patch.object(atest_utils, 'get_android_junit_config_filters')
1097    @mock.patch.object(test_finder_utils, 'get_test_config_and_srcs')
1098    def test_get_matched_test_infos_no_filter(self, _mock_get_conf_srcs,
1099        _mock_get_filters):
1100        """Test _get_matched_test_infos without test filters."""
1101        test_info1 = 'test_info1'
1102        test_infos = [test_info1]
1103        test_config = 'test_config'
1104        test_srcs = ['src1', 'src2']
1105        _mock_get_conf_srcs.return_value = test_config, test_srcs
1106        filter_dict = {}
1107        _mock_get_filters.return_value = filter_dict
1108
1109        self.assertEqual(
1110            self.mod_finder._get_matched_test_infos(test_infos, {'method'}),
1111            test_infos)
1112
1113    @mock.patch.object(module_finder.ModuleFinder,
1114                       '_is_srcs_match_method_annotation')
1115    @mock.patch.object(atest_utils, 'get_android_junit_config_filters')
1116    @mock.patch.object(test_finder_utils, 'get_test_config_and_srcs')
1117    def test_get_matched_test_infos_get_filter_method_match(
1118        self, _mock_get_conf_srcs, _mock_get_filters, _mock_method_match):
1119        """Test _get_matched_test_infos with test filters and method match."""
1120        test_infos = [KERNEL_MODULE_CLASS_INFO]
1121        test_config = 'test_config'
1122        test_srcs = ['src1', 'src2']
1123        _mock_get_conf_srcs.return_value = test_config, test_srcs
1124        filter_dict = {'include-annotation': 'annotate1'}
1125        _mock_get_filters.return_value = filter_dict
1126        _mock_method_match.return_value = True
1127
1128        unittest_utils.assert_strict_equal(
1129            self,
1130            self.mod_finder._get_matched_test_infos(test_infos, {'method'}),
1131            test_infos)
1132
1133    @mock.patch.object(module_finder.ModuleFinder,
1134                       '_is_srcs_match_method_annotation')
1135    @mock.patch.object(atest_utils, 'get_android_junit_config_filters')
1136    @mock.patch.object(test_finder_utils, 'get_test_config_and_srcs')
1137    def test_get_matched_test_infos_filter_method_not_match(
1138        self, _mock_get_conf_srcs, _mock_get_filters, _mock_method_match):
1139        """Test _get_matched_test_infos but method not match."""
1140        test_infos = [KERNEL_MODULE_CLASS_INFO]
1141        test_config = 'test_config'
1142        test_srcs = ['src1', 'src2']
1143        _mock_get_conf_srcs.return_value = test_config, test_srcs
1144        filter_dict = {'include-annotation': 'annotate1'}
1145        _mock_get_filters.return_value = filter_dict
1146        _mock_method_match.return_value = False
1147
1148        self.assertEqual(
1149            self.mod_finder._get_matched_test_infos(test_infos, {'method'}),
1150            [])
1151
1152    @mock.patch.object(module_finder.ModuleFinder, '_get_matched_test_infos')
1153    @mock.patch.object(module_finder.ModuleFinder, '_get_test_infos',
1154                       return_value=uc.MODULE_INFO)
1155    @mock.patch.object(module_finder.ModuleFinder, '_get_test_info_filter',
1156                       return_value=uc.CLASS_FILTER)
1157    @mock.patch.object(test_finder_utils, 'find_class_file',
1158                       return_value=['path1'])
1159    def test_find_test_by_class_name_not_matched_filters(
1160        self, _mock_class_path, _mock_test_filters,
1161        _mock_test_infos, _mock_matched_test_infos):
1162        """Test find_test_by_class_name which has not matched filters."""
1163        found_test_infos = [uc.MODULE_INFO, uc.MODULE_INFO2]
1164        _mock_test_infos.return_value = found_test_infos
1165        matched_test_infos = [uc.MODULE_INFO2]
1166        _mock_matched_test_infos.return_value = matched_test_infos
1167
1168        # Test if class without method
1169        test_infos = self.mod_finder.find_test_by_class_name('my.test.class')
1170        self.assertEqual(len(test_infos), 2)
1171        unittest_utils.assert_equal_testinfos(
1172            self, test_infos[0], uc.MODULE_INFO)
1173        unittest_utils.assert_equal_testinfos(
1174            self, test_infos[1], uc.MODULE_INFO2)
1175
1176        # Test if class with method
1177        test_infos = self.mod_finder.find_test_by_class_name(
1178            'my.test.class#myMethod')
1179        self.assertEqual(len(test_infos), 1)
1180        unittest_utils.assert_equal_testinfos(
1181            self, test_infos[0], uc.MODULE_INFO2)
1182
1183    @mock.patch.object(module_finder.ModuleFinder, '_get_test_infos',
1184                       return_value=None)
1185    @mock.patch.object(module_finder.ModuleFinder, '_get_test_info_filter',
1186                       return_value=uc.CLASS_FILTER)
1187    @mock.patch.object(test_finder_utils, 'find_class_file',
1188                       return_value=['path1'])
1189    def test_find_test_by_class_name_get_test_infos_none(
1190        self, _mock_class_path, _mock_test_filters, _mock_test_infos):
1191        """Test find_test_by_class_name which has not matched test infos."""
1192        self.assertEqual(
1193            self.mod_finder.find_test_by_class_name('my.test.class'),
1194            None)
1195
1196if __name__ == '__main__':
1197    unittest.main()
1198