OLD | NEW |
---|---|
1 # Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 # Copyright (c) 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 import copy | 5 import copy |
6 import fnmatch | 6 import fnmatch |
7 import glob | |
7 import logging | 8 import logging |
8 import os | 9 import os |
10 import shutil | |
9 | 11 |
10 from pylib import android_commands | 12 from pylib import android_commands |
11 from pylib import cmd_helper | 13 from pylib import cmd_helper |
12 from pylib import constants | 14 from pylib import constants |
13 from pylib import ports | 15 from pylib import ports |
14 from pylib.base import shard | 16 from pylib.base import shard |
15 from pylib.utils import emulator | 17 from pylib.utils import emulator |
16 from pylib.utils import report_results | 18 from pylib.utils import report_results |
17 from pylib.utils import xvfb | 19 from pylib.utils import xvfb |
18 | 20 |
19 import gtest_config | 21 import gtest_config |
20 import test_runner | 22 import test_runner |
21 | 23 |
22 | 24 |
25 # TODO(frankf): Enable the use of the remaining isolate files | |
26 # after making sure we don't blow up the dependency size (and | |
27 # the world). | |
28 _ISOLATE_FILE_PATHS = { | |
29 'base_unittests': 'base/base_unittests.isolate', | |
30 'unit_tests': 'chrome/unit_tests.isolate', | |
31 #'net_unittests': 'net/net_unittests.isolate', | |
M-A Ruel
2013/07/08 17:56:02
I'd recommend to keep the keys sorted even if the
frankf
2013/07/09 01:09:35
Done.
| |
32 #'content_browsertests': 'content/content_browsertests.isolate', | |
33 #'content_unittests': 'content/content_unittests.isolate', | |
34 } | |
35 # Used for filtering large data deps at a finer grain than what's allowed in | |
M-A Ruel
2013/07/08 17:56:02
Add at least one whitespace between a variable and
frankf
2013/07/09 01:09:35
Done.
| |
36 # isolate files since pushing deps to devices is expensive. | |
37 _DEPS_EXCLUSION_LIST = [ | |
38 'chrome/test/data/extensions/api_test', | |
39 'chrome/test/data/extensions/secure_shell', | |
40 'chrome/test/data/firefox*', | |
41 'chrome/test/data/image_decoding', | |
42 'chrome/test/data/import', | |
43 'chrome/test/data/page_cycler', | |
44 'chrome/test/data/perf', | |
45 'chrome/test/data/pyauto_private', | |
46 'chrome/test/data/safari_import', | |
47 'chrome/test/data/scroll', | |
48 'chrome/test/data/third_party', | |
49 'third_party/hunspell_dictionaries/*.dic', | |
50 ] | |
51 _ISOLATE_SCRIPT = os.path.join( | |
52 constants.DIR_SOURCE_ROOT, 'tools', 'swarm_client', 'isolate.py') | |
53 | |
54 | |
55 def _GenerateDepsDirUsingIsolate(test_suite, build_type): | |
56 """Generate the dependency dir for the test suite using isolate. | |
57 | |
58 Args: | |
59 test_suite: The test suite basename (e.g. base_unittests). | |
60 build_type: Release/Debug | |
61 | |
62 Returns: | |
63 If an isolate file exists, returns path to dependency dir on the host. | |
64 Otherwise, returns False. | |
65 """ | |
66 product_dir = os.path.join(cmd_helper.OutDirectory.get(), build_type) | |
67 assert os.path.isabs(product_dir) | |
68 isolate_rel_path = _ISOLATE_FILE_PATHS.get(test_suite) | |
69 if not isolate_rel_path: | |
70 return False | |
71 | |
72 isolate_abs_path = os.path.join(constants.DIR_SOURCE_ROOT, isolate_rel_path) | |
73 isolated_abs_path = os.path.join( | |
74 product_dir, '%s.isolated' % test_suite) | |
75 assert os.path.exists(isolate_abs_path) | |
76 deps_dir = os.path.join(product_dir, 'isolate_deps_dir') | |
77 if os.path.isdir(deps_dir): | |
78 shutil.rmtree(deps_dir) | |
79 # We're relying on the fact that timestamps are preserved | |
80 # by the remap command (hardlinked). Otherwise, all the data | |
csharp
2013/07/04 13:23:16
I'm a bit concerned about this code relying on rem
M-A Ruel
2013/07/08 17:56:02
Or add a unit test for remap to ensure this assump
frankf
2013/07/09 01:09:35
Done. I'm checking that the first file we hit duri
| |
81 # will be pushed to the device once we move to using time diff | |
82 # instead of md5sum. | |
83 isolate_cmd = [ | |
84 'python', _ISOLATE_SCRIPT, | |
85 'remap', | |
86 '--isolate=%s' % isolate_abs_path, | |
M-A Ruel
2013/07/08 17:56:02
'--isolate', isolate_abs_path,
same for --isolate
frankf
2013/07/09 01:09:35
Done.
| |
87 '--isolated=%s' % isolated_abs_path, | |
88 '-V', 'PRODUCT_DIR=%s' % product_dir, | |
89 '-V', 'OS=android', | |
90 '--outdir=%s' % deps_dir, | |
91 ] | |
92 assert not cmd_helper.RunCmd(isolate_cmd) | |
93 | |
94 # Delete excluded files as defined by _DEPS_EXCLUSION_LIST. | |
95 old_cwd = os.getcwd() | |
96 os.chdir(deps_dir) | |
M-A Ruel
2013/07/08 17:56:02
try/finally
frankf
2013/07/09 01:09:35
Done.
| |
97 excluded_paths = [x for y in _DEPS_EXCLUSION_LIST for x in glob.glob(y)] | |
98 if excluded_paths: | |
99 logging.warning('Excluding the following from dependency list: %s', | |
100 excluded_paths) | |
101 for p in excluded_paths: | |
102 if os.path.isdir(p): | |
103 shutil.rmtree(p) | |
104 else: | |
105 os.remove(p) | |
106 os.chdir(old_cwd) | |
107 | |
108 # On Android, all pak files need to be in the top-level 'paks' directory. | |
109 paks_dir = os.path.join(deps_dir, 'paks') | |
110 os.mkdir(paks_dir) | |
111 for root, _, filenames in os.walk(os.path.join(deps_dir, 'out')): | |
112 for filename in fnmatch.filter(filenames, '*.pak'): | |
113 shutil.move(os.path.join(root, filename), paks_dir) | |
114 | |
115 # Move everything in PRODUCT_DIR to top level. | |
116 deps_product_dir = os.path.join(deps_dir, 'out', build_type) | |
117 if os.path.isdir(deps_product_dir): | |
118 for p in os.listdir(deps_product_dir): | |
119 shutil.move(os.path.join(deps_product_dir, p), deps_dir) | |
120 | |
121 return deps_dir | |
122 | |
123 | |
23 def _FullyQualifiedTestSuites(exe, option_test_suite, build_type): | 124 def _FullyQualifiedTestSuites(exe, option_test_suite, build_type): |
24 """Get a list of absolute paths to test suite targets. | 125 """Get a list of absolute paths to test suite targets. |
25 | 126 |
26 Args: | 127 Args: |
27 exe: if True, use the executable-based test runner. | 128 exe: if True, use the executable-based test runner. |
28 option_test_suite: the test_suite specified as an option. | 129 option_test_suite: the test_suite specified as an option. |
29 build_type: 'Release' or 'Debug'. | 130 build_type: 'Release' or 'Debug'. |
30 | 131 |
31 Returns: | 132 Returns: |
32 A list of tuples containing the suite and absolute path. | 133 A list of tuples containing the suite and absolute path. |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
131 attached_devices = android_commands.GetAttachedDevices() | 232 attached_devices = android_commands.GetAttachedDevices() |
132 | 233 |
133 if not attached_devices: | 234 if not attached_devices: |
134 raise Exception('A device must be attached and online.') | 235 raise Exception('A device must be attached and online.') |
135 | 236 |
136 # Reset the test port allocation. It's important to do it before starting | 237 # Reset the test port allocation. It's important to do it before starting |
137 # to dispatch any tests. | 238 # to dispatch any tests. |
138 if not ports.ResetTestServerPortAllocation(): | 239 if not ports.ResetTestServerPortAllocation(): |
139 raise Exception('Failed to reset test server port.') | 240 raise Exception('Failed to reset test server port.') |
140 | 241 |
242 deps_dir = _GenerateDepsDirUsingIsolate(suite_name, options.build_type) | |
243 | |
141 # Constructs a new TestRunner with the current options. | 244 # Constructs a new TestRunner with the current options. |
142 def RunnerFactory(device, shard_index): | 245 def RunnerFactory(device, shard_index): |
143 return test_runner.TestRunner( | 246 return test_runner.TestRunner( |
144 device, | 247 device, |
145 options.test_suite, | 248 options.test_suite, |
146 options.test_arguments, | 249 options.test_arguments, |
147 options.timeout, | 250 options.timeout, |
148 options.cleanup_test_files, | 251 options.cleanup_test_files, |
149 options.tool, | 252 options.tool, |
150 options.build_type, | 253 options.build_type, |
151 options.webkit, | 254 options.webkit, |
152 options.push_deps, | 255 options.push_deps, |
153 constants.GTEST_TEST_PACKAGE_NAME, | 256 constants.GTEST_TEST_PACKAGE_NAME, |
154 constants.GTEST_TEST_ACTIVITY_NAME, | 257 constants.GTEST_TEST_ACTIVITY_NAME, |
155 constants.GTEST_COMMAND_LINE_FILE) | 258 constants.GTEST_COMMAND_LINE_FILE, |
259 deps_dir=deps_dir) | |
156 | 260 |
157 # Get tests and split them up based on the number of devices. | 261 # Get tests and split them up based on the number of devices. |
158 if options.gtest_filter: | 262 if options.gtest_filter: |
159 all_tests = [t for t in options.gtest_filter.split(':') if t] | 263 all_tests = [t for t in options.gtest_filter.split(':') if t] |
160 else: | 264 else: |
161 all_tests = GetAllEnabledTests(RunnerFactory, attached_devices) | 265 all_tests = GetAllEnabledTests(RunnerFactory, attached_devices) |
162 num_devices = len(attached_devices) | 266 num_devices = len(attached_devices) |
163 tests = [':'.join(all_tests[i::num_devices]) for i in xrange(num_devices)] | 267 tests = [':'.join(all_tests[i::num_devices]) for i in xrange(num_devices)] |
164 tests = [t for t in tests if t] | 268 tests = [t for t in tests if t] |
165 | 269 |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
214 failures = 0 | 318 failures = 0 |
215 for suite_name, suite_path in all_test_suites: | 319 for suite_name, suite_path in all_test_suites: |
216 # Give each test suite its own copy of options. | 320 # Give each test suite its own copy of options. |
217 test_options = copy.deepcopy(options) | 321 test_options = copy.deepcopy(options) |
218 test_options.test_suite = suite_path | 322 test_options.test_suite = suite_path |
219 failures += _RunATestSuite(test_options, suite_name) | 323 failures += _RunATestSuite(test_options, suite_name) |
220 | 324 |
221 if options.use_xvfb: | 325 if options.use_xvfb: |
222 framebuffer.Stop() | 326 framebuffer.Stop() |
223 return failures | 327 return failures |
OLD | NEW |