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