diff --git a/utils/check-coverage-regressions.py b/utils/check-coverage-regressions.py deleted file mode 100755 index 4f239a303d7..00000000000 --- a/utils/check-coverage-regressions.py +++ /dev/null @@ -1,139 +0,0 @@ -#!/usr/bin/env python - -'''Compare two coverage summaries for regressions. - -You can create a coverage summary by using the `llvm-cov report` command. -Alternatively, you can use `utils/prepare-code-coverage-artifact.py` which -creates summaries as well as file-based html reports. -''' - -from __future__ import print_function - -import argparse -import collections -import re -import sys - -# This threshold must be in [0, 1]. The lower the threshold, the less likely -# it is that a regression will be flagged and vice versa. -kThresh = 1.0 - -FileCoverage = collections.namedtuple('FileCoverage', - ['Regions', 'MissedRegions', 'RegionCoverage', - 'Functions', 'MissedFunctions', 'Executed', - 'Lines', 'MissedLines', 'LineCoverage']) - -CoverageEntry = re.compile(r'^(.*)' - r' +(\d+) +(\d+) +([\d.]+)%' - r' +(\d+) +(\d+) +([\d.]+)%' - r' +(\d+) +(\d+) +([\d.]+)%$') - -def parse_file_coverage_line(line): - '''Parse @line as a summary of a file's coverage information. - - >>> parse_file_coverage_line('report.cpp 5 2 60.00% 4 1 75.00% 13 4 69.23%') - ('report.cpp', FileCoverage(\ -Regions=5, MissedRegions=2, RegionCoverage=60.0, \ -Functions=4, MissedFunctions=1, Executed=75.0, \ -Lines=13, MissedLines=4, LineCoverage=69.23)) - ''' - - m = re.match(CoverageEntry, line) - if not m: - print("Could not read coverage summary:", line) - exit(1) - - groups = m.groups() - filename = groups[0].strip() - regions = int(groups[1]) - missed_regions = int(groups[2]) - region_coverage = float(groups[3]) - functions = int(groups[4]) - missed_functions = int(groups[5]) - executed = float(groups[6]) - lines = int(groups[7]) - missed_lines = int(groups[8]) - line_coverage = float(groups[9]) - return (filename, - FileCoverage(regions, missed_regions, region_coverage, - functions, missed_functions, executed, - lines, missed_lines, line_coverage)) - -def parse_summary(path): - '''Parse the summary at @path. Return a dictionary mapping filenames to - FileCoverage instances.''' - - with open(path, 'r') as f: - lines = f.readlines() - - # Drop the header and the cell dividers. Include "TOTAL" in this list. - file_coverages = lines[2:-2] + [lines[-1]] - - summary = {} - for line in file_coverages: - filename, fc = parse_file_coverage_line(line) - summary[filename] = fc - return summary - -def find_coverage_regressions(old_coverage, new_coverage): - '''Given two coverage summaries, generate coverage regressions of the form: - (filename, old FileCoverage, new FileCoverage).''' - - for filename in old_coverage.keys(): - if filename not in new_coverage: - continue - - old_fc = old_coverage[filename] - new_fc = new_coverage[filename] - if new_fc.RegionCoverage < kThresh * old_fc.RegionCoverage or \ - new_fc.Executed < kThresh * old_fc.Executed: - yield (filename, old_fc, new_fc) - -def print_regression(filename, old_fc, new_fc): - '''Pretty-print a coverage regression in @filename. @old_fc is the old - FileCoverage and @new_fc is the new one. - - >>> print_regression('foo.cpp', \ - FileCoverage(10, 5, 50.0, 10, 10, 0, 20, 10, 50.0), \ - FileCoverage(10, 7, 30.0, 10, 10, 0, 20, 14, 30.0)) - Code coverage regression: - File: foo.cpp - Change in function coverage: 0.00% (0/10 -> 0/10) - Change in line coverage : -20.00% (10/20 -> 6/20) - Change in region coverage : -20.00% (5/10 -> 3/10) - ''' - - func_coverage_delta = new_fc.Executed - old_fc.Executed - line_coverage_delta = new_fc.LineCoverage - old_fc.LineCoverage - region_coverage_delta = new_fc.RegionCoverage - old_fc.RegionCoverage - print("Code coverage regression:") - print(" File:", filename) - print(" Change in function coverage: {0:.2f}% ({1}/{2} -> {3}/{4})".format( - func_coverage_delta, old_fc.Functions - old_fc.MissedFunctions, - old_fc.Functions, new_fc.Functions - new_fc.MissedFunctions, - new_fc.Functions)) - print(" Change in line coverage : {0:.2f}% ({1}/{2} -> {3}/{4})".format( - line_coverage_delta, old_fc.Lines - old_fc.MissedLines, old_fc.Lines, - new_fc.Lines - new_fc.MissedLines, new_fc.Lines)) - print(" Change in region coverage : {0:.2f}% ({1}/{2} -> {3}/{4})".format( - region_coverage_delta, old_fc.Regions - old_fc.MissedRegions, - old_fc.Regions, new_fc.Regions - new_fc.MissedRegions, new_fc.Regions)) - -if __name__ == '__main__': - parser = argparse.ArgumentParser(description=__doc__) - parser.add_argument('old_summary', help='Path to the old coverage summary') - parser.add_argument('new_summary', help='Path to the new coverage summary') - args = parser.parse_args() - - old_coverage = parse_summary(args.old_summary) - new_coverage = parse_summary(args.new_summary) - - num_regressions = 0 - for filename, old_fc, new_fc in \ - find_coverage_regressions(old_coverage, new_coverage): - print_regression(filename, old_fc, new_fc) - num_regressions += 1 - - if num_regressions > 0: - exit(1) - exit(0)