1#!/usr/bin/env python
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 test_finder_utils."""
18
19import os
20import unittest
21import mock
22
23# pylint: disable=import-error
24import atest_error
25import constants
26import module_info
27import unittest_constants as uc
28import unittest_utils
29from test_finders import test_finder_utils
30
31CLASS_DIR = 'foo/bar/jank/src/android/jank/cts/ui'
32OTHER_DIR = 'other/dir/'
33OTHER_CLASS_NAME = 'test.java'
34CLASS_NAME3 = 'test2'
35INT_DIR1 = os.path.join(uc.TEST_DATA_DIR, 'integration_dir_testing/int_dir1')
36INT_DIR2 = os.path.join(uc.TEST_DATA_DIR, 'integration_dir_testing/int_dir2')
37INT_FILE_NAME = 'int_dir_testing'
38FIND_TWO = uc.ROOT + 'other/dir/test.java\n' + uc.FIND_ONE
39FIND_THREE = '/a/b/c.java\n/d/e/f.java\n/g/h/i.java'
40FIND_THREE_LIST = ['/a/b/c.java', '/d/e/f.java', '/g/h/i.java']
41VTS_XML = 'VtsAndroidTest.xml'
42VTS_BITNESS_XML = 'VtsBitnessAndroidTest.xml'
43VTS_PUSH_DIR = 'vts_push_files'
44VTS_PLAN_DIR = 'vts_plan_files'
45VTS_XML_TARGETS = {'VtsTestName',
46                   'DATA/nativetest/vts_treble_vintf_test/vts_treble_vintf_test',
47                   'DATA/nativetest64/vts_treble_vintf_test/vts_treble_vintf_test',
48                   'DATA/lib/libhidl-gen-hash.so',
49                   'DATA/lib64/libhidl-gen-hash.so',
50                   'hal-hidl-hash/frameworks/hardware/interfaces/current.txt',
51                   'hal-hidl-hash/hardware/interfaces/current.txt',
52                   'hal-hidl-hash/system/hardware/interfaces/current.txt',
53                   'hal-hidl-hash/system/libhidl/transport/current.txt',
54                   'target_with_delim',
55                   'out/dir/target',
56                   'push_file1_target1',
57                   'push_file1_target2',
58                   'push_file2_target1',
59                   'push_file2_target2',
60                   'CtsDeviceInfo.apk',
61                   'DATA/app/DeviceHealthTests/DeviceHealthTests.apk',
62                   'DATA/app/sl4a/sl4a.apk'}
63VTS_PLAN_TARGETS = {os.path.join(uc.TEST_DATA_DIR, VTS_PLAN_DIR, 'vts-staging-default.xml'),
64                    os.path.join(uc.TEST_DATA_DIR, VTS_PLAN_DIR, 'vts-aa.xml'),
65                    os.path.join(uc.TEST_DATA_DIR, VTS_PLAN_DIR, 'vts-bb.xml'),
66                    os.path.join(uc.TEST_DATA_DIR, VTS_PLAN_DIR, 'vts-cc.xml'),
67                    os.path.join(uc.TEST_DATA_DIR, VTS_PLAN_DIR, 'vts-dd.xml')}
68XML_TARGETS = {'CtsJankDeviceTestCases', 'perf-setup.sh', 'cts-tradefed',
69               'GtsEmptyTestApp'}
70PATH_TO_MODULE_INFO_WITH_AUTOGEN = {
71    'foo/bar/jank' : [{'auto_test_config' : True}]}
72PATH_TO_MODULE_INFO_WITH_MULTI_AUTOGEN = {
73    'foo/bar/jank' : [{'auto_test_config' : True},
74                      {'auto_test_config' : True}]}
75PATH_TO_MODULE_INFO_WITH_MULTI_AUTOGEN_AND_ROBO = {
76    'foo/bar' : [{'auto_test_config' : True},
77                 {'auto_test_config' : True}],
78    'foo/bar/jank': [{constants.MODULE_CLASS : [constants.MODULE_CLASS_ROBOLECTRIC]}]}
79
80#pylint: disable=protected-access
81class TestFinderUtilsUnittests(unittest.TestCase):
82    """Unit tests for test_finder_utils.py"""
83
84    def test_split_methods(self):
85        """Test _split_methods method."""
86        # Class
87        unittest_utils.assert_strict_equal(
88            self,
89            test_finder_utils.split_methods('Class.Name'),
90            ('Class.Name', set()))
91        unittest_utils.assert_strict_equal(
92            self,
93            test_finder_utils.split_methods('Class.Name#Method'),
94            ('Class.Name', {'Method'}))
95        unittest_utils.assert_strict_equal(
96            self,
97            test_finder_utils.split_methods('Class.Name#Method,Method2'),
98            ('Class.Name', {'Method', 'Method2'}))
99        unittest_utils.assert_strict_equal(
100            self,
101            test_finder_utils.split_methods('Class.Name#Method,Method2'),
102            ('Class.Name', {'Method', 'Method2'}))
103        unittest_utils.assert_strict_equal(
104            self,
105            test_finder_utils.split_methods('Class.Name#Method,Method2'),
106            ('Class.Name', {'Method', 'Method2'}))
107        self.assertRaises(
108            atest_error.TooManyMethodsError, test_finder_utils.split_methods,
109            'class.name#Method,class.name.2#method')
110        # Path
111        unittest_utils.assert_strict_equal(
112            self,
113            test_finder_utils.split_methods('foo/bar/class.java'),
114            ('foo/bar/class.java', set()))
115        unittest_utils.assert_strict_equal(
116            self,
117            test_finder_utils.split_methods('foo/bar/class.java#Method'),
118            ('foo/bar/class.java', {'Method'}))
119
120    @mock.patch.object(test_finder_utils, 'has_method_in_file',
121                       return_value=False)
122    @mock.patch('__builtin__.raw_input', return_value='1')
123    def test_extract_test_path(self, _, has_method):
124        """Test extract_test_dir method."""
125        paths = [os.path.join(uc.ROOT, CLASS_DIR, uc.CLASS_NAME + '.java')]
126        unittest_utils.assert_strict_equal(
127            self, test_finder_utils.extract_test_path(uc.FIND_ONE), paths)
128        paths = [os.path.join(uc.ROOT, CLASS_DIR, uc.CLASS_NAME + '.java')]
129        unittest_utils.assert_strict_equal(
130            self, test_finder_utils.extract_test_path(FIND_TWO), paths)
131        has_method.return_value = True
132        paths = [os.path.join(uc.ROOT, CLASS_DIR, uc.CLASS_NAME + '.java')]
133        unittest_utils.assert_strict_equal(
134            self, test_finder_utils.extract_test_path(uc.FIND_ONE, 'method'), paths)
135
136    def test_has_method_in_file(self):
137        """Test has_method_in_file method."""
138        test_path = os.path.join(uc.TEST_DATA_DIR, 'class_file_path_testing',
139                                 'hello_world_test.cc')
140        self.assertTrue(test_finder_utils.has_method_in_file(
141            test_path, frozenset(['PrintHelloWorld'])))
142        self.assertFalse(test_finder_utils.has_method_in_file(
143            test_path, frozenset(['PrintHelloWorld1'])))
144        test_path = os.path.join(uc.TEST_DATA_DIR, 'class_file_path_testing',
145                                 'hello_world_test.java')
146        self.assertTrue(test_finder_utils.has_method_in_file(
147            test_path, frozenset(['testMethod1'])))
148        test_path = os.path.join(uc.TEST_DATA_DIR, 'class_file_path_testing',
149                                 'hello_world_test.java')
150        self.assertTrue(test_finder_utils.has_method_in_file(
151            test_path, frozenset(['testMethod', 'testMethod2'])))
152        test_path = os.path.join(uc.TEST_DATA_DIR, 'class_file_path_testing',
153                                 'hello_world_test.java')
154        self.assertFalse(test_finder_utils.has_method_in_file(
155            test_path, frozenset(['testMethod'])))
156
157    @mock.patch('__builtin__.raw_input', return_value='1')
158    def test_extract_test_from_tests(self, mock_input):
159        """Test method extract_test_from_tests method."""
160        tests = []
161        self.assertEquals(test_finder_utils.extract_test_from_tests(tests), None)
162        paths = [os.path.join(uc.ROOT, CLASS_DIR, uc.CLASS_NAME + '.java')]
163        unittest_utils.assert_strict_equal(
164            self, test_finder_utils.extract_test_path(uc.FIND_ONE), paths)
165        paths = [os.path.join(uc.ROOT, OTHER_DIR, OTHER_CLASS_NAME)]
166        mock_input.return_value = '0'
167        unittest_utils.assert_strict_equal(
168            self, test_finder_utils.extract_test_path(FIND_TWO), paths)
169        # Test inputing out-of-range integer or a string
170        mock_input.return_value = '100'
171        self.assertEquals(test_finder_utils.extract_test_from_tests(
172            uc.CLASS_NAME), [])
173        mock_input.return_value = 'lOO'
174        self.assertEquals(test_finder_utils.extract_test_from_tests(
175            uc.CLASS_NAME), [])
176
177    @mock.patch('__builtin__.raw_input', return_value='1')
178    def test_extract_test_from_multiselect(self, mock_input):
179        """Test method extract_test_from_tests method."""
180        # selecting 'All'
181        paths = ['/a/b/c.java', '/d/e/f.java', '/g/h/i.java']
182        mock_input.return_value = '3'
183        unittest_utils.assert_strict_equal(
184            self, sorted(test_finder_utils.extract_test_from_tests(
185                FIND_THREE_LIST)), sorted(paths))
186        # multi-select
187        paths = ['/a/b/c.java', '/g/h/i.java']
188        mock_input.return_value = '0,2'
189        unittest_utils.assert_strict_equal(
190            self, sorted(test_finder_utils.extract_test_from_tests(
191                FIND_THREE_LIST)), sorted(paths))
192        # selecting a range
193        paths = ['/d/e/f.java', '/g/h/i.java']
194        mock_input.return_value = '1-2'
195        unittest_utils.assert_strict_equal(
196            self, test_finder_utils.extract_test_from_tests(FIND_THREE_LIST), paths)
197        # mixed formats
198        paths = ['/a/b/c.java', '/d/e/f.java', '/g/h/i.java']
199        mock_input.return_value = '0,1-2'
200        unittest_utils.assert_strict_equal(
201            self, sorted(test_finder_utils.extract_test_from_tests(
202                FIND_THREE_LIST)), sorted(paths))
203        # input unsupported formats, return empty
204        paths = []
205        mock_input.return_value = '?/#'
206        unittest_utils.assert_strict_equal(
207            self, test_finder_utils.extract_test_path(FIND_THREE), paths)
208
209    @mock.patch('os.path.isdir')
210    def test_is_equal_or_sub_dir(self, mock_isdir):
211        """Test is_equal_or_sub_dir method."""
212        self.assertTrue(test_finder_utils.is_equal_or_sub_dir('/a/b/c', '/'))
213        self.assertTrue(test_finder_utils.is_equal_or_sub_dir('/a/b/c', '/a'))
214        self.assertTrue(test_finder_utils.is_equal_or_sub_dir('/a/b/c',
215                                                              '/a/b/c'))
216        self.assertFalse(test_finder_utils.is_equal_or_sub_dir('/a/b',
217                                                               '/a/b/c'))
218        self.assertFalse(test_finder_utils.is_equal_or_sub_dir('/a', '/f'))
219        mock_isdir.return_value = False
220        self.assertFalse(test_finder_utils.is_equal_or_sub_dir('/a/b', '/a'))
221
222    @mock.patch('os.path.isdir', return_value=True)
223    @mock.patch('os.path.isfile',
224                side_effect=unittest_utils.isfile_side_effect)
225    def test_find_parent_module_dir(self, _isfile, _isdir):
226        """Test _find_parent_module_dir method."""
227        abs_class_dir = '/%s' % CLASS_DIR
228        mock_module_info = mock.Mock(spec=module_info.ModuleInfo)
229        mock_module_info.path_to_module_info = {}
230        unittest_utils.assert_strict_equal(
231            self,
232            test_finder_utils.find_parent_module_dir(uc.ROOT,
233                                                     abs_class_dir,
234                                                     mock_module_info),
235            uc.MODULE_DIR)
236
237    @mock.patch('os.path.isdir', return_value=True)
238    @mock.patch('os.path.isfile', return_value=False)
239    def test_find_parent_module_dir_with_autogen_config(self, _isfile, _isdir):
240        """Test _find_parent_module_dir method."""
241        abs_class_dir = '/%s' % CLASS_DIR
242        mock_module_info = mock.Mock(spec=module_info.ModuleInfo)
243        mock_module_info.path_to_module_info = PATH_TO_MODULE_INFO_WITH_AUTOGEN
244        unittest_utils.assert_strict_equal(
245            self,
246            test_finder_utils.find_parent_module_dir(uc.ROOT,
247                                                     abs_class_dir,
248                                                     mock_module_info),
249            uc.MODULE_DIR)
250
251    @mock.patch('os.path.isdir', return_value=True)
252    @mock.patch('os.path.isfile', side_effect=[False] * 5 + [True])
253    def test_find_parent_module_dir_with_autogen_subconfig(self, _isfile, _isdir):
254        """Test _find_parent_module_dir method.
255
256        This case is testing when the auto generated config is in a
257        sub-directory of a larger test that contains a test config in a parent
258        directory.
259        """
260        abs_class_dir = '/%s' % CLASS_DIR
261        mock_module_info = mock.Mock(spec=module_info.ModuleInfo)
262        mock_module_info.path_to_module_info = (
263            PATH_TO_MODULE_INFO_WITH_MULTI_AUTOGEN)
264        unittest_utils.assert_strict_equal(
265            self,
266            test_finder_utils.find_parent_module_dir(uc.ROOT,
267                                                     abs_class_dir,
268                                                     mock_module_info),
269            uc.MODULE_DIR)
270
271    @mock.patch('os.path.isdir', return_value=True)
272    @mock.patch('os.path.isfile', return_value=False)
273    def test_find_parent_module_dir_with_multi_autogens(self, _isfile, _isdir):
274        """Test _find_parent_module_dir method.
275
276        This case returns folders with multiple autogenerated configs defined.
277        """
278        abs_class_dir = '/%s' % CLASS_DIR
279        mock_module_info = mock.Mock(spec=module_info.ModuleInfo)
280        mock_module_info.path_to_module_info = (
281            PATH_TO_MODULE_INFO_WITH_MULTI_AUTOGEN)
282        unittest_utils.assert_strict_equal(
283            self,
284            test_finder_utils.find_parent_module_dir(uc.ROOT,
285                                                     abs_class_dir,
286                                                     mock_module_info),
287            uc.MODULE_DIR)
288
289    @mock.patch('os.path.isdir', return_value=True)
290    @mock.patch('os.path.isfile', return_value=False)
291    def test_find_parent_module_dir_with_robo_and_autogens(self, _isfile,
292                                                           _isdir):
293        """Test _find_parent_module_dir method.
294
295        This case returns folders with multiple autogenerated configs defined
296        with a Robo test above them, which is the expected result.
297        """
298        abs_class_dir = '/%s' % CLASS_DIR
299        mock_module_info = mock.Mock(spec=module_info.ModuleInfo)
300        mock_module_info.path_to_module_info = (
301            PATH_TO_MODULE_INFO_WITH_MULTI_AUTOGEN_AND_ROBO)
302        unittest_utils.assert_strict_equal(
303            self,
304            test_finder_utils.find_parent_module_dir(uc.ROOT,
305                                                     abs_class_dir,
306                                                     mock_module_info),
307            uc.MODULE_DIR)
308
309
310    @mock.patch('os.path.isdir', return_value=True)
311    @mock.patch('os.path.isfile', return_value=False)
312    def test_find_parent_module_dir_robo(self, _isfile, _isdir):
313        """Test _find_parent_module_dir method.
314
315        Make sure we behave as expected when we encounter a robo module path.
316        """
317        abs_class_dir = '/%s' % CLASS_DIR
318        mock_module_info = mock.Mock(spec=module_info.ModuleInfo)
319        mock_module_info.is_robolectric_module.return_value = True
320        rel_class_dir_path = os.path.relpath(abs_class_dir, uc.ROOT)
321        mock_module_info.path_to_module_info = {rel_class_dir_path: [{}]}
322        unittest_utils.assert_strict_equal(
323            self,
324            test_finder_utils.find_parent_module_dir(uc.ROOT,
325                                                     abs_class_dir,
326                                                     mock_module_info),
327            rel_class_dir_path)
328
329    def test_get_targets_from_xml(self):
330        """Test get_targets_from_xml method."""
331        # Mocking Etree is near impossible, so use a real file, but mocking
332        # ModuleInfo is still fine. Just have it return False when it finds a
333        # module that states it's not a module.
334        mock_module_info = mock.Mock(spec=module_info.ModuleInfo)
335        mock_module_info.is_module.side_effect = lambda module: (
336            not module == 'is_not_module')
337        xml_file = os.path.join(uc.TEST_DATA_DIR, constants.MODULE_CONFIG)
338        unittest_utils.assert_strict_equal(
339            self,
340            test_finder_utils.get_targets_from_xml(xml_file, mock_module_info),
341            XML_TARGETS)
342
343    @mock.patch.object(test_finder_utils, '_VTS_PUSH_DIR',
344                       os.path.join(uc.TEST_DATA_DIR, VTS_PUSH_DIR))
345    def test_get_targets_from_vts_xml(self):
346        """Test get_targets_from_xml method."""
347        # Mocking Etree is near impossible, so use a real file, but mock out
348        # ModuleInfo,
349        mock_module_info = mock.Mock(spec=module_info.ModuleInfo)
350        mock_module_info.is_module.return_value = True
351        xml_file = os.path.join(uc.TEST_DATA_DIR, VTS_XML)
352        unittest_utils.assert_strict_equal(
353            self,
354            test_finder_utils.get_targets_from_vts_xml(xml_file, '',
355                                                       mock_module_info),
356            VTS_XML_TARGETS)
357
358    @mock.patch('subprocess.check_output')
359    def test_get_ignored_dirs(self, _mock_check_output):
360        """Test _get_ignored_dirs method."""
361
362        # Clean cached value for test.
363        test_finder_utils._get_ignored_dirs.cached_ignore_dirs = []
364
365        build_top = '/a/b'
366        _mock_check_output.return_value = ('/a/b/c/.find-ignore\n'
367                                           '/a/b/out/.out-dir\n'
368                                           '/a/b/d/.out-dir\n\n')
369        # Case 1: $OUT_DIR = ''. No customized out dir.
370        os_environ_mock = {constants.ANDROID_BUILD_TOP: build_top,
371                           constants.ANDROID_OUT_DIR: ''}
372        with mock.patch.dict('os.environ', os_environ_mock, clear=True):
373            correct_ignore_dirs = ['/a/b/c', '/a/b/out', '/a/b/d']
374            ignore_dirs = test_finder_utils._get_ignored_dirs()
375            self.assertEqual(ignore_dirs, correct_ignore_dirs)
376        # Case 2: $OUT_DIR = 'out2'
377        test_finder_utils._get_ignored_dirs.cached_ignore_dirs = []
378        os_environ_mock = {constants.ANDROID_BUILD_TOP: build_top,
379                           constants.ANDROID_OUT_DIR: 'out2'}
380        with mock.patch.dict('os.environ', os_environ_mock, clear=True):
381            correct_ignore_dirs = ['/a/b/c', '/a/b/out', '/a/b/d', '/a/b/out2']
382            ignore_dirs = test_finder_utils._get_ignored_dirs()
383            self.assertEqual(ignore_dirs, correct_ignore_dirs)
384        # Case 3: The $OUT_DIR is abs dir but not under $ANDROID_BUILD_TOP
385        test_finder_utils._get_ignored_dirs.cached_ignore_dirs = []
386        os_environ_mock = {constants.ANDROID_BUILD_TOP: build_top,
387                           constants.ANDROID_OUT_DIR: '/x/y/e/g'}
388        with mock.patch.dict('os.environ', os_environ_mock, clear=True):
389            correct_ignore_dirs = ['/a/b/c', '/a/b/out', '/a/b/d']
390            ignore_dirs = test_finder_utils._get_ignored_dirs()
391            self.assertEqual(ignore_dirs, correct_ignore_dirs)
392        # Case 4: The $OUT_DIR is abs dir and under $ANDROID_BUILD_TOP
393        test_finder_utils._get_ignored_dirs.cached_ignore_dirs = []
394        os_environ_mock = {constants.ANDROID_BUILD_TOP: build_top,
395                           constants.ANDROID_OUT_DIR: '/a/b/e/g'}
396        with mock.patch.dict('os.environ', os_environ_mock, clear=True):
397            correct_ignore_dirs = ['/a/b/c', '/a/b/out', '/a/b/d', '/a/b/e/g']
398            ignore_dirs = test_finder_utils._get_ignored_dirs()
399            self.assertEqual(ignore_dirs, correct_ignore_dirs)
400        # Case 5: There is a file of '.out-dir' under $OUT_DIR.
401        test_finder_utils._get_ignored_dirs.cached_ignore_dirs = []
402        os_environ_mock = {constants.ANDROID_BUILD_TOP: build_top,
403                           constants.ANDROID_OUT_DIR: 'out'}
404        with mock.patch.dict('os.environ', os_environ_mock, clear=True):
405            correct_ignore_dirs = ['/a/b/c', '/a/b/out', '/a/b/d']
406            ignore_dirs = test_finder_utils._get_ignored_dirs()
407            self.assertEqual(ignore_dirs, correct_ignore_dirs)
408        # Case 6: Testing cache. All of the changes are useless.
409        _mock_check_output.return_value = ('/a/b/X/.find-ignore\n'
410                                           '/a/b/YY/.out-dir\n'
411                                           '/a/b/d/.out-dir\n\n')
412        os_environ_mock = {constants.ANDROID_BUILD_TOP: build_top,
413                           constants.ANDROID_OUT_DIR: 'new'}
414        with mock.patch.dict('os.environ', os_environ_mock, clear=True):
415            cached_answer = ['/a/b/c', '/a/b/out', '/a/b/d']
416            none_cached_answer = ['/a/b/X', '/a/b/YY', '/a/b/d', 'a/b/new']
417            ignore_dirs = test_finder_utils._get_ignored_dirs()
418            self.assertEqual(ignore_dirs, cached_answer)
419            self.assertNotEqual(ignore_dirs, none_cached_answer)
420
421    @mock.patch('__builtin__.raw_input', return_value='0')
422    def test_search_integration_dirs(self, mock_input):
423        """Test search_integration_dirs."""
424        mock_input.return_value = '0'
425        paths = [os.path.join(uc.ROOT, INT_DIR1, INT_FILE_NAME+'.xml')]
426        int_dirs = [INT_DIR1]
427        test_result = test_finder_utils.search_integration_dirs(INT_FILE_NAME, int_dirs)
428        unittest_utils.assert_strict_equal(self, test_result, paths)
429        int_dirs = [INT_DIR1, INT_DIR2]
430        test_result = test_finder_utils.search_integration_dirs(INT_FILE_NAME, int_dirs)
431        unittest_utils.assert_strict_equal(self, test_result, paths)
432
433    @mock.patch('os.path.isfile', return_value=False)
434    @mock.patch('os.environ.get', return_value=uc.TEST_CONFIG_DATA_DIR)
435    @mock.patch('__builtin__.raw_input', return_value='0')
436    # pylint: disable=too-many-statements
437    def test_find_class_file(self, mock_input, _mock_env, _mock_isfile):
438        """Test find_class_file."""
439        # 1. Java class(find).
440        java_tmp_test_result = []
441        mock_input.return_value = '0'
442        java_class = os.path.join(uc.FIND_PATH, uc.FIND_PATH_TESTCASE_JAVA + '.java')
443        java_tmp_test_result.extend(test_finder_utils.find_class_file(uc.FIND_PATH,
444                                                                      uc.FIND_PATH_TESTCASE_JAVA))
445        mock_input.return_value = '1'
446        kt_class = os.path.join(uc.FIND_PATH, uc.FIND_PATH_TESTCASE_JAVA + '.kt')
447        java_tmp_test_result.extend(test_finder_utils.find_class_file(uc.FIND_PATH,
448                                                                      uc.FIND_PATH_TESTCASE_JAVA))
449        self.assertTrue(java_class in java_tmp_test_result)
450        self.assertTrue(kt_class in java_tmp_test_result)
451
452        # 2. Java class(read index).
453        del java_tmp_test_result[:]
454        mock_input.return_value = '0'
455        _mock_isfile = True
456        test_finder_utils.FIND_INDEXES['CLASS'] = uc.CLASS_INDEX
457        java_class = os.path.join(uc.FIND_PATH, uc.FIND_PATH_TESTCASE_JAVA + '.java')
458        java_tmp_test_result.extend(test_finder_utils.find_class_file(uc.FIND_PATH,
459                                                                      uc.FIND_PATH_TESTCASE_JAVA))
460        mock_input.return_value = '1'
461        kt_class = os.path.join(uc.FIND_PATH, uc.FIND_PATH_TESTCASE_JAVA + '.kt')
462        java_tmp_test_result.extend(test_finder_utils.find_class_file(uc.FIND_PATH,
463                                                                      uc.FIND_PATH_TESTCASE_JAVA))
464        self.assertTrue(java_class in java_tmp_test_result)
465        self.assertTrue(kt_class in java_tmp_test_result)
466
467        # 3. Qualified Java class(find).
468        del java_tmp_test_result[:]
469        mock_input.return_value = '0'
470        _mock_isfile = False
471        java_qualified_class = '{0}.{1}'.format(uc.FIND_PATH_FOLDER, uc.FIND_PATH_TESTCASE_JAVA)
472        java_tmp_test_result.extend(test_finder_utils.find_class_file(uc.FIND_PATH,
473                                                                      java_qualified_class))
474        mock_input.return_value = '1'
475        java_tmp_test_result.extend(test_finder_utils.find_class_file(uc.FIND_PATH,
476                                                                      java_qualified_class))
477        self.assertTrue(java_class in java_tmp_test_result)
478        self.assertTrue(kt_class in java_tmp_test_result)
479
480        # 4. Qualified Java class(read index).
481        del java_tmp_test_result[:]
482        mock_input.return_value = '0'
483        _mock_isfile = True
484        test_finder_utils.FIND_INDEXES['QUALIFIED_CLASS'] = uc.QCLASS_INDEX
485        java_qualified_class = '{0}.{1}'.format(uc.FIND_PATH_FOLDER, uc.FIND_PATH_TESTCASE_JAVA)
486        java_tmp_test_result.extend(test_finder_utils.find_class_file(uc.FIND_PATH,
487                                                                      java_qualified_class))
488        mock_input.return_value = '1'
489        java_tmp_test_result.extend(test_finder_utils.find_class_file(uc.FIND_PATH,
490                                                                      java_qualified_class))
491        self.assertTrue(java_class in java_tmp_test_result)
492        self.assertTrue(kt_class in java_tmp_test_result)
493
494        # 5. CC class(find).
495        cc_tmp_test_result = []
496        _mock_isfile = False
497        mock_input.return_value = '0'
498        cpp_class = os.path.join(uc.FIND_PATH, uc.FIND_PATH_FILENAME_CC + '.cpp')
499        cc_tmp_test_result.extend(test_finder_utils.find_class_file(uc.FIND_PATH,
500                                                                    uc.FIND_PATH_TESTCASE_CC,
501                                                                    True))
502        mock_input.return_value = '1'
503        cc_class = os.path.join(uc.FIND_PATH, uc.FIND_PATH_FILENAME_CC + '.cc')
504        cc_tmp_test_result.extend(test_finder_utils.find_class_file(uc.FIND_PATH,
505                                                                    uc.FIND_PATH_TESTCASE_CC,
506                                                                    True))
507        self.assertTrue(cpp_class in cc_tmp_test_result)
508        self.assertTrue(cc_class in cc_tmp_test_result)
509
510        # 6. CC class(read index).
511        del cc_tmp_test_result[:]
512        mock_input.return_value = '0'
513        _mock_isfile = True
514        test_finder_utils.FIND_INDEXES['CC_CLASS'] = uc.CC_CLASS_INDEX
515        cpp_class = os.path.join(uc.FIND_PATH, uc.FIND_PATH_FILENAME_CC + '.cpp')
516        cc_tmp_test_result.extend(test_finder_utils.find_class_file(uc.FIND_PATH,
517                                                                    uc.FIND_PATH_TESTCASE_CC,
518                                                                    True))
519        mock_input.return_value = '1'
520        cc_class = os.path.join(uc.FIND_PATH, uc.FIND_PATH_FILENAME_CC + '.cc')
521        cc_tmp_test_result.extend(test_finder_utils.find_class_file(uc.FIND_PATH,
522                                                                    uc.FIND_PATH_TESTCASE_CC,
523                                                                    True))
524        self.assertTrue(cpp_class in cc_tmp_test_result)
525        self.assertTrue(cc_class in cc_tmp_test_result)
526
527    @mock.patch('__builtin__.raw_input', return_value='0')
528    @mock.patch.object(test_finder_utils, 'get_dir_path_and_filename')
529    @mock.patch('os.path.exists', return_value=True)
530    def test_get_int_dir_from_path(self, _exists, _find, mock_input):
531        """Test get_int_dir_from_path."""
532        mock_input.return_value = '0'
533        int_dirs = [INT_DIR1]
534        path = os.path.join(uc.ROOT, INT_DIR1, INT_FILE_NAME+'.xml')
535        _find.return_value = (INT_DIR1, INT_FILE_NAME+'.xml')
536        test_result = test_finder_utils.get_int_dir_from_path(path, int_dirs)
537        unittest_utils.assert_strict_equal(self, test_result, INT_DIR1)
538        _find.return_value = (INT_DIR1, None)
539        test_result = test_finder_utils.get_int_dir_from_path(path, int_dirs)
540        unittest_utils.assert_strict_equal(self, test_result, None)
541        int_dirs = [INT_DIR1, INT_DIR2]
542        _find.return_value = (INT_DIR1, INT_FILE_NAME+'.xml')
543        test_result = test_finder_utils.get_int_dir_from_path(path, int_dirs)
544        unittest_utils.assert_strict_equal(self, test_result, INT_DIR1)
545
546    def test_get_install_locations(self):
547        """Test get_install_locations."""
548        host_installed_paths = ["out/host/a/b"]
549        host_expect = set(['host'])
550        self.assertEqual(test_finder_utils.get_install_locations(host_installed_paths),
551                         host_expect)
552        device_installed_paths = ["out/target/c/d"]
553        device_expect = set(['device'])
554        self.assertEqual(test_finder_utils.get_install_locations(device_installed_paths),
555                         device_expect)
556        both_installed_paths = ["out/host/e", "out/target/f"]
557        both_expect = set(['host', 'device'])
558        self.assertEqual(test_finder_utils.get_install_locations(both_installed_paths),
559                         both_expect)
560        no_installed_paths = []
561        no_expect = set()
562        self.assertEqual(test_finder_utils.get_install_locations(no_installed_paths),
563                         no_expect)
564
565    def test_get_plans_from_vts_xml(self):
566        """Test get_plans_from_vts_xml method."""
567        xml_path = os.path.join(uc.TEST_DATA_DIR, VTS_PLAN_DIR, 'vts-staging-default.xml')
568        self.assertEqual(
569            test_finder_utils.get_plans_from_vts_xml(xml_path),
570            VTS_PLAN_TARGETS)
571        xml_path = os.path.join(uc.TEST_DATA_DIR, VTS_PLAN_DIR, 'NotExist.xml')
572        self.assertRaises(atest_error.XmlNotExistError,
573                          test_finder_utils.get_plans_from_vts_xml, xml_path)
574
575    def test_get_levenshtein_distance(self):
576        """Test get_levenshetine distance module correctly returns distance."""
577        self.assertEqual(test_finder_utils.get_levenshtein_distance(uc.MOD1, uc.FUZZY_MOD1), 1)
578        self.assertEqual(test_finder_utils.get_levenshtein_distance(uc.MOD2, uc.FUZZY_MOD2,
579                                                                    dir_costs=(1, 2, 3)), 3)
580        self.assertEqual(test_finder_utils.get_levenshtein_distance(uc.MOD3, uc.FUZZY_MOD3,
581                                                                    dir_costs=(1, 2, 1)), 8)
582
583
584if __name__ == '__main__':
585    unittest.main()
586