Revision d4ad32d7bd908d0b065c04ed697c5c157cd4512d authored by Maysam Yabandeh on 13 July 2018, 00:19:57 UTC, committed by Facebook Github Bot on 13 July 2018, 00:27:31 UTC
Summary:
BlockIter is getting crowded including details that specific only to either index or data blocks. The patch moves down such details to DataBlockIter and IndexBlockIter, both inheriting from BlockIter.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/4121

Differential Revision: D8816832

Pulled By: maysamyabandeh

fbshipit-source-id: d492e74155c11d8a0c1c85cd7ee33d24c7456197
1 parent 6390443
Raw File
parse_gcov_output.py
import re
import sys

from optparse import OptionParser

# the gcov report follows certain pattern. Each file will have two lines
# of report, from which we can extract the file name, total lines and coverage
# percentage.
def parse_gcov_report(gcov_input):
    per_file_coverage = {}
    total_coverage = None

    for line in sys.stdin:
        line = line.strip()

        # --First line of the coverage report (with file name in it)?
        match_obj = re.match("^File '(.*)'$", line)
        if match_obj:
            # fetch the file name from the first line of the report.
            current_file = match_obj.group(1)
            continue

        # -- Second line of the file report (with coverage percentage)
        match_obj = re.match("^Lines executed:(.*)% of (.*)", line)

        if match_obj:
            coverage = float(match_obj.group(1))
            lines = int(match_obj.group(2))

            if current_file is not None:
                per_file_coverage[current_file] = (coverage, lines)
                current_file = None
            else:
                # If current_file is not set, we reach the last line of report,
                # which contains the summarized coverage percentage.
                total_coverage = (coverage, lines)
            continue

        # If the line's pattern doesn't fall into the above categories. We
        # can simply ignore them since they're either empty line or doesn't
        # find executable lines of the given file.
        current_file = None

    return per_file_coverage, total_coverage

def get_option_parser():
    usage = "Parse the gcov output and generate more human-readable code " +\
            "coverage report."
    parser = OptionParser(usage)

    parser.add_option(
        "--interested-files", "-i",
        dest="filenames",
        help="Comma separated files names. if specified, we will display " +
             "the coverage report only for interested source files. " +
             "Otherwise we will display the coverage report for all " +
             "source files."
    )
    return parser

def display_file_coverage(per_file_coverage, total_coverage):
    # To print out auto-adjustable column, we need to know the longest
    # length of file names.
    max_file_name_length = max(
        len(fname) for fname in per_file_coverage.keys()
    )

    # -- Print header
    # size of separator is determined by 3 column sizes:
    # file name, coverage percentage and lines.
    header_template = \
        "%" + str(max_file_name_length) + "s\t%s\t%s"
    separator = "-" * (max_file_name_length + 10 + 20)
    print header_template % ("Filename", "Coverage", "Lines")  # noqa: E999 T25377293 Grandfathered in
    print separator

    # -- Print body
    # template for printing coverage report for each file.
    record_template = "%" + str(max_file_name_length) + "s\t%5.2f%%\t%10d"

    for fname, coverage_info in per_file_coverage.items():
        coverage, lines = coverage_info
        print record_template % (fname, coverage, lines)

    # -- Print footer
    if total_coverage:
        print separator
        print record_template % ("Total", total_coverage[0], total_coverage[1])

def report_coverage():
    parser = get_option_parser()
    (options, args) = parser.parse_args()

    interested_files = set()
    if options.filenames is not None:
        interested_files = set(f.strip() for f in options.filenames.split(','))

    # To make things simple, right now we only read gcov report from the input
    per_file_coverage, total_coverage = parse_gcov_report(sys.stdin)

    # Check if we need to display coverage info for interested files.
    if len(interested_files):
        per_file_coverage = dict(
            (fname, per_file_coverage[fname]) for fname in interested_files
            if fname in per_file_coverage
        )
        # If we only interested in several files, it makes no sense to report
        # the total_coverage
        total_coverage = None

    if not len(per_file_coverage):
        print >> sys.stderr, "Cannot find coverage info for the given files."
        return
    display_file_coverage(per_file_coverage, total_coverage)

if __name__ == "__main__":
    report_coverage()
back to top