From 7e251cd0868aabf5a5234e2ff8c57e0d6f39e0c2 Mon Sep 17 00:00:00 2001 From: Denys Fedoryshchenko Date: Sat, 13 Jun 2026 15:13:03 +0300 Subject: [PATCH 1/2] Report infrastructure failures as KCIDB ERROR Use inherited Infrastructure error metadata when parsing test node status so nodes that were already marked fail by the runtime path still publish ERROR to KCIDB. This prevents infrastructure failures from being reported as test failures in KCIDB. This is a best-effort fix for the old discussion around issue #1087. I am not fully sure this is the correct final fix because that discussion happened a while ago and I do not remember all the details, so this should get maintainer review against the original failure modes. Signed-off-by: Denys Fedoryshchenko --- src/send_kcidb.py | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/src/send_kcidb.py b/src/send_kcidb.py index 92df54751..e87bb632a 100755 --- a/src/send_kcidb.py +++ b/src/send_kcidb.py @@ -412,9 +412,14 @@ def _parse_node_path(self, path, is_checkout_child): return formatted_path_str if formatted_path_str else None return None - def _parse_node_result(self, test_node): + def _parse_node_result(self, test_node, error_metadata=None): + error_code = test_node["data"].get("error_code") + if not error_code and error_metadata: + error_code = error_metadata.get("error_code") + if error_code == "Infrastructure": + return "ERROR" + if test_node["result"] == "incomplete": - error_code = test_node["data"].get("error_code") if error_code in ERRORED_TEST_CODES: return "ERROR" if error_code in MISSED_TEST_CODES: @@ -554,8 +559,14 @@ def _parse_test_node(self, origin, test_node): }, } + error_metadata = None + if test_node["result"] != "pass": + error_metadata = self._get_error_metadata(test_node) + if test_node["result"]: - parsed_test_node["status"] = self._parse_node_result(test_node) + parsed_test_node["status"] = self._parse_node_result( + test_node, error_metadata + ) if parsed_test_node["status"] == "SKIP": # No artifacts and metadata will be available for skipped tests return parsed_test_node, dummy_build @@ -590,15 +601,13 @@ def _parse_test_node(self, origin, test_node): if log_url: parsed_test_node["log_excerpt"] = self._get_log_excerpt(log_url) - if test_node["result"] != "pass": - error_metadata = self._get_error_metadata(test_node) - if error_metadata: - parsed_test_node["misc"]["error_code"] = error_metadata.get( - "error_code" - ) - parsed_test_node["misc"]["error_msg"] = error_metadata.get( - "error_msg" - ) + if error_metadata: + parsed_test_node["misc"]["error_code"] = error_metadata.get( + "error_code" + ) + parsed_test_node["misc"]["error_msg"] = error_metadata.get( + "error_msg" + ) return parsed_test_node, dummy_build From 8edc88e0d43e7ed96e0a587b906937f202c3e910 Mon Sep 17 00:00:00 2001 From: Denys Fedoryshchenko Date: Wed, 8 Jul 2026 00:19:31 +0300 Subject: [PATCH 2/2] send_kcidb: narrow inherited error_code use, skip metadata fetch for SKIP Address Copilot review feedback on PR #1513: - _parse_node_result() only used inherited error_metadata for detecting Infrastructure errors, but the fallback also leaked into the incomplete-result ERRORED_TEST_CODES/MISSED_TEST_CODES checks, changing classification for nodes that previously had no error_code of their own. Restrict inheritance to the Infrastructure check only. - _get_error_metadata() was being called (with its parent-node recursion) for every non-pass result, including nodes that end up SKIP and return before that metadata is ever used. Skip the fetch for skip results. Signed-off-by: Denys Fedoryshchenko --- src/send_kcidb.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/send_kcidb.py b/src/send_kcidb.py index e87bb632a..43910b22a 100755 --- a/src/send_kcidb.py +++ b/src/send_kcidb.py @@ -414,12 +414,19 @@ def _parse_node_path(self, path, is_checkout_child): def _parse_node_result(self, test_node, error_metadata=None): error_code = test_node["data"].get("error_code") + inherited_error_code = None if not error_code and error_metadata: - error_code = error_metadata.get("error_code") - if error_code == "Infrastructure": + inherited_error_code = error_metadata.get("error_code") + if ( + error_code == "Infrastructure" + or inherited_error_code == "Infrastructure" + ): return "ERROR" if test_node["result"] == "incomplete": + # Only the node's own error_code decides ERROR/MISS + # classification here, inherited error codes are only + # used above to detect Infrastructure errors. if error_code in ERRORED_TEST_CODES: return "ERROR" if error_code in MISSED_TEST_CODES: @@ -560,7 +567,7 @@ def _parse_test_node(self, origin, test_node): } error_metadata = None - if test_node["result"] != "pass": + if test_node["result"] not in ("pass", "skip"): error_metadata = self._get_error_metadata(test_node) if test_node["result"]: