Skip to content
This repository has been archived by the owner on Apr 17, 2019. It is now read-only.

Coverage: remove function signature lines that are never report as hit #2156

Open
wants to merge 2 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .jenkinsci-new/build.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ def initialCoverage(String buildDir) {

def postCoverage(buildDir, String cobertura_bin) {
sh "cmake --build ${buildDir} --target coverage.info"
sh "python ${cobertura_bin} ${buildDir}/reports/coverage.info -o ${buildDir}/reports/coverage.xml"
sh "python .jenkinsci-new/helpers/remove-function-lines.py ${buildDir}/reports/coverage.info ${buildDir}/reports/cleaned-coverage.info"
sh "python ${cobertura_bin} ${buildDir}/reports/cleaned-coverage.info -o ${buildDir}/reports/coverage.xml"
cobertura autoUpdateHealth: false, autoUpdateStability: false,
coberturaReportFile: "**/${buildDir}/reports/coverage.xml", conditionalCoverageTargets: '75, 50, 0',
failUnhealthy: false, failUnstable: false, lineCoverageTargets: '75, 50, 0', maxNumberOfBuilds: 50,
Expand Down
48 changes: 48 additions & 0 deletions .jenkinsci-new/helpers/remove-function-lines.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#!/usr/bin/env python3

# https://github.com/JeremyAgost/lcov-llvm-function-mishit-filter
# https://github.com/linux-test-project/lcov/issues/30

import argparse
import subprocess

def demangle(symbol):
p = subprocess.Popen(['c++filt','-n'], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
Copy link
Contributor

@BulatSaif BulatSaif Mar 13, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Coverage almost always runs at gcc5, but it possible to run coverage at any other compiler
with Custom command:
ex. parameters to run build:

custom_cmd: x64linux_compiler_list = ['clang7']; coverage = true

or on mac:

custom_cmd: x64linux_compiler_list = []; mac_compiler_list = ['appleclang']; coverage = true

This python code looks simple and hope it won't fail on mac, also until now nobody used coverage at mac

return p.communicate(input=symbol.encode())[0].decode().strip()

def filter_lcov(lines, verbose=False):
defs, srcfile = {}, ''
for line in lines:
if line.startswith('SF:'):
defs = {}
srcfile = line[3:].strip()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this line can be placed behind if verbose

elif line.startswith('end_of_record'):
defs = {}
elif line.startswith('FN:'):
lineno, symbol = line[3:].split(',')
if verbose:
defs[lineno] = demangle(symbol)
else:
defs[lineno] = True
elif line.startswith('DA:'):
lineno = line[3:].split(',')[0]
if lineno in defs:
if verbose:
printf('Ignoring: {srcfile}:{lineno}:{defs[lineno]}')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does this work? I see such syntax for the first time and did not find any docs on such printf function.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this did not work on my setup. I suggest removing verbose stuff: srcfile, demangle, printf, cli arg, etc. because we do not use it and it is bogous.

continue
yield line

def main():
p = argparse.ArgumentParser()
p.add_argument('input', type=str)
p.add_argument('output', type=str)
p.add_argument('--verbose', '-v', action='store_true')
args = p.parse_args()
with open(args.input, 'r') as fin:
lines = list(fin)
with open(args.output, 'w') as fout:
for line in filter_lcov(lines, verbose=args.verbose):
fout.write(line)

if __name__ == '__main__':
main()