Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(577)

Side by Side Diff: build/android/pylib/gtest/dispatch.py

Issue 18233018: [Android] Use isolate remap instead of check. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: webkit_unit_tests depend on third_party/hyphen/hyph_en_US.dic Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « build/android/pylib/base/base_test_runner.py ('k') | build/android/pylib/gtest/test_package.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 """Dispatches GTests.""" 5 """Dispatches GTests."""
6 6
7 import copy 7 import copy
8 import fnmatch 8 import fnmatch
9 import glob
9 import logging 10 import logging
10 import os 11 import os
12 import shutil
11 13
12 from pylib import android_commands 14 from pylib import android_commands
13 from pylib import cmd_helper 15 from pylib import cmd_helper
14 from pylib import constants 16 from pylib import constants
15 from pylib import ports 17 from pylib import ports
16 from pylib.base import base_test_result 18 from pylib.base import base_test_result
17 from pylib.base import shard 19 from pylib.base import shard
18 from pylib.utils import emulator 20 from pylib.utils import emulator
19 from pylib.utils import report_results 21 from pylib.utils import report_results
20 from pylib.utils import xvfb 22 from pylib.utils import xvfb
21 23
22 import gtest_config 24 import gtest_config
23 import test_runner 25 import test_runner
24 26
25 27
28 # TODO(frankf): Add more test targets here after making sure we don't
29 # blow up the dependency size (and the world).
30 _ISOLATE_FILE_PATHS = {
31 'base_unittests': 'base/base_unittests.isolate',
32 'unit_tests': 'chrome/unit_tests.isolate',
33 }
34
35 # Used for filtering large data deps at a finer grain than what's allowed in
36 # isolate files since pushing deps to devices is expensive.
37 # Wildcards are allowed.
38 _DEPS_EXCLUSION_LIST = [
39 'chrome/test/data/extensions/api_test',
40 'chrome/test/data/extensions/secure_shell',
41 'chrome/test/data/firefox*',
42 'chrome/test/data/gpu',
43 'chrome/test/data/image_decoding',
44 'chrome/test/data/import',
45 'chrome/test/data/page_cycler',
46 'chrome/test/data/perf',
47 'chrome/test/data/pyauto_private',
48 'chrome/test/data/safari_import',
49 'chrome/test/data/scroll',
50 'chrome/test/data/third_party',
51 'third_party/hunspell_dictionaries/*.dic',
52 ]
53
54 _ISOLATE_SCRIPT = os.path.join(
55 constants.DIR_SOURCE_ROOT, 'tools', 'swarm_client', 'isolate.py')
56
57
58 def _GenerateDepsDirUsingIsolate(test_suite, build_type):
59 """Generate the dependency dir for the test suite using isolate.
60
61 Args:
62 test_suite: The test suite basename (e.g. base_unittests).
63 build_type: Release/Debug
64
65 Returns:
66 If an isolate file exists, returns path to dependency dir on the host.
67 Otherwise, returns False.
68 """
69 product_dir = os.path.join(cmd_helper.OutDirectory.get(), build_type)
70 assert os.path.isabs(product_dir)
71 isolate_rel_path = _ISOLATE_FILE_PATHS.get(test_suite)
72 if not isolate_rel_path:
73 return False
74
75 isolate_abs_path = os.path.join(constants.DIR_SOURCE_ROOT, isolate_rel_path)
76 isolated_abs_path = os.path.join(
77 product_dir, '%s.isolated' % test_suite)
78 assert os.path.exists(isolate_abs_path)
79 deps_dir = os.path.join(product_dir, 'isolate_deps_dir')
80 if os.path.isdir(deps_dir):
81 shutil.rmtree(deps_dir)
82 isolate_cmd = [
83 'python', _ISOLATE_SCRIPT,
84 'remap',
85 '--isolate', isolate_abs_path,
86 '--isolated', isolated_abs_path,
87 '-V', 'PRODUCT_DIR=%s' % product_dir,
88 '-V', 'OS=android',
89 '--outdir', deps_dir,
90 ]
91 assert not cmd_helper.RunCmd(isolate_cmd)
92
93 # We're relying on the fact that timestamps are preserved
94 # by the remap command (hardlinked). Otherwise, all the data
95 # will be pushed to the device once we move to using time diff
96 # instead of md5sum. Perform a sanity check here.
97 for root, _, filenames in os.walk(deps_dir):
98 if filenames:
99 linked_file = os.path.join(root, filenames[0])
100 orig_file = os.path.join(
101 constants.DIR_SOURCE_ROOT,
102 os.path.relpath(linked_file, deps_dir))
103 if os.stat(linked_file).st_ino == os.stat(orig_file).st_ino:
104 break
105 else:
106 raise Exception('isolate remap command did not use hardlinks.')
107
108 # Delete excluded files as defined by _DEPS_EXCLUSION_LIST.
109 old_cwd = os.getcwd()
110 try:
111 os.chdir(deps_dir)
112 excluded_paths = [x for y in _DEPS_EXCLUSION_LIST for x in glob.glob(y)]
113 if excluded_paths:
114 logging.info('Excluding the following from dependency list: %s',
115 excluded_paths)
116 for p in excluded_paths:
117 if os.path.isdir(p):
118 shutil.rmtree(p)
119 else:
120 os.remove(p)
121 finally:
122 os.chdir(old_cwd)
123
124 # On Android, all pak files need to be in the top-level 'paks' directory.
125 paks_dir = os.path.join(deps_dir, 'paks')
126 os.mkdir(paks_dir)
127 for root, _, filenames in os.walk(os.path.join(deps_dir, 'out')):
128 for filename in fnmatch.filter(filenames, '*.pak'):
129 shutil.move(os.path.join(root, filename), paks_dir)
130
131 # Move everything in PRODUCT_DIR to top level.
132 deps_product_dir = os.path.join(deps_dir, 'out', build_type)
133 if os.path.isdir(deps_product_dir):
134 for p in os.listdir(deps_product_dir):
135 shutil.move(os.path.join(deps_product_dir, p), deps_dir)
136 os.rmdir(deps_product_dir)
137 os.rmdir(os.path.join(deps_dir, 'out'))
138
139 return deps_dir
140
141
26 def _FullyQualifiedTestSuites(exe, option_test_suite, build_type): 142 def _FullyQualifiedTestSuites(exe, option_test_suite, build_type):
27 """Get a list of absolute paths to test suite targets. 143 """Get a list of absolute paths to test suite targets.
28 144
29 Args: 145 Args:
30 exe: if True, use the executable-based test runner. 146 exe: if True, use the executable-based test runner.
31 option_test_suite: the test_suite specified as an option. 147 option_test_suite: the test_suite specified as an option.
32 build_type: 'Release' or 'Debug'. 148 build_type: 'Release' or 'Debug'.
33 149
34 Returns: 150 Returns:
35 A list of tuples containing the suite and absolute path. 151 A list of tuples containing the suite and absolute path.
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
143 attached_devices = android_commands.GetAttachedDevices() 259 attached_devices = android_commands.GetAttachedDevices()
144 260
145 if not attached_devices: 261 if not attached_devices:
146 raise Exception('A device must be attached and online.') 262 raise Exception('A device must be attached and online.')
147 263
148 # Reset the test port allocation. It's important to do it before starting 264 # Reset the test port allocation. It's important to do it before starting
149 # to dispatch any tests. 265 # to dispatch any tests.
150 if not ports.ResetTestServerPortAllocation(): 266 if not ports.ResetTestServerPortAllocation():
151 raise Exception('Failed to reset test server port.') 267 raise Exception('Failed to reset test server port.')
152 268
269 deps_dir = _GenerateDepsDirUsingIsolate(suite_name, options.build_type)
270
153 # Constructs a new TestRunner with the current options. 271 # Constructs a new TestRunner with the current options.
154 def RunnerFactory(device, shard_index): 272 def RunnerFactory(device, shard_index):
155 return test_runner.TestRunner( 273 return test_runner.TestRunner(
156 device, 274 device,
157 options.test_suite, 275 options.test_suite,
158 options.test_arguments, 276 options.test_arguments,
159 options.timeout, 277 options.timeout,
160 options.cleanup_test_files, 278 options.cleanup_test_files,
161 options.tool, 279 options.tool,
162 options.build_type, 280 options.build_type,
163 options.webkit, 281 options.webkit,
164 options.push_deps, 282 options.push_deps,
165 constants.GTEST_TEST_PACKAGE_NAME, 283 constants.GTEST_TEST_PACKAGE_NAME,
166 constants.GTEST_TEST_ACTIVITY_NAME, 284 constants.GTEST_TEST_ACTIVITY_NAME,
167 constants.GTEST_COMMAND_LINE_FILE) 285 constants.GTEST_COMMAND_LINE_FILE,
286 deps_dir=deps_dir)
168 287
169 # Get tests and split them up based on the number of devices. 288 # Get tests and split them up based on the number of devices.
170 if options.test_filter: 289 if options.test_filter:
171 all_tests = [t for t in options.test_filter.split(':') if t] 290 all_tests = [t for t in options.test_filter.split(':') if t]
172 else: 291 else:
173 all_tests = GetAllEnabledTests(RunnerFactory, attached_devices) 292 all_tests = GetAllEnabledTests(RunnerFactory, attached_devices)
174 num_devices = len(attached_devices) 293 num_devices = len(attached_devices)
175 tests = [':'.join(all_tests[i::num_devices]) for i in xrange(num_devices)] 294 tests = [':'.join(all_tests[i::num_devices]) for i in xrange(num_devices)]
176 tests = [t for t in tests if t] 295 tests = [t for t in tests if t]
177 296
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
231 test_options.test_suite = suite_path 350 test_options.test_suite = suite_path
232 test_results, test_exit_code = _RunATestSuite(test_options, suite_name) 351 test_results, test_exit_code = _RunATestSuite(test_options, suite_name)
233 results.AddTestRunResults(test_results) 352 results.AddTestRunResults(test_results)
234 if test_exit_code and exit_code != constants.ERROR_EXIT_CODE: 353 if test_exit_code and exit_code != constants.ERROR_EXIT_CODE:
235 exit_code = test_exit_code 354 exit_code = test_exit_code
236 355
237 if options.use_xvfb: 356 if options.use_xvfb:
238 framebuffer.Stop() 357 framebuffer.Stop()
239 358
240 return (results, exit_code) 359 return (results, exit_code)
OLDNEW
« no previous file with comments | « build/android/pylib/base/base_test_runner.py ('k') | build/android/pylib/gtest/test_package.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698