diff --git a/sbin/prepare_dev_env.sh b/sbin/prepare_dev_env.sh index 080ceb4725570870313225300b5730364c74bee4..d3dbc6094ef114ee9896a64ac23857b887a36d05 100755 --- a/sbin/prepare_dev_env.sh +++ b/sbin/prepare_dev_env.sh @@ -5,7 +5,7 @@ # # Url to the jumppad download location -jumppad_download="https://git.astron.nl/lofar2.0/tango/-/package_files/37347/download" +jumppad_download="https://git.astron.nl/lofar2.0/tango/-/package_files/40604/download" if [ -z "$LOFAR20_DIR" ]; then # We assume we aren't in the PATH, so we can derive our path. diff --git a/tangostationcontrol/integration_test/base.py b/tangostationcontrol/integration_test/base.py index cc42e12a2cfda188697e0cf6eb9345998bb79531..c944fda682c6f48b3d38b94035d5f1a87a0e93e8 100644 --- a/tangostationcontrol/integration_test/base.py +++ b/tangostationcontrol/integration_test/base.py @@ -3,7 +3,6 @@ import unittest -import asynctest import testscenarios from tangostationcontrol.common.lofar_logging import configure_logger @@ -25,7 +24,9 @@ class IntegrationTestCase(BaseIntegrationTestCase): super().setUp() -class IntegrationAsyncTestCase(testscenarios.WithScenarios, asynctest.TestCase): +class IntegrationAsyncTestCase( + testscenarios.WithScenarios, unittest.IsolatedAsyncioTestCase +): """Integration test case base class for all asyncio unit tests.""" def setUp(self): diff --git a/tangostationcontrol/integration_test/default/client/test_opcua_client_against_server.py b/tangostationcontrol/integration_test/default/client/test_opcua_client_against_server.py index f941298b8ca94fe4320618acba560865d8c8d844..c8bce5e602f2c3322466c04eb70740f2dd24a782 100644 --- a/tangostationcontrol/integration_test/default/client/test_opcua_client_against_server.py +++ b/tangostationcontrol/integration_test/default/client/test_opcua_client_against_server.py @@ -90,7 +90,6 @@ class TestClientServer(base.IntegrationAsyncTestCase): self.namespace, 5, self.fault_func, - self.loop, OPCUAConnectionStatus(), ) try: @@ -106,7 +105,6 @@ class TestClientServer(base.IntegrationAsyncTestCase): self.namespace, 5, self.fault_func, - self.loop, OPCUAConnectionStatus(), ) try: @@ -135,7 +133,6 @@ class TestClientServer(base.IntegrationAsyncTestCase): self.namespace, 5, self.fault_func, - self.loop, OPCUAConnectionStatus(), ) try: @@ -166,7 +163,6 @@ class TestClientServer(base.IntegrationAsyncTestCase): self.namespace, 5, self.fault_func, - self.loop, OPCUAConnectionStatus(), ) @@ -185,7 +181,6 @@ class TestClientServer(base.IntegrationAsyncTestCase): self.namespace, 5, self.fault_func, - self.loop, OPCUAConnectionStatus(), ) try: @@ -208,7 +203,6 @@ class TestClientServer(base.IntegrationAsyncTestCase): self.namespace, 5, self.fault_func, - self.loop, OPCUAConnectionStatus(), ) try: @@ -230,7 +224,6 @@ class TestClientServer(base.IntegrationAsyncTestCase): self.namespace, 5, self.fault_func, - self.loop, OPCUAConnectionStatus(), ) @@ -251,7 +244,6 @@ class TestClientServer(base.IntegrationAsyncTestCase): 5, self.fault_func, OPCUAConnectionStatus(), - self.loop, ) try: diff --git a/tangostationcontrol/test-requirements.txt b/tangostationcontrol/test-requirements.txt index 450da51eaace2090c33ccba0ea08fb052046d18e..cc253161b5ac00411a4a8954b7bf3e4553d91221 100644 --- a/tangostationcontrol/test-requirements.txt +++ b/tangostationcontrol/test-requirements.txt @@ -3,7 +3,6 @@ # integration process, which may cause wedges in the gate later. importlib-metadata<2.0.0,>=0.12;python_version<"3.8" -asynctest>=0.13.0 # Apache-2.0 bandit>=1.6.0 # Apache-2.0 virtualenv>=20.16.0 # MIT build>=0.8.0 # MIT diff --git a/tangostationcontrol/test/base.py b/tangostationcontrol/test/base.py index 8920e3bd3c68e317433d10854ba6bb7f4c6c4538..1149385f39c735cb6440a3b2031d053190ae6c63 100644 --- a/tangostationcontrol/test/base.py +++ b/tangostationcontrol/test/base.py @@ -7,7 +7,6 @@ from unittest import mock from typing import Dict from typing import Union -import asynctest import testscenarios from tangostationcontrol.common.lofar_logging import configure_logger @@ -41,7 +40,7 @@ class TestCase(BaseTestCase): super().setUp() -class AsyncTestCase(testscenarios.WithScenarios, asynctest.TestCase): +class AsyncTestCase(testscenarios.WithScenarios, unittest.IsolatedAsyncioTestCase): """Test case base class for all asyncio unit tests.""" def setUp(self): diff --git a/tangostationcontrol/test/clients/test_opcua_client.py b/tangostationcontrol/test/clients/test_opcua_client.py index 01987c99e3e2bae922e9e843db9d4e95bd07085d..af9f558ac51a61435538e547e692dab4a256e5a4 100644 --- a/tangostationcontrol/test/clients/test_opcua_client.py +++ b/tangostationcontrol/test/clients/test_opcua_client.py @@ -3,9 +3,10 @@ import asyncio import io +import unittest from unittest import mock +from unittest.mock import patch -import asynctest import asyncua import numpy @@ -15,8 +16,6 @@ from tangostationcontrol.clients.opcua_client import ( OPCUAConnectionStatus, ) -from test import base - class AttrProps: def __init__(self, numpy_type): @@ -44,27 +43,39 @@ IMAGE_SHAPE = (2, 3) DIMENSION_TESTS = [SCALAR_SHAPE, SPECTRUM_SHAPE, IMAGE_SHAPE] -class TestOPCua(base.AsyncTestCase): - @asynctest.patch.object(OPCUAConnection, "ping") - @asynctest.patch.object(OPCUAConnection, "_servername") - @asynctest.patch.object(opcua_client, "Client") +def create_mocked_coroutine(return_value=None): + if return_value is None: + return_value = mock.Mock() + + async def mock_coro(*args, **kwargs): + return return_value + + return mock.Mock(wraps=mock_coro) + + +class TestOPCua(unittest.IsolatedAsyncioTestCase): + @patch.object(OPCUAConnection, "ping") + @patch.object(OPCUAConnection, "_servername") + @patch.object(opcua_client, "Client") async def test_opcua_connection(self, m_opc_client, m_servername, m_ping): """ This tests verifies whether the correct connection steps happen. It checks whether we can init an OPCUAConnection object Whether we can set the namespace, and the OPCua client. """ - m_opc_client_members = asynctest.asynctest.CoroutineMock() - m_opc_client_members.get_namespace_index = asynctest.asynctest.CoroutineMock( + m_opc_client_members = create_mocked_coroutine() + m_opc_client_members.get_namespace_index = create_mocked_coroutine( return_value=42 ) - m_opc_client_members.connect = asynctest.asynctest.CoroutineMock() - m_opc_client_members.disconnect = asynctest.asynctest.CoroutineMock() - m_opc_client_members.send_hello = asynctest.asynctest.CoroutineMock() - - m_opc_client_members.update_protocol_attributes = ( - asynctest.asynctest.CoroutineMock() - ) + m_opc_client_members.connect = create_mocked_coroutine() + m_opc_client_members.disconnect = create_mocked_coroutine() + m_opc_client_members.send_hello = create_mocked_coroutine() + + m_objects_node = mock.Mock() + m_objects_node.get_child = create_mocked_coroutine() + m_objects_node.get_children_descriptions = create_mocked_coroutine([]) + m_opc_client_members.get_objects_node = mock.Mock(return_value=m_objects_node) + m_opc_client_members.update_protocol_attributes = create_mocked_coroutine() m_opc_client.return_value = m_opc_client_members test_client = OPCUAConnection( @@ -73,7 +84,6 @@ class TestOPCua(base.AsyncTestCase): 5, mock.Mock(), OPCUAConnectionStatus(), - self.loop, ) try: @@ -89,10 +99,10 @@ class TestOPCua(base.AsyncTestCase): finally: await test_client.stop() - @asynctest.patch.object(OPCUAConnection, "ping") - @asynctest.patch.object(OPCUAConnection, "_servername") - @asynctest.patch.object(opcua_client, "Client") - @asynctest.patch.object(opcua_client, "ProtocolAttribute") + @patch.object(OPCUAConnection, "ping") + @patch.object(OPCUAConnection, "_servername") + @patch.object(opcua_client, "Client") + @patch.object(opcua_client, "ProtocolAttribute") async def test_opcua_attr_setup( self, m_protocol_attr, m_opc_client, m_servername, m_ping ): @@ -104,22 +114,18 @@ class TestOPCua(base.AsyncTestCase): Test succeeds if there are no errors. """ - m_opc_client_members = asynctest.asynctest.CoroutineMock() - m_opc_client_members.get_namespace_index = asynctest.asynctest.CoroutineMock( + m_opc_client_members = create_mocked_coroutine() + m_opc_client_members.get_namespace_index = create_mocked_coroutine( return_value=2 ) - m_opc_client_members.connect = asynctest.asynctest.CoroutineMock() - m_opc_client_members.disconnect = asynctest.asynctest.CoroutineMock() - m_opc_client_members.send_hello = asynctest.asynctest.CoroutineMock() - m_objects_node = asynctest.Mock() - m_objects_node.get_child = asynctest.asynctest.CoroutineMock() - m_objects_node.get_children_descriptions = asynctest.asynctest.CoroutineMock() - m_opc_client_members.get_objects_node = asynctest.Mock( - return_value=m_objects_node - ) - m_opc_client_members.update_protocol_attributes = ( - asynctest.asynctest.CoroutineMock() - ) + m_opc_client_members.connect = create_mocked_coroutine() + m_opc_client_members.disconnect = create_mocked_coroutine() + m_opc_client_members.send_hello = create_mocked_coroutine() + m_objects_node = mock.Mock() + m_objects_node.get_child = create_mocked_coroutine() + m_objects_node.get_children_descriptions = create_mocked_coroutine([]) + m_opc_client_members.get_objects_node = mock.Mock(return_value=m_objects_node) + m_opc_client_members.update_protocol_attributes = create_mocked_coroutine() m_opc_client.return_value = m_opc_client_members @@ -153,7 +159,6 @@ class TestOPCua(base.AsyncTestCase): 5, mock.Mock(), OPCUAConnectionStatus(), - self.loop, ) try: @@ -240,7 +245,7 @@ class TestOPCua(base.AsyncTestCase): for i in ATTR_TEST_TYPES: self._get_test_value(j, i.numpy_type) - m_node = asynctest.asynctest.CoroutineMock() + m_node = mock.Mock() if len(j) == 1: test = opcua_client.ProtocolAttribute( @@ -274,7 +279,7 @@ class TestOPCua(base.AsyncTestCase): # test 0-2 dimensions of strings for dims in range(0, 2): - m_node = asynctest.asynctest.CoroutineMock() + m_node = mock.Mock() m_node.get_value.return_value = get_unicode_value(dims) # create the ProtocolAttribute to test @@ -372,7 +377,7 @@ class TestOPCua(base.AsyncTestCase): ), ) - m_node = asynctest.asynctest.CoroutineMock() + m_node = mock.Mock() m_node.set_data_value.return_value = asyncio.Future() m_node.set_data_value.return_value.set_result(None) diff --git a/tangostationcontrol/tox.ini b/tangostationcontrol/tox.ini index 3e4f13eb407b5df5a4724ea4c7fa27cc83ace5db..499efc4f571bfa6e6626dda90a79c1724afe4d8a 100644 --- a/tangostationcontrol/tox.ini +++ b/tangostationcontrol/tox.ini @@ -2,7 +2,7 @@ min_version = 4.3.3 requires = tox-ignore-env-name-mismatch ~= 0.2.0 -envlist = black,pep8,pylint,py310,docs +envlist = black,pep8,pylint,py3{10,11},docs [testenv] usedevelop = True @@ -10,8 +10,6 @@ package = wheel wheel_build_env = .pkg ; Python and tox variables are used to access modules and binaries instead of ; directly. This makes the setup robust for using sitepackages=True. -install_command = {envbindir}/pip3 install {opts} {packages} -passenv = HOME setenv = PYTHONWARNINGS=default::DeprecationWarning ; Share the same envdir with as many jobs as possible due to extensive time it @@ -24,17 +22,12 @@ deps = allowlist_externals = {work_dir}/.tox/bin/python commands_pre = - {work_dir}/.tox/bin/python -m tox --version {envpython} --version + {work_dir}/.tox/bin/python -m tox --version commands = {envpython} -m pytest --version {envpython} -m pytest -v --log-level=DEBUG --forked test/{posargs} -; We can't detect the current Python version for an environment dynamically -; so each Python version specific job needs its own envdir. -[testenv:py310] -envdir = {toxworkdir}/testenvpy310 - [testenv:integration] allowlist_externals = {work_dir}/.tox/bin/python