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

Side by Side Diff: tools/llvm_coverage_run.py

Issue 1213063009: Add scripts for running LLVM coverage (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: remove accidentally-include script Created 5 years, 5 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
« tools/llvm_coverage_build ('K') | « tools/llvm_coverage_build ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
11 import json
12 import os
13 import shlex
14 import subprocess
15 import sys
16
17
18 BUILDTYPE = 'Coverage'
19 OUT_DIR = os.path.realpath(os.path.join('out', BUILDTYPE))
20 PROFILE_DATA = 'default.profraw'
21 PROFILE_DATA_MERGED = 'prof_merged'
22
23
24 def _fix_filename(filename):
25 """Return a filename which we can use to identify the file.
26
27 The file paths printed by llvm-cov take the form:
28
29 /path/to/repo/out/dir/../../src/filename.cpp
30
31 And then they're truncated to 22 characters with leading ellipses:
32
33 ...../../src/filename.cpp
34
35 This makes it really tough to determine whether the file actually belongs in
36 the Skia repo. This function strips out the leading junk so that, if the file
37 exists in the repo, the returned string matches the end of some relative path
38 in the repo. This doesn't guarantee correctness, but it's about as close as
39 we can get.
40 """
41 return filename.split('..')[-1].lstrip('./')
42
43
44 def _filter_results(results):
45 """Filter out any results for files not in the Skia repo.
46
47 We run through the list of checked-in files and determine whether each file
48 belongs in the repo. Unfortunately, llvm-cov leaves us with fragments of the
49 file paths, so we can't guarantee accuracy. See the docstring for
50 _fix_filename for more details.
51 """
52 all_files = subprocess.check_output(['git', 'ls-files']).splitlines()
53 filtered = []
54 for percent, filename in results:
55 new_file = _fix_filename(filename)
56 matched = []
57 for f in all_files:
58 if f.endswith(new_file):
59 matched.append(f)
60 if len(matched) == 1:
61 filtered.append((percent, matched[0]))
62 elif len(matched) > 1:
63 print >> sys.stderr, ('WARNING: multiple matches for %s; skipping:\n\t%s'
64 % (new_file, '\n\t'.join(matched)))
65 print 'Filtered out %d files.' % (len(results) - len(filtered))
66 return filtered
borenet 2015/07/01 20:06:51 The right solution here is to submit a change to L
mtklein 2015/07/01 20:17:37 I wonder how basename.startswith('Sk') works as ou
borenet 2015/07/06 12:06:35 Maybe. The biggest problem with that is we'll mis
67
68
69 def run_coverage(cmd):
70 """Run the given command and return per-file coverage data.
71
72 Assumes that the binary has been built using llvm_coverage_build and that
73 LLVM 3.6 or newer is installed.
74 """
75 binary_path = os.path.join(OUT_DIR, cmd[0])
76 subprocess.call([binary_path] + cmd[1:])
77 try:
78 subprocess.check_call(
79 ['llvm-profdata', 'merge', PROFILE_DATA,
80 '-output=%s' % PROFILE_DATA_MERGED])
81 finally:
82 os.remove(PROFILE_DATA)
83 try:
84 report = subprocess.check_output(
85 ['llvm-cov', 'report', '-instr-profile', PROFILE_DATA_MERGED,
86 binary_path])
87 finally:
88 os.remove(PROFILE_DATA_MERGED)
89 results = []
90 for line in report.splitlines()[2:-2]:
91 filename, _, _, cover, _, _ = shlex.split(line)
92 percent = float(cover.split('%')[0])
93 results.append((percent, filename))
94 results = _filter_results(results)
95 results.sort()
96 return results
97
98
99 def main():
100 res = run_coverage(sys.argv[1:])
101 print '% Covered\tFilename'
102 for percent, f in res:
mtklein 2015/07/01 20:17:37 Can we get a line-by-line breakdown or some sort o
borenet 2015/07/06 12:06:35 `llvm-cov show` generates a giant file which shows
103 print '%f\t%s' % (percent, f)
104
105
106 if __name__ == '__main__':
107 main()
OLDNEW
« tools/llvm_coverage_build ('K') | « tools/llvm_coverage_build ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698