mikehoran | be9102f | 2017-08-04 16:04:03 -0700 | [diff] [blame] | 1 | #!/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 | |
| 19 | import unittest |
mikehoran | 1e50d2b | 2017-08-28 14:00:46 -0700 | [diff] [blame] | 20 | import os |
mikehoran | 9e62c29 | 2018-01-31 12:05:19 -0800 | [diff] [blame] | 21 | import re |
mikehoran | be9102f | 2017-08-04 16:04:03 -0700 | [diff] [blame] | 22 | import mock |
| 23 | |
| 24 | import cli_translator as cli_t |
Dan Shi | 7a8e1ad | 2018-04-12 11:01:07 -0700 | [diff] [blame] | 25 | import constants |
Kevin Cheng | 8b2c94c | 2017-12-18 14:43:26 -0800 | [diff] [blame] | 26 | import test_finder_handler |
Dan Shi | cdbda55 | 2018-05-18 23:31:33 -0700 | [diff] [blame] | 27 | import test_mapping |
Kevin Cheng | 8b2c94c | 2017-12-18 14:43:26 -0800 | [diff] [blame] | 28 | import unittest_constants as uc |
Kevin Cheng | 7edb0b9 | 2017-12-14 15:00:25 -0800 | [diff] [blame] | 29 | import unittest_utils |
Kevin Cheng | 8b2c94c | 2017-12-18 14:43:26 -0800 | [diff] [blame] | 30 | from test_finders import test_finder_base |
mikehoran | be9102f | 2017-08-04 16:04:03 -0700 | [diff] [blame] | 31 | |
Dan Shi | d6881bb | 2017-10-12 15:13:25 -0700 | [diff] [blame] | 32 | # TEST_MAPPING related consts |
Dan Shi | e4e267f | 2018-06-01 11:31:57 -0700 | [diff] [blame] | 33 | TEST_MAPPING_TOP_DIR = os.path.join(uc.TEST_DATA_DIR, 'test_mapping') |
| 34 | TEST_MAPPING_DIR = os.path.join(TEST_MAPPING_TOP_DIR, 'folder1') |
| 35 | TEST_1 = test_mapping.TestDetail({'name': 'test1'}) |
| 36 | TEST_2 = test_mapping.TestDetail({'name': 'test2'}) |
| 37 | TEST_3 = test_mapping.TestDetail({'name': 'test3'}) |
| 38 | TEST_4 = test_mapping.TestDetail({'name': 'test4'}) |
Dan Shi | 350e747 | 2018-06-19 12:25:32 -0700 | [diff] [blame] | 39 | TEST_5 = test_mapping.TestDetail({'name': 'test5'}) |
| 40 | TEST_6 = test_mapping.TestDetail({'name': 'test6'}) |
| 41 | TEST_7 = test_mapping.TestDetail({'name': 'test7'}) |
| 42 | TEST_8 = test_mapping.TestDetail({'name': 'test8'}) |
| 43 | TEST_9 = test_mapping.TestDetail({'name': 'test9'}) |
| 44 | TEST_10 = test_mapping.TestDetail({'name': 'test10'}) |
Dan Shi | d6881bb | 2017-10-12 15:13:25 -0700 | [diff] [blame] | 45 | |
mikehoran | 9e62c29 | 2018-01-31 12:05:19 -0800 | [diff] [blame] | 46 | SEARCH_DIR_RE = re.compile(r'^find ([^ ]*).*$') |
| 47 | |
mikehoran | 58a68c4 | 2017-08-30 13:18:21 -0700 | [diff] [blame] | 48 | |
Dan Shi | cdbda55 | 2018-05-18 23:31:33 -0700 | [diff] [blame] | 49 | #pylint: disable=unused-argument |
| 50 | def gettestinfos_side_effect(test_names, test_mapping_test_details=None): |
Kevin Cheng | 09c2a2c | 2017-12-15 12:52:46 -0800 | [diff] [blame] | 51 | """Mock return values for _get_test_info.""" |
Kevin Cheng | 8b2c94c | 2017-12-18 14:43:26 -0800 | [diff] [blame] | 52 | 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 |
mikehoran | 58a68c4 | 2017-08-30 13:18:21 -0700 | [diff] [blame] | 59 | |
mikehoran | 9e62c29 | 2018-01-31 12:05:19 -0800 | [diff] [blame] | 60 | |
mikehoran | be9102f | 2017-08-04 16:04:03 -0700 | [diff] [blame] | 61 | #pylint: disable=protected-access |
mikehoran | 43ed32d | 2017-08-18 17:13:36 -0700 | [diff] [blame] | 62 | #pylint: disable=no-self-use |
mikehoran | be9102f | 2017-08-04 16:04:03 -0700 | [diff] [blame] | 63 | class CLITranslatorUnittests(unittest.TestCase): |
| 64 | """Unit tests for cli_t.py""" |
| 65 | |
| 66 | def setUp(self): |
| 67 | """Run before execution of every test""" |
Kevin Cheng | 8b2c94c | 2017-12-18 14:43:26 -0800 | [diff] [blame] | 68 | self.ctr = cli_t.CLITranslator() |
mikehoran | be9102f | 2017-08-04 16:04:03 -0700 | [diff] [blame] | 69 | |
Dan Shi | 0ddd3e4 | 2018-05-30 11:24:30 -0700 | [diff] [blame] | 70 | # 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 |
Simran Basi | 2cc996e | 2018-10-09 12:19:25 -0700 | [diff] [blame] | 76 | self.ctr.mod_info = mock.Mock |
| 77 | self.ctr.mod_info.name_to_module_info = {} |
Dan Shi | 0ddd3e4 | 2018-05-30 11:24:30 -0700 | [diff] [blame] | 78 | |
Jim Tang | ae8eb44 | 2018-10-29 16:42:33 +0800 | [diff] [blame^] | 79 | def tearDown(self): |
| 80 | """Run after execution of every test""" |
| 81 | reload(uc) |
| 82 | |
Kevin Cheng | 8b2c94c | 2017-12-18 14:43:26 -0800 | [diff] [blame] | 83 | @mock.patch.object(test_finder_handler, 'get_find_methods_for_test') |
| 84 | def test_get_test_infos(self, mock_getfindmethods): |
| 85 | """Test _get_test_infos method.""" |
| 86 | ctr = cli_t.CLITranslator() |
| 87 | find_method_return_module_info = lambda x, y: uc.MODULE_INFO |
| 88 | # pylint: disable=invalid-name |
| 89 | find_method_return_module_class_info = (lambda x, test: uc.MODULE_INFO |
| 90 | if test == uc.MODULE_NAME |
| 91 | else uc.CLASS_INFO) |
| 92 | find_method_return_nothing = lambda x, y: None |
| 93 | one_test = [uc.MODULE_NAME] |
| 94 | mult_test = [uc.MODULE_NAME, uc.CLASS_NAME] |
mikehoran | 43ed32d | 2017-08-18 17:13:36 -0700 | [diff] [blame] | 95 | |
Kevin Cheng | 8b2c94c | 2017-12-18 14:43:26 -0800 | [diff] [blame] | 96 | # Let's make sure we return what we expect. |
| 97 | expected_test_infos = {uc.MODULE_INFO} |
| 98 | mock_getfindmethods.return_value = [ |
nelsonli | 34997d5 | 2018-08-17 09:43:28 +0800 | [diff] [blame] | 99 | test_finder_base.Finder(None, find_method_return_module_info, None)] |
Kevin Cheng | 8b2c94c | 2017-12-18 14:43:26 -0800 | [diff] [blame] | 100 | unittest_utils.assert_strict_equal( |
| 101 | self, ctr._get_test_infos(one_test), expected_test_infos) |
| 102 | |
| 103 | # Check we receive multiple test infos. |
| 104 | expected_test_infos = {uc.MODULE_INFO, uc.CLASS_INFO} |
| 105 | mock_getfindmethods.return_value = [ |
nelsonli | 34997d5 | 2018-08-17 09:43:28 +0800 | [diff] [blame] | 106 | test_finder_base.Finder(None, find_method_return_module_class_info, |
| 107 | None)] |
Kevin Cheng | 8b2c94c | 2017-12-18 14:43:26 -0800 | [diff] [blame] | 108 | unittest_utils.assert_strict_equal( |
| 109 | self, ctr._get_test_infos(mult_test), expected_test_infos) |
| 110 | |
nelsonli | c4a7145 | 2018-09-13 14:10:30 +0800 | [diff] [blame] | 111 | # Check return null set when we have no tests found. |
Kevin Cheng | 8b2c94c | 2017-12-18 14:43:26 -0800 | [diff] [blame] | 112 | mock_getfindmethods.return_value = [ |
nelsonli | 34997d5 | 2018-08-17 09:43:28 +0800 | [diff] [blame] | 113 | test_finder_base.Finder(None, find_method_return_nothing, None)] |
nelsonli | c4a7145 | 2018-09-13 14:10:30 +0800 | [diff] [blame] | 114 | null_test_info = set() |
| 115 | self.assertEqual(null_test_info, ctr._get_test_infos(one_test)) |
| 116 | self.assertEqual(null_test_info, ctr._get_test_infos(mult_test)) |
Kevin Cheng | 8b2c94c | 2017-12-18 14:43:26 -0800 | [diff] [blame] | 117 | |
Dan Shi | cdbda55 | 2018-05-18 23:31:33 -0700 | [diff] [blame] | 118 | # Check the method works for test mapping. |
| 119 | test_detail1 = test_mapping.TestDetail(uc.TEST_MAPPING_TEST) |
| 120 | test_detail2 = test_mapping.TestDetail(uc.TEST_MAPPING_TEST_WITH_OPTION) |
| 121 | expected_test_infos = {uc.MODULE_INFO, uc.CLASS_INFO} |
| 122 | mock_getfindmethods.return_value = [ |
nelsonli | 34997d5 | 2018-08-17 09:43:28 +0800 | [diff] [blame] | 123 | test_finder_base.Finder(None, find_method_return_module_class_info, |
| 124 | None)] |
Dan Shi | cdbda55 | 2018-05-18 23:31:33 -0700 | [diff] [blame] | 125 | test_infos = ctr._get_test_infos( |
| 126 | mult_test, [test_detail1, test_detail2]) |
| 127 | unittest_utils.assert_strict_equal( |
| 128 | self, test_infos, expected_test_infos) |
| 129 | for test_info in test_infos: |
| 130 | if test_info == uc.MODULE_INFO: |
| 131 | self.assertEqual( |
| 132 | test_detail1.options, |
| 133 | test_info.data[constants.TI_MODULE_ARG]) |
| 134 | else: |
| 135 | self.assertEqual( |
| 136 | test_detail2.options, |
| 137 | test_info.data[constants.TI_MODULE_ARG]) |
| 138 | |
Kevin Cheng | 8b2c94c | 2017-12-18 14:43:26 -0800 | [diff] [blame] | 139 | @mock.patch.object(cli_t.CLITranslator, '_get_test_infos', |
| 140 | side_effect=gettestinfos_side_effect) |
Dan Shi | 0ddd3e4 | 2018-05-30 11:24:30 -0700 | [diff] [blame] | 141 | def test_translate_class(self, _info): |
| 142 | """Test translate method for tests by class name.""" |
Kevin Cheng | 8b2c94c | 2017-12-18 14:43:26 -0800 | [diff] [blame] | 143 | # Check that we can find a class. |
Dan Shi | 0ddd3e4 | 2018-05-30 11:24:30 -0700 | [diff] [blame] | 144 | self.args.tests = [uc.CLASS_NAME] |
| 145 | targets, test_infos = self.ctr.translate(self.args) |
Dan Shi | 7a8e1ad | 2018-04-12 11:01:07 -0700 | [diff] [blame] | 146 | unittest_utils.assert_strict_equal( |
| 147 | self, targets, uc.CLASS_BUILD_TARGETS) |
Kevin Cheng | 8b2c94c | 2017-12-18 14:43:26 -0800 | [diff] [blame] | 148 | unittest_utils.assert_strict_equal(self, test_infos, {uc.CLASS_INFO}) |
mikehoran | be9102f | 2017-08-04 16:04:03 -0700 | [diff] [blame] | 149 | |
Dan Shi | 0ddd3e4 | 2018-05-30 11:24:30 -0700 | [diff] [blame] | 150 | @mock.patch.object(cli_t.CLITranslator, '_get_test_infos', |
| 151 | side_effect=gettestinfos_side_effect) |
| 152 | def test_translate_module(self, _info): |
| 153 | """Test translate method for tests by module or class name.""" |
Kevin Cheng | 8b2c94c | 2017-12-18 14:43:26 -0800 | [diff] [blame] | 154 | # Check that we get all the build targets we expect. |
Dan Shi | 0ddd3e4 | 2018-05-30 11:24:30 -0700 | [diff] [blame] | 155 | self.args.tests = [uc.MODULE_NAME, uc.CLASS_NAME] |
| 156 | targets, test_infos = self.ctr.translate(self.args) |
Dan Shi | 7a8e1ad | 2018-04-12 11:01:07 -0700 | [diff] [blame] | 157 | unittest_utils.assert_strict_equal( |
| 158 | self, targets, uc.MODULE_CLASS_COMBINED_BUILD_TARGETS) |
Kevin Cheng | 8b2c94c | 2017-12-18 14:43:26 -0800 | [diff] [blame] | 159 | unittest_utils.assert_strict_equal(self, test_infos, {uc.MODULE_INFO, |
| 160 | uc.CLASS_INFO}) |
| 161 | |
Dan Shi | 0ddd3e4 | 2018-05-30 11:24:30 -0700 | [diff] [blame] | 162 | @mock.patch.object(cli_t.CLITranslator, '_find_tests_by_test_mapping') |
| 163 | @mock.patch.object(cli_t.CLITranslator, '_get_test_infos', |
| 164 | side_effect=gettestinfos_side_effect) |
| 165 | def test_translate_test_mapping(self, _info, mock_testmapping): |
| 166 | """Test translate method for tests in test mapping.""" |
Kevin Cheng | 8b2c94c | 2017-12-18 14:43:26 -0800 | [diff] [blame] | 167 | # Check that test mappings feeds into get_test_info properly. |
Dan Shi | cdbda55 | 2018-05-18 23:31:33 -0700 | [diff] [blame] | 168 | test_detail1 = test_mapping.TestDetail(uc.TEST_MAPPING_TEST) |
| 169 | test_detail2 = test_mapping.TestDetail(uc.TEST_MAPPING_TEST_WITH_OPTION) |
| 170 | mock_testmapping.return_value = ([test_detail1, test_detail2], None) |
Dan Shi | 0ddd3e4 | 2018-05-30 11:24:30 -0700 | [diff] [blame] | 171 | self.args.tests = [] |
| 172 | targets, test_infos = self.ctr.translate(self.args) |
Dan Shi | 7a8e1ad | 2018-04-12 11:01:07 -0700 | [diff] [blame] | 173 | unittest_utils.assert_strict_equal( |
| 174 | self, targets, uc.MODULE_CLASS_COMBINED_BUILD_TARGETS) |
Kevin Cheng | 8b2c94c | 2017-12-18 14:43:26 -0800 | [diff] [blame] | 175 | unittest_utils.assert_strict_equal(self, test_infos, {uc.MODULE_INFO, |
| 176 | uc.CLASS_INFO}) |
| 177 | |
Dan Shi | e4e267f | 2018-06-01 11:31:57 -0700 | [diff] [blame] | 178 | @mock.patch.object(cli_t.CLITranslator, '_find_tests_by_test_mapping') |
| 179 | @mock.patch.object(cli_t.CLITranslator, '_get_test_infos', |
| 180 | side_effect=gettestinfos_side_effect) |
| 181 | def test_translate_test_mapping_all(self, _info, mock_testmapping): |
| 182 | """Test translate method for tests in test mapping.""" |
| 183 | # Check that test mappings feeds into get_test_info properly. |
| 184 | test_detail1 = test_mapping.TestDetail(uc.TEST_MAPPING_TEST) |
| 185 | test_detail2 = test_mapping.TestDetail(uc.TEST_MAPPING_TEST_WITH_OPTION) |
| 186 | mock_testmapping.return_value = ([test_detail1, test_detail2], None) |
| 187 | self.args.tests = ['src_path:all'] |
| 188 | self.args.test_mapping = True |
| 189 | targets, test_infos = self.ctr.translate(self.args) |
| 190 | unittest_utils.assert_strict_equal( |
| 191 | self, targets, uc.MODULE_CLASS_COMBINED_BUILD_TARGETS) |
| 192 | unittest_utils.assert_strict_equal(self, test_infos, {uc.MODULE_INFO, |
| 193 | uc.CLASS_INFO}) |
| 194 | |
| 195 | def test_find_tests_by_test_mapping_presubmit(self): |
| 196 | """Test _find_tests_by_test_mapping method to locate presubmit tests.""" |
Dan Shi | 350e747 | 2018-06-19 12:25:32 -0700 | [diff] [blame] | 197 | os_environ_mock = {constants.ANDROID_BUILD_TOP: uc.TEST_DATA_DIR} |
| 198 | with mock.patch.dict('os.environ', os_environ_mock, clear=True): |
| 199 | tests, all_tests = self.ctr._find_tests_by_test_mapping( |
| 200 | path=TEST_MAPPING_DIR, file_name='test_mapping_sample', |
| 201 | checked_files=set()) |
| 202 | expected = set([TEST_1, TEST_2, TEST_5, TEST_7, TEST_9]) |
Dan Shi | 7a8e1ad | 2018-04-12 11:01:07 -0700 | [diff] [blame] | 203 | expected_all_tests = {'presubmit': expected, |
Dan Shi | 350e747 | 2018-06-19 12:25:32 -0700 | [diff] [blame] | 204 | 'postsubmit': set( |
| 205 | [TEST_3, TEST_6, TEST_8, TEST_10]), |
Dan Shi | e4e267f | 2018-06-01 11:31:57 -0700 | [diff] [blame] | 206 | 'other_group': set([TEST_4])} |
Dan Shi | 7a8e1ad | 2018-04-12 11:01:07 -0700 | [diff] [blame] | 207 | self.assertEqual(expected, tests) |
| 208 | self.assertEqual(expected_all_tests, all_tests) |
Dan Shi | d6881bb | 2017-10-12 15:13:25 -0700 | [diff] [blame] | 209 | |
Dan Shi | e4e267f | 2018-06-01 11:31:57 -0700 | [diff] [blame] | 210 | def test_find_tests_by_test_mapping_postsubmit(self): |
Dan Shi | 350e747 | 2018-06-19 12:25:32 -0700 | [diff] [blame] | 211 | """Test _find_tests_by_test_mapping method to locate postsubmit tests. |
| 212 | """ |
| 213 | os_environ_mock = {constants.ANDROID_BUILD_TOP: uc.TEST_DATA_DIR} |
| 214 | with mock.patch.dict('os.environ', os_environ_mock, clear=True): |
| 215 | tests, all_tests = self.ctr._find_tests_by_test_mapping( |
| 216 | path=TEST_MAPPING_DIR, |
| 217 | test_group=constants.TEST_GROUP_POSTSUBMIT, |
| 218 | file_name='test_mapping_sample', checked_files=set()) |
| 219 | expected_presubmit = set([TEST_1, TEST_2, TEST_5, TEST_7, TEST_9]) |
| 220 | expected = set( |
| 221 | [TEST_1, TEST_2, TEST_3, TEST_5, TEST_6, TEST_7, TEST_8, TEST_9, |
| 222 | TEST_10]) |
Dan Shi | e4e267f | 2018-06-01 11:31:57 -0700 | [diff] [blame] | 223 | expected_all_tests = {'presubmit': expected_presubmit, |
Dan Shi | 350e747 | 2018-06-19 12:25:32 -0700 | [diff] [blame] | 224 | 'postsubmit': set( |
| 225 | [TEST_3, TEST_6, TEST_8, TEST_10]), |
Dan Shi | e4e267f | 2018-06-01 11:31:57 -0700 | [diff] [blame] | 226 | 'other_group': set([TEST_4])} |
Dan Shi | 7a8e1ad | 2018-04-12 11:01:07 -0700 | [diff] [blame] | 227 | self.assertEqual(expected, tests) |
| 228 | self.assertEqual(expected_all_tests, all_tests) |
Dan Shi | d6881bb | 2017-10-12 15:13:25 -0700 | [diff] [blame] | 229 | |
Dan Shi | e4e267f | 2018-06-01 11:31:57 -0700 | [diff] [blame] | 230 | def test_find_tests_by_test_mapping_all_group(self): |
Dan Shi | 350e747 | 2018-06-19 12:25:32 -0700 | [diff] [blame] | 231 | """Test _find_tests_by_test_mapping method to locate postsubmit tests. |
| 232 | """ |
| 233 | os_environ_mock = {constants.ANDROID_BUILD_TOP: uc.TEST_DATA_DIR} |
| 234 | with mock.patch.dict('os.environ', os_environ_mock, clear=True): |
| 235 | tests, all_tests = self.ctr._find_tests_by_test_mapping( |
| 236 | path=TEST_MAPPING_DIR, test_group=constants.TEST_GROUP_ALL, |
| 237 | file_name='test_mapping_sample', checked_files=set()) |
| 238 | expected_presubmit = set([TEST_1, TEST_2, TEST_5, TEST_7, TEST_9]) |
| 239 | expected = set([ |
| 240 | TEST_1, TEST_2, TEST_3, TEST_4, TEST_5, TEST_6, TEST_7, TEST_8, |
| 241 | TEST_9, TEST_10]) |
Dan Shi | e4e267f | 2018-06-01 11:31:57 -0700 | [diff] [blame] | 242 | expected_all_tests = {'presubmit': expected_presubmit, |
Dan Shi | 350e747 | 2018-06-19 12:25:32 -0700 | [diff] [blame] | 243 | 'postsubmit': set( |
| 244 | [TEST_3, TEST_6, TEST_8, TEST_10]), |
Dan Shi | e4e267f | 2018-06-01 11:31:57 -0700 | [diff] [blame] | 245 | 'other_group': set([TEST_4])} |
| 246 | self.assertEqual(expected, tests) |
| 247 | self.assertEqual(expected_all_tests, all_tests) |
| 248 | |
| 249 | def test_find_tests_by_test_mapping_include_subdir(self): |
| 250 | """Test _find_tests_by_test_mapping method to include sub directory.""" |
Dan Shi | 350e747 | 2018-06-19 12:25:32 -0700 | [diff] [blame] | 251 | os_environ_mock = {constants.ANDROID_BUILD_TOP: uc.TEST_DATA_DIR} |
| 252 | with mock.patch.dict('os.environ', os_environ_mock, clear=True): |
| 253 | tests, all_tests = self.ctr._find_tests_by_test_mapping( |
| 254 | path=TEST_MAPPING_TOP_DIR, file_name='test_mapping_sample', |
| 255 | include_subdirs=True, checked_files=set()) |
| 256 | expected = set([TEST_1, TEST_2, TEST_5, TEST_7, TEST_9]) |
Dan Shi | e4e267f | 2018-06-01 11:31:57 -0700 | [diff] [blame] | 257 | expected_all_tests = {'presubmit': expected, |
Dan Shi | 350e747 | 2018-06-19 12:25:32 -0700 | [diff] [blame] | 258 | 'postsubmit': set([ |
| 259 | TEST_3, TEST_6, TEST_8, TEST_10]), |
Dan Shi | e4e267f | 2018-06-01 11:31:57 -0700 | [diff] [blame] | 260 | 'other_group': set([TEST_4])} |
| 261 | self.assertEqual(expected, tests) |
| 262 | self.assertEqual(expected_all_tests, all_tests) |
| 263 | |
| 264 | |
mikehoran | be9102f | 2017-08-04 16:04:03 -0700 | [diff] [blame] | 265 | if __name__ == '__main__': |
| 266 | unittest.main() |