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

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

Issue 15261003: Add a new script bb_host_steps.py which handles all host side steps. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: yet another rebase 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
« no previous file with comments | « build/android/PRESUBMIT.py ('k') | build/android/buildbot/bb_host_steps.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 #!/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 json
9 import multiprocessing 8 import multiprocessing
10 import optparse
11 import os 9 import os
12 import pipes
13 import shutil 10 import shutil
14 import subprocess
15 import sys 11 import sys
16 12
13 import bb_utils
14
17 sys.path.append(os.path.join(os.path.dirname(__file__), '..')) 15 sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
18 from pylib import android_commands 16 from pylib import android_commands
19 from pylib import buildbot_report 17 from pylib import buildbot_report
20 from pylib import constants 18 from pylib import constants
21 from pylib.gtest import gtest_config 19 from pylib.gtest import gtest_config
22 20
23 sys.path.append(os.path.join( 21 sys.path.append(os.path.join(
24 constants.DIR_SOURCE_ROOT, 'third_party', 'android_testrunner')) 22 constants.DIR_SOURCE_ROOT, 'third_party', 'android_testrunner'))
25 import errors 23 import errors
26 24
27 25
28 TESTING = 'BUILDBOT_TESTING' in os.environ
29
30 CHROME_SRC = constants.DIR_SOURCE_ROOT 26 CHROME_SRC = constants.DIR_SOURCE_ROOT
31 27
32 # Describes an instrumation test suite: 28 # Describes an instrumation test suite:
33 # test: Name of test we're running. 29 # test: Name of test we're running.
34 # apk: apk to be installed. 30 # apk: apk to be installed.
35 # apk_package: package for the apk to be installed. 31 # apk_package: package for the apk to be installed.
36 # test_apk: apk to run tests on. 32 # test_apk: apk to run tests on.
37 # test_data: data folder in format destination:source. 33 # test_data: data folder in format destination:source.
38 I_TEST = collections.namedtuple('InstrumentationTest', [ 34 I_TEST = collections.namedtuple('InstrumentationTest', [
39 'name', 'apk', 'apk_package', 'test_apk', 'test_data', 'host_driven_root']) 35 'name', 'apk', 'apk_package', 'test_apk', 'test_data', 'host_driven_root'])
(...skipping 14 matching lines...) Expand all
54 I_TEST('AndroidWebView', 50 I_TEST('AndroidWebView',
55 'AndroidWebView.apk', 51 'AndroidWebView.apk',
56 'org.chromium.android_webview.shell', 52 'org.chromium.android_webview.shell',
57 'AndroidWebViewTest', 53 'AndroidWebViewTest',
58 'webview:android_webview/test/data/device_files', 54 'webview:android_webview/test/data/device_files',
59 None), 55 None),
60 ]) 56 ])
61 57
62 VALID_TESTS = set(['chromedriver', 'ui', 'unit', 'webkit', 'webkit_layout']) 58 VALID_TESTS = set(['chromedriver', 'ui', 'unit', 'webkit', 'webkit_layout'])
63 59
64 60 RunCmd = bb_utils.RunCmd
65 def SpawnCmd(command):
66 """Spawn a process without waiting for termination."""
67 print '>', ' '.join(map(pipes.quote, command))
68 sys.stdout.flush()
69 if TESTING:
70 class MockPopen(object):
71 @staticmethod
72 def wait():
73 return 0
74 return MockPopen()
75
76 return subprocess.Popen(command, cwd=CHROME_SRC)
77
78 def RunCmd(command, flunk_on_failure=True, halt_on_failure=False):
79 """Run a command relative to the chrome source root."""
80 code = SpawnCmd(command).wait()
81 print '<', ' '.join(map(pipes.quote, command))
82 if code != 0:
83 print 'ERROR: process exited with code %d' % code
84 if flunk_on_failure:
85 buildbot_report.PrintError()
86 else:
87 buildbot_report.PrintWarning()
88 # Allow steps to have both halting (i.e. 1) and non-halting exit codes.
89 if code != 0 and code != 88 and halt_on_failure:
90 raise OSError()
91 return code
92 61
93 62
94 # multiprocessing map_async requires a top-level function for pickle library. 63 # multiprocessing map_async requires a top-level function for pickle library.
95 def RebootDeviceSafe(device): 64 def RebootDeviceSafe(device):
96 """Reboot a device, wait for it to start, and squelch timeout exceptions.""" 65 """Reboot a device, wait for it to start, and squelch timeout exceptions."""
97 try: 66 try:
98 android_commands.AndroidCommands(device).Reboot(True) 67 android_commands.AndroidCommands(device).Reboot(True)
99 except errors.DeviceUnresponsiveError as e: 68 except errors.DeviceUnresponsiveError as e:
100 return e 69 return e
101 70
102 71
103 def RebootDevices(): 72 def RebootDevices():
104 """Reboot all attached and online devices.""" 73 """Reboot all attached and online devices."""
105 buildbot_report.PrintNamedStep('Reboot devices') 74 buildbot_report.PrintNamedStep('Reboot devices')
106 # Early return here to avoid presubmit dependence on adb, 75 # Early return here to avoid presubmit dependence on adb,
107 # which might not exist in this checkout. 76 # which might not exist in this checkout.
108 if TESTING: 77 if bb_utils.TESTING:
109 return 78 return
110 devices = android_commands.GetAttachedDevices() 79 devices = android_commands.GetAttachedDevices()
111 print 'Rebooting: %s' % devices 80 print 'Rebooting: %s' % devices
112 if devices: 81 if devices:
113 pool = multiprocessing.Pool(len(devices)) 82 pool = multiprocessing.Pool(len(devices))
114 results = pool.map_async(RebootDeviceSafe, devices).get(99999) 83 results = pool.map_async(RebootDeviceSafe, devices).get(99999)
115 84
116 for device, result in zip(devices, results): 85 for device, result in zip(devices, results):
117 if result: 86 if result:
118 print '%s failed to startup.' % device 87 print '%s failed to startup.' % device
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
253 222
254 def MainTestWrapper(options): 223 def MainTestWrapper(options):
255 # Restart adb to work around bugs, sleep to wait for usb discovery. 224 # Restart adb to work around bugs, sleep to wait for usb discovery.
256 RunCmd(['adb', 'kill-server']) 225 RunCmd(['adb', 'kill-server'])
257 RunCmd(['adb', 'start-server']) 226 RunCmd(['adb', 'start-server'])
258 RunCmd(['sleep', '1']) 227 RunCmd(['sleep', '1'])
259 228
260 # Spawn logcat monitor 229 # Spawn logcat monitor
261 logcat_dir = os.path.join(CHROME_SRC, 'out/logcat') 230 logcat_dir = os.path.join(CHROME_SRC, 'out/logcat')
262 shutil.rmtree(logcat_dir, ignore_errors=True) 231 shutil.rmtree(logcat_dir, ignore_errors=True)
263 SpawnCmd(['build/android/adb_logcat_monitor.py', logcat_dir]) 232 bb_utils.SpawnCmd(['build/android/adb_logcat_monitor.py', logcat_dir])
264 233
265 # Wait for logcat_monitor to pull existing logcat 234 # Wait for logcat_monitor to pull existing logcat
266 RunCmd(['sleep', '5']) 235 RunCmd(['sleep', '5'])
267 236
268 if options.reboot: 237 if options.reboot:
269 RebootDevices() 238 RebootDevices()
270 239
271 # Device check and alert emails 240 # Device check and alert emails
272 buildbot_report.PrintNamedStep('device_status_check') 241 buildbot_report.PrintNamedStep('device_status_check')
273 RunCmd(['build/android/device_status_check.py'], halt_on_failure=True) 242 RunCmd(['build/android/device_status_check.py'], halt_on_failure=True)
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
305 RunCmd(['build/android/adb_logcat_printer.py', logcat_dir]) 274 RunCmd(['build/android/adb_logcat_printer.py', logcat_dir])
306 275
307 buildbot_report.PrintNamedStep('test_report') 276 buildbot_report.PrintNamedStep('test_report')
308 for report in glob.glob( 277 for report in glob.glob(
309 os.path.join(CHROME_SRC, 'out', options.target, 'test_logs', '*.log')): 278 os.path.join(CHROME_SRC, 'out', options.target, 'test_logs', '*.log')):
310 RunCmd(['cat', report]) 279 RunCmd(['cat', report])
311 os.remove(report) 280 os.remove(report)
312 281
313 282
314 def main(argv): 283 def main(argv):
315 parser = optparse.OptionParser() 284 parser = bb_utils.GetParser()
316
317 def convert_json(option, _, value, parser):
318 setattr(parser.values, option.dest, json.loads(value))
319
320 parser.add_option('--build-properties', action='callback',
321 callback=convert_json, type='string', default={},
322 help='build properties in JSON format')
323 parser.add_option('--factory-properties', action='callback',
324 callback=convert_json, type='string', default={},
325 help='factory properties in JSON format')
326 parser.add_option('--slave-properties', action='callback',
327 callback=convert_json, type='string', default={},
328 help='Properties set by slave script in JSON format')
329 parser.add_option('--experimental', action='store_true', 285 parser.add_option('--experimental', action='store_true',
330 help='Run experiemental tests') 286 help='Run experiemental tests')
331 parser.add_option('-f', '--test-filter', metavar='<filter>', default=[], 287 parser.add_option('-f', '--test-filter', metavar='<filter>', default=[],
332 action='append', 288 action='append',
333 help=('Run a test suite. Test suites: "%s"' % 289 help=('Run a test suite. Test suites: "%s"' %
334 '", "'.join(VALID_TESTS))) 290 '", "'.join(VALID_TESTS)))
335 parser.add_option('--asan', action='store_true', help='Run tests with asan.') 291 parser.add_option('--asan', action='store_true', help='Run tests with asan.')
336 parser.add_option('--install', metavar='<apk name>', 292 parser.add_option('--install', metavar='<apk name>',
337 help='Install an apk by name') 293 help='Install an apk by name')
338 parser.add_option('--reboot', action='store_true', 294 parser.add_option('--reboot', action='store_true',
339 help='Reboot devices before running tests') 295 help='Reboot devices before running tests')
340 parser.add_option('--upload-to-flakiness-server', action='store_true', 296 parser.add_option('--upload-to-flakiness-server', action='store_true',
341 help='Upload the results to the flakiness dashboard.') 297 help='Upload the results to the flakiness dashboard.')
342 parser.add_option( 298 parser.add_option(
343 '--auto-reconnect', action='store_true', 299 '--auto-reconnect', action='store_true',
344 help='Push script to device which restarts adbd on disconnections.') 300 help='Push script to device which restarts adbd on disconnections.')
345 options, args = parser.parse_args(argv[1:]) 301 options, args = parser.parse_args(argv[1:])
346 302
347 def ParserError(msg):
348 """We avoid parser.error because it calls sys.exit."""
349 parser.print_help()
350 print >> sys.stderr, '\nERROR:', msg
351 return 1
352
353 if args: 303 if args:
354 return ParserError('Unused args %s' % args) 304 return sys.exit('Unused args %s' % args)
355 305
356 unknown_tests = set(options.test_filter) - VALID_TESTS 306 unknown_tests = set(options.test_filter) - VALID_TESTS
357 if unknown_tests: 307 if unknown_tests:
358 return ParserError('Unknown tests %s' % list(unknown_tests)) 308 return sys.exit('Unknown tests %s' % list(unknown_tests))
359 309
360 setattr(options, 'target', options.factory_properties.get('target', 'Debug')) 310 setattr(options, 'target', options.factory_properties.get('target', 'Debug'))
361 311
362 # Add adb binary and chromium-source platform-tools to tip of PATH variable. 312 # Add adb binary and chromium-source platform-tools to tip of PATH variable.
363 android_paths = [os.path.join(constants.ANDROID_SDK_ROOT, 'platform-tools')] 313 android_paths = [os.path.join(constants.ANDROID_SDK_ROOT, 'platform-tools')]
364 314
365 # Bots checkout chrome in /b/build/slave/<name>/build/src 315 # Bots checkout chrome in /b/build/slave/<name>/build/src
366 build_internal_android = os.path.abspath(os.path.join( 316 build_internal_android = os.path.abspath(os.path.join(
367 CHROME_SRC, '..', '..', '..', '..', '..', 'build_internal', 'scripts', 317 CHROME_SRC, '..', '..', '..', '..', '..', 'build_internal', 'scripts',
368 'slave', 'android')) 318 'slave', 'android'))
369 if os.path.exists(build_internal_android): 319 if os.path.exists(build_internal_android):
370 android_paths.insert(0, build_internal_android) 320 android_paths.insert(0, build_internal_android)
371 os.environ['PATH'] = os.pathsep.join(android_paths + [os.environ['PATH']]) 321 os.environ['PATH'] = os.pathsep.join(android_paths + [os.environ['PATH']])
372 322
373 MainTestWrapper(options) 323 MainTestWrapper(options)
374 324
375 325
376 if __name__ == '__main__': 326 if __name__ == '__main__':
377 sys.exit(main(sys.argv)) 327 sys.exit(main(sys.argv))
OLDNEW
« no previous file with comments | « build/android/PRESUBMIT.py ('k') | build/android/buildbot/bb_host_steps.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698