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

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

Issue 23345003: [Android] Buildbot changes for EMMA code coverage (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Cleans up |coverage_dir|, moves upload into its own function Created 7 years, 4 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
« no previous file with comments | « no previous file | build/android/buildbot/bb_run_bot.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 multiprocessing 8 import multiprocessing
9 import os 9 import os
10 import shutil 10 import shutil
11 import sys 11 import sys
12 import time
12 13
13 import bb_utils 14 import bb_utils
14 import bb_annotations 15 import bb_annotations
15 16
16 sys.path.append(os.path.join(os.path.dirname(__file__), '..')) 17 sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
17 import provision_devices 18 import provision_devices
18 from pylib import android_commands 19 from pylib import android_commands
19 from pylib import constants 20 from pylib import constants
20 from pylib.gtest import gtest_config 21 from pylib.gtest import gtest_config
21 22
22 sys.path.append(os.path.join( 23 sys.path.append(os.path.join(
23 constants.DIR_SOURCE_ROOT, 'third_party', 'android_testrunner')) 24 constants.DIR_SOURCE_ROOT, 'third_party', 'android_testrunner'))
24 import errors 25 import errors
25 26
26 27
27 CHROME_SRC = constants.DIR_SOURCE_ROOT 28 CHROME_SRC = constants.DIR_SOURCE_ROOT
28 LOGCAT_DIR = os.path.join(CHROME_SRC, 'out', 'logcat') 29 LOGCAT_DIR = os.path.join(CHROME_SRC, 'out', 'logcat')
30 REVISION_FILENAME = 'FULL_BUILD_REVISION'
29 31
30 # Describes an instrumation test suite: 32 # Describes an instrumation test suite:
31 # test: Name of test we're running. 33 # test: Name of test we're running.
32 # apk: apk to be installed. 34 # apk: apk to be installed.
33 # apk_package: package for the apk to be installed. 35 # apk_package: package for the apk to be installed.
34 # test_apk: apk to run tests on. 36 # test_apk: apk to run tests on.
35 # test_data: data folder in format destination:source. 37 # test_data: data folder in format destination:source.
36 # host_driven_root: The host-driven test root directory. 38 # host_driven_root: The host-driven test root directory.
37 # annotation: Annotation of the tests to include. 39 # annotation: Annotation of the tests to include.
38 # exclude_annotation: The annotation of the tests to exclude. 40 # exclude_annotation: The annotation of the tests to exclude.
39 I_TEST = collections.namedtuple('InstrumentationTest', [ 41 I_TEST = collections.namedtuple('InstrumentationTest', [
40 'name', 'apk', 'apk_package', 'test_apk', 'test_data', 'host_driven_root', 42 'name', 'apk', 'apk_package', 'test_apk', 'test_data', 'coverage',
41 'annotation', 'exclude_annotation', 'extra_flags']) 43 'host_driven_root', 'annotation', 'exclude_annotation', 'extra_flags'])
42 44
43 def I(name, apk, apk_package, test_apk, test_data, host_driven_root=None, 45 def I(name, apk, apk_package, test_apk, test_data, coverage=True,
44 annotation=None, exclude_annotation=None, extra_flags=None): 46 host_driven_root=None, annotation=None, exclude_annotation=None,
45 return I_TEST(name, apk, apk_package, test_apk, test_data, host_driven_root, 47 extra_flags=None):
46 annotation, exclude_annotation, extra_flags) 48 return I_TEST(name, apk, apk_package, test_apk, test_data, coverage,
49 host_driven_root, annotation, exclude_annotation, extra_flags)
47 50
48 INSTRUMENTATION_TESTS = dict((suite.name, suite) for suite in [ 51 INSTRUMENTATION_TESTS = dict((suite.name, suite) for suite in [
49 I('ContentShell', 52 I('ContentShell',
50 'ContentShell.apk', 53 'ContentShell.apk',
51 'org.chromium.content_shell_apk', 54 'org.chromium.content_shell_apk',
52 'ContentShellTest', 55 'ContentShellTest',
53 'content:content/test/data/android/device_files'), 56 'content:content/test/data/android/device_files'),
54 I('ChromiumTestShell', 57 I('ChromiumTestShell',
55 'ChromiumTestShell.apk', 58 'ChromiumTestShell.apk',
56 'org.chromium.chrome.testshell', 59 'org.chromium.chrome.testshell',
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
158 InstallApk(options, test) 161 InstallApk(options, test)
159 args = ['--test-apk', test.test_apk, '--test_data', test.test_data, 162 args = ['--test-apk', test.test_apk, '--test_data', test.test_data,
160 '--verbose'] 163 '--verbose']
161 if options.target == 'Release': 164 if options.target == 'Release':
162 args.append('--release') 165 args.append('--release')
163 if options.asan: 166 if options.asan:
164 args.append('--tool=asan') 167 args.append('--tool=asan')
165 if options.flakiness_server: 168 if options.flakiness_server:
166 args.append('--flakiness-dashboard-server=%s' % 169 args.append('--flakiness-dashboard-server=%s' %
167 options.flakiness_server) 170 options.flakiness_server)
171 if options.coverage_bucket and test.coverage:
172 args.append('--coverage-dir=%s' % options.coverage_dir)
168 if test.host_driven_root: 173 if test.host_driven_root:
169 args.append('--host-driven-root=%s' % test.host_driven_root) 174 args.append('--host-driven-root=%s' % test.host_driven_root)
170 if test.annotation: 175 if test.annotation:
171 args.extend(['-A', test.annotation]) 176 args.extend(['-A', test.annotation])
172 if test.exclude_annotation: 177 if test.exclude_annotation:
173 args.extend(['-E', test.exclude_annotation]) 178 args.extend(['-E', test.exclude_annotation])
174 if test.extra_flags: 179 if test.extra_flags:
175 args.extend(test.extra_flags) 180 args.extend(test.extra_flags)
176 if python_only: 181 if python_only:
177 args.append('-p') 182 args.append('-p')
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
263 ('provision_devices', ProvisionDevices), 268 ('provision_devices', ProvisionDevices),
264 ('device_status_check', DeviceStatusCheck) 269 ('device_status_check', DeviceStatusCheck)
265 ] 270 ]
266 271
267 272
268 def RunUnitTests(options): 273 def RunUnitTests(options):
269 RunTestSuites(options, gtest_config.STABLE_TEST_SUITES) 274 RunTestSuites(options, gtest_config.STABLE_TEST_SUITES)
270 275
271 276
272 def RunInstrumentationTests(options): 277 def RunInstrumentationTests(options):
278 if options.coverage_bucket:
279 shutil.rmtree(options.coverage_dir, ignore_errors=True)
Isaac (away) 2013/08/20 23:28:10 not needed for triggered bots. Also, I'd prefer w
gkanwar1 2013/08/20 23:40:29 Good to know, removed. Not sure what you mean by s
Isaac (away) 2013/08/22 18:10:37 I mean, if you're going to delete a folder, print
gkanwar1 2013/08/22 18:12:11 Ah, got it. Good to know for the future. For this
280 os.mkdir(options.coverage_dir)
281
273 for test in INSTRUMENTATION_TESTS.itervalues(): 282 for test in INSTRUMENTATION_TESTS.itervalues():
274 RunInstrumentationSuite(options, test) 283 RunInstrumentationSuite(options, test)
275 284
285 if options.coverage_bucket:
Isaac (away) 2013/08/20 23:28:10 Does this need to be called from RunInstrumentatio
gkanwar1 2013/08/20 23:40:29 Nope. It was there because it was acting sort of a
286 GenerateJavaCoverageReport(options)
287
276 288
277 def RunWebkitTests(options): 289 def RunWebkitTests(options):
278 RunTestSuites(options, ['webkit_unit_tests']) 290 RunTestSuites(options, ['webkit_unit_tests'])
279 RunWebkitLint(options.target) 291 RunWebkitLint(options.target)
280 292
281 293
282 def RunWebRTCTests(options): 294 def RunWebRTCTests(options):
283 RunTestSuites(options, gtest_config.WEBRTC_TEST_SUITES) 295 RunTestSuites(options, gtest_config.WEBRTC_TEST_SUITES)
284 296
285 297
286 def GetTestStepCmds(): 298 def GetTestStepCmds():
287 return [ 299 return [
288 ('chromedriver', RunChromeDriverTests), 300 ('chromedriver', RunChromeDriverTests),
289 ('unit', RunUnitTests), 301 ('unit', RunUnitTests),
290 ('ui', RunInstrumentationTests), 302 ('ui', RunInstrumentationTests),
291 ('webkit', RunWebkitTests), 303 ('webkit', RunWebkitTests),
292 ('webkit_layout', RunWebkitLayoutTests), 304 ('webkit_layout', RunWebkitLayoutTests),
293 ('webrtc', RunWebRTCTests), 305 ('webrtc', RunWebRTCTests),
294 ] 306 ]
295 307
296 308
309 def UploadCoverageData(options, path, coverage_type):
310 revision_file = os.path.join(CHROME_SRC, 'out', options.target,
311 REVISION_FILENAME)
Isaac (away) 2013/08/20 23:28:10 Would be better to use revision from build_propert
gkanwar1 2013/08/20 23:40:29 Ah, didn't realize that was in build_properties. D
312 # If the revision file doesn't exist, we're just testing the bot
313 if os.path.exists(revision_file):
314 with open(revision_file) as f:
315 revision = f.read()
316 else:
317 revision = 'testing'
318 bot_id = options.build_properties.get('buildername', 'unknown')
319
320 timehash = hash(time.time())
321
322 boto_config = os.path.join(bb_utils.BB_BUILD_DIR, 'site_config', '.boto')
323 os.environ['AWS_CREDENTIAL_FILE'] = boto_config
Isaac (away) 2013/08/20 23:28:10 These are set automatically on bots; this isn't ne
gkanwar1 2013/08/20 23:40:29 Good to know, removed.
324 os.environ['BOTO_CONFIG'] = boto_config
325 RunCmd([os.path.join(bb_utils.BB_BUILD_DIR, 'third_party',
Isaac (away) 2013/08/20 23:28:10 let's make the gsutil path a constant in bb_utils.
gkanwar1 2013/08/20 23:40:30 Done.
326 'gsutil', 'gsutil'), 'cp', '-R',
327 path, 'gs://%s/%s/%s/%s/%s' %
328 (options.coverage_bucket, coverage_type,
329 bot_id, revision, timehash)])
330 bb_annotations.PrintLink(
331 'Coverage report',
332 'https://storage.googleapis.com/%s/%s/%s/%s/%s/index.html'
333 % (options.coverage_bucket, coverage_type, bot_id, revision, timehash))
334
335
336 def GenerateJavaCoverageReport(options):
337 bb_annotations.PrintNamedStep('java_coverage_report')
338
339 coverage_html = os.path.join(options.coverage_dir, 'coverage_html')
340 RunCmd(['build/android/generate_emma_html.py',
341 '--coverage-dir', options.coverage_dir,
342 '--metadata-dir', os.path.join(CHROME_SRC, 'out', options.target),
343 '--output', os.path.join(coverage_html, 'coverage.html')])
344 UploadCoverageData(options, coverage_html, 'java')
345
346
297 def LogcatDump(options): 347 def LogcatDump(options):
298 # Print logcat, kill logcat monitor 348 # Print logcat, kill logcat monitor
299 bb_annotations.PrintNamedStep('logcat_dump') 349 bb_annotations.PrintNamedStep('logcat_dump')
300 logcat_file = os.path.join(CHROME_SRC, 'out', options.target, 'full_log') 350 logcat_file = os.path.join(CHROME_SRC, 'out', options.target, 'full_log')
301 with open(logcat_file, 'w') as f: 351 with open(logcat_file, 'w') as f:
302 RunCmd([ 352 RunCmd([
303 os.path.join(CHROME_SRC, 'build', 'android', 'adb_logcat_printer.py'), 353 os.path.join(CHROME_SRC, 'build', 'android', 'adb_logcat_printer.py'),
304 LOGCAT_DIR], stdout=f) 354 LOGCAT_DIR], stdout=f)
305 RunCmd(['cat', logcat_file]) 355 RunCmd(['cat', logcat_file])
306 356
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
347 help='Run experiemental tests') 397 help='Run experiemental tests')
348 parser.add_option('-f', '--test-filter', metavar='<filter>', default=[], 398 parser.add_option('-f', '--test-filter', metavar='<filter>', default=[],
349 action='append', 399 action='append',
350 help=('Run a test suite. Test suites: "%s"' % 400 help=('Run a test suite. Test suites: "%s"' %
351 '", "'.join(VALID_TESTS))) 401 '", "'.join(VALID_TESTS)))
352 parser.add_option('--asan', action='store_true', help='Run tests with asan.') 402 parser.add_option('--asan', action='store_true', help='Run tests with asan.')
353 parser.add_option('--install', metavar='<apk name>', 403 parser.add_option('--install', metavar='<apk name>',
354 help='Install an apk by name') 404 help='Install an apk by name')
355 parser.add_option('--reboot', action='store_true', 405 parser.add_option('--reboot', action='store_true',
356 help='Reboot devices before running tests') 406 help='Reboot devices before running tests')
407 parser.add_option('--coverage-bucket',
408 help=('Bucket name to store coverage results. Coverage is '
409 'only run if this is set.'))
357 parser.add_option( 410 parser.add_option(
358 '--flakiness-server', 411 '--flakiness-server',
359 help='The flakiness dashboard server to which the results should be ' 412 help='The flakiness dashboard server to which the results should be '
360 'uploaded.') 413 'uploaded.')
361 parser.add_option( 414 parser.add_option(
362 '--auto-reconnect', action='store_true', 415 '--auto-reconnect', action='store_true',
363 help='Push script to device which restarts adbd on disconnections.') 416 help='Push script to device which restarts adbd on disconnections.')
364 parser.add_option( 417 parser.add_option(
365 '--logcat-dump-output', 418 '--logcat-dump-output',
366 help='The logcat dump output will be "tee"-ed into this file') 419 help='The logcat dump output will be "tee"-ed into this file')
367 420
368 return parser 421 return parser
369 422
370 423
371 def main(argv): 424 def main(argv):
372 parser = GetDeviceStepsOptParser() 425 parser = GetDeviceStepsOptParser()
373 options, args = parser.parse_args(argv[1:]) 426 options, args = parser.parse_args(argv[1:])
374 427
375 if args: 428 if args:
376 return sys.exit('Unused args %s' % args) 429 return sys.exit('Unused args %s' % args)
377 430
378 unknown_tests = set(options.test_filter) - VALID_TESTS 431 unknown_tests = set(options.test_filter) - VALID_TESTS
379 if unknown_tests: 432 if unknown_tests:
380 return sys.exit('Unknown tests %s' % list(unknown_tests)) 433 return sys.exit('Unknown tests %s' % list(unknown_tests))
381 434
382 setattr(options, 'target', options.factory_properties.get('target', 'Debug')) 435 setattr(options, 'target', options.factory_properties.get('target', 'Debug'))
436 if options.coverage_bucket:
437 setattr(options, 'coverage_dir',
438 os.path.join(CHROME_SRC, 'out', options.target, 'coverage'))
383 439
384 MainTestWrapper(options) 440 MainTestWrapper(options)
385 441
386 442
387 if __name__ == '__main__': 443 if __name__ == '__main__':
388 sys.exit(main(sys.argv)) 444 sys.exit(main(sys.argv))
OLDNEW
« no previous file with comments | « no previous file | build/android/buildbot/bb_run_bot.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698