diff --git a/common/log_parser/bbr/fwts/json_to_html.py b/common/log_parser/bbr/fwts/json_to_html.py index baf256ad..1602d695 100755 --- a/common/log_parser/bbr/fwts/json_to_html.py +++ b/common/log_parser/bbr/fwts/json_to_html.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2024-2025, Arm Limited or its affiliates. All rights reserved. +# Copyright (c) 2024-2026, Arm Limited or its affiliates. All rights reserved. # SPDX-License-Identifier : Apache-2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -281,11 +281,11 @@ def generate_html_fwts(suite_summary, test_results, chart_data, output_html_path {# Consolidate all reasons into one block #} {% set all_reasons = [] %} - {% if s.pass_reasons %}{% for reason in s.pass_reasons %}{% set _ = all_reasons.append(reason) %}{% endfor %}{% endif %} - {% if s.fail_reasons %}{% for reason in s.fail_reasons %}{% set _ = all_reasons.append(reason) %}{% endfor %}{% endif %} - {% if s.abort_reasons %}{% for reason in s.abort_reasons %}{% set _ = all_reasons.append(reason) %}{% endfor %}{% endif %} - {% if s.skip_reasons %}{% for reason in s.skip_reasons %}{% set _ = all_reasons.append(reason) %}{% endfor %}{% endif %} - {% if s.warning_reasons %}{% for reason in s.warning_reasons %}{% set _ = all_reasons.append(reason) %}{% endfor %}{% endif %} + {% if s.pass_reasons %}{% for reason in s.pass_reasons %}{% set _ = all_reasons.append("[PASSED] " ~ reason) %}{% endfor %}{% endif %} + {% if s.fail_reasons %}{% for reason in s.fail_reasons %}{% set _ = all_reasons.append("[FAILED] " ~ reason) %}{% endfor %}{% endif %} + {% if s.abort_reasons %}{% for reason in s.abort_reasons %}{% set _ = all_reasons.append("[ABORTED] " ~ reason) %}{% endfor %}{% endif %} + {% if s.skip_reasons %}{% for reason in s.skip_reasons %}{% set _ = all_reasons.append("[SKIPPED] " ~ reason) %}{% endfor %}{% endif %} + {% if s.warning_reasons %}{% for reason in s.warning_reasons %}{% set _ = all_reasons.append("[WARNING] " ~ reason) %}{% endfor %}{% endif %} {{ all_reasons|join("
") if all_reasons else "N/A" }} diff --git a/common/log_parser/bbr/fwts/logs_to_json.py b/common/log_parser/bbr/fwts/logs_to_json.py index d842cf5a..71bd69c4 100755 --- a/common/log_parser/bbr/fwts/logs_to_json.py +++ b/common/log_parser/bbr/fwts/logs_to_json.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2024-2025, Arm Limited or its affiliates. All rights reserved. +# Copyright (c) 2024-2026, Arm Limited or its affiliates. All rights reserved. # SPDX-License-Identifier : Apache-2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -48,6 +48,9 @@ def parse_fwts_log(log_path): "total_warnings": 0 } + def is_new_entry_line(text): + return bool(re.match(r"^(Test \d+ of \d+:|\w+:|PASSED\b|FAILED\b|SKIPPED\b|WARNING\b|ABORTED\b)", text)) + # First, identify all main tests from the "Running tests:" lines running_tests_started = False for line in log_data: @@ -153,7 +156,7 @@ def parse_fwts_log(log_path): while j < len(log_data): next_line = log_data[j].strip() # Break if next_line is empty or looks like the start of a new test/subtest entry - if not next_line or re.match(r"^(Test \d+ of \d+:|\w+:)", next_line): + if not next_line or is_new_entry_line(next_line): break reason_text += " " + next_line j += 1 @@ -170,7 +173,7 @@ def parse_fwts_log(log_path): while j < len(log_data): next_line = log_data[j].strip() # Stop if next_line is empty or looks like the start of a new test/subtest - if not next_line or re.match(r"^(Test \d+ of \d+:|\w+:)", next_line): + if not next_line or is_new_entry_line(next_line): break reason_text += " " + next_line j += 1 @@ -183,7 +186,7 @@ def parse_fwts_log(log_path): while j < len(log_data): next_line = log_data[j].strip() # Break if next_line is empty or looks like the start of a new test/subtest - if not next_line or re.match(r"^(Test \d+ of \d+:|\w+:)", next_line): + if not next_line or is_new_entry_line(next_line): break reason_text += " " + next_line j += 1 @@ -198,7 +201,7 @@ def parse_fwts_log(log_path): while j < len(log_data): next_line = log_data[j].strip() # Break if next_line is empty or looks like the start of a new test/subtest entry - if not next_line or re.match(r"^(Test \d+ of \d+:|\w+:)", next_line): + if not next_line or is_new_entry_line(next_line): break reason_text += " " + next_line j += 1 @@ -336,6 +339,20 @@ def parse_fwts_log(log_path): # Remove empty reason arrays from each subtest for sub in test["subtests"]: sub_res = sub["sub_test_result"] + # Mark subtests with no results as warnings for visibility + if ( + sub_res.get("PASSED", 0) == 0 + and sub_res.get("FAILED", 0) == 0 + and sub_res.get("ABORTED", 0) == 0 + and sub_res.get("SKIPPED", 0) == 0 + and sub_res.get("WARNINGS", 0) == 0 + ): + sub_res["WARNINGS"] = 1 + sub_res.setdefault("warning_reasons", []).append( + "No result found in log for this subtest." + ) + test["test_suite_summary"]["total_warnings"] += 1 + final_suite_summary["total_warnings"] += 1 # For each reason array, remove it if it's empty if not sub_res["pass_reasons"]: del sub_res["pass_reasons"]