OLD | NEW |
---|---|
1 # Copyright 2013 The Chromium Authors. All rights reserved. | 1 # Copyright 2013 The Chromium Authors. All rights reserved. |
2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 | 4 |
5 """Generates test runner factory and tests for GTests.""" | 5 """Generates test runner factory and tests for GTests.""" |
6 # pylint: disable=W0212 | 6 # pylint: disable=W0212 |
7 | 7 |
8 import logging | 8 import logging |
9 import os | 9 import os |
10 import sys | 10 import sys |
11 | 11 |
12 from pylib import constants | 12 from pylib import constants |
13 from pylib import valgrind_tools | |
14 | 13 |
14 from pylib.base import base_setup | |
15 from pylib.base import base_test_result | 15 from pylib.base import base_test_result |
16 from pylib.base import test_dispatcher | 16 from pylib.base import test_dispatcher |
17 from pylib.device import device_utils | 17 from pylib.device import device_utils |
18 from pylib.gtest import test_package_apk | 18 from pylib.gtest import test_package_apk |
19 from pylib.gtest import test_package_exe | 19 from pylib.gtest import test_package_exe |
20 from pylib.gtest import test_runner | 20 from pylib.gtest import test_runner |
21 from pylib.utils import isolator | |
22 | 21 |
23 sys.path.insert(0, | 22 sys.path.insert(0, |
24 os.path.join(constants.DIR_SOURCE_ROOT, 'build', 'util', 'lib', | 23 os.path.join(constants.DIR_SOURCE_ROOT, 'build', 'util', 'lib', |
25 'common')) | 24 'common')) |
26 import unittest_util # pylint: disable=F0401 | 25 import unittest_util # pylint: disable=F0401 |
27 | 26 |
28 | 27 |
29 _ISOLATE_FILE_PATHS = { | 28 ISOLATE_FILE_PATHS = { |
30 'base_unittests': 'base/base_unittests.isolate', | 29 'base_unittests': 'base/base_unittests.isolate', |
31 'blink_heap_unittests': | 30 'blink_heap_unittests': |
32 'third_party/WebKit/Source/platform/heap/BlinkHeapUnitTests.isolate', | 31 'third_party/WebKit/Source/platform/heap/BlinkHeapUnitTests.isolate', |
33 'breakpad_unittests': 'breakpad/breakpad_unittests.isolate', | 32 'breakpad_unittests': 'breakpad/breakpad_unittests.isolate', |
34 'cc_perftests': 'cc/cc_perftests.isolate', | 33 'cc_perftests': 'cc/cc_perftests.isolate', |
35 'components_unittests': 'components/components_unittests.isolate', | 34 'components_unittests': 'components/components_unittests.isolate', |
36 'content_browsertests': 'content/content_browsertests.isolate', | 35 'content_browsertests': 'content/content_browsertests.isolate', |
37 'content_unittests': 'content/content_unittests.isolate', | 36 'content_unittests': 'content/content_unittests.isolate', |
38 'media_perftests': 'media/media_perftests.isolate', | 37 'media_perftests': 'media/media_perftests.isolate', |
39 'media_unittests': 'media/media_unittests.isolate', | 38 'media_unittests': 'media/media_unittests.isolate', |
40 'net_unittests': 'net/net_unittests.isolate', | 39 'net_unittests': 'net/net_unittests.isolate', |
41 'sql_unittests': 'sql/sql_unittests.isolate', | 40 'sql_unittests': 'sql/sql_unittests.isolate', |
42 'ui_base_unittests': 'ui/base/ui_base_tests.isolate', | 41 'ui_base_unittests': 'ui/base/ui_base_tests.isolate', |
43 'ui_unittests': 'ui/base/ui_base_tests.isolate', | 42 'ui_unittests': 'ui/base/ui_base_tests.isolate', |
44 'unit_tests': 'chrome/unit_tests.isolate', | 43 'unit_tests': 'chrome/unit_tests.isolate', |
45 'webkit_unit_tests': | 44 'webkit_unit_tests': |
46 'third_party/WebKit/Source/web/WebKitUnitTests.isolate', | 45 'third_party/WebKit/Source/web/WebKitUnitTests.isolate', |
47 } | 46 } |
48 | 47 |
49 # Used for filtering large data deps at a finer grain than what's allowed in | 48 # Used for filtering large data deps at a finer grain than what's allowed in |
50 # isolate files since pushing deps to devices is expensive. | 49 # isolate files since pushing deps to devices is expensive. |
51 # Wildcards are allowed. | 50 # Wildcards are allowed. |
52 _DEPS_EXCLUSION_LIST = [ | 51 DEPS_EXCLUSION_LIST = [ |
53 'chrome/test/data/extensions/api_test', | 52 'chrome/test/data/extensions/api_test', |
54 'chrome/test/data/extensions/secure_shell', | 53 'chrome/test/data/extensions/secure_shell', |
55 'chrome/test/data/firefox*', | 54 'chrome/test/data/firefox*', |
56 'chrome/test/data/gpu', | 55 'chrome/test/data/gpu', |
57 'chrome/test/data/image_decoding', | 56 'chrome/test/data/image_decoding', |
58 'chrome/test/data/import', | 57 'chrome/test/data/import', |
59 'chrome/test/data/page_cycler', | 58 'chrome/test/data/page_cycler', |
60 'chrome/test/data/perf', | 59 'chrome/test/data/perf', |
61 'chrome/test/data/pyauto_private', | 60 'chrome/test/data/pyauto_private', |
62 'chrome/test/data/safari_import', | 61 'chrome/test/data/safari_import', |
63 'chrome/test/data/scroll', | 62 'chrome/test/data/scroll', |
64 'chrome/test/data/third_party', | 63 'chrome/test/data/third_party', |
65 'third_party/hunspell_dictionaries/*.dic', | 64 'third_party/hunspell_dictionaries/*.dic', |
66 # crbug.com/258690 | 65 # crbug.com/258690 |
67 'webkit/data/bmp_decoder', | 66 'webkit/data/bmp_decoder', |
68 'webkit/data/ico_decoder', | 67 'webkit/data/ico_decoder', |
69 ] | 68 ] |
70 | 69 |
71 | 70 |
72 def _GenerateDepsDirUsingIsolate(suite_name, isolate_file_path=None): | |
73 """Generate the dependency dir for the test suite using isolate. | |
74 | |
75 Args: | |
76 suite_name: Name of the test suite (e.g. base_unittests). | |
77 isolate_file_path: .isolate file path to use. If there is a default .isolate | |
78 file path for the suite_name, this will override it. | |
79 """ | |
80 if isolate_file_path: | |
81 if os.path.isabs(isolate_file_path): | |
82 isolate_abs_path = isolate_file_path | |
83 else: | |
84 isolate_abs_path = os.path.join(constants.DIR_SOURCE_ROOT, | |
85 isolate_file_path) | |
86 else: | |
87 isolate_rel_path = _ISOLATE_FILE_PATHS.get(suite_name) | |
88 if not isolate_rel_path: | |
89 logging.info('Did not find an isolate file for the test suite.') | |
90 return | |
91 isolate_abs_path = os.path.join(constants.DIR_SOURCE_ROOT, isolate_rel_path) | |
92 | |
93 isolated_abs_path = os.path.join( | |
94 constants.GetOutDirectory(), '%s.isolated' % suite_name) | |
95 assert os.path.exists(isolate_abs_path), 'Cannot find %s' % isolate_abs_path | |
96 | |
97 i = isolator.Isolator(constants.ISOLATE_DEPS_DIR) | |
98 i.Clear() | |
99 i.Remap(isolate_abs_path, isolated_abs_path) | |
100 # We're relying on the fact that timestamps are preserved | |
101 # by the remap command (hardlinked). Otherwise, all the data | |
102 # will be pushed to the device once we move to using time diff | |
103 # instead of md5sum. Perform a sanity check here. | |
104 i.VerifyHardlinks() | |
105 i.PurgeExcluded(_DEPS_EXCLUSION_LIST) | |
106 i.MoveOutputDeps() | |
107 | |
108 | |
109 def _GetDisabledTestsFilterFromFile(suite_name): | 71 def _GetDisabledTestsFilterFromFile(suite_name): |
110 """Returns a gtest filter based on the *_disabled file. | 72 """Returns a gtest filter based on the *_disabled file. |
111 | 73 |
112 Args: | 74 Args: |
113 suite_name: Name of the test suite (e.g. base_unittests). | 75 suite_name: Name of the test suite (e.g. base_unittests). |
114 | 76 |
115 Returns: | 77 Returns: |
116 A gtest filter which excludes disabled tests. | 78 A gtest filter which excludes disabled tests. |
117 Example: '*-StackTrace.*:StringPrintfTest.StringPrintfMisc' | 79 Example: '*-StackTrace.*:StringPrintfTest.StringPrintfMisc' |
118 """ | 80 """ |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
207 List of tests remaining. | 169 List of tests remaining. |
208 """ | 170 """ |
209 tests = _FilterTestsUsingPrefixes( | 171 tests = _FilterTestsUsingPrefixes( |
210 tests, has_gtest_filter, has_gtest_filter) | 172 tests, has_gtest_filter, has_gtest_filter) |
211 tests = unittest_util.FilterTestNames( | 173 tests = unittest_util.FilterTestNames( |
212 tests, _GetDisabledTestsFilterFromFile(suite_name)) | 174 tests, _GetDisabledTestsFilterFromFile(suite_name)) |
213 | 175 |
214 return tests | 176 return tests |
215 | 177 |
216 | 178 |
217 def PushDataDeps(device, test_options, test_package): | |
218 valgrind_tools.PushFilesForTool(test_options.tool, device) | |
219 if os.path.exists(constants.ISOLATE_DEPS_DIR): | |
220 device_dir = ( | |
221 constants.TEST_EXECUTABLE_DIR | |
222 if test_package.suite_name == 'breakpad_unittests' | |
223 else device.GetExternalStoragePath()) | |
224 device.PushChangedFiles([ | |
225 (os.path.join(constants.ISOLATE_DEPS_DIR, p), | |
226 '%s/%s' % (device_dir, p)) | |
227 for p in os.listdir(constants.ISOLATE_DEPS_DIR)]) | |
228 | |
229 | |
230 def Setup(test_options, devices): | 179 def Setup(test_options, devices): |
231 """Create the test runner factory and tests. | 180 """Create the test runner factory and tests. |
232 | 181 |
233 Args: | 182 Args: |
234 test_options: A GTestOptions object. | 183 test_options: A GTestOptions object. |
235 devices: A list of attached devices. | 184 devices: A list of attached devices. |
236 | 185 |
237 Returns: | 186 Returns: |
238 A tuple of (TestRunnerFactory, tests). | 187 A tuple of (TestRunnerFactory, tests). |
239 """ | 188 """ |
240 test_package = test_package_apk.TestPackageApk(test_options.suite_name) | 189 test_package = test_package_apk.TestPackageApk(test_options.suite_name) |
241 if not os.path.exists(test_package.suite_path): | 190 if not os.path.exists(test_package.suite_path): |
242 exe_test_package = test_package_exe.TestPackageExecutable( | 191 exe_test_package = test_package_exe.TestPackageExecutable( |
243 test_options.suite_name) | 192 test_options.suite_name) |
244 if not os.path.exists(exe_test_package.suite_path): | 193 if not os.path.exists(exe_test_package.suite_path): |
245 raise Exception( | 194 raise Exception( |
246 'Did not find %s target. Ensure it has been built.\n' | 195 'Did not find %s target. Ensure it has been built.\n' |
247 '(not found at %s or %s)' | 196 '(not found at %s or %s)' |
248 % (test_options.suite_name, | 197 % (test_options.suite_name, |
249 test_package.suite_path, | 198 test_package.suite_path, |
250 exe_test_package.suite_path)) | 199 exe_test_package.suite_path)) |
251 test_package = exe_test_package | 200 test_package = exe_test_package |
252 logging.warning('Found target %s', test_package.suite_path) | 201 logging.warning('Found target %s', test_package.suite_path) |
253 | 202 |
254 _GenerateDepsDirUsingIsolate(test_options.suite_name, | 203 base_setup.GenerateDepsDirUsingIsolate(test_options.suite_name, |
255 test_options.isolate_file_path) | 204 test_options.isolate_file_path, |
256 | 205 ISOLATE_FILE_PATHS, |
206 DEPS_EXCLUSION_LIST) | |
207 def DeviceDir(device): | |
208 return (constants.TEST_EXECUTABLE_DIR | |
209 if test_package.suite_name == 'breakpad_unittests' | |
210 else device.GetExternalStoragePath()) | |
257 device_utils.DeviceUtils.parallel(devices).pMap( | 211 device_utils.DeviceUtils.parallel(devices).pMap( |
258 PushDataDeps, test_options, test_package) | 212 (lambda d, opts: base_setup.PushDataDeps(d, DeviceDir(d), opts)), |
jbudorick
2014/11/03 15:52:32
Instead of defining DeviceDir as a separate functi
mikecase (-- gone --)
2014/11/06 00:12:21
Done.
| |
213 test_options) | |
259 | 214 |
260 tests = _GetTests(test_options, test_package, devices) | 215 tests = _GetTests(test_options, test_package, devices) |
261 | 216 |
262 # Constructs a new TestRunner with the current options. | 217 # Constructs a new TestRunner with the current options. |
263 def TestRunnerFactory(device, _shard_index): | 218 def TestRunnerFactory(device, _shard_index): |
264 return test_runner.TestRunner( | 219 return test_runner.TestRunner( |
265 test_options, | 220 test_options, |
266 device, | 221 device, |
267 test_package) | 222 test_package) |
268 | 223 |
269 if test_options.run_disabled: | 224 if test_options.run_disabled: |
270 test_options = test_options._replace( | 225 test_options = test_options._replace( |
271 test_arguments=('%s --gtest_also_run_disabled_tests' % | 226 test_arguments=('%s --gtest_also_run_disabled_tests' % |
272 test_options.test_arguments)) | 227 test_options.test_arguments)) |
273 else: | 228 else: |
274 tests = _FilterDisabledTests(tests, test_options.suite_name, | 229 tests = _FilterDisabledTests(tests, test_options.suite_name, |
275 bool(test_options.gtest_filter)) | 230 bool(test_options.gtest_filter)) |
276 if test_options.gtest_filter: | 231 if test_options.gtest_filter: |
277 tests = unittest_util.FilterTestNames(tests, test_options.gtest_filter) | 232 tests = unittest_util.FilterTestNames(tests, test_options.gtest_filter) |
278 | 233 |
279 # Coalesce unit tests into a single test per device | 234 # Coalesce unit tests into a single test per device |
280 if test_options.suite_name != 'content_browsertests': | 235 if test_options.suite_name != 'content_browsertests': |
281 num_devices = len(devices) | 236 num_devices = len(devices) |
282 tests = [':'.join(tests[i::num_devices]) for i in xrange(num_devices)] | 237 tests = [':'.join(tests[i::num_devices]) for i in xrange(num_devices)] |
283 tests = [t for t in tests if t] | 238 tests = [t for t in tests if t] |
284 | 239 |
285 return (TestRunnerFactory, tests) | 240 return (TestRunnerFactory, tests) |
OLD | NEW |