From e186880aae87917ef4c9f81e0d7ce82b4b04dca5 Mon Sep 17 00:00:00 2001 From: Max Chesterfield Date: Mon, 13 Oct 2025 17:57:06 +1100 Subject: [PATCH 1/3] fix borked test, also drop python 3.9 tests from hypothesis Signed-off-by: Max Chesterfield --- changelog.md | 1 + .../cim/iec61968/metering/controlled_appliance.py | 2 ++ .../metering/test_pan_demand_response_function.py | 15 ++++++++------- .../network/translator/test_network_translator.py | 5 +++-- tox.ini | 4 ++-- 5 files changed, 16 insertions(+), 11 deletions(-) diff --git a/changelog.md b/changelog.md index 6139b2ab..8ee7d087 100644 --- a/changelog.md +++ b/changelog.md @@ -13,6 +13,7 @@ ### Fixes * Moved ZepbenTokenAuth to use python dataclasses instead of `zepben.ewb.dataclassy`, existing code should work as is. * `TypeError`s occurring in `StepAction`s will no longer silently pass +* Drop python 3.9 from list of test envs in tox ### Notes * None. diff --git a/src/zepben/ewb/model/cim/iec61968/metering/controlled_appliance.py b/src/zepben/ewb/model/cim/iec61968/metering/controlled_appliance.py index 18e30342..943eaebf 100644 --- a/src/zepben/ewb/model/cim/iec61968/metering/controlled_appliance.py +++ b/src/zepben/ewb/model/cim/iec61968/metering/controlled_appliance.py @@ -83,6 +83,8 @@ def f(bitmask: int, nxt: Appliance) -> int: if len(appliances) > 1: _ = [acc := f(acc, app) for app in appliances[1:]] self._bitmask = acc + else: + raise TypeError('appliances must be a int or Appliance') @property def bitmask(self): diff --git a/test/cim/extensions/iec61968/metering/test_pan_demand_response_function.py b/test/cim/extensions/iec61968/metering/test_pan_demand_response_function.py index 91cb58c6..c74b6a64 100644 --- a/test/cim/extensions/iec61968/metering/test_pan_demand_response_function.py +++ b/test/cim/extensions/iec61968/metering/test_pan_demand_response_function.py @@ -4,10 +4,10 @@ # file, You can obtain one at https://mozilla.org/MPL/2.0/. from pytest import raises from hypothesis import given -from hypothesis.strategies import sampled_from, integers +from hypothesis.strategies import sampled_from, lists, builds -from cim.iec61968.metering.test_end_device_function import end_device_function_kwargs, end_device_function_args, verify_end_device_function_constructor_default, \ - verify_end_device_function_constructor_args +from cim.iec61968.metering.test_end_device_function import end_device_function_kwargs, end_device_function_args, \ + verify_end_device_function_constructor_default, verify_end_device_function_constructor_args from test.cim.iec61968.metering.test_end_device_function import verify_end_device_function_constructor_kwargs from zepben.ewb import PanDemandResponseFunction, ControlledAppliance, Appliance from zepben.ewb.model.cim.iec61968.metering.end_device_function_kind import EndDeviceFunctionKind @@ -15,10 +15,10 @@ pan_demand_response_function_kwargs = { **end_device_function_kwargs, "kind": sampled_from(EndDeviceFunctionKind), - "appliance": integers(min_value=0, max_value=4095) + "appliance": builds(ControlledAppliance, appliances=lists(sampled_from(Appliance), max_size=4, min_size=1, unique=True)) } -pan_demand_response_function_args = [*end_device_function_args, EndDeviceFunctionKind.demandResponse, 1] +pan_demand_response_function_args = [*end_device_function_args, EndDeviceFunctionKind.demandResponse, sampled_from(Appliance)] def test_pan_demand_response_function_constructor_default(): @@ -36,7 +36,7 @@ def test_pan_demand_response_function_constructor_kwargs(kind, appliance, **kwar verify_end_device_function_constructor_kwargs(pdrf, **kwargs) assert pdrf.kind == kind - assert pdrf.appliance.bitmask == appliance + assert pdrf.appliance == appliance def test_pan_demand_response_function_constructor_args(): @@ -44,7 +44,8 @@ def test_pan_demand_response_function_constructor_args(): verify_end_device_function_constructor_args(pdrf) - assert pan_demand_response_function_args[-2:] == [pdrf.kind, pdrf.appliance.bitmask] + assert pan_demand_response_function_args[-2] == pdrf.kind + assert pan_demand_response_function_args[-1][0].bitmask == pdrf.appliance.bitmask def test_constructor_with_controlled_appliance(): diff --git a/test/services/network/translator/test_network_translator.py b/test/services/network/translator/test_network_translator.py index 5a185c33..a9d8d837 100644 --- a/test/services/network/translator/test_network_translator.py +++ b/test/services/network/translator/test_network_translator.py @@ -225,10 +225,11 @@ "create_circuit": create_circuit(), } - +# FIXME: this test is terrible, it needs to be broken up to run PER CIM object, not all at once. it takes only one failure in creating an object +# for hypothesis to throw the whole generated batch out and try again, its very expensive. @pytest.mark.timeout(100000) @given(**types_to_test) -@settings(suppress_health_check=[HealthCheck.too_slow, HealthCheck.large_base_example, HealthCheck.data_too_large], stateful_step_count=2) +@settings(suppress_health_check=[HealthCheck.too_slow, HealthCheck.large_base_example, HealthCheck.data_too_large], stateful_step_count=2, max_examples=2) def test_network_service_translations(**kwargs): # # NOTE: To prevent the `assume` required for the location from making this test take way too long, it has been separated out. diff --git a/tox.ini b/tox.ini index dc276a09..c9749972 100644 --- a/tox.ini +++ b/tox.ini @@ -1,6 +1,6 @@ [tox] envlist = - py{312, 311, 310, 39} + py{312, 311, 310} build [testenv] @@ -10,7 +10,7 @@ pip_pre = true extras = test depends = # build the package after testing - build: py{312, 311, 310, 39} + build: py{312, 311, 310} commands = pytest --cov=zepben.ewb --cov-report=xml --cov-branch {posargs} [testenv:build] From 213b1e5b027069b571458494ba904e33ec4633c8 Mon Sep 17 00:00:00 2001 From: Max Chesterfield Date: Mon, 13 Oct 2025 22:53:31 +1100 Subject: [PATCH 2/3] I fixed it.... Its finally dead... Signed-off-by: Max Chesterfield --- pyproject.toml | 2 +- src/zepben/ewb/services/common/difference.py | 4 +- test/cim/cim_creators.py | 2 +- .../test_pan_demand_response_function.py | 4 +- .../common/translator/base_test_translator.py | 76 +++++++++++-------- .../translator/test_customer_translator.py | 6 +- .../translator/test_diagram_translator.py | 6 +- .../translator/test_network_translator.py | 48 ++---------- 8 files changed, 61 insertions(+), 87 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 01fc985c..05ca3b53 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -49,7 +49,7 @@ "pytest-asyncio==1.1.0", "pytest-timeout==2.4.0", "pytest-subtests==0.14.2", - "hypothesis==6.138.2", + "hypothesis==6.140.3", "grpcio-testing==1.61.3", "pylint==2.14.5", "six==1.16.0", diff --git a/src/zepben/ewb/services/common/difference.py b/src/zepben/ewb/services/common/difference.py index cba02ad4..0e0e865a 100644 --- a/src/zepben/ewb/services/common/difference.py +++ b/src/zepben/ewb/services/common/difference.py @@ -30,8 +30,8 @@ class CollectionDifference(Difference): @dataclass() class ObjectDifference(Difference): - source: T - target: T + source: IdentifiedObject + target: IdentifiedObject differences: Dict[str, Difference] = field(default_factory=dict) diff --git a/test/cim/cim_creators.py b/test/cim/cim_creators.py index 559551b7..e17ca143 100644 --- a/test/cim/cim_creators.py +++ b/test/cim/cim_creators.py @@ -818,7 +818,7 @@ def create_equipment(include_runtime: bool): def create_equipment_container(include_runtime: bool, add_equipment: bool = True): equipment = { - "equipment": lists(sampled_equipment(include_runtime), min_size=1, max_size=2) + "equipment": lists(sampled_equipment(include_runtime), min_size=1, max_size=30) } if add_equipment else {} return { diff --git a/test/cim/extensions/iec61968/metering/test_pan_demand_response_function.py b/test/cim/extensions/iec61968/metering/test_pan_demand_response_function.py index c74b6a64..f15ac8f9 100644 --- a/test/cim/extensions/iec61968/metering/test_pan_demand_response_function.py +++ b/test/cim/extensions/iec61968/metering/test_pan_demand_response_function.py @@ -18,7 +18,7 @@ "appliance": builds(ControlledAppliance, appliances=lists(sampled_from(Appliance), max_size=4, min_size=1, unique=True)) } -pan_demand_response_function_args = [*end_device_function_args, EndDeviceFunctionKind.demandResponse, sampled_from(Appliance)] +pan_demand_response_function_args = [*end_device_function_args, EndDeviceFunctionKind.demandResponse, Appliance.IRRIGATION_PUMP] def test_pan_demand_response_function_constructor_default(): @@ -45,7 +45,7 @@ def test_pan_demand_response_function_constructor_args(): verify_end_device_function_constructor_args(pdrf) assert pan_demand_response_function_args[-2] == pdrf.kind - assert pan_demand_response_function_args[-1][0].bitmask == pdrf.appliance.bitmask + assert pan_demand_response_function_args[-1].bitmask == pdrf.appliance.bitmask def test_constructor_with_controlled_appliance(): diff --git a/test/services/common/translator/base_test_translator.py b/test/services/common/translator/base_test_translator.py index 019e841f..52996031 100644 --- a/test/services/common/translator/base_test_translator.py +++ b/test/services/common/translator/base_test_translator.py @@ -2,13 +2,16 @@ # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at https://mozilla.org/MPL/2.0/. -from traceback import print_tb, format_tb -from typing import TypeVar, Type, Set +from traceback import print_tb +from typing import TypeVar, Type, Set, Any + +from hypothesis import given, settings, Verbosity +from hypothesis.strategies import SearchStrategy from zepben.ewb import IdentifiedObject, BaseService, BaseServiceComparator, EquipmentContainer, OperationalRestriction, ConnectivityNode, TableVersion, \ TableMetadataDataSources, TableNameTypes, TableNames, SqliteTable from zepben.ewb.database.sqlite.common.base_database_tables import BaseDatabaseTables -from zepben.protobuf.cim.iec61970.base.core.IdentifiedObject_pb2 import IdentifiedObject as PBIdentifiedObject +from zepben.ewb.streaming.get.consumer import PBIdentifiedObject T = TypeVar("T", bound=IdentifiedObject) @@ -20,11 +23,11 @@ def validate_service_translations( comparator: BaseServiceComparator, database_tables: BaseDatabaseTables, excluded_tables: Set[Type[SqliteTable]], - **kwargs + types_to_test: dict[str, SearchStrategy[Any]], ): expected_tables = {it.__class__ for it in database_tables.tables} - excluded_tables - _excluded_base_tables - if len(kwargs) != len(expected_tables): - actual = {k.removeprefix("create_") for k, v in kwargs.items()} + if len(types_to_test) != len(expected_tables): + actual = {k.removeprefix("create_") for k in types_to_test.keys()} expected = {it().name for it in expected_tables} # create variant without the last two letters to cater for `s` and `es` plurals in the logging. @@ -47,37 +50,45 @@ def validate_service_translations( print() diffs = {} processing = "" + try: - for desc, cim in kwargs.items(): - processing = f"blank {desc}" - blank = type(cim)() - - # Convert the blank object to protobuf and ensure it didn't get converted to an instance of PBIdentifiedObject, - # which indicates a missing `to_pb` implementation or import. - blank_as_pb = blank.to_pb() - assert type(blank_as_pb) is not PBIdentifiedObject, f"There is something wrong with {type(cim)}.to_pb. It is calling directly to the base class." - - # noinspection PyUnresolvedReferences - translated_blank = service_type().add_from_pb(blank_as_pb) - assert translated_blank is not None, f"{blank_as_pb}: Failed to add the translated protobuf object to the service." - assert type(translated_blank) is type(cim), f"{translated_blank}: Converted object should be the same type as {cim}" - - result = comparator.compare_objects(blank, translated_blank) - if result.differences: - diffs[f"blank {desc}"] = result - - processing = f"populated {desc}" - _remove_unsent_references(cim) - # noinspection PyUnresolvedReferences - service = service_type() # outside _add_with_unresolved_references so weak references on `cim` cant be garbage collected before being compared. - result = comparator.compare_objects(cim, _add_with_unresolved_references(service, cim)) - if result.differences: - diffs[f"populated {desc}"] = result + for desc, _cim in types_to_test.items(): + print(desc) + + @given(_cim) + @settings(verbosity=Verbosity.verbose) + def run_test(cim): + nonlocal processing + blank = type(cim)() + + # Convert the blank object to protobuf and ensure it didn't get converted to an instance of PBIdentifiedObject, + # which indicates a missing `to_pb` implementation or import. + blank_as_pb = blank.to_pb() + assert type( + blank_as_pb) is not PBIdentifiedObject, f"There is something wrong with {type(cim)}.to_pb. It is calling directly to the base class." + + # noinspection PyUnresolvedReferences + translated_blank = service_type('test').add_from_pb(blank_as_pb) + assert translated_blank is not None, f"{blank_as_pb}: Failed to add the translated protobuf object to the service." + assert type(translated_blank) is type(cim), f"{translated_blank}: Converted object should be the same type as {cim}" + + result = comparator.compare_objects(blank, translated_blank) + if result.differences: + diffs[f"blank {desc}"] = result + + processing = f"populated {desc}" + _remove_unsent_references(cim) + # outside _add_with_unresolved_references so weak references on `cim` cant be garbage collected before being compared. + service = service_type('test') + result = comparator.compare_objects(cim, _add_with_unresolved_references(service, cim)) + if result.differences: + diffs[f"populated {desc}"] = result + + run_test() except BaseException as e: print("###########################") print(f"Processing {processing}:") print(f"Exception [{type(e).__name__}: {e}") - test = format_tb(e.__traceback__) print_tb(e.__traceback__) print("---------------------------") print(diffs) @@ -88,7 +99,6 @@ def validate_service_translations( print(diffs) assert not diffs - def _format_validation_error(description: str, classes: Set[str]) -> str: return f"\n{description}: {classes}\n" if classes else "" diff --git a/test/services/customer/translator/test_customer_translator.py b/test/services/customer/translator/test_customer_translator.py index 05d7ac5f..08d25d27 100644 --- a/test/services/customer/translator/test_customer_translator.py +++ b/test/services/customer/translator/test_customer_translator.py @@ -4,7 +4,6 @@ # file, You can obtain one at https://mozilla.org/MPL/2.0/. from typing import TypeVar -from hypothesis import given from zepben.ewb import IdentifiedObject, CustomerService, NameType, CustomerDatabaseTables, TableCustomerAgreementsPricingStructures, \ TablePricingStructuresTariffs from zepben.ewb.services.common.translator.base_proto2cim import get_nullable @@ -35,8 +34,7 @@ } -@given(**types_to_test) -def test_customer_service_translations(**kwargs): +def test_customer_service_translations(): validate_service_translations( CustomerService, CustomerServiceComparator(), @@ -45,7 +43,7 @@ def test_customer_service_translations(**kwargs): TableCustomerAgreementsPricingStructures, TablePricingStructuresTariffs }, - **kwargs + types_to_test=types_to_test, ) diff --git a/test/services/diagram/translator/test_diagram_translator.py b/test/services/diagram/translator/test_diagram_translator.py index 242cead2..56820126 100644 --- a/test/services/diagram/translator/test_diagram_translator.py +++ b/test/services/diagram/translator/test_diagram_translator.py @@ -4,7 +4,6 @@ # file, You can obtain one at https://mozilla.org/MPL/2.0/. from typing import TypeVar -from hypothesis import given from zepben.ewb import IdentifiedObject, DiagramService, NameType, DiagramDatabaseTables, TableDiagramObjectPoints from zepben.ewb.services.common.translator.base_proto2cim import get_nullable from zepben.ewb.services.diagram.diagram_service_comparator import DiagramServiceComparator @@ -26,8 +25,7 @@ } -@given(**types_to_test) -def test_diagram_service_translations(**kwargs): +def test_diagram_service_translations(): validate_service_translations( DiagramService, DiagramServiceComparator(), @@ -35,7 +33,7 @@ def test_diagram_service_translations(**kwargs): excluded_tables={ TableDiagramObjectPoints }, - **kwargs + types_to_test=types_to_test, ) diff --git a/test/services/network/translator/test_network_translator.py b/test/services/network/translator/test_network_translator.py index a9d8d837..b2abec53 100644 --- a/test/services/network/translator/test_network_translator.py +++ b/test/services/network/translator/test_network_translator.py @@ -5,10 +5,10 @@ from typing import TypeVar import pytest -from hypothesis import given, HealthCheck, settings +from hypothesis import given, HealthCheck, settings, Verbosity from database.sqlite.schema_utils import assume_non_blank_street_address_details -from services.common.translator.base_test_translator import validate_service_translations +from services.common.translator.base_test_translator import validate_service_translations, _remove_unsent_references, _add_with_unresolved_references from test.cim.cim_creators import * from zepben.ewb import IdentifiedObject, PowerTransformerEnd, PowerTransformer, NetworkService, Location, NetworkServiceComparator, NameType, \ NetworkDatabaseTables, TableLocations, TableAssetOrganisationRolesAssets, TableCircuitsSubstations, TableCircuitsTerminals, \ @@ -21,7 +21,7 @@ T = TypeVar("T", bound=IdentifiedObject) -types_to_test = { +types_to_test_creators = { ################################## # Extensions IEC61968 Asset Info # ################################## @@ -223,24 +223,12 @@ ############################### "create_circuit": create_circuit(), + + "create_location": create_location(), } -# FIXME: this test is terrible, it needs to be broken up to run PER CIM object, not all at once. it takes only one failure in creating an object -# for hypothesis to throw the whole generated batch out and try again, its very expensive. -@pytest.mark.timeout(100000) -@given(**types_to_test) -@settings(suppress_health_check=[HealthCheck.too_slow, HealthCheck.large_base_example, HealthCheck.data_too_large], stateful_step_count=2, max_examples=2) -def test_network_service_translations(**kwargs): - # - # NOTE: To prevent the `assume` required for the location from making this test take way too long, it has been separated out. - # - # If this test still appears to lock up, it is likely you have missed validating a class or forgot to exclude the table. Either figure out which - # case you have, or wait for the test to finish, and it will tell you. - # - # NOTE: updating hypothesis can break this test on python 3.9 to 1.200.0 and beyond, if you do that, and it breaks, this command - # will run only this test: - # tox -e py39 -- test/services/network/translator/test_network_translator.py::test_network_service_translations --no-cov - # +@pytest.mark.timeout(20000) +def test_network_service_translations(): validate_service_translations( NetworkService, NetworkServiceComparator(), @@ -273,31 +261,11 @@ def test_network_service_translations(**kwargs): TableProtectionRelayFunctionsSensors, TableRecloseDelays, - # Excluded location table in the other test. - TableLocations }, - **kwargs - ) - - -@given(location=create_location()) -@settings(suppress_health_check=[HealthCheck.too_slow]) -def test_network_service_translations_location(location: Location): - # If this `assume` is placed with the other checks it makes the test take a very long time to run due to the number of falsifying examples it creates. - assume_non_blank_street_address_details(location.main_address) - validate_service_translations( - NetworkService, - NetworkServiceComparator(), - NetworkDatabaseTables(), - excluded_tables={it.__class__ for it in NetworkDatabaseTables().tables if not isinstance(it, TableLocations)}, - location=location + types_to_test=types_to_test_creators, ) - -# # NOTE: NameType is not sent via any grpc messages at this stage, so test it separately -# - def test_creates_new_name_type(): # noinspection PyArgumentList, PyUnresolvedReferences pb = NameType("nt1 name", "nt1 desc").to_pb() From 420231ce4e41071ea18efba53f0b7c5eb5cc260c Mon Sep 17 00:00:00 2001 From: Max Chesterfield Date: Thu, 16 Oct 2025 18:24:57 +1100 Subject: [PATCH 3/3] PR fixes Signed-off-by: Max Chesterfield --- .../common/translator/base_test_translator.py | 20 +++++++++---------- .../translator/test_network_translator.py | 19 +++++++----------- 2 files changed, 17 insertions(+), 22 deletions(-) diff --git a/test/services/common/translator/base_test_translator.py b/test/services/common/translator/base_test_translator.py index 52996031..ebfa2b97 100644 --- a/test/services/common/translator/base_test_translator.py +++ b/test/services/common/translator/base_test_translator.py @@ -1,17 +1,17 @@ -# Copyright 2024 Zeppelin Bend Pty Ltd +# Copyright 2025 Zeppelin Bend Pty Ltd # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at https://mozilla.org/MPL/2.0/. from traceback import print_tb from typing import TypeVar, Type, Set, Any -from hypothesis import given, settings, Verbosity +from hypothesis import given from hypothesis.strategies import SearchStrategy from zepben.ewb import IdentifiedObject, BaseService, BaseServiceComparator, EquipmentContainer, OperationalRestriction, ConnectivityNode, TableVersion, \ - TableMetadataDataSources, TableNameTypes, TableNames, SqliteTable + TableMetadataDataSources, TableNameTypes, TableNames, SqliteTable, NetworkService, CustomerService, DiagramService from zepben.ewb.database.sqlite.common.base_database_tables import BaseDatabaseTables -from zepben.ewb.streaming.get.consumer import PBIdentifiedObject +from zepben.protobuf.cim.iec61970.base.core.IdentifiedObject_pb2 import IdentifiedObject as PBIdentifiedObject T = TypeVar("T", bound=IdentifiedObject) @@ -19,7 +19,7 @@ def validate_service_translations( - service_type: Type[BaseService], + service_type: Type[NetworkService | CustomerService | DiagramService], comparator: BaseServiceComparator, database_tables: BaseDatabaseTables, excluded_tables: Set[Type[SqliteTable]], @@ -52,13 +52,13 @@ def validate_service_translations( processing = "" try: - for desc, _cim in types_to_test.items(): + for desc, cim_builder in types_to_test.items(): print(desc) - @given(_cim) - @settings(verbosity=Verbosity.verbose) + @given(cim_builder) def run_test(cim): nonlocal processing + processing = f"blank {desc}" blank = type(cim)() # Convert the blank object to protobuf and ensure it didn't get converted to an instance of PBIdentifiedObject, @@ -68,7 +68,7 @@ def run_test(cim): blank_as_pb) is not PBIdentifiedObject, f"There is something wrong with {type(cim)}.to_pb. It is calling directly to the base class." # noinspection PyUnresolvedReferences - translated_blank = service_type('test').add_from_pb(blank_as_pb) + translated_blank = service_type().add_from_pb(blank_as_pb) assert translated_blank is not None, f"{blank_as_pb}: Failed to add the translated protobuf object to the service." assert type(translated_blank) is type(cim), f"{translated_blank}: Converted object should be the same type as {cim}" @@ -79,7 +79,7 @@ def run_test(cim): processing = f"populated {desc}" _remove_unsent_references(cim) # outside _add_with_unresolved_references so weak references on `cim` cant be garbage collected before being compared. - service = service_type('test') + service = service_type() result = comparator.compare_objects(cim, _add_with_unresolved_references(service, cim)) if result.differences: diffs[f"populated {desc}"] = result diff --git a/test/services/network/translator/test_network_translator.py b/test/services/network/translator/test_network_translator.py index b2abec53..a160d5b3 100644 --- a/test/services/network/translator/test_network_translator.py +++ b/test/services/network/translator/test_network_translator.py @@ -1,17 +1,15 @@ -# Copyright 2024 Zeppelin Bend Pty Ltd +# Copyright 2025 Zeppelin Bend Pty Ltd # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at https://mozilla.org/MPL/2.0/. from typing import TypeVar import pytest -from hypothesis import given, HealthCheck, settings, Verbosity -from database.sqlite.schema_utils import assume_non_blank_street_address_details -from services.common.translator.base_test_translator import validate_service_translations, _remove_unsent_references, _add_with_unresolved_references +from services.common.translator.base_test_translator import validate_service_translations from test.cim.cim_creators import * -from zepben.ewb import IdentifiedObject, PowerTransformerEnd, PowerTransformer, NetworkService, Location, NetworkServiceComparator, NameType, \ - NetworkDatabaseTables, TableLocations, TableAssetOrganisationRolesAssets, TableCircuitsSubstations, TableCircuitsTerminals, \ +from zepben.ewb import IdentifiedObject, PowerTransformerEnd, PowerTransformer, NetworkService, NetworkServiceComparator, NameType, \ + NetworkDatabaseTables, TableAssetOrganisationRolesAssets, TableCircuitsSubstations, TableCircuitsTerminals, \ TableEquipmentEquipmentContainers, TableEquipmentOperationalRestrictions, TableEquipmentUsagePoints, TableLoopsSubstations, \ TableProtectionRelayFunctionsProtectedSwitches, TableProtectionRelaySchemesProtectionRelayFunctions, TableUsagePointsEndDevices, \ TableLocationStreetAddresses, TablePositionPoints, TablePowerTransformerEndRatings, TableProtectionRelayFunctionThresholds, \ @@ -21,7 +19,7 @@ T = TypeVar("T", bound=IdentifiedObject) -types_to_test_creators = { +types_to_test = { ################################## # Extensions IEC61968 Asset Info # ################################## @@ -94,8 +92,7 @@ # IEC61968 Common # ################### - # NOTE: location is tested separately due to constraints on the translation. - # "create_location": create_location(), + "create_location": create_location(), "create_organisation": create_organisation(), ##################################### @@ -223,8 +220,6 @@ ############################### "create_circuit": create_circuit(), - - "create_location": create_location(), } @pytest.mark.timeout(20000) @@ -262,7 +257,7 @@ def test_network_service_translations(): TableRecloseDelays, }, - types_to_test=types_to_test_creators, + types_to_test=types_to_test, ) # NOTE: NameType is not sent via any grpc messages at this stage, so test it separately