blob: 75f12bd44ee9e42266fa6368f90315dbe4028dd3 [file] [log] [blame]
#!/usr/bin/env python3
import os
import argparse
import subprocess
import tempfile
def find_workspace(path):
"""Finds enclosing bazel WORKSPACE directory to |path|."""
if os.path.isfile(os.path.join(path, 'WORKSPACE')):
return path
else:
parent = os.path.dirname(path)
return None if parent == path else find_workspace(parent)
def bazel_query(bazel, query):
print(' bazel query {}'.format(query))
return subprocess.check_output([bazel, 'query', query]).decode('utf-8').splitlines()
def main():
"""Finds all bazel jacoco agent coverage reports and generates them."""
parser = argparse.ArgumentParser(description='Generate coverage reports.')
parser.add_argument('--bazel_testlogs', default='bazel-testlogs', help='location of the testlogs dir to analyze')
args = parser.parse_args()
test_logs_dir = args.bazel_testlogs
workspace = find_workspace(os.path.realpath(__file__))
bazel = workspace + '/tools/base/bazel/bazel'
universe = '//tools/...'
print('Finding all possible coverage reports...')
coverage_targets = bazel_query(
bazel, 'attr("tags","agent_coverage_report",kind(java_binary, ' + universe
+ '))')
if not coverage_targets:
print('No coverage targets found')
return
print('found targets:')
for coverage_target in coverage_targets:
print(' {}'.format(coverage_target))
targets_map = {target: tempfile.NamedTemporaryFile(mode='w+t') for target in coverage_targets}
for (coverage_target, production_targets_file) in targets_map.items():
print('Finding test targets for report ' + coverage_target)
# find the tests for the production code that this coverage report relates to
production_targets = bazel_query(
bazel,
'kind(test, rdeps(' + universe + ', deps(' + coverage_target + ')))')
for target in production_targets:
production_targets_file.write(target)
production_targets_file.write('\n')
print(' ... found {} targets'.format(len(production_targets)))
for (coverage_target, production_targets_file) in targets_map.items():
report_name = coverage_target[2:].replace(':', '/')
# generate the coverage report
subprocess.check_call(
[bazel, 'run', coverage_target, '--config=remote', '--', report_name, production_targets_file.name, test_logs_dir])
print('Done.')
if __name__ == '__main__':
main()