scripts: twister: get status of coverage data processing

Do not break processing when incorrect coverage data are received.
Instead, report failures but still process valid data.

Include coverage processing status within twister retrun code.

Signed-off-by: Piotr Kosycarz <piotr.kosycarz@nordicsemi.no>
This commit is contained in:
Piotr Kosycarz 2023-10-11 21:14:12 +02:00 committed by Carles Cufí
commit 8c5a15aac4
2 changed files with 28 additions and 6 deletions

View file

@ -71,6 +71,7 @@ class CoverageTool:
@staticmethod
def create_gcda_files(extracted_coverage_info):
gcda_created = True
logger.debug("Generating gcda files")
for filename, hexdump_val in extracted_coverage_info.items():
# if kobject_hash is given for coverage gcovr fails
@ -83,19 +84,33 @@ class CoverageTool:
pass
continue
with open(filename, 'wb') as fp:
fp.write(bytes.fromhex(hexdump_val))
try:
with open(filename, 'wb') as fp:
fp.write(bytes.fromhex(hexdump_val))
except ValueError:
logger.exception("Unable to convert hex data for file: {}".format(filename))
gcda_created = False
except FileNotFoundError:
logger.exception("Unable to create gcda file: {}".format(filename))
gcda_created = False
return gcda_created
def generate(self, outdir):
coverage_completed = True
for filename in glob.glob("%s/**/handler.log" % outdir, recursive=True):
gcov_data = self.__class__.retrieve_gcov_data(filename)
capture_complete = gcov_data['complete']
extracted_coverage_info = gcov_data['data']
if capture_complete:
self.__class__.create_gcda_files(extracted_coverage_info)
logger.debug("Gcov data captured: {}".format(filename))
gcda_created = self.__class__.create_gcda_files(extracted_coverage_info)
if gcda_created:
logger.debug("Gcov data captured: {}".format(filename))
else:
logger.error("Gcov data invalid for: {}".format(filename))
coverage_completed = False
else:
logger.error("Gcov data capture incomplete: {}".format(filename))
coverage_completed = False
with open(os.path.join(outdir, "coverage.log"), "a") as coveragelog:
ret = self._generate(outdir, coveragelog)
@ -111,6 +126,10 @@ class CoverageTool:
}
for r in self.output_formats.split(','):
logger.info(report_log[r])
else:
coverage_completed = False
logger.debug("All coverage data processed: {}".format(coverage_completed))
return coverage_completed
class Lcov(CoverageTool):
@ -280,4 +299,5 @@ def run_coverage(testplan, options):
coverage_tool.add_ignore_file('generated')
coverage_tool.add_ignore_directory('tests')
coverage_tool.add_ignore_directory('samples')
coverage_tool.generate(options.outdir)
coverage_completed = coverage_tool.generate(options.outdir)
return coverage_completed

View file

@ -207,9 +207,10 @@ def main(options):
report.summary(runner.results, options.disable_unrecognized_section_test, duration)
coverage_completed = True
if options.coverage:
if not options.build_only:
run_coverage(tplan, options)
coverage_completed = run_coverage(tplan, options)
else:
logger.info("Skipping coverage report generation due to --build-only.")
@ -235,6 +236,7 @@ def main(options):
runner.results.failed
or runner.results.error
or (tplan.warnings and options.warnings_as_errors)
or (options.coverage and not coverage_completed)
):
return 1