d55c2d7a2c
* many files had no license comments at all * some files had license comments suggesting that they weren't open source (like a terse "all rights reserved") when they actually are open source. * all our files are licensed under apache and should be marked as such
267 lines
7.6 KiB
Bash
Executable File
267 lines
7.6 KiB
Bash
Executable File
#!/bin/bash
|
|
#
|
|
# Copyright 2011 Google Inc.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
#
|
|
# A helper for running gcov on all of the project sources.
|
|
# Usage:
|
|
# gcov-all.sh (--prepare | --summarize) path
|
|
#
|
|
# where path is the same location where one runs make
|
|
#
|
|
# There are two modes:
|
|
# --prepare cleans up all the .gcda files. This should be done
|
|
# before running the test, as we need an accurate set of these
|
|
# to know which object files to include in the executable.
|
|
# It also effectively zeroes all the measurements, preventing
|
|
# different runs from getting added together.
|
|
#
|
|
# --summarize goes through the produced files, runs gcov on
|
|
# them, producing the gcov-summary.html and the gcov/ directory
|
|
# with individual dumps
|
|
#
|
|
# Glossary:
|
|
# .gcno file: produced by gcc during compilation, along with the
|
|
# corresponding .o file
|
|
# .gcda file: produced when an instrumented application is run
|
|
# (or .so is loaded), and then at its exit. Contains
|
|
# the actual measurements.
|
|
#
|
|
# To invoke gcov, we need to pass it in a list of all the source
|
|
# files we want coverage information for, as well as the directory
|
|
# to look into for the corresponding .gcno/.gcda files. The
|
|
# summarize mode collects these based on the .gcda files that exist.
|
|
#
|
|
# TODO(morlovich): evaluate lcov as an option? Its output looks nice.
|
|
|
|
function summarize {
|
|
WORKDIR=`mktemp -d`
|
|
SRCDIR=`pwd`
|
|
OUTNAME=gcov-summary.html
|
|
|
|
echo "Collecting all object and profile data into:" $WORKDIR
|
|
|
|
# Here, we look for the .gcda files, and the .o and .gcno that go with them.
|
|
# This is because they get generated for any object files that gets linked in,
|
|
# as soon as the executable/module are initialized, giving us an accurate
|
|
# picture of what should be checked
|
|
|
|
GCDAS=`find ./out/Debug_Coverage -name '*.gcda'`
|
|
DATA=
|
|
for F in $GCDAS
|
|
do
|
|
BASE=${F%.gcda}
|
|
GCNO=$BASE.gcno
|
|
O=$BASE.o
|
|
if [ ! -f $GCNO ]; then
|
|
echo "WARNING: can't find " $GCNO
|
|
continue
|
|
fi
|
|
|
|
if [ ! -f $O ]; then
|
|
echo "WARNING: can't find " $O
|
|
continue
|
|
fi
|
|
|
|
DATA+=" $F $GCNO $O"
|
|
done
|
|
|
|
cp $DATA $WORKDIR/
|
|
|
|
echo "Generating gcov summary into file://"$PWD/$OUTNAME
|
|
|
|
# Collect relevant sources. For each one, we check if we have the
|
|
# gcda (which means we have gcno, too). We want this for two reasons:
|
|
#
|
|
# 1) We only want coverage for a file if the gcda is there
|
|
# 2) gcov has a bug that screws up output if some files' .gcno
|
|
# does not exist (see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35568)
|
|
#
|
|
# TODO(morlovich): worry about duplicate names!
|
|
SOURCES=`find -L $SRCDIR/net $SRCDIR/pagespeed -name '*.cc' -or -name '*.c'`
|
|
|
|
FILTERED_SOURCES=
|
|
for F in $SOURCES
|
|
do
|
|
GCDA=`basename $F .c`
|
|
GCDA=$WORKDIR/`basename $GCDA .cc`.gcda
|
|
if [ -f $GCDA ]; then
|
|
if [ $F == ${F/.svn/marker/} ]; then
|
|
FILTERED_SOURCES="$FILTERED_SOURCES $GCDA"
|
|
fi
|
|
fi
|
|
done
|
|
htmlDriver > $OUTNAME
|
|
echo "<pre id='data' style='display:none'>" >> $OUTNAME
|
|
gcov -o $WORKDIR $FILTERED_SOURCES >> $OUTNAME
|
|
echo "</pre>" >> $OUTNAME
|
|
|
|
echo "Moving all the .gcov files to gcov subdir (after wiping it)"
|
|
rm -rf $SRCDIR/gcov
|
|
mkdir $SRCDIR/gcov
|
|
mv *.gcov $SRCDIR/gcov
|
|
|
|
echo "Cleaning up..."
|
|
rm -r $WORKDIR
|
|
}
|
|
|
|
# This outputs the html driver that visualizes the results
|
|
function htmlDriver {
|
|
cat <<TEMPLATE_END
|
|
<!DOCTYPE html>
|
|
<head>
|
|
<script>
|
|
// Computes a color for given goodness percentage. (Using CSS3 hsl syntax)
|
|
function percentColor(percent) {
|
|
var hue = (percent / 100 * 120).toFixed(0);
|
|
return 'hsl(' + hue + ', 100%, 50%)';
|
|
}
|
|
|
|
// Adds a row with given DOM for the file info and given coverage
|
|
// percentage to the provided table section, giving it the appropriate color
|
|
function addResultRow(tsection, fileInfo, percent) {
|
|
var row = tsection.insertRow(-1);
|
|
row.style.backgroundColor = percentColor(percent);
|
|
|
|
var fileNameCell = row.insertCell(-1);
|
|
fileNameCell.appendChild(fileInfo);
|
|
|
|
var percentCell = row.insertCell(-1);
|
|
percentCell.align = 'right';
|
|
percentCell.appendChild(document.createTextNode(percent.toFixed(2) + '%'));
|
|
}
|
|
|
|
// Adds a result for given filename and coverage percentage to the first body
|
|
// of the table with id 'outTable'
|
|
function addFileResultRow(fileName, percent) {
|
|
var table = document.getElementById('outTable');
|
|
var tbody = table.tBodies[0];
|
|
|
|
// We want a link to the .gcov file here
|
|
var a = document.createElement('a');
|
|
a.appendChild(document.createTextNode(fileName));
|
|
|
|
var fragments = fileName.split('/');
|
|
a.setAttribute('href', 'gcov/' + fragments[fragments.length - 1] + '.gcov');
|
|
|
|
addResultRow(tbody, a, percent);
|
|
}
|
|
|
|
function addSummaryResultRow(summary, percent) {
|
|
var table = document.getElementById('outTable');
|
|
var tfoot = table.tFoot;
|
|
|
|
addResultRow(tfoot, document.createTextNode(summary), percent);
|
|
}
|
|
|
|
function prettifySummary() {
|
|
// Get the raw data from the <pre id='data'>
|
|
var preNode = document.getElementById('data');
|
|
var txt = (preNode.textContent ? preNode.textContent : preNode.innerText);
|
|
var allLines = txt.split('\n');
|
|
|
|
var currentFile;
|
|
|
|
// Collect file names, percentages, and lines
|
|
var allFiles = []; // array of name, coverage %, lines pairs
|
|
for (var i = 0; i < allLines.length; ++i) {
|
|
var line = allLines[i];
|
|
var fileInfo = /File '(.*)'/.exec(line);
|
|
if (fileInfo) {
|
|
currentFile = fileInfo[1];
|
|
// get rid of ./ if needed.
|
|
if (currentFile.substring(0, 2) == './') {
|
|
currentFile = currentFile.substring(2);
|
|
}
|
|
}
|
|
|
|
var linesInfo = /Lines executed:(.*)% of (\d+)/.exec(line);
|
|
if (linesInfo) {
|
|
allFiles.push([currentFile, Number(linesInfo[1]), Number(linesInfo[2])]);
|
|
}
|
|
|
|
if (/No executable lines/.exec(line)) {
|
|
allFiles.push([currentFile, 0, 0]);
|
|
}
|
|
}
|
|
|
|
// Sort by filename
|
|
allFiles.sort(function(a, b) {
|
|
if (a[0] < b[0]) {
|
|
return -1;
|
|
} else if (a[0] == b[0]) {
|
|
return 0;
|
|
} else {
|
|
return 1;
|
|
}
|
|
});
|
|
|
|
// Append all results we want to table, coloring by coverage; and also compute
|
|
// an overall number (which may include a few things we don't care about)
|
|
var totalLines = 0;
|
|
var totalCovered = 0;
|
|
for (var i = 0; i < allFiles.length; ++i) {
|
|
var fileName = allFiles[i][0];
|
|
var percent = allFiles[i][1];
|
|
var lines = allFiles[i][2];
|
|
|
|
// Skip paths -- we don't need coverage information for system headers
|
|
if (fileName.charAt(0) == '/') {
|
|
continue;
|
|
}
|
|
|
|
totalLines += lines;
|
|
totalCovered += Math.round(lines * percent / 100);
|
|
|
|
addFileResultRow(fileName, percent);
|
|
}
|
|
|
|
addSummaryResultRow('Total (' + totalCovered + '/' + totalLines +')',
|
|
totalCovered / totalLines * 100);
|
|
}
|
|
</script>
|
|
</head>
|
|
<body onload="prettifySummary()">
|
|
<table id="outTable">
|
|
<thead>
|
|
<tr><th>File name</th><th>Coverage percentage</th></tr>
|
|
</thead>
|
|
<tbody></tbody>
|
|
<tfoot style="font-weight:bold; "></tfoot>
|
|
</table>
|
|
TEMPLATE_END
|
|
}
|
|
|
|
function usage {
|
|
echo "Usage:" $0 "(--prepare | --summarize) path"
|
|
}
|
|
|
|
if [ -z $2 ]; then
|
|
usage
|
|
exit
|
|
fi
|
|
|
|
cd $2
|
|
|
|
case $1 in
|
|
--prepare)
|
|
echo "Removing old .gcda files"
|
|
find $2/out/Debug_Coverage -name '*.gcda' -delete;;
|
|
--summarize)
|
|
summarize;;
|
|
*)
|
|
usage;;
|
|
esac
|
|
|