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
10import argparse
11import os
12import subprocess
13
14
15BUILDTYPE = 'Coverage'
16PROFILE_DATA = 'default.profraw'
17PROFILE_DATA_MERGED = 'prof_merged'
18SKIA_OUT = 'SKIA_OUT'
19
20
21def _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
27def 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  """
33  binary_path = os.path.join(_get_out_dir(), cmd[0])
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:
42    return subprocess.check_output(['llvm-cov', 'show', '-no-colors',
43                                    '-instr-profile', PROFILE_DATA_MERGED,
44                                    binary_path])
45  finally:
46    os.remove(PROFILE_DATA_MERGED)
47
48
49def main():
50  """Run coverage and generate a report."""
51  # Parse args.
52  parser = argparse.ArgumentParser()
53  parser.add_argument('--outResultsFile')
54  args, cmd = parser.parse_known_args()
55
56  # Run coverage.
57  report = run_coverage(cmd)
58  with open(args.outResultsFile, 'w') as f:
59    f.write(report)
60
61
62if __name__ == '__main__':
63  main()
64