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

Side by Side Diff: build/android/buildbot/bb_device_steps.py

Issue 17114007: [Android] Refactor the buildbot scripts to prepare for downstream usage. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Change title so that all refactors are captured in one CL Created 7 years, 6 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
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright (c) 2013 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2013 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 import collections 6 import collections
7 import glob 7 import glob
8 import multiprocessing 8 import multiprocessing
9 import os 9 import os
10 import shutil 10 import shutil
11 import sys 11 import sys
12 12
13 import bb_utils 13 import bb_utils
14 14
15 sys.path.append(os.path.join(os.path.dirname(__file__), '..')) 15 sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
16 from pylib import android_commands 16 from pylib import android_commands
17 from pylib import buildbot_report 17 from pylib import buildbot_report
18 from pylib import constants 18 from pylib import constants
19 from pylib.gtest import gtest_config 19 from pylib.gtest import gtest_config
20 20
21 sys.path.append(os.path.join( 21 sys.path.append(os.path.join(
22 constants.DIR_SOURCE_ROOT, 'third_party', 'android_testrunner')) 22 constants.DIR_SOURCE_ROOT, 'third_party', 'android_testrunner'))
23 import errors 23 import errors
24 24
25 25
26 CHROME_SRC = constants.DIR_SOURCE_ROOT 26 CHROME_SRC = constants.DIR_SOURCE_ROOT
27 LOGCAT_DIR = os.path.join(CHROME_SRC, 'out', 'logcat')
27 28
28 # Describes an instrumation test suite: 29 # Describes an instrumation test suite:
29 # test: Name of test we're running. 30 # test: Name of test we're running.
30 # apk: apk to be installed. 31 # apk: apk to be installed.
31 # apk_package: package for the apk to be installed. 32 # apk_package: package for the apk to be installed.
32 # test_apk: apk to run tests on. 33 # test_apk: apk to run tests on.
33 # test_data: data folder in format destination:source. 34 # test_data: data folder in format destination:source.
Isaac (away) 2013/06/28 01:39:12 need documentation for additional options.
Siva Chandra 2013/06/28 21:34:10 Done.
34 I_TEST = collections.namedtuple('InstrumentationTest', [ 35 I_TEST = collections.namedtuple('InstrumentationTest', [
35 'name', 'apk', 'apk_package', 'test_apk', 'test_data', 'host_driven_root']) 36 'name', 'apk', 'apk_package', 'test_apk', 'test_data', 'host_driven_root',
Isaac (away) 2013/06/28 01:39:12 too many args for this -- can we group into subtup
Siva Chandra 2013/06/28 21:34:10 I have removed one arg. TBF, I do not understand t
37 'screenshot', 'annotation', 'exclude_annotation', 'extra_flags'])
38
39 def I(name, apk, apk_package, test_apk, test_data, host_driven_root=None,
40 screenshot=None, annotation=None, exclude_annotation=None,
41 extra_flags=None):
42 return I_TEST(name, apk, apk_package, test_apk, test_data, host_driven_root,
43 screenshot, annotation, exclude_annotation, extra_flags)
36 44
37 INSTRUMENTATION_TESTS = dict((suite.name, suite) for suite in [ 45 INSTRUMENTATION_TESTS = dict((suite.name, suite) for suite in [
38 I_TEST('ContentShell', 46 I('ContentShell',
39 'ContentShell.apk', 47 'ContentShell.apk',
40 'org.chromium.content_shell_apk', 48 'org.chromium.content_shell_apk',
41 'ContentShellTest', 49 'ContentShellTest',
42 'content:content/test/data/android/device_files', 50 'content:content/test/data/android/device_files'),
43 None), 51 I('ChromiumTestShell',
44 I_TEST('ChromiumTestShell', 52 'ChromiumTestShell.apk',
45 'ChromiumTestShell.apk', 53 'org.chromium.chrome.testshell',
46 'org.chromium.chrome.testshell', 54 'ChromiumTestShellTest',
47 'ChromiumTestShellTest', 55 'chrome:chrome/test/data/android/device_files',
48 'chrome:chrome/test/data/android/device_files', 56 constants.CHROMIUM_TEST_SHELL_HOST_DRIVEN_DIR),
49 constants.CHROMIUM_TEST_SHELL_HOST_DRIVEN_DIR), 57 I('AndroidWebView',
50 I_TEST('AndroidWebView', 58 'AndroidWebView.apk',
51 'AndroidWebView.apk', 59 'org.chromium.android_webview.shell',
52 'org.chromium.android_webview.shell', 60 'AndroidWebViewTest',
53 'AndroidWebViewTest', 61 'webview:android_webview/test/data/device_files'),
54 'webview:android_webview/test/data/device_files',
55 None),
56 ]) 62 ])
57 63
58 VALID_TESTS = set(['chromedriver', 'ui', 'unit', 'webkit', 'webkit_layout']) 64 VALID_TESTS = set(['chromedriver', 'ui', 'unit', 'webkit', 'webkit_layout'])
59 65
60 RunCmd = bb_utils.RunCmd 66 RunCmd = bb_utils.RunCmd
61 67
62 68
63 # multiprocessing map_async requires a top-level function for pickle library. 69 # multiprocessing map_async requires a top-level function for pickle library.
64 def RebootDeviceSafe(device): 70 def RebootDeviceSafe(device):
65 """Reboot a device, wait for it to start, and squelch timeout exceptions.""" 71 """Reboot a device, wait for it to start, and squelch timeout exceptions."""
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
117 options: options object. 123 options: options object.
118 """ 124 """
119 args = ['--verbose', '--num_retries=1'] 125 args = ['--verbose', '--num_retries=1']
120 if options.target == 'Release': 126 if options.target == 'Release':
121 args.append('--release') 127 args.append('--release')
122 if options.asan: 128 if options.asan:
123 args.append('--tool=asan') 129 args.append('--tool=asan')
124 buildbot_report.PrintNamedStep(constants.BROWSERTEST_SUITE_NAME) 130 buildbot_report.PrintNamedStep(constants.BROWSERTEST_SUITE_NAME)
125 RunCmd(['build/android/run_browser_tests.py'] + args) 131 RunCmd(['build/android/run_browser_tests.py'] + args)
126 132
127 def RunChromeDriverTests(): 133 def RunChromeDriverTests(_):
128 """Run all the steps for running chromedriver tests.""" 134 """Run all the steps for running chromedriver tests."""
129 buildbot_report.PrintNamedStep('chromedriver_annotation') 135 buildbot_report.PrintNamedStep('chromedriver_annotation')
130 RunCmd(['chrome/test/chromedriver/run_buildbot_steps.py', 136 RunCmd(['chrome/test/chromedriver/run_buildbot_steps.py',
131 '--android-package=%s' % constants.CHROMIUM_TEST_SHELL_PACKAGE]) 137 '--android-package=%s' % constants.CHROMIUM_TEST_SHELL_PACKAGE])
132 138
133 def InstallApk(options, test, print_step=False): 139 def InstallApk(options, test, print_step=False):
134 """Install an apk to all phones. 140 """Install an apk to all phones.
135 141
136 Args: 142 Args:
137 options: options object 143 options: options object
(...skipping 23 matching lines...) Expand all
161 '--verbose', '-I'] 167 '--verbose', '-I']
162 if options.target == 'Release': 168 if options.target == 'Release':
163 args.append('--release') 169 args.append('--release')
164 if options.asan: 170 if options.asan:
165 args.append('--tool=asan') 171 args.append('--tool=asan')
166 if options.upload_to_flakiness_server: 172 if options.upload_to_flakiness_server:
167 args.append('--flakiness-dashboard-server=%s' % 173 args.append('--flakiness-dashboard-server=%s' %
168 constants.UPSTREAM_FLAKINESS_SERVER) 174 constants.UPSTREAM_FLAKINESS_SERVER)
169 if test.host_driven_root: 175 if test.host_driven_root:
170 args.append('--python_test_root=%s' % test.host_driven_root) 176 args.append('--python_test_root=%s' % test.host_driven_root)
177 if test.screenshot:
Isaac (away) 2013/06/28 01:39:12 Are screenshots ever off?
Siva Chandra 2013/06/28 21:34:10 Yes. For example, downstream chrome-driver tests b
178 args.append('--screenshot')
179 if test.annotation:
180 args.extend(['-A', test.annotation])
181 if test.exclude_annotation:
182 args.extend(['-E', test.exclude_annotation])
183 if test.extra_flags:
184 args.extend(test.extra_flags)
171 185
172 RunCmd(['build/android/run_instrumentation_tests.py'] + args) 186 RunCmd(['build/android/run_instrumentation_tests.py'] + args)
173 187
174 188
175 def RunWebkitLint(target): 189 def RunWebkitLint(target):
176 """Lint WebKit's TestExpectation files.""" 190 """Lint WebKit's TestExpectation files."""
177 buildbot_report.PrintNamedStep('webkit_lint') 191 buildbot_report.PrintNamedStep('webkit_lint')
178 RunCmd(['webkit/tools/layout_tests/run_webkit_tests.py', 192 RunCmd(['webkit/tools/layout_tests/run_webkit_tests.py',
179 '--lint-test-files', 193 '--lint-test-files',
180 '--chromium', 194 '--chromium',
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
212 # TODO(dpranke): Remove this block after 226 # TODO(dpranke): Remove this block after
213 # https://codereview.chromium.org/12927002/ lands. 227 # https://codereview.chromium.org/12927002/ lands.
214 for f in options.factory_properties.get('additional_expectations_files', []): 228 for f in options.factory_properties.get('additional_expectations_files', []):
215 cmd_args.extend( 229 cmd_args.extend(
216 ['--additional-expectations=%s' % os.path.join(CHROME_SRC, *f)]) 230 ['--additional-expectations=%s' % os.path.join(CHROME_SRC, *f)])
217 231
218 RunCmd(['webkit/tools/layout_tests/run_webkit_tests.py'] + cmd_args, 232 RunCmd(['webkit/tools/layout_tests/run_webkit_tests.py'] + cmd_args,
219 flunk_on_failure=False) 233 flunk_on_failure=False)
220 234
221 235
222 def MainTestWrapper(options): 236 def SpawnLogcatMonitor():
237 shutil.rmtree(LOGCAT_DIR, ignore_errors=True)
238 bb_utils.SpawnCmd([
239 os.path.join(CHROME_SRC, 'build', 'android', 'adb_logcat_monitor.py'),
240 LOGCAT_DIR])
Isaac (away) 2013/06/28 01:39:12 sleep should be here
Siva Chandra 2013/06/28 21:34:10 Done.
241
242 def ProvisionDevices(options):
223 # Restart adb to work around bugs, sleep to wait for usb discovery. 243 # Restart adb to work around bugs, sleep to wait for usb discovery.
224 RunCmd(['adb', 'kill-server']) 244 RunCmd(['adb', 'kill-server'])
225 RunCmd(['adb', 'start-server']) 245 RunCmd(['adb', 'start-server'])
226 RunCmd(['sleep', '1']) 246 RunCmd(['sleep', '1'])
227 247
228 # Spawn logcat monitor
229 logcat_dir = os.path.join(CHROME_SRC, 'out/logcat')
230 shutil.rmtree(logcat_dir, ignore_errors=True)
231 bb_utils.SpawnCmd(['build/android/adb_logcat_monitor.py', logcat_dir])
232
233 # Wait for logcat_monitor to pull existing logcat
234 RunCmd(['sleep', '5'])
235
236 # Provision devices
237 buildbot_report.PrintNamedStep('provision_devices') 248 buildbot_report.PrintNamedStep('provision_devices')
238 if options.reboot: 249 if options.reboot:
239 RebootDevices() 250 RebootDevices()
240 RunCmd(['build/android/provision_devices.py', '-t', options.target]) 251 RunCmd(['build/android/provision_devices.py', '-t', options.target])
241 252
242 # Device check and alert emails 253
254 def DeviceStatusCheck(_):
243 buildbot_report.PrintNamedStep('device_status_check') 255 buildbot_report.PrintNamedStep('device_status_check')
244 RunCmd(['build/android/device_status_check.py'], halt_on_failure=True) 256 RunCmd(['build/android/device_status_check.py'], halt_on_failure=True)
245 257
246 if options.install:
247 test_obj = INSTRUMENTATION_TESTS[options.install]
248 InstallApk(options, test_obj, print_step=True)
249 258
250 if 'chromedriver' in options.test_filter: 259 def GetDeviceSetupStepCmds():
251 RunChromeDriverTests() 260 return [
252 if 'unit' in options.test_filter: 261 ('provision_devices', ProvisionDevices),
253 RunTestSuites(options, gtest_config.STABLE_TEST_SUITES) 262 ('device_status_check', DeviceStatusCheck)
254 if 'ui' in options.test_filter: 263 ]
255 for test in INSTRUMENTATION_TESTS.itervalues():
256 RunInstrumentationSuite(options, test)
257 if 'webkit' in options.test_filter:
258 RunTestSuites(options, [
259 gtest_config.Apk('webkit_unit_tests'),
260 ])
261 RunWebkitLint(options.target)
262 if 'webkit_layout' in options.test_filter:
263 RunWebkitLayoutTests(options)
264 264
265 if options.experimental:
266 RunTestSuites(options, gtest_config.EXPERIMENTAL_TEST_SUITES)
267 RunBrowserTestSuite(options)
268 265
266 def RunUnitTests(options):
267 RunTestSuites(options, gtest_config.STABLE_TEST_SUITES)
268
269
270 def RunInstrumentationTests(options):
271 for test in INSTRUMENTATION_TESTS.itervalues():
272 RunInstrumentationSuite(options, test)
273
274
275 def RunWebkitTests(options):
276 RunTestSuites(options, [gtest_config.Apk('webkit_unit_tests')])
277 RunWebkitLint(options.target)
278
279
280 def GetTestStepCmds():
281 return [
282 ('chromedriver', RunChromeDriverTests),
283 ('unit', RunUnitTests),
284 ('ui', RunInstrumentationTests),
285 ('webkit', RunWebkitTests),
286 ('webkit_layout', RunWebkitLayoutTests)
287 ]
288
289
290 def LogcatDump(options):
269 # Print logcat, kill logcat monitor 291 # Print logcat, kill logcat monitor
270 buildbot_report.PrintNamedStep('logcat_dump') 292 buildbot_report.PrintNamedStep('logcat_dump')
271 RunCmd(['build/android/adb_logcat_printer.py', logcat_dir]) 293 cmd_str = 'build/android/adb_logcat_printer.py ' + LOGCAT_DIR
294 if options.logcat_dump_output:
295 cmd_str += ' | tee %s' % options.logcat_dump_output
296 RunCmd(['bash', '-c', cmd_str])
272 297
298
299 def GenerateTestReport(options):
273 buildbot_report.PrintNamedStep('test_report') 300 buildbot_report.PrintNamedStep('test_report')
274 for report in glob.glob( 301 for report in glob.glob(
275 os.path.join(CHROME_SRC, 'out', options.target, 'test_logs', '*.log')): 302 os.path.join(CHROME_SRC, 'out', options.target, 'test_logs', '*.log')):
276 RunCmd(['cat', report]) 303 RunCmd(['cat', report])
277 os.remove(report) 304 os.remove(report)
278 305
279 306
280 def main(argv): 307 def GetPostTestStepCmds():
308 return [
309 ('logcat_dump', LogcatDump),
310 ('test_report', GenerateTestReport)
311 ]
312
313
314 def MainTestWrapper(options):
315 # Spawn logcat monitor
316 SpawnLogcatMonitor()
317
318 # Wait for logcat_monitor to pull existing logcat
319 RunCmd(['sleep', '5'])
320
321 bb_utils.RunAllSteps(GetDeviceSetupStepCmds(), options)
322
323 if options.install:
324 test_obj = INSTRUMENTATION_TESTS[options.install]
325 InstallApk(options, test_obj, print_step=True)
326
327 if options.test_filter:
328 bb_utils.RunSteps(options.test_filter, GetTestStepCmds(), options)
329
330 if options.experimental:
331 RunTestSuites(options, gtest_config.EXPERIMENTAL_TEST_SUITES)
332 RunBrowserTestSuite(options)
333
334 bb_utils.RunAllSteps(GetPostTestStepCmds(), options)
335
336
337 def GetDeviceStepsOptParser():
281 parser = bb_utils.GetParser() 338 parser = bb_utils.GetParser()
282 parser.add_option('--experimental', action='store_true', 339 parser.add_option('--experimental', action='store_true',
283 help='Run experiemental tests') 340 help='Run experiemental tests')
284 parser.add_option('-f', '--test-filter', metavar='<filter>', default=[], 341 parser.add_option('-f', '--test-filter', metavar='<filter>', default=[],
285 action='append', 342 action='append',
286 help=('Run a test suite. Test suites: "%s"' % 343 help=('Run a test suite. Test suites: "%s"' %
287 '", "'.join(VALID_TESTS))) 344 '", "'.join(VALID_TESTS)))
288 parser.add_option('--asan', action='store_true', help='Run tests with asan.') 345 parser.add_option('--asan', action='store_true', help='Run tests with asan.')
289 parser.add_option('--install', metavar='<apk name>', 346 parser.add_option('--install', metavar='<apk name>',
290 help='Install an apk by name') 347 help='Install an apk by name')
291 parser.add_option('--reboot', action='store_true', 348 parser.add_option('--reboot', action='store_true',
292 help='Reboot devices before running tests') 349 help='Reboot devices before running tests')
293 parser.add_option('--upload-to-flakiness-server', action='store_true', 350 parser.add_option('--upload-to-flakiness-server', action='store_true',
294 help='Upload the results to the flakiness dashboard.') 351 help='Upload the results to the flakiness dashboard.')
295 parser.add_option( 352 parser.add_option(
296 '--auto-reconnect', action='store_true', 353 '--auto-reconnect', action='store_true',
297 help='Push script to device which restarts adbd on disconnections.') 354 help='Push script to device which restarts adbd on disconnections.')
355 parser.add_option(
356 '--logcat-dump-output',
357 help='The logcat dump output will be "tee"-ed into this file')
358
359 return parser
360
361
362 def main(argv):
363 parser = GetDeviceStepsOptParser()
298 options, args = parser.parse_args(argv[1:]) 364 options, args = parser.parse_args(argv[1:])
299 365
300 if args: 366 if args:
301 return sys.exit('Unused args %s' % args) 367 return sys.exit('Unused args %s' % args)
302 368
303 unknown_tests = set(options.test_filter) - VALID_TESTS 369 unknown_tests = set(options.test_filter) - VALID_TESTS
304 if unknown_tests: 370 if unknown_tests:
305 return sys.exit('Unknown tests %s' % list(unknown_tests)) 371 return sys.exit('Unknown tests %s' % list(unknown_tests))
306 372
307 setattr(options, 'target', options.factory_properties.get('target', 'Debug')) 373 setattr(options, 'target', options.factory_properties.get('target', 'Debug'))
308 374
309 MainTestWrapper(options) 375 MainTestWrapper(options)
310 376
311 377
312 if __name__ == '__main__': 378 if __name__ == '__main__':
313 sys.exit(main(sys.argv)) 379 sys.exit(main(sys.argv))
OLDNEW
« no previous file with comments | « no previous file | build/android/buildbot/bb_host_steps.py » ('j') | build/android/buildbot/bb_run_bot.py » ('J')

Powered by Google App Engine
This is Rietveld 408576698