This is an automated email from the ASF dual-hosted git repository. av pushed a commit to branch ignite-ducktape in repository https://gitbox.apache.org/repos/asf/ignite.git
The following commit(s) were added to refs/heads/ignite-ducktape by this push: new dd071b4 Implement IntEnum enhancement (construct_from) for better support of parametrization. (#8476) dd071b4 is described below commit dd071b4abf724c7d7ec636637d97736dbf1ab6cb Author: Ivan Daschinskiy <ivanda...@gmail.com> AuthorDate: Thu Nov 19 12:05:19 2020 +0300 Implement IntEnum enhancement (construct_from) for better support of parametrization. (#8476) --- .../tests/checks/utils/check_enum_constructible.py | 72 ++++++++++++++++++++++ .../ignitetest/tests/cellular_affinity_test.py | 16 +++-- .../tests/ignitetest/tests/discovery_test.py | 18 +++--- modules/ducktests/tests/ignitetest/utils/enum.py | 66 ++++++++++++++++++++ 4 files changed, 159 insertions(+), 13 deletions(-) diff --git a/modules/ducktests/tests/checks/utils/check_enum_constructible.py b/modules/ducktests/tests/checks/utils/check_enum_constructible.py new file mode 100644 index 0000000..3c6781e --- /dev/null +++ b/modules/ducktests/tests/checks/utils/check_enum_constructible.py @@ -0,0 +1,72 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +""" +Checks IntEnum enhancement. +""" + +from enum import IntEnum + +import pytest +from ignitetest.utils.enum import constructible + + +@constructible +class ConnectType(IntEnum): + """ + Example of IntEnum. + """ + UDP = 0 + TCP = 1 + HTTP = 2 + + +check_params = [] +for name, value in ConnectType.__members__.items(): + check_params.append([name, value]) + check_params.append([int(value), value]) + check_params.append([value, value]) + + +# pylint: disable=no-self-use, no-member +class CheckEnumConstructible: + """ + Basic test of IntEnum decorated with @constructible. + """ + @pytest.mark.parametrize( + ['input_value', 'expected_value'], + check_params + ) + def check_construct_from(self, input_value, expected_value): + """Basic checks.""" + with ConnectType.construct_from(input_value) as conn_type: + assert conn_type is expected_value + + @pytest.mark.parametrize( + ['input_value'], + [[val] for val in [-1, .6, 'test']] + ) + def check_invalid_input(self, input_value): + """Check invalid input.""" + with pytest.raises(Exception): + ConnectType.construct_from(input_value) + + def check_invalid_usage(self): + """Check invalid type decoration.""" + with pytest.raises(AssertionError): + class SimpleClass: + """Cannot be decorated""" + + constructible(SimpleClass) diff --git a/modules/ducktests/tests/ignitetest/tests/cellular_affinity_test.py b/modules/ducktests/tests/ignitetest/tests/cellular_affinity_test.py index 3b11434..381c5d2 100644 --- a/modules/ducktests/tests/ignitetest/tests/cellular_affinity_test.py +++ b/modules/ducktests/tests/ignitetest/tests/cellular_affinity_test.py @@ -29,8 +29,10 @@ from ignitetest.services.utils.ignite_configuration.discovery import from_ignite from ignitetest.utils import ignite_versions, version_if, cluster from ignitetest.utils.ignite_test import IgniteTest from ignitetest.utils.version import DEV_BRANCH, IgniteVersion, LATEST_2_8 +from ignitetest.utils.enum import constructible +@constructible class StopType(IntEnum): """ Node stop method type. @@ -148,12 +150,14 @@ class CellularAffinity(IgniteTest): streamer.await_event("WARMUP_FINISHED", 180, from_the_beginning=True) # node left with prepared txs. - if stop_type is StopType.SIGTERM: - failed_loader.stop_async() - elif stop_type is StopType.SIGKILL: - failed_loader.stop(clean_shutdown=False) - elif stop_type is StopType.DISCONNECT: - failed_loader.drop_network() + # pylint: disable=no-member + with StopType.construct_from(stop_type) as s_type: + if s_type is StopType.SIGTERM: + failed_loader.stop_async() + elif s_type is StopType.SIGKILL: + failed_loader.stop(clean_shutdown=False) + elif s_type is StopType.DISCONNECT: + failed_loader.drop_network() for streamer in streamers: streamer.await_event("Node left topology\\|Node FAILED", 60, from_the_beginning=True) diff --git a/modules/ducktests/tests/ignitetest/tests/discovery_test.py b/modules/ducktests/tests/ignitetest/tests/discovery_test.py index a4606f1..758b54b 100644 --- a/modules/ducktests/tests/ignitetest/tests/discovery_test.py +++ b/modules/ducktests/tests/ignitetest/tests/discovery_test.py @@ -37,8 +37,10 @@ from ignitetest.services.zk.zookeeper import ZookeeperService, ZookeeperSettings from ignitetest.utils import ignite_versions, version_if, cluster from ignitetest.utils.ignite_test import IgniteTest from ignitetest.utils.version import DEV_BRANCH, LATEST_2_8, V_2_8_0, IgniteVersion +from ignitetest.utils.enum import constructible +@constructible class ClusterLoad(IntEnum): """ Type of cluster loading. @@ -61,7 +63,7 @@ class DiscoveryTestConfig(NamedTuple): failure_detection_timeout: int = 1000 -# pylint: disable=W0223 +# pylint: disable=W0223, no-member class DiscoveryTest(IgniteTest): """ Test various node failure scenarios (TCP and ZooKeeper). @@ -93,7 +95,7 @@ class DiscoveryTest(IgniteTest): Test nodes failure scenario with TcpDiscoverySpi not allowing nodes to fail in a row. """ test_config = DiscoveryTestConfig(version=IgniteVersion(ignite_version), nodes_to_kill=nodes_to_kill, - load_type=load_type, sequential_failure=False) + load_type=ClusterLoad.construct_from(load_type), sequential_failure=False) return self._perform_node_fail_scenario(test_config) @@ -104,8 +106,8 @@ class DiscoveryTest(IgniteTest): """ Test 2 nodes sequential failure scenario with TcpDiscoverySpi. """ - test_config = DiscoveryTestConfig(version=IgniteVersion(ignite_version), nodes_to_kill=2, load_type=load_type, - sequential_failure=True) + test_config = DiscoveryTestConfig(version=IgniteVersion(ignite_version), nodes_to_kill=2, + load_type=ClusterLoad.construct_from(load_type), sequential_failure=True) return self._perform_node_fail_scenario(test_config) @@ -119,7 +121,8 @@ class DiscoveryTest(IgniteTest): Test node failure scenario with ZooKeeperSpi not allowing nodes to fail in a row. """ test_config = DiscoveryTestConfig(version=IgniteVersion(ignite_version), nodes_to_kill=nodes_to_kill, - load_type=load_type, sequential_failure=False, with_zk=True) + load_type=ClusterLoad.construct_from(load_type), sequential_failure=False, + with_zk=True) return self._perform_node_fail_scenario(test_config) @@ -131,8 +134,9 @@ class DiscoveryTest(IgniteTest): """ Test node failure scenario with ZooKeeperSpi not allowing to fail nodes in a row. """ - test_config = DiscoveryTestConfig(version=IgniteVersion(ignite_version), nodes_to_kill=2, load_type=load_type, - sequential_failure=True, with_zk=True) + test_config = DiscoveryTestConfig(version=IgniteVersion(ignite_version), nodes_to_kill=2, + load_type=ClusterLoad.construct_from(load_type), sequential_failure=True, + with_zk=True) return self._perform_node_fail_scenario(test_config) diff --git a/modules/ducktests/tests/ignitetest/utils/enum.py b/modules/ducktests/tests/ignitetest/utils/enum.py new file mode 100644 index 0000000..3aa3b2c --- /dev/null +++ b/modules/ducktests/tests/ignitetest/utils/enum.py @@ -0,0 +1,66 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +""" +This module contains various syntaxic sugar for enums +""" + +from enum import IntEnum + + +def constructible(cls): + """ + If decorate IntEnum subclass with this decorator, following is possible: + + @constructible + class StopType(IntEnum): + SIGTERM = 0 + SIGKILL = 1 + DISCONNECT = 2 + + stop_type = 1 + + with StopType.construct_from(stop_type) as sp: + if sp is StopType.SIGKILL: + print('got sigkill') + + stop_type = 'DISCONNECT' + + with StopType.construct_from(stop_type) as sp: + if sp is StopType.DISCONNECT: + print('got disconnect') + + """ + assert issubclass(cls, IntEnum) + + members = dict(cls.__members__.items()) + + def construct_from(val): + if isinstance(val, str): + return members[val] + return cls.__new__(cls, val) + + def __enter__(self): + return self + + # pylint: disable=unused-argument + def __exit__(self, *args, **kwargs): + pass + + cls.construct_from = construct_from + cls.__enter__ = __enter__ + cls.__exit__ = __exit__ + + return cls