Skip to content

Commit c8bc974

Browse files
committed
Add checksum support to py2lcov, perl2lcov
Signed-off-by: Henry Cox <[email protected]>
1 parent 21685cc commit c8bc974

File tree

5 files changed

+72
-13
lines changed

5 files changed

+72
-13
lines changed

bin/perl2lcov

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,11 @@ foreach my $db (@ARGV) {
192192
"unable to process $file without statement data");
193193
next;
194194
}
195+
if ($lcovutil::verify_checksum &&
196+
!-f $file) {
197+
lcovutil::ignorable_error($lcovutil::ERROR_SOURCE,
198+
"cannot read '$f': unable to compute --checksum");
199+
}
195200
my $version = lcovutil::extractFileVersion($file) if -f $file;
196201
$fileData->version($version) if defined($version) && $version ne '';
197202

@@ -321,7 +326,7 @@ foreach my $db (@ARGV) {
321326

322327
$info->applyFilters();
323328
$info->add_comments(@lcovutil::comments);
324-
$info->write_info_file($output_file);
329+
$info->write_info_file($output_file, $lcovutil::verify_checksum);
325330

326331
lcovutil::warn_file_patterns();
327332
lcovutil::summarize_cov_filters();

bin/py2lcov

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,14 @@ import xml.etree.ElementTree as ET
4444
import fnmatch
4545
import subprocess
4646
import copy
47+
import base64
48+
import hashlib
49+
50+
def line_hash(line: str) -> str:
51+
"""Produce a hash of a source line for use in the LCOV file."""
52+
hashed = hashlib.md5(line.encode("utf-8")).digest()
53+
return base64.b64encode(hashed).decode("ascii").rstrip("=")
54+
4755

4856
class ProcessFile:
4957
def __init__(self, scriptArgs):
@@ -344,7 +352,16 @@ class ProcessFile:
344352
self._outf.write("FN:%(start)d,%(end)d,%(name)s\nFNDA:%(hit)d,%(name)s\n" % f)
345353
# print the LCOV line data.
346354
for lineNo in sorted(lineData.keys()):
347-
self._outf.write("DA:%d,%d\n" % (lineNo, lineData[lineNo]));
355+
checksum = ''
356+
if self._args.checksum:
357+
try:
358+
checksum = ',' + line_hash(lines[lineNo])
359+
except IndexError as err:
360+
print('"%s":%d: unable to compute checksum for missing line' % (filename, lineNo))
361+
if not self._args.keepGoing:
362+
raise(err)
363+
364+
self._outf.write("DA:%d,%d%s\n" % (lineNo, lineData[lineNo], checksum));
348365

349366
# print the LCOV totals - not used by lcov, but maybe somebody does
350367
for key in totals:
@@ -406,6 +423,9 @@ Example:
406423
help="print debug messages")
407424
parser.add_argument('--version-script', dest='version',
408425
help="version extract callback")
426+
parser.add_argument('--checksum', dest='checksum', action='store_true',
427+
default=False,
428+
help="compute line checksum - see 'man lcov'")
409429
parser.add_argument("--no-functions", dest='deriveFunctions',
410430
default=True, action='store_false',
411431
help="do not derive function coverpoints")

lib/lcovutil.pm

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6584,15 +6584,15 @@ sub _read_info
65846584
}
65856585

65866586
# Store line checksum if available
6587-
if (defined($checksum)) {
6587+
if (defined($checksum) &&
6588+
$lcovutil::verify_checksum) {
65886589
# Does it match a previous definition
65896590
if ($fileData->check()->mapped($line) &&
65906591
($fileData->check()->value($line) ne $checksum)) {
65916592
lcovutil::ignorable_error($lcovutil::ERROR_VERSION,
65926593
"checksum mismatch at $filename:$line in $tracefile"
65936594
);
65946595
}
6595-
65966596
$fileData->check()->replace($line, $checksum);
65976597
}
65986598
last;
@@ -6898,14 +6898,8 @@ sub write_info($$$)
68986898
print(INFO_HANDLE "VER:" . $entry->version() . "\n")
68996899
if defined($entry->version());
69006900
if (defined($srcReader)) {
6901-
$srcReader->close();
6902-
if (is_c_file($source_file)) {
6903-
lcovutil::info(1,
6904-
"reading $source_file for lcov checksum\n");
6905-
$srcReader->open($source_file);
6906-
} else {
6907-
lcovutil::debug("not reading $source_file: no ext match\n");
6908-
}
6901+
lcovutil::info(1, "reading $source_file for lcov checksum\n");
6902+
$srcReader->open($source_file);
69096903
}
69106904

69116905
my $functionMap = $testfncdata->{$testname};
@@ -7010,7 +7004,8 @@ sub write_info($$$)
70107004
if ($verify_checksum) {
70117005
if (exists($checkdata->{$line})) {
70127006
$chk = $checkdata->{$line};
7013-
} elsif (defined($srcReader)) {
7007+
} elsif (defined($srcReader) &&
7008+
$srcReader->notEmpty()) {
70147009
my $content = $srcReader->getLine($line);
70157010
$chk = Digest::MD5::md5_base64($content);
70167011
}

tests/perl2lcov/perltest1.sh

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,25 @@ if [ "$G" != 'FN:6,8,global1' ] ; then
138138
exit 1
139139
fi
140140

141+
# run again, collecting checksum..
142+
$COVER ${EXEC_COVER} $PERL2LCOV_TOOL --output checksum.info --testname testCheck ./cover_one --checksum
143+
if [ 0 != $? ] ; then
144+
echo "perl2lcov checksum failed"
145+
fi
146+
147+
# do we see the checksums we expect?
148+
# expect to see checksum on each DA line..
149+
for l in `grep -E '^DA:' checksum.info` ; do
150+
echo $l | grep -E 'DA:[0-9]+,[0-9]+,.+'
151+
if [ 0 != $? ] ; then
152+
echo "no checksum in '$l'"
153+
if [ 0 == $KEEP_GOING ] ; then
154+
exit 1
155+
fi
156+
fi
157+
done
158+
159+
141160
$COVER ${EXEC_COVER} $PERL2LCOV_TOOL --help
142161
if [ 0 != $? ] ; then
143162
echo "perl2lcov help failed"

tests/py2lcov/py2lcov.sh

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,26 @@ if [ 0 != $? ] ; then
221221
fi
222222
fi
223223

224+
# run again, generating checksum data...
225+
eval ${PYCOV} ${PY2LCOV_TOOL} -o checksum.info functions.dat $VERSION --checksum
226+
if [ 0 != $? ] ; then
227+
echo "py2lcov failed function example"
228+
if [ 0 == $KEEP_GOING ] ; then
229+
exit 1
230+
fi
231+
fi
232+
233+
# expect to see checksum on each DA line..
234+
for l in `grep -E '^DA:' checksum.info` ; do
235+
echo $l | grep -E 'DA:[0-9]+,[0-9]+,.+'
236+
if [ 0 != $? ] ; then
237+
echo "no checksum in '$l'"
238+
if [ 0 == $KEEP_GOING ] ; then
239+
exit 1
240+
fi
241+
fi
242+
done
243+
224244
# run without generating function data:
225245
eval ${PYCOV} ${PY2LCOV_TOOL} functions.dat -o no_functions.info $VERSION --no-function
226246
if [ 0 != $? ] ; then

0 commit comments

Comments
 (0)