blob: fb2530e3c5016692bad25b9b049a18a4137002d4 [file] [log] [blame]
mikehoranbe9102f2017-08-04 16:04:03 -07001#!/usr/bin/env python
2#
3# Copyright 2017, 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 cli_translator."""
18
19import unittest
mikehoran1e50d2b2017-08-28 14:00:46 -070020import os
mikehoran9e62c292018-01-31 12:05:19 -080021import re
mikehoranbe9102f2017-08-04 16:04:03 -070022import mock
23
24import cli_translator as cli_t
Dan Shi7a8e1ad2018-04-12 11:01:07 -070025import constants
Kevin Cheng8b2c94c2017-12-18 14:43:26 -080026import test_finder_handler
Dan Shicdbda552018-05-18 23:31:33 -070027import test_mapping
Kevin Cheng8b2c94c2017-12-18 14:43:26 -080028import unittest_constants as uc
Kevin Cheng7edb0b92017-12-14 15:00:25 -080029import unittest_utils
Kevin Cheng8b2c94c2017-12-18 14:43:26 -080030from test_finders import test_finder_base
mikehoranbe9102f2017-08-04 16:04:03 -070031
Dan Shid6881bb2017-10-12 15:13:25 -070032# TEST_MAPPING related consts
Dan Shie4e267f2018-06-01 11:31:57 -070033TEST_MAPPING_TOP_DIR = os.path.join(uc.TEST_DATA_DIR, 'test_mapping')
34TEST_MAPPING_DIR = os.path.join(TEST_MAPPING_TOP_DIR, 'folder1')
35TEST_1 = test_mapping.TestDetail({'name': 'test1'})
36TEST_2 = test_mapping.TestDetail({'name': 'test2'})
37TEST_3 = test_mapping.TestDetail({'name': 'test3'})
38TEST_4 = test_mapping.TestDetail({'name': 'test4'})
Dan Shi350e7472018-06-19 12:25:32 -070039TEST_5 = test_mapping.TestDetail({'name': 'test5'})
40TEST_6 = test_mapping.TestDetail({'name': 'test6'})
41TEST_7 = test_mapping.TestDetail({'name': 'test7'})
42TEST_8 = test_mapping.TestDetail({'name': 'test8'})
43TEST_9 = test_mapping.TestDetail({'name': 'test9'})
44TEST_10 = test_mapping.TestDetail({'name': 'test10'})
Dan Shid6881bb2017-10-12 15:13:25 -070045
mikehoran9e62c292018-01-31 12:05:19 -080046SEARCH_DIR_RE = re.compile(r'^find ([^ ]*).*$')
47
mikehoran58a68c42017-08-30 13:18:21 -070048
Dan Shicdbda552018-05-18 23:31:33 -070049#pylint: disable=unused-argument
50def gettestinfos_side_effect(test_names, test_mapping_test_details=None):
Kevin Cheng09c2a2c2017-12-15 12:52:46 -080051 """Mock return values for _get_test_info."""
Kevin Cheng8b2c94c2017-12-18 14:43:26 -080052 test_infos = set()
53 for test_name in test_names:
54 if test_name == uc.MODULE_NAME:
55 test_infos.add(uc.MODULE_INFO)
56 if test_name == uc.CLASS_NAME:
57 test_infos.add(uc.CLASS_INFO)
58 return test_infos
mikehoran58a68c42017-08-30 13:18:21 -070059
mikehoran9e62c292018-01-31 12:05:19 -080060
mikehoranbe9102f2017-08-04 16:04:03 -070061#pylint: disable=protected-access
mikehoran43ed32d2017-08-18 17:13:36 -070062#pylint: disable=no-self-use
mikehoranbe9102f2017-08-04 16:04:03 -070063class CLITranslatorUnittests(unittest.TestCase):
64 """Unit tests for cli_t.py"""
65
66 def setUp(self):
67 """Run before execution of every test"""
Kevin Cheng8b2c94c2017-12-18 14:43:26 -080068 self.ctr = cli_t.CLITranslator()
mikehoranbe9102f2017-08-04 16:04:03 -070069
Dan Shi0ddd3e42018-05-30 11:24:30 -070070 # Create a mock of args.
71 self.args = mock.Mock
72 self.args.tests = []
73 # Test mapping related args
74 self.args.test_mapping = False
75 self.args.include_subdirs = False
76
Kevin Cheng8b2c94c2017-12-18 14:43:26 -080077 @mock.patch.object(test_finder_handler, 'get_find_methods_for_test')
78 def test_get_test_infos(self, mock_getfindmethods):
79 """Test _get_test_infos method."""
80 ctr = cli_t.CLITranslator()
81 find_method_return_module_info = lambda x, y: uc.MODULE_INFO
82 # pylint: disable=invalid-name
83 find_method_return_module_class_info = (lambda x, test: uc.MODULE_INFO
84 if test == uc.MODULE_NAME
85 else uc.CLASS_INFO)
86 find_method_return_nothing = lambda x, y: None
87 one_test = [uc.MODULE_NAME]
88 mult_test = [uc.MODULE_NAME, uc.CLASS_NAME]
mikehoran43ed32d2017-08-18 17:13:36 -070089
Kevin Cheng8b2c94c2017-12-18 14:43:26 -080090 # Let's make sure we return what we expect.
91 expected_test_infos = {uc.MODULE_INFO}
92 mock_getfindmethods.return_value = [
nelsonli34997d52018-08-17 09:43:28 +080093 test_finder_base.Finder(None, find_method_return_module_info, None)]
Kevin Cheng8b2c94c2017-12-18 14:43:26 -080094 unittest_utils.assert_strict_equal(
95 self, ctr._get_test_infos(one_test), expected_test_infos)
96
97 # Check we receive multiple test infos.
98 expected_test_infos = {uc.MODULE_INFO, uc.CLASS_INFO}
99 mock_getfindmethods.return_value = [
nelsonli34997d52018-08-17 09:43:28 +0800100 test_finder_base.Finder(None, find_method_return_module_class_info,
101 None)]
Kevin Cheng8b2c94c2017-12-18 14:43:26 -0800102 unittest_utils.assert_strict_equal(
103 self, ctr._get_test_infos(mult_test), expected_test_infos)
104
nelsonlic4a71452018-09-13 14:10:30 +0800105 # Check return null set when we have no tests found.
Kevin Cheng8b2c94c2017-12-18 14:43:26 -0800106 mock_getfindmethods.return_value = [
nelsonli34997d52018-08-17 09:43:28 +0800107 test_finder_base.Finder(None, find_method_return_nothing, None)]
nelsonlic4a71452018-09-13 14:10:30 +0800108 null_test_info = set()
109 self.assertEqual(null_test_info, ctr._get_test_infos(one_test))
110 self.assertEqual(null_test_info, ctr._get_test_infos(mult_test))
Kevin Cheng8b2c94c2017-12-18 14:43:26 -0800111
Dan Shicdbda552018-05-18 23:31:33 -0700112 # Check the method works for test mapping.
113 test_detail1 = test_mapping.TestDetail(uc.TEST_MAPPING_TEST)
114 test_detail2 = test_mapping.TestDetail(uc.TEST_MAPPING_TEST_WITH_OPTION)
115 expected_test_infos = {uc.MODULE_INFO, uc.CLASS_INFO}
116 mock_getfindmethods.return_value = [
nelsonli34997d52018-08-17 09:43:28 +0800117 test_finder_base.Finder(None, find_method_return_module_class_info,
118 None)]
Dan Shicdbda552018-05-18 23:31:33 -0700119 test_infos = ctr._get_test_infos(
120 mult_test, [test_detail1, test_detail2])
121 unittest_utils.assert_strict_equal(
122 self, test_infos, expected_test_infos)
123 for test_info in test_infos:
124 if test_info == uc.MODULE_INFO:
125 self.assertEqual(
126 test_detail1.options,
127 test_info.data[constants.TI_MODULE_ARG])
128 else:
129 self.assertEqual(
130 test_detail2.options,
131 test_info.data[constants.TI_MODULE_ARG])
132
Kevin Cheng8b2c94c2017-12-18 14:43:26 -0800133 @mock.patch.object(cli_t.CLITranslator, '_get_test_infos',
134 side_effect=gettestinfos_side_effect)
Dan Shi0ddd3e42018-05-30 11:24:30 -0700135 def test_translate_class(self, _info):
136 """Test translate method for tests by class name."""
Kevin Cheng8b2c94c2017-12-18 14:43:26 -0800137 # Check that we can find a class.
Dan Shi0ddd3e42018-05-30 11:24:30 -0700138 self.args.tests = [uc.CLASS_NAME]
139 targets, test_infos = self.ctr.translate(self.args)
Dan Shi7a8e1ad2018-04-12 11:01:07 -0700140 unittest_utils.assert_strict_equal(
141 self, targets, uc.CLASS_BUILD_TARGETS)
Kevin Cheng8b2c94c2017-12-18 14:43:26 -0800142 unittest_utils.assert_strict_equal(self, test_infos, {uc.CLASS_INFO})
mikehoranbe9102f2017-08-04 16:04:03 -0700143
Dan Shi0ddd3e42018-05-30 11:24:30 -0700144 @mock.patch.object(cli_t.CLITranslator, '_get_test_infos',
145 side_effect=gettestinfos_side_effect)
146 def test_translate_module(self, _info):
147 """Test translate method for tests by module or class name."""
Kevin Cheng8b2c94c2017-12-18 14:43:26 -0800148 # Check that we get all the build targets we expect.
Dan Shi0ddd3e42018-05-30 11:24:30 -0700149 self.args.tests = [uc.MODULE_NAME, uc.CLASS_NAME]
150 targets, test_infos = self.ctr.translate(self.args)
Dan Shi7a8e1ad2018-04-12 11:01:07 -0700151 unittest_utils.assert_strict_equal(
152 self, targets, uc.MODULE_CLASS_COMBINED_BUILD_TARGETS)
Kevin Cheng8b2c94c2017-12-18 14:43:26 -0800153 unittest_utils.assert_strict_equal(self, test_infos, {uc.MODULE_INFO,
154 uc.CLASS_INFO})
155
Dan Shi0ddd3e42018-05-30 11:24:30 -0700156 @mock.patch.object(cli_t.CLITranslator, '_find_tests_by_test_mapping')
157 @mock.patch.object(cli_t.CLITranslator, '_get_test_infos',
158 side_effect=gettestinfos_side_effect)
159 def test_translate_test_mapping(self, _info, mock_testmapping):
160 """Test translate method for tests in test mapping."""
Kevin Cheng8b2c94c2017-12-18 14:43:26 -0800161 # Check that test mappings feeds into get_test_info properly.
Dan Shicdbda552018-05-18 23:31:33 -0700162 test_detail1 = test_mapping.TestDetail(uc.TEST_MAPPING_TEST)
163 test_detail2 = test_mapping.TestDetail(uc.TEST_MAPPING_TEST_WITH_OPTION)
164 mock_testmapping.return_value = ([test_detail1, test_detail2], None)
Dan Shi0ddd3e42018-05-30 11:24:30 -0700165 self.args.tests = []
166 targets, test_infos = self.ctr.translate(self.args)
Dan Shi7a8e1ad2018-04-12 11:01:07 -0700167 unittest_utils.assert_strict_equal(
168 self, targets, uc.MODULE_CLASS_COMBINED_BUILD_TARGETS)
Kevin Cheng8b2c94c2017-12-18 14:43:26 -0800169 unittest_utils.assert_strict_equal(self, test_infos, {uc.MODULE_INFO,
170 uc.CLASS_INFO})
171
Dan Shie4e267f2018-06-01 11:31:57 -0700172 @mock.patch.object(cli_t.CLITranslator, '_find_tests_by_test_mapping')
173 @mock.patch.object(cli_t.CLITranslator, '_get_test_infos',
174 side_effect=gettestinfos_side_effect)
175 def test_translate_test_mapping_all(self, _info, mock_testmapping):
176 """Test translate method for tests in test mapping."""
177 # Check that test mappings feeds into get_test_info properly.
178 test_detail1 = test_mapping.TestDetail(uc.TEST_MAPPING_TEST)
179 test_detail2 = test_mapping.TestDetail(uc.TEST_MAPPING_TEST_WITH_OPTION)
180 mock_testmapping.return_value = ([test_detail1, test_detail2], None)
181 self.args.tests = ['src_path:all']
182 self.args.test_mapping = True
183 targets, test_infos = self.ctr.translate(self.args)
184 unittest_utils.assert_strict_equal(
185 self, targets, uc.MODULE_CLASS_COMBINED_BUILD_TARGETS)
186 unittest_utils.assert_strict_equal(self, test_infos, {uc.MODULE_INFO,
187 uc.CLASS_INFO})
188
189 def test_find_tests_by_test_mapping_presubmit(self):
190 """Test _find_tests_by_test_mapping method to locate presubmit tests."""
Dan Shi350e7472018-06-19 12:25:32 -0700191 os_environ_mock = {constants.ANDROID_BUILD_TOP: uc.TEST_DATA_DIR}
192 with mock.patch.dict('os.environ', os_environ_mock, clear=True):
193 tests, all_tests = self.ctr._find_tests_by_test_mapping(
194 path=TEST_MAPPING_DIR, file_name='test_mapping_sample',
195 checked_files=set())
196 expected = set([TEST_1, TEST_2, TEST_5, TEST_7, TEST_9])
Dan Shi7a8e1ad2018-04-12 11:01:07 -0700197 expected_all_tests = {'presubmit': expected,
Dan Shi350e7472018-06-19 12:25:32 -0700198 'postsubmit': set(
199 [TEST_3, TEST_6, TEST_8, TEST_10]),
Dan Shie4e267f2018-06-01 11:31:57 -0700200 'other_group': set([TEST_4])}
Dan Shi7a8e1ad2018-04-12 11:01:07 -0700201 self.assertEqual(expected, tests)
202 self.assertEqual(expected_all_tests, all_tests)
Dan Shid6881bb2017-10-12 15:13:25 -0700203
Dan Shie4e267f2018-06-01 11:31:57 -0700204 def test_find_tests_by_test_mapping_postsubmit(self):
Dan Shi350e7472018-06-19 12:25:32 -0700205 """Test _find_tests_by_test_mapping method to locate postsubmit tests.
206 """
207 os_environ_mock = {constants.ANDROID_BUILD_TOP: uc.TEST_DATA_DIR}
208 with mock.patch.dict('os.environ', os_environ_mock, clear=True):
209 tests, all_tests = self.ctr._find_tests_by_test_mapping(
210 path=TEST_MAPPING_DIR,
211 test_group=constants.TEST_GROUP_POSTSUBMIT,
212 file_name='test_mapping_sample', checked_files=set())
213 expected_presubmit = set([TEST_1, TEST_2, TEST_5, TEST_7, TEST_9])
214 expected = set(
215 [TEST_1, TEST_2, TEST_3, TEST_5, TEST_6, TEST_7, TEST_8, TEST_9,
216 TEST_10])
Dan Shie4e267f2018-06-01 11:31:57 -0700217 expected_all_tests = {'presubmit': expected_presubmit,
Dan Shi350e7472018-06-19 12:25:32 -0700218 'postsubmit': set(
219 [TEST_3, TEST_6, TEST_8, TEST_10]),
Dan Shie4e267f2018-06-01 11:31:57 -0700220 'other_group': set([TEST_4])}
Dan Shi7a8e1ad2018-04-12 11:01:07 -0700221 self.assertEqual(expected, tests)
222 self.assertEqual(expected_all_tests, all_tests)
Dan Shid6881bb2017-10-12 15:13:25 -0700223
Dan Shie4e267f2018-06-01 11:31:57 -0700224 def test_find_tests_by_test_mapping_all_group(self):
Dan Shi350e7472018-06-19 12:25:32 -0700225 """Test _find_tests_by_test_mapping method to locate postsubmit tests.
226 """
227 os_environ_mock = {constants.ANDROID_BUILD_TOP: uc.TEST_DATA_DIR}
228 with mock.patch.dict('os.environ', os_environ_mock, clear=True):
229 tests, all_tests = self.ctr._find_tests_by_test_mapping(
230 path=TEST_MAPPING_DIR, test_group=constants.TEST_GROUP_ALL,
231 file_name='test_mapping_sample', checked_files=set())
232 expected_presubmit = set([TEST_1, TEST_2, TEST_5, TEST_7, TEST_9])
233 expected = set([
234 TEST_1, TEST_2, TEST_3, TEST_4, TEST_5, TEST_6, TEST_7, TEST_8,
235 TEST_9, TEST_10])
Dan Shie4e267f2018-06-01 11:31:57 -0700236 expected_all_tests = {'presubmit': expected_presubmit,
Dan Shi350e7472018-06-19 12:25:32 -0700237 'postsubmit': set(
238 [TEST_3, TEST_6, TEST_8, TEST_10]),
Dan Shie4e267f2018-06-01 11:31:57 -0700239 'other_group': set([TEST_4])}
240 self.assertEqual(expected, tests)
241 self.assertEqual(expected_all_tests, all_tests)
242
243 def test_find_tests_by_test_mapping_include_subdir(self):
244 """Test _find_tests_by_test_mapping method to include sub directory."""
Dan Shi350e7472018-06-19 12:25:32 -0700245 os_environ_mock = {constants.ANDROID_BUILD_TOP: uc.TEST_DATA_DIR}
246 with mock.patch.dict('os.environ', os_environ_mock, clear=True):
247 tests, all_tests = self.ctr._find_tests_by_test_mapping(
248 path=TEST_MAPPING_TOP_DIR, file_name='test_mapping_sample',
249 include_subdirs=True, checked_files=set())
250 expected = set([TEST_1, TEST_2, TEST_5, TEST_7, TEST_9])
Dan Shie4e267f2018-06-01 11:31:57 -0700251 expected_all_tests = {'presubmit': expected,
Dan Shi350e7472018-06-19 12:25:32 -0700252 'postsubmit': set([
253 TEST_3, TEST_6, TEST_8, TEST_10]),
Dan Shie4e267f2018-06-01 11:31:57 -0700254 'other_group': set([TEST_4])}
255 self.assertEqual(expected, tests)
256 self.assertEqual(expected_all_tests, all_tests)
257
258
mikehoranbe9102f2017-08-04 16:04:03 -0700259if __name__ == '__main__':
260 unittest.main()