summaryrefslogtreecommitdiffstats
path: root/WebKitTools/CodeCoverage/regenerate-coverage-display
diff options
context:
space:
mode:
Diffstat (limited to 'WebKitTools/CodeCoverage/regenerate-coverage-display')
-rw-r--r--WebKitTools/CodeCoverage/regenerate-coverage-display408
1 files changed, 0 insertions, 408 deletions
diff --git a/WebKitTools/CodeCoverage/regenerate-coverage-display b/WebKitTools/CodeCoverage/regenerate-coverage-display
deleted file mode 100644
index 9139c9a..0000000
--- a/WebKitTools/CodeCoverage/regenerate-coverage-display
+++ /dev/null
@@ -1,408 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright (C) 2004, 2005, 2006 Nathaniel Smith
-# Copyright (C) 2007 Holger Hans Peter Freyther
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-#
-# 1. Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# 2. Redistributions in binary form must reproduce the above copyright
-# notice, this list of conditions and the following disclaimer in the
-# documentation and/or other materials provided with the distribution.
-# 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
-# its contributors may be used to endorse or promote products derived
-# from this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
-# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-# DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
-# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#
-# HTML output inspired by the output of lcov as found on the GStreamer
-# site. I assume this is not copyrightable.
-#
-
-
-#
-# Read all CSV files and
-# Create an overview file
-#
-#
-
-
-import sys
-import csv
-import glob
-import time
-import os
-import os.path
-import datetime
-import shutil
-
-os.environ["TTFPATH"] = ":".join(["/usr/share/fonts/truetype/" + d
- for d in "ttf-bitstream-vera",
- "freefont",
- "msttcorefonts"])
-import matplotlib
-matplotlib.use("Agg")
-import matplotlib.pylab as m
-
-level_LOW = 10
-level_MEDIUM = 70
-
-def copy_files(dest_dir):
- """
- Copy the CSS and the png's to the destination directory
- """
- images = ["amber.png", "emerald.png", "glass.png", "ruby.png", "snow.png"]
- css = "gcov.css"
- (base_path, name) = os.path.split(__file__)
- base_path = os.path.abspath(base_path)
-
- shutil.copyfile(os.path.join(base_path,css), os.path.join(dest_dir,css))
- map(lambda x: shutil.copyfile(os.path.join(base_path,x), os.path.join(dest_dir,x)), images)
-
-def sumcov(cov):
- return "%.2f%% (%s/%s)" % (cov[1] * 100.0 / (cov[0] or 1), cov[1], cov[0])
-
-def create_page(dest_dir, name):
- index = open(os.path.join(dest_dir, name), "w")
- index.write("""<HTML>
- <HEAD>
- <TITLE>WebKit test coverage information</TITLE>
- <link rel="stylesheet" type="text/css" href="gcov.css">
- </HEAD>
- <BODY>
- """)
- return index
-
-def generate_header(file, last_time, total_lines, total_executed, path, image):
- product = "WebKit"
- date = time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime(last_time))
- covered_lines = sumcov((total_lines, total_executed))
-
- file.write("""<table width="100%%" border=0 cellspacing=0 cellpadding=0>
- <tr><td class="title">GCOV code coverage report</td></tr>
- <tr><td class="ruler"><img src="glass.png" width=3 height=3 alt=""></td></tr>
-
- <tr>
- <td width="100%%">
- <table cellpadding=1 border=0 width="100%%">
- <tr>
- <td class="headerItem" width="20%%">Current&nbsp;view:</td>
- <td class="headerValue" width="80%%" colspan=4>%(path)s</td>
- </tr>
- <tr>
- <td class="headerItem" width="20%%">Test:</td>
- <td class="headerValue" width="80%%" colspan=4>%(product)s</td>
- </tr>
- <tr>
- <td class="headerItem" width="20%%">Date:</td>
- <td class="headerValue" width="20%%">%(date)s</td>
- <td width="20%%"></td>
- <td class="headerItem" width="20%%">Instrumented&nbsp;lines:</td>
- <td class="headerValue" width="20%%">%(total_lines)s</td>
- </tr>
- <tr>
- <td class="headerItem" width="20%%">Code&nbsp;covered:</td>
- <td class="headerValue" width="20%%">%(covered_lines)s</td>
- <td width="20%%"></td>
- <td class="headerItem" width="20%%">Executed&nbsp;lines:</td>
- <td class="headerValue" width="20%%">%(total_executed)s</td>
- </tr>
- </table>
- </td>
- </tr>
- <tr><td class="ruler"><img src="glass.png" width=3 height=3 alt=""></td></tr>
- </table>""" % vars())
- # disabled for now <tr><td><img src="%(image)s"></td></tr>
-
-def generate_table_item(file, name, total_lines, covered_lines):
- covered_precise = (covered_lines*100.0)/(total_lines or 1.0)
- covered = int(round(covered_precise))
- remainder = 100-covered
- (image,perClass,numClass) = coverage_icon(covered_precise)
- site = "%s.html" % name.replace(os.path.sep,'__')
- file.write("""
- <tr>
- <td class="coverFile"><a href="%(site)s">%(name)s</a></td>
- <td class="coverBar" align="center">
- <table border=0 cellspacing=0 cellpadding=1><tr><td class="coverBarOutline"><img src="%(image)s" width=%(covered)s height=10 alt="%(covered_precise).2f"><img src="snow.png" width=%(remainder)s height=10 alt="%(covered_precise).2f"></td></tr></table>
- </td>
- <td class="%(perClass)s">%(covered_precise).2f&nbsp;%%</td>
- <td class="%(numClass)s">%(covered_lines)s&nbsp;/&nbsp;%(total_lines)s&nbsp;lines</td>
- </tr>
- """ % vars())
-
-def generate_table_header_start(file):
- file.write("""<center>
- <table width="80%%" cellpadding=2 cellspacing=1 border=0>
-
- <tr>
- <td width="50%%"><br></td>
- <td width="15%%"></td>
- <td width="15%%"></td>
- <td width="20%%"></td>
- </tr>
-
- <tr>
- <td class="tableHead">Directory&nbsp;name</td>
- <td class="tableHead" colspan=3>Coverage</td>
- </tr>
- """)
-
-def coverage_icon(percent):
- if percent < level_LOW:
- return ("ruby.png", "coverPerLo", "coverNumLo")
- elif percent < level_MEDIUM:
- return ("amber.png", "coverPerMed", "coverNumMed")
- else:
- return ("emerald.png", "coverPerHi", "coverNumHi")
-
-def replace(text, *pairs):
- """
- From pydoc... almost identical at least
- """
- from string import split, join
- while pairs:
- (a,b) = pairs[0]
- text = join(split(text, a), b)
- pairs = pairs[1:]
- return text
-
-def escape(text):
- """
- Escape string to be conform HTML
- """
- return replace(text,
- ('&', '&amp;'),
- ('<', '&lt;' ),
- ('>', '&gt;' ) )
-
-def generate_table_header_end(file):
- file.write("""</table>
- </center>""")
-
-def write_title_page(dest_dir,plot_files, last_time, last_tot_lines, last_tot_covered, dir_series):
- """
- Write the index.html with a overview of each directory
- """
- index= create_page(dest_dir, "index.html")
- generate_header(index, last_time, last_tot_lines, last_tot_covered, "directory", "images/Total.png")
- # Create the directory overview
- generate_table_header_start(index)
- dirs = dir_series.keys()
- dirs.sort()
- for dir in dirs:
- (dir_files, total_lines, covered_lines,_) = dir_series[dir][-1]
- generate_table_item(index, dir, total_lines, covered_lines)
- generate_table_header_end(index)
-
- index.write("""</BODY></HTML>""")
- index.close()
-
-def write_directory_site(dest_dir, plot_files, dir_name, last_time, dir_series, file_series):
- escaped_dir = dir_name.replace(os.path.sep,'__')
- site = create_page(dest_dir, "%s.html" % escaped_dir)
- (_,tot_lines,tot_covered,files) = dir_series[dir_name][-1]
- generate_header(site, last_time, tot_lines, tot_covered, "directory - %s" % dir_name, "images/%s.png" % escaped_dir)
-
- files.sort()
-
- generate_table_header_start(site)
- for file in files:
- (lines,covered) = file_series[file][-1]
- generate_table_item(site, file, lines, covered)
-
- generate_table_header_end(site)
- site.write("""</BODY></HTML>""")
- site.close()
-
-def write_file_site(dest_dir, plot_files, file_name, last_time, data_dir, last_id, file_series):
- escaped_name = file_name.replace(os.path.sep,'__')
- site = create_page(dest_dir, "%s.html" % escaped_name)
- (tot_lines,tot_covered) = file_series[file_name][-1]
- generate_header(site, last_time, tot_lines, tot_covered, "file - %s" % file_name, "images/%s.png" % escaped_name)
-
- path = "%s/%s.annotated%s" % (data_dir,last_id,file_name)
-
- # In contrast to the lcov we want to show files that have been compiled
- # but have not been tested at all. This means we have sourcefiles with 0
- # lines covered in the path but they are not lcov files.
- # To identify them we check the first line now. If we see that we can
- # continue
- # -: 0:Source:
- try:
- file = open(path, "r")
- except:
- return
- all_lines = file.read().split("\n")
-
- # Convert the gcov file to HTML if we have a chanche to do so
- # Scan each line and see if it was covered or not and escape the
- # text
- if len(all_lines) == 0 or not "-: 0:Source:" in all_lines[0]:
- site.write("<p>The file was not excercised</p>")
- else:
- site.write("""</br><table cellpadding=0 cellspacing=0 border=0>
- <tr>
- <td><br></td>
- </tr>
- <tr>
- <td><pre class="source">
- """)
- for line in all_lines:
- split_line = line.split(':',2)
- # e.g. at the EOF
- if len(split_line) == 1:
- continue
- line_number = split_line[1].strip()
- if line_number == "0":
- continue
- covered = 15*" "
- end = ""
- if "#####" in split_line[0]:
- covered = '<span class="lineNoCov">%15s' % "0"
- end = "</span>"
- elif split_line[0].strip() != "-":
- covered = '<span class="lineCov">%15s' % split_line[0].strip()
- end = "</span>"
-
- escaped_line = escape(split_line[2])
- str = '<span class="lineNum">%(line_number)10s </span>%(covered)s: %(escaped_line)s%(end)s\n' % vars()
- site.write(str)
- site.write("</pre></td></tr></table>")
- site.write("</BODY></HTML>")
- site.close()
-
-def main(progname, args):
- if len(args) != 2:
- sys.exit("Usage: %s DATADIR OUTDIR" % progname)
-
- branch = "WebKit from trunk"
- datadir, outdir = args
-
- # First, load in all data from the data directory.
- data = []
- for datapath in glob.glob(os.path.join(datadir, "*.csv")):
- data.append(read_csv(datapath))
- # Sort by time
- data.sort()
-
- # Calculate time series for each file.
- times = [sample[0] for sample in data]
- times = [datetime.datetime.utcfromtimestamp(t) for t in times]
- times = m.date2num(times)
- all_files = {}
- all_dirs = {}
- for sample in data:
- t, i, tot_line, tot_cover, per_file, per_dir = sample
- all_files.update(per_file)
- all_dirs.update(per_dir)
- total_series = []
- file_serieses = dict([[k, [(0, 0)] * len(times)] for k in all_files.keys()])
- dir_serieses = dict([[k, [(0, 0, 0, [])] * len(times)] for k in all_dirs.keys()])
- data_idx = 0
- for sample in data:
- t, i, tot_line, tot_cover, per_file, per_dir = sample
- total_series.append([tot_line, tot_cover])
- for f, covinfo in per_file.items():
- file_serieses[f][data_idx] = covinfo
- for f, covinfo in per_dir.items():
- dir_serieses[f][data_idx] = covinfo
- data_idx += 1
-
-
- # Okay, ready to start outputting. First make sure our directories
- # exist.
- if not os.path.exists(outdir):
- os.makedirs(outdir)
- rel_imgdir = "images"
- imgdir = os.path.join(outdir, rel_imgdir)
- if not os.path.exists(imgdir):
- os.makedirs(imgdir)
-
- # Now plot the actual graphs
- plot_files = {}
- #plot_files["Total"] = plot_coverage(times, total_series, imgdir, "Total")
- #for dir, series in dir_serieses.items():
- # plot_files[dir] = plot_coverage(times, map(lambda (a,b,c,d):(b,c), series), imgdir, dir)
- #for f, series in file_serieses.items():
- # plot_files[f] = plot_coverage(times, series, imgdir, f)
-
- # And look up the latest revision id, and coverage information
- last_time, last_id, last_tot_lines, last_tot_covered = data[-1][:4]
-
- # Now start generating our html file
- copy_files(outdir)
- write_title_page(outdir, plot_files, last_time, last_tot_lines, last_tot_covered, dir_serieses)
-
- dir_keys = dir_serieses.keys()
- dir_keys.sort()
- for dir_name in dir_keys:
- write_directory_site(outdir, plot_files, dir_name, last_time, dir_serieses, file_serieses)
-
- file_keys = file_serieses.keys()
- for file_name in file_keys:
- write_file_site(outdir, plot_files, file_name, last_time, datadir, last_id, file_serieses)
-
-def read_csv(path):
- r = csv.reader(open(path, "r"))
- # First line is id, time
- for row in r:
- id, time_str = row
- break
- time = int(float(time_str))
- # Rest of lines are path, total_lines, covered_lines
- per_file = {}
- per_dir = {}
- grand_total_lines, grand_covered_lines = 0, 0
- for row in r:
- path, total_lines_str, covered_lines_str = row
- total_lines = int(total_lines_str)
- covered_lines = int(covered_lines_str)
- grand_total_lines += total_lines
- grand_covered_lines += covered_lines
- per_file[path] = [total_lines, covered_lines]
-
- # Update dir statistics
- dirname = os.path.dirname(path)
- if not dirname in per_dir:
- per_dir[dirname] = (0,0,0,[])
- (dir_files,dir_total_lines,dir_covered_lines, files) = per_dir[dirname]
- dir_files += 1
- dir_total_lines += total_lines
- dir_covered_lines += covered_lines
- files.append(path)
- per_dir[dirname] = (dir_files,dir_total_lines,dir_covered_lines,files)
- return [time, id, grand_total_lines, grand_covered_lines, per_file, per_dir]
-
-
-def plot_coverage(times, series, imgdir, name):
- percentages = [cov * 100.0 / (tot or 1) for tot, cov in series]
- m.plot_date(times, percentages, "b-")
- m.plot_date(times, percentages, "bo")
- m.title(name)
- m.ylim(0, 100)
- m.xlabel("Date")
- m.ylabel("Statement Coverage (%)")
- outfile_base = name.replace("/", "__") + ".png"
- outfile = os.path.join(imgdir, outfile_base)
- m.savefig(outfile, dpi=75)
- m.close()
- return outfile_base
-
-
-if __name__ == "__main__":
- import sys
- main(sys.argv[0], sys.argv[1:])