Add per-spec fallback for categorized watcher grouped summaries
- update the categorized watcher to fall back to earlier per-spec Run Finished entries when a grouped Cloud Run Finished section is present but does not contain host rows - broaden duration parsing so colon-form timings like 13:59 and 15:32 from per-spec Cypress summaries are converted into seconds correctly - make grouped Mattermost posting resilient across categorized batches whose cloud-summary output is incomplete or inconsistent, not just a single distro family
This commit is contained in:
@@ -265,6 +265,14 @@ def extract_check_xml_timestamp_from_file(xml_path: Path) -> Optional[datetime]:
|
||||
|
||||
def parse_duration_seconds(raw: str) -> Optional[float]:
|
||||
raw = " ".join(raw.split())
|
||||
if re.fullmatch(r"\d+:\d+(?::\d+)?", raw):
|
||||
parts = [int(part) for part in raw.split(":")]
|
||||
if len(parts) == 2:
|
||||
minutes, seconds = parts
|
||||
return minutes * 60 + seconds
|
||||
if len(parts) == 3:
|
||||
hours, minutes, seconds = parts
|
||||
return hours * 3600 + minutes * 60 + seconds
|
||||
match = re.search(r"(?:(\d+)h\s+)?(?:(\d+)m\s+)?(\d+(?:\.\d+)?)(?:s)?", raw)
|
||||
if not match:
|
||||
return None
|
||||
@@ -274,6 +282,33 @@ def parse_duration_seconds(raw: str) -> Optional[float]:
|
||||
return hours * 3600 + minutes * 60 + seconds
|
||||
|
||||
|
||||
def extract_host_results_from_run_finished_segment(segment_text: str, inventory: Dict[str, str]) -> Dict[str, HostResult]:
|
||||
host_results: Dict[str, HostResult] = {}
|
||||
normalized = re.sub(r"\n\s*│\s*s\s*│", "s", segment_text)
|
||||
for host_match in re.finditer(
|
||||
r"✔\s+(atvm[^\s]+)\.ts\s+([0-9:hms.\s]+?)\s+(\d+)\s+(\d+)\s+([-\d]+)\s+([-\d]+)\s+([-\d]+)",
|
||||
normalized,
|
||||
re.S,
|
||||
):
|
||||
host = host_match.group(1)
|
||||
duration_seconds = parse_duration_seconds(host_match.group(2))
|
||||
tests = int(host_match.group(3))
|
||||
passing = int(host_match.group(4))
|
||||
failing = 0 if host_match.group(5) == "-" else int(host_match.group(5))
|
||||
detail = f"{tests} tests, {failing} failures"
|
||||
status = "FAIL" if failing else "PASS"
|
||||
host_results[host] = HostResult(
|
||||
host=host,
|
||||
kernel=inventory.get(host, "unknown"),
|
||||
status=status,
|
||||
detail=detail,
|
||||
tests=tests,
|
||||
failures=failing,
|
||||
duration_seconds=duration_seconds,
|
||||
)
|
||||
return host_results
|
||||
|
||||
|
||||
def extract_completed_subrun_summaries(log_text: str, inventory: Dict[str, str]) -> List[Dict[str, object]]:
|
||||
summaries: List[Dict[str, object]] = []
|
||||
cloud_blocks = list(
|
||||
@@ -283,33 +318,16 @@ def extract_completed_subrun_summaries(log_text: str, inventory: Dict[str, str])
|
||||
re.S,
|
||||
)
|
||||
)
|
||||
previous_block_end = 0
|
||||
for block in cloud_blocks:
|
||||
block_text = block.group(1)
|
||||
currents_url = block.group(2)
|
||||
normalized = re.sub(r"\n\s*│\s*s\s*│", "s", block_text)
|
||||
host_results: Dict[str, HostResult] = {}
|
||||
for host_match in re.finditer(
|
||||
r"✔\s+(atvm[^\s]+)\.ts\s+([0-9hms.\s]+?)\s+(\d+)\s+(\d+)\s+([-\d]+)\s+([-\d]+)\s+([-\d]+)",
|
||||
normalized,
|
||||
re.S,
|
||||
):
|
||||
host = host_match.group(1)
|
||||
duration_seconds = parse_duration_seconds(host_match.group(2))
|
||||
tests = int(host_match.group(3))
|
||||
passing = int(host_match.group(4))
|
||||
failing = 0 if host_match.group(5) == "-" else int(host_match.group(5))
|
||||
detail = f"{tests} tests, {failing} failures"
|
||||
status = "FAIL" if failing else "PASS"
|
||||
host_results[host] = HostResult(
|
||||
host=host,
|
||||
kernel=inventory.get(host, "unknown"),
|
||||
status=status,
|
||||
detail=detail,
|
||||
tests=tests,
|
||||
failures=failing,
|
||||
duration_seconds=duration_seconds,
|
||||
)
|
||||
host_results = extract_host_results_from_run_finished_segment(block_text, inventory)
|
||||
if not host_results:
|
||||
prior_segment = log_text[previous_block_end:block.start()]
|
||||
host_results = extract_host_results_from_run_finished_segment(prior_segment, inventory)
|
||||
if not host_results:
|
||||
previous_block_end = block.end()
|
||||
continue
|
||||
summaries.append(
|
||||
{
|
||||
@@ -317,6 +335,7 @@ def extract_completed_subrun_summaries(log_text: str, inventory: Dict[str, str])
|
||||
"currents_url": currents_url,
|
||||
}
|
||||
)
|
||||
previous_block_end = block.end()
|
||||
return summaries
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user