borenet | 11271fe | 2015-07-06 07:43:58 -0700 | [diff] [blame] | 1 | #!/usr/bin/env python |
| 2 | # Copyright (c) 2015 The Chromium Authors. All rights reserved. |
| 3 | # Use of this source code is governed by a BSD-style license that can be |
| 4 | # found in the LICENSE file. |
| 5 | |
| 6 | |
| 7 | """Run the given command through LLVM's coverage tools.""" |
| 8 | |
| 9 | |
| 10 | import argparse |
borenet | 11271fe | 2015-07-06 07:43:58 -0700 | [diff] [blame] | 11 | import os |
borenet | 11271fe | 2015-07-06 07:43:58 -0700 | [diff] [blame] | 12 | import subprocess |
borenet | 11271fe | 2015-07-06 07:43:58 -0700 | [diff] [blame] | 13 | |
| 14 | |
| 15 | BUILDTYPE = 'Coverage' |
borenet | 11271fe | 2015-07-06 07:43:58 -0700 | [diff] [blame] | 16 | PROFILE_DATA = 'default.profraw' |
| 17 | PROFILE_DATA_MERGED = 'prof_merged' |
borenet | f0c8440 | 2015-07-15 07:43:06 -0700 | [diff] [blame] | 18 | SKIA_OUT = 'SKIA_OUT' |
borenet | 11271fe | 2015-07-06 07:43:58 -0700 | [diff] [blame] | 19 | |
| 20 | |
borenet | f0c8440 | 2015-07-15 07:43:06 -0700 | [diff] [blame] | 21 | def _get_out_dir(): |
| 22 | """Determine the location for compiled binaries.""" |
| 23 | return os.path.join(os.environ.get(SKIA_OUT, os.path.realpath('out')), |
| 24 | BUILDTYPE) |
| 25 | |
| 26 | |
borenet | 11271fe | 2015-07-06 07:43:58 -0700 | [diff] [blame] | 27 | def run_coverage(cmd): |
| 28 | """Run the given command and return per-file coverage data. |
| 29 | |
| 30 | Assumes that the binary has been built using llvm_coverage_build and that |
| 31 | LLVM 3.6 or newer is installed. |
| 32 | """ |
borenet | f0c8440 | 2015-07-15 07:43:06 -0700 | [diff] [blame] | 33 | binary_path = os.path.join(_get_out_dir(), cmd[0]) |
borenet | 11271fe | 2015-07-06 07:43:58 -0700 | [diff] [blame] | 34 | subprocess.call([binary_path] + cmd[1:]) |
| 35 | try: |
| 36 | subprocess.check_call( |
| 37 | ['llvm-profdata', 'merge', PROFILE_DATA, |
| 38 | '-output=%s' % PROFILE_DATA_MERGED]) |
| 39 | finally: |
| 40 | os.remove(PROFILE_DATA) |
| 41 | try: |
borenet | a6ae14e | 2015-07-20 09:43:36 -0700 | [diff] [blame] | 42 | return subprocess.check_output(['llvm-cov', 'show', '-no-colors', |
| 43 | '-instr-profile', PROFILE_DATA_MERGED, |
| 44 | binary_path]) |
borenet | 11271fe | 2015-07-06 07:43:58 -0700 | [diff] [blame] | 45 | finally: |
| 46 | os.remove(PROFILE_DATA_MERGED) |
borenet | 334e588 | 2015-07-06 11:18:45 -0700 | [diff] [blame] | 47 | |
| 48 | |
borenet | 11271fe | 2015-07-06 07:43:58 -0700 | [diff] [blame] | 49 | def main(): |
borenet | 334e588 | 2015-07-06 11:18:45 -0700 | [diff] [blame] | 50 | """Run coverage and generate a report.""" |
| 51 | # Parse args. |
| 52 | parser = argparse.ArgumentParser() |
| 53 | parser.add_argument('--outResultsFile') |
borenet | 334e588 | 2015-07-06 11:18:45 -0700 | [diff] [blame] | 54 | args, cmd = parser.parse_known_args() |
borenet | 8a955af | 2015-07-16 07:01:44 -0700 | [diff] [blame] | 55 | |
borenet | 334e588 | 2015-07-06 11:18:45 -0700 | [diff] [blame] | 56 | # Run coverage. |
borenet | a6ae14e | 2015-07-20 09:43:36 -0700 | [diff] [blame] | 57 | report = run_coverage(cmd) |
| 58 | with open(args.outResultsFile, 'w') as f: |
| 59 | f.write(report) |
borenet | 11271fe | 2015-07-06 07:43:58 -0700 | [diff] [blame] | 60 | |
| 61 | |
| 62 | if __name__ == '__main__': |
| 63 | main() |