twister: Support --coverage-formats on lcov also

When using twister to generate coverage with the coverage tool lcov,
allow using --coverage-formats to pick if you want lcov or html,
defaulting to both. Picking html will also use lcov, since that is
required for geninfo.  This will allow callers to avoid the potentially
slow and disk intensive html reports if they only wanted the lcov info
file.

Signed-off-by: Jeremy Bettis <jbettis@google.com>
This commit is contained in:
Jeremy Bettis 2023-06-09 12:12:27 -06:00 committed by Anas Nashif
commit d72c4344ed
2 changed files with 9 additions and 10 deletions

View file

@ -102,6 +102,7 @@ class CoverageTool:
if ret == 0: if ret == 0:
report_log = { report_log = {
"html": "HTML report generated: {}".format(os.path.join(outdir, "coverage", "index.html")), "html": "HTML report generated: {}".format(os.path.join(outdir, "coverage", "index.html")),
"lcov": "LCOV report generated: {}".format(os.path.join(outdir, "coverage.info")),
"xml": "XML report generated: {}".format(os.path.join(outdir, "coverage", "coverage.xml")), "xml": "XML report generated: {}".format(os.path.join(outdir, "coverage", "coverage.xml")),
"csv": "CSV report generated: {}".format(os.path.join(outdir, "coverage", "coverage.csv")), "csv": "CSV report generated: {}".format(os.path.join(outdir, "coverage", "coverage.csv")),
"txt": "TXT report generated: {}".format(os.path.join(outdir, "coverage", "coverage.txt")), "txt": "TXT report generated: {}".format(os.path.join(outdir, "coverage", "coverage.txt")),
@ -117,6 +118,7 @@ class Lcov(CoverageTool):
def __init__(self): def __init__(self):
super().__init__() super().__init__()
self.ignores = [] self.ignores = []
self.output_formats = "lcov,html"
def add_ignore_file(self, pattern): def add_ignore_file(self, pattern):
self.ignores.append('*' + pattern + '*') self.ignores.append('*' + pattern + '*')
@ -159,6 +161,9 @@ class Lcov(CoverageTool):
coveragefile, "--rc", "lcov_branch_coverage=1"], coveragefile, "--rc", "lcov_branch_coverage=1"],
stdout=coveragelog) stdout=coveragelog)
if 'html' not in self.output_formats.split(','):
return 0
# The --ignore-errors source option is added to avoid it exiting due to # The --ignore-errors source option is added to avoid it exiting due to
# samples/application_development/external_lib/ # samples/application_development/external_lib/
return subprocess.call(["genhtml", "--legend", "--branch-coverage", return subprocess.call(["genhtml", "--legend", "--branch-coverage",
@ -173,6 +178,7 @@ class Gcovr(CoverageTool):
def __init__(self): def __init__(self):
super().__init__() super().__init__()
self.ignores = [] self.ignores = []
self.output_formats = "html"
def add_ignore_file(self, pattern): def add_ignore_file(self, pattern):
self.ignores.append('.*' + pattern + '.*') self.ignores.append('.*' + pattern + '.*')
@ -269,9 +275,8 @@ def run_coverage(testplan, options):
coverage_tool.gcov_tool = options.gcov_tool coverage_tool.gcov_tool = options.gcov_tool
coverage_tool.base_dir = os.path.abspath(options.coverage_basedir) coverage_tool.base_dir = os.path.abspath(options.coverage_basedir)
# Apply output format default # Apply output format default
if options.coverage_formats is None: if options.coverage_formats is not None:
options.coverage_formats = "html" coverage_tool.output_formats = options.coverage_formats
coverage_tool.output_formats = options.coverage_formats
coverage_tool.add_ignore_file('generated') coverage_tool.add_ignore_file('generated')
coverage_tool.add_ignore_directory('tests') coverage_tool.add_ignore_directory('tests')
coverage_tool.add_ignore_directory('samples') coverage_tool.add_ignore_directory('samples')

View file

@ -299,9 +299,8 @@ structure in the main Zephyr tree: boards/<arch>/<board_name>/""")
parser.add_argument("--coverage-formats", action="store", default=None, # default behavior is set in run_coverage parser.add_argument("--coverage-formats", action="store", default=None, # default behavior is set in run_coverage
help="Output formats to use for generated coverage reports, as a comma-separated list. " help="Output formats to use for generated coverage reports, as a comma-separated list. "
"Only used in conjunction with gcovr. "
"Default to html. " "Default to html. "
"Valid options are html, xml, csv, txt, coveralls, sonarqube.") "Valid options are html, xml, csv, txt, coveralls, sonarqube, lcov.")
parser.add_argument("--test-config", action="store", default=os.path.join(ZEPHYR_BASE, "tests", "test_config.yaml"), parser.add_argument("--test-config", action="store", default=os.path.join(ZEPHYR_BASE, "tests", "test_config.yaml"),
help="Path to file with plans and test configurations.") help="Path to file with plans and test configurations.")
@ -741,11 +740,6 @@ def parse_arguments(parser, args, options = None):
logger.error("--shuffle-tests-seed requires --shuffle-tests") logger.error("--shuffle-tests-seed requires --shuffle-tests")
sys.exit(1) sys.exit(1)
if options.coverage_formats and (options.coverage_tool != "gcovr"):
logger.error("""--coverage-formats can only be used when coverage
tool is set to gcovr""")
sys.exit(1)
if options.size: if options.size:
from twisterlib.size_calc import SizeCalculator from twisterlib.size_calc import SizeCalculator
for fn in options.size: for fn in options.size: