]>
git.proxmox.com Git - ceph.git/blob - ceph/src/rocksdb/coverage/parse_gcov_output.py
2 # Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
4 from __future__
import print_function
10 # the gcov report follows certain pattern. Each file will have two lines
11 # of report, from which we can extract the file name, total lines and coverage
13 def parse_gcov_report(gcov_input
):
14 per_file_coverage
= {}
17 for line
in sys
.stdin
:
20 # --First line of the coverage report (with file name in it)?
21 match_obj
= re
.match("^File '(.*)'$", line
)
23 # fetch the file name from the first line of the report.
24 current_file
= match_obj
.group(1)
27 # -- Second line of the file report (with coverage percentage)
28 match_obj
= re
.match("^Lines executed:(.*)% of (.*)", line
)
31 coverage
= float(match_obj
.group(1))
32 lines
= int(match_obj
.group(2))
34 if current_file
is not None:
35 per_file_coverage
[current_file
] = (coverage
, lines
)
38 # If current_file is not set, we reach the last line of report,
39 # which contains the summarized coverage percentage.
40 total_coverage
= (coverage
, lines
)
43 # If the line's pattern doesn't fall into the above categories. We
44 # can simply ignore them since they're either empty line or doesn't
45 # find executable lines of the given file.
48 return per_file_coverage
, total_coverage
50 def get_option_parser():
51 usage
= "Parse the gcov output and generate more human-readable code " +\
53 parser
= optparse
.OptionParser(usage
)
56 "--interested-files", "-i",
58 help="Comma separated files names. if specified, we will display " +
59 "the coverage report only for interested source files. " +
60 "Otherwise we will display the coverage report for all " +
65 def display_file_coverage(per_file_coverage
, total_coverage
):
66 # To print out auto-adjustable column, we need to know the longest
67 # length of file names.
68 max_file_name_length
= max(
69 len(fname
) for fname
in per_file_coverage
.keys()
73 # size of separator is determined by 3 column sizes:
74 # file name, coverage percentage and lines.
76 "%" + str(max_file_name_length
) + "s\t%s\t%s"
77 separator
= "-" * (max_file_name_length
+ 10 + 20)
78 print(header_template
% ("Filename", "Coverage", "Lines")) # noqa: E999 T25377293 Grandfathered in
82 # template for printing coverage report for each file.
83 record_template
= "%" + str(max_file_name_length
) + "s\t%5.2f%%\t%10d"
85 for fname
, coverage_info
in per_file_coverage
.items():
86 coverage
, lines
= coverage_info
87 print(record_template
% (fname
, coverage
, lines
))
92 print(record_template
% ("Total", total_coverage
[0], total_coverage
[1]))
94 def report_coverage():
95 parser
= get_option_parser()
96 (options
, args
) = parser
.parse_args()
98 interested_files
= set()
99 if options
.filenames
is not None:
100 interested_files
= set(f
.strip() for f
in options
.filenames
.split(','))
102 # To make things simple, right now we only read gcov report from the input
103 per_file_coverage
, total_coverage
= parse_gcov_report(sys
.stdin
)
105 # Check if we need to display coverage info for interested files.
106 if len(interested_files
):
107 per_file_coverage
= dict(
108 (fname
, per_file_coverage
[fname
]) for fname
in interested_files
109 if fname
in per_file_coverage
111 # If we only interested in several files, it makes no sense to report
113 total_coverage
= None
115 if not len(per_file_coverage
):
116 print("Cannot find coverage info for the given files.", file=sys
.stderr
)
118 display_file_coverage(per_file_coverage
, total_coverage
)
120 if __name__
== "__main__":