Skip to content

Commit 14fd9c4

Browse files
committed
src/regression_tracker: fix detection of individual job events
Until now the regression detection only worked for job submissions that include a tree of child nodes, and the results were only checked for the child nodes. This fixes the detection of failed jobs that are submitted without a hanging tree of nodes (kbuilds, kver, kunit tests). See #337 Signed-off-by: Ricardo Cañuelo <[email protected]>
1 parent b02e9dc commit 14fd9c4

File tree

1 file changed

+24
-5
lines changed

1 file changed

+24
-5
lines changed

src/regression_tracker.py

+24-5
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ def _stop(self, sub_id):
3131
if sub_id:
3232
self._api_helper.unsubscribe_filters(sub_id)
3333

34-
def _create_regression(self, failed_node, last_successful_node):
34+
def _create_regression(self, failed_node, last_pass_node):
3535
"""Method to create a regression"""
3636
regression = {}
3737
regression['kind'] = 'regression'
@@ -41,7 +41,7 @@ def _create_regression(self, failed_node, last_successful_node):
4141
regression['state'] = 'done'
4242
regression['data'] = {
4343
'fail_node': failed_node['id'],
44-
'pass_node': last_successful_node['id'],
44+
'pass_node': last_pass_node['id'],
4545
'arch': failed_node['data'].get('arch'),
4646
'defconfig': failed_node['data'].get('defconfig'),
4747
'compiler': failed_node['data'].get('compiler'),
@@ -53,7 +53,8 @@ def _create_regression(self, failed_node, last_successful_node):
5353
self.log.info(f"Regression submitted: {reg['id']}")
5454

5555
def _detect_regression(self, fail_node):
56-
"""Method to check and detect regression"""
56+
"""Detects if <fail_node> (a failed job) produces a regression,
57+
ie. if the previous job run with the same parameters passed"""
5758
previous_nodes = self._api.node.find({
5859
'name': fail_node['name'],
5960
'group': fail_node['group'],
@@ -81,7 +82,20 @@ def _detect_regression(self, fail_node):
8182
if previous_node['result'] == 'pass':
8283
self.log.info("Detected regression for node id: "
8384
f"{fail_node['id']}")
84-
self._create_regression(fail_node, previous_node)
85+
# Skip the regression generation if it was already in the
86+
# DB. This may happen if a job was detected to generate a
87+
# regression when it failed and then the same job was
88+
# checked again after its parent job finished running and
89+
# was updated.
90+
existing_regression = self._api.node.find({
91+
'kind': 'regression',
92+
'data.fail_node': fail_node['id'],
93+
'data.pass_node': previous_node['id']
94+
})
95+
if not existing_regression:
96+
self._create_regression(fail_node, previous_node)
97+
else:
98+
self.log.info(f"Skipping regression: already exists")
8599

86100
def _get_all_failed_child_nodes(self, failures, root_node):
87101
"""Method to get all failed nodes recursively from top-level node"""
@@ -92,14 +106,19 @@ def _get_all_failed_child_nodes(self, failures, root_node):
92106
self._get_all_failed_child_nodes(failures, node)
93107

94108
def _run(self, sub_id):
95-
"""Method to run regression tracking"""
109+
"""Method to run regression detection and generation"""
96110
self.log.info("Tracking regressions... ")
97111
self.log.info("Press Ctrl-C to stop.")
98112
sys.stdout.flush()
99113
while True:
100114
node = self._api_helper.receive_event_node(sub_id)
101115
if node['kind'] == 'checkout':
102116
continue
117+
if node['result'] == 'fail':
118+
self._detect_regression(node)
119+
# When a node hierarchy is submitted on a single operation,
120+
# an event is generated only for the root node. Walk the
121+
# children node tree to check for event-less failed jobs
103122
failures = []
104123
self._get_all_failed_child_nodes(failures, node)
105124
for node in failures:

0 commit comments

Comments
 (0)