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
21import re
22import unittest
23import os
24
25from unittest import mock
26
27import atest_error
28import constants
29import module_info
30import unittest_constants as uc
31import unittest_utils
32
33from test_finders import module_finder
34from test_finders import test_finder_utils
35from test_finders import test_info
36from test_runners import atest_tf_test_runner as atf_tr
37
38MODULE_CLASS = '%s:%s' % (uc.MODULE_NAME, uc.CLASS_NAME)
39MODULE_PACKAGE = '%s:%s' % (uc.MODULE_NAME, uc.PACKAGE)
40CC_MODULE_CLASS = '%s:%s' % (uc.CC_MODULE_NAME, uc.CC_CLASS_NAME)
41KERNEL_TEST_CLASS = 'test_class_1'
42KERNEL_TEST_CONFIG = 'KernelTest.xml'
43KERNEL_MODULE_CLASS = '%s:%s' % (constants.REQUIRED_KERNEL_TEST_MODULES[0],
44                                 KERNEL_TEST_CLASS)
45KERNEL_CONFIG_FILE = os.path.join(uc.TEST_DATA_DIR, KERNEL_TEST_CONFIG)
46KERNEL_CLASS_FILTER = test_info.TestFilter(KERNEL_TEST_CLASS, frozenset())
47KERNEL_MODULE_CLASS_DATA = {constants.TI_REL_CONFIG: KERNEL_CONFIG_FILE,
48                            constants.TI_FILTER: frozenset([KERNEL_CLASS_FILTER])}
49KERNEL_MODULE_CLASS_INFO = test_info.TestInfo(
50    constants.REQUIRED_KERNEL_TEST_MODULES[0],
51    atf_tr.AtestTradefedTestRunner.NAME,
52    uc.CLASS_BUILD_TARGETS, KERNEL_MODULE_CLASS_DATA)
53FLAT_METHOD_INFO = test_info.TestInfo(
54    uc.MODULE_NAME,
55    atf_tr.AtestTradefedTestRunner.NAME,
56    uc.MODULE_BUILD_TARGETS,
57    data={constants.TI_FILTER: frozenset([uc.FLAT_METHOD_FILTER]),
58          constants.TI_REL_CONFIG: uc.CONFIG_FILE})
59MODULE_CLASS_METHOD = '%s#%s' % (MODULE_CLASS, uc.METHOD_NAME)
60CC_MODULE_CLASS_METHOD = '%s#%s' % (CC_MODULE_CLASS, uc.CC_METHOD_NAME)
61CLASS_INFO_MODULE_2 = test_info.TestInfo(
62    uc.MODULE2_NAME,
63    atf_tr.AtestTradefedTestRunner.NAME,
64    uc.CLASS_BUILD_TARGETS,
65    data={constants.TI_FILTER: frozenset([uc.CLASS_FILTER]),
66          constants.TI_REL_CONFIG: uc.CONFIG2_FILE})
67CC_CLASS_INFO_MODULE_2 = test_info.TestInfo(
68    uc.CC_MODULE2_NAME,
69    atf_tr.AtestTradefedTestRunner.NAME,
70    uc.CLASS_BUILD_TARGETS,
71    data={constants.TI_FILTER: frozenset([uc.CC_CLASS_FILTER]),
72          constants.TI_REL_CONFIG: uc.CC_CONFIG2_FILE})
73DEFAULT_INSTALL_PATH = ['/path/to/install']
74ROBO_MOD_PATH = ['/shared/robo/path']
75NON_RUN_ROBO_MOD_NAME = 'robo_mod'
76RUN_ROBO_MOD_NAME = 'run_robo_mod'
77NON_RUN_ROBO_MOD = {constants.MODULE_NAME: NON_RUN_ROBO_MOD_NAME,
78                    constants.MODULE_PATH: ROBO_MOD_PATH,
79                    constants.MODULE_CLASS: ['random_class']}
80RUN_ROBO_MOD = {constants.MODULE_NAME: RUN_ROBO_MOD_NAME,
81                constants.MODULE_PATH: ROBO_MOD_PATH,
82                constants.MODULE_CLASS: [constants.MODULE_CLASS_ROBOLECTRIC]}
83
84SEARCH_DIR_RE = re.compile(r'^find ([^ ]*).*$')
85
86#pylint: disable=unused-argument
87def classoutside_side_effect(find_cmd, shell=False):
88    """Mock the check output of a find cmd where class outside module path."""
89    search_dir = SEARCH_DIR_RE.match(find_cmd).group(1).strip()
90    if search_dir == uc.ROOT:
91        return uc.FIND_ONE
92    return None
93
94
95#pylint: disable=protected-access
96class ModuleFinderUnittests(unittest.TestCase):
97    """Unit tests for module_finder.py"""
98
99    def setUp(self):
100        """Set up stuff for testing."""
101        self.mod_finder = module_finder.ModuleFinder()
102        self.mod_finder.module_info = mock.Mock(spec=module_info.ModuleInfo)
103        self.mod_finder.module_info.path_to_module_info = {}
104        self.mod_finder.root_dir = uc.ROOT
105
106    def test_is_vts_module(self):
107        """Test _load_module_info_file regular operation."""
108        mod_name = 'mod'
109        is_vts_module_info = {'compatibility_suites': ['vts10', 'tests']}
110        self.mod_finder.module_info.get_module_info.return_value = is_vts_module_info
111        self.assertTrue(self.mod_finder._is_vts_module(mod_name))
112
113        is_not_vts_module = {'compatibility_suites': ['vts10', 'cts']}
114        self.mod_finder.module_info.get_module_info.return_value = is_not_vts_module
115        self.assertFalse(self.mod_finder._is_vts_module(mod_name))
116
117    # pylint: disable=unused-argument
118    @mock.patch.object(module_finder.ModuleFinder, '_get_build_targets',
119                       return_value=uc.MODULE_BUILD_TARGETS)
120    def test_find_test_by_module_name(self, _get_targ):
121        """Test find_test_by_module_name."""
122        self.mod_finder.module_info.is_robolectric_test.return_value = False
123        self.mod_finder.module_info.has_test_config.return_value = True
124        mod_info = {'installed': ['/path/to/install'],
125                    'path': [uc.MODULE_DIR],
126                    constants.MODULE_CLASS: [],
127                    constants.MODULE_COMPATIBILITY_SUITES: []}
128        self.mod_finder.module_info.get_module_info.return_value = mod_info
129        t_infos = self.mod_finder.find_test_by_module_name(uc.MODULE_NAME)
130        unittest_utils.assert_equal_testinfos(
131            self,
132            t_infos[0],
133            uc.MODULE_INFO)
134        self.mod_finder.module_info.get_module_info.return_value = None
135        self.mod_finder.module_info.is_testable_module.return_value = False
136        self.assertIsNone(self.mod_finder.find_test_by_module_name('Not_Module'))
137
138    @mock.patch.object(test_finder_utils, 'has_method_in_file',
139                       return_value=True)
140    @mock.patch.object(module_finder.ModuleFinder, '_is_vts_module',
141                       return_value=False)
142    @mock.patch.object(module_finder.ModuleFinder, '_get_build_targets')
143    @mock.patch('subprocess.check_output', return_value=uc.FIND_ONE)
144    @mock.patch.object(test_finder_utils, 'get_fully_qualified_class_name',
145                       return_value=uc.FULL_CLASS_NAME)
146    @mock.patch('os.path.isfile', side_effect=unittest_utils.isfile_side_effect)
147    @mock.patch('os.path.isdir', return_value=True)
148    #pylint: disable=unused-argument
149    def test_find_test_by_class_name(self, _isdir, _isfile, _fqcn,
150                                     mock_checkoutput, mock_build,
151                                     _vts, _has_method_in_file):
152        """Test find_test_by_class_name."""
153        mock_build.return_value = uc.CLASS_BUILD_TARGETS
154        self.mod_finder.module_info.is_auto_gen_test_config.return_value = False
155        self.mod_finder.module_info.is_robolectric_test.return_value = False
156        self.mod_finder.module_info.has_test_config.return_value = True
157        self.mod_finder.module_info.get_module_names.return_value = [uc.MODULE_NAME]
158        self.mod_finder.module_info.get_module_info.return_value = {
159            constants.MODULE_INSTALLED: DEFAULT_INSTALL_PATH,
160            constants.MODULE_NAME: uc.MODULE_NAME,
161            constants.MODULE_CLASS: [],
162            constants.MODULE_COMPATIBILITY_SUITES: []}
163        t_infos = self.mod_finder.find_test_by_class_name(uc.CLASS_NAME)
164        unittest_utils.assert_equal_testinfos(
165            self, t_infos[0], uc.CLASS_INFO)
166
167        # with method
168        mock_build.return_value = uc.MODULE_BUILD_TARGETS
169        class_with_method = '%s#%s' % (uc.CLASS_NAME, uc.METHOD_NAME)
170        t_infos = self.mod_finder.find_test_by_class_name(class_with_method)
171        unittest_utils.assert_equal_testinfos(
172            self, t_infos[0], uc.METHOD_INFO)
173        mock_build.return_value = uc.MODULE_BUILD_TARGETS
174        class_methods = '%s,%s' % (class_with_method, uc.METHOD2_NAME)
175        t_infos = self.mod_finder.find_test_by_class_name(class_methods)
176        unittest_utils.assert_equal_testinfos(
177            self, t_infos[0],
178            FLAT_METHOD_INFO)
179        # module and rel_config passed in
180        mock_build.return_value = uc.CLASS_BUILD_TARGETS
181        t_infos = self.mod_finder.find_test_by_class_name(
182            uc.CLASS_NAME, uc.MODULE_NAME, uc.CONFIG_FILE)
183        unittest_utils.assert_equal_testinfos(
184            self, t_infos[0], uc.CLASS_INFO)
185        # find output fails to find class file
186        mock_checkoutput.return_value = ''
187        self.assertIsNone(self.mod_finder.find_test_by_class_name('Not class'))
188        # class is outside given module path
189        mock_checkoutput.side_effect = classoutside_side_effect
190        t_infos = self.mod_finder.find_test_by_class_name(uc.CLASS_NAME,
191                                                          uc.MODULE2_NAME,
192                                                          uc.CONFIG2_FILE)
193        unittest_utils.assert_equal_testinfos(
194            self, t_infos[0],
195            CLASS_INFO_MODULE_2)
196
197    @mock.patch.object(test_finder_utils, 'has_method_in_file',
198                       return_value=True)
199    @mock.patch.object(module_finder.ModuleFinder, '_is_vts_module',
200                       return_value=False)
201    @mock.patch.object(module_finder.ModuleFinder, '_get_build_targets')
202    @mock.patch('subprocess.check_output', return_value=uc.FIND_ONE)
203    @mock.patch.object(test_finder_utils, 'get_fully_qualified_class_name',
204                       return_value=uc.FULL_CLASS_NAME)
205    @mock.patch('os.path.isfile', side_effect=unittest_utils.isfile_side_effect)
206    #pylint: disable=unused-argument
207    def test_find_test_by_module_and_class(self, _isfile, _fqcn,
208                                           mock_checkoutput, mock_build,
209                                           _vts, _has_method_in_file):
210        """Test find_test_by_module_and_class."""
211        # Native test was tested in test_find_test_by_cc_class_name().
212        self.mod_finder.module_info.is_native_test.return_value = False
213        self.mod_finder.module_info.is_auto_gen_test_config.return_value = False
214        self.mod_finder.module_info.is_robolectric_test.return_value = False
215        self.mod_finder.module_info.has_test_config.return_value = True
216        mock_build.return_value = uc.CLASS_BUILD_TARGETS
217        mod_info = {constants.MODULE_INSTALLED: DEFAULT_INSTALL_PATH,
218                    constants.MODULE_PATH: [uc.MODULE_DIR],
219                    constants.MODULE_CLASS: [],
220                    constants.MODULE_COMPATIBILITY_SUITES: []}
221        self.mod_finder.module_info.get_module_info.return_value = mod_info
222        t_infos = self.mod_finder.find_test_by_module_and_class(MODULE_CLASS)
223        unittest_utils.assert_equal_testinfos(self, t_infos[0], uc.CLASS_INFO)
224        # with method
225        mock_build.return_value = uc.MODULE_BUILD_TARGETS
226        t_infos = self.mod_finder.find_test_by_module_and_class(MODULE_CLASS_METHOD)
227        unittest_utils.assert_equal_testinfos(self, t_infos[0], uc.METHOD_INFO)
228        self.mod_finder.module_info.is_testable_module.return_value = False
229        # bad module, good class, returns None
230        bad_module = '%s:%s' % ('BadMod', uc.CLASS_NAME)
231        self.mod_finder.module_info.get_module_info.return_value = None
232        self.assertIsNone(self.mod_finder.find_test_by_module_and_class(bad_module))
233        # find output fails to find class file
234        mock_checkoutput.return_value = ''
235        bad_class = '%s:%s' % (uc.MODULE_NAME, 'Anything')
236        self.mod_finder.module_info.get_module_info.return_value = mod_info
237        self.assertIsNone(self.mod_finder.find_test_by_module_and_class(bad_class))
238
239    @mock.patch.object(module_finder.ModuleFinder, 'find_test_by_kernel_class_name',
240                       return_value=None)
241    @mock.patch.object(module_finder.ModuleFinder, '_is_vts_module',
242                       return_value=False)
243    @mock.patch.object(module_finder.ModuleFinder, '_get_build_targets')
244    @mock.patch('subprocess.check_output', return_value=uc.FIND_CC_ONE)
245    @mock.patch.object(test_finder_utils, 'find_class_file',
246                       side_effect=[None, None, '/'])
247    @mock.patch('os.path.isfile', side_effect=unittest_utils.isfile_side_effect)
248    #pylint: disable=unused-argument
249    def test_find_test_by_module_and_class_part_2(self, _isfile, mock_fcf,
250                                                  mock_checkoutput, mock_build,
251                                                  _vts, _find_kernel):
252        """Test find_test_by_module_and_class for MODULE:CC_CLASS."""
253        # Native test was tested in test_find_test_by_cc_class_name()
254        self.mod_finder.module_info.is_native_test.return_value = False
255        self.mod_finder.module_info.is_auto_gen_test_config.return_value = False
256        self.mod_finder.module_info.is_robolectric_test.return_value = False
257        self.mod_finder.module_info.has_test_config.return_value = True
258        mock_build.return_value = uc.CLASS_BUILD_TARGETS
259        mod_info = {constants.MODULE_INSTALLED: DEFAULT_INSTALL_PATH,
260                    constants.MODULE_PATH: [uc.CC_MODULE_DIR],
261                    constants.MODULE_CLASS: [],
262                    constants.MODULE_COMPATIBILITY_SUITES: []}
263        self.mod_finder.module_info.get_module_info.return_value = mod_info
264        t_infos = self.mod_finder.find_test_by_module_and_class(CC_MODULE_CLASS)
265        unittest_utils.assert_equal_testinfos(self, t_infos[0], uc.CC_MODULE_CLASS_INFO)
266        # with method
267        mock_build.return_value = uc.MODULE_BUILD_TARGETS
268        mock_fcf.side_effect = [None, None, '/']
269        t_infos = self.mod_finder.find_test_by_module_and_class(CC_MODULE_CLASS_METHOD)
270        unittest_utils.assert_equal_testinfos(self, t_infos[0], uc.CC_METHOD_INFO)
271        # bad module, good class, returns None
272        bad_module = '%s:%s' % ('BadMod', uc.CC_CLASS_NAME)
273        self.mod_finder.module_info.get_module_info.return_value = None
274        self.mod_finder.module_info.is_testable_module.return_value = False
275        self.assertIsNone(self.mod_finder.find_test_by_module_and_class(bad_module))
276
277    @mock.patch.object(module_finder.ModuleFinder, '_get_module_test_config',
278                       return_value=KERNEL_CONFIG_FILE)
279    @mock.patch.object(module_finder.ModuleFinder, '_is_vts_module',
280                       return_value=False)
281    @mock.patch.object(module_finder.ModuleFinder, '_get_build_targets')
282    @mock.patch('subprocess.check_output', return_value=uc.FIND_CC_ONE)
283    @mock.patch.object(test_finder_utils, 'find_class_file',
284                       side_effect=[None, None, '/'])
285    @mock.patch('os.path.isfile', side_effect=unittest_utils.isfile_side_effect)
286    #pylint: disable=unused-argument
287    def test_find_test_by_module_and_class_for_kernel_test(
288            self, _isfile, mock_fcf, mock_checkoutput, mock_build, _vts,
289            _test_config):
290        """Test find_test_by_module_and_class for MODULE:CC_CLASS."""
291        # Kernel test was tested in find_test_by_kernel_class_name()
292        self.mod_finder.module_info.is_native_test.return_value = False
293        self.mod_finder.module_info.is_auto_gen_test_config.return_value = False
294        self.mod_finder.module_info.is_robolectric_test.return_value = False
295        self.mod_finder.module_info.has_test_config.return_value = True
296        mock_build.return_value = uc.CLASS_BUILD_TARGETS
297        mod_info = {constants.MODULE_INSTALLED: DEFAULT_INSTALL_PATH,
298                    constants.MODULE_PATH: [uc.CC_MODULE_DIR],
299                    constants.MODULE_CLASS: [],
300                    constants.MODULE_COMPATIBILITY_SUITES: []}
301        self.mod_finder.module_info.get_module_info.return_value = mod_info
302        t_infos = self.mod_finder.find_test_by_module_and_class(KERNEL_MODULE_CLASS)
303        unittest_utils.assert_equal_testinfos(self, t_infos[0], KERNEL_MODULE_CLASS_INFO)
304
305    @mock.patch.object(module_finder.ModuleFinder, '_is_vts_module',
306                       return_value=False)
307    @mock.patch.object(module_finder.ModuleFinder, '_get_build_targets')
308    @mock.patch('subprocess.check_output', return_value=uc.FIND_PKG)
309    @mock.patch('os.path.isfile', side_effect=unittest_utils.isfile_side_effect)
310    @mock.patch('os.path.isdir', return_value=True)
311    #pylint: disable=unused-argument
312    def test_find_test_by_package_name(self, _isdir, _isfile, mock_checkoutput,
313                                       mock_build, _vts):
314        """Test find_test_by_package_name."""
315        self.mod_finder.module_info.is_auto_gen_test_config.return_value = False
316        self.mod_finder.module_info.is_robolectric_test.return_value = False
317        self.mod_finder.module_info.has_test_config.return_value = True
318        mock_build.return_value = uc.CLASS_BUILD_TARGETS
319        self.mod_finder.module_info.get_module_names.return_value = [uc.MODULE_NAME]
320        self.mod_finder.module_info.get_module_info.return_value = {
321            constants.MODULE_INSTALLED: DEFAULT_INSTALL_PATH,
322            constants.MODULE_NAME: uc.MODULE_NAME,
323            constants.MODULE_CLASS: [],
324            constants.MODULE_COMPATIBILITY_SUITES: []
325            }
326        t_infos = self.mod_finder.find_test_by_package_name(uc.PACKAGE)
327        unittest_utils.assert_equal_testinfos(
328            self, t_infos[0],
329            uc.PACKAGE_INFO)
330        # with method, should raise
331        pkg_with_method = '%s#%s' % (uc.PACKAGE, uc.METHOD_NAME)
332        self.assertRaises(atest_error.MethodWithoutClassError,
333                          self.mod_finder.find_test_by_package_name,
334                          pkg_with_method)
335        # module and rel_config passed in
336        t_infos = self.mod_finder.find_test_by_package_name(
337            uc.PACKAGE, uc.MODULE_NAME, uc.CONFIG_FILE)
338        unittest_utils.assert_equal_testinfos(
339            self, t_infos[0], uc.PACKAGE_INFO)
340        # find output fails to find class file
341        mock_checkoutput.return_value = ''
342        self.assertIsNone(self.mod_finder.find_test_by_package_name('Not pkg'))
343
344    @mock.patch('os.path.isdir', return_value=False)
345    @mock.patch.object(module_finder.ModuleFinder, '_is_vts_module',
346                       return_value=False)
347    @mock.patch.object(module_finder.ModuleFinder, '_get_build_targets')
348    @mock.patch('subprocess.check_output', return_value=uc.FIND_PKG)
349    @mock.patch('os.path.isfile', side_effect=unittest_utils.isfile_side_effect)
350    #pylint: disable=unused-argument
351    def test_find_test_by_module_and_package(self, _isfile, mock_checkoutput,
352                                             mock_build, _vts, _isdir):
353        """Test find_test_by_module_and_package."""
354        self.mod_finder.module_info.is_auto_gen_test_config.return_value = False
355        self.mod_finder.module_info.is_robolectric_test.return_value = False
356        self.mod_finder.module_info.has_test_config.return_value = True
357        mock_build.return_value = uc.CLASS_BUILD_TARGETS
358        mod_info = {constants.MODULE_INSTALLED: DEFAULT_INSTALL_PATH,
359                    constants.MODULE_PATH: [uc.MODULE_DIR],
360                    constants.MODULE_CLASS: [],
361                    constants.MODULE_COMPATIBILITY_SUITES: []}
362        self.mod_finder.module_info.get_module_info.return_value = mod_info
363        t_infos = self.mod_finder.find_test_by_module_and_package(MODULE_PACKAGE)
364        self.assertEqual(t_infos, None)
365        _isdir.return_value = True
366        t_infos = self.mod_finder.find_test_by_module_and_package(MODULE_PACKAGE)
367        unittest_utils.assert_equal_testinfos(self, t_infos[0], uc.PACKAGE_INFO)
368
369        # with method, raises
370        module_pkg_with_method = '%s:%s#%s' % (uc.MODULE2_NAME, uc.PACKAGE,
371                                               uc.METHOD_NAME)
372        self.assertRaises(atest_error.MethodWithoutClassError,
373                          self.mod_finder.find_test_by_module_and_package,
374                          module_pkg_with_method)
375        # bad module, good pkg, returns None
376        self.mod_finder.module_info.is_testable_module.return_value = False
377        bad_module = '%s:%s' % ('BadMod', uc.PACKAGE)
378        self.mod_finder.module_info.get_module_info.return_value = None
379        self.assertIsNone(self.mod_finder.find_test_by_module_and_package(bad_module))
380        # find output fails to find package path
381        mock_checkoutput.return_value = ''
382        bad_pkg = '%s:%s' % (uc.MODULE_NAME, 'Anything')
383        self.mod_finder.module_info.get_module_info.return_value = mod_info
384        self.assertIsNone(self.mod_finder.find_test_by_module_and_package(bad_pkg))
385
386    @mock.patch.object(test_finder_utils, 'has_method_in_file',
387                       return_value=True)
388    @mock.patch.object(test_finder_utils, 'has_cc_class',
389                       return_value=True)
390    @mock.patch.object(module_finder.ModuleFinder, '_get_build_targets')
391    @mock.patch.object(module_finder.ModuleFinder, '_is_vts_module',
392                       return_value=False)
393    @mock.patch.object(test_finder_utils, 'get_fully_qualified_class_name',
394                       return_value=uc.FULL_CLASS_NAME)
395    @mock.patch('os.path.realpath',
396                side_effect=unittest_utils.realpath_side_effect)
397    @mock.patch('os.path.isfile', side_effect=unittest_utils.isfile_side_effect)
398    @mock.patch.object(test_finder_utils, 'find_parent_module_dir')
399    @mock.patch('os.path.exists')
400    #pylint: disable=unused-argument
401    def test_find_test_by_path(self, mock_pathexists, mock_dir, _isfile, _real,
402                               _fqcn, _vts, mock_build, _has_cc_class,
403                               _has_method_in_file):
404        """Test find_test_by_path."""
405        self.mod_finder.module_info.is_robolectric_test.return_value = False
406        self.mod_finder.module_info.has_test_config.return_value = True
407        mock_build.return_value = set()
408        # Check that we don't return anything with invalid test references.
409        mock_pathexists.return_value = False
410        unittest_utils.assert_equal_testinfos(
411            self, None, self.mod_finder.find_test_by_path('bad/path'))
412        mock_pathexists.return_value = True
413        mock_dir.return_value = None
414        unittest_utils.assert_equal_testinfos(
415            self, None, self.mod_finder.find_test_by_path('no/module'))
416        self.mod_finder.module_info.get_module_names.return_value = [uc.MODULE_NAME]
417        self.mod_finder.module_info.get_module_info.return_value = {
418            constants.MODULE_INSTALLED: DEFAULT_INSTALL_PATH,
419            constants.MODULE_NAME: uc.MODULE_NAME,
420            constants.MODULE_CLASS: [],
421            constants.MODULE_COMPATIBILITY_SUITES: []}
422
423        # Happy path testing.
424        mock_dir.return_value = uc.MODULE_DIR
425
426        class_path = '%s.kt' % uc.CLASS_NAME
427        mock_build.return_value = uc.CLASS_BUILD_TARGETS
428        t_infos = self.mod_finder.find_test_by_path(class_path)
429        unittest_utils.assert_equal_testinfos(
430            self, uc.CLASS_INFO, t_infos[0])
431
432        class_path = '%s.java' % uc.CLASS_NAME
433        mock_build.return_value = uc.CLASS_BUILD_TARGETS
434        t_infos = self.mod_finder.find_test_by_path(class_path)
435        unittest_utils.assert_equal_testinfos(
436            self, uc.CLASS_INFO, t_infos[0])
437
438        class_with_method = '%s#%s' % (class_path, uc.METHOD_NAME)
439        mock_build.return_value = uc.MODULE_BUILD_TARGETS
440        t_infos = self.mod_finder.find_test_by_path(class_with_method)
441        unittest_utils.assert_equal_testinfos(
442            self, t_infos[0], uc.METHOD_INFO)
443
444        class_with_methods = '%s,%s' % (class_with_method, uc.METHOD2_NAME)
445        mock_build.return_value = uc.MODULE_BUILD_TARGETS
446        t_infos = self.mod_finder.find_test_by_path(class_with_methods)
447        unittest_utils.assert_equal_testinfos(
448            self, t_infos[0],
449            FLAT_METHOD_INFO)
450
451        # Cc path testing.
452        self.mod_finder.module_info.get_module_names.return_value = [uc.CC_MODULE_NAME]
453        self.mod_finder.module_info.get_module_info.return_value = {
454            constants.MODULE_INSTALLED: DEFAULT_INSTALL_PATH,
455            constants.MODULE_NAME: uc.CC_MODULE_NAME,
456            constants.MODULE_CLASS: [],
457            constants.MODULE_COMPATIBILITY_SUITES: []}
458        mock_dir.return_value = uc.CC_MODULE_DIR
459        class_path = '%s' % uc.CC_PATH
460        mock_build.return_value = uc.CLASS_BUILD_TARGETS
461        t_infos = self.mod_finder.find_test_by_path(class_path)
462        unittest_utils.assert_equal_testinfos(
463            self, uc.CC_PATH_INFO2, t_infos[0])
464
465    @mock.patch.object(module_finder.ModuleFinder, '_get_build_targets',
466                       return_value=uc.MODULE_BUILD_TARGETS)
467    @mock.patch.object(module_finder.ModuleFinder, '_is_vts_module',
468                       return_value=False)
469    @mock.patch.object(test_finder_utils, 'find_parent_module_dir',
470                       return_value=os.path.relpath(uc.TEST_DATA_DIR, uc.ROOT))
471    #pylint: disable=unused-argument
472    def test_find_test_by_path_part_2(self, _find_parent, _is_vts, _get_build):
473        """Test find_test_by_path for directories."""
474        self.mod_finder.module_info.is_auto_gen_test_config.return_value = False
475        self.mod_finder.module_info.is_robolectric_test.return_value = False
476        self.mod_finder.module_info.has_test_config.return_value = True
477        # Dir with java files in it, should run as package
478        class_dir = os.path.join(uc.TEST_DATA_DIR, 'path_testing')
479        self.mod_finder.module_info.get_module_names.return_value = [uc.MODULE_NAME]
480        self.mod_finder.module_info.get_module_info.return_value = {
481            constants.MODULE_INSTALLED: DEFAULT_INSTALL_PATH,
482            constants.MODULE_NAME: uc.MODULE_NAME,
483            constants.MODULE_CLASS: [],
484            constants.MODULE_COMPATIBILITY_SUITES: []}
485        t_infos = self.mod_finder.find_test_by_path(class_dir)
486        unittest_utils.assert_equal_testinfos(
487            self, uc.PATH_INFO, t_infos[0])
488        # Dir with no java files in it, should run whole module
489        empty_dir = os.path.join(uc.TEST_DATA_DIR, 'path_testing_empty')
490        t_infos = self.mod_finder.find_test_by_path(empty_dir)
491        unittest_utils.assert_equal_testinfos(
492            self, uc.EMPTY_PATH_INFO,
493            t_infos[0])
494        # Dir with cc files in it, should run as cc class
495        class_dir = os.path.join(uc.TEST_DATA_DIR, 'cc_path_testing')
496        self.mod_finder.module_info.get_module_names.return_value = [uc.CC_MODULE_NAME]
497        self.mod_finder.module_info.get_module_info.return_value = {
498            constants.MODULE_INSTALLED: DEFAULT_INSTALL_PATH,
499            constants.MODULE_NAME: uc.CC_MODULE_NAME,
500            constants.MODULE_CLASS: [],
501            constants.MODULE_COMPATIBILITY_SUITES: []}
502        t_infos = self.mod_finder.find_test_by_path(class_dir)
503        unittest_utils.assert_equal_testinfos(
504            self, uc.CC_PATH_INFO, t_infos[0])
505
506    @mock.patch.object(test_finder_utils, 'has_method_in_file',
507                       return_value=True)
508    @mock.patch.object(module_finder.ModuleFinder, '_is_vts_module',
509                       return_value=False)
510    @mock.patch.object(module_finder.ModuleFinder, '_get_build_targets')
511    @mock.patch('subprocess.check_output', return_value=uc.CC_FIND_ONE)
512    @mock.patch('os.path.isfile', side_effect=unittest_utils.isfile_side_effect)
513    @mock.patch('os.path.isdir', return_value=True)
514    #pylint: disable=unused-argument
515    def test_find_test_by_cc_class_name(self, _isdir, _isfile,
516                                        mock_checkoutput, mock_build,
517                                        _vts, _has_method):
518        """Test find_test_by_cc_class_name."""
519        mock_build.return_value = uc.CLASS_BUILD_TARGETS
520        self.mod_finder.module_info.is_auto_gen_test_config.return_value = False
521        self.mod_finder.module_info.is_robolectric_test.return_value = False
522        self.mod_finder.module_info.has_test_config.return_value = True
523        self.mod_finder.module_info.get_module_names.return_value = [uc.CC_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.CC_MODULE_NAME,
527            constants.MODULE_CLASS: [],
528            constants.MODULE_COMPATIBILITY_SUITES: []}
529        t_infos = self.mod_finder.find_test_by_cc_class_name(uc.CC_CLASS_NAME)
530        unittest_utils.assert_equal_testinfos(
531            self, t_infos[0], uc.CC_CLASS_INFO)
532
533        # with method
534        mock_build.return_value = uc.MODULE_BUILD_TARGETS
535        class_with_method = '%s#%s' % (uc.CC_CLASS_NAME, uc.CC_METHOD_NAME)
536        t_infos = self.mod_finder.find_test_by_cc_class_name(class_with_method)
537        unittest_utils.assert_equal_testinfos(
538            self,
539            t_infos[0],
540            uc.CC_METHOD_INFO)
541        mock_build.return_value = uc.MODULE_BUILD_TARGETS
542        class_methods = '%s,%s' % (class_with_method, uc.CC_METHOD2_NAME)
543        t_infos = self.mod_finder.find_test_by_cc_class_name(class_methods)
544        unittest_utils.assert_equal_testinfos(
545            self, t_infos[0],
546            uc.CC_METHOD2_INFO)
547        # module and rel_config passed in
548        mock_build.return_value = uc.CLASS_BUILD_TARGETS
549        t_infos = self.mod_finder.find_test_by_cc_class_name(
550            uc.CC_CLASS_NAME, uc.CC_MODULE_NAME, uc.CC_CONFIG_FILE)
551        unittest_utils.assert_equal_testinfos(
552            self, t_infos[0], uc.CC_CLASS_INFO)
553        # find output fails to find class file
554        mock_checkoutput.return_value = ''
555        self.assertIsNone(self.mod_finder.find_test_by_cc_class_name(
556            'Not class'))
557        # class is outside given module path
558        mock_checkoutput.return_value = uc.CC_FIND_ONE
559        t_infos = self.mod_finder.find_test_by_cc_class_name(
560            uc.CC_CLASS_NAME,
561            uc.CC_MODULE2_NAME,
562            uc.CC_CONFIG2_FILE)
563        unittest_utils.assert_equal_testinfos(
564            self, t_infos[0],
565            CC_CLASS_INFO_MODULE_2)
566
567    def test_get_testable_modules_with_ld(self):
568        """Test get_testable_modules_with_ld"""
569        self.mod_finder.module_info.get_testable_modules.return_value = [
570            uc.MODULE_NAME, uc.MODULE2_NAME]
571        # Without a misfit constraint
572        ld1 = self.mod_finder.get_testable_modules_with_ld(uc.TYPO_MODULE_NAME)
573        self.assertEqual([[16, uc.MODULE2_NAME], [1, uc.MODULE_NAME]], ld1)
574        # With a misfit constraint
575        ld2 = self.mod_finder.get_testable_modules_with_ld(uc.TYPO_MODULE_NAME, 2)
576        self.assertEqual([[1, uc.MODULE_NAME]], ld2)
577
578    def test_get_fuzzy_searching_modules(self):
579        """Test get_fuzzy_searching_modules"""
580        self.mod_finder.module_info.get_testable_modules.return_value = [
581            uc.MODULE_NAME, uc.MODULE2_NAME]
582        result = self.mod_finder.get_fuzzy_searching_results(uc.TYPO_MODULE_NAME)
583        self.assertEqual(uc.MODULE_NAME, result[0])
584
585    def test_get_build_targets_w_vts_core(self):
586        """Test _get_build_targets."""
587        self.mod_finder.module_info.is_auto_gen_test_config.return_value = True
588        self.mod_finder.module_info.get_paths.return_value = []
589        mod_info = {constants.MODULE_COMPATIBILITY_SUITES:
590                        [constants.VTS_CORE_SUITE]}
591        self.mod_finder.module_info.get_module_info.return_value = mod_info
592        self.assertEqual(self.mod_finder._get_build_targets('', ''),
593                         {constants.VTS_CORE_TF_MODULE})
594
595
596if __name__ == '__main__':
597    unittest.main()
598