powertrain-build/tests/interface/test_model_yaml_verification.py
olindgre 2ece01e1d7 Make powertrain-build not overlap with pybuild in site-packages
Change-Id: I7b59f3f04f0f787d35db0b9389f295bf1ad24f56
2024-09-17 10:25:04 +02:00

319 lines
15 KiB
Python

# Copyright 2024 Volvo Car Corporation
# Licensed under Apache 2.0.
"""Module to test the ModelYmlVerification class."""
import unittest
from unittest import mock
from powertrain_build.interface.model_yaml_verification import ModelYmlVerification
class TestModelYamlVerification(unittest.TestCase):
"""Unit tests for the ModelYmlVerification class."""
def test_verify_outsignals(self):
"""Test the verify_signals method with outsignals."""
app = mock.MagicMock()
modelyamlver = ModelYmlVerification(app)
modelyamlver.model_name = "dummy_model"
modelyamlver.signal_properties = {"dummy_model": []}
modelyamlver.app_outsignals = {}
modelyamlver.raw = {"dummy_dp": [{"property": "test_outsignal", "outsignal": "test_outsignal"}]}
exception_msg = "ERROR:root:test_outsignal is not defined as an outsignal in json file\n"
with self.assertLogs(level="INFO") as warn_info:
modelyamlver.verify_signals(modelyamlver.raw)
self.assertEqual(warn_info.output, [exception_msg])
# Different properties connected to the same outsignal in the same device proxy.
modelyamlver.app_outsignals = ["test_outsignal"]
modelyamlver.signal_properties = {"dummy_model": []}
modelyamlver.raw = {
"dummy_dp": [
{"property": "test_property", "outsignal": "test_outsignal"},
{"property": "test_property2", "outsignal": "test_outsignal"},
]
}
exception_msg = (
"ERROR:root:You can't connect a signal test_outsignal in dummy_model model to the same "
"interface (dummy_dp) twice. It's already connected as "
"dummy_dp.test_property.test_outsignal in model dummy_model.\n"
)
with self.assertLogs(level="INFO") as warn_info:
modelyamlver.verify_signals(modelyamlver.raw)
self.assertEqual(warn_info.output, [exception_msg])
# Different properties connected to the same outsignal in different device proxies.
modelyamlver.app_outsignals = ["test_outsignal"]
modelyamlver.signal_properties = {"dummy_model": []}
modelyamlver.raw = {
"dummy_dp": [
{"property": "test_property", "outsignal": "test_outsignal"},
],
"dummy_dp2": [{"property": "test_property2", "outsignal": "test_outsignal"}],
}
expected_signal_properties = {
"dummy_model": ["dummy_dp.test_property.test_outsignal", "dummy_dp2.test_property2.test_outsignal"],
}
modelyamlver.verify_signals(modelyamlver.raw)
self.assertEqual(expected_signal_properties, modelyamlver.signal_properties)
# Different properties connected to the same outsignal in different device proxies.
modelyamlver.app_outsignals = ["test_outsignal2", "test_outsignal"]
modelyamlver.signal_properties = {"dummy_model": []}
modelyamlver.raw = {
"dummy_dp": [
{"property": "test_property2", "outsignal": "test_outsignal2"},
{"property": "test_property", "outsignal": "test_outsignal"},
]
}
expected_signal_properties = {
"dummy_model": ["dummy_dp.test_property2.test_outsignal2", "dummy_dp.test_property.test_outsignal"],
}
modelyamlver.verify_signals(modelyamlver.raw)
self.assertEqual(expected_signal_properties, modelyamlver.signal_properties)
# Different outsignals connected to the same property
modelyamlver.app_outsignals = ["test_outsignal", "test_outsignal2"]
modelyamlver.signal_properties = {"dummy_model": []}
modelyamlver.raw = {
"dummy_dp": [
{"property": "test_property", "outsignal": "test_outsignal"},
{"property": "test_property", "outsignal": "test_outsignal2"},
]
}
exception_msg = (
"ERROR:root:You can't connect another signal to the existing property "
"dummy_dp.test_property.test_outsignal2"
" in dummy_model model, because it is already defined in dummy_model model.\n"
)
with self.assertLogs(level="INFO") as warn_info:
modelyamlver.verify_signals(modelyamlver.raw)
self.assertEqual(warn_info.output, [exception_msg])
# Same outsignal connected to the same property several times
modelyamlver.app_outsignals = ["test_outsignal", "test_outsignal2"]
modelyamlver.signal_properties = {"dummy_model": []}
modelyamlver.raw = {
"dummy_dp": [
{"property": "test_property", "outsignal": "test_outsignal"},
{"property": "test_property", "outsignal": "test_outsignal"},
]
}
exception_msg = "ERROR:root:You can't connect signal test_outsignal in dummy_model model twice.\n"
with self.assertLogs(level="INFO") as warn_info:
modelyamlver.verify_signals(modelyamlver.raw)
self.assertEqual(warn_info.output, [exception_msg])
def test_verify_insignals(self):
"""Test the verify_signals method with insignals."""
app = mock.MagicMock()
modelyamlver = ModelYmlVerification(app)
modelyamlver.model_name = "dummy_model"
modelyamlver.app_insignals = {}
modelyamlver.raw = {"dummy_dp": [{"property": "test_property", "insignal": "test_insignal"}]}
exception_msg = "ERROR:root:test_insignal is not defined as an insignal in json file\n"
with self.assertLogs(level="INFO") as warn_info:
modelyamlver.verify_signals(modelyamlver.raw)
self.assertEqual(warn_info.output, [exception_msg])
# Different properties connected to the same insignal
modelyamlver.app_insignals = ["test_insignal"]
modelyamlver.signal_properties = {"dummy_model": []}
modelyamlver.raw = {
"dummy_dp": [
{"property": "test_property", "insignal": "test_insignal"},
{"property": "test_property2", "insignal": "test_insignal"},
]
}
exception_msg = (
"ERROR:root:You can't connect a signal test_insignal in dummy_model model to two"
" different primitives. It's already connected in dummy_model model\n"
)
with self.assertLogs(level="INFO") as warn_info:
modelyamlver.verify_signals(modelyamlver.raw)
self.assertEqual(warn_info.output, [exception_msg])
# Different insignals connected to the same property
modelyamlver.app_insignals = ["test_insignal", "test_insignal2"]
modelyamlver.signal_properties = {"dummy_model": []}
modelyamlver.raw = {
"dummy_dp": [
{"property": "test_property", "insignal": "test_insignal"},
{"property": "test_property", "insignal": "test_insignal2"},
]
}
exception_msg = (
"ERROR:root:You can't connect another signal to the existing property "
"dummy_dp.test_property.test_insignal2"
" in dummy_model model, because it is already defined in dummy_model model.\n"
)
with self.assertLogs(level="INFO") as warn_info:
modelyamlver.verify_signals(modelyamlver.raw)
self.assertEqual(warn_info.output, [exception_msg])
# Different insignals connected to the same property in different models, should give an error message
modelyamlver.signal_properties = {"dummy_model": [], "dummy_model2": []}
modelyamlver.app_insignals = ["test_insignal", "test_insignal2"]
model_signal = {"dummy_model": "test_insignal", "dummy_model2": "test_insignal2"}
for model in ["dummy_model", "dummy_model2"]:
modelyamlver.model_name = model
modelyamlver.raw = {"dummy_dp": [{"property": "test_property", "insignal": model_signal[model]}]}
exception_msg = (
"ERROR:root:You can't connect another signal to the existing property "
"dummy_dp.test_property.test_insignal2"
" in dummy_model2 model, because it is already defined in dummy_model model.\n"
)
try:
with self.assertLogs(level="INFO") as warn_info:
modelyamlver.verify_signals(modelyamlver.raw)
except AssertionError:
warn_info = None
if not hasattr(warn_info, "output"):
raise AssertionError("no logs of level INFO or higher triggered on root")
self.assertEqual(warn_info.output, [exception_msg])
# Same insignal connected to the same property several times
modelyamlver.app_insignals = ["test_insignal", "test_insignal2"]
modelyamlver.signal_properties = {"dummy_model": []}
modelyamlver.model_name = "dummy_model"
modelyamlver.raw = {
"dummy_dp": [
{"property": "test_property", "insignal": "test_insignal"},
{"property": "test_property", "insignal": "test_insignal"},
]
}
exception_msg = "ERROR:root:You can't connect signal test_insignal in dummy_model model twice.\n"
with self.assertLogs(level="INFO") as warn_info:
modelyamlver.verify_signals(modelyamlver.raw)
self.assertEqual(warn_info.output, [exception_msg])
# Same insignal connected to the same property in different models, this should not give an error message
modelyamlver.signal_properties = {"dummy_model": [], "dummy_model2": []}
modelyamlver.app_insignals = ["test_insignal"]
for model in ["dummy_model", "dummy_model2"]:
modelyamlver.model_name = model
modelyamlver.raw = {"dummy_dp": [{"property": "test_property", "insignal": "test_insignal"}]}
exception_msg = (
"ERROR:root:You can't write dummy_dp.test_property in dummy_model2 model."
" It already exists in dummy_model model\n"
)
try:
with self.assertLogs(level="INFO") as warn_info:
modelyamlver.verify_signals(modelyamlver.raw)
except AssertionError:
continue
raise AssertionError(f"Error raised: {warn_info.output}")
def test_verify_hal_struct(self):
"""Test the verify_signals method for hal struct."""
app = mock.MagicMock()
modelyamlver = ModelYmlVerification(app)
modelyamlver.model_name = "dummy_model"
modelyamlver.app_insignals = {}
modelyamlver.raw = {
"insignal_struct": [
{"insignal": "test_insignal", "property": "test_insignal"},
{"property": "test_insignal2", "insignal": "test_insignal2"},
]
}
exception_msg = [
"ERROR:root:test_insignal is not defined as an insignal in json file\n",
"ERROR:root:test_insignal2 is not defined as an insignal in json file\n",
]
with self.assertLogs(level="INFO") as warn_info:
modelyamlver.verify_signals(modelyamlver.raw)
self.assertEqual(warn_info.output, exception_msg)
def test_verify_hal_signals(self):
"""Test the verify_signals method for hal signals."""
app = mock.MagicMock()
modelyamlver = ModelYmlVerification(app)
modelyamlver.model_name = "dummy_model"
modelyamlver.app_insignals = {}
modelyamlver.raw = {"insignal_property": [{"insignal": "test_insignal"}]}
exception_msg = "ERROR:root:test_insignal is not defined as an insignal in json file\n"
with self.assertLogs(level="INFO") as warn_info:
modelyamlver.verify_signals(modelyamlver.raw, is_hal=True, is_service=False, group="dummy_grp")
self.assertEqual(warn_info.output, [exception_msg])
app = mock.MagicMock()
modelyamlver = ModelYmlVerification(app)
modelyamlver.model_name = "dummy_model"
modelyamlver.app_insignals = ["test_insignal"]
modelyamlver.raw = {"insignal_property": [{"insignal": "test_insignal"}]}
modelyamlver.signal_properties = {"dummy_model": ["dummy_dp.property_outsignal"]}
modelyamlver.verify_signals(modelyamlver.raw, is_hal=True, is_service=False, group="dummy_grp")
expected_signal_properties = {
"dummy_model": ["dummy_dp.property_outsignal", "insignal_property.dummy_grp.test_insignal"]
}
self.assertEqual(modelyamlver.signal_properties, expected_signal_properties)
def test_parse_service_definitions(self):
"""Test the parse_service_definitions method."""
app = mock.MagicMock()
modelyamlver = ModelYmlVerification(app)
modelyamlver.model_name = "dummy_model"
modelyamlver.app_insignals = ["test_insignal"]
modelyamlver.signal_properties = {"dummy_model": []}
modelyamlver.raw = {
"dummy_service": {
"methods": [
{
"dummy_endpoint1": [{"insignal": "test_insignal"}],
"dummy_endpoint2": [{"insignal": "test_insignal"}],
}
]
}
}
exception_msg = [
"ERROR:root:You can't connect a signal test_insignal in dummy_model model to two "
"different primitives. It's already connected in dummy_model model\n"
]
with self.assertLogs(level="INFO") as warn_info:
modelyamlver.parse_service_definitions(modelyamlver.raw)
self.assertEqual(warn_info.output, exception_msg)
def test_validate_dp_signal_schema(self):
"""Test the validate_signal_schema method."""
app = mock.MagicMock()
modelyamlver = ModelYmlVerification(app)
modelyamlver.model_name = "dummy_model"
signal_spec = {"insignal": "test_insignal"}
exception_msg = "ERROR:root:required key not provided @ data['property'] in dummy_model\n"
with self.assertLogs(level="INFO") as warn_info:
modelyamlver.validate_signal_schema(signal_spec, "insignal", is_hal=False, is_service=False)
self.assertEqual(warn_info.output, [exception_msg])
def test_check_dp_property(self):
"""Test the verify_primitive method."""
app = mock.MagicMock()
modelyamlver = ModelYmlVerification(app)
modelyamlver.model_name = "dummy_model2"
modelyamlver.signal_properties = {"dummy_model1": ["dummy_dp.property_outsignal.signal"], "dummy_model2": []}
exception_msg = (
"ERROR:root:You can't connect another signal to the existing property "
"dummy_dp.property_outsignal.signal2"
" in dummy_model2 model, because it is already defined in dummy_model1 model.\n"
)
with self.assertLogs(level="INFO") as warn_info:
modelyamlver.check_property("dummy_dp.property_outsignal.signal2")
self.assertEqual(warn_info.output, [exception_msg])
app = mock.MagicMock()
modelyamlver = ModelYmlVerification(app)
modelyamlver.model_name = "dummy_model2"
modelyamlver.signal_properties = {"dummy_model1": ["dummy_dp.property_outsignal"], "dummy_model2": []}
expected_signal_properties = {
"dummy_model1": ["dummy_dp.property_outsignal"],
"dummy_model2": ["dummy_dp.property_insignal.signal"],
}
modelyamlver.verify_primitive("dummy_dp.property_insignal.signal", "outsignal")
self.assertEqual(expected_signal_properties, modelyamlver.signal_properties)