diff --git a/poetry.lock b/poetry.lock index f0329c1..54a71a0 100644 --- a/poetry.lock +++ b/poetry.lock @@ -29,7 +29,7 @@ pydantic-xml = "^2.11.0" type = "git" url = "https://github.com/asam-ev/qc-baselib-py.git" reference = "develop" -resolved_reference = "f7ea664805bcce456ebd0ede93c852dd389c1944" +resolved_reference = "8ed36cb58c8994b9674f7c6ea74992dacb65bdaf" [[package]] name = "black" @@ -316,13 +316,13 @@ files = [ [[package]] name = "platformdirs" -version = "4.3.2" +version = "4.3.3" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." optional = false python-versions = ">=3.8" files = [ - {file = "platformdirs-4.3.2-py3-none-any.whl", hash = "sha256:eb1c8582560b34ed4ba105009a4badf7f6f85768b30126f351328507b2beb617"}, - {file = "platformdirs-4.3.2.tar.gz", hash = "sha256:9e5e27a08aa095dd127b9f2e764d74254f482fef22b0970773bfba79d091ab8c"}, + {file = "platformdirs-4.3.3-py3-none-any.whl", hash = "sha256:50a5450e2e84f44539718293cbb1da0a0885c9d14adf21b77bae4e66fc99d9b5"}, + {file = "platformdirs-4.3.3.tar.gz", hash = "sha256:d4e0b7d8ec176b341fb03cb11ca12d0276faa8c485f9cd218f613840463fc2c0"}, ] [package.extras] diff --git a/qc_openscenario/checks/data_type_checker/non_negative_transition_time_in_light_state_action.py b/qc_openscenario/checks/data_type_checker/non_negative_transition_time_in_light_state_action.py index dce5958..9093c59 100644 --- a/qc_openscenario/checks/data_type_checker/non_negative_transition_time_in_light_state_action.py +++ b/qc_openscenario/checks/data_type_checker/non_negative_transition_time_in_light_state_action.py @@ -75,16 +75,18 @@ def check_rule(checker_data: models.CheckerData) -> None: logging.debug(f"current_transition_time: {current_transition_time}") if not utils.is_xsd_double(current_transition_time): - logging.error( - f"Cannot convert '{current_transition_time}' to double as it does not match xsd:double pattern. Skipping check..." - ) - checker_data.result.set_checker_status( checker_bundle_name=constants.BUNDLE_NAME, checker_id=CHECKER_ID, status=StatusType.SKIPPED, ) + checker_data.result.add_checker_summary( + constants.BUNDLE_NAME, + CHECKER_ID, + f"Cannot convert '{current_transition_time}' to double as it does not match xsd:double pattern. Skip the check.", + ) + return current_numeric_value = utils.to_float(current_transition_time) diff --git a/qc_openscenario/checks/data_type_checker/positive_duration_in_phase.py b/qc_openscenario/checks/data_type_checker/positive_duration_in_phase.py index 8fb66f8..5ab263c 100644 --- a/qc_openscenario/checks/data_type_checker/positive_duration_in_phase.py +++ b/qc_openscenario/checks/data_type_checker/positive_duration_in_phase.py @@ -62,16 +62,18 @@ def check_rule(checker_data: models.CheckerData) -> None: current_duration = current_duration_param_value if not utils.is_xsd_double(current_duration): - logging.error( - f"Cannot convert '{current_duration}' to double as it does not match xsd:double pattern. Skipping check..." - ) - checker_data.result.set_checker_status( checker_bundle_name=constants.BUNDLE_NAME, checker_id=CHECKER_ID, status=StatusType.SKIPPED, ) + checker_data.result.add_checker_summary( + constants.BUNDLE_NAME, + CHECKER_ID, + f"Cannot convert '{current_duration}' to double as it does not match xsd:double pattern. Skip the check.", + ) + return current_numeric_value = utils.to_float(current_duration) diff --git a/qc_openscenario/checks/parameters_checker/valid_parameter_declaration_in_catalogs.py b/qc_openscenario/checks/parameters_checker/valid_parameter_declaration_in_catalogs.py index afc70f7..88d58e4 100644 --- a/qc_openscenario/checks/parameters_checker/valid_parameter_declaration_in_catalogs.py +++ b/qc_openscenario/checks/parameters_checker/valid_parameter_declaration_in_catalogs.py @@ -44,6 +44,12 @@ def check_rule(checker_data: models.CheckerData) -> None: status=StatusType.SKIPPED, ) + checker_data.result.add_checker_summary( + constants.BUNDLE_NAME, + CHECKER_ID, + "Cannot find Catalog nodes in provided XOSC file. Skip the check.", + ) + return logging.debug(f"catalogs_node : {catalogs_node}") diff --git a/qc_openscenario/checks/reference_checker/resolvable_entity_references.py b/qc_openscenario/checks/reference_checker/resolvable_entity_references.py index 4a8be5a..9d799c7 100644 --- a/qc_openscenario/checks/reference_checker/resolvable_entity_references.py +++ b/qc_openscenario/checks/reference_checker/resolvable_entity_references.py @@ -33,13 +33,18 @@ def check_rule(checker_data: models.CheckerData) -> None: entities_node = root.find("Entities") if entities_node is None: - logging.error("Cannot find Entities node in provided XOSC file. Skipping check") - checker_data.result.set_checker_status( checker_bundle_name=constants.BUNDLE_NAME, checker_id=CHECKER_ID, status=StatusType.SKIPPED, ) + + checker_data.result.add_checker_summary( + constants.BUNDLE_NAME, + CHECKER_ID, + "Cannot find Entities node in provided XOSC file. Skip the check.", + ) + return defined_entities = set() @@ -51,15 +56,18 @@ def check_rule(checker_data: models.CheckerData) -> None: logging.debug(f"Defined entities : {defined_entities}") storyboard_node = root.find("Storyboard") if storyboard_node is None: - logging.error( - "Cannot find Storyboard node in provided XOSC file. Skipping check" - ) - checker_data.result.set_checker_status( checker_bundle_name=constants.BUNDLE_NAME, checker_id=CHECKER_ID, status=StatusType.SKIPPED, ) + + checker_data.result.add_checker_summary( + constants.BUNDLE_NAME, + CHECKER_ID, + "Cannot find Storyboard node in provided XOSC file. Skip the check.", + ) + return nodes_with_entity_ref = storyboard_node.xpath(".//*[@entityRef]") diff --git a/qc_openscenario/checks/reference_checker/resolvable_signal_id_in_traffic_signal_state_action.py b/qc_openscenario/checks/reference_checker/resolvable_signal_id_in_traffic_signal_state_action.py index 6fc5935..a0e58ae 100644 --- a/qc_openscenario/checks/reference_checker/resolvable_signal_id_in_traffic_signal_state_action.py +++ b/qc_openscenario/checks/reference_checker/resolvable_signal_id_in_traffic_signal_state_action.py @@ -32,23 +32,35 @@ def check_rule(checker_data: models.CheckerData) -> None: root = checker_data.input_file_xml_root if checker_data.xodr_root is None: - logging.error(f" - Cannot read xodr file. Abort") checker_data.result.set_checker_status( checker_bundle_name=constants.BUNDLE_NAME, checker_id=CHECKER_ID, status=StatusType.SKIPPED, ) + + checker_data.result.add_checker_summary( + constants.BUNDLE_NAME, + CHECKER_ID, + "Cannot read xodr file. Skip the check.", + ) + return xodr_signal_list = checker_data.xodr_root.findall(".//signal") if xodr_signal_list is None: - logging.error(f" - Cannot read signals from xodr file. Abort") checker_data.result.set_checker_status( checker_bundle_name=constants.BUNDLE_NAME, checker_id=CHECKER_ID, status=StatusType.SKIPPED, ) + + checker_data.result.add_checker_summary( + constants.BUNDLE_NAME, + CHECKER_ID, + "Cannot read signals from xodr file. Skip the check.", + ) + return xodr_signal_ids = set() diff --git a/qc_openscenario/checks/reference_checker/resolvable_storyboard_element_reference.py b/qc_openscenario/checks/reference_checker/resolvable_storyboard_element_reference.py index c0ff15d..f411076 100644 --- a/qc_openscenario/checks/reference_checker/resolvable_storyboard_element_reference.py +++ b/qc_openscenario/checks/reference_checker/resolvable_storyboard_element_reference.py @@ -39,27 +39,34 @@ def check_rule(checker_data: models.CheckerData) -> None: storyboard_node = root.find("Storyboard") if storyboard_node is None: - logging.error( - "Cannot find Storyboard node in provided XOSC file. Skipping check" - ) checker_data.result.set_checker_status( checker_bundle_name=constants.BUNDLE_NAME, checker_id=CHECKER_ID, status=StatusType.SKIPPED, ) + + checker_data.result.add_checker_summary( + constants.BUNDLE_NAME, + CHECKER_ID, + "Cannot find Storyboard node in the provided XOSC file. Skip the check.", + ) return xpath_expr = "|".join([f"//{node}" for node in STORYBOARD_ELEMENTS]) storyboard_elements = storyboard_node.xpath(xpath_expr) if storyboard_elements is None: - logging.error( - "Cannot find Storyboard elements node in provided XOSC file. Skipping check" - ) checker_data.result.set_checker_status( checker_bundle_name=constants.BUNDLE_NAME, checker_id=CHECKER_ID, status=StatusType.SKIPPED, ) + + checker_data.result.add_checker_summary( + constants.BUNDLE_NAME, + CHECKER_ID, + "Cannot find Storyboard elements node in the provided XOSC file. Skip the check.", + ) + return storyboard_element_type = {} diff --git a/qc_openscenario/checks/reference_checker/resolvable_traffic_signal_controller_by_traffic_signal_controller_ref.py b/qc_openscenario/checks/reference_checker/resolvable_traffic_signal_controller_by_traffic_signal_controller_ref.py index 4a26ec8..d017367 100644 --- a/qc_openscenario/checks/reference_checker/resolvable_traffic_signal_controller_by_traffic_signal_controller_ref.py +++ b/qc_openscenario/checks/reference_checker/resolvable_traffic_signal_controller_by_traffic_signal_controller_ref.py @@ -36,27 +36,35 @@ def check_rule(checker_data: models.CheckerData) -> None: road_network = root.find("RoadNetwork") if road_network is None: - logging.error( - "Cannot find RoadNetwork node in provided XOSC file. Skipping check" - ) checker_data.result.set_checker_status( checker_bundle_name=constants.BUNDLE_NAME, checker_id=CHECKER_ID, status=StatusType.SKIPPED, ) + + checker_data.result.add_checker_summary( + constants.BUNDLE_NAME, + CHECKER_ID, + "Cannot find RoadNetwork node. Skip the check.", + ) + return # ts = traffic signal ts_controllers = road_network.findall(".//TrafficSignalController") if ts_controllers is None: - logging.error( - "Cannot find TrafficSignalController nodes in RoadNetwork of provided XOSC file. Skipping check" - ) checker_data.result.set_checker_status( checker_bundle_name=constants.BUNDLE_NAME, checker_id=CHECKER_ID, status=StatusType.SKIPPED, ) + + checker_data.result.add_checker_summary( + constants.BUNDLE_NAME, + CHECKER_ID, + "Cannot find TrafficSignalController nodes in RoadNetwork. Skip the check.", + ) + return ts_controller_names = set() diff --git a/qc_openscenario/checks/reference_checker/resolvable_variable_reference.py b/qc_openscenario/checks/reference_checker/resolvable_variable_reference.py index cc788ed..9310c85 100644 --- a/qc_openscenario/checks/reference_checker/resolvable_variable_reference.py +++ b/qc_openscenario/checks/reference_checker/resolvable_variable_reference.py @@ -51,16 +51,18 @@ def check_rule(checker_data: models.CheckerData) -> None: storyboard_node = root.find("Storyboard") if storyboard_node is None: - logging.error( - "Cannot find Storyboard node in provided XOSC file. Skipping check" - ) - checker_data.result.set_checker_status( checker_bundle_name=constants.BUNDLE_NAME, checker_id=CHECKER_ID, status=StatusType.SKIPPED, ) + checker_data.result.add_checker_summary( + constants.BUNDLE_NAME, + CHECKER_ID, + "Cannot find Storyboard node. Skip the check.", + ) + return nodes_with_variable_ref = storyboard_node.xpath(".//*[@variableRef]") diff --git a/qc_openscenario/checks/reference_checker/valid_actor_reference_in_private_actions.py b/qc_openscenario/checks/reference_checker/valid_actor_reference_in_private_actions.py index 5fe3dd9..f53ebd5 100644 --- a/qc_openscenario/checks/reference_checker/valid_actor_reference_in_private_actions.py +++ b/qc_openscenario/checks/reference_checker/valid_actor_reference_in_private_actions.py @@ -40,14 +40,17 @@ def check_rule(checker_data: models.CheckerData) -> None: maneuver_groups = root.findall(".//ManeuverGroup") if maneuver_groups is None: - logging.error( - "Cannot find ManeuverGroup node in provided XOSC file. Skipping check" - ) checker_data.result.set_checker_status( checker_bundle_name=constants.BUNDLE_NAME, checker_id=CHECKER_ID, status=StatusType.SKIPPED, ) + + checker_data.result.add_checker_summary( + constants.BUNDLE_NAME, + CHECKER_ID, + "Cannot find ManeuverGroup node. Skip the check.", + ) return for maneuver_group in maneuver_groups: @@ -56,15 +59,18 @@ def check_rule(checker_data: models.CheckerData) -> None: entity_refs = maneuver_group.findall(".//EntityRef") if private_actions is None or entity_refs is None: - logging.error( - "Cannot find PrivateAction or EntityRef node in provided XOSC file. Skipping check" - ) - checker_data.result.set_checker_status( checker_bundle_name=constants.BUNDLE_NAME, checker_id=CHECKER_ID, status=StatusType.SKIPPED, ) + + checker_data.result.add_checker_summary( + constants.BUNDLE_NAME, + CHECKER_ID, + "Cannot find PrivateAction or EntityRef node. Skip the check.", + ) + return has_private_action = len(private_actions) > 0 diff --git a/qc_openscenario/checks/schema_checker/valid_schema.py b/qc_openscenario/checks/schema_checker/valid_schema.py index 9373fc0..e3bf782 100644 --- a/qc_openscenario/checks/schema_checker/valid_schema.py +++ b/qc_openscenario/checks/schema_checker/valid_schema.py @@ -68,16 +68,18 @@ def check_rule(checker_data: models.CheckerData) -> None: xsd_file = schema_files.SCHEMA_FILES.get(schema_version) if xsd_file is None: - logging.info( - f"- Schema file for version {schema_version} does not exist. Skipping check" - ) - checker_data.result.set_checker_status( checker_bundle_name=constants.BUNDLE_NAME, checker_id=CHECKER_ID, status=StatusType.SKIPPED, ) + checker_data.result.add_checker_summary( + constants.BUNDLE_NAME, + CHECKER_ID, + f"- Schema file for version {schema_version} does not exist. Skip the check.", + ) + return xsd_file_path = str( diff --git a/qc_openscenario/main.py b/qc_openscenario/main.py index a57b830..4345b4c 100644 --- a/qc_openscenario/main.py +++ b/qc_openscenario/main.py @@ -68,6 +68,12 @@ def execute_checker( status=StatusType.SKIPPED, ) + checker_data.result.add_checker_summary( + constants.BUNDLE_NAME, + checker.CHECKER_ID, + "Preconditions are not satisfied. Skip the check.", + ) + return # Checker definition setting. If not satisfied then set status as SKIPPED and return @@ -84,6 +90,12 @@ def execute_checker( status=StatusType.SKIPPED, ) + checker_data.result.add_checker_summary( + constants.BUNDLE_NAME, + checker.CHECKER_ID, + f"Version {schema_version} is lower than definition setting {definition_setting}. Skip the check.", + ) + return # Execute checker @@ -100,7 +112,7 @@ def execute_checker( checker_id=checker.CHECKER_ID, status=StatusType.COMPLETED, ) - except Exception: + except Exception as e: # If any exception occurs during the check, set the status as ERROR checker_data.result.set_checker_status( checker_bundle_name=constants.BUNDLE_NAME, @@ -108,6 +120,10 @@ def execute_checker( status=StatusType.ERROR, ) + checker_data.result.add_checker_summary( + constants.BUNDLE_NAME, checker.CHECKER_ID, f"Error: {str(e)}." + ) + def run_checks(config: Configuration, result: Result) -> None: checker_data = models.CheckerData( @@ -236,7 +252,8 @@ def main(): result.write_to_file( config.get_checker_bundle_param( checker_bundle_name=constants.BUNDLE_NAME, param_name="resultFile" - ) + ), + generate_summary=True, ) if args.generate_markdown: