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 hashlib |
8 import multiprocessing | 9 import multiprocessing |
9 import os | 10 import os |
| 11 import random |
10 import shutil | 12 import shutil |
11 import sys | 13 import sys |
12 | 14 |
13 import bb_utils | 15 import bb_utils |
14 import bb_annotations | 16 import bb_annotations |
15 | 17 |
16 sys.path.append(os.path.join(os.path.dirname(__file__), '..')) | 18 sys.path.append(os.path.join(os.path.dirname(__file__), '..')) |
17 import provision_devices | 19 import provision_devices |
18 from pylib import android_commands | 20 from pylib import android_commands |
19 from pylib import constants | 21 from pylib import constants |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
158 InstallApk(options, test) | 160 InstallApk(options, test) |
159 args = ['--test-apk', test.test_apk, '--test_data', test.test_data, | 161 args = ['--test-apk', test.test_apk, '--test_data', test.test_data, |
160 '--verbose'] | 162 '--verbose'] |
161 if options.target == 'Release': | 163 if options.target == 'Release': |
162 args.append('--release') | 164 args.append('--release') |
163 if options.asan: | 165 if options.asan: |
164 args.append('--tool=asan') | 166 args.append('--tool=asan') |
165 if options.flakiness_server: | 167 if options.flakiness_server: |
166 args.append('--flakiness-dashboard-server=%s' % | 168 args.append('--flakiness-dashboard-server=%s' % |
167 options.flakiness_server) | 169 options.flakiness_server) |
| 170 if options.coverage_bucket: |
| 171 args.append('--coverage-dir=%s' % options.coverage_dir) |
168 if test.host_driven_root: | 172 if test.host_driven_root: |
169 args.append('--host-driven-root=%s' % test.host_driven_root) | 173 args.append('--host-driven-root=%s' % test.host_driven_root) |
170 if test.annotation: | 174 if test.annotation: |
171 args.extend(['-A', test.annotation]) | 175 args.extend(['-A', test.annotation]) |
172 if test.exclude_annotation: | 176 if test.exclude_annotation: |
173 args.extend(['-E', test.exclude_annotation]) | 177 args.extend(['-E', test.exclude_annotation]) |
174 if test.extra_flags: | 178 if test.extra_flags: |
175 args.extend(test.extra_flags) | 179 args.extend(test.extra_flags) |
176 if python_only: | 180 if python_only: |
177 args.append('-p') | 181 args.append('-p') |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
287 return [ | 291 return [ |
288 ('chromedriver', RunChromeDriverTests), | 292 ('chromedriver', RunChromeDriverTests), |
289 ('unit', RunUnitTests), | 293 ('unit', RunUnitTests), |
290 ('ui', RunInstrumentationTests), | 294 ('ui', RunInstrumentationTests), |
291 ('webkit', RunWebkitTests), | 295 ('webkit', RunWebkitTests), |
292 ('webkit_layout', RunWebkitLayoutTests), | 296 ('webkit_layout', RunWebkitLayoutTests), |
293 ('webrtc', RunWebRTCTests), | 297 ('webrtc', RunWebRTCTests), |
294 ] | 298 ] |
295 | 299 |
296 | 300 |
| 301 def UploadCoverageData(options, path, coverage_type): |
| 302 """Uploads directory at |path| to Google Storage. |
| 303 |
| 304 The directory at path should ostensibly contain HTML coverage data. |
| 305 |
| 306 Args: |
| 307 options: Command line options. |
| 308 path: Path to the directory to be uploaded. |
| 309 coverage_type: String used as the first component of the url. |
| 310 |
| 311 Returns: |
| 312 None. |
| 313 """ |
| 314 revision = options.build_properties.get('got_revision', 'testing') |
| 315 bot_id = options.build_properties.get('buildername', 'testing') |
| 316 randhash = hashlib.sha1(str(random.random())).hexdigest() |
| 317 gs_path = '%s/%s/%s/%s/%s' % (options.coverage_bucket, coverage_type, |
| 318 bot_id, revision, randhash) |
| 319 |
| 320 RunCmd([bb_utils.GSUTIL_PATH, 'cp', '-R', path, 'gs://%s' % gs_path]) |
| 321 bb_annotations.PrintLink( |
| 322 'Coverage report', |
| 323 'https://storage.googleapis.com/%s/index.html' % gs_path) |
| 324 |
| 325 |
| 326 def GenerateJavaCoverageReport(options): |
| 327 """Generates an HTML coverage report using EMMA and uploads it.""" |
| 328 bb_annotations.PrintNamedStep('java_coverage_report') |
| 329 |
| 330 coverage_html = os.path.join(options.coverage_dir, 'coverage_html') |
| 331 RunCmd(['build/android/generate_emma_html.py', |
| 332 '--coverage-dir', options.coverage_dir, |
| 333 '--metadata-dir', os.path.join(CHROME_SRC, 'out', options.target), |
| 334 '--output', os.path.join(coverage_html, 'index.html')]) |
| 335 UploadCoverageData(options, coverage_html, 'java') |
| 336 |
| 337 |
297 def LogcatDump(options): | 338 def LogcatDump(options): |
298 # Print logcat, kill logcat monitor | 339 # Print logcat, kill logcat monitor |
299 bb_annotations.PrintNamedStep('logcat_dump') | 340 bb_annotations.PrintNamedStep('logcat_dump') |
300 logcat_file = os.path.join(CHROME_SRC, 'out', options.target, 'full_log') | 341 logcat_file = os.path.join(CHROME_SRC, 'out', options.target, 'full_log') |
301 with open(logcat_file, 'w') as f: | 342 with open(logcat_file, 'w') as f: |
302 RunCmd([ | 343 RunCmd([ |
303 os.path.join(CHROME_SRC, 'build', 'android', 'adb_logcat_printer.py'), | 344 os.path.join(CHROME_SRC, 'build', 'android', 'adb_logcat_printer.py'), |
304 LOGCAT_DIR], stdout=f) | 345 LOGCAT_DIR], stdout=f) |
305 RunCmd(['cat', logcat_file]) | 346 RunCmd(['cat', logcat_file]) |
306 | 347 |
(...skipping 15 matching lines...) Expand all Loading... |
322 for _, cmd in GetDeviceSetupStepCmds(): | 363 for _, cmd in GetDeviceSetupStepCmds(): |
323 cmd(options) | 364 cmd(options) |
324 | 365 |
325 if options.install: | 366 if options.install: |
326 test_obj = INSTRUMENTATION_TESTS[options.install] | 367 test_obj = INSTRUMENTATION_TESTS[options.install] |
327 InstallApk(options, test_obj, print_step=True) | 368 InstallApk(options, test_obj, print_step=True) |
328 | 369 |
329 if options.test_filter: | 370 if options.test_filter: |
330 bb_utils.RunSteps(options.test_filter, GetTestStepCmds(), options) | 371 bb_utils.RunSteps(options.test_filter, GetTestStepCmds(), options) |
331 | 372 |
| 373 if options.coverage_bucket: |
| 374 GenerateJavaCoverageReport(options) |
| 375 |
332 if options.experimental: | 376 if options.experimental: |
333 RunTestSuites(options, gtest_config.EXPERIMENTAL_TEST_SUITES) | 377 RunTestSuites(options, gtest_config.EXPERIMENTAL_TEST_SUITES) |
334 | 378 |
335 finally: | 379 finally: |
336 # Run all post test steps | 380 # Run all post test steps |
337 LogcatDump(options) | 381 LogcatDump(options) |
338 GenerateTestReport(options) | 382 GenerateTestReport(options) |
339 # KillHostHeartbeat() has logic to check if heartbeat process is running, | 383 # KillHostHeartbeat() has logic to check if heartbeat process is running, |
340 # and kills only if it finds the process is running on the host. | 384 # and kills only if it finds the process is running on the host. |
341 provision_devices.KillHostHeartbeat() | 385 provision_devices.KillHostHeartbeat() |
342 | 386 |
343 | 387 |
344 def GetDeviceStepsOptParser(): | 388 def GetDeviceStepsOptParser(): |
345 parser = bb_utils.GetParser() | 389 parser = bb_utils.GetParser() |
346 parser.add_option('--experimental', action='store_true', | 390 parser.add_option('--experimental', action='store_true', |
347 help='Run experiemental tests') | 391 help='Run experiemental tests') |
348 parser.add_option('-f', '--test-filter', metavar='<filter>', default=[], | 392 parser.add_option('-f', '--test-filter', metavar='<filter>', default=[], |
349 action='append', | 393 action='append', |
350 help=('Run a test suite. Test suites: "%s"' % | 394 help=('Run a test suite. Test suites: "%s"' % |
351 '", "'.join(VALID_TESTS))) | 395 '", "'.join(VALID_TESTS))) |
352 parser.add_option('--asan', action='store_true', help='Run tests with asan.') | 396 parser.add_option('--asan', action='store_true', help='Run tests with asan.') |
353 parser.add_option('--install', metavar='<apk name>', | 397 parser.add_option('--install', metavar='<apk name>', |
354 help='Install an apk by name') | 398 help='Install an apk by name') |
355 parser.add_option('--reboot', action='store_true', | 399 parser.add_option('--reboot', action='store_true', |
356 help='Reboot devices before running tests') | 400 help='Reboot devices before running tests') |
| 401 parser.add_option('--coverage-bucket', |
| 402 help=('Bucket name to store coverage results. Coverage is ' |
| 403 'only run if this is set.')) |
357 parser.add_option( | 404 parser.add_option( |
358 '--flakiness-server', | 405 '--flakiness-server', |
359 help='The flakiness dashboard server to which the results should be ' | 406 help='The flakiness dashboard server to which the results should be ' |
360 'uploaded.') | 407 'uploaded.') |
361 parser.add_option( | 408 parser.add_option( |
362 '--auto-reconnect', action='store_true', | 409 '--auto-reconnect', action='store_true', |
363 help='Push script to device which restarts adbd on disconnections.') | 410 help='Push script to device which restarts adbd on disconnections.') |
364 parser.add_option( | 411 parser.add_option( |
365 '--logcat-dump-output', | 412 '--logcat-dump-output', |
366 help='The logcat dump output will be "tee"-ed into this file') | 413 help='The logcat dump output will be "tee"-ed into this file') |
367 | 414 |
368 return parser | 415 return parser |
369 | 416 |
370 | 417 |
371 def main(argv): | 418 def main(argv): |
372 parser = GetDeviceStepsOptParser() | 419 parser = GetDeviceStepsOptParser() |
373 options, args = parser.parse_args(argv[1:]) | 420 options, args = parser.parse_args(argv[1:]) |
374 | 421 |
375 if args: | 422 if args: |
376 return sys.exit('Unused args %s' % args) | 423 return sys.exit('Unused args %s' % args) |
377 | 424 |
378 unknown_tests = set(options.test_filter) - VALID_TESTS | 425 unknown_tests = set(options.test_filter) - VALID_TESTS |
379 if unknown_tests: | 426 if unknown_tests: |
380 return sys.exit('Unknown tests %s' % list(unknown_tests)) | 427 return sys.exit('Unknown tests %s' % list(unknown_tests)) |
381 | 428 |
382 setattr(options, 'target', options.factory_properties.get('target', 'Debug')) | 429 setattr(options, 'target', options.factory_properties.get('target', 'Debug')) |
| 430 if options.coverage_bucket: |
| 431 setattr(options, 'coverage_dir', |
| 432 os.path.join(CHROME_SRC, 'out', options.target, 'coverage')) |
383 | 433 |
384 MainTestWrapper(options) | 434 MainTestWrapper(options) |
385 | 435 |
386 | 436 |
387 if __name__ == '__main__': | 437 if __name__ == '__main__': |
388 sys.exit(main(sys.argv)) | 438 sys.exit(main(sys.argv)) |
OLD | NEW |