]> git.proxmox.com Git - ceph.git/blob - ceph/src/rocksdb/coverage/parse_gcov_output.py
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / rocksdb / coverage / parse_gcov_output.py
1 import optparse
2 import re
3 import sys
4
5 from optparse import OptionParser
6
7 # the gcov report follows certain pattern. Each file will have two lines
8 # of report, from which we can extract the file name, total lines and coverage
9 # percentage.
10 def parse_gcov_report(gcov_input):
11 per_file_coverage = {}
12 total_coverage = None
13
14 for line in sys.stdin:
15 line = line.strip()
16
17 # --First line of the coverage report (with file name in it)?
18 match_obj = re.match("^File '(.*)'$", line)
19 if match_obj:
20 # fetch the file name from the first line of the report.
21 current_file = match_obj.group(1)
22 continue
23
24 # -- Second line of the file report (with coverage percentage)
25 match_obj = re.match("^Lines executed:(.*)% of (.*)", line)
26
27 if match_obj:
28 coverage = float(match_obj.group(1))
29 lines = int(match_obj.group(2))
30
31 if current_file is not None:
32 per_file_coverage[current_file] = (coverage, lines)
33 current_file = None
34 else:
35 # If current_file is not set, we reach the last line of report,
36 # which contains the summarized coverage percentage.
37 total_coverage = (coverage, lines)
38 continue
39
40 # If the line's pattern doesn't fall into the above categories. We
41 # can simply ignore them since they're either empty line or doesn't
42 # find executable lines of the given file.
43 current_file = None
44
45 return per_file_coverage, total_coverage
46
47 def get_option_parser():
48 usage = "Parse the gcov output and generate more human-readable code " +\
49 "coverage report."
50 parser = OptionParser(usage)
51
52 parser.add_option(
53 "--interested-files", "-i",
54 dest="filenames",
55 help="Comma separated files names. if specified, we will display " +
56 "the coverage report only for interested source files. " +
57 "Otherwise we will display the coverage report for all " +
58 "source files."
59 )
60 return parser
61
62 def display_file_coverage(per_file_coverage, total_coverage):
63 # To print out auto-adjustable column, we need to know the longest
64 # length of file names.
65 max_file_name_length = max(
66 len(fname) for fname in per_file_coverage.keys()
67 )
68
69 # -- Print header
70 # size of separator is determined by 3 column sizes:
71 # file name, coverage percentage and lines.
72 header_template = \
73 "%" + str(max_file_name_length) + "s\t%s\t%s"
74 separator = "-" * (max_file_name_length + 10 + 20)
75 print header_template % ("Filename", "Coverage", "Lines")
76 print separator
77
78 # -- Print body
79 # template for printing coverage report for each file.
80 record_template = "%" + str(max_file_name_length) + "s\t%5.2f%%\t%10d"
81
82 for fname, coverage_info in per_file_coverage.items():
83 coverage, lines = coverage_info
84 print record_template % (fname, coverage, lines)
85
86 # -- Print footer
87 if total_coverage:
88 print separator
89 print record_template % ("Total", total_coverage[0], total_coverage[1])
90
91 def report_coverage():
92 parser = get_option_parser()
93 (options, args) = parser.parse_args()
94
95 interested_files = set()
96 if options.filenames is not None:
97 interested_files = set(f.strip() for f in options.filenames.split(','))
98
99 # To make things simple, right now we only read gcov report from the input
100 per_file_coverage, total_coverage = parse_gcov_report(sys.stdin)
101
102 # Check if we need to display coverage info for interested files.
103 if len(interested_files):
104 per_file_coverage = dict(
105 (fname, per_file_coverage[fname]) for fname in interested_files
106 if fname in per_file_coverage
107 )
108 # If we only interested in several files, it makes no sense to report
109 # the total_coverage
110 total_coverage = None
111
112 if not len(per_file_coverage):
113 print >> sys.stderr, "Cannot find coverage info for the given files."
114 return
115 display_file_coverage(per_file_coverage, total_coverage)
116
117 if __name__ == "__main__":
118 report_coverage()