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 'unit_tests': 'chrome/unit_tests.isolate', | 42 'unit_tests': 'chrome/unit_tests.isolate', |
44 'webkit_unit_tests': | 43 'webkit_unit_tests': |
45 'third_party/WebKit/Source/web/WebKitUnitTests.isolate', | 44 'third_party/WebKit/Source/web/WebKitUnitTests.isolate', |
46 } | 45 } |
47 | 46 |
48 # Used for filtering large data deps at a finer grain than what's allowed in | 47 # Used for filtering large data deps at a finer grain than what's allowed in |
49 # isolate files since pushing deps to devices is expensive. | 48 # isolate files since pushing deps to devices is expensive. |
50 # Wildcards are allowed. | 49 # Wildcards are allowed. |
51 _DEPS_EXCLUSION_LIST = [ | 50 DEPS_EXCLUSION_LIST = [ |
52 'chrome/test/data/extensions/api_test', | 51 'chrome/test/data/extensions/api_test', |
53 'chrome/test/data/extensions/secure_shell', | 52 'chrome/test/data/extensions/secure_shell', |
54 'chrome/test/data/firefox*', | 53 'chrome/test/data/firefox*', |
55 'chrome/test/data/gpu', | 54 'chrome/test/data/gpu', |
56 'chrome/test/data/image_decoding', | 55 'chrome/test/data/image_decoding', |
57 'chrome/test/data/import', | 56 'chrome/test/data/import', |
58 'chrome/test/data/page_cycler', | 57 'chrome/test/data/page_cycler', |
59 'chrome/test/data/perf', | 58 'chrome/test/data/perf', |
60 'chrome/test/data/pyauto_private', | 59 'chrome/test/data/pyauto_private', |
61 'chrome/test/data/safari_import', | 60 'chrome/test/data/safari_import', |
62 'chrome/test/data/scroll', | 61 'chrome/test/data/scroll', |
63 'chrome/test/data/third_party', | 62 'chrome/test/data/third_party', |
64 'third_party/hunspell_dictionaries/*.dic', | 63 'third_party/hunspell_dictionaries/*.dic', |
65 # crbug.com/258690 | 64 # crbug.com/258690 |
66 'webkit/data/bmp_decoder', | 65 'webkit/data/bmp_decoder', |
67 'webkit/data/ico_decoder', | 66 'webkit/data/ico_decoder', |
68 ] | 67 ] |
69 | 68 |
70 | 69 |
71 def _GenerateDepsDirUsingIsolate(suite_name, isolate_file_path=None): | |
72 """Generate the dependency dir for the test suite using isolate. | |
73 | |
74 Args: | |
75 suite_name: Name of the test suite (e.g. base_unittests). | |
76 isolate_file_path: .isolate file path to use. If there is a default .isolate | |
77 file path for the suite_name, this will override it. | |
78 """ | |
79 if isolate_file_path: | |
80 if os.path.isabs(isolate_file_path): | |
81 isolate_abs_path = isolate_file_path | |
82 else: | |
83 isolate_abs_path = os.path.join(constants.DIR_SOURCE_ROOT, | |
84 isolate_file_path) | |
85 else: | |
86 isolate_rel_path = _ISOLATE_FILE_PATHS.get(suite_name) | |
87 if not isolate_rel_path: | |
88 logging.info('Did not find an isolate file for the test suite.') | |
89 return | |
90 isolate_abs_path = os.path.join(constants.DIR_SOURCE_ROOT, isolate_rel_path) | |
91 | |
92 isolated_abs_path = os.path.join( | |
93 constants.GetOutDirectory(), '%s.isolated' % suite_name) | |
94 assert os.path.exists(isolate_abs_path), 'Cannot find %s' % isolate_abs_path | |
95 | |
96 i = isolator.Isolator(constants.ISOLATE_DEPS_DIR) | |
97 i.Clear() | |
98 i.Remap(isolate_abs_path, isolated_abs_path) | |
99 # We're relying on the fact that timestamps are preserved | |
100 # by the remap command (hardlinked). Otherwise, all the data | |
101 # will be pushed to the device once we move to using time diff | |
102 # instead of md5sum. Perform a sanity check here. | |
103 i.VerifyHardlinks() | |
104 i.PurgeExcluded(_DEPS_EXCLUSION_LIST) | |
105 i.MoveOutputDeps() | |
106 | |
107 | |
108 def _GetDisabledTestsFilterFromFile(suite_name): | 70 def _GetDisabledTestsFilterFromFile(suite_name): |
109 """Returns a gtest filter based on the *_disabled file. | 71 """Returns a gtest filter based on the *_disabled file. |
110 | 72 |
111 Args: | 73 Args: |
112 suite_name: Name of the test suite (e.g. base_unittests). | 74 suite_name: Name of the test suite (e.g. base_unittests). |
113 | 75 |
114 Returns: | 76 Returns: |
115 A gtest filter which excludes disabled tests. | 77 A gtest filter which excludes disabled tests. |
116 Example: '*-StackTrace.*:StringPrintfTest.StringPrintfMisc' | 78 Example: '*-StackTrace.*:StringPrintfTest.StringPrintfMisc' |
117 """ | 79 """ |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
211 List of tests remaining. | 173 List of tests remaining. |
212 """ | 174 """ |
213 tests = _FilterTestsUsingPrefixes( | 175 tests = _FilterTestsUsingPrefixes( |
214 tests, has_gtest_filter, has_gtest_filter) | 176 tests, has_gtest_filter, has_gtest_filter) |
215 tests = unittest_util.FilterTestNames( | 177 tests = unittest_util.FilterTestNames( |
216 tests, _GetDisabledTestsFilterFromFile(suite_name)) | 178 tests, _GetDisabledTestsFilterFromFile(suite_name)) |
217 | 179 |
218 return tests | 180 return tests |
219 | 181 |
220 | 182 |
221 def PushDataDeps(device, test_options, test_package): | |
222 valgrind_tools.PushFilesForTool(test_options.tool, device) | |
223 if os.path.exists(constants.ISOLATE_DEPS_DIR): | |
224 device_dir = ( | |
225 constants.TEST_EXECUTABLE_DIR | |
226 if test_package.suite_name == 'breakpad_unittests' | |
227 else device.GetExternalStoragePath()) | |
228 device.PushChangedFiles([ | |
229 (os.path.join(constants.ISOLATE_DEPS_DIR, p), | |
230 '%s/%s' % (device_dir, p)) | |
231 for p in os.listdir(constants.ISOLATE_DEPS_DIR)]) | |
232 | |
233 | |
234 def Setup(test_options, devices): | 183 def Setup(test_options, devices): |
235 """Create the test runner factory and tests. | 184 """Create the test runner factory and tests. |
236 | 185 |
237 Args: | 186 Args: |
238 test_options: A GTestOptions object. | 187 test_options: A GTestOptions object. |
239 devices: A list of attached devices. | 188 devices: A list of attached devices. |
240 | 189 |
241 Returns: | 190 Returns: |
242 A tuple of (TestRunnerFactory, tests). | 191 A tuple of (TestRunnerFactory, tests). |
243 """ | 192 """ |
244 test_package = test_package_apk.TestPackageApk(test_options.suite_name) | 193 test_package = test_package_apk.TestPackageApk(test_options.suite_name) |
245 if not os.path.exists(test_package.suite_path): | 194 if not os.path.exists(test_package.suite_path): |
246 exe_test_package = test_package_exe.TestPackageExecutable( | 195 exe_test_package = test_package_exe.TestPackageExecutable( |
247 test_options.suite_name) | 196 test_options.suite_name) |
248 if not os.path.exists(exe_test_package.suite_path): | 197 if not os.path.exists(exe_test_package.suite_path): |
249 raise Exception( | 198 raise Exception( |
250 'Did not find %s target. Ensure it has been built.\n' | 199 'Did not find %s target. Ensure it has been built.\n' |
251 '(not found at %s or %s)' | 200 '(not found at %s or %s)' |
252 % (test_options.suite_name, | 201 % (test_options.suite_name, |
253 test_package.suite_path, | 202 test_package.suite_path, |
254 exe_test_package.suite_path)) | 203 exe_test_package.suite_path)) |
255 test_package = exe_test_package | 204 test_package = exe_test_package |
256 logging.warning('Found target %s', test_package.suite_path) | 205 logging.warning('Found target %s', test_package.suite_path) |
257 | 206 |
258 _GenerateDepsDirUsingIsolate(test_options.suite_name, | 207 base_setup.GenerateDepsDirUsingIsolate(test_options.suite_name, |
259 test_options.isolate_file_path) | 208 test_options.isolate_file_path, |
260 | 209 ISOLATE_FILE_PATHS, |
261 device_utils.DeviceUtils.parallel(devices).pMap( | 210 DEPS_EXCLUSION_LIST) |
262 PushDataDeps, test_options, test_package) | 211 def push_data_deps_to_device_dir(device): |
| 212 device_dir = (constants.TEST_EXECUTABLE_DIR |
| 213 if test_package.suite_name == 'breakpad_unittests' |
| 214 else device.GetExternalStoragePath()) |
| 215 base_setup.PushDataDeps(device, device_dir, test_options) |
| 216 device_utils.DeviceUtils.parallel(devices).pMap(push_data_deps_to_device_dir) |
263 | 217 |
264 tests = _GetTests(test_options, test_package, devices) | 218 tests = _GetTests(test_options, test_package, devices) |
265 | 219 |
266 # Constructs a new TestRunner with the current options. | 220 # Constructs a new TestRunner with the current options. |
267 def TestRunnerFactory(device, _shard_index): | 221 def TestRunnerFactory(device, _shard_index): |
268 return test_runner.TestRunner( | 222 return test_runner.TestRunner( |
269 test_options, | 223 test_options, |
270 device, | 224 device, |
271 test_package) | 225 test_package) |
272 | 226 |
273 if test_options.run_disabled: | 227 if test_options.run_disabled: |
274 test_options = test_options._replace( | 228 test_options = test_options._replace( |
275 test_arguments=('%s --gtest_also_run_disabled_tests' % | 229 test_arguments=('%s --gtest_also_run_disabled_tests' % |
276 test_options.test_arguments)) | 230 test_options.test_arguments)) |
277 else: | 231 else: |
278 tests = _FilterDisabledTests(tests, test_options.suite_name, | 232 tests = _FilterDisabledTests(tests, test_options.suite_name, |
279 bool(test_options.gtest_filter)) | 233 bool(test_options.gtest_filter)) |
280 if test_options.gtest_filter: | 234 if test_options.gtest_filter: |
281 tests = unittest_util.FilterTestNames(tests, test_options.gtest_filter) | 235 tests = unittest_util.FilterTestNames(tests, test_options.gtest_filter) |
282 | 236 |
283 # Coalesce unit tests into a single test per device | 237 # Coalesce unit tests into a single test per device |
284 if test_options.suite_name != 'content_browsertests': | 238 if test_options.suite_name != 'content_browsertests': |
285 num_devices = len(devices) | 239 num_devices = len(devices) |
286 tests = [':'.join(tests[i::num_devices]) for i in xrange(num_devices)] | 240 tests = [':'.join(tests[i::num_devices]) for i in xrange(num_devices)] |
287 tests = [t for t in tests if t] | 241 tests = [t for t in tests if t] |
288 | 242 |
289 return (TestRunnerFactory, tests) | 243 return (TestRunnerFactory, tests) |
OLD | NEW |