diff --git a/examples/somersaultecu.py b/examples/somersaultecu.py index d2bd0fd3..536a5bbf 100755 --- a/examples/somersaultecu.py +++ b/examples/somersaultecu.py @@ -2144,6 +2144,7 @@ class SomersaultSID(IntEnum): comparam_refs=somersault_comparam_refs, libraries=NamedItemList(), prot_stack_snref=None, + sub_components=NamedItemList(), ) somersault_protocol = Protocol(diag_layer_raw=somersault_protocol_raw) @@ -2182,6 +2183,7 @@ class SomersaultSID(IntEnum): diag_variables_raw=[], variable_groups=NamedItemList(), libraries=NamedItemList(), + sub_components=NamedItemList(), dyn_defined_spec=None) somersault_base_variant = BaseVariant(diag_layer_raw=somersault_base_variant_raw) @@ -2231,6 +2233,7 @@ class SomersaultSID(IntEnum): variable_groups=NamedItemList(), libraries=NamedItemList(), dyn_defined_spec=None, + sub_components=NamedItemList(), ) somersault_lazy_ecu = EcuVariant(diag_layer_raw=somersault_lazy_ecu_raw) @@ -2469,6 +2472,7 @@ class SomersaultSID(IntEnum): variable_groups=NamedItemList(), libraries=NamedItemList(), dyn_defined_spec=None, + sub_components=NamedItemList(), ) somersault_assiduous_ecu = EcuVariant(diag_layer_raw=somersault_assiduous_ecu_raw) diff --git a/odxtools/diaglayers/diaglayer.py b/odxtools/diaglayers/diaglayer.py index caf5cfd1..2f3766fc 100644 --- a/odxtools/diaglayers/diaglayer.py +++ b/odxtools/diaglayers/diaglayer.py @@ -24,6 +24,7 @@ from ..singleecujob import SingleEcuJob from ..snrefcontext import SnRefContext from ..specialdatagroup import SpecialDataGroup +from ..subcomponent import SubComponent from ..unitgroup import UnitGroup from .diaglayerraw import DiagLayerRaw from .diaglayertype import DiagLayerType @@ -261,9 +262,13 @@ def import_refs(self) -> List[OdxLinkRef]: return self.diag_layer_raw.import_refs @property - def libraries(self) -> List[Library]: + def libraries(self) -> NamedItemList[Library]: return self.diag_layer_raw.libraries + @property + def sub_components(self) -> NamedItemList[SubComponent]: + return self.diag_layer_raw.sub_components + @property def sdgs(self) -> List[SpecialDataGroup]: return self.diag_layer_raw.sdgs diff --git a/odxtools/diaglayers/diaglayerraw.py b/odxtools/diaglayers/diaglayerraw.py index f9d0e592..0d11aad7 100644 --- a/odxtools/diaglayers/diaglayerraw.py +++ b/odxtools/diaglayers/diaglayerraw.py @@ -22,6 +22,7 @@ from ..snrefcontext import SnRefContext from ..specialdatagroup import SpecialDataGroup from ..statechart import StateChart +from ..subcomponent import SubComponent from ..utils import dataclass_fields_asdict from .diaglayertype import DiagLayerType @@ -47,7 +48,7 @@ class DiagLayerRaw(IdentifiableElement): import_refs: List[OdxLinkRef] state_charts: NamedItemList[StateChart] additional_audiences: NamedItemList[AdditionalAudience] - # sub_components: List[DiagLayer] # TODO + sub_components: NamedItemList[SubComponent] libraries: NamedItemList[Library] sdgs: List[SpecialDataGroup] @@ -154,6 +155,11 @@ def from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment]) -> Library.from_et(el, doc_frags) for el in et_element.iterfind("LIBRARYS/LIBRARY") ] + sub_components = [ + SubComponent.from_et(el, doc_frags) + for el in et_element.iterfind("SUB-COMPONENTS/SUB-COMPONENT") + ] + sdgs = [ SpecialDataGroup.from_et(sdge, doc_frags) for sdge in et_element.iterfind("SDGS/SDG") ] @@ -174,6 +180,7 @@ def from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment]) -> state_charts=NamedItemList(state_charts), additional_audiences=NamedItemList(additional_audiences), libraries=NamedItemList(libraries), + sub_components=NamedItemList(sub_components), sdgs=sdgs, **kwargs) @@ -208,6 +215,8 @@ def _build_odxlinks(self) -> Dict[OdxLinkId, Any]: odxlinks.update(additional_audience._build_odxlinks()) for library in self.libraries: odxlinks.update(library._build_odxlinks()) + for sub_comp in self.sub_components: + odxlinks.update(sub_comp._build_odxlinks()) for sdg in self.sdgs: odxlinks.update(sdg._build_odxlinks()) @@ -262,6 +271,8 @@ def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None: additional_audience._resolve_odxlinks(odxlinks) for library in self.libraries: library._resolve_odxlinks(odxlinks) + for sub_component in self.sub_components: + sub_component._resolve_odxlinks(odxlinks) for sdg in self.sdgs: sdg._resolve_odxlinks(odxlinks) @@ -294,5 +305,7 @@ def _resolve_snrefs(self, context: SnRefContext) -> None: additional_audience._resolve_snrefs(context) for library in self.libraries: library._resolve_snrefs(context) + for sub_component in self.sub_components: + sub_component._resolve_snrefs(context) for sdg in self.sdgs: sdg._resolve_snrefs(context) diff --git a/odxtools/subcomponent.py b/odxtools/subcomponent.py new file mode 100644 index 00000000..5fcd2d2c --- /dev/null +++ b/odxtools/subcomponent.py @@ -0,0 +1,288 @@ +# SPDX-License-Identifier: MIT +from dataclasses import dataclass +from typing import Any, Dict, List, Optional +from xml.etree import ElementTree + +from .diagnostictroublecode import DiagnosticTroubleCode +from .diagservice import DiagService +from .dtcdop import DtcDop +from .element import IdentifiableElement, NamedElement +from .environmentdata import EnvironmentData +from .environmentdatadescription import EnvironmentDataDescription +from .exceptions import odxraise, odxrequire +from .matchingparameter import MatchingParameter +from .nameditemlist import NamedItemList +from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef, resolve_snref +from .parameters.parameter import Parameter +from .snrefcontext import SnRefContext +from .table import Table +from .tablerow import TableRow +from .utils import dataclass_fields_asdict + + +@dataclass +class SubComponentPattern: + matching_parameters: List[MatchingParameter] + + @staticmethod + def from_et(et_element: ElementTree.Element, + doc_frags: List[OdxDocFragment]) -> "SubComponentPattern": + + matching_parameters = [ + MatchingParameter.from_et(el, doc_frags) + for el in et_element.iterfind("MATCHING-PARAMETERS/MATCHING-PARAMETER") + ] + + return SubComponentPattern(matching_parameters=matching_parameters) + + +@dataclass +class SubComponentParamConnector(IdentifiableElement): + diag_comm_snref: str + + # TODO: we currently only support SNREFs, not SNPATHREFs + out_param_if_refs: List[str] + in_param_if_refs: List[str] + + @property + def service(self) -> DiagService: + return self._service + + @property + def out_param_ifs(self) -> NamedItemList[Parameter]: + return self._out_param_ifs + + @property + def in_param_ifs(self) -> NamedItemList[Parameter]: + return self._in_param_ifs + + @staticmethod + def from_et(et_element: ElementTree.Element, + doc_frags: List[OdxDocFragment]) -> "SubComponentParamConnector": + kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, doc_frags)) + + diag_comm_snref = odxrequire( + odxrequire(et_element.find("DIAG-COMM-SNREF")).get("SHORT-NAME")) + + out_param_if_refs = [] + for elem in et_element.find("OUT-PARAM-IF-REFS") or []: + if elem.tag != "OUT-PARAM-IF-SNREF": + odxraise("Currently, only SNREFS are supported for OUT-PARAM-IF-REFS") + continue + + out_param_if_refs.append(odxrequire(elem.get("SHORT-NAME"))) + + in_param_if_refs = [] + for elem in et_element.find("IN-PARAM-IF-REFS") or []: + if elem.tag != "IN-PARAM-IF-SNREF": + odxraise("Currently, only SNREFS are supported for IN-PARAM-IF-REFS") + continue + + in_param_if_refs.append(odxrequire(elem.get("SHORT-NAME"))) + + return SubComponentParamConnector( + diag_comm_snref=diag_comm_snref, + out_param_if_refs=out_param_if_refs, + in_param_if_refs=in_param_if_refs, + **kwargs) + + def _build_odxlinks(self) -> Dict[OdxLinkId, Any]: + return {} + + def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None: + pass + + def _resolve_snrefs(self, context: SnRefContext) -> None: + service = resolve_snref(self.diag_comm_snref, + odxrequire(context.diag_layer).diag_comms, DiagService) + self._service = service + + if self._service.request is not None: + odxraise() + return + if not self._service.positive_responses: + odxraise() + return + request = odxrequire(service.request) + response = service.positive_responses[0] + + in_param_ifs = [] + for x in self.in_param_if_refs: + in_param_ifs.append(resolve_snref(x, request.parameters, Parameter)) + + out_param_ifs = [] + for x in self.out_param_if_refs: + out_param_ifs.append(resolve_snref(x, response.parameters, Parameter)) + + self._in_param_ifs = NamedItemList(in_param_ifs) + self._out_param_ifs = NamedItemList(out_param_ifs) + + +@dataclass +class TableRowConnector(NamedElement): + table_ref: OdxLinkRef + table_row_snref: str + + @property + def table(self) -> Table: + return self._table + + @property + def table_row(self) -> TableRow: + return self._table_row + + @staticmethod + def from_et(et_element: ElementTree.Element, + doc_frags: List[OdxDocFragment]) -> "TableRowConnector": + kwargs = dataclass_fields_asdict(NamedElement.from_et(et_element, doc_frags)) + + table_ref = odxrequire(OdxLinkRef.from_et(et_element.find("TABLE-REF"), doc_frags)) + table_row_snref_el = odxrequire(et_element.find("TABLE-ROW-SNREF")) + table_row_snref = odxrequire(table_row_snref_el.get("SHORT-NAME")) + + return TableRowConnector(table_ref=table_ref, table_row_snref=table_row_snref, **kwargs) + + def _build_odxlinks(self) -> Dict[OdxLinkId, Any]: + return {} + + def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None: + self._table = odxlinks.resolve(self.table_ref, Table) + + def _resolve_snrefs(self, context: SnRefContext) -> None: + self._table_row = resolve_snref(self.table_row_snref, self._table.table_rows, TableRow) + + +@dataclass +class DtcConnector(NamedElement): + dtc_dop_ref: OdxLinkRef + dtc_snref: str + + @property + def dtc_dop(self) -> DtcDop: + return self._dtc_dop + + @property + def dtc(self) -> DiagnosticTroubleCode: + return self._dtc + + @staticmethod + def from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment]) -> "DtcConnector": + kwargs = dataclass_fields_asdict(NamedElement.from_et(et_element, doc_frags)) + + dtc_dop_ref = odxrequire(OdxLinkRef.from_et(et_element.find("DTC-DOP-REF"), doc_frags)) + dtc_snref_el = odxrequire(et_element.find("DTC-SNREF")) + dtc_snref = odxrequire(dtc_snref_el.get("SHORT-NAME")) + + return DtcConnector(dtc_dop_ref=dtc_dop_ref, dtc_snref=dtc_snref, **kwargs) + + def _build_odxlinks(self) -> Dict[OdxLinkId, Any]: + return {} + + def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None: + self._dtc_dop = odxlinks.resolve(self.dtc_dop_ref, DtcDop) + + def _resolve_snrefs(self, context: SnRefContext) -> None: + self._dtc = resolve_snref(self.dtc_snref, self._dtc_dop.dtcs, DiagnosticTroubleCode) + + +@dataclass +class EnvDataConnector(NamedElement): + env_data_desc_ref: OdxLinkRef + env_data_snref: str + + @property + def env_data_desc(self) -> EnvironmentDataDescription: + return self._env_data_desc + + @property + def env_data(self) -> EnvironmentData: + return self._env_data + + @staticmethod + def from_et(et_element: ElementTree.Element, + doc_frags: List[OdxDocFragment]) -> "EnvDataConnector": + kwargs = dataclass_fields_asdict(NamedElement.from_et(et_element, doc_frags)) + + env_data_desc_ref = odxrequire( + OdxLinkRef.from_et(et_element.find("ENV-DATA-DESC-REF"), doc_frags)) + env_data_snref_el = odxrequire(et_element.find("ENV-DATA-SNREF")) + env_data_snref = odxrequire(env_data_snref_el.get("SHORT-NAME")) + + return EnvDataConnector( + env_data_desc_ref=env_data_desc_ref, env_data_snref=env_data_snref, **kwargs) + + def _build_odxlinks(self) -> Dict[OdxLinkId, Any]: + return {} + + def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None: + self._env_data_desc = odxlinks.resolve(self.env_data_desc_ref, EnvironmentDataDescription) + + def _resolve_snrefs(self, context: SnRefContext) -> None: + self._env_data = resolve_snref(self.env_data_snref, self._env_data_desc.env_datas, + EnvironmentData) + + +@dataclass +class SubComponent(IdentifiableElement): + """Sub-components describe collections of related diagnostic variables + + Note that the communication paradigm via diagnostic variables is + somewhat uncommon. If your ECU does not define any, there's no + need for it to define sub-components. + + """ + + #sub_component_patterns: NamedItemList[SubComponentPattern] + sub_component_param_connectors: NamedItemList[SubComponentParamConnector] + table_row_connectors: NamedItemList[TableRowConnector] + env_data_connectors: NamedItemList[EnvDataConnector] + dtc_connectors: NamedItemList[DtcConnector] + + semantic: Optional[str] + + @staticmethod + def from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment]) -> "SubComponent": + kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, doc_frags)) + + semantic = et_element.get("SEMANTIC") + + sub_component_param_connectors = [ + SubComponentParamConnector.from_et(el, doc_frags) for el in et_element.iterfind( + "SUB-COMPONENT-PARAM-CONNECTORS/SUB-COMPONENT-PARAM-CONNECTOR") + ] + table_row_connectors = [ + TableRowConnector.from_et(el, doc_frags) + for el in et_element.iterfind("TABLE-ROW-CONNECTORS/TABLE-ROW-CONNECTOR") + ] + env_data_connectors = [ + EnvDataConnector.from_et(el, doc_frags) + for el in et_element.iterfind("ENV-DATA-CONNECTORS/ENV-DATA-CONNECTOR") + ] + dtc_connectors = [ + DtcConnector.from_et(el, doc_frags) + for el in et_element.iterfind("DTC-CONNECTORS/DTC-CONNECTOR") + ] + + return SubComponent( + semantic=semantic, + sub_component_param_connectors=NamedItemList(sub_component_param_connectors), + table_row_connectors=NamedItemList(table_row_connectors), + env_data_connectors=NamedItemList(env_data_connectors), + dtc_connectors=NamedItemList(dtc_connectors), + **kwargs) + + def _build_odxlinks(self) -> Dict[OdxLinkId, Any]: + result = {} + + for dtc_conn in self.dtc_connectors: + result.update(dtc_conn._build_odxlinks()) + + return result + + def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None: + for dtc_conn in self.dtc_connectors: + dtc_conn._resolve_odxlinks(odxlinks) + + def _resolve_snrefs(self, context: SnRefContext) -> None: + for dtc_conn in self.dtc_connectors: + dtc_conn._resolve_snrefs(context) diff --git a/odxtools/templates/macros/printDiagLayer.xml.jinja2 b/odxtools/templates/macros/printDiagLayer.xml.jinja2 index 0697b9e6..7cb8c969 100644 --- a/odxtools/templates/macros/printDiagLayer.xml.jinja2 +++ b/odxtools/templates/macros/printDiagLayer.xml.jinja2 @@ -22,6 +22,7 @@ {%- import('macros/printResponse.xml.jinja2') as presp %} {%- import('macros/printStateChart.xml.jinja2') as psc %} {%- import('macros/printAudience.xml.jinja2') as paud %} +{%- import('macros/printSubComponent.xml.jinja2') as psubcomp %} {%- import('macros/printLibrary.xml.jinja2') as plib %} {%- import('macros/printSpecialData.xml.jinja2') as psd %} {%- import('macros/printEcuVariantPattern.xml.jinja2') as pvpat %} @@ -203,6 +204,13 @@ {%- endfor %} {%- endif %} +{%- if dlr.sub_components %} + + {%- for sc in dlr.sub_components %} + {{ psubcomp.printSubComponent(sc)|indent(2) }} + {%- endfor %} + +{%- endif %} {%- if dlr.libraries %} {%- for lib in dlr.libraries %} diff --git a/odxtools/templates/macros/printSubComponent.xml.jinja2 b/odxtools/templates/macros/printSubComponent.xml.jinja2 new file mode 100644 index 00000000..9118f835 --- /dev/null +++ b/odxtools/templates/macros/printSubComponent.xml.jinja2 @@ -0,0 +1,104 @@ +{#- -*- mode: sgml; tab-width: 1; indent-tabs-mode: nil -*- +# +# SPDX-License-Identifier: MIT +-#} + +{%- import('macros/printElementId.xml.jinja2') as peid %} +{%- import('macros/printEcuVariantPattern.xml.jinja2') as pevp %} + +{%- macro printSubComponentPattern(pat) %} + + + {%- for mp in pat.matching_parameters %} + {{ pvp.printMatchingParameter(mp)|indent(4) }} + {%- endfor %} + + +{%- endmacro %} + +{%- macro printSubComponentParamConnector(conn) %} + + {{ peid.printElementIdSubtags(conn)|indent(2) }} + + {%- if conn.out_param_if_refs %} + + {%- for snref in conn.out_param_if_refs %} + + {%- endfor %} + + {%- endif %} + {%- if conn.in_param_if_refs %} + + {%- for snref in conn.in_param_if_refs %} + + {%- endfor %} + + {%- endif %} + +{%- endmacro %} + +{%- macro printTableRowConnector(conn) %} + + {{ peid.printElementIdSubtags(conn)|indent(2) }} + + + +{%- endmacro %} + +{%- macro printEnvDataConnector(conn) %} + + {{ peid.printElementIdSubtags(conn)|indent(2) }} + + + +{%- endmacro %} + +{%- macro printDtcConnector(conn) %} + + {{ peid.printElementIdSubtags(conn)|indent(2) }} + + + +{%- endmacro %} + +{%- macro printSubComponent(sc) %} + + {{ peid.printElementIdSubtags(sc)|indent(2) }} + {%- if sc.sub_component_patterns %} + + {%- for scp in sc.sub_component_patterns %} + {{ printSubComponentPattern(scp)|indent(4) }} + {%- endfor %} + + {%- endif %} + {%- if sc.sub_component_param_connectors %} + + {%- for conn in sc.sub_component_param_connectors %} + {{ printSubComponentParamConnector(conn)|indent(4) }} + {%- endfor %} + + {%- endif %} + {%- if sc.table_row_connectors %} + + {%- for conn in sc.table_row_connectors %} + {{ printTableRowConnector(conn)|indent(4) }} + {%- endfor %} + + {%- endif %} + {%- if sc.env_data_connectors %} + + {%- for conn in sc.env_data_connectors %} + {{ printEnvDataConnector(conn)|indent(4) }} + {%- endfor %} + + {%- endif %} + {%- if sc.dtc_connectors %} + + {%- for conn in sc.dtc_connectors %} + {{ printDtcConnector(conn)|indent(4) }} + {%- endfor %} + + {%- endif %} + +{%- endmacro %} diff --git a/tests/test_decoding.py b/tests/test_decoding.py index c2a5b23f..c48a2b1e 100644 --- a/tests/test_decoding.py +++ b/tests/test_decoding.py @@ -238,6 +238,7 @@ def test_prefix_tree_construction(self) -> None: variable_groups=NamedItemList(), libraries=NamedItemList(), dyn_defined_spec=None, + sub_components=NamedItemList(), ) ecu_variant = EcuVariant(diag_layer_raw=ecu_variant_raw) db = Database() @@ -364,6 +365,7 @@ def test_decode_request_coded_const(self) -> None: variable_groups=NamedItemList(), libraries=NamedItemList(), dyn_defined_spec=None, + sub_components=NamedItemList(), ) ecu_variant = EcuVariant(diag_layer_raw=ecu_variant_raw) odxlinks = OdxLinkDatabase() @@ -562,6 +564,7 @@ def test_decode_nrc_const(self) -> None: variable_groups=NamedItemList(), libraries=NamedItemList(), dyn_defined_spec=None, + sub_components=NamedItemList(), ) ecu_variant = BaseVariant(diag_layer_raw=base_variant_raw) db = Database() @@ -719,6 +722,7 @@ def test_decode_request_coded_const_undefined_byte_position(self) -> None: variable_groups=NamedItemList(), libraries=NamedItemList(), dyn_defined_spec=None, + sub_components=NamedItemList(), ) ecu_variant = EcuVariant(diag_layer_raw=ecu_variant_raw) db = Database() @@ -938,6 +942,7 @@ def test_decode_request_structure(self) -> None: variable_groups=NamedItemList(), libraries=NamedItemList(), dyn_defined_spec=None, + sub_components=NamedItemList(), ) ecu_variant = EcuVariant(diag_layer_raw=ecu_variant_raw) odxlinks = OdxLinkDatabase() @@ -1158,6 +1163,7 @@ def test_static_field_coding(self) -> None: variable_groups=NamedItemList(), libraries=NamedItemList(), dyn_defined_spec=None, + sub_components=NamedItemList(), ) ecu_variant = EcuVariant(diag_layer_raw=ecu_variant_raw) odxlinks = OdxLinkDatabase() @@ -1511,6 +1517,7 @@ def test_dynamic_endmarker_field_coding(self) -> None: variable_groups=NamedItemList(), libraries=NamedItemList(), dyn_defined_spec=None, + sub_components=NamedItemList(), ) ecu_variant = EcuVariant(diag_layer_raw=ecu_variant_raw) odxlinks = OdxLinkDatabase() @@ -1797,6 +1804,7 @@ def test_dynamic_length_field_coding(self) -> None: variable_groups=NamedItemList(), libraries=NamedItemList(), dyn_defined_spec=None, + sub_components=NamedItemList(), ) ecu_variant = EcuVariant(diag_layer_raw=ecu_variant_raw) odxlinks = OdxLinkDatabase() @@ -2040,6 +2048,7 @@ def test_decode_request_end_of_pdu_field(self) -> None: variable_groups=NamedItemList(), libraries=NamedItemList(), dyn_defined_spec=None, + sub_components=NamedItemList(), ) ecu_variant = EcuVariant(diag_layer_raw=ecu_variant_raw) odxlinks = OdxLinkDatabase() @@ -2229,6 +2238,7 @@ def test_decode_request_linear_compu_method(self) -> None: variable_groups=NamedItemList(), libraries=NamedItemList(), dyn_defined_spec=None, + sub_components=NamedItemList(), ) ecu_variant = EcuVariant(diag_layer_raw=ecu_variant_raw) odxlinks = OdxLinkDatabase() @@ -2428,6 +2438,7 @@ def test_decode_response(self) -> None: variable_groups=NamedItemList(), libraries=NamedItemList(), dyn_defined_spec=None, + sub_components=NamedItemList(), ) ecu_variant = EcuVariant(diag_layer_raw=ecu_variant_raw) odxlinks = OdxLinkDatabase() diff --git a/tests/test_diag_coded_types.py b/tests/test_diag_coded_types.py index 36c19e9a..83d56156 100644 --- a/tests/test_diag_coded_types.py +++ b/tests/test_diag_coded_types.py @@ -301,6 +301,7 @@ def test_end_to_end(self) -> None: variable_groups=NamedItemList(), libraries=NamedItemList(), dyn_defined_spec=None, + sub_components=NamedItemList(), ) ecu_variant = EcuVariant(diag_layer_raw=ecu_variant_raw) odxlinks = OdxLinkDatabase() @@ -636,6 +637,7 @@ def test_end_to_end(self) -> None: variable_groups=NamedItemList(), libraries=NamedItemList(), dyn_defined_spec=None, + sub_components=NamedItemList(), ) ecu_variant = EcuVariant(diag_layer_raw=ecu_variant_raw) odxlinks = OdxLinkDatabase() @@ -981,6 +983,7 @@ def test_end_to_end(self) -> None: variable_groups=NamedItemList(), libraries=NamedItemList(), dyn_defined_spec=None, + sub_components=NamedItemList(), ) ecu_variant = EcuVariant(diag_layer_raw=ecu_variant_raw) odxlinks = OdxLinkDatabase() diff --git a/tests/test_ecu_variant_matching.py b/tests/test_ecu_variant_matching.py index ae72f9c5..b4b1748a 100644 --- a/tests/test_ecu_variant_matching.py +++ b/tests/test_ecu_variant_matching.py @@ -227,6 +227,7 @@ def ecu_variant_1( variable_groups=NamedItemList(), libraries=NamedItemList(), dyn_defined_spec=None, + sub_components=NamedItemList(), ) result = EcuVariant(diag_layer_raw=raw_layer) odxlinks.update(result._build_odxlinks()) @@ -269,6 +270,7 @@ def ecu_variant_2( variable_groups=NamedItemList(), libraries=NamedItemList(), dyn_defined_spec=None, + sub_components=NamedItemList(), ) result = EcuVariant(diag_layer_raw=raw_layer) odxlinks.update(result._build_odxlinks()) @@ -312,6 +314,7 @@ def ecu_variant_3( variable_groups=NamedItemList(), libraries=NamedItemList(), dyn_defined_spec=None, + sub_components=NamedItemList(), ) result = EcuVariant(diag_layer_raw=raw_layer) odxlinks.update(result._build_odxlinks()) diff --git a/tests/test_encoding.py b/tests/test_encoding.py index c3e9f936..709d38f5 100644 --- a/tests/test_encoding.py +++ b/tests/test_encoding.py @@ -398,6 +398,7 @@ def test_encode_nrc_const(self) -> None: variable_groups=NamedItemList(), libraries=NamedItemList(), dyn_defined_spec=None, + sub_components=NamedItemList(), ) ecu_variant = EcuVariant(diag_layer_raw=ecu_variant_raw) diff --git a/tests/test_singleecujob.py b/tests/test_singleecujob.py index 1a962c38..e24c589e 100644 --- a/tests/test_singleecujob.py +++ b/tests/test_singleecujob.py @@ -478,6 +478,7 @@ def test_resolve_odxlinks(self) -> None: entrypoint="i_am_great") ]), dyn_defined_spec=None, + sub_components=NamedItemList(), ) ecu_variant = EcuVariant(diag_layer_raw=ecu_variant_raw) odxlinks = OdxLinkDatabase() diff --git a/tests/test_unit_spec.py b/tests/test_unit_spec.py index f057aa5b..7464d565 100644 --- a/tests/test_unit_spec.py +++ b/tests/test_unit_spec.py @@ -214,6 +214,7 @@ def test_resolve_odxlinks(self) -> None: variable_groups=NamedItemList(), libraries=NamedItemList(), dyn_defined_spec=None, + sub_components=NamedItemList(), ) dl = EcuVariant(diag_layer_raw=dl_raw) odxlinks = OdxLinkDatabase()