Fixed newlines in github_ci_tool.py

This commit is contained in:
2025-06-02 18:41:03 -05:00
committed by GitHub
parent fdec4bac8e
commit e036d91b8f
+11 -32
View File
@@ -288,13 +288,7 @@ class GitHubCIHelper(BaseTool): # Inherits from BaseTool
# then a line of hyphens, "Traceback (most recent call last):", and the traceback details. # then a line of hyphens, "Traceback (most recent call last):", and the traceback details.
# It stops before the next failure block or common summary lines. # It stops before the next failure block or common summary lines.
failure_pattern = re.compile( failure_pattern = re.compile(
r"^(FAIL|ERROR): (.*?)\s*\\((.*?)\\)\s*\ r"^(FAIL|ERROR): (.*?)\s*\\((.*?)\\)\s*\n-{5,}\\s*\nTraceback \\(most recent call last\\):\\s*\n(.*?)(?=\n(?:FAIL:|ERROR:)|\n-{5,}\\s*\nRan \\d+ tests? in|\\Z)",
-{5,}\\s*\
Traceback \\(most recent call last\\):\\s*\
(.*?)(?=\
(?:FAIL:|ERROR:)|\
-{5,}\\s*\
Ran \\d+ tests? in|\\Z)",
re.DOTALL | re.MULTILINE re.DOTALL | re.MULTILINE
) )
@@ -307,12 +301,9 @@ Ran \\d+ tests? in|\\Z)",
# Reconstruct a readable failure block # Reconstruct a readable failure block
failure_block = ( failure_block = (
f"{failure_type}: {test_name} ({test_module_class})\ f"{failure_type}: {test_name} ({test_module_class})\n"
" f"---------------------\n"
f"---------------------\ f"Traceback (most recent call last):\n"
"
f"Traceback (most recent call last):\
"
f"{traceback_details}" f"{traceback_details}"
) )
failures.append(failure_block) failures.append(failure_block)
@@ -324,20 +315,14 @@ Ran \\d+ tests? in|\\Z)",
# Fallback: A more general pattern if the above doesn't match (e.g., due to slight variations in formatting) # Fallback: A more general pattern if the above doesn't match (e.g., due to slight variations in formatting)
# This looks for "FAIL:" or "ERROR:", a line for the test name, then captures content until common separators. # This looks for "FAIL:" or "ERROR:", a line for the test name, then captures content until common separators.
general_failure_pattern = re.compile( general_failure_pattern = re.compile(
r"^(FAIL|ERROR): ([^\ r"^(FAIL|ERROR): ([^\n]+)\n(.*?)(?=\n(?:FAIL:|ERROR:)|\n-{20,}\n|Ran \\d+ tests? in|\\Z)",
]+)\
(.*?)(?=\
(?:FAIL:|ERROR:)|\
-{20,}\
|Ran \\d+ tests? in|\\Z)",
re.DOTALL | re.MULTILINE re.DOTALL | re.MULTILINE
) )
for match in general_failure_pattern.finditer(log_content): for match in general_failure_pattern.finditer(log_content):
failure_type = match.group(1) failure_type = match.group(1)
test_header = match.group(2).strip() test_header = match.group(2).strip()
details = match.group(3).strip() details = match.group(3).strip()
full_block = f"{failure_type}: {test_header}\ full_block = f"{failure_type}: {test_header}\n{details}"
{details}"
# Avoid adding essentially duplicate or overly broad captures if specific ones exist # Avoid adding essentially duplicate or overly broad captures if specific ones exist
if not any(f.startswith(f"{failure_type}: {test_header}") for f in failures): if not any(f.startswith(f"{failure_type}: {test_header}") for f in failures):
failures.append(full_block) failures.append(full_block)
@@ -353,14 +338,12 @@ Ran \\d+ tests? in|\\Z)",
start_index = log_content.find(summary_marker) start_index = log_content.find(summary_marker)
if start_index != -1: if start_index != -1:
# Try to find a reasonable end for this summary block # Try to find a reasonable end for this summary block
end_pattern = re.compile(r"Ran \\d+ tests? in [\\d\\.]+s|\ end_pattern = re.compile(r"Ran \\d+ tests? in [\\d\\.]+s|\n-{70,}")
-{70,}")
end_match = end_pattern.search(log_content, start_index) end_match = end_pattern.search(log_content, start_index)
end_index = end_match.start() if end_match else len(log_content) end_index = end_match.start() if end_match else len(log_content)
failure_summary_block = log_content[start_index:end_index].strip() failure_summary_block = log_content[start_index:end_index].strip()
if failure_summary_block: if failure_summary_block:
failures.append(f"FAILURE SUMMARY BLOCK:\ failures.append(f"FAILURE SUMMARY BLOCK:\n{failure_summary_block}")
{failure_summary_block}")
self.logger.info("Captured a general failure summary block.") self.logger.info("Captured a general failure summary block.")
return failures return failures
@@ -400,19 +383,15 @@ if __name__ == "__main__":
if isinstance(log_content, str) and not log_content.startswith("Error") and not log_content.startswith("Job") and not log_content.startswith("Failed"): if isinstance(log_content, str) and not log_content.startswith("Error") and not log_content.startswith("Job") and not log_content.startswith("Failed"):
example_logger.info(f"Successfully downloaded logs (length: {len(log_content)} characters).") example_logger.info(f"Successfully downloaded logs (length: {len(log_content)} characters).")
example_logger.info("\ example_logger.info("\n--- Parsing unittest failures ---")
--- Parsing unittest failures ---")
failures = helper.parse_unittest_failures_from_log(log_content) failures = helper.parse_unittest_failures_from_log(log_content)
if failures: if failures:
for i, failure_details in enumerate(failures): for i, failure_details in enumerate(failures):
print(f"\ print(f"\nFailure {i+1}:\n{failure_details}")
Failure {i+1}:\
{failure_details}")
else: else:
print("No specific unittest failures parsed by the tool.") print("No specific unittest failures parsed by the tool.")
# Consider logging the beginning of the log if parsing fails, for debugging the regexes # Consider logging the beginning of the log if parsing fails, for debugging the regexes
# print(f"Log start:\ # print(f"Log start:\n{log_content[:2000]}")
{log_content[:2000]}")
elif log_content is None: elif log_content is None:
example_logger.error("Could not retrieve log content (returned None).") example_logger.error("Could not retrieve log content (returned None).")
else: # If it\'s an error message string from the function itself else: # If it\'s an error message string from the function itself