Skip to content

Commit f3a4797

Browse files
committed
src: send_kcidb: process coverage-report nodes
Coverage report nodes are meant to provide global coverage percentages for a while `kbuild`, aggregating the results from individual test jobs. As such, they shouldn't be sent to KCIDB as nodes, but rather parsed in order to submit an updated build node which includes the functions/lines coverage percentages as misc fields. Add a new processing function for such nodes, which are of kind `process` and are named `coverage-report-<arch>`. Signed-off-by: Arnaud Ferraris <[email protected]>
1 parent f925646 commit f3a4797

File tree

1 file changed

+38
-0
lines changed

1 file changed

+38
-0
lines changed

src/send_kcidb.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -566,6 +566,41 @@ def _parse_test_node(self, origin, test_node):
566566

567567
return parsed_test_node, dummy_build
568568

569+
def _parse_coverage_node(self, origin, node):
570+
# Coverage report nodes are not sent to the DB themselves, but rather
571+
# parsed to submit an updated build node including the functions/lines
572+
# coverage percentages as misc fields.
573+
build_node = self._get_node_cached(node['parent'])
574+
# Coverage report nodes are also created for individual test jobs, the
575+
# results of which being only useful to the "top-level" (i.e. direct
576+
# child of the kbuild node) instance.
577+
if build_node['kind'] != 'kbuild':
578+
self.log.debug(f"{node['id']} is not a top-level coverage node, skipping")
579+
return []
580+
parsed_coverage_node = self._parse_build_node(origin, build_node)
581+
582+
# Add misc fields for coverage results
583+
child_nodes = self._api.node.find({'parent': node['id'], 'kind': 'test'})
584+
for child in child_nodes:
585+
if not child['name'].startswith('coverage.'):
586+
continue
587+
if 'misc' not in child['data'] or 'measurement' not in child['data']['misc']:
588+
self.log.warning(f"No measurement in node '{child['name']}' ({child['id']})")
589+
continue
590+
field_name = self._replace_restricted_chars(child['name'], r'^[a-zA-Z0-9_]*$')
591+
parsed_coverage_node['misc'][field] = child['data']['misc']['measurement']
592+
593+
# Add HTML coverage report to the build node's artifacts
594+
artifacts = node.get('artifacts')
595+
if artifacts:
596+
parsed_coverage_node['coverage_report_url'] = artifacts.get('coverage_report')
597+
parsed_coverage_node['coverage_log_url'] = artifacts.get('log')
598+
log_url = parsed_coverage_node['coverage_log_url']
599+
if log_url:
600+
parsed_coverage_node['coverage_log_excerpt'] = self._get_log_excerpt(log_url)
601+
602+
return [parsed_coverage_node]
603+
569604
def _get_test_data(self, node, origin,
570605
parsed_test_node, parsed_build_node):
571606
test_node, build_node = self._parse_test_node(
@@ -809,6 +844,9 @@ def _process_node(self, node, origin, is_hierarchy):
809844
elif node['kind'] == 'kbuild':
810845
parsed_data['build_node'] = self._parse_build_node(origin, node)
811846

847+
elif node['kind'] == 'process' and node['name'].startswith('coverage-report'):
848+
parsed_data['build_node'] = self._parse_coverage_node(origin, node)
849+
812850
elif node['kind'] in ['test', 'job']:
813851
self._get_test_data(node, origin, parsed_data['test_node'],
814852
parsed_data['build_node'])

0 commit comments

Comments
 (0)