• 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=invalid-name
20# pylint: disable=line-too-long
21# pylint: disable=missing-function-docstring
22# pylint: disable=too-many-lines
23# pylint: disable=unsubscriptable-object
24
25import copy
26import re
27import tempfile
28import unittest
29import os
30
31from pathlib import Path
32from unittest import mock
33
34# pylint: disable=import-error
35from pyfakefs import fake_filesystem_unittest
36
37from atest import atest_error
38from atest import atest_configs
39from atest import atest_utils
40from atest import constants
41from atest import module_info
42from atest import unittest_constants as uc
43from atest import unittest_utils
44
45from atest.test_finders import module_finder
46from atest.test_finders import test_finder_utils
47from atest.test_finders import test_info
48from atest.test_runners import atest_tf_test_runner as atf_tr
49
50MODULE_CLASS = '%s:%s' % (uc.MODULE_NAME, uc.CLASS_NAME)
51MODULE_PACKAGE = '%s:%s' % (uc.MODULE_NAME, uc.PACKAGE)
52CC_MODULE_CLASS = '%s:%s' % (uc.CC_MODULE_NAME, uc.CC_CLASS_NAME)
53KERNEL_TEST_CLASS = 'test_class_1'
54KERNEL_TEST_CONFIG = 'KernelTest.xml.data'
55KERNEL_MODULE_CLASS = '%s:%s' % (constants.REQUIRED_LTP_TEST_MODULES[0],
56                                 KERNEL_TEST_CLASS)
57KERNEL_CONFIG_FILE = os.path.join(uc.TEST_DATA_DIR, KERNEL_TEST_CONFIG)
58KERNEL_CLASS_FILTER = test_info.TestFilter(KERNEL_TEST_CLASS, frozenset())
59KERNEL_MODULE_CLASS_DATA = {constants.TI_REL_CONFIG: KERNEL_CONFIG_FILE,
60                            constants.TI_FILTER: frozenset([KERNEL_CLASS_FILTER])}
61KERNEL_MODULE_CLASS_INFO = test_info.TestInfo(
62    constants.REQUIRED_LTP_TEST_MODULES[0],
63    atf_tr.AtestTradefedTestRunner.NAME,
64    uc.CLASS_BUILD_TARGETS, KERNEL_MODULE_CLASS_DATA)
65FLAT_METHOD_INFO = test_info.TestInfo(
66    uc.MODULE_NAME,
67    atf_tr.AtestTradefedTestRunner.NAME,
68    uc.MODULE_BUILD_TARGETS,
69    data={constants.TI_FILTER: frozenset([uc.FLAT_METHOD_FILTER]),
70          constants.TI_REL_CONFIG: uc.CONFIG_FILE})
71MODULE_CLASS_METHOD = '%s#%s' % (MODULE_CLASS, uc.METHOD_NAME)
72CC_MODULE_CLASS_METHOD = '%s#%s' % (CC_MODULE_CLASS, uc.CC_METHOD_NAME)
73CLASS_INFO_MODULE_2 = test_info.TestInfo(
74    uc.MODULE2_NAME,
75    atf_tr.AtestTradefedTestRunner.NAME,
76    uc.CLASS_BUILD_TARGETS,
77    data={constants.TI_FILTER: frozenset([uc.CLASS_FILTER]),
78          constants.TI_REL_CONFIG: uc.CONFIG2_FILE})
79CC_CLASS_INFO_MODULE_2 = test_info.TestInfo(
80    uc.CC_MODULE2_NAME,
81    atf_tr.AtestTradefedTestRunner.NAME,
82    uc.CLASS_BUILD_TARGETS,
83    data={constants.TI_FILTER: frozenset([uc.CC_CLASS_FILTER]),
84          constants.TI_REL_CONFIG: uc.CC_CONFIG2_FILE})
85DEFAULT_INSTALL_PATH = ['/path/to/install']
86ROBO_MOD_PATH = ['/shared/robo/path']
87NON_RUN_ROBO_MOD_NAME = 'robo_mod'
88RUN_ROBO_MOD_NAME = 'run_robo_mod'
89NON_RUN_ROBO_MOD = {constants.MODULE_NAME: NON_RUN_ROBO_MOD_NAME,
90                    constants.MODULE_PATH: ROBO_MOD_PATH,
91                    constants.MODULE_CLASS: ['random_class']}
92RUN_ROBO_MOD = {constants.MODULE_NAME: RUN_ROBO_MOD_NAME,
93                constants.MODULE_PATH: ROBO_MOD_PATH,
94                constants.MODULE_CLASS: [constants.MODULE_CLASS_ROBOLECTRIC]}
95
96SEARCH_DIR_RE = re.compile(r'^find ([^ ]*).*$')
97
98#pylint: disable=unused-argument
99def classoutside_side_effect(find_cmd, shell=False):
100    """Mock the check output of a find cmd where class outside module path."""
101    search_dir = SEARCH_DIR_RE.match(find_cmd).group(1).strip()
102    if search_dir == uc.ROOT:
103        return uc.FIND_ONE
104    return None
105
106class ModuleFinderFindTestByModuleName(fake_filesystem_unittest.TestCase):
107    """Unit tests for module_finder.py"""
108
109    def setUp(self):
110        self.setUpPyfakefs()
111        self.build_top = Path('/')
112        self.product_out = self.build_top.joinpath('out/product')
113        self.product_out.mkdir(parents=True, exist_ok=True)
114        self.module_info_file = self.product_out.joinpath('atest_merged_dep.json')
115        self.fs.create_file(
116            self.module_info_file,
117            contents=('''
118                { "CtsJankDeviceTestCases": {
119                    "class":["APPS"],
120                    "path":["foo/bar/jank"],
121                    "tags": ["optional"],
122                    "installed": ["path/to/install/CtsJankDeviceTestCases.apk"],
123                    "test_config": ["foo/bar/jank/AndroidTest.xml",
124                                    "foo/bar/jank/CtsJankDeviceTestCases2.xml"],
125                    "module_name": "CtsJankDeviceTestCases" }
126                }''')
127            )
128
129    @mock.patch('builtins.input', return_value='1')
130    def test_find_test_by_module_name_w_multiple_config(self, _):
131        """Test find_test_by_module_name (test_config_select)"""
132        atest_configs.GLOBAL_ARGS = mock.Mock()
133        atest_configs.GLOBAL_ARGS.test_config_select = True
134        # The original test name will be updated to the config name when multiple
135        # configs were found.
136        expected_test_info = create_test_info(
137            test_name='CtsJankDeviceTestCases2',
138            raw_test_name='CtsJankDeviceTestCases',
139            test_runner='AtestTradefedTestRunner',
140            module_class=['APPS'],
141            build_targets={'MODULES-IN-foo-bar-jank', 'CtsJankDeviceTestCases'},
142            data={'rel_config': 'foo/bar/jank/CtsJankDeviceTestCases2.xml',
143                  'filter': frozenset()}
144            )
145        self.fs.create_file(
146            self.build_top.joinpath('foo/bar/jank/CtsJankDeviceTestCases2.xml'),
147            contents=('''
148                <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
149                    <option name="test-file-name" value="CtsUiDeviceTestCases.apk" />
150                </target_preparer>
151            ''')
152            )
153
154        mod_info = module_info.ModuleInfo(module_file=self.module_info_file)
155        mod_finder = module_finder.ModuleFinder(module_info=mod_info)
156        t_infos = mod_finder.find_test_by_module_name('CtsJankDeviceTestCases')
157
158        self.assertEqual(len(t_infos), 1)
159        unittest_utils.assert_equal_testinfos(self,
160            t_infos[0], expected_test_info)
161
162    def test_find_test_by_module_name_w_multiple_config_all(self):
163        """Test find_test_by_module_name."""
164        atest_configs.GLOBAL_ARGS = mock.Mock()
165        atest_configs.GLOBAL_ARGS.test_config_select = False
166        expected_test_info = [
167            create_test_info(
168                test_name='CtsJankDeviceTestCases',
169                test_runner='AtestTradefedTestRunner',
170                module_class=['APPS'],
171                build_targets={'MODULES-IN-foo-bar-jank', 'CtsJankDeviceTestCases'},
172                data={'rel_config': 'foo/bar/jank/AndroidTest.xml',
173                      'filter': frozenset()}
174        ),
175            create_test_info(
176                test_name='CtsJankDeviceTestCases2',
177                raw_test_name='CtsJankDeviceTestCases',
178                test_runner='AtestTradefedTestRunner',
179                module_class=['APPS'],
180                build_targets={'MODULES-IN-foo-bar-jank', 'CtsJankDeviceTestCases'},
181                data={'rel_config': 'foo/bar/jank/CtsJankDeviceTestCases2.xml',
182                      'filter': frozenset()}
183            )]
184        self.fs.create_file(
185            self.build_top.joinpath('foo/bar/jank/AndroidTest.xml'),
186            contents=('''
187                <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
188                    <option name="test-file-name" value="CtsUiDeviceTestCases.apk" />
189                </target_preparer>
190            ''')
191            )
192
193        mod_info = module_info.ModuleInfo(module_file=self.module_info_file)
194        mod_finder = module_finder.ModuleFinder(module_info=mod_info)
195        t_infos = mod_finder.find_test_by_module_name('CtsJankDeviceTestCases')
196
197        self.assertEqual(len(t_infos), 2)
198        unittest_utils.assert_equal_testinfos(self,
199            t_infos[0], expected_test_info[0])
200        unittest_utils.assert_equal_testinfos(self,
201            t_infos[1], expected_test_info[1])
202
203class ModuleFinderFindTestByPath(fake_filesystem_unittest.TestCase):
204    """Test cases that invoke find_test_by_path."""
205    def setUp(self):
206        self.setUpPyfakefs()
207
208    # pylint: disable=protected-access
209    def create_empty_module_info(self):
210        fake_temp_file_name = next(tempfile._get_candidate_names())
211        self.fs.create_file(fake_temp_file_name, contents='{}')
212        return module_info.ModuleInfo(module_file=fake_temp_file_name)
213
214    def create_module_info(self, modules=None):
215        mod_info = self.create_empty_module_info()
216        modules = modules or []
217
218        for m in modules:
219            mod_info.name_to_module_info[m['module_name']] = m
220            for path in m['path']:
221                if path in mod_info.path_to_module_info:
222                    mod_info.path_to_module_info[path].append(m)
223                else:
224                    mod_info.path_to_module_info[path] = [m]
225
226        return mod_info
227
228    # TODO: remove below mocks and hide unnecessary information.
229    @mock.patch.object(module_finder.ModuleFinder, '_get_test_info_filter')
230    @mock.patch.object(test_finder_utils, 'find_parent_module_dir',
231                       return_value=None)
232    @mock.patch('os.path.exists')
233    #pylint: disable=unused-argument
234    def test_find_test_by_path_belong_to_dependencies(
235            self, _mock_exists, _mock_find_parent, _mock_test_filter):
236        """Test find_test_by_path if belong to test dependencies."""
237        test1 = module(name='test1',
238                       classes=['class'],
239                       dependencies=['lib1'],
240                       installed=['install/test1'],
241                       auto_test_config=[True])
242        test2 = module(name='test2',
243                       classes=['class'],
244                       dependencies=['lib2'],
245                       installed=['install/test2'],
246                       auto_test_config=[True])
247        lib1 = module(name='lib1',
248                      srcs=['path/src1'])
249        lib2 = module(name='lib2',
250                      srcs=['path/src2'])
251        mod_info = self.create_module_info(
252            [test1, test2, lib1, lib2])
253        mod_finder = module_finder.ModuleFinder(module_info=mod_info)
254        _mock_exists.return_value = True
255        test1_filter = test_info.TestFilter('test1Filter', frozenset())
256        _mock_test_filter.return_value = test1_filter
257
258        t_infos = mod_finder.find_test_by_path('path/src1')
259
260        unittest_utils.assert_equal_testinfos(
261            self,
262            test_info.TestInfo(
263                'test1',
264                atf_tr.AtestTradefedTestRunner.NAME,
265                {'test1', 'MODULES-IN-'},
266                {constants.TI_FILTER: test1_filter,
267                 constants.TI_REL_CONFIG: 'AndroidTest.xml'},
268                module_class=['class']),
269            t_infos[0])
270
271#pylint: disable=protected-access
272class ModuleFinderUnittests(unittest.TestCase):
273    """Unit tests for module_finder.py"""
274
275    def setUp(self):
276        """Set up stuff for testing."""
277        self.mod_finder = module_finder.ModuleFinder()
278        self.mod_finder.module_info = mock.Mock(spec=module_info.ModuleInfo)
279        self.mod_finder.module_info.path_to_module_info = {}
280        self.mod_finder.root_dir = uc.ROOT
281
282    def test_is_vts_module(self):
283        """Test _load_module_info_file regular operation."""
284        mod_name = 'mod'
285        is_vts_module_info = {'compatibility_suites': ['vts10', 'tests']}
286        self.mod_finder.module_info.get_module_info.return_value = is_vts_module_info
287        self.assertTrue(self.mod_finder._is_vts_module(mod_name))
288
289        is_not_vts_module = {'compatibility_suites': ['vts10', 'cts']}
290        self.mod_finder.module_info.get_module_info.return_value = is_not_vts_module
291        self.assertFalse(self.mod_finder._is_vts_module(mod_name))
292
293    # pylint: disable=unused-argument
294    @mock.patch.object(module_finder.ModuleFinder, '_get_build_targets',
295                       return_value=copy.deepcopy(uc.MODULE_BUILD_TARGETS))
296    def test_find_test_by_module_name(self, _get_targ):
297        """Test find_test_by_module_name."""
298        self.mod_finder.module_info.is_robolectric_test.return_value = False
299        self.mod_finder.module_info.get_instrumentation_target_apps.return_value = {}
300        self.mod_finder.module_info.has_test_config.return_value = True
301        mod_info = {'installed': ['/path/to/install'],
302                    'path': [uc.MODULE_DIR],
303                    constants.MODULE_CLASS: [],
304                    constants.MODULE_COMPATIBILITY_SUITES: []}
305        self.mod_finder.module_info.get_module_info.return_value = mod_info
306        self.mod_finder.module_info.get_robolectric_type.return_value = 0
307        t_infos = self.mod_finder.find_test_by_module_name(uc.MODULE_NAME)
308        unittest_utils.assert_equal_testinfos(
309            self,
310            t_infos[0],
311            uc.MODULE_INFO)
312        self.mod_finder.module_info.get_module_info.return_value = None
313        self.mod_finder.module_info.is_testable_module.return_value = False
314        self.assertIsNone(self.mod_finder.find_test_by_module_name('Not_Module'))
315
316    @mock.patch.object(test_finder_utils, 'find_host_unit_tests',
317                       return_value=[])
318    @mock.patch.object(atest_utils, 'is_build_file', return_value=True)
319    @mock.patch.object(test_finder_utils, 'is_parameterized_java_class',
320                       return_value=False)
321    @mock.patch.object(test_finder_utils, 'has_method_in_file',
322                       return_value=True)
323    @mock.patch.object(module_finder.ModuleFinder, '_is_vts_module',
324                       return_value=False)
325    @mock.patch.object(module_finder.ModuleFinder, '_get_build_targets')
326    @mock.patch('subprocess.check_output', return_value=uc.FIND_ONE)
327    @mock.patch.object(test_finder_utils, 'get_fully_qualified_class_name',
328                       return_value=uc.FULL_CLASS_NAME)
329    @mock.patch('os.path.isfile', side_effect=unittest_utils.isfile_side_effect)
330    @mock.patch('os.path.isdir', return_value=True)
331    #pylint: disable=unused-argument
332    def test_find_test_by_class_name(self, _isdir, _isfile, _fqcn,
333                                     mock_checkoutput, mock_build,
334                                     _vts, _has_method_in_file,
335                                     _is_parameterized, _is_build_file,
336                                     _mock_unit_tests):
337        """Test find_test_by_class_name."""
338        mock_build.return_value = uc.CLASS_BUILD_TARGETS
339        self.mod_finder.module_info.is_auto_gen_test_config.return_value = False
340        self.mod_finder.module_info.is_robolectric_test.return_value = False
341        self.mod_finder.module_info.get_instrumentation_target_apps.return_value = {}
342        self.mod_finder.module_info.has_test_config.return_value = True
343        self.mod_finder.module_info.get_module_names.return_value = [uc.MODULE_NAME]
344        self.mod_finder.module_info.get_module_info.return_value = {
345            constants.MODULE_INSTALLED: DEFAULT_INSTALL_PATH,
346            constants.MODULE_NAME: uc.MODULE_NAME,
347            constants.MODULE_CLASS: [],
348            constants.MODULE_COMPATIBILITY_SUITES: []}
349        self.mod_finder.module_info.get_robolectric_type.return_value = 0
350        t_infos = self.mod_finder.find_test_by_class_name(uc.CLASS_NAME)
351        unittest_utils.assert_equal_testinfos(
352            self, t_infos[0], uc.CLASS_INFO)
353
354        # with method
355        mock_build.return_value = copy.deepcopy(uc.MODULE_BUILD_TARGETS)
356        class_with_method = '%s#%s' % (uc.CLASS_NAME, uc.METHOD_NAME)
357        t_infos = self.mod_finder.find_test_by_class_name(class_with_method)
358        unittest_utils.assert_equal_testinfos(
359            self, t_infos[0], uc.METHOD_INFO)
360        mock_build.return_value = copy.deepcopy(uc.MODULE_BUILD_TARGETS)
361        class_methods = '%s,%s' % (class_with_method, uc.METHOD2_NAME)
362        t_infos = self.mod_finder.find_test_by_class_name(class_methods)
363        unittest_utils.assert_equal_testinfos(
364            self, t_infos[0],
365            FLAT_METHOD_INFO)
366        # module and rel_config passed in
367        mock_build.return_value = uc.CLASS_BUILD_TARGETS
368        t_infos = self.mod_finder.find_test_by_class_name(
369            uc.CLASS_NAME, uc.MODULE_NAME, uc.CONFIG_FILE)
370        unittest_utils.assert_equal_testinfos(
371            self, t_infos[0], uc.CLASS_INFO)
372        # find output fails to find class file
373        mock_checkoutput.return_value = ''
374        self.assertIsNone(self.mod_finder.find_test_by_class_name('Not class'))
375        # class is outside given module path
376        mock_checkoutput.side_effect = classoutside_side_effect
377        t_infos = self.mod_finder.find_test_by_class_name(uc.CLASS_NAME,
378                                                          uc.MODULE2_NAME,
379                                                          uc.CONFIG2_FILE)
380        unittest_utils.assert_equal_testinfos(
381            self, t_infos[0],
382            CLASS_INFO_MODULE_2)
383
384    @mock.patch.object(test_finder_utils, 'is_parameterized_java_class',
385                       return_value=False)
386    @mock.patch.object(test_finder_utils, 'has_method_in_file',
387                       return_value=True)
388    @mock.patch.object(module_finder.ModuleFinder, '_is_vts_module',
389                       return_value=False)
390    @mock.patch.object(module_finder.ModuleFinder, '_get_build_targets')
391    @mock.patch('subprocess.check_output', return_value=uc.FIND_ONE)
392    @mock.patch.object(test_finder_utils, 'get_fully_qualified_class_name',
393                       return_value=uc.FULL_CLASS_NAME)
394    @mock.patch('os.path.isfile', side_effect=unittest_utils.isfile_side_effect)
395    #pylint: disable=unused-argument
396    def test_find_test_by_module_and_class(self, _isfile, _fqcn,
397                                           mock_checkoutput, mock_build,
398                                           _vts, _has_method_in_file,
399                                           _is_parameterized):
400        """Test find_test_by_module_and_class."""
401        # Native test was tested in test_find_test_by_cc_class_name().
402        self.mod_finder.module_info.is_native_test.return_value = False
403        self.mod_finder.module_info.is_auto_gen_test_config.return_value = False
404        self.mod_finder.module_info.is_robolectric_test.return_value = False
405        self.mod_finder.module_info.has_test_config.return_value = True
406        mock_build.return_value = uc.CLASS_BUILD_TARGETS
407        mod_info = {constants.MODULE_INSTALLED: DEFAULT_INSTALL_PATH,
408                    constants.MODULE_PATH: [uc.MODULE_DIR],
409                    constants.MODULE_CLASS: [],
410                    constants.MODULE_COMPATIBILITY_SUITES: []}
411        self.mod_finder.module_info.get_module_info.return_value = mod_info
412        self.mod_finder.module_info.get_robolectric_type.return_value = 0
413        self.mod_finder.module_info.get_instrumentation_target_apps.return_value = {}
414        t_infos = self.mod_finder.find_test_by_module_and_class(MODULE_CLASS)
415        unittest_utils.assert_equal_testinfos(self, t_infos[0], uc.CLASS_INFO)
416        # with method
417        mock_build.return_value = copy.deepcopy(uc.MODULE_BUILD_TARGETS)
418        t_infos = self.mod_finder.find_test_by_module_and_class(MODULE_CLASS_METHOD)
419        unittest_utils.assert_equal_testinfos(self, t_infos[0], uc.METHOD_INFO)
420        self.mod_finder.module_info.is_testable_module.return_value = False
421        # bad module, good class, returns None
422        bad_module = '%s:%s' % ('BadMod', uc.CLASS_NAME)
423        self.mod_finder.module_info.get_module_info.return_value = None
424        self.assertIsNone(self.mod_finder.find_test_by_module_and_class(bad_module))
425        # find output fails to find class file
426        mock_checkoutput.return_value = ''
427        bad_class = '%s:%s' % (uc.MODULE_NAME, 'Anything')
428        self.mod_finder.module_info.get_module_info.return_value = mod_info
429        self.assertIsNone(self.mod_finder.find_test_by_module_and_class(bad_class))
430
431    @mock.patch.object(module_finder.test_finder_utils, 'get_cc_class_info')
432    @mock.patch.object(module_finder.ModuleFinder, 'find_test_by_kernel_class_name',
433                       return_value=None)
434    @mock.patch.object(module_finder.ModuleFinder, '_is_vts_module',
435                       return_value=False)
436    @mock.patch.object(module_finder.ModuleFinder, '_get_build_targets')
437    @mock.patch('subprocess.check_output', return_value=uc.FIND_CC_ONE)
438    @mock.patch.object(test_finder_utils, 'find_class_file',
439                       side_effect=[None, None, '/'])
440    @mock.patch('os.path.isfile', side_effect=unittest_utils.isfile_side_effect)
441    #pylint: disable=unused-argument
442    def test_find_test_by_module_and_class_part_2(self, _isfile, mock_fcf,
443                                                  mock_checkoutput, mock_build,
444                                                  _vts, _find_kernel, _class_info):
445        """Test find_test_by_module_and_class for MODULE:CC_CLASS."""
446        # Native test was tested in test_find_test_by_cc_class_name()
447        self.mod_finder.module_info.is_native_test.return_value = False
448        self.mod_finder.module_info.is_auto_gen_test_config.return_value = False
449        self.mod_finder.module_info.is_robolectric_test.return_value = False
450        self.mod_finder.module_info.has_test_config.return_value = True
451        self.mod_finder.module_info.get_paths.return_value = []
452        mock_build.return_value = uc.CLASS_BUILD_TARGETS
453        mod_info = {constants.MODULE_INSTALLED: DEFAULT_INSTALL_PATH,
454                    constants.MODULE_PATH: [uc.CC_MODULE_DIR],
455                    constants.MODULE_CLASS: [],
456                    constants.MODULE_COMPATIBILITY_SUITES: []}
457        self.mod_finder.module_info.get_module_info.return_value = mod_info
458        _class_info.return_value = {'PFTest': {'methods':{'test1', 'test2'},
459                                               'prefixes': set(),
460                                               'typed': False}}
461        self.mod_finder.module_info.get_robolectric_type.return_value = 0
462        self.mod_finder.module_info.get_instrumentation_target_apps.return_value = {}
463        t_infos = self.mod_finder.find_test_by_module_and_class(CC_MODULE_CLASS)
464        unittest_utils.assert_equal_testinfos(self, t_infos[0], uc.CC_MODULE_CLASS_INFO)
465        # with method
466        mock_build.return_value = copy.deepcopy(uc.MODULE_BUILD_TARGETS)
467        mock_fcf.side_effect = [None, None, '/']
468        t_infos = self.mod_finder.find_test_by_module_and_class(CC_MODULE_CLASS_METHOD)
469        unittest_utils.assert_equal_testinfos(self, t_infos[0], uc.CC_METHOD3_INFO)
470        # bad module, good class, returns None
471        bad_module = '%s:%s' % ('BadMod', uc.CC_CLASS_NAME)
472        self.mod_finder.module_info.get_module_info.return_value = None
473        self.mod_finder.module_info.is_testable_module.return_value = False
474        self.assertIsNone(self.mod_finder.find_test_by_module_and_class(bad_module))
475
476    @mock.patch.object(module_finder.ModuleFinder, '_get_module_test_config',
477                       return_value=[KERNEL_CONFIG_FILE])
478    @mock.patch.object(module_finder.ModuleFinder, '_is_vts_module',
479                       return_value=False)
480    @mock.patch.object(module_finder.ModuleFinder, '_get_build_targets')
481    @mock.patch('subprocess.check_output', return_value=uc.FIND_CC_ONE)
482    @mock.patch.object(test_finder_utils, 'find_class_file',
483                       side_effect=[None, None, '/'])
484    @mock.patch('os.path.isfile', side_effect=unittest_utils.isfile_side_effect)
485    #pylint: disable=unused-argument
486    def test_find_test_by_module_and_class_for_kernel_test(
487            self, _isfile, mock_fcf, mock_checkoutput, mock_build, _vts,
488            _test_config):
489        """Test find_test_by_module_and_class for MODULE:CC_CLASS."""
490        # Kernel test was tested in find_test_by_kernel_class_name()
491        self.mod_finder.module_info.is_native_test.return_value = False
492        self.mod_finder.module_info.is_auto_gen_test_config.return_value = False
493        self.mod_finder.module_info.is_robolectric_test.return_value = False
494        self.mod_finder.module_info.has_test_config.return_value = True
495        self.mod_finder.module_info.get_paths.return_value = []
496        mock_build.return_value = uc.CLASS_BUILD_TARGETS
497        mod_info = {constants.MODULE_INSTALLED: DEFAULT_INSTALL_PATH,
498                    constants.MODULE_PATH: [uc.CC_MODULE_DIR],
499                    constants.MODULE_CLASS: [],
500                    constants.MODULE_COMPATIBILITY_SUITES: []}
501        self.mod_finder.module_info.get_module_info.return_value = mod_info
502        self.mod_finder.module_info.get_robolectric_type.return_value = 0
503        self.mod_finder.module_info.get_instrumentation_target_apps.return_value = {}
504        t_infos = self.mod_finder.find_test_by_module_and_class(KERNEL_MODULE_CLASS)
505        unittest_utils.assert_equal_testinfos(self, t_infos[0], KERNEL_MODULE_CLASS_INFO)
506
507    @mock.patch.object(test_finder_utils, 'find_host_unit_tests',
508                       return_value=[])
509    @mock.patch.object(module_finder.ModuleFinder, '_is_vts_module',
510                       return_value=False)
511    @mock.patch.object(module_finder.ModuleFinder, '_get_build_targets')
512    @mock.patch('subprocess.check_output', return_value=uc.FIND_PKG)
513    @mock.patch('os.path.isfile', side_effect=unittest_utils.isfile_side_effect)
514    @mock.patch('os.path.isdir', return_value=True)
515    #pylint: disable=unused-argument
516    def test_find_test_by_package_name(self, _isdir, _isfile, mock_checkoutput,
517                                       mock_build, _vts, _mock_unit_tests):
518        """Test find_test_by_package_name."""
519        self.mod_finder.module_info.is_auto_gen_test_config.return_value = False
520        self.mod_finder.module_info.is_robolectric_test.return_value = False
521        self.mod_finder.module_info.has_test_config.return_value = True
522        mock_build.return_value = uc.CLASS_BUILD_TARGETS
523        self.mod_finder.module_info.get_module_names.return_value = [uc.MODULE_NAME]
524        self.mod_finder.module_info.get_module_info.return_value = {
525            constants.MODULE_INSTALLED: DEFAULT_INSTALL_PATH,
526            constants.MODULE_NAME: uc.MODULE_NAME,
527            constants.MODULE_CLASS: [],
528            constants.MODULE_COMPATIBILITY_SUITES: []
529            }
530        self.mod_finder.module_info.get_robolectric_type.return_value = 0
531        self.mod_finder.module_info.get_instrumentation_target_apps.return_value = {}
532        t_infos = self.mod_finder.find_test_by_package_name(uc.PACKAGE)
533        unittest_utils.assert_equal_testinfos(
534            self, t_infos[0],
535            uc.PACKAGE_INFO)
536        # with method, should raise
537        pkg_with_method = '%s#%s' % (uc.PACKAGE, uc.METHOD_NAME)
538        self.assertRaises(atest_error.MethodWithoutClassError,
539                          self.mod_finder.find_test_by_package_name,
540                          pkg_with_method)
541        # module and rel_config passed in
542        t_infos = self.mod_finder.find_test_by_package_name(
543            uc.PACKAGE, uc.MODULE_NAME, uc.CONFIG_FILE)
544        unittest_utils.assert_equal_testinfos(
545            self, t_infos[0], uc.PACKAGE_INFO)
546        # find output fails to find class file
547        mock_checkoutput.return_value = ''
548        self.assertIsNone(self.mod_finder.find_test_by_package_name('Not pkg'))
549
550    @mock.patch('os.path.isdir', return_value=False)
551    @mock.patch.object(module_finder.ModuleFinder, '_is_vts_module',
552                       return_value=False)
553    @mock.patch.object(module_finder.ModuleFinder, '_get_build_targets')
554    @mock.patch('subprocess.check_output', return_value=uc.FIND_PKG)
555    @mock.patch('os.path.isfile', side_effect=unittest_utils.isfile_side_effect)
556    #pylint: disable=unused-argument
557    def test_find_test_by_module_and_package(self, _isfile, mock_checkoutput,
558                                             mock_build, _vts, _isdir):
559        """Test find_test_by_module_and_package."""
560        self.mod_finder.module_info.is_auto_gen_test_config.return_value = False
561        self.mod_finder.module_info.is_robolectric_test.return_value = False
562        self.mod_finder.module_info.has_test_config.return_value = True
563        self.mod_finder.module_info.get_paths.return_value = []
564        mock_build.return_value = uc.CLASS_BUILD_TARGETS
565        mod_info = {constants.MODULE_INSTALLED: DEFAULT_INSTALL_PATH,
566                    constants.MODULE_PATH: [uc.MODULE_DIR],
567                    constants.MODULE_CLASS: [],
568                    constants.MODULE_COMPATIBILITY_SUITES: []}
569        self.mod_finder.module_info.get_module_info.return_value = mod_info
570        self.mod_finder.module_info.get_instrumentation_target_apps.return_value = {}
571        t_infos = self.mod_finder.find_test_by_module_and_package(MODULE_PACKAGE)
572        self.assertEqual(t_infos, None)
573        _isdir.return_value = True
574        self.mod_finder.module_info.get_robolectric_type.return_value = 0
575        t_infos = self.mod_finder.find_test_by_module_and_package(MODULE_PACKAGE)
576        unittest_utils.assert_equal_testinfos(self, t_infos[0], uc.PACKAGE_INFO)
577
578        # with method, raises
579        module_pkg_with_method = '%s:%s#%s' % (uc.MODULE2_NAME, uc.PACKAGE,
580                                               uc.METHOD_NAME)
581        self.assertRaises(atest_error.MethodWithoutClassError,
582                          self.mod_finder.find_test_by_module_and_package,
583                          module_pkg_with_method)
584        # bad module, good pkg, returns None
585        self.mod_finder.module_info.is_testable_module.return_value = False
586        bad_module = '%s:%s' % ('BadMod', uc.PACKAGE)
587        self.mod_finder.module_info.get_module_info.return_value = None
588        self.assertIsNone(self.mod_finder.find_test_by_module_and_package(bad_module))
589        # find output fails to find package path
590        mock_checkoutput.return_value = ''
591        bad_pkg = '%s:%s' % (uc.MODULE_NAME, 'Anything')
592        self.mod_finder.module_info.get_module_info.return_value = mod_info
593        self.assertIsNone(self.mod_finder.find_test_by_module_and_package(bad_pkg))
594
595    # TODO: Move and rewite it to ModuleFinderFindTestByPath.
596    @mock.patch.object(test_finder_utils, 'find_host_unit_tests',
597                       return_value=[])
598    @mock.patch.object(test_finder_utils, 'get_cc_class_info', return_value={})
599    @mock.patch.object(atest_utils, 'is_build_file', return_value=True)
600    @mock.patch.object(test_finder_utils, 'is_parameterized_java_class',
601                       return_value=False)
602    @mock.patch.object(test_finder_utils, 'has_method_in_file',
603                       return_value=True)
604    @mock.patch.object(test_finder_utils, 'has_cc_class',
605                       return_value=True)
606    @mock.patch.object(module_finder.ModuleFinder, '_get_build_targets')
607    @mock.patch.object(module_finder.ModuleFinder, '_is_vts_module',
608                       return_value=False)
609    @mock.patch.object(test_finder_utils, 'get_fully_qualified_class_name',
610                       return_value=uc.FULL_CLASS_NAME)
611    @mock.patch('os.path.realpath',
612                side_effect=unittest_utils.realpath_side_effect)
613    @mock.patch('os.path.isfile', side_effect=unittest_utils.isfile_side_effect)
614    @mock.patch.object(test_finder_utils, 'find_parent_module_dir')
615    @mock.patch('os.path.exists')
616    #pylint: disable=unused-argument
617    def test_find_test_by_path(
618            self, mock_pathexists, mock_dir, _isfile, _real, _fqcn, _vts,
619            mock_build, _has_cc_class, _has_method_in_file, _is_parameterized,
620            _is_build_file, _get_cc_class_info, _mock_unit_tests):
621        """Test find_test_by_path."""
622        self.mod_finder.module_info.is_robolectric_test.return_value = False
623        self.mod_finder.module_info.has_test_config.return_value = True
624        self.mod_finder.module_info.get_modules_by_include_deps.return_value = set()
625        mock_build.return_value = set()
626        # Check that we don't return anything with invalid test references.
627        mock_pathexists.return_value = False
628        unittest_utils.assert_equal_testinfos(
629            self, None, self.mod_finder.find_test_by_path('bad/path'))
630        mock_pathexists.return_value = True
631        mock_dir.return_value = None
632        unittest_utils.assert_equal_testinfos(
633            self, None, self.mod_finder.find_test_by_path('no/module'))
634        self.mod_finder.module_info.get_module_names.return_value = [uc.MODULE_NAME]
635        self.mod_finder.module_info.get_module_info.return_value = {
636            constants.MODULE_INSTALLED: DEFAULT_INSTALL_PATH,
637            constants.MODULE_NAME: uc.MODULE_NAME,
638            constants.MODULE_CLASS: [],
639            constants.MODULE_COMPATIBILITY_SUITES: []}
640
641        # Happy path testing.
642        mock_dir.return_value = uc.MODULE_DIR
643
644        class_path = '%s.kt' % uc.CLASS_NAME
645        mock_build.return_value = uc.CLASS_BUILD_TARGETS
646        self.mod_finder.module_info.get_robolectric_type.return_value = 0
647        self.mod_finder.module_info.get_instrumentation_target_apps.return_value = {}
648        t_infos = self.mod_finder.find_test_by_path(class_path)
649        unittest_utils.assert_equal_testinfos(
650            self, uc.CLASS_INFO, t_infos[0])
651
652        class_with_method = '%s#%s' % (class_path, uc.METHOD_NAME)
653        mock_build.return_value = copy.deepcopy(uc.MODULE_BUILD_TARGETS)
654        t_infos = self.mod_finder.find_test_by_path(class_with_method)
655        unittest_utils.assert_equal_testinfos(
656            self, t_infos[0], uc.METHOD_INFO)
657
658        class_path = '%s.java' % uc.CLASS_NAME
659        mock_build.return_value = uc.CLASS_BUILD_TARGETS
660        t_infos = self.mod_finder.find_test_by_path(class_path)
661        unittest_utils.assert_equal_testinfos(
662            self, uc.CLASS_INFO, t_infos[0])
663
664        class_with_method = '%s#%s' % (class_path, uc.METHOD_NAME)
665        mock_build.return_value = copy.deepcopy(uc.MODULE_BUILD_TARGETS)
666        t_infos = self.mod_finder.find_test_by_path(class_with_method)
667        unittest_utils.assert_equal_testinfos(
668            self, t_infos[0], uc.METHOD_INFO)
669
670        class_with_methods = '%s,%s' % (class_with_method, uc.METHOD2_NAME)
671        mock_build.return_value = copy.deepcopy(uc.MODULE_BUILD_TARGETS)
672        t_infos = self.mod_finder.find_test_by_path(class_with_methods)
673        unittest_utils.assert_equal_testinfos(
674            self, t_infos[0],
675            FLAT_METHOD_INFO)
676
677        # Cc path testing.
678        self.mod_finder.module_info.get_module_names.return_value = [uc.CC_MODULE_NAME]
679        self.mod_finder.module_info.get_module_info.return_value = {
680            constants.MODULE_INSTALLED: DEFAULT_INSTALL_PATH,
681            constants.MODULE_NAME: uc.CC_MODULE_NAME,
682            constants.MODULE_CLASS: [],
683            constants.MODULE_COMPATIBILITY_SUITES: []}
684        mock_dir.return_value = uc.CC_MODULE_DIR
685        class_path = '%s' % uc.CC_PATH
686        mock_build.return_value = uc.CLASS_BUILD_TARGETS
687        t_infos = self.mod_finder.find_test_by_path(class_path)
688        unittest_utils.assert_equal_testinfos(
689            self, uc.CC_PATH_INFO2, t_infos[0])
690
691    # TODO: Move and rewite it to ModuleFinderFindTestByPath.
692    @mock.patch.object(module_finder.ModuleFinder, '_get_build_targets',
693                       return_value=copy.deepcopy(uc.MODULE_BUILD_TARGETS))
694    @mock.patch.object(module_finder.ModuleFinder, '_is_vts_module',
695                       return_value=False)
696    @mock.patch.object(test_finder_utils, 'find_parent_module_dir',
697                       return_value=os.path.relpath(uc.TEST_DATA_DIR, uc.ROOT))
698    #pylint: disable=unused-argument
699    def test_find_test_by_path_part_2(self, _find_parent, _is_vts, _get_build):
700        """Test find_test_by_path for directories."""
701        self.mod_finder.module_info.is_auto_gen_test_config.return_value = False
702        self.mod_finder.module_info.is_robolectric_test.return_value = False
703        self.mod_finder.module_info.has_test_config.return_value = True
704        # Dir with java files in it, should run as package
705        class_dir = os.path.join(uc.TEST_DATA_DIR, 'path_testing')
706        self.mod_finder.module_info.get_module_names.return_value = [uc.MODULE_NAME]
707        self.mod_finder.module_info.get_module_info.return_value = {
708            constants.MODULE_INSTALLED: DEFAULT_INSTALL_PATH,
709            constants.MODULE_NAME: uc.MODULE_NAME,
710            constants.MODULE_CLASS: [],
711            constants.MODULE_COMPATIBILITY_SUITES: []}
712        self.mod_finder.module_info.get_robolectric_type.return_value = 0
713        self.mod_finder.module_info.get_instrumentation_target_apps.return_value = {}
714        t_infos = self.mod_finder.find_test_by_path(class_dir)
715        unittest_utils.assert_equal_testinfos(
716            self, uc.PATH_INFO, t_infos[0])
717        # Dir with no java files in it, should run whole module
718        empty_dir = os.path.join(uc.TEST_DATA_DIR, 'path_testing_empty')
719        t_infos = self.mod_finder.find_test_by_path(empty_dir)
720        unittest_utils.assert_equal_testinfos(
721            self, uc.EMPTY_PATH_INFO,
722            t_infos[0])
723        # Dir with cc files in it, should run as cc class
724        class_dir = os.path.join(uc.TEST_DATA_DIR, 'cc_path_testing')
725        self.mod_finder.module_info.get_module_names.return_value = [uc.CC_MODULE_NAME]
726        self.mod_finder.module_info.get_module_info.return_value = {
727            constants.MODULE_INSTALLED: DEFAULT_INSTALL_PATH,
728            constants.MODULE_NAME: uc.CC_MODULE_NAME,
729            constants.MODULE_CLASS: [],
730            constants.MODULE_COMPATIBILITY_SUITES: []}
731        t_infos = self.mod_finder.find_test_by_path(class_dir)
732        unittest_utils.assert_equal_testinfos(
733            self, uc.CC_PATH_INFO, t_infos[0])
734
735    @mock.patch.object(module_finder.test_finder_utils, 'get_cc_class_info')
736    @mock.patch.object(test_finder_utils, 'find_host_unit_tests',
737                       return_value=[])
738    @mock.patch.object(atest_utils, 'is_build_file', return_value=True)
739    @mock.patch.object(test_finder_utils, 'has_method_in_file',
740                       return_value=True)
741    @mock.patch.object(module_finder.ModuleFinder, '_is_vts_module',
742                       return_value=False)
743    @mock.patch.object(module_finder.ModuleFinder, '_get_build_targets')
744    @mock.patch('subprocess.check_output', return_value=uc.CC_FIND_ONE)
745    @mock.patch('os.path.isfile', side_effect=unittest_utils.isfile_side_effect)
746    @mock.patch('os.path.isdir', return_value=True)
747    #pylint: disable=unused-argument
748    def test_find_test_by_cc_class_name(self, _isdir, _isfile,
749                                        mock_checkoutput, mock_build,
750                                        _vts, _has_method, _is_build_file,
751                                       _mock_unit_tests, _class_info):
752        """Test find_test_by_cc_class_name."""
753        mock_build.return_value = uc.CLASS_BUILD_TARGETS
754        self.mod_finder.module_info.is_auto_gen_test_config.return_value = False
755        self.mod_finder.module_info.is_robolectric_test.return_value = False
756        self.mod_finder.module_info.has_test_config.return_value = True
757        self.mod_finder.module_info.get_module_names.return_value = [uc.CC_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.CC_MODULE_NAME,
761            constants.MODULE_CLASS: [],
762            constants.MODULE_COMPATIBILITY_SUITES: []}
763        self.mod_finder.module_info.get_robolectric_type.return_value = 0
764        self.mod_finder.module_info.get_instrumentation_target_apps.return_value = {}
765        _class_info.return_value = {'PFTest': {'methods': {'test1', 'test2'},
766                                               'prefixes': set(),
767                                               'typed': False}}
768        t_infos = self.mod_finder.find_test_by_cc_class_name(uc.CC_CLASS_NAME)
769        unittest_utils.assert_equal_testinfos(
770            self, t_infos[0], uc.CC_CLASS_INFO)
771
772        # with method
773        mock_build.return_value = copy.deepcopy(uc.MODULE_BUILD_TARGETS)
774        class_with_method = '%s#%s' % (uc.CC_CLASS_NAME, uc.CC_METHOD_NAME)
775        t_infos = self.mod_finder.find_test_by_cc_class_name(class_with_method)
776        unittest_utils.assert_equal_testinfos(
777            self,
778            t_infos[0],
779            uc.CC_METHOD_INFO)
780        mock_build.return_value = copy.deepcopy(uc.MODULE_BUILD_TARGETS)
781        class_methods = '%s,%s' % (class_with_method, uc.CC_METHOD2_NAME)
782        t_infos = self.mod_finder.find_test_by_cc_class_name(class_methods)
783        unittest_utils.assert_equal_testinfos(
784            self, t_infos[0],
785            uc.CC_METHOD2_INFO)
786        # module and rel_config passed in
787        mock_build.return_value = uc.CLASS_BUILD_TARGETS
788        t_infos = self.mod_finder.find_test_by_cc_class_name(
789            uc.CC_CLASS_NAME, uc.CC_MODULE_NAME, uc.CC_CONFIG_FILE)
790        unittest_utils.assert_equal_testinfos(
791            self, t_infos[0], uc.CC_CLASS_INFO)
792        # find output fails to find class file
793        mock_checkoutput.return_value = ''
794        self.assertIsNone(self.mod_finder.find_test_by_cc_class_name(
795            'Not class'))
796        # class is outside given module path
797        mock_checkoutput.return_value = uc.CC_FIND_ONE
798        t_infos = self.mod_finder.find_test_by_cc_class_name(
799            uc.CC_CLASS_NAME,
800            uc.CC_MODULE2_NAME,
801            uc.CC_CONFIG2_FILE)
802        unittest_utils.assert_equal_testinfos(
803            self, t_infos[0],
804            CC_CLASS_INFO_MODULE_2)
805
806    def test_get_testable_modules_with_ld(self):
807        """Test get_testable_modules_with_ld"""
808        self.mod_finder.module_info.get_testable_modules.return_value = [
809            uc.MODULE_NAME, uc.MODULE2_NAME]
810        # Without a misfit constraint
811        ld1 = self.mod_finder.get_testable_modules_with_ld(uc.TYPO_MODULE_NAME)
812        self.assertEqual([[16, uc.MODULE2_NAME], [1, uc.MODULE_NAME]], ld1)
813        # With a misfit constraint
814        ld2 = self.mod_finder.get_testable_modules_with_ld(uc.TYPO_MODULE_NAME, 2)
815        self.assertEqual([[1, uc.MODULE_NAME]], ld2)
816
817    def test_get_fuzzy_searching_modules(self):
818        """Test get_fuzzy_searching_modules"""
819        self.mod_finder.module_info.get_testable_modules.return_value = [
820            uc.MODULE_NAME, uc.MODULE2_NAME]
821        result = self.mod_finder.get_fuzzy_searching_results(uc.TYPO_MODULE_NAME)
822        self.assertEqual(uc.MODULE_NAME, result[0])
823
824    def test_get_build_targets_w_vts_core(self):
825        """Test _get_build_targets."""
826        self.mod_finder.module_info.is_auto_gen_test_config.return_value = True
827        self.mod_finder.module_info.get_paths.return_value = []
828        mod_info = {constants.MODULE_COMPATIBILITY_SUITES:
829                        [constants.VTS_CORE_SUITE]}
830        self.mod_finder.module_info.get_module_info.return_value = mod_info
831        self.assertEqual(self.mod_finder._get_build_targets('', ''),
832                         {constants.VTS_CORE_TF_MODULE})
833
834    def test_get_build_targets_w_mts(self):
835        """Test _get_build_targets if module belong to mts."""
836        self.mod_finder.module_info.is_auto_gen_test_config.return_value = True
837        self.mod_finder.module_info.get_paths.return_value = []
838        mod_info = {constants.MODULE_COMPATIBILITY_SUITES:
839                        [constants.MTS_SUITE]}
840        self.mod_finder.module_info.get_module_info.return_value = mod_info
841        self.assertEqual(self.mod_finder._get_build_targets('', ''),
842                         {constants.CTS_JAR})
843
844    @mock.patch.object(test_finder_utils, 'is_parameterized_java_class',
845                       return_value=False)
846    @mock.patch.object(module_finder.ModuleFinder, '_is_vts_module',
847                       return_value=False)
848    @mock.patch.object(module_finder.ModuleFinder, '_get_build_targets')
849    @mock.patch('subprocess.check_output', return_value='')
850    @mock.patch.object(test_finder_utils, 'get_fully_qualified_class_name',
851                       return_value=uc.FULL_CLASS_NAME)
852    @mock.patch('os.path.isfile', side_effect=unittest_utils.isfile_side_effect)
853    @mock.patch('os.path.isdir', return_value=True)
854    #pylint: disable=unused-argument
855    def test_find_test_by_class_name_w_module(self, _isdir, _isfile, _fqcn,
856                                              mock_checkoutput, mock_build,
857                                              _vts, _is_parameterized):
858        """Test test_find_test_by_class_name with module but without class found."""
859        mock_build.return_value = uc.CLASS_BUILD_TARGETS
860        self.mod_finder.module_info.is_auto_gen_test_config.return_value = False
861        self.mod_finder.module_info.is_robolectric_test.return_value = False
862        self.mod_finder.module_info.has_test_config.return_value = True
863        self.mod_finder.module_info.get_module_names.return_value = [uc.MODULE_NAME]
864        self.mod_finder.module_info.get_module_info.return_value = {
865            constants.MODULE_INSTALLED: DEFAULT_INSTALL_PATH,
866            constants.MODULE_NAME: uc.MODULE_NAME,
867            constants.MODULE_CLASS: [],
868            constants.MODULE_COMPATIBILITY_SUITES: []}
869        self.mod_finder.module_info.get_paths.return_value = [uc.TEST_DATA_CONFIG]
870        self.mod_finder.module_info.get_robolectric_type.return_value = 0
871        self.mod_finder.module_info.get_instrumentation_target_apps.return_value = {}
872        t_infos = self.mod_finder.find_test_by_class_name(
873            uc.FULL_CLASS_NAME, module_name=uc.MODULE_NAME,
874            rel_config=uc.CONFIG_FILE)
875        unittest_utils.assert_equal_testinfos(
876            self, t_infos[0], uc.CLASS_INFO)
877
878    @mock.patch.object(module_finder.ModuleFinder, '_is_vts_module',
879                       return_value=False)
880    @mock.patch.object(module_finder.ModuleFinder, '_get_build_targets')
881    @mock.patch('subprocess.check_output', return_value='')
882    @mock.patch('os.path.isfile', side_effect=unittest_utils.isfile_side_effect)
883    @mock.patch('os.path.isdir', return_value=True)
884    #pylint: disable=unused-argument
885    def test_find_test_by_package_name_w_module(self, _isdir, _isfile,
886                                                mock_checkoutput, mock_build,
887                                                _vts):
888        """Test find_test_by_package_name with module but without package found."""
889        self.mod_finder.module_info.is_auto_gen_test_config.return_value = False
890        self.mod_finder.module_info.is_robolectric_test.return_value = False
891        self.mod_finder.module_info.has_test_config.return_value = True
892        mock_build.return_value = uc.CLASS_BUILD_TARGETS
893        self.mod_finder.module_info.get_module_names.return_value = [uc.MODULE_NAME]
894        self.mod_finder.module_info.get_module_info.return_value = {
895            constants.MODULE_INSTALLED: DEFAULT_INSTALL_PATH,
896            constants.MODULE_NAME: uc.MODULE_NAME,
897            constants.MODULE_CLASS: [],
898            constants.MODULE_COMPATIBILITY_SUITES: []
899        }
900        self.mod_finder.module_info.get_paths.return_value = [uc.TEST_DATA_CONFIG]
901        self.mod_finder.module_info.get_robolectric_type.return_value = 0
902        self.mod_finder.module_info.get_instrumentation_target_apps.return_value = {}
903        t_infos = self.mod_finder.find_test_by_package_name(
904            uc.PACKAGE, module_name=uc.MODULE_NAME, rel_config=uc.CONFIG_FILE)
905        unittest_utils.assert_equal_testinfos(
906            self, t_infos[0],
907            uc.PACKAGE_INFO)
908
909    @mock.patch.object(atest_utils, 'is_build_file', return_value=True)
910    @mock.patch.object(test_finder_utils, 'is_parameterized_java_class',
911                       return_value=True)
912    @mock.patch.object(test_finder_utils, 'has_method_in_file',
913                       return_value=True)
914    @mock.patch.object(test_finder_utils, 'has_cc_class',
915                       return_value=True)
916    @mock.patch.object(module_finder.ModuleFinder, '_get_build_targets')
917    @mock.patch.object(module_finder.ModuleFinder, '_is_vts_module',
918                       return_value=False)
919    @mock.patch.object(test_finder_utils, 'get_fully_qualified_class_name',
920                       return_value=uc.FULL_CLASS_NAME)
921    @mock.patch('os.path.realpath',
922                side_effect=unittest_utils.realpath_side_effect)
923    @mock.patch('os.path.isfile', side_effect=unittest_utils.isfile_side_effect)
924    @mock.patch.object(test_finder_utils, 'find_parent_module_dir')
925    @mock.patch('os.path.exists')
926    #pylint: disable=unused-argument
927    def test_find_test_by_path_is_parameterized_java(
928            self, mock_pathexists, mock_dir, _isfile, _real, _fqcn, _vts,
929            mock_build, _has_cc_class, _has_method_in_file, _is_parameterized,
930            _is_build_file):
931        """Test find_test_by_path and input path is parameterized class."""
932        self.mod_finder.module_info.is_robolectric_test.return_value = False
933        self.mod_finder.module_info.has_test_config.return_value = True
934        mock_build.return_value = set()
935        mock_pathexists.return_value = True
936        self.mod_finder.module_info.get_module_names.return_value = [uc.MODULE_NAME]
937        self.mod_finder.module_info.get_module_info.return_value = {
938            constants.MODULE_INSTALLED: DEFAULT_INSTALL_PATH,
939            constants.MODULE_NAME: uc.MODULE_NAME,
940            constants.MODULE_CLASS: [],
941            constants.MODULE_COMPATIBILITY_SUITES: []}
942        self.mod_finder.module_info.get_robolectric_type.return_value = 0
943        self.mod_finder.module_info.get_instrumentation_target_apps.return_value = {}
944        # Happy path testing.
945        mock_dir.return_value = uc.MODULE_DIR
946        class_path = '%s.java' % uc.CLASS_NAME
947        # Input include only one method
948        class_with_method = '%s#%s' % (class_path, uc.METHOD_NAME)
949        mock_build.return_value = copy.deepcopy(uc.MODULE_BUILD_TARGETS)
950        t_infos = self.mod_finder.find_test_by_path(class_with_method)
951        unittest_utils.assert_equal_testinfos(
952            self, t_infos[0], uc.PARAMETERIZED_METHOD_INFO)
953        # Input include multiple methods
954        class_with_methods = '%s,%s' % (class_with_method, uc.METHOD2_NAME)
955        mock_build.return_value = copy.deepcopy(uc.MODULE_BUILD_TARGETS)
956        t_infos = self.mod_finder.find_test_by_path(class_with_methods)
957        unittest_utils.assert_equal_testinfos(
958            self, t_infos[0], uc.PARAMETERIZED_FLAT_METHOD_INFO)
959
960    @mock.patch.object(test_finder_utils, 'find_host_unit_tests',
961                           return_value=[])
962    @mock.patch.object(atest_utils, 'is_build_file', return_value=True)
963    @mock.patch.object(test_finder_utils, 'is_parameterized_java_class',
964                       return_value=True)
965    @mock.patch.object(test_finder_utils, 'has_method_in_file',
966                       return_value=True)
967    @mock.patch.object(module_finder.ModuleFinder, '_is_vts_module',
968                       return_value=False)
969    @mock.patch.object(module_finder.ModuleFinder, '_get_build_targets')
970    @mock.patch('subprocess.check_output', return_value=uc.FIND_ONE)
971    @mock.patch.object(test_finder_utils, 'get_fully_qualified_class_name',
972                       return_value=uc.FULL_CLASS_NAME)
973    @mock.patch('os.path.isfile', side_effect=unittest_utils.isfile_side_effect)
974    @mock.patch('os.path.isdir', return_value=True)
975    #pylint: disable=unused-argument
976    def test_find_test_by_class_name_is_parameterized(
977            self, _isdir, _isfile, _fqcn, mock_checkoutput, mock_build, _vts,
978            _has_method_in_file, _is_parameterized, _is_build_file,
979            _mock_unit_tests):
980        """Test find_test_by_class_name and the class is parameterized java."""
981        mock_build.return_value = uc.CLASS_BUILD_TARGETS
982        self.mod_finder.module_info.is_auto_gen_test_config.return_value = False
983        self.mod_finder.module_info.is_robolectric_test.return_value = False
984        self.mod_finder.module_info.get_instrumentation_target_apps.return_value = {}
985        self.mod_finder.module_info.has_test_config.return_value = True
986        self.mod_finder.module_info.get_module_names.return_value = [uc.MODULE_NAME]
987        self.mod_finder.module_info.get_module_info.return_value = {
988            constants.MODULE_INSTALLED: DEFAULT_INSTALL_PATH,
989            constants.MODULE_NAME: uc.MODULE_NAME,
990            constants.MODULE_CLASS: [],
991            constants.MODULE_COMPATIBILITY_SUITES: []}
992        # With method
993        mock_build.return_value = copy.deepcopy(uc.MODULE_BUILD_TARGETS)
994        self.mod_finder.module_info.get_robolectric_type.return_value = 0
995        class_with_method = '%s#%s' % (uc.CLASS_NAME, uc.METHOD_NAME)
996        t_infos = self.mod_finder.find_test_by_class_name(class_with_method)
997        unittest_utils.assert_equal_testinfos(
998            self, t_infos[0], uc.PARAMETERIZED_METHOD_INFO)
999        # With multiple method
1000        mock_build.return_value = copy.deepcopy(uc.MODULE_BUILD_TARGETS)
1001        class_methods = '%s,%s' % (class_with_method, uc.METHOD2_NAME)
1002        t_infos = self.mod_finder.find_test_by_class_name(class_methods)
1003        unittest_utils.assert_equal_testinfos(
1004            self, t_infos[0], uc.PARAMETERIZED_FLAT_METHOD_INFO)
1005
1006    # pylint: disable=unused-argument
1007    @mock.patch.object(module_finder.ModuleFinder, '_get_build_targets',
1008                       return_value=copy.deepcopy(uc.MODULE_BUILD_TARGETS))
1009    def test_find_test_by_config_name(self, _get_targ):
1010        """Test find_test_by_config_name."""
1011        self.mod_finder.module_info.is_robolectric_test.return_value = False
1012        self.mod_finder.module_info.has_test_config.return_value = True
1013
1014        mod_info = {'installed': ['/path/to/install'],
1015                    'path': [uc.MODULE_DIR],
1016                    constants.MODULE_TEST_CONFIG: [uc.CONFIG_FILE,
1017                                                   uc.EXTRA_CONFIG_FILE],
1018                    constants.MODULE_CLASS: [],
1019                    constants.MODULE_COMPATIBILITY_SUITES: []}
1020        name_to_module_info = {uc.MODULE_NAME: mod_info}
1021        self.mod_finder.module_info.name_to_module_info = name_to_module_info
1022        t_infos = self.mod_finder.find_test_by_config_name(uc.MODULE_CONFIG_NAME)
1023        unittest_utils.assert_equal_testinfos(
1024            self,
1025            t_infos[0],
1026            uc.TEST_CONFIG_MODULE_INFO)
1027
1028    @mock.patch.object(test_finder_utils, 'is_parameterized_java_class',
1029                       return_value=False)
1030    @mock.patch.object(test_finder_utils, 'has_method_in_file',
1031                       return_value=True)
1032    @mock.patch.object(test_finder_utils, 'has_cc_class',
1033                       return_value=True)
1034    @mock.patch.object(module_finder.ModuleFinder, '_get_build_targets')
1035    @mock.patch.object(module_finder.ModuleFinder, '_is_vts_module',
1036                       return_value=False)
1037    @mock.patch.object(test_finder_utils, 'get_fully_qualified_class_name',
1038                       return_value=uc.FULL_CLASS_NAME)
1039    @mock.patch('os.path.realpath',
1040                side_effect=unittest_utils.realpath_side_effect)
1041    @mock.patch('os.path.isfile', side_effect=unittest_utils.isfile_side_effect)
1042    @mock.patch.object(test_finder_utils, 'find_parent_module_dir')
1043    @mock.patch('os.path.exists')
1044    #pylint: disable=unused-argument
1045    def test_find_test_by_path_w_src_verify(
1046            self, mock_pathexists, mock_dir, _isfile, _real, _fqcn, _vts,
1047            mock_build, _has_cc_class, _has_method_in_file, _is_parameterized):
1048        """Test find_test_by_path with src information."""
1049        self.mod_finder.module_info.is_robolectric_test.return_value = False
1050        self.mod_finder.module_info.has_test_config.return_value = True
1051        self.mod_finder.module_info.get_module_names.return_value = [uc.MODULE_NAME]
1052        mock_build.return_value = uc.CLASS_BUILD_TARGETS
1053
1054        # Happy path testing.
1055        mock_dir.return_value = uc.MODULE_DIR
1056        # Test path not in module's src list.
1057        class_path = '%s.java' % uc.CLASS_NAME
1058        self.mod_finder.module_info.get_module_info.return_value = {
1059            constants.MODULE_INSTALLED: DEFAULT_INSTALL_PATH,
1060            constants.MODULE_NAME: uc.MODULE_NAME,
1061            constants.MODULE_CLASS: [],
1062            constants.MODULE_COMPATIBILITY_SUITES: [],
1063            constants.MODULE_SRCS: ['not_matched_%s' % class_path]}
1064        t_infos = self.mod_finder.find_test_by_path(class_path)
1065        self.assertEqual(0, len(t_infos))
1066
1067        # Test input file is in module's src list.
1068        class_path = '%s.java' % uc.CLASS_NAME
1069        self.mod_finder.module_info.get_module_info.return_value = {
1070            constants.MODULE_INSTALLED: DEFAULT_INSTALL_PATH,
1071            constants.MODULE_NAME: uc.MODULE_NAME,
1072            constants.MODULE_CLASS: [],
1073            constants.MODULE_COMPATIBILITY_SUITES: [],
1074            constants.MODULE_SRCS: [class_path]}
1075        self.mod_finder.module_info.get_robolectric_type.return_value = 0
1076        self.mod_finder.module_info.get_instrumentation_target_apps.return_value = {}
1077        t_infos = self.mod_finder.find_test_by_path(class_path)
1078        unittest_utils.assert_equal_testinfos(self, uc.CLASS_INFO, t_infos[0])
1079
1080    @mock.patch.object(test_finder_utils, 'get_cc_class_info')
1081    @mock.patch.object(atest_utils, 'is_build_file', return_value=True)
1082    @mock.patch.object(test_finder_utils, 'is_parameterized_java_class',
1083                       return_value=False)
1084    @mock.patch.object(test_finder_utils, 'has_method_in_file',
1085                       return_value=True)
1086    @mock.patch.object(test_finder_utils, 'has_cc_class',
1087                       return_value=True)
1088    @mock.patch.object(module_finder.ModuleFinder, '_get_build_targets')
1089    @mock.patch.object(module_finder.ModuleFinder, '_is_vts_module',
1090                       return_value=False)
1091    @mock.patch.object(test_finder_utils, 'get_fully_qualified_class_name',
1092                       return_value=uc.FULL_CLASS_NAME)
1093    @mock.patch('os.path.realpath',
1094                side_effect=unittest_utils.realpath_side_effect)
1095    @mock.patch('os.path.isfile', side_effect=unittest_utils.isfile_side_effect)
1096    @mock.patch.object(test_finder_utils, 'find_parent_module_dir')
1097    @mock.patch('os.path.exists')
1098    #pylint: disable=unused-argument
1099    def test_find_test_by_path_for_cc_file(self, mock_pathexists, mock_dir,
1100        _isfile, _real, _fqcn, _vts, mock_build, _has_cc_class,
1101        _has_method_in_file, _is_parameterized, _is_build_file,
1102        _mock_cc_class_info):
1103        """Test find_test_by_path for handling correct CC filter."""
1104        self.mod_finder.module_info.is_robolectric_test.return_value = False
1105        self.mod_finder.module_info.has_test_config.return_value = True
1106        mock_build.return_value = set()
1107        # Check that we don't return anything with invalid test references.
1108        mock_pathexists.return_value = False
1109        mock_pathexists.return_value = True
1110        mock_dir.return_value = None
1111        self.mod_finder.module_info.get_module_names.return_value = [uc.MODULE_NAME]
1112        self.mod_finder.module_info.get_module_info.return_value = {
1113            constants.MODULE_INSTALLED: DEFAULT_INSTALL_PATH,
1114            constants.MODULE_NAME: uc.MODULE_NAME,
1115            constants.MODULE_CLASS: [],
1116            constants.MODULE_COMPATIBILITY_SUITES: []}
1117        # Happy path testing.
1118        mock_dir.return_value = uc.MODULE_DIR
1119        # Cc path testing if get_cc_class_info found those information.
1120        self.mod_finder.module_info.get_module_names.return_value = [uc.CC_MODULE_NAME]
1121        self.mod_finder.module_info.get_module_info.return_value = {
1122            constants.MODULE_INSTALLED: DEFAULT_INSTALL_PATH,
1123            constants.MODULE_NAME: uc.CC_MODULE_NAME,
1124            constants.MODULE_CLASS: [],
1125            constants.MODULE_COMPATIBILITY_SUITES: []}
1126        mock_dir.return_value = uc.CC_MODULE_DIR
1127        class_path = '%s' % uc.CC_PATH
1128        mock_build.return_value = uc.CLASS_BUILD_TARGETS
1129        # Test without parameterized test
1130        founded_classed = 'class1'
1131        founded_methods = {'method1'}
1132        founded_prefixes = set()
1133        _mock_cc_class_info.return_value = {founded_classed: {
1134                                              'methods': founded_methods,
1135                                              'prefixes': founded_prefixes,
1136                                              'typed': False}}
1137        self.mod_finder.module_info.get_robolectric_type.return_value = 0
1138        self.mod_finder.module_info.get_instrumentation_target_apps.return_value = {}
1139        cc_path_data = {constants.TI_REL_CONFIG: uc.CC_CONFIG_FILE,
1140                        constants.TI_FILTER: frozenset(
1141                            {test_info.TestFilter(class_name='class1.*',
1142                                                  methods=frozenset())})}
1143        cc_path_info = test_info.TestInfo(uc.CC_MODULE_NAME,
1144                                          atf_tr.AtestTradefedTestRunner.NAME,
1145                                          uc.CLASS_BUILD_TARGETS, cc_path_data)
1146        t_infos = self.mod_finder.find_test_by_path(class_path)
1147        unittest_utils.assert_equal_testinfos(self, cc_path_info, t_infos[0])
1148        # Test with paramertize test defined in input path
1149        founded_prefixes = {'class1'}
1150        _mock_cc_class_info.return_value = {founded_classed: {
1151                                              'methods': founded_methods,
1152                                              'prefixes': founded_prefixes,
1153                                              'typed': False}}
1154        cc_path_data = {constants.TI_REL_CONFIG: uc.CC_CONFIG_FILE,
1155                        constants.TI_FILTER: frozenset(
1156                            {test_info.TestFilter(class_name='*/class1.*',
1157                                                  methods=frozenset())})}
1158        cc_path_info = test_info.TestInfo(uc.CC_MODULE_NAME,
1159                                          atf_tr.AtestTradefedTestRunner.NAME,
1160                                          uc.CLASS_BUILD_TARGETS, cc_path_data)
1161        t_infos = self.mod_finder.find_test_by_path(class_path)
1162        unittest_utils.assert_equal_testinfos(self, cc_path_info, t_infos[0])
1163
1164    # pylint: disable=unused-argument
1165    @mock.patch.object(module_finder.ModuleFinder, '_is_vts_module',
1166                       return_value=False)
1167    @mock.patch.object(module_finder.ModuleFinder, '_get_build_targets',
1168                       return_value=copy.deepcopy(uc.MODULE_BUILD_TARGETS))
1169    def test_process_test_info(self, _get_targ, _is_vts):
1170        """Test _process_test_info."""
1171        mod_info = {'installed': ['/path/to/install'],
1172                    'path': [uc.MODULE_DIR],
1173                    constants.MODULE_CLASS: [
1174                        constants.MODULE_CLASS_JAVA_LIBRARIES],
1175                    constants.MODULE_COMPATIBILITY_SUITES: []}
1176        self.mod_finder.module_info.is_robolectric_test.return_value = False
1177        self.mod_finder.module_info.is_auto_gen_test_config.return_value = True
1178        self.mod_finder.module_info.get_robolectric_type.return_value = 0
1179        self.mod_finder.module_info.get_instrumentation_target_apps.return_value = {}
1180        self.mod_finder.module_info.get_module_info.return_value = mod_info
1181        processed_info = self.mod_finder._process_test_info(
1182            copy.deepcopy(uc.MODULE_INFO))
1183        unittest_utils.assert_equal_testinfos(
1184            self,
1185            processed_info,
1186            uc.MODULE_INFO_W_DALVIK)
1187
1188    # pylint: disable=unused-argument
1189    @mock.patch.object(module_finder.ModuleFinder, '_get_build_targets')
1190    @mock.patch.object(module_info.ModuleInfo, 'get_instrumentation_target_apps')
1191    @mock.patch.object(module_info.ModuleInfo, 'get_robolectric_type')
1192    @mock.patch.object(module_info.ModuleInfo, 'is_testable_module')
1193    def test_process_test_info_with_instrumentation_target_apps(
1194        self, testable, robotype, tapps, btargets):
1195        """Test _process_test_info."""
1196        testable.return_value = True
1197        robotype.return_value = 0
1198        target_module = 'AmSlam'
1199        test_module = 'AmSlamTests'
1200        artifact_path = '/out/somewhere/app/AmSlam.apk'
1201        tapps.return_value = {target_module: {artifact_path}}
1202        btargets.return_value = {target_module}
1203        self.mod_finder.module_info.is_auto_gen_test_config.return_value = True
1204        self.mod_finder.module_info.get_robolectric_type.return_value = 0
1205        test1 = module(name=target_module,
1206                       classes=['APPS'],
1207                       path=['foo/bar/AmSlam'],
1208                       installed=[artifact_path])
1209        test2 = module(name=test_module,
1210                       classes=['APPS'],
1211                       path=['foo/bar/AmSlam/test'],
1212                       installed=['/out/somewhere/app/AmSlamTests.apk'])
1213        info = test_info.TestInfo(test_module,
1214                                  atf_tr.AtestTradefedTestRunner.NAME,
1215                                  set(),
1216                                  {constants.TI_REL_CONFIG: uc.CONFIG_FILE,
1217                                   constants.TI_FILTER: frozenset()})
1218
1219        self.mod_finder.module_info = create_module_info([test1, test2])
1220        t_infos = self.mod_finder._process_test_info(info)
1221
1222        self.assertTrue(target_module in t_infos.build_targets)
1223        self.assertEqual([artifact_path], t_infos.artifacts)
1224
1225    @mock.patch.object(test_finder_utils, 'get_annotated_methods')
1226    def test_is_srcs_match_method_annotation_include_anno(
1227        self, _mock_get_anno_methods):
1228        """Test _is_srcs_match_method_annotation with include annotation."""
1229        annotation_dict = {constants.INCLUDE_ANNOTATION: 'includeAnnotation1'}
1230        input_method = 'my_input_method'
1231        input_srcs = ['src1']
1232        # Test if input method matched include annotation.
1233        _mock_get_anno_methods.return_value = {input_method,
1234                                               'not_my_input_method'}
1235
1236        is_matched = self.mod_finder._is_srcs_match_method_annotation(
1237            input_method, input_srcs, annotation_dict)
1238
1239        self.assertTrue(is_matched)
1240        # Test if input method not matched include annotation.
1241        _mock_get_anno_methods.return_value = {'not_my_input_method'}
1242
1243        is_matched = self.mod_finder._is_srcs_match_method_annotation(
1244            input_method, input_srcs, annotation_dict)
1245
1246        self.assertFalse(is_matched)
1247
1248    @mock.patch.object(test_finder_utils, 'get_annotated_methods')
1249    @mock.patch.object(test_finder_utils, 'get_java_methods')
1250    def test_is_srcs_match_method_exclude_anno(self, _mock_get_java_methods,
1251        _mock_get_exclude_anno_methods):
1252        """Test _is_srcs_match_method_annotation with exclude annotation."""
1253        annotation_dict = {constants.EXCLUDE_ANNOTATION: 'excludeAnnotation1'}
1254        input_method = 'my_input_method'
1255        input_srcs = ['src1']
1256        _mock_get_java_methods.return_value = {input_method,
1257                                               'method1',
1258                                               'method2'}
1259        # Test if input method matched exclude annotation.
1260        _mock_get_exclude_anno_methods.return_value = {input_method, 'method1'}
1261
1262        is_matched = self.mod_finder._is_srcs_match_method_annotation(
1263            input_method, input_srcs, annotation_dict)
1264
1265        self.assertFalse(is_matched)
1266
1267        # Test if input method not matched exclude annotation.
1268        _mock_get_exclude_anno_methods.return_value = {'method2'}
1269
1270        is_matched = self.mod_finder._is_srcs_match_method_annotation(
1271            input_method, input_srcs, annotation_dict)
1272
1273        self.assertTrue(is_matched)
1274
1275    @mock.patch.object(atest_utils, 'get_android_junit_config_filters')
1276    @mock.patch.object(test_finder_utils, 'get_test_config_and_srcs')
1277    def test_get_matched_test_infos_no_filter(self, _mock_get_conf_srcs,
1278        _mock_get_filters):
1279        """Test _get_matched_test_infos without test filters."""
1280        test_info1 = 'test_info1'
1281        test_infos = [test_info1]
1282        test_config = 'test_config'
1283        test_srcs = ['src1', 'src2']
1284        _mock_get_conf_srcs.return_value = test_config, test_srcs
1285        filter_dict = {}
1286        _mock_get_filters.return_value = filter_dict
1287
1288        self.assertEqual(
1289            self.mod_finder._get_matched_test_infos(test_infos, {'method'}),
1290            test_infos)
1291
1292    @mock.patch.object(module_finder.ModuleFinder,
1293                       '_is_srcs_match_method_annotation')
1294    @mock.patch.object(atest_utils, 'get_android_junit_config_filters')
1295    @mock.patch.object(test_finder_utils, 'get_test_config_and_srcs')
1296    def test_get_matched_test_infos_get_filter_method_match(
1297        self, _mock_get_conf_srcs, _mock_get_filters, _mock_method_match):
1298        """Test _get_matched_test_infos with test filters and method match."""
1299        test_infos = [KERNEL_MODULE_CLASS_INFO]
1300        test_config = 'test_config'
1301        test_srcs = ['src1', 'src2']
1302        _mock_get_conf_srcs.return_value = test_config, test_srcs
1303        filter_dict = {'include-annotation': 'annotate1'}
1304        _mock_get_filters.return_value = filter_dict
1305        _mock_method_match.return_value = True
1306
1307        unittest_utils.assert_strict_equal(
1308            self,
1309            self.mod_finder._get_matched_test_infos(test_infos, {'method'}),
1310            test_infos)
1311
1312    @mock.patch.object(module_finder.ModuleFinder,
1313                       '_is_srcs_match_method_annotation')
1314    @mock.patch.object(atest_utils, 'get_android_junit_config_filters')
1315    @mock.patch.object(test_finder_utils, 'get_test_config_and_srcs')
1316    def test_get_matched_test_infos_filter_method_not_match(
1317        self, _mock_get_conf_srcs, _mock_get_filters, _mock_method_match):
1318        """Test _get_matched_test_infos but method not match."""
1319        test_infos = [KERNEL_MODULE_CLASS_INFO]
1320        test_config = 'test_config'
1321        test_srcs = ['src1', 'src2']
1322        _mock_get_conf_srcs.return_value = test_config, test_srcs
1323        filter_dict = {'include-annotation': 'annotate1'}
1324        _mock_get_filters.return_value = filter_dict
1325        _mock_method_match.return_value = False
1326
1327        self.assertEqual(
1328            self.mod_finder._get_matched_test_infos(test_infos, {'method'}),
1329            [])
1330
1331    @mock.patch.object(module_finder.ModuleFinder, '_get_matched_test_infos')
1332    @mock.patch.object(module_finder.ModuleFinder, '_get_test_infos',
1333                       return_value=uc.MODULE_INFO)
1334    @mock.patch.object(module_finder.ModuleFinder, '_get_test_info_filter',
1335                       return_value=uc.CLASS_FILTER)
1336    @mock.patch.object(test_finder_utils, 'find_class_file',
1337                       return_value=['path1'])
1338    def test_find_test_by_class_name_not_matched_filters(
1339        self, _mock_class_path, _mock_test_filters,
1340        _mock_test_infos, _mock_matched_test_infos):
1341        """Test find_test_by_class_name which has not matched filters."""
1342        found_test_infos = [uc.MODULE_INFO, uc.MODULE_INFO2]
1343        _mock_test_infos.return_value = found_test_infos
1344        matched_test_infos = [uc.MODULE_INFO2]
1345        _mock_matched_test_infos.return_value = matched_test_infos
1346
1347        # Test if class without method
1348        test_infos = self.mod_finder.find_test_by_class_name('my.test.class')
1349        self.assertEqual(len(test_infos), 2)
1350        unittest_utils.assert_equal_testinfos(
1351            self, test_infos[0], uc.MODULE_INFO)
1352        unittest_utils.assert_equal_testinfos(
1353            self, test_infos[1], uc.MODULE_INFO2)
1354
1355        # Test if class with method
1356        test_infos = self.mod_finder.find_test_by_class_name(
1357            'my.test.class#myMethod')
1358        self.assertEqual(len(test_infos), 1)
1359        unittest_utils.assert_equal_testinfos(
1360            self, test_infos[0], uc.MODULE_INFO2)
1361
1362    @mock.patch.object(module_finder.ModuleFinder, '_get_test_infos',
1363                       return_value=None)
1364    @mock.patch.object(module_finder.ModuleFinder, '_get_test_info_filter',
1365                       return_value=uc.CLASS_FILTER)
1366    @mock.patch.object(test_finder_utils, 'find_class_file',
1367                       return_value=['path1'])
1368    def test_find_test_by_class_name_get_test_infos_none(
1369        self, _mock_class_path, _mock_test_filters, _mock_test_infos):
1370        """Test find_test_by_class_name which has not matched test infos."""
1371        self.assertEqual(
1372            self.mod_finder.find_test_by_class_name('my.test.class'),
1373            None)
1374
1375
1376def create_empty_module_info():
1377    with fake_filesystem_unittest.Patcher() as patcher:
1378        # pylint: disable=protected-access
1379        fake_temp_file_name = next(tempfile._get_candidate_names())
1380        patcher.fs.create_file(fake_temp_file_name, contents='{}')
1381        return module_info.ModuleInfo(module_file=fake_temp_file_name)
1382
1383
1384def create_module_info(modules=None):
1385    mod_info = create_empty_module_info()
1386    modules = modules or []
1387
1388    for m in modules:
1389        mod_info.name_to_module_info[m['module_name']] = m
1390
1391    return mod_info
1392
1393
1394# pylint: disable=too-many-arguments
1395def module(
1396    name=None,
1397    path=None,
1398    installed=None,
1399    classes=None,
1400    auto_test_config=None,
1401    shared_libs=None,
1402    dependencies=None,
1403    runtime_dependencies=None,
1404    data=None,
1405    data_dependencies=None,
1406    compatibility_suites=None,
1407    host_dependencies=None,
1408    srcs=None,
1409):
1410    name = name or 'libhello'
1411
1412    m = {}
1413
1414    m['module_name'] = name
1415    m['class'] = classes
1416    m['path'] = [path or '']
1417    m['installed'] = installed or []
1418    m['is_unit_test'] = 'false'
1419    m['auto_test_config'] = auto_test_config or []
1420    m['shared_libs'] = shared_libs or []
1421    m['runtime_dependencies'] = runtime_dependencies or []
1422    m['dependencies'] = dependencies or []
1423    m['data'] = data or []
1424    m['data_dependencies'] = data_dependencies or []
1425    m['compatibility_suites'] = compatibility_suites or []
1426    m['host_dependencies'] = host_dependencies or []
1427    m['srcs'] = srcs or []
1428    return m
1429
1430# pylint: disable=too-many-locals
1431def create_test_info(**kwargs):
1432    test_name = kwargs.pop('test_name')
1433    test_runner = kwargs.pop('test_runner')
1434    build_targets = kwargs.pop('build_targets')
1435    data = kwargs.pop('data', None)
1436    suite = kwargs.pop('suite', None)
1437    module_class = kwargs.pop('module_class', None)
1438    install_locations = kwargs.pop('install_locations', None)
1439    test_finder = kwargs.pop('test_finder', '')
1440    compatibility_suites = kwargs.pop('compatibility_suites', None)
1441
1442    t_info = test_info.TestInfo(
1443        test_name=test_name,
1444        test_runner=test_runner,
1445        build_targets=build_targets,
1446        data=data,
1447        suite=suite,
1448        module_class=module_class,
1449        install_locations=install_locations,
1450        test_finder=test_finder,
1451        compatibility_suites=compatibility_suites
1452    )
1453    raw_test_name = kwargs.pop('raw_test_name', None)
1454    if raw_test_name:
1455        t_info.raw_test_name = raw_test_name
1456    artifacts = kwargs.pop('artifacts', set())
1457    if artifacts:
1458        t_info.artifacts = artifacts
1459    robo_type = kwargs.pop('robo_type', None)
1460    if robo_type:
1461        t_info.robo_type = robo_type
1462    mainline_modules = kwargs.pop('mainline_modules', set())
1463    if mainline_modules:
1464        t_info._mainline_modules = mainline_modules
1465    for keyword in ['from_test_mapping',
1466                    'host',
1467                    'aggregate_metrics_result']:
1468        value = kwargs.pop(keyword, 'None')
1469        if isinstance(value, bool):
1470            setattr(t_info, keyword, value)
1471    if kwargs:
1472        assert f'Unknown keyword(s) for test_info: {kwargs.keys()}'
1473    return t_info
1474
1475
1476if __name__ == '__main__':
1477    unittest.main()
1478