-
-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Showing
8 changed files
with
174 additions
and
6 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
Empty file.
37 changes: 37 additions & 0 deletions
37
tests/software_tests/database/test_abstract_data_record.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,37 @@ | ||
import pytest | ||
from mock import Mock, patch | ||
|
||
from uds.database.abstract_data_record import AbstractDataRecord | ||
|
||
SCRIPT_LOCATION = "uds.database.abstract_data_record" | ||
|
||
|
||
class TestAbstractDataRecord: | ||
|
||
def setup_method(self): | ||
self.mock_data_record = Mock(spec=AbstractDataRecord) | ||
|
||
# __init__ | ||
|
||
@patch(f"{SCRIPT_LOCATION}.isinstance") | ||
def test_init__type_error(self, mock_isinstance): | ||
mock_isinstance.return_value = False | ||
mock_name = Mock() | ||
with pytest.raises(TypeError): | ||
AbstractDataRecord.__init__(self.mock_data_record, mock_name) | ||
mock_isinstance.assert_called_once_with(mock_name, str) | ||
|
||
@patch(f"{SCRIPT_LOCATION}.isinstance") | ||
def test_init__valid(self, mock_isinstance): | ||
mock_isinstance.return_value = True | ||
mock_name = Mock() | ||
assert AbstractDataRecord.__init__(self.mock_data_record, mock_name) is None | ||
assert self.mock_data_record._AbstractDataRecord__name == mock_name.strip.return_value | ||
mock_isinstance.assert_called_once_with(mock_name, str) | ||
mock_name.strip.assert_called_once_with() | ||
|
||
# name | ||
|
||
def test_name(self): | ||
self.mock_data_record._AbstractDataRecord__name = Mock() | ||
assert AbstractDataRecord.name.fget(self.mock_data_record) == self.mock_data_record._AbstractDataRecord__name |
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 |
---|---|---|
|
@@ -28,6 +28,7 @@ | |
|
||
|
||
import uds.can | ||
import uds.database | ||
import uds.message | ||
import uds.packet | ||
import uds.segmentation | ||
|
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,7 @@ | ||
""" | ||
Implementation for diagnostic messages databases. | ||
Tools for decoding and encoding information from/to diagnostic messages. | ||
""" | ||
|
||
from .abstract_data_record import AbstractDataRecord, DataRecordType, DecodedDataRecord |
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,123 @@ | ||
""" | ||
Definition of all Data Records types. | ||
Each Data Record contains mapping (translation) of raw data (sequence of bits in diagnostic message payload) to some | ||
meaningful information (e.g. physical value, text). | ||
""" | ||
|
||
__all__ = ["DataRecordType", "AbstractDataRecord", "DecodedDataRecord"] | ||
|
||
from abc import ABC, abstractmethod | ||
from typing import Tuple, TypedDict, Union, Optional | ||
|
||
from uds.utilities import ValidatedEnum | ||
|
||
DataRecordPhysicalValueAlias = Union[int, float, str, Tuple["DecodedDataRecord", ...]] | ||
"""Alias of Data Records' physical value.""" | ||
|
||
|
||
class DecodedDataRecord(TypedDict): | ||
"""Structure of decoded Data Record.""" | ||
|
||
name: str | ||
raw_value: int | ||
physical_value: DataRecordPhysicalValueAlias # noqa: F841 | ||
|
||
|
||
class DataRecordType(ValidatedEnum): | ||
"""All Data Record types.""" | ||
|
||
# TODO: fill with following tasks: | ||
# - https://github.com/mdabrowski1990/uds/issues/2 | ||
# - https://github.com/mdabrowski1990/uds/issues/6 | ||
# - https://github.com/mdabrowski1990/uds/issues/8 | ||
# - https://github.com/mdabrowski1990/uds/issues/9 | ||
# - https://github.com/mdabrowski1990/uds/issues/10 | ||
|
||
|
||
class AbstractDataRecord(ABC): | ||
"""Common implementation and interface for all Data Records.""" | ||
|
||
def __init__(self, name: str) -> None: | ||
""" | ||
Initialize common part for all Data Records. | ||
:param name: Name to assign to this Data Record. | ||
:raise TypeError: Provided value of name is not str type. | ||
""" | ||
if not isinstance(name, str): | ||
raise TypeError("Provided name is not str type.") | ||
self.__name = name.strip() | ||
|
||
@property | ||
def name(self) -> str: | ||
"""Name of this Data Record.""" | ||
return self.__name | ||
|
||
@property # noqa: F841 | ||
@abstractmethod | ||
def data_record_type(self) -> DataRecordType: | ||
"""Type of this Data Record.""" | ||
|
||
@property # noqa: F841 | ||
@abstractmethod | ||
def length(self) -> int: | ||
"""Get number of bits that this Data Record is stored over.""" | ||
|
||
@property # noqa: F841 | ||
@abstractmethod | ||
def is_reoccurring(self) -> bool: | ||
""" | ||
Whether this Data Record might occur multiple times. | ||
Values meaning: | ||
- False - exactly one occurrence in every diagnostic message | ||
- True - number of occurrences might vary | ||
""" | ||
|
||
@property # noqa: F841 | ||
@abstractmethod | ||
def min_occurrences(self) -> int: | ||
""" | ||
Minimal number of this Data Record occurrences. | ||
.. note:: Relevant only if :attr:`~uds.database.abstract_data_record.AbstractDataRecord.is_reoccurring` | ||
equals True. | ||
""" | ||
|
||
@property # noqa: F841 | ||
@abstractmethod | ||
def max_occurrences(self) -> Optional[int]: | ||
""" | ||
Maximal number of this Data Record occurrences. | ||
.. note:: Relevant only if :attr:`~uds.database.abstract_data_record.AbstractDataRecord.is_reoccurring` | ||
equals True. | ||
.. warning:: No maximal number (infinite number of occurrences) is represented by None value. | ||
""" | ||
|
||
@property # noqa: F841 | ||
@abstractmethod | ||
def contains(self) -> Tuple["AbstractDataRecord", ...]: | ||
"""Get Data Records contained by this Data Record.""" | ||
|
||
@abstractmethod | ||
def decode(self, raw_value: int) -> DecodedDataRecord: # noqa: F841 | ||
""" | ||
Decode physical value for provided raw value. | ||
:param raw_value: Raw (bit) value of Data Record. | ||
:return: Dictionary with physical value for this Data Record. | ||
""" | ||
|
||
@abstractmethod | ||
def encode(self, physical_value: DataRecordPhysicalValueAlias) -> int: # noqa: F841 | ||
""" | ||
Encode raw value for provided physical value. | ||
:param physical_value: Physical (meaningful e.g. float, str type) value of this Data Record. | ||
:return: Raw Value of this Data Record. | ||
""" |
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