-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add unique name checks and tests (#11)
Signed-off-by: romanodanilo <[email protected]> Signed-off-by: romanodanilo <[email protected]>
- Loading branch information
1 parent
72ed71e
commit 68e39a6
Showing
14 changed files
with
614 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
from . import reference_constants as reference_constants | ||
from . import reference_checker as reference_checker | ||
from . import ( | ||
uniquely_resolvable_entity_references as uniquely_resolvable_entity_references, | ||
) |
67 changes: 67 additions & 0 deletions
67
qc_openscenario/checks/reference_checker/reference_checker.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
import logging | ||
|
||
from lxml import etree | ||
|
||
from qc_baselib import Configuration, Result, StatusType | ||
|
||
from qc_openscenario import constants | ||
from qc_openscenario.checks import utils, models | ||
|
||
from qc_openscenario.checks.reference_checker import ( | ||
reference_constants, | ||
uniquely_resolvable_entity_references, | ||
) | ||
|
||
|
||
def run_checks(checker_data: models.CheckerData) -> None: | ||
logging.info("Executing reference checks") | ||
|
||
checker_data.result.register_checker( | ||
checker_bundle_name=constants.BUNDLE_NAME, | ||
checker_id=reference_constants.CHECKER_ID, | ||
description="Check if xml properties of input file are properly set", | ||
summary="", | ||
) | ||
|
||
# Skip if basic checks fail | ||
if checker_data.input_file_xml_root is None: | ||
logging.error( | ||
f"Invalid xml input file. Checker {reference_constants.CHECKER_ID} skipped" | ||
) | ||
checker_data.result.set_checker_status( | ||
checker_bundle_name=constants.BUNDLE_NAME, | ||
checker_id=reference_constants.CHECKER_ID, | ||
status=StatusType.SKIPPED, | ||
) | ||
return | ||
|
||
# Skip if schema checks are skipped | ||
if ( | ||
checker_data.result.get_checker_result("xoscBundle", "schema_xosc").status | ||
is StatusType.SKIPPED | ||
): | ||
logging.error( | ||
f"Schema checks have been skipped. Checker {reference_constants.CHECKER_ID} skipped" | ||
) | ||
checker_data.result.set_checker_status( | ||
checker_bundle_name=constants.BUNDLE_NAME, | ||
checker_id=reference_constants.CHECKER_ID, | ||
status=StatusType.SKIPPED, | ||
) | ||
return | ||
|
||
rule_list = [uniquely_resolvable_entity_references.check_rule] | ||
|
||
for rule in rule_list: | ||
rule(checker_data=checker_data) | ||
|
||
logging.info( | ||
f"Issues found - {checker_data.result.get_checker_issue_count(checker_bundle_name=constants.BUNDLE_NAME, checker_id=reference_constants.CHECKER_ID)}" | ||
) | ||
|
||
# TODO: Add logic to deal with error or to skip it | ||
checker_data.result.set_checker_status( | ||
checker_bundle_name=constants.BUNDLE_NAME, | ||
checker_id=reference_constants.CHECKER_ID, | ||
status=StatusType.COMPLETED, | ||
) |
1 change: 1 addition & 0 deletions
1
qc_openscenario/checks/reference_checker/reference_constants.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
CHECKER_ID = "reference_xosc" |
116 changes: 116 additions & 0 deletions
116
qc_openscenario/checks/reference_checker/uniquely_resolvable_entity_references.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
import os, logging | ||
|
||
from dataclasses import dataclass | ||
from typing import List | ||
|
||
from lxml import etree | ||
|
||
from qc_baselib import Configuration, Result, IssueSeverity | ||
|
||
from qc_openscenario import constants | ||
from qc_openscenario.schema import schema_files | ||
from qc_openscenario.checks import utils, models | ||
|
||
from qc_openscenario.checks.reference_checker import reference_constants | ||
from collections import deque, defaultdict | ||
|
||
MIN_RULE_VERSION = "1.2.0" | ||
|
||
|
||
def get_catalogs(root: etree._ElementTree) -> List[etree._ElementTree]: | ||
catalogs = [] | ||
|
||
for catalog in root.iter("Catalog"): | ||
catalogs.append(catalog) | ||
|
||
return catalogs | ||
|
||
|
||
def get_xpath(root: etree._ElementTree, element: etree._ElementTree) -> str: | ||
return root.getpath(element) | ||
|
||
|
||
def check_rule(checker_data: models.CheckerData) -> None: | ||
""" | ||
Implements a rule to check if referenced entities are unique | ||
More info at | ||
- https://github.com/asam-ev/qc-openscenarioxml/issues/8 | ||
""" | ||
logging.info("Executing uniquely_resolvable_entity_references check") | ||
|
||
schema_version = checker_data.schema_version | ||
if schema_version is None: | ||
logging.info(f"- Version not found in the file. Skipping check") | ||
return | ||
|
||
rule_severity = IssueSeverity.WARNING | ||
if utils.compare_versions(schema_version, MIN_RULE_VERSION) < 0: | ||
logging.info( | ||
f"- Version {schema_version} is less than minimum required version {MIN_RULE_VERSION}. Skipping check" | ||
) | ||
return | ||
|
||
rule_uid = checker_data.result.register_rule( | ||
checker_bundle_name=constants.BUNDLE_NAME, | ||
checker_id=reference_constants.CHECKER_ID, | ||
emanating_entity="asam.net", | ||
standard="xosc", | ||
definition_setting=MIN_RULE_VERSION, | ||
rule_full_name="reference_control.uniquely_resolvable_entity_references", | ||
) | ||
|
||
root = checker_data.input_file_xml_root | ||
|
||
# List to store problematic nodes | ||
errors = [] | ||
|
||
# Iterate over each 'Catalog' node | ||
for catalog_node in root.findall(".//Catalog"): | ||
# Dictionary to track child nodes by 'name' attribute | ||
child_names = {} | ||
|
||
# Iterate catalog children within current 'Catalog' node | ||
# Currently the checks verifies that the same name is not used in the same | ||
# catalog regardless the tag type | ||
# E.g. Catalog children: | ||
# # [Vehicle name="abc", Maneuver name="abc"] | ||
# Will trigger the issue | ||
for child_node in catalog_node.iterchildren(): | ||
name_attr = child_node.attrib.get("name") | ||
if name_attr: | ||
if name_attr in child_names: | ||
errors.append( | ||
{ | ||
"name": name_attr, | ||
"tag": child_node.tag, | ||
"first_xpath": get_xpath(root, child_names[name_attr]), | ||
"duplicate_xpath": get_xpath(root, child_node), | ||
} | ||
) | ||
else: | ||
child_names[name_attr] = child_node | ||
|
||
if len(errors) > 0: | ||
issue_id = checker_data.result.register_issue( | ||
checker_bundle_name=constants.BUNDLE_NAME, | ||
checker_id=reference_constants.CHECKER_ID, | ||
description="Issue flagging when referenced names are not unique", | ||
level=rule_severity, | ||
rule_uid=rule_uid, | ||
) | ||
|
||
for error in errors: | ||
error_name = error["name"] | ||
error_first_xpath = error["first_xpath"] | ||
error_duplicate_xpath = error["duplicate_xpath"] | ||
error_msg = f"Duplicate name {error_name}. First occurrence at {error_first_xpath} duplicate at {error_duplicate_xpath}" | ||
logging.error(f"- Error: {error_msg}") | ||
logging.error(f"- Duplicate xpath: {error_duplicate_xpath}") | ||
checker_data.result.add_xml_location( | ||
checker_bundle_name=constants.BUNDLE_NAME, | ||
checker_id=reference_constants.CHECKER_ID, | ||
issue_id=issue_id, | ||
xpath=error_duplicate_xpath, | ||
description=error_msg, | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
34 changes: 34 additions & 0 deletions
34
tests/data/uniquely_resolvable_entity_references/long_catalog_negative.xosc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<OpenSCENARIO> | ||
<FileHeader description="Vehicle Catalog" author="ASAM" revMajor="1" revMinor="2" | ||
date="2023-11-15T11:00:00.000000" /> | ||
<Catalog name="VehicleCatalog_1"> | ||
<Vehicle name="car_white" vehicleCategory="car"> | ||
<BoundingBox> | ||
<Center x="1.4" y="0.0" z="0.9" /> | ||
<Dimensions width="2.0" length="5.0" height="1.8" /> | ||
</BoundingBox> | ||
<Performance maxSpeed="69" maxDeceleration="30" maxAcceleration="5" /> | ||
<Axles> | ||
<FrontAxle maxSteering="30" wheelDiameter="0.8" trackWidth="1.68" positionX="2.98" | ||
positionZ="0.4" /> | ||
<RearAxle maxSteering="30" wheelDiameter="0.8" trackWidth="1.68" positionX="0" | ||
positionZ="0.4" /> | ||
</Axles> | ||
<Properties> | ||
<Property name="control" value="internal" /> | ||
<Property name="model_id" value="0" /> | ||
<File | ||
filepath="../../../external/delivery/esmini-noosg/resources/osgb/car_white.osgb" /> | ||
</Properties> | ||
</Vehicle> | ||
<Vehicle name="car_red" /> | ||
<Controller name="abc" /> | ||
<Controller name="controller2" /> | ||
<Maneuver name="abc" /> | ||
<Maneuver name="maneuver2" /> | ||
<Route name="route1" /> | ||
<Route name="route2" /> | ||
|
||
</Catalog> | ||
</OpenSCENARIO> |
34 changes: 34 additions & 0 deletions
34
tests/data/uniquely_resolvable_entity_references/long_catalog_positive.xosc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<OpenSCENARIO> | ||
<FileHeader description="Vehicle Catalog" author="ASAM" revMajor="1" revMinor="2" | ||
date="2023-11-15T11:00:00.000000" /> | ||
<Catalog name="VehicleCatalog_1"> | ||
<Vehicle name="car_white" vehicleCategory="car"> | ||
<BoundingBox> | ||
<Center x="1.4" y="0.0" z="0.9" /> | ||
<Dimensions width="2.0" length="5.0" height="1.8" /> | ||
</BoundingBox> | ||
<Performance maxSpeed="69" maxDeceleration="30" maxAcceleration="5" /> | ||
<Axles> | ||
<FrontAxle maxSteering="30" wheelDiameter="0.8" trackWidth="1.68" positionX="2.98" | ||
positionZ="0.4" /> | ||
<RearAxle maxSteering="30" wheelDiameter="0.8" trackWidth="1.68" positionX="0" | ||
positionZ="0.4" /> | ||
</Axles> | ||
<Properties> | ||
<Property name="control" value="internal" /> | ||
<Property name="model_id" value="0" /> | ||
<File | ||
filepath="../../../external/delivery/esmini-noosg/resources/osgb/car_white.osgb" /> | ||
</Properties> | ||
</Vehicle> | ||
<Vehicle name="car_red" /> | ||
<Controller name="controller1" /> | ||
<Controller name="controller2" /> | ||
<Maneuver name="maneuver1" /> | ||
<Maneuver name="maneuver2" /> | ||
<Route name="route1" /> | ||
<Route name="route2" /> | ||
|
||
</Catalog> | ||
</OpenSCENARIO> |
45 changes: 45 additions & 0 deletions
45
tests/data/uniquely_resolvable_entity_references/vehicle_catalog_negative.xosc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<OpenSCENARIO> | ||
<FileHeader description="Vehicle Catalog" author="ASAM" revMajor="1" revMinor="2" | ||
date="2023-11-15T11:00:00.000000" /> | ||
<Catalog name="VehicleCatalog"> | ||
<Vehicle name="car_white" vehicleCategory="car"> | ||
<BoundingBox> | ||
<Center x="1.4" y="0.0" z="0.9" /> | ||
<Dimensions width="2.0" length="5.0" height="1.8" /> | ||
</BoundingBox> | ||
<Performance maxSpeed="69" maxDeceleration="30" maxAcceleration="5" /> | ||
<Axles> | ||
<FrontAxle maxSteering="30" wheelDiameter="0.8" trackWidth="1.68" positionX="2.98" | ||
positionZ="0.4" /> | ||
<RearAxle maxSteering="30" wheelDiameter="0.8" trackWidth="1.68" positionX="0" | ||
positionZ="0.4" /> | ||
</Axles> | ||
<Properties> | ||
<Property name="control" value="internal" /> | ||
<Property name="model_id" value="0" /> | ||
<File | ||
filepath="../../../external/delivery/esmini-noosg/resources/osgb/car_white.osgb" /> | ||
</Properties> | ||
</Vehicle> | ||
<Vehicle name="car_white" vehicleCategory="car"> | ||
<BoundingBox> | ||
<Center x="1.4" y="0.0" z="0.9" /> | ||
<Dimensions width="2.0" length="5.0" height="1.8" /> | ||
</BoundingBox> | ||
<Performance maxSpeed="69" maxDeceleration="30" maxAcceleration="5" /> | ||
<Axles> | ||
<FrontAxle maxSteering="30" wheelDiameter="0.8" trackWidth="1.68" positionX="2.98" | ||
positionZ="0.4" /> | ||
<RearAxle maxSteering="30" wheelDiameter="0.8" trackWidth="1.68" positionX="0" | ||
positionZ="0.4" /> | ||
</Axles> | ||
<Properties> | ||
<Property name="control" value="internal" /> | ||
<Property name="model_id" value="0" /> | ||
<File | ||
filepath="../../../external/delivery/esmini-noosg/resources/osgb/car_white.osgb" /> | ||
</Properties> | ||
</Vehicle> | ||
</Catalog> | ||
</OpenSCENARIO> |
Oops, something went wrong.