From edab4bc85738ccdc38d3dcb218f242fe110cf7e2 Mon Sep 17 00:00:00 2001 From: cogu Date: Tue, 23 Jul 2024 20:23:56 +0200 Subject: [PATCH] Implement more event classes - DataReceiveErrorEvent - DataSendCompletedEvent - DataWriteCompletedEvent - ModeSwitchedAckEvent - OperationInvokedEvent - SwcModeSwitchEvent - TimingEvent --- CHANGELOG.md | 7 + src/autosar/xml/element.py | 224 +++++++++++- src/autosar/xml/enumeration.py | 94 +++-- src/autosar/xml/reader.py | 263 ++++++++++++-- src/autosar/xml/reference.py | 47 ++- src/autosar/xml/writer.py | 201 ++++++++++- tests/xml/test_swc_internal_behavior.py | 450 +++++++++++++++++++++++- 7 files changed, 1208 insertions(+), 78 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 78e1610..95342fb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,8 +16,15 @@ Non-collectable elements are various sub-elements to collectable elements. #### XML - SWC internal behavior elements +* DataReceiveErrorEvent | DATA-RECEIVE-ERROR-EVENT * DataReceivedEvent | DATA-RECEIVED-EVENT +* DataSendCompletedEvent | DATA-SEND-COMPLETED-EVENT +* DataWriteCompletedEvent | DATA-WRITE-COMPLETED-EVENT * InitEvent | INIT-EVENT +* ModeSwitchedAckEvent | MODE-SWITCHED-ACK-EVENT +* OperationInvokedEvent | OPERATION-INVOKED-EVENT +* SwcModeSwitchEvent | SWC-MODE-SWITCH-EVENT +* TimingEvent | TIMING-EVENT * InternalBehavior | SWC-INTERNAL-BEHAVIOR (Partly implemented) * RunnableEntity | RUNNABLE-ENTITY diff --git a/src/autosar/xml/element.py b/src/autosar/xml/element.py index 19d4394..2666676 100644 --- a/src/autosar/xml/element.py +++ b/src/autosar/xml/element.py @@ -45,7 +45,10 @@ ExclusiveAreaRef, ExclusiveAreaNestingOrderRef, AbstractRequiredPortPrototypeRef, + AbstractProvidedPortPrototypeRef, RunnableEntityRef, + VariableAccessRef, + ModeSwitchPointRef, ) @@ -5260,7 +5263,7 @@ def __init__(self, context_port: AbstractRequiredPortPrototypeRef | None = None, target_data_element: VariableDataPrototypeRef | str | None = None, ) -> None: - # .CONTEXT-R-PORT-REF (Use same name as in RModeInAtomicSwcInstanceRef for consistency) + # .CONTEXT-R-PORT-REF (Keep name consistent in similar classes) self.context_port: AbstractRequiredPortPrototypeRef | None = None # .TARGET-DATA-ELEMENT-REF self.target_data_element: VariableDataPrototypeRef | None = None @@ -5268,6 +5271,23 @@ def __init__(self, self._assign_optional("target_data_element", target_data_element, VariableDataPrototypeRef) +class POperationInAtomicSwcInstanceRef(ARObject): + """ + Complex type AR:P-OPERATION-IN-ATOMIC-SWC-INSTANCE-REF + Tag variants: 'OPERATION-IREF' + """ + + def __init__(self, + context_port: AbstractProvidedPortPrototypeRef | None = None, + target_provided_operation: ClientServerOperationRef | str | None = None, + ) -> None: + # .CONTEXT-P-PORT-REF (Keep name consistent in similar classes) + self.context_port: AbstractProvidedPortPrototypeRef | None = None + # .TARGET-PROVIDED-OPERATION-REF + self.target_provided_operation: ClientServerOperationRef | None = None + self._assign_optional("context_port", context_port, AbstractProvidedPortPrototypeRef) + self._assign_optional("target_provided_operation", target_provided_operation, ClientServerOperationRef) + # --- SWC internal behavior elements @@ -5501,7 +5521,7 @@ def __init__(self, activation_reasons: ActivationReasonArgumentType = None, can_enter_leave: CanEnterLeaveArgumentType = None, exclusive_area_nesting_order: ExclusiveAreaNestingOrderArgumentType = None, - minimum_start_interval: float | None = None, + minimum_start_interval: int | float | None = None, reentrancy_level: ar_enum.ReentrancyLevel | None = None, runs_insides: RunsInsidesArgumentType = None, sw_addr_method: str | SwAddrMethodRef | None = None, @@ -5632,6 +5652,39 @@ def append_disabled_mode(self, disabled_mode: RModeInAtomicSwcInstanceRef) -> No raise TypeError("disabled_mode must be of type RModeInAtomicSwcInstanceRef") +class DataReceiveErrorEvent(RteEvent): + """ + Complex Type AR:DATA-RECEIVE-ERROR-EVENT + Tag variants: 'DATA-RECEIVE-ERROR-EVENT' + """ + + def __init__(self, + name: str, + start_on_event: RunnableEntityRef | str | None = None, + data: RVariableInAtomicSwcInstanceRef | None = None, + **kwargs) -> None: + super().__init__(name, start_on_event, **kwargs) + # .DATA-IREF + self.data: RVariableInAtomicSwcInstanceRef | None = None + self._assign_optional_strict("data", data, RVariableInAtomicSwcInstanceRef) + + @classmethod + def make(cls, + name: str, + start_on_event: RunnableEntityRef | str | None = None, + context_port: AbstractRequiredPortPrototypeRef | None = None, + target_data_element: VariableDataPrototypeRef | str | None = None, + **kwargs) -> "DataReceiveErrorEvent": + """ + #convenience-method + + Simplified creation method that automatically creates + and uses the necessary RVariableInAtomicSwcInstanceRef object + """ + data = RVariableInAtomicSwcInstanceRef(context_port, target_data_element) + return cls(name, start_on_event, data, **kwargs) + + class DataReceivedEvent(RteEvent): """ Complex Type AR:DATA-RECEIVED-EVENT @@ -5665,6 +5718,40 @@ def make(cls, return cls(name, start_on_event, data, **kwargs) +class DataSendCompletedEvent(RteEvent): + """ + Complex Type AR:DATA-SEND-COMPLETED-EVENT + Tag variants: 'DATA-SEND-COMPLETED-EVENT' + """ + + def __init__(self, + name: str, + start_on_event: RunnableEntityRef | str | None = None, + event_source: VariableAccessRef | str | None = None, + **kwargs) -> None: + super().__init__(name, start_on_event, **kwargs) + # .EVENT-SOURCE-REF + self.event_source: VariableAccessRef | None = None + self._assign_optional("event_source", event_source, VariableAccessRef) + + +class DataWriteCompletedEvent(RteEvent): + """ + Complex Type AR:DATA-WRITE-COMPLETED-EVENT + Tag variants: 'DATA-WRITE-COMPLETED-EVENT' + """ + + def __init__(self, + name: str, + start_on_event: RunnableEntityRef | str | None = None, + event_source: VariableAccessRef | str | None = None, + **kwargs) -> None: + super().__init__(name, start_on_event, **kwargs) + # .EVENT-SOURCE-REF + self.event_source: VariableAccessRef | None = None + self._assign_optional("event_source", event_source, VariableAccessRef) + + class InitEvent(RteEvent): """ Complex Type AR:INIT-EVENT @@ -5673,6 +5760,139 @@ class InitEvent(RteEvent): """ +class ModeSwitchedAckEvent(RteEvent): + """ + Complex type AR:MODE-SWITCHED-ACK-EVENT + Tag variants: 'MODE-SWITCHED-ACK-EVENT' + """ + + def __init__(self, + name: str, + start_on_event: RunnableEntityRef | str | None = None, + event_source: ModeSwitchPointRef | str | None = None, + **kwargs) -> None: + super().__init__(name, start_on_event, **kwargs) + # .EVENT-SOURCE-REF + self.event_source: ModeSwitchPointRef | None = None + self._assign_optional("event_source", event_source, ModeSwitchPointRef) + + +class OperationInvokedEvent(RteEvent): + """ + Complex type AR:OPERATION-INVOKED-EVENT + Tag variants: 'OPERATION-INVOKED-EVENT' + """ + + def __init__(self, + name: str, + start_on_event: RunnableEntityRef | str | None = None, + operation: POperationInAtomicSwcInstanceRef | None = None, + **kwargs) -> None: + super().__init__(name, start_on_event, **kwargs) + # .OPERATION-IREF + self.operation: POperationInAtomicSwcInstanceRef | None = None + self._assign_optional_strict("operation", operation, POperationInAtomicSwcInstanceRef) + + @classmethod + def make(cls, + name: str, + start_on_event: RunnableEntityRef | str | None = None, + context_port: AbstractProvidedPortPrototypeRef | None = None, + target_provided_operation: ClientServerOperationRef | str | None = None, + **kwargs) -> "OperationInvokedEvent": + """ + #convenience-method + + Simplified creation method that automatically creates + and uses the necessary POperationInAtomicSwcInstanceRef object + """ + operation = POperationInAtomicSwcInstanceRef(context_port, target_provided_operation) + return cls(name, start_on_event, operation, **kwargs) + + +SwcModeSwitchEventModeType = Union[RModeInAtomicSwcInstanceRef, + tuple[RModeInAtomicSwcInstanceRef, RModeInAtomicSwcInstanceRef], + None] + + +class SwcModeSwitchEvent(RteEvent): + """ + Complex type AR:SWC-MODE-SWITCH-EVENT + Tag variants: 'SWC-MODE-SWITCH-EVENT' + """ + + def __init__(self, + name: str, + start_on_event: RunnableEntityRef | str | None = None, + activation: ar_enum.ModeActivationKind | None = None, + mode: SwcModeSwitchEventModeType = None, + **kwargs) -> None: + super().__init__(name, start_on_event, **kwargs) + # .ACTIVATION + self.activation: ar_enum.ModeActivationKind | None = None + # .MODE-IREFS + self.mode: SwcModeSwitchEventModeType = None + + self._assign_optional("activation", activation, ar_enum.ModeActivationKind) + if mode is not None: + if isinstance(mode, RModeInAtomicSwcInstanceRef): + self.mode = mode + elif isinstance(mode, tuple): + if (isinstance(mode[0], RModeInAtomicSwcInstanceRef) and # noqa W504 + isinstance(mode[1], RModeInAtomicSwcInstanceRef)): + self.mode = mode + else: + raise TypeError("Both values of mode tuple must be of type RModeInAtomicSwcInstanceRef") + else: + msg_part1 = "Invalid type for parameter 'mode'. " + msg_part2 = "Expected types are RModeInAtomicSwcInstanceRef or tuple of same type." + msg_part3 = f"Got {str(type(mode))}" + raise TypeError(msg_part1 + msg_part2 + msg_part3) + + @classmethod + def make(cls, + name: str, + start_on_event: RunnableEntityRef | str | None = None, + activation: ar_enum.ModeActivationKind | None = None, + context_port: AbstractRequiredPortPrototypeRef | None = None, + context_mode_declaration_group_prototype: ModeDeclarationGroupPrototypeRef | None = None, + target_mode_declaration: ModeDeclarationRef | None = None, + **kwargs) -> "SwcModeSwitchEvent": + """ + #convenience-method + + Only suitable for ON-ENTRY and ON-EXIT activation types. + For ON-TRANSITION activation, use the class constructor instead. + + """ + mode = RModeInAtomicSwcInstanceRef(context_port, + context_mode_declaration_group_prototype, + target_mode_declaration) + return cls(name, start_on_event, activation, mode, **kwargs) + + +class TimingEvent(RteEvent): + """ + Complex type AR:TIMING-EVENT + Tag variants: 'TIMING-EVENT' + """ + + def __init__(self, + name: str, + start_on_event: RunnableEntityRef | str | None = None, + offset: int | float | None = None, + period: int | float | None = None, + **kwargs) -> None: + super().__init__(name, start_on_event, **kwargs) + # .OFFSET + self.offset: int | float | None = None + # .PERIOD + self.period: int | float | None = None + + self._assign_optional("offset", offset, float) + self._assign_optional("period", period, float) + + class InternalBehavior(Identifiable): """ Group AR:INTERNAL-BEHAVIOR diff --git a/src/autosar/xml/enumeration.py b/src/autosar/xml/enumeration.py index 45f4903..2f0e23a 100644 --- a/src/autosar/xml/enumeration.py +++ b/src/autosar/xml/enumeration.py @@ -227,23 +227,25 @@ class IdentifiableSubTypes(Enum): MODE_DECLARATION_GROUP = 33 MODE_DECLARATION_GROUP_PROTOTYPE = 34 MODE_SWITCH_INTERFACE = 35 - NV_DATA_INTERFACE = 36 - P_PORT_PROTOTYPE = 37 - PARAMETER_INTERFACE = 38 - PARAMETER_DATA_PROTOTYPE = 39 - PHYSICAL_DIMENSION = 40 - PORT_PROTOTYPE = 41 - PR_PORT_PROTOTYPE = 42 - R_PORT_PROTOTYPE = 43 - RUNNABLE_ENTITY = 44 - SENDER_RECEIVER_INTERFACE = 45 - SW_ADDR_METHOD = 46 - SW_BASE_TYPE = 47 - SW_COMPONENT_PROTOTYPE = 48 - SWC_IMPLEMENTATION = 49 - SWC_INTERNAL_BEHAVIOR = 50 - UNIT = 51 - VARIABLE_DATA_PROTOTYPE = 52 + MODE_SWITCH_POINT = 36 + NV_DATA_INTERFACE = 37 + P_PORT_PROTOTYPE = 38 + PARAMETER_INTERFACE = 39 + PARAMETER_DATA_PROTOTYPE = 40 + PHYSICAL_DIMENSION = 41 + PORT_PROTOTYPE = 42 + PR_PORT_PROTOTYPE = 43 + R_PORT_PROTOTYPE = 44 + RUNNABLE_ENTITY = 45 + SENDER_RECEIVER_INTERFACE = 46 + SW_ADDR_METHOD = 47 + SW_BASE_TYPE = 48 + SW_COMPONENT_PROTOTYPE = 49 + SWC_IMPLEMENTATION = 50 + SWC_INTERNAL_BEHAVIOR = 51 + UNIT = 52 + VARIABLE_ACCESS = 53 + VARIABLE_DATA_PROTOTYPE = 54 class IntervalType(Enum): @@ -410,6 +412,16 @@ class Language(Enum): ZU = 136 # Zulu +class ModeActivationKind(Enum): + """ + AR:MODE-ACTIVATION-KIND--SIMPLE + """ + + ON_ENTRY = 0 + ON_EXIT = 1 + ON_TRANSITION = 2 + + class ModeErrorReactionPolicy(Enum): """ AR:MODE-ERROR-REACTION-POLICY-ENUM--SIMPLE @@ -741,6 +753,7 @@ class VersionedTextValue: "MODE-DECLARATION-GROUP": IdentifiableSubTypes.MODE_DECLARATION_GROUP, "MODE-DECLARATION-GROUP-PROTOTYPE": IdentifiableSubTypes.MODE_DECLARATION_GROUP_PROTOTYPE, "MODE-SWITCH-INTERFACE": IdentifiableSubTypes.MODE_SWITCH_INTERFACE, + "MODE-SWITCH-POINT": IdentifiableSubTypes.MODE_SWITCH_POINT, "NV-DATA-INTERFACE": IdentifiableSubTypes.NV_DATA_INTERFACE, "P-PORT-PROTOTYPE": IdentifiableSubTypes.P_PORT_PROTOTYPE, "PARAMETER-DATA-PROTOTYPE": IdentifiableSubTypes.PARAMETER_DATA_PROTOTYPE, @@ -757,6 +770,7 @@ class VersionedTextValue: "SWC-IMPLEMENTATION": IdentifiableSubTypes.SWC_IMPLEMENTATION, "SWC-INTERNAL-BEHAVIOR": IdentifiableSubTypes.SWC_INTERNAL_BEHAVIOR, "UNIT": IdentifiableSubTypes.UNIT, + "VARIABLE-ACCESS": IdentifiableSubTypes.VARIABLE_ACCESS, "VARIABLE-DATA-PROTOTYPE": IdentifiableSubTypes.VARIABLE_DATA_PROTOTYPE, }, "IntervalType": { @@ -906,6 +920,11 @@ class VersionedTextValue: "ZH": Language.ZH, "ZU": Language.ZU, }, + "ModeActivationKind": { + "ON-ENTRY": ModeActivationKind.ON_ENTRY, + "ON-EXIT": ModeActivationKind.ON_EXIT, + "ON-TRANSITION": ModeActivationKind.ON_TRANSITION, + }, "ModeErrorReactionPolicy": { "DEFAULT-MODE": ModeErrorReactionPolicy.DEFAULT_MODE, "LAST-MODE": ModeErrorReactionPolicy.LAST_MODE @@ -1106,23 +1125,25 @@ def xml_to_enum(enum_type_name: str, xml_text: str, schema_version: int = ar_bas "MODE-DECLARATION-GROUP", # 33 "MODE-DECLARATION-GROUP-PROTOTYPE", # 34 "MODE-SWITCH-INTERFACE", # 35 - "NV-DATA-INTERFACE", # 36 - "P-PORT-PROTOTYPE", # 37 - "PARAMETER-INTERFACE", # 38 - "PARAMETER-DATA-PROTOTYPE", # 39 - "PHYSICAL-DIMENSION", # 40 - "PORT-PROTOTYPE", # 41 - "PR-PORT-PROTOTYPE", # 42 - "R-PORT-PROTOTYPE", # 43 - "RUNNABLE-ENTITY", # 44 - "SENDER-RECEIVER-INTERFACE", # 45 - "SW-ADDR-METHOD", # 46 - "SW-BASE-TYPE", # 47 - "SW-COMPONENT-PROTOTYPE", # 48 - "SWC-IMPLEMENTATION", # 49 - "SWC-INTERNAL-BEHAVIOR", # 50 - "UNIT", # 51 - "VARIABLE-DATA-PROTOTYPE", # 52 + "MODE-SWITCH-POINT", # 36 + "NV-DATA-INTERFACE", # 37 + "P-PORT-PROTOTYPE", # 38 + "PARAMETER-INTERFACE", # 39 + "PARAMETER-DATA-PROTOTYPE", # 40 + "PHYSICAL-DIMENSION", # 41 + "PORT-PROTOTYPE", # 42 + "PR-PORT-PROTOTYPE", # 43 + "R-PORT-PROTOTYPE", # 44 + "RUNNABLE-ENTITY", # 45 + "SENDER-RECEIVER-INTERFACE", # 46 + "SW-ADDR-METHOD", # 47 + "SW-BASE-TYPE", # 48 + "SW-COMPONENT-PROTOTYPE", # 49 + "SWC-IMPLEMENTATION", # 50 + "SWC-INTERNAL-BEHAVIOR", # 51 + "UNIT", # 52 + "VARIABLE-ACCESS", # 53 + "VARIABLE-DATA-PROTOTYPE", # 54 ], "IntervalType": [ "CLOSED", # 0 @@ -1271,6 +1292,11 @@ def xml_to_enum(enum_type_name: str, xml_text: str, schema_version: int = ar_bas "ZH", # 135 "ZU", # 136 ], + "ModeActivationKind": [ + "ON-ENTRY", # 0 + "ON-EXIT", # 1 + "ON-TRANSITION", # 2 + ], "ModeErrorReactionPolicy": [ "DEFAULT-MODE", # 0 "LAST-MODE" # 1 diff --git a/src/autosar/xml/reader.py b/src/autosar/xml/reader.py index 9226dcd..59845a2 100644 --- a/src/autosar/xml/reader.py +++ b/src/autosar/xml/reader.py @@ -266,11 +266,18 @@ def __init__(self, 'VARIABLE-ACCESS': self._read_variable_access, 'EXECUTABLE-ENTITY-ACTIVATION-REASON': self._read_executable_entity_activation_reason, 'EXCLUSIVE-AREA-REF-CONDITIONAL': self._read_exclusive_area_ref_conditional, - 'DISABLED-MODE-IREF': self._read_rmode_in_atomic_swc_instance_ref, + 'DISABLED-MODE-IREF': self._read_r_mode_in_atomic_swc_instance_ref, 'SWC-INTERNAL-BEHAVIOR': self._read_swc_internal_behavior, 'RUNNABLE-ENTITY': self._read_runnable_entity, + 'DATA-RECEIVE-ERROR-EVENT': self._read_data_receive_error_event, 'DATA-RECEIVED-EVENT': self._read_data_received_event, + 'DATA-SEND-COMPLETED-EVENT': self._read_send_completed_event, + 'DATA-WRITE-COMPLETED-EVENT': self._read_data_write_completed_event, 'INIT-EVENT': self._read_init_event, + 'MODE-SWITCHED-ACK-EVENT': self._read_mode_switched_ack_event, + 'OPERATION-INVOKED-EVENT': self._read_operation_invoked_event, + 'SWC-MODE-SWITCH-EVENT': self._read_swc_mode_switch_event, + 'TIMING-EVENT': self._read_timing_event, } self.switcher_all = {} @@ -331,7 +338,7 @@ def read_str_elem(self, xml: str, type_name: str | None = None) -> None | ar_ele else: raise NotImplementedError(f"Found no reader for '{elem.tag}'") - # Utility methods + # --- Utility methods def _report_unprocessed_elements(self, xml_elements: ChildElementMap): """ @@ -412,7 +419,7 @@ def _read_integer(self, text: str) -> int: raise ar_exception.ParseError(f"Failed to parse integer: {text}") from exc return value - # Abstract base classes + # --- Abstract base classes def _read_referrable(self, element_map: ChildElementMap, data: dict) -> None: """ @@ -514,7 +521,7 @@ def _read_admin_data_sd(self, xml_element: ElementTree.Element) -> dict[str, str value = xml_element.text return {key: value} - # AUTOSAR Document + # --- AUTOSAR Document def _read_root_element(self) -> None: self._read_schema_version() @@ -620,7 +627,7 @@ def _read_sub_packages(self, package: ar_element.Package, xml_packages: ElementT assert isinstance(child_package, ar_element.Package) package.append(child_package) - # Documentation elements + # --- Documentation elements def _read_annotation(self, xml_elem: ElementTree.Element) -> ar_element.Annotation: """ @@ -1247,7 +1254,7 @@ def _read_compu_numerator_denominator_values(self, xml_element: ElementTree.Elem values.append(num_val.value) return tuple(values) - # Constraint elements + # --- Constraint elements def _read_data_constraint(self, xml_element: ElementTree.Element) -> ar_element.DataConstraint: """ @@ -1387,7 +1394,7 @@ def _read_scale_constraint(self, xml_element: ElementTree.Element) -> ar_element data["upper_limit_type"] = interval_type return ar_element.ScaleConstraint(**data) - # Unit elements + # --- Unit elements def _read_unit(self, xml_element: ElementTree.Element) -> ar_element.Unit: """ @@ -1422,7 +1429,7 @@ def _read_unit_group(self, child_elements: ChildElementMap, data: dict) -> None: if xml_child is not None: data["physical_dimension_ref"] = self._read_physical_dimension_ref(xml_child) - # Common structure elements + # --- Common structure elements def _read_data_filter(self, xml_element: ElementTree.Element) -> ar_element.DataFilter: """ @@ -1522,7 +1529,7 @@ def _read_implementation(self, child_elements: ChildElementMap, data: dict) -> N child_elements.skip("USED-CODE-GENERATOR") child_elements.skip("VENDOR-ID") - # Data type elements + # --- Data type elements def _read_sw_addr_method(self, xml_element: ElementTree.Element) -> ar_element.SwAddrMethod: """ @@ -2204,7 +2211,7 @@ def _read_argument_data_prototype_group(self, child_elements: ChildElementMap, d child_elements.skip("TYPE-BLUEPRINTS") # Not supported child_elements.skip("VARIATION-POINT") # Not supported -# --- Reference elements + # --- Reference elements def _read_base_ref_attributes(self, attr: dict, data: dict) -> None: """ @@ -2214,13 +2221,15 @@ def _read_base_ref_attributes(self, attr: dict, data: dict) -> None: if data['dest'] is None: raise ar_exception.ParseError("Missing required attribute 'DEST'") + def _read_ref_dest(self, xml_elem: ElementTree.Element) -> ar_enum.IdentifiableSubTypes: + data = {} + self._read_base_ref_attributes(xml_elem.attrib, data) + return ar_enum.xml_to_enum('IdentifiableSubTypes', data['dest'], self.schema_version) + def _read_compu_method_ref(self, xml_elem: ElementTree.Element) -> ar_element.CompuMethodRef: """ Reads AR:COMPU-METHOD-REF - Type: Concrete Tag Variants: 'COMPU-METHOD-REF' - - Note: the name of this complex type is anonymous in the XML achema """ data = {} self._read_base_ref_attributes(xml_elem.attrib, data) @@ -2616,23 +2625,48 @@ def _read_abstract_required_port_prototype_ref(self, """ Reads references to AR:ABSTRACT-REQUIRED-PORT-PROTOTYPE--SUBTYPES-ENUM """ - data = {} - self._read_base_ref_attributes(xml_elem.attrib, data) - dest_enum = ar_enum.xml_to_enum('IdentifiableSubTypes', data['dest'], self.schema_version) + dest_enum = self._read_ref_dest(xml_elem) return ar_element.AbstractRequiredPortPrototypeRef(xml_elem.text, dest_enum) + def _read_abstract_provided_port_prototype_ref(self, + xml_elem: ElementTree.Element + ) -> ar_element.AbstractProvidedPortPrototypeRef: + """ + Reads references to AR:ABSTRACT-PROVIDED-PORT-PROTOTYPE--SUBTYPES-ENUM + """ + dest_enum = self._read_ref_dest(xml_elem) + return ar_element.AbstractProvidedPortPrototypeRef(xml_elem.text, dest_enum) + def _read_runnable_entity_ref(self, xml_elem: ElementTree.Element ) -> ar_element.RunnableEntityRef: """ Reads references to RUNNABLE-ENTITY--SUBTYPES-ENUM """ - data = {} - self._read_base_ref_attributes(xml_elem.attrib, data) - dest_enum = ar_enum.xml_to_enum('IdentifiableSubTypes', data['dest'], self.schema_version) + dest_enum = self._read_ref_dest(xml_elem) return ar_element.RunnableEntityRef(xml_elem.text, dest_enum) -# --- Constant and value specifications + def _read_variable_access_ref(self, + xml_elem: ElementTree.Element + ) -> ar_element.VariableAccessRef: + """ + Reads references to AR:VARIABLE-ACCESS--SUBTYPES-ENUM + Tag variants: 'EVENT-SOURCE-REF' | 'VARIABLE-ACCESS-REF' | 'TARGET-VARIABLE-ACCESS-REF' + """ + dest_enum = self._read_ref_dest(xml_elem) + return ar_element.VariableAccessRef(xml_elem.text, dest_enum) + + def _read_mode_switch_point_ref(self, + xml_elem: ElementTree.Element + ) -> ar_element.ModeSwitchPointRef: + """ + Reads references to AR:MODE-SWITCH-POINT--SUBTYPES-ENUM + Tag variants: 'EVENT-SOURCE-REF' + """ + dest_enum = self._read_ref_dest(xml_elem) + return ar_element.ModeSwitchPointRef(xml_elem.text, dest_enum) + + # --- Constant and value specifications def _read_text_value_specification(self, xml_element: ElementTree.Element) -> ar_element.TextValueSpecification: @@ -4278,9 +4312,9 @@ def _read_swc_implementation_group(self, child_elements: ChildElementMap, data: if xml_child is not None: data["required_rte_vendor"] = xml_child.text - def _read_rmode_in_atomic_swc_instance_ref(self, - xml_element: ElementTree.Element - ) -> ar_element.RModeInAtomicSwcInstanceRef: + def _read_r_mode_in_atomic_swc_instance_ref(self, + xml_element: ElementTree.Element + ) -> ar_element.RModeInAtomicSwcInstanceRef: """ Reads complex type AR:R-MODE-IN-ATOMIC-SWC-INSTANCE-REF Tag variants: 'DISABLED-MODE-IREF' | 'MODE-IREF' @@ -4300,9 +4334,9 @@ def _read_rmode_in_atomic_swc_instance_ref(self, self._report_unprocessed_elements(child_elements) return ar_element.RModeInAtomicSwcInstanceRef(**data) - def _read_rvariable_in_atomic_swc_instance_ref(self, - xml_element: ElementTree.Element - ) -> ar_element.RVariableInAtomicSwcInstanceRef: + def _read_r_variable_in_atomic_swc_instance_ref(self, + xml_element: ElementTree.Element + ) -> ar_element.RVariableInAtomicSwcInstanceRef: """ Reads complex type AR:R-VARIABLE-IN-ATOMIC-SWC-INSTANCE-REF Tag variants: 'DATA-IREF' @@ -4318,6 +4352,24 @@ def _read_rvariable_in_atomic_swc_instance_ref(self, self._report_unprocessed_elements(child_elements) return ar_element.RVariableInAtomicSwcInstanceRef(**data) + def _read_p_operation_in_atomic_swc_instance_ref(self, + xml_element: ElementTree.Element + ) -> ar_element.POperationInAtomicSwcInstanceRef: + """ + Complex type AR:P-OPERATION-IN-ATOMIC-SWC-INSTANCE-REF + Tag variants: 'OPERATION-IREF' + """ + data = {} + child_elements = ChildElementMap(xml_element) + xml_child = child_elements.get("CONTEXT-P-PORT-REF") + if xml_child is not None: + data["context_port"] = self._read_abstract_provided_port_prototype_ref(xml_child) + xml_child = child_elements.get("TARGET-PROVIDED-OPERATION-REF") + if xml_child is not None: + data["target_provided_operation"] = self._read_client_server_operation_ref(xml_child) + self._report_unprocessed_elements(child_elements) + return ar_element.POperationInAtomicSwcInstanceRef(**data) + # --- Internal Behavior elements def _read_variable_in_impl_data_instance_ref(self, @@ -4576,13 +4628,32 @@ def _read_rte_event(self, child_elements: ChildElementMap, data: dict) -> None: if xml_child is not None: disabled_modes = [] for xml_grand_child in xml_child.findall("./DISABLED-MODE-IREF"): - disabled_modes.append(self._read_rmode_in_atomic_swc_instance_ref(xml_grand_child)) + disabled_modes.append(self._read_r_mode_in_atomic_swc_instance_ref(xml_grand_child)) data["disabled_modes"] = disabled_modes xml_child = child_elements.get("START-ON-EVENT-REF") if xml_child is not None: data["start_on_event"] = self._read_runnable_entity_ref(xml_child) child_elements.skip("VARIATION-POINT") # Not supported + def _read_data_receive_error_event(self, + xml_element: ElementTree.Element + ) -> ar_element.DataReceiveErrorEvent: + """ + Reads complex Type AR:DATA-RECEIVE-ERROR-EVENT + Tag variants: 'DATA-RECEIVE-ERROR-EVENT' + """ + data = {} + child_elements = ChildElementMap(xml_element) + self._read_referrable(child_elements, data) + self._read_multi_language_referrable(child_elements, data) + self._read_identifiable(child_elements, xml_element.attrib, data) + self._read_rte_event(child_elements, data) + xml_child = child_elements.get("DATA-IREF") + if xml_child is not None: + data["data"] = self._read_r_variable_in_atomic_swc_instance_ref(xml_child) + self._report_unprocessed_elements(child_elements) + return ar_element.DataReceiveErrorEvent(**data) + def _read_data_received_event(self, xml_element: ElementTree.Element ) -> ar_element.DataReceivedEvent: @@ -4598,10 +4669,48 @@ def _read_data_received_event(self, self._read_rte_event(child_elements, data) xml_child = child_elements.get("DATA-IREF") if xml_child is not None: - data["data"] = self._read_rvariable_in_atomic_swc_instance_ref(xml_child) + data["data"] = self._read_r_variable_in_atomic_swc_instance_ref(xml_child) self._report_unprocessed_elements(child_elements) return ar_element.DataReceivedEvent(**data) + def _read_send_completed_event(self, + xml_element: ElementTree.Element + ) -> ar_element.DataSendCompletedEvent: + """ + Reads complex Type AR:DATA-SEND-COMPLETED-EVENT + Tag variants: 'DATA-SEND-COMPLETED-EVENT' + """ + data = {} + child_elements = ChildElementMap(xml_element) + self._read_referrable(child_elements, data) + self._read_multi_language_referrable(child_elements, data) + self._read_identifiable(child_elements, xml_element.attrib, data) + self._read_rte_event(child_elements, data) + xml_child = child_elements.get("EVENT-SOURCE-REF") + if xml_child is not None: + data["event_source"] = self._read_variable_access_ref(xml_child) + self._report_unprocessed_elements(child_elements) + return ar_element.DataSendCompletedEvent(**data) + + def _read_data_write_completed_event(self, + xml_element: ElementTree.Element + ) -> ar_element.DataWriteCompletedEvent: + """ + Reads complex type AR:DATA-WRITE-COMPLETED-EVENT + Tag variants: 'DATA-WRITE-COMPLETED-EVENT' + """ + data = {} + child_elements = ChildElementMap(xml_element) + self._read_referrable(child_elements, data) + self._read_multi_language_referrable(child_elements, data) + self._read_identifiable(child_elements, xml_element.attrib, data) + self._read_rte_event(child_elements, data) + xml_child = child_elements.get("EVENT-SOURCE-REF") + if xml_child is not None: + data["event_source"] = self._read_variable_access_ref(xml_child) + self._report_unprocessed_elements(child_elements) + return ar_element.DataWriteCompletedEvent(**data) + def _read_init_event(self, xml_element: ElementTree.Element ) -> ar_element.InitEvent: @@ -4618,6 +4727,104 @@ def _read_init_event(self, self._report_unprocessed_elements(child_elements) return ar_element.InitEvent(**data) + def _read_mode_switched_ack_event(self, + xml_element: ElementTree.Element + ) -> ar_element.ModeSwitchedAckEvent: + """ + Reads Complex type MODE-SWITCHED-ACK-EVENT + Tag variants: 'MODE-SWITCHED-ACK-EVENT' + """ + data = {} + child_elements = ChildElementMap(xml_element) + self._read_referrable(child_elements, data) + self._read_multi_language_referrable(child_elements, data) + self._read_identifiable(child_elements, xml_element.attrib, data) + self._read_rte_event(child_elements, data) + xml_child = child_elements.get("EVENT-SOURCE-REF") + if xml_child is not None: + data["event_source"] = self._read_mode_switch_point_ref(xml_child) + self._report_unprocessed_elements(child_elements) + return ar_element.ModeSwitchedAckEvent(**data) + + def _read_operation_invoked_event(self, + xml_element: ElementTree.Element + ) -> ar_element.OperationInvokedEvent: + """ + Complex type AR:OPERATION-INVOKED-EVENT + Tag variants: 'OPERATION-INVOKED-EVENT' + """ + data = {} + child_elements = ChildElementMap(xml_element) + self._read_referrable(child_elements, data) + self._read_multi_language_referrable(child_elements, data) + self._read_identifiable(child_elements, xml_element.attrib, data) + self._read_rte_event(child_elements, data) + xml_child = child_elements.get("OPERATION-IREF") + if xml_child is not None: + data["operation"] = self._read_p_operation_in_atomic_swc_instance_ref(xml_child) + self._report_unprocessed_elements(child_elements) + return ar_element.OperationInvokedEvent(**data) + + def _read_swc_mode_switch_event(self, + xml_element: ElementTree.Element + ) -> ar_element.SwcModeSwitchEvent: + """ + Reads complex type AR:SWC-MODE-SWITCH-EVENT + Tag variants: 'SWC-MODE-SWITCH-EVENT' + """ + data = {} + child_elements = ChildElementMap(xml_element) + self._read_referrable(child_elements, data) + self._read_multi_language_referrable(child_elements, data) + self._read_identifiable(child_elements, xml_element.attrib, data) + self._read_rte_event(child_elements, data) + self._read_swc_mode_switch_event_group(child_elements, data) + self._report_unprocessed_elements(child_elements) + return ar_element.SwcModeSwitchEvent(**data) + + def _read_swc_mode_switch_event_group(self, child_elements: ChildElementMap, data: dict) -> None: + """ + Reads group AR:SWC-MODE-SWITCH-EVENT + """ + xml_child = child_elements.get("ACTIVATION") + if xml_child is not None: + data["activation"] = ar_enum.xml_to_enum("ModeActivationKind", xml_child.text) + xml_child = child_elements.get("MODE-IREFS") + if xml_child is not None: + modes = [] + for xml_grand_child in xml_child.findall("./MODE-IREF"): + modes.append(self._read_r_mode_in_atomic_swc_instance_ref(xml_grand_child)) + if len(modes) == 0: + pass + elif len(modes) == 1: + data["mode"] = modes[0] + elif len(modes) == 2: + data["mode"] = (modes[0], modes[1]) + else: + self._raise_parse_error(xml_child, "Max two mode references are allowed") + + def _read_timing_event(self, + xml_element: ElementTree.Element + ) -> ar_element.TimingEvent: + """ + Reads complex type AR:TIMING-EVENT + Tag variants: 'TIMING-EVENT' + """ + data = {} + child_elements = ChildElementMap(xml_element) + self._read_referrable(child_elements, data) + self._read_multi_language_referrable(child_elements, data) + self._read_identifiable(child_elements, xml_element.attrib, data) + self._read_rte_event(child_elements, data) + xml_child = child_elements.get("OFFSET") + if xml_child is not None: + data["offset"] = self._read_number(xml_child.text) + xml_child = child_elements.get("PERIOD") + if xml_child is not None: + data["period"] = self._read_number(xml_child.text) + self._report_unprocessed_elements(child_elements) + return ar_element.TimingEvent(**data) + def _read_swc_internal_behavior(self, xml_element: ElementTree.Element) -> ar_element.SwcInternalBehavior: """ Reads complex type AR:SWC-INTERNAL-BEHAVIOR diff --git a/src/autosar/xml/reference.py b/src/autosar/xml/reference.py index b363fb6..890e654 100644 --- a/src/autosar/xml/reference.py +++ b/src/autosar/xml/reference.py @@ -570,9 +570,22 @@ def accepted_sub_types(cls) -> set[ar_enum.IdentifiableSubTypes]: ar_enum.IdentifiableSubTypes.R_PORT_PROTOTYPE} +class AbstractProvidedPortPrototypeRef(BaseRef): + """ + AR:ABSTRACT-PROVIDED-PORT-PROTOTYPE--SUBTYPES-ENUM + """ + + @classmethod + def accepted_sub_types(cls) -> set[ar_enum.IdentifiableSubTypes]: + """Acceptable values for dest""" + return {ar_enum.IdentifiableSubTypes.ABSTRACT_PROVIDED_PORT_PROTOTYPE, + ar_enum.IdentifiableSubTypes.P_PORT_PROTOTYPE, + ar_enum.IdentifiableSubTypes.PR_PORT_PROTOTYPE} + + class RunnableEntityRef(BaseRef): """ - RUNNABLE-ENTITY--SUBTYPES-ENUM + AR:RUNNABLE-ENTITY--SUBTYPES-ENUM """ def __init__(self, value: str, @@ -584,3 +597,35 @@ def __init__(self, value: str, def accepted_sub_types(cls) -> set[ar_enum.IdentifiableSubTypes]: """Acceptable values for dest""" return {ar_enum.IdentifiableSubTypes.RUNNABLE_ENTITY} + + +class VariableAccessRef(BaseRef): + """ + VARIABLE-ACCESS--SUBTYPES-ENUM + """ + + def __init__(self, value: str, + dest: ar_enum.IdentifiableSubTypes = ar_enum.IdentifiableSubTypes.VARIABLE_ACCESS + ) -> None: + super().__init__(value, dest) + + @classmethod + def accepted_sub_types(cls) -> set[ar_enum.IdentifiableSubTypes]: + """Acceptable values for dest""" + return {ar_enum.IdentifiableSubTypes.VARIABLE_ACCESS} + + +class ModeSwitchPointRef(BaseRef): + """ + AR:MODE-SWITCH-POINT--SUBTYPES-ENUM + """ + + def __init__(self, value: str, + dest: ar_enum.IdentifiableSubTypes = ar_enum.IdentifiableSubTypes.MODE_SWITCH_POINT + ) -> None: + super().__init__(value, dest) + + @classmethod + def accepted_sub_types(cls) -> set[ar_enum.IdentifiableSubTypes]: + """Acceptable values for dest""" + return {ar_enum.IdentifiableSubTypes.MODE_SWITCH_POINT} diff --git a/src/autosar/xml/writer.py b/src/autosar/xml/writer.py index 6be497e..bbfcd03 100644 --- a/src/autosar/xml/writer.py +++ b/src/autosar/xml/writer.py @@ -330,7 +330,7 @@ def __init__(self, 'AssemblySwConnector': self._write_assembly_sw_connector, 'DelegationSwConnector': self._write_delegation_sw_connector, 'PassThroughSwConnector': self._write_passthrough_sw_connector, - 'RModeInAtomicSwcInstanceRef': self._write_rmode_in_atomic_swc_instance_ref, + 'RModeInAtomicSwcInstanceRef': self._write_r_mode_in_atomic_swc_instance_ref, # SWC internal behavior elements 'ArVariableInImplementationDataInstanceRef': self._write_variable_in_impl_data_instance_ref, 'VariableInAtomicSWCTypeInstanceRef': self._write_variable_in_atomic_swc_type_instance_ref, @@ -340,9 +340,15 @@ def __init__(self, 'ExecutableEntityActivationReason': self._write_executable_entity_activation_reason, 'ExclusiveAreaRefConditional': self._write_exclusive_area_ref_conditional, 'RunnableEntity': self._write_runnable_entity, + 'DataReceiveErrorEvent': self._write_data_receive_error_event, 'DataReceivedEvent': self._write_data_received_event, + 'DataSendCompletedEvent': self._write_data_send_completed_event, + 'DataWriteCompletedEvent': self._write_data_write_completed_event, 'InitEvent': self._write_init_event, - + 'ModeSwitchedAckEvent': self._write_mode_switched_ack_event, + 'OperationInvokedEvent': self._write_operation_invoked_event, + 'SwcModeSwitchEvent': self._write_swc_mode_switch_event, + 'TimingEvent': self._write_timing_event, } self.switcher_all = {} # All concrete elements (used for unit testing) self.switcher_all.update(self.switcher_collectable) @@ -2271,12 +2277,22 @@ def _write_abstract_required_port_prototype_ref(self, elem: ar_element.AbstractRequiredPortPrototypeRef, tag: str) -> None: """ - Writes references to ABSTRACT-REQUIRED-PORT-PROTOTYPE--SUBTYPES-ENUM + Writes references to AR:ABSTRACT-REQUIRED-PORT'-PROTOTYPE--SUBTYPES-ENUM + Tag variants: 'REQUIRED-OUTER-PORT-REF' | 'CONTEXT-R-PORT-REF' | 'CONTEXT-PORT-REF' + 'TARGET-R-PORT-REF' | """ assert isinstance(elem, ar_element.AbstractRequiredPortPrototypeRef) - attr: TupleList = [] - self._collect_base_ref_attr(elem, attr) - self._add_content(tag, elem.value, attr) + self._write_ref_content(elem, tag) + + def _write_abstract_provided_port_prototype_ref(self, + elem: ar_element.AbstractProvidedPortPrototypeRef, + tag: str) -> None: + """ + Writes references to AR:ABSTRACT-PROVIDED-PORT-PROTOTYPE--SUBTYPES-ENUM + Tag variants: 'CONTEXT-P-PORT-REF' | 'TARGET-P-PORT-REF' | 'PROVIDED-OUTER-PORT-REF' + """ + assert isinstance(elem, ar_element.AbstractProvidedPortPrototypeRef) + self._write_ref_content(elem, tag) def _write_swc_internal_behavior_ref(self, elem: ar_element.SwcInternalBehaviorRef, @@ -2298,6 +2314,26 @@ def _write_runnable_entity_ref(self, assert isinstance(elem, ar_element.RunnableEntityRef) self._write_ref_content(elem, tag) + def _write_variable_access_ref(self, + elem: ar_element.VariableAccessRef, + tag: str) -> None: + """ + Writes references to AR:VARIABLE-ACCESS--SUBTYPES-ENUM + Tag variants: 'EVENT-SOURCE-REF' | 'VARIABLE-ACCESS-REF' | 'TARGET-VARIABLE-ACCESS-REF' + """ + assert isinstance(elem, ar_element.VariableAccessRef) + self._write_ref_content(elem, tag) + + def _write_mode_switch_point_ref(self, + elem: ar_element.ModeSwitchPointRef + ) -> None: + """ + Writes references to AR:MODE-SWITCH-POINT--SUBTYPES-ENUM + Tag variants: 'EVENT-SOURCE-REF' + """ + assert isinstance(elem, ar_element.ModeSwitchPointRef) + self._write_ref_content(elem, "EVENT-SOURCE-REF") + # -- Constant and value specifications def _write_text_value_specification(self, elem: ar_element.TextValueSpecification) -> None: @@ -3691,7 +3727,7 @@ def _write_swc_implementation_group(self, elem: ar_element.SwcImplementation) -> if elem.required_rte_vendor is not None: self._add_content("REQUIRED-RTE-VENDOR", elem.required_rte_vendor) - def _write_rmode_in_atomic_swc_instance_ref(self, elem: ar_element.RModeInAtomicSwcInstanceRef, tag: str) -> None: + def _write_r_mode_in_atomic_swc_instance_ref(self, elem: ar_element.RModeInAtomicSwcInstanceRef, tag: str) -> None: """ Writes complex type AR:R-MODE-IN-ATOMIC-SWC-INSTANCE-REF Tag variants: 'DISABLED-MODE-IREF' | 'MODE-IREF' @@ -3710,9 +3746,9 @@ def _write_rmode_in_atomic_swc_instance_ref(self, elem: ar_element.RModeInAtomic self._write_mode_declaration_ref(elem.target_mode_declaration, "TARGET-MODE-DECLARATION-REF") self._leave_child() - def _write_rvariable_in_atomic_swc_instance_ref(self, - elem: ar_element.RVariableInAtomicSwcInstanceRef - ) -> None: + def _write_r_variable_in_atomic_swc_instance_ref(self, + elem: ar_element.RVariableInAtomicSwcInstanceRef + ) -> None: """ Writes complex type AR:R-VARIABLE-IN-ATOMIC-SWC-INSTANCE-REF Tag variants: 'DATA-IREF' @@ -3729,6 +3765,26 @@ def _write_rvariable_in_atomic_swc_instance_ref(self, self._write_variable_data_prototype_ref(elem.target_data_element, "TARGET-DATA-ELEMENT-REF") self._leave_child() + def _write_p_operation_in_atomic_swc_instance_ref(self, + elem: ar_element.POperationInAtomicSwcInstanceRef + ) -> None: + """ + Writes complex type AR:P-OPERATION-IN-ATOMIC-SWC-INSTANCE-REF + Tag variants: 'OPERATION-IREF' + """ + assert isinstance(elem, ar_element.POperationInAtomicSwcInstanceRef) + tag = "OPERATION-IREF" + if elem.is_empty: + self._add_content(tag) + else: + self._add_child(tag) + if elem.context_port is not None: + self._write_abstract_provided_port_prototype_ref(elem.context_port, "CONTEXT-P-PORT-REF") + if elem.target_provided_operation is not None: + self._write_client_server_operation_ref(elem.target_provided_operation, + "TARGET-PROVIDED-OPERATION-REF") + self._leave_child() + # --- SWC Internal behavior elements def _write_variable_in_impl_data_instance_ref(self, @@ -3932,11 +3988,26 @@ def _write_rte_event(self, elem: ar_element.RteEvent) -> None: if elem.disabled_modes: self._add_child("DISABLED-MODE-IREFS") for disabled_mode in elem.disabled_modes: - self._write_rmode_in_atomic_swc_instance_ref(disabled_mode, "DISABLED-MODE-IREF") + self._write_r_mode_in_atomic_swc_instance_ref(disabled_mode, "DISABLED-MODE-IREF") self._leave_child() if elem.start_on_event is not None: self._write_runnable_entity_ref(elem.start_on_event, "START-ON-EVENT-REF") + def _write_data_receive_error_event(self, elem: ar_element.DataReceiveErrorEvent) -> None: + """ + Writes complex Type AR:DATA-RECEIVE-ERROR-EVENT + Tag variants: 'DATA-RECEIVE-ERROR-EVENT' + """ + assert isinstance(elem, ar_element.DataReceiveErrorEvent) + self._add_child("DATA-RECEIVE-ERROR-EVENT") + self._write_referrable(elem) + self._write_multilanguage_referrable(elem) + self._write_identifiable(elem) + self._write_rte_event(elem) + if elem.data is not None: + self._write_r_variable_in_atomic_swc_instance_ref(elem.data) + self._leave_child() + def _write_data_received_event(self, elem: ar_element.DataReceivedEvent) -> None: """ Writes complex Type AR:DATA-RECEIVED-EVENT @@ -3949,7 +4020,37 @@ def _write_data_received_event(self, elem: ar_element.DataReceivedEvent) -> None self._write_identifiable(elem) self._write_rte_event(elem) if elem.data is not None: - self._write_rvariable_in_atomic_swc_instance_ref(elem.data) + self._write_r_variable_in_atomic_swc_instance_ref(elem.data) + self._leave_child() + + def _write_data_send_completed_event(self, elem: ar_element.DataSendCompletedEvent) -> None: + """ + Writes complex Type AR:DATA-SEND-COMPLETED-EVENT + Tag variants: 'DATA-SEND-COMPLETED-EVENT' + """ + assert isinstance(elem, ar_element.DataSendCompletedEvent) + self._add_child("DATA-SEND-COMPLETED-EVENT") + self._write_referrable(elem) + self._write_multilanguage_referrable(elem) + self._write_identifiable(elem) + self._write_rte_event(elem) + if elem.event_source is not None: + self._write_variable_access_ref(elem.event_source, "EVENT-SOURCE-REF") + self._leave_child() + + def _write_data_write_completed_event(self, elem: ar_element.DataWriteCompletedEvent) -> None: + """ + Writes complex Type AR:DATA-WRITE-COMPLETED-EVENT + Tag variants: 'DATA-WRITE-COMPLETED-EVENT' + """ + assert isinstance(elem, ar_element.DataWriteCompletedEvent) + self._add_child("DATA-WRITE-COMPLETED-EVENT") + self._write_referrable(elem) + self._write_multilanguage_referrable(elem) + self._write_identifiable(elem) + self._write_rte_event(elem) + if elem.event_source is not None: + self._write_variable_access_ref(elem.event_source, "EVENT-SOURCE-REF") self._leave_child() def _write_init_event(self, elem: ar_element.InitEvent) -> None: @@ -3965,6 +4066,82 @@ def _write_init_event(self, elem: ar_element.InitEvent) -> None: self._write_rte_event(elem) self._leave_child() + def _write_mode_switched_ack_event(self, elem: ar_element.ModeSwitchedAckEvent) -> None: + """ + Writes complex type MODE-SWITCHED-ACK-EVENT + Tag variants: 'MODE-SWITCHED-ACK-EVENT' + """ + assert isinstance(elem, ar_element.ModeSwitchedAckEvent) + self._add_child("MODE-SWITCHED-ACK-EVENT") + self._write_referrable(elem) + self._write_multilanguage_referrable(elem) + self._write_identifiable(elem) + self._write_rte_event(elem) + if elem.event_source is not None: + self._write_mode_switch_point_ref(elem.event_source) + self._leave_child() + + def _write_operation_invoked_event(self, elem: ar_element.OperationInvokedEvent) -> None: + """ + Writes complex type AR:OPERATION-INVOKED-EVENT + Tag variants: 'OPERATION-INVOKED-EVENT' + """ + assert isinstance(elem, ar_element.OperationInvokedEvent) + self._add_child("OPERATION-INVOKED-EVENT") + self._write_referrable(elem) + self._write_multilanguage_referrable(elem) + self._write_identifiable(elem) + self._write_rte_event(elem) + if elem.operation is not None: + self._write_p_operation_in_atomic_swc_instance_ref(elem.operation) + self._leave_child() + + def _write_swc_mode_switch_event(self, elem: ar_element.SwcModeSwitchEvent) -> None: + """ + Writes complex type AR:SWC-MODE-SWITCH-EVENT + Tag variants: 'SWC-MODE-SWITCH-EVENT' + """ + assert isinstance(elem, ar_element.SwcModeSwitchEvent) + self._add_child("SWC-MODE-SWITCH-EVENT") + self._write_referrable(elem) + self._write_multilanguage_referrable(elem) + self._write_identifiable(elem) + self._write_rte_event(elem) + self._write_swc_mode_switch_event_group(elem) + self._leave_child() + + def _write_swc_mode_switch_event_group(self, elem: ar_element.SwcModeSwitchEvent) -> None: + """ + Writes group AR:SWC-MODE-SWITCH-EVENT + """ + if elem.activation is not None: + self._add_content("ACTIVATION", ar_enum.enum_to_xml(elem.activation)) + if elem.mode is not None: + self._add_child("MODE-IREFS") + if isinstance(elem.mode, tuple): + self._write_r_mode_in_atomic_swc_instance_ref(elem.mode[0], "MODE-IREF") + self._write_r_mode_in_atomic_swc_instance_ref(elem.mode[1], "MODE-IREF") + else: + self._write_r_mode_in_atomic_swc_instance_ref(elem.mode, "MODE-IREF") + self._leave_child() + + def _write_timing_event(self, elem: ar_element.TimingEvent) -> None: + """ + Writes complex type AR:TIMING-EVENT + Tag variants: 'TIMING-EVENT' + """ + assert isinstance(elem, ar_element.TimingEvent) + self._add_child("TIMING-EVENT") + self._write_referrable(elem) + self._write_multilanguage_referrable(elem) + self._write_identifiable(elem) + self._write_rte_event(elem) + if elem.offset is not None: + self._add_content("OFFSET", self._format_number(elem.offset)) + if elem.period is not None: + self._add_content("PERIOD", self._format_number(elem.period)) + self._leave_child() + def _write_swc_internal_behavior(self, elem: ar_element.SwcInternalBehavior) -> None: """ Writes complex type AR:SWC-INTERNAL-BEHAVIOR diff --git a/tests/xml/test_swc_internal_behavior.py b/tests/xml/test_swc_internal_behavior.py index b66ffb7..cfae70d 100644 --- a/tests/xml/test_swc_internal_behavior.py +++ b/tests/xml/test_swc_internal_behavior.py @@ -839,11 +839,78 @@ def test_start_on_event(self): self.assertEqual(str(elem.start_on_event), ref_str) -class TestDataReceivedEvent(unittest.TestCase): +class TestDataReceiveErrorEvent(unittest.TestCase): """ Base elements are tested in TestInitEvent """ + def test_name_only(self): + element = ar_element.DataReceiveErrorEvent('MyName') + writer = autosar.xml.Writer() + xml = ''' + MyName +''' + self.assertEqual(writer.write_str_elem(element), xml) + reader = autosar.xml.Reader() + elem: ar_element.DataReceiveErrorEvent = reader.read_str_elem(xml) + self.assertIsInstance(elem, ar_element.DataReceiveErrorEvent) + self.assertEqual(elem.name, 'MyName') + + def test_data_from_element(self): + context_port_ref_str = "/ComponentTypes/MyComponent/CurrentWorkload" + target_data_element_str = "/PortInterfaces/CurrentWorkload_I/CurrentWorkload" + context_port = ar_element.PortPrototypeRef(context_port_ref_str, ar_enum.IdentifiableSubTypes.R_PORT_PROTOTYPE) + target_data_element = ar_element.VariableDataPrototypeRef(target_data_element_str) + data = ar_element.RVariableInAtomicSwcInstanceRef(context_port=context_port, + target_data_element=target_data_element) + element = ar_element.DataReceiveErrorEvent('MyName', + data=data) + xml = f''' + MyName + + {context_port_ref_str} + {target_data_element_str} + +''' + writer = autosar.xml.Writer() + self.assertEqual(writer.write_str_elem(element), xml) + reader = autosar.xml.Reader() + elem: ar_element.DataReceiveErrorEvent = reader.read_str_elem(xml) + self.assertIsInstance(elem, ar_element.DataReceiveErrorEvent) + inner: ar_element.RVariableInAtomicSwcInstanceRef = elem.data + self.assertEqual(str(inner.context_port), context_port_ref_str) + self.assertEqual(str(inner.target_data_element), target_data_element_str) + + def test_create_using_conveneince_method(self): + start_on_event_ref_str = "/ComponentTypes/MyComponent/InternalBehavior/MyRunnable" + context_port_ref_str = "/ComponentTypes/MyComponent/CurrentWorkload" + target_data_element_str = "/PortInterfaces/CurrentWorkload_I/CurrentWorkload" + context_port = ar_element.PortPrototypeRef(context_port_ref_str, ar_enum.IdentifiableSubTypes.R_PORT_PROTOTYPE) + element = ar_element.DataReceiveErrorEvent.make('MyName', + start_on_event_ref_str, + context_port, + target_data_element_str) + xml = f''' + MyName + {start_on_event_ref_str} + + {context_port_ref_str} + {target_data_element_str} + +''' + writer = autosar.xml.Writer() + self.assertEqual(writer.write_str_elem(element), xml) + reader = autosar.xml.Reader() + elem: ar_element.DataReceiveErrorEvent = reader.read_str_elem(xml) + self.assertEqual(str(elem.start_on_event), start_on_event_ref_str) + self.assertIsInstance(elem, ar_element.DataReceiveErrorEvent) + inner: ar_element.RVariableInAtomicSwcInstanceRef = elem.data + self.assertEqual(str(inner.context_port), context_port_ref_str) + self.assertEqual(str(inner.target_data_element), target_data_element_str) + + +class TestDataReceivedEvent(unittest.TestCase): + def test_name_only(self): element = ar_element.DataReceivedEvent('MyName') writer = autosar.xml.Writer() @@ -909,6 +976,387 @@ def test_create_using_conveneince_method(self): self.assertEqual(str(inner.target_data_element), target_data_element_str) +class TestDataSendCompletedEvent(unittest.TestCase): + + def test_name_only(self): + element = ar_element.DataSendCompletedEvent('MyName') + writer = autosar.xml.Writer() + xml = ''' + MyName +''' + self.assertEqual(writer.write_str_elem(element), xml) + reader = autosar.xml.Reader() + elem: ar_element.DataSendCompletedEvent = reader.read_str_elem(xml) + self.assertIsInstance(elem, ar_element.DataSendCompletedEvent) + self.assertEqual(elem.name, 'MyName') + + def test_event_source(self): + variable_access_ref_str = "/ComponentTypes/MyComponent/MyComponent_InternalBehavior/run/SEND_ButtonPressed" + variable_access_ref = ar_element.VariableAccessRef(variable_access_ref_str) + element = ar_element.DataSendCompletedEvent('MyName', event_source=variable_access_ref) + xml = f''' + MyName + {variable_access_ref_str} +''' + writer = autosar.xml.Writer() + self.assertEqual(writer.write_str_elem(element), xml) + reader = autosar.xml.Reader() + elem: ar_element.DataSendCompletedEvent = reader.read_str_elem(xml) + self.assertIsInstance(elem, ar_element.DataSendCompletedEvent) + self.assertEqual(str(elem.event_source), variable_access_ref_str) + + +class TestDataWriteCompletedEvent(unittest.TestCase): + + def test_name_only(self): + element = ar_element.DataWriteCompletedEvent('MyName') + writer = autosar.xml.Writer() + xml = ''' + MyName +''' + self.assertEqual(writer.write_str_elem(element), xml) + reader = autosar.xml.Reader() + elem: ar_element.DataWriteCompletedEvent = reader.read_str_elem(xml) + self.assertIsInstance(elem, ar_element.DataWriteCompletedEvent) + self.assertEqual(elem.name, 'MyName') + + def test_event_source(self): + variable_access_ref_str = "/ComponentTypes/MyComponent/MyComponent_InternalBehavior/run/SEND_ButtonPressed" + variable_access_ref = ar_element.VariableAccessRef(variable_access_ref_str) + element = ar_element.DataWriteCompletedEvent('MyName', event_source=variable_access_ref) + xml = f''' + MyName + {variable_access_ref_str} +''' + writer = autosar.xml.Writer() + self.assertEqual(writer.write_str_elem(element), xml) + reader = autosar.xml.Reader() + elem: ar_element.DataWriteCompletedEvent = reader.read_str_elem(xml) + self.assertIsInstance(elem, ar_element.DataWriteCompletedEvent) + self.assertEqual(str(elem.event_source), variable_access_ref_str) + + +class TestModeSwitchedAckEvent(unittest.TestCase): + + def test_name_only(self): + element = ar_element.ModeSwitchedAckEvent('MyName') + writer = autosar.xml.Writer() + xml = ''' + MyName +''' + self.assertEqual(writer.write_str_elem(element), xml) + reader = autosar.xml.Reader() + elem: ar_element.ModeSwitchedAckEvent = reader.read_str_elem(xml) + self.assertIsInstance(elem, ar_element.ModeSwitchedAckEvent) + self.assertEqual(elem.name, 'MyName') + + def test_event_source(self): + mode_switch_point_ref_str = "/ComponentTypes/MyComponent/MyComponent_InternalBehavior" \ + "/ack/SWITCH_ModePortName_ModeGroupName" + variable_access_ref = ar_element.ModeSwitchPointRef(mode_switch_point_ref_str) + element = ar_element.ModeSwitchedAckEvent('MyName', event_source=variable_access_ref) + xml = f''' + MyName + {mode_switch_point_ref_str} +''' + writer = autosar.xml.Writer() + self.assertEqual(writer.write_str_elem(element), xml) + reader = autosar.xml.Reader() + elem: ar_element.ModeSwitchedAckEvent = reader.read_str_elem(xml) + self.assertIsInstance(elem, ar_element.ModeSwitchedAckEvent) + self.assertEqual(str(elem.event_source), mode_switch_point_ref_str) + + +class TestOperationInvokedEvent(unittest.TestCase): + + def test_name_only(self): + element = ar_element.OperationInvokedEvent('MyName') + writer = autosar.xml.Writer() + xml = ''' + MyName +''' + self.assertEqual(writer.write_str_elem(element), xml) + reader = autosar.xml.Reader() + elem: ar_element.OperationInvokedEvent = reader.read_str_elem(xml) + self.assertIsInstance(elem, ar_element.OperationInvokedEvent) + self.assertEqual(elem.name, 'MyName') + + def test_operation_from_element(self): + context_port_ref_str = "/ComponentTypes/MyComponent/StoredData" + target_operation_ref_str = "/PortInterfaces/StoredData_I/Read" + context_port = ar_element.PortPrototypeRef(context_port_ref_str, ar_enum.IdentifiableSubTypes.P_PORT_PROTOTYPE) + target_operation = ar_element.ClientServerOperationRef(target_operation_ref_str) + operation = ar_element.POperationInAtomicSwcInstanceRef(context_port=context_port, + target_provided_operation=target_operation) + element = ar_element.OperationInvokedEvent('MyName', + operation=operation) + dest_str = "CLIENT-SERVER-OPERATION" + xml = f''' + MyName + + {context_port_ref_str} + {target_operation_ref_str} + +''' + writer = autosar.xml.Writer() + self.assertEqual(writer.write_str_elem(element), xml) + reader = autosar.xml.Reader() + elem: ar_element.OperationInvokedEvent = reader.read_str_elem(xml) + self.assertIsInstance(elem, ar_element.OperationInvokedEvent) + inner: ar_element.POperationInAtomicSwcInstanceRef = elem.operation + self.assertEqual(str(inner.context_port), context_port_ref_str) + self.assertEqual(str(inner.target_provided_operation), target_operation_ref_str) + + def test_create_using_conveneince_method(self): + start_on_event_ref_str = "/ComponentTypes/MyComponent/InternalBehavior/MyRunnable" + context_port_ref_str = "/ComponentTypes/MyComponent/StoredData" + target_operation_ref_str = "/PortInterfaces/StoredData_I/Read" + context_port = ar_element.PortPrototypeRef(context_port_ref_str, ar_enum.IdentifiableSubTypes.P_PORT_PROTOTYPE) + element = ar_element.OperationInvokedEvent.make('MyName', + start_on_event_ref_str, + context_port, + target_operation_ref_str) + dest_str = "CLIENT-SERVER-OPERATION" + xml = f''' + MyName + {start_on_event_ref_str} + + {context_port_ref_str} + {target_operation_ref_str} + +''' + writer = autosar.xml.Writer() + self.assertEqual(writer.write_str_elem(element), xml) + reader = autosar.xml.Reader() + elem: ar_element.OperationInvokedEvent = reader.read_str_elem(xml) + self.assertEqual(str(elem.start_on_event), start_on_event_ref_str) + self.assertIsInstance(elem, ar_element.OperationInvokedEvent) + inner: ar_element.POperationInAtomicSwcInstanceRef = elem.operation + self.assertEqual(str(inner.context_port), context_port_ref_str) + self.assertEqual(str(inner.target_provided_operation), target_operation_ref_str) + + +class TestSwcModeSwitchEvent(unittest.TestCase): + + def test_name_only(self): + element = ar_element.SwcModeSwitchEvent('MyName') + writer = autosar.xml.Writer() + xml = ''' + MyName +''' + self.assertEqual(writer.write_str_elem(element), xml) + reader = autosar.xml.Reader() + elem: ar_element.SwcModeSwitchEvent = reader.read_str_elem(xml) + self.assertIsInstance(elem, ar_element.SwcModeSwitchEvent) + self.assertEqual(elem.name, 'MyName') + + def test_activation(self): + element = ar_element.SwcModeSwitchEvent('MyName', + activation=ar_enum.ModeActivationKind.ON_ENTRY) + writer = autosar.xml.Writer() + xml = ''' + MyName + ON-ENTRY +''' + self.assertEqual(writer.write_str_elem(element), xml) + reader = autosar.xml.Reader() + elem: ar_element.SwcModeSwitchEvent = reader.read_str_elem(xml) + self.assertIsInstance(elem, ar_element.SwcModeSwitchEvent) + self.assertEqual(elem.activation, ar_enum.ModeActivationKind.ON_ENTRY) + + def test_mode_from_single_element(self): + context_port_ref_str = "/ComponentTypes/MyComponent/BswM_Mode" + context_mode_decl_group_ref_str = "/PortInterfaces/BswM_ModeSwitchInterface/BswM_Mode" + target_mode_decl_ref_str = "/ModeDclrGroups/BswM_Mode/POSTRUN" + context_port = ar_element.PortPrototypeRef(context_port_ref_str, ar_enum.IdentifiableSubTypes.R_PORT_PROTOTYPE) + context_mode_decl_group = ar_element.ModeDeclarationGroupPrototypeRef(context_mode_decl_group_ref_str) + target_mode_decl = ar_element.ModeDeclarationRef(target_mode_decl_ref_str) + mode_instance = ar_element.RModeInAtomicSwcInstanceRef( + context_port=context_port, + context_mode_declaration_group_prototype=context_mode_decl_group, + target_mode_declaration=target_mode_decl) + element = ar_element.SwcModeSwitchEvent('MyName', + mode=mode_instance) + xml = f''' + MyName + + + {context_port_ref_str} + \ +{context_mode_decl_group_ref_str} + {target_mode_decl_ref_str} + + +''' + writer = autosar.xml.Writer() + self.assertEqual(writer.write_str_elem(element), xml) + reader = autosar.xml.Reader() + elem: ar_element.SwcModeSwitchEvent = reader.read_str_elem(xml) + self.assertIsInstance(elem, ar_element.SwcModeSwitchEvent) + mode: ar_element.RModeInAtomicSwcInstanceRef = elem.mode + self.assertEqual(str(mode.context_port), context_port_ref_str) + self.assertEqual(str(mode.context_mode_declaration_group_prototype), context_mode_decl_group_ref_str) + self.assertEqual(str(mode.target_mode_declaration), target_mode_decl_ref_str) + + def test_mode_from_tuple_element(self): + context_port_ref_str = "/ComponentTypes/MyComponent/BswM_Mode" + context_mode_decl_group_ref_str = "/PortInterfaces/BswM_ModeSwitchInterface/BswM_Mode" + target_mode_decl_ref_str1 = "/ModeDclrGroups/BswM_Mode/RUN" + target_mode_decl_ref_str2 = "/ModeDclrGroups/BswM_Mode/POSTRUN" + context_port = ar_element.PortPrototypeRef(context_port_ref_str, ar_enum.IdentifiableSubTypes.R_PORT_PROTOTYPE) + context_mode_decl_group = ar_element.ModeDeclarationGroupPrototypeRef(context_mode_decl_group_ref_str) + target_mode_decl1 = ar_element.ModeDeclarationRef(target_mode_decl_ref_str1) + target_mode_decl2 = ar_element.ModeDeclarationRef(target_mode_decl_ref_str2) + mode_instance1 = ar_element.RModeInAtomicSwcInstanceRef( + context_port=context_port, + context_mode_declaration_group_prototype=context_mode_decl_group, + target_mode_declaration=target_mode_decl1) + mode_instance2 = ar_element.RModeInAtomicSwcInstanceRef( + context_port=context_port, + context_mode_declaration_group_prototype=context_mode_decl_group, + target_mode_declaration=target_mode_decl2) + element = ar_element.SwcModeSwitchEvent('MyName', + mode=(mode_instance1, mode_instance2)) + xml = f''' + MyName + + + {context_port_ref_str} + \ +{context_mode_decl_group_ref_str} + {target_mode_decl_ref_str1} + + + {context_port_ref_str} + \ +{context_mode_decl_group_ref_str} + {target_mode_decl_ref_str2} + + +''' + writer = autosar.xml.Writer() + self.assertEqual(writer.write_str_elem(element), xml) + reader = autosar.xml.Reader() + elem: ar_element.SwcModeSwitchEvent = reader.read_str_elem(xml) + self.assertIsInstance(elem, ar_element.SwcModeSwitchEvent) + mode: ar_element.RModeInAtomicSwcInstanceRef = elem.mode[0] + self.assertEqual(str(mode.context_port), context_port_ref_str) + self.assertEqual(str(mode.context_mode_declaration_group_prototype), context_mode_decl_group_ref_str) + self.assertEqual(str(mode.target_mode_declaration), target_mode_decl_ref_str1) + mode = elem.mode[1] + self.assertEqual(str(mode.context_port), context_port_ref_str) + self.assertEqual(str(mode.context_mode_declaration_group_prototype), context_mode_decl_group_ref_str) + self.assertEqual(str(mode.target_mode_declaration), target_mode_decl_ref_str2) + + def test_create_using_conveneince_method(self): + start_on_event_ref_str = "/ComponentTypes/MyComponent/InternalBehavior/MyRunnable" + context_port_ref_str = "/ComponentTypes/MyComponent/BswM_Mode" + context_mode_decl_group_ref_str = "/PortInterfaces/BswM_ModeSwitchInterface/BswM_Mode" + target_mode_decl_ref_str = "/ModeDclrGroups/BswM_Mode/RUN" + context_port = ar_element.PortPrototypeRef(context_port_ref_str, ar_enum.IdentifiableSubTypes.R_PORT_PROTOTYPE) + context_mode_decl_group = ar_element.ModeDeclarationGroupPrototypeRef(context_mode_decl_group_ref_str) + target_mode_decl = ar_element.ModeDeclarationRef(target_mode_decl_ref_str) + element = ar_element.SwcModeSwitchEvent.make('MyName', + start_on_event_ref_str, + ar_enum.ModeActivationKind.ON_ENTRY, + context_port, + context_mode_decl_group, + target_mode_decl) + xml = f''' + MyName + {start_on_event_ref_str} + ON-ENTRY + + + {context_port_ref_str} + \ +{context_mode_decl_group_ref_str} + {target_mode_decl_ref_str} + + +''' + writer = autosar.xml.Writer() + self.assertEqual(writer.write_str_elem(element), xml) + reader = autosar.xml.Reader() + elem: ar_element.SwcModeSwitchEvent = reader.read_str_elem(xml) + self.assertIsInstance(elem, ar_element.SwcModeSwitchEvent) + mode: ar_element.RModeInAtomicSwcInstanceRef = elem.mode + self.assertEqual(str(mode.context_port), context_port_ref_str) + self.assertEqual(str(mode.context_mode_declaration_group_prototype), context_mode_decl_group_ref_str) + self.assertEqual(str(mode.target_mode_declaration), target_mode_decl_ref_str) + + +class TestTimingEvent(unittest.TestCase): + + def test_name_only(self): + element = ar_element.TimingEvent('MyName') + writer = autosar.xml.Writer() + xml = ''' + MyName +''' + self.assertEqual(writer.write_str_elem(element), xml) + reader = autosar.xml.Reader() + elem: ar_element.TimingEvent = reader.read_str_elem(xml) + self.assertIsInstance(elem, ar_element.TimingEvent) + self.assertEqual(elem.name, 'MyName') + + def test_offset_from_int(self): + offset = 1 + element = ar_element.TimingEvent('MyName', offset=offset) + xml = f''' + MyName + {offset} +''' + writer = autosar.xml.Writer() + self.assertEqual(writer.write_str_elem(element), xml) + reader = autosar.xml.Reader() + elem: ar_element.TimingEvent = reader.read_str_elem(xml) + self.assertIsInstance(elem, ar_element.TimingEvent) + self.assertAlmostEqual(elem.offset, offset) + + def test_offset_from_float(self): + offset = 0.1 + element = ar_element.TimingEvent('MyName', offset=offset) + xml = f''' + MyName + {offset} +''' + writer = autosar.xml.Writer() + self.assertEqual(writer.write_str_elem(element), xml) + reader = autosar.xml.Reader() + elem: ar_element.TimingEvent = reader.read_str_elem(xml) + self.assertIsInstance(elem, ar_element.TimingEvent) + self.assertAlmostEqual(elem.offset, offset) + + def test_period_from_int(self): + period = 1 + element = ar_element.TimingEvent('MyName', period=period) + xml = f''' + MyName + {period} +''' + writer = autosar.xml.Writer() + self.assertEqual(writer.write_str_elem(element), xml) + reader = autosar.xml.Reader() + elem: ar_element.TimingEvent = reader.read_str_elem(xml) + self.assertIsInstance(elem, ar_element.TimingEvent) + self.assertAlmostEqual(elem.period, period) + + def test_period_from_float(self): + period = 0.1 + element = ar_element.TimingEvent('MyName', period=period) + xml = f''' + MyName + {period} +''' + writer = autosar.xml.Writer() + self.assertEqual(writer.write_str_elem(element), xml) + reader = autosar.xml.Reader() + elem: ar_element.TimingEvent = reader.read_str_elem(xml) + self.assertIsInstance(elem, ar_element.TimingEvent) + self.assertAlmostEqual(elem.period, period) + + class TestSwcInternalBehavior(unittest.TestCase): """ Most elements are not implemented yet