OLD | NEW |
---|---|
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 | 9 import optparse |
11 import os | 10 import os |
12 import pipes | |
13 import shutil | 11 import shutil |
14 import subprocess | |
15 import sys | 12 import sys |
16 | 13 |
Isaac (away)
2013/05/29 20:28:07
change to
import bb_utils
Siva Chandra
2013/06/04 00:34:03
Done.
| |
14 from bb_utils import ConvertJson | |
15 from bb_utils import OptParserError | |
16 from bb_utils import RunCmd | |
17 from bb_utils import SpawnCmd | |
18 from bb_utils import TESTING | |
19 | |
17 sys.path.append(os.path.join(os.path.dirname(__file__), '..')) | 20 sys.path.append(os.path.join(os.path.dirname(__file__), '..')) |
18 from pylib import android_commands | 21 from pylib import android_commands |
19 from pylib import buildbot_report | 22 from pylib import buildbot_report |
20 from pylib import constants | 23 from pylib import constants |
21 from pylib.gtest import gtest_config | 24 from pylib.gtest import gtest_config |
22 | 25 |
23 sys.path.append(os.path.join( | 26 sys.path.append(os.path.join( |
24 constants.CHROME_DIR, 'third_party', 'android_testrunner')) | 27 constants.CHROME_DIR, 'third_party', 'android_testrunner')) |
25 import errors | 28 import errors |
26 | 29 |
27 | 30 |
28 TESTING = 'BUILDBOT_TESTING' in os.environ | |
29 | |
30 CHROME_SRC = constants.CHROME_DIR | 31 CHROME_SRC = constants.CHROME_DIR |
31 | 32 |
32 # Describes an instrumation test suite: | 33 # Describes an instrumation test suite: |
33 # test: Name of test we're running. | 34 # test: Name of test we're running. |
34 # apk: apk to be installed. | 35 # apk: apk to be installed. |
35 # apk_package: package for the apk to be installed. | 36 # apk_package: package for the apk to be installed. |
36 # test_apk: apk to run tests on. | 37 # test_apk: apk to run tests on. |
37 # test_data: data folder in format destination:source. | 38 # test_data: data folder in format destination:source. |
38 I_TEST = collections.namedtuple('InstrumentationTest', [ | 39 I_TEST = collections.namedtuple('InstrumentationTest', [ |
39 'name', 'apk', 'apk_package', 'test_apk', 'test_data', 'host_driven_root']) | 40 'name', 'apk', 'apk_package', 'test_apk', 'test_data', 'host_driven_root']) |
(...skipping 15 matching lines...) Expand all Loading... | |
55 'AndroidWebView.apk', | 56 'AndroidWebView.apk', |
56 'org.chromium.android_webview.shell', | 57 'org.chromium.android_webview.shell', |
57 'AndroidWebViewTest', | 58 'AndroidWebViewTest', |
58 'webview:android_webview/test/data/device_files', | 59 'webview:android_webview/test/data/device_files', |
59 None), | 60 None), |
60 ]) | 61 ]) |
61 | 62 |
62 VALID_TESTS = set(['chromedriver', 'ui', 'unit', 'webkit', 'webkit_layout']) | 63 VALID_TESTS = set(['chromedriver', 'ui', 'unit', 'webkit', 'webkit_layout']) |
63 | 64 |
64 | 65 |
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 | |
93 | |
94 # multiprocessing map_async requires a top-level function for pickle library. | 66 # multiprocessing map_async requires a top-level function for pickle library. |
95 def RebootDeviceSafe(device): | 67 def RebootDeviceSafe(device): |
96 """Reboot a device, wait for it to start, and squelch timeout exceptions.""" | 68 """Reboot a device, wait for it to start, and squelch timeout exceptions.""" |
97 try: | 69 try: |
98 android_commands.AndroidCommands(device).Reboot(True) | 70 android_commands.AndroidCommands(device).Reboot(True) |
99 except errors.DeviceUnresponsiveError as e: | 71 except errors.DeviceUnresponsiveError as e: |
100 return e | 72 return e |
101 | 73 |
102 | 74 |
103 def RebootDevices(): | 75 def RebootDevices(): |
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
317 RunCmd(['build/android/adb_logcat_printer.py', logcat_dir]) | 289 RunCmd(['build/android/adb_logcat_printer.py', logcat_dir]) |
318 | 290 |
319 buildbot_report.PrintNamedStep('test_report') | 291 buildbot_report.PrintNamedStep('test_report') |
320 for report in glob.glob( | 292 for report in glob.glob( |
321 os.path.join(CHROME_SRC, 'out', options.target, 'test_logs', '*.log')): | 293 os.path.join(CHROME_SRC, 'out', options.target, 'test_logs', '*.log')): |
322 RunCmd(['cat', report]) | 294 RunCmd(['cat', report]) |
323 os.remove(report) | 295 os.remove(report) |
324 | 296 |
325 | 297 |
326 def main(argv): | 298 def main(argv): |
299 buildbot_report.PrintNamedStep('Run tests') | |
327 parser = optparse.OptionParser() | 300 parser = optparse.OptionParser() |
328 | 301 |
329 def convert_json(option, _, value, parser): | |
330 setattr(parser.values, option.dest, json.loads(value)) | |
331 | |
332 parser.add_option('--build-properties', action='callback', | 302 parser.add_option('--build-properties', action='callback', |
Isaac (away)
2013/05/29 20:28:07
let's make a function in bb_utils "GetParser()" wh
Siva Chandra
2013/06/04 00:34:03
Done.
| |
333 callback=convert_json, type='string', default={}, | 303 callback=ConvertJson, type='string', default={}, |
334 help='build properties in JSON format') | 304 help='build properties in JSON format') |
335 parser.add_option('--factory-properties', action='callback', | 305 parser.add_option('--factory-properties', action='callback', |
336 callback=convert_json, type='string', default={}, | 306 callback=ConvertJson, type='string', default={}, |
337 help='factory properties in JSON format') | 307 help='factory properties in JSON format') |
338 parser.add_option('--slave-properties', action='callback', | 308 parser.add_option('--slave-properties', action='callback', |
339 callback=convert_json, type='string', default={}, | 309 callback=ConvertJson, type='string', default={}, |
340 help='Properties set by slave script in JSON format') | 310 help='Properties set by slave script in JSON format') |
341 parser.add_option('--experimental', action='store_true', | 311 parser.add_option('--experimental', action='store_true', |
342 help='Run experiemental tests') | 312 help='Run experiemental tests') |
343 parser.add_option('-f', '--test-filter', metavar='<filter>', default=[], | 313 parser.add_option('-f', '--test-filter', metavar='<filter>', default=[], |
344 action='append', | 314 action='append', |
345 help=('Run a test suite. Test suites: "%s"' % | 315 help=('Run a test suite. Test suites: "%s"' % |
346 '", "'.join(VALID_TESTS))) | 316 '", "'.join(VALID_TESTS))) |
347 parser.add_option('--asan', action='store_true', help='Run tests with asan.') | 317 parser.add_option('--asan', action='store_true', help='Run tests with asan.') |
348 parser.add_option('--install', metavar='<apk name>', | 318 parser.add_option('--install', metavar='<apk name>', |
349 help='Install an apk by name') | 319 help='Install an apk by name') |
350 parser.add_option('--reboot', action='store_true', | 320 parser.add_option('--reboot', action='store_true', |
351 help='Reboot devices before running tests') | 321 help='Reboot devices before running tests') |
352 parser.add_option('--upload-to-flakiness-server', action='store_true', | 322 parser.add_option('--upload-to-flakiness-server', action='store_true', |
353 help='Upload the results to the flakiness dashboard.') | 323 help='Upload the results to the flakiness dashboard.') |
354 parser.add_option( | 324 parser.add_option( |
355 '--auto-reconnect', action='store_true', | 325 '--auto-reconnect', action='store_true', |
356 help='Push script to device which restarts adbd on disconnections.') | 326 help='Push script to device which restarts adbd on disconnections.') |
357 options, args = parser.parse_args(argv[1:]) | 327 options, args = parser.parse_args(argv[1:]) |
358 | 328 |
359 def ParserError(msg): | |
360 """We avoid parser.error because it calls sys.exit.""" | |
361 parser.print_help() | |
362 print >> sys.stderr, '\nERROR:', msg | |
363 return 1 | |
364 | |
365 if args: | 329 if args: |
366 return ParserError('Unused args %s' % args) | 330 return OptParserError(parser, 'Unused args %s' % args) |
Isaac (away)
2013/05/29 20:28:07
GetParser should be able to return a parser with a
Siva Chandra
2013/06/04 00:34:03
Done.
| |
367 | 331 |
368 unknown_tests = set(options.test_filter) - VALID_TESTS | 332 unknown_tests = set(options.test_filter) - VALID_TESTS |
369 if unknown_tests: | 333 if unknown_tests: |
370 return ParserError('Unknown tests %s' % list(unknown_tests)) | 334 return OptParserError(parser, 'Unknown tests %s' % list(unknown_tests)) |
371 | 335 |
372 setattr(options, 'target', options.factory_properties.get('target', 'Debug')) | 336 setattr(options, 'target', options.factory_properties.get('target', 'Debug')) |
373 | 337 |
374 # Add adb binary and chromium-source platform-tools to tip of PATH variable. | 338 # Add adb binary and chromium-source platform-tools to tip of PATH variable. |
375 android_paths = [os.path.join(constants.ANDROID_SDK_ROOT, 'platform-tools')] | 339 android_paths = [os.path.join(constants.ANDROID_SDK_ROOT, 'platform-tools')] |
376 | 340 |
377 # Bots checkout chrome in /b/build/slave/<name>/build/src | 341 # Bots checkout chrome in /b/build/slave/<name>/build/src |
378 build_internal_android = os.path.abspath(os.path.join( | 342 build_internal_android = os.path.abspath(os.path.join( |
379 CHROME_SRC, '..', '..', '..', '..', '..', 'build_internal', 'scripts', | 343 CHROME_SRC, '..', '..', '..', '..', '..', 'build_internal', 'scripts', |
380 'slave', 'android')) | 344 'slave', 'android')) |
381 if os.path.exists(build_internal_android): | 345 if os.path.exists(build_internal_android): |
382 android_paths.insert(0, build_internal_android) | 346 android_paths.insert(0, build_internal_android) |
383 os.environ['PATH'] = os.pathsep.join(android_paths + [os.environ['PATH']]) | 347 os.environ['PATH'] = os.pathsep.join(android_paths + [os.environ['PATH']]) |
384 | 348 |
385 MainTestWrapper(options) | 349 MainTestWrapper(options) |
386 | 350 |
387 | 351 |
388 if __name__ == '__main__': | 352 if __name__ == '__main__': |
389 sys.exit(main(sys.argv)) | 353 sys.exit(main(sys.argv)) |
OLD | NEW |