diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 6231e02ee4f971f8a34e728d797694e628f1208c..269f7a687c9d5bac7075cc1fcc9bb37fbee23650 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -321,7 +321,7 @@ service_test_docker: extends: .test_docker script: # Do not remove 'bash' or statement will be ignored by primitive docker shell - - bash -e $CI_PROJECT_DIR/sbin/run_service_test.sh + - bash -e $CI_PROJECT_DIR/sbin/run_integration_test.sh --no-build --skip-tests --module="services" --station=cs multi_project_integration_test: stage: integration-tests diff --git a/README.md b/README.md index 9fe839d03d82e24424fd0d64f27da5335a51b39d..d6189af1a9b672d9beb366d275d224d0ea8b9b43 100644 --- a/README.md +++ b/README.md @@ -150,6 +150,7 @@ Next change the version in the following places: through [https://git.astron.nl/lofar2.0/tango/-/tags](Deploy Tags) # Release Notes +* 0.47.0 Migrate from lofar-station-client to lofar-lotus package. Update various package dependencies. * 0.46.1 Include clock_RW in metadata JSON * 0.46.0 Expose latest BST/SST/XST from ZMQ over gRPC * 0.45.12 Improve syslog parsing for PyPCC logs diff --git a/docker/jupyter-lab/Dockerfile b/docker/jupyter-lab/Dockerfile index af215b0d201a31463b08b07edf961d22c9cd8e7f..6f8926c2f5746ec6e653db3d6edb3188eaaf98a0 100644 --- a/docker/jupyter-lab/Dockerfile +++ b/docker/jupyter-lab/Dockerfile @@ -17,7 +17,7 @@ RUN mamba install --yes 'jupyterlab-git>=0.50.0' && \ RUN jupyter server extension enable --py jupyterlab_git COPY requirements.txt ./ -RUN pip install --break-system-packages -r requirements.txt --extra-index-url=https://git.astron.nl/api/v4/projects/395/packages/pypi/simple +RUN pip install --break-system-packages -r requirements.txt --extra-index-url=https://git.astron.nl/api/v4/groups/36/-/packages/pypi/simple RUN rm requirements.txt USER root diff --git a/docker/jupyter-lab/ipython-profiles/stationcontrol-jupyter/startup/01-stationcontrol.py b/docker/jupyter-lab/ipython-profiles/stationcontrol-jupyter/startup/01-stationcontrol.py index a9c046560add3bae6d2223810b72a6e7ecf97155..3d143d2ac03c1552f3a2230d6d5ee86d71ed0693 100644 --- a/docker/jupyter-lab/ipython-profiles/stationcontrol-jupyter/startup/01-stationcontrol.py +++ b/docker/jupyter-lab/ipython-profiles/stationcontrol-jupyter/startup/01-stationcontrol.py @@ -2,7 +2,8 @@ # SPDX-License-Identifier: Apache-2.0 # noinspection PyUnresolvedReferences -import lofar_station_client +import lofar_lotus as lofar_station_client +import lofar_lotus # noinspection PyUnresolvedReferences import tangostationcontrol diff --git a/docker/jupyter-lab/requirements.txt b/docker/jupyter-lab/requirements.txt index 222dc787a24e754285580a29ac469fb27c758f3c..e052016d4347c1e7115d61121a461919da6a6bd3 100644 --- a/docker/jupyter-lab/requirements.txt +++ b/docker/jupyter-lab/requirements.txt @@ -11,7 +11,7 @@ jupyter_server_nbmodel[lab,rtc] # BSD-3 # NB: tangostationcontrol will also install lofar-station-client. The latter # is omitted here to avoid pip getting confused. tangostationcontrol >= 0.39 ---extra-index-url https://git.astron.nl/api/v4/projects/71/packages/pypi/simple +--extra-index-url https://git.astron.nl/api/v4/groups/36/-/packages/pypi/simple PyTango # low-level access to station components diff --git a/docker/lofar-device-base/Dockerfile b/docker/lofar-device-base/Dockerfile index 3abd30ee66df2ff501ded9cffc89519d5ac4dea2..21e50e6695ea4e60b4c8e53d9630283d98a2002f 100644 --- a/docker/lofar-device-base/Dockerfile +++ b/docker/lofar-device-base/Dockerfile @@ -65,12 +65,12 @@ COPY tmp/debug-requirements.txt /tangostationcontrol-debug-requirements.txt RUN echo "DEBUG_BUILD: ${DEBUG_BUILD}" RUN if [ $DEBUG_BUILD ]; then \ echo "Installing debug requirements"; \ - sudo pip3 install -r /tangostationcontrol-debug-requirements.txt --extra-index-url=https://git.astron.nl/api/v4/projects/395/packages/pypi/simple; \ + sudo pip3 install -r /tangostationcontrol-debug-requirements.txt --extra-index-url=https://git.astron.nl/api/v4/groups/36/-/packages/pypi/simple; \ fi COPY tmp/*.whl / RUN echo "Installing prebuild Station Control wheel"; \ - sudo pip3 install /*.whl --extra-index-url=https://git.astron.nl/api/v4/projects/395/packages/pypi/simple; + sudo pip3 install /*.whl --extra-index-url=https://git.astron.nl/api/v4/groups/36/-/packages/pypi/simple; # install and use ephimerides and geodetic ("measures") tables for casacore. # we install a _stub_ since the tables need to be deployed explicitly from within the software. diff --git a/infra/dev/services/services.hcl b/infra/dev/services/services.hcl index ce72e23e5dd9ce345cda1d638dac34108f7dccf2..77bb8a1e826a374d4f20e687691963ad4a095c6a 100644 --- a/infra/dev/services/services.hcl +++ b/infra/dev/services/services.hcl @@ -9,17 +9,17 @@ resource "nomad_job" "monitoring" { } } -resource "nomad_job" "logging" { - cluster = variable.nomad_cluster - - paths = ["../jobs/station/logging.nomad"] - depends_on = ["resource.nomad_job.monitoring"] - - health_check { - timeout = "300s" - jobs = ["log-scraping"] - } -} +# resource "nomad_job" "logging" { +# cluster = variable.nomad_cluster +# +# paths = ["../jobs/station/logging.nomad"] +# depends_on = ["resource.nomad_job.monitoring"] +# +# health_check { +# timeout = "300s" +# jobs = ["log-scraping"] +# } +# } resource "ingress" "grafana" { port = 3000 diff --git a/infra/dev/tango/tango.hcl b/infra/dev/tango/tango.hcl index 976ee8090325aaa42fb6ad94ba70d32d3a0f7369..f89b1b5871375d9d7ad9a1fbc96b1226871e2ce2 100644 --- a/infra/dev/tango/tango.hcl +++ b/infra/dev/tango/tango.hcl @@ -140,6 +140,19 @@ resource "nomad_job" "device-servers" { jobs = ["device-servers"] } } +resource "nomad_job" "rpc-server" { + depends_on = [ + "resource.nomad_job.device-servers" + ] + cluster = variable.nomad_cluster + + paths = ["../jobs/station/rpc-server.nomad"] + + health_check { + timeout = "3000s" + jobs = ["rpc-server"] + } +} resource "ingress" "minio_s3" { port = 9000 diff --git a/infra/jobs/station/rpc-server.levant.nomad b/infra/jobs/station/rpc-server.levant.nomad index 9c8ac0d01cecb8994895a96d7d8c7002cb19f528..4fd85a1968ba83de42d52f68f9cccc5f6933e752 100644 --- a/infra/jobs/station/rpc-server.levant.nomad +++ b/infra/jobs/station/rpc-server.levant.nomad @@ -45,8 +45,9 @@ job "rpc-server" { entrypoint = [""] command = "l2ss-rpc-server" args = [ - "--port", "${NOMAD_PORT_rpc}", - "--metrics-port", "${NOMAD_PORT_metrics}" + "--port", "${NOMAD_PORT_grpc}", + "--metrics-port", "${NOMAD_PORT_metrics}", + "--station", "[[.station]]" [[ range $name, $tr := $.sdptr.instances ]] , "--antenna-field", "[[ $name ]]" , "--statistics-zmq", "tcp://stingray-[[ $name ]]-bst-zmq.service.consul:6001" diff --git a/sbin/run_integration_test.sh b/sbin/run_integration_test.sh index 7e0f526e42605fd4b57ed978265d3f1becfad184..72077cfb6aac66c661c4148090a470e0fc2f9eda 100755 --- a/sbin/run_integration_test.sh +++ b/sbin/run_integration_test.sh @@ -23,7 +23,7 @@ function usage { disables building of docker images" echo "" echo "./$(basename "$0") --skip-tests - Only setup environment, implies --preserve" + Only setup environment" echo "" echo "./$(basename "$0") --preserve Prevents tearing down the dev environment afterwards" @@ -67,9 +67,7 @@ while true; do ;; --skip-tests) echo "Only setup and configure environment don't run any tests" - echo "Implies --preserve" export no_tests=1 - export preserve=1 ;; --preserve) echo "Preserve test environment" diff --git a/sbin/run_service_test.sh b/sbin/run_service_test.sh deleted file mode 100755 index e2060eef654ea1e44004e3f35664edaa291038b4..0000000000000000000000000000000000000000 --- a/sbin/run_service_test.sh +++ /dev/null @@ -1,62 +0,0 @@ -#!/bin/bash -e -# -# Copyright (C) 2023 ASTRON (Netherlands Institute for Radio Astronomy) -# SPDX-License-Identifier: Apache-2.0 -# - -if [ -z "$LOFAR20_DIR" ]; then - # We assume we aren't in the PATH, so we can derive our path. - # We need our parent directory. - LOFAR20_DIR_RELATIVE=$(dirname "$0")/.. - - # As an absolute path - LOFAR20_DIR=$(readlink -f "${LOFAR20_DIR_RELATIVE}") -fi - -if [ -z "$TAG" ]; then - export TAG="latest" -fi - -docker network rm station || true - -# prepare a docker volume for nomad -tmp_volume="test_$(hexdump -n 16 -v -e '/1 "%02X"' /dev/urandom)" - -function cleanup { - cd "$LOFAR20_DIR" - if [ -n "${save_logs}" ]; then - mkdir -p log - for container in $(docker ps -a --format "{{.Names}}") - do - echo "Saving log for container $container" - docker logs "${container}" >& "log/${container}.log" - done - bash "${LOFAR20_DIR}"/sbin/dsconfig.sh --dump >& log/dump_ConfigDb.log - fi - - if [ -z "${preserve}" ]; then - HOME="$JUMPPAD_HOME" jumppad down - docker volume rm "$tmp_volume" || true - fi -} - -trap cleanup INT EXIT TERM ERR SIGTERM SIGINT - -cd "$LOFAR20_DIR" || exit 1 - -source "${LOFAR20_DIR}"/sbin/prepare_dev_env.sh --volume="$tmp_volume" - -if [ -z "$JUMPPAD_HOME" ]; then - JUMPPAD_HOME="$HOME" -fi - -rm -rf "$JUMPPAD_HOME/.jumppad/" - -jumppad_options=( - --var="host_volume=$tmp_volume" - --var="image_tag=$TAG" -) - -HOME="$JUMPPAD_HOME" jumppad up "${jumppad_options[@]}" infra/dev/services.hcl --no-browser - -echo "success" diff --git a/tangostationcontrol/VERSION b/tangostationcontrol/VERSION index 620104d8208446199c33c5cdafb5ae4be455ce81..421ab545d9adc503fddf2ea2ce447a9a8c5323af 100644 --- a/tangostationcontrol/VERSION +++ b/tangostationcontrol/VERSION @@ -1 +1 @@ -0.46.1 +0.47.0 diff --git a/tangostationcontrol/integration_test/common/base_device_classes/power_hierarchy_tests.py b/tangostationcontrol/integration_test/common/base_device_classes/power_hierarchy_tests.py index aded09f1fbb1e317f9e27c9edd9935437760d7dd..d10330e6b169807202d337ada85a607e8934bff0 100644 --- a/tangostationcontrol/integration_test/common/base_device_classes/power_hierarchy_tests.py +++ b/tangostationcontrol/integration_test/common/base_device_classes/power_hierarchy_tests.py @@ -10,7 +10,7 @@ from tango import DevState, DeviceProxy from integration_test import base from integration_test.device_proxy import TestDeviceProxy -from lofar_station_client.common import CaseInsensitiveString +from lofar_lotus.dict import CaseInsensitiveString from tangostationcontrol.common.constants import N_rcu, N_rcu_inp from tangostationcontrol.devices.base_device_classes.hierarchy_device import ( NotFoundException, diff --git a/tangostationcontrol/integration_test/common/device_digitalbeam_tests.py b/tangostationcontrol/integration_test/common/device_digitalbeam_tests.py index 4ec817c05803c7a090ae0d434f3358efb405e123..1df9562ae52f7d88d0d7f3670ab0424cc9559cf1 100644 --- a/tangostationcontrol/integration_test/common/device_digitalbeam_tests.py +++ b/tangostationcontrol/integration_test/common/device_digitalbeam_tests.py @@ -5,7 +5,7 @@ import logging import time import numpy -import timeout_decorator +import pytest from integration_test.device_proxy import TestDeviceProxy from integration_test.default.devices.base import TestDeviceBase @@ -223,7 +223,7 @@ class DigitalBeamDeviceTests(TestDeviceBase): f"{FPGA_bf_weights_pp_RW}", ) - @timeout_decorator.timeout(15) + @pytest.mark.timeout(15) def test_beam_tracking_90_percent_interval(self): """Verify that the beam tracking operates within 95% of interval""" diff --git a/tangostationcontrol/integration_test/common/device_observation_control_tests.py b/tangostationcontrol/integration_test/common/device_observation_control_tests.py index 1e7caa9dc18b5426928947fadcfdfa8517fbe75d..30ff14af6aa9a9c58aece120b92bf40b2989174d 100644 --- a/tangostationcontrol/integration_test/common/device_observation_control_tests.py +++ b/tangostationcontrol/integration_test/common/device_observation_control_tests.py @@ -7,12 +7,14 @@ import time from datetime import datetime from datetime import timedelta + import numpy +import pytest + from integration_test.default.devices.base import TestDeviceBase from tango import DevFailed, DevState from tangostationcontrol.common.constants import CS001_TILES -from timeout_decorator import timeout_decorator logger = logging.getLogger() @@ -271,7 +273,7 @@ class DeviceObservationControlTests(TestDeviceBase): self.on_device_assert(self.proxy) self.assertRaises(DevFailed, self.proxy.add_observation, json.dumps(parameters)) - @timeout_decorator.timeout(60) + @pytest.mark.timeout(60) def test_add_observation_callbacks(self): """Test adding an observation and checking start / stop callbacks work""" diff --git a/tangostationcontrol/integration_test/common/device_tilebeam_tests.py b/tangostationcontrol/integration_test/common/device_tilebeam_tests.py index bc71c941ab4d792d174f2f1556e82026a2619f55..2c3a23dd29156bce31b2e2cfbd81366ffbd9ff37 100644 --- a/tangostationcontrol/integration_test/common/device_tilebeam_tests.py +++ b/tangostationcontrol/integration_test/common/device_tilebeam_tests.py @@ -7,7 +7,7 @@ import json import time import numpy -import timeout_decorator +import pytest from integration_test.device_proxy import TestDeviceProxy from integration_test.default.devices.base import TestDeviceBase @@ -251,7 +251,7 @@ class TileBeamDeviceTests(TestDeviceBase): new_pointings[0:2], list(self.proxy.Pointing_direction_R[0:2]) ) - @timeout_decorator.timeout(120) + @pytest.mark.timeout(120) def test_beam_tracking_95_percent_interval(self): """Verify that the beam tracking operates within 95% of interval""" diff --git a/tangostationcontrol/integration_test/configuration/test_device_configuration.py b/tangostationcontrol/integration_test/configuration/test_device_configuration.py index 4ffa79404db469fff84be55870a115bd9d60fdb9..ede698fcd87e3a7897c501bf38246135d6f5114e 100644 --- a/tangostationcontrol/integration_test/configuration/test_device_configuration.py +++ b/tangostationcontrol/integration_test/configuration/test_device_configuration.py @@ -11,8 +11,8 @@ except ImportError: from importlib_resources import files # type: ignore from integration_test.default.devices.base import TestDeviceBase -from lofar_station_client.common import CaseInsensitiveDict -from lofar_station_client.common import CaseInsensitiveString +from lofar_lotus.dict import CaseInsensitiveDict +from lofar_lotus.dict import CaseInsensitiveString from tango import DevState diff --git a/tangostationcontrol/integration_test/default/devices/test_device_protection_control.py b/tangostationcontrol/integration_test/default/devices/test_device_protection_control.py index e539aeadc1ed5ff68625420e1d0ea1968f344121..599d21786bddfac110a5d7221031d581bbaef231 100644 --- a/tangostationcontrol/integration_test/default/devices/test_device_protection_control.py +++ b/tangostationcontrol/integration_test/default/devices/test_device_protection_control.py @@ -5,7 +5,7 @@ import logging import time from typing import List -import timeout_decorator +import pytest from tango import Database, DevState from tangostationcontrol.devices import UNB2, SDPFirmware, RECVL, RECVH, APSCT, APSPU @@ -84,7 +84,7 @@ class TestDeviceProtectionControl(TestDeviceBase): self.proxy.number_of_connected_devices_R, ) - @timeout_decorator.timeout(10) + @pytest.mark.timeout(10) def test_change_events_received(self): self.proxy.boot() diff --git a/tangostationcontrol/integration_test/default/devices/test_observation_client.py b/tangostationcontrol/integration_test/default/devices/test_observation_client.py index fb1290d53f757e3db90ed4feccaf182ceed663ca..e21c38cc21e9b55b8853bcfdc066c1807325b261 100644 --- a/tangostationcontrol/integration_test/default/devices/test_observation_client.py +++ b/tangostationcontrol/integration_test/default/devices/test_observation_client.py @@ -4,15 +4,17 @@ from json import loads from os import environ -from lofar_station_client.observation.station_observation import ( - StationObservation, -) from integration_test import base from integration_test.device_proxy import TestDeviceProxy from tangostationcontrol.test.dummy_observation_settings import ( get_observation_settings_hba_core_immediate, ) - +import grpc +from lofar_sid.interface.stationcontrol.observation_pb2 import ( + StartObservationRequest, + StopObservationRequest, +) +from lofar_sid.interface.stationcontrol.observation_pb2_grpc import ObservationStub from tango import DevState @@ -57,25 +59,27 @@ class TestObservation(base.IntegrationTestCase): """Test of the observation_wrapper class basic functionality""" # convert the JSON specification to a dict for this class - specification_dict = loads( - get_observation_settings_hba_core_immediate().to_json() - ) + specification = get_observation_settings_hba_core_immediate().to_json() + specification_dict = loads(specification) # create an observation class using the dict and as host just get it using a # util function - observation = StationObservation( - specification=specification_dict, host=environ["TANGO_HOST"] - ) - # Assert the observation is running after starting it - observation.start() - self.assertTrue(observation.is_running) + tango_host = environ["TANGO_HOST"] + obs = TestDeviceProxy(f"tango://{tango_host}/STAT/ObservationControl/1") + + obs_id = specification_dict["antenna_fields"][0]["observation_id"] - # Assert the proxy is on - station = observation.observation - proxy = station.observation_field_proxies[0] - self.assertTrue(proxy.state() == DevState.ON) + with grpc.insecure_channel("rpc.service.consul:50051") as channel: + stub = ObservationStub(channel) + stub.StartObservation(StartObservationRequest(configuration=specification)) + + # Assert the observation is running after starting it + self.assertTrue(obs.is_observation_running(obs_id)) # Assert the observation has stopped after aborting - observation.stop() - self.assertFalse(observation.is_running) + + with grpc.insecure_channel("rpc.service.consul:50051") as channel: + stub = ObservationStub(channel) + stub.StopObservation(StopObservationRequest(observation_id=obs_id)) + self.assertFalse(obs.is_observation_running(obs_id)) diff --git a/tangostationcontrol/pyproject.toml b/tangostationcontrol/pyproject.toml index 63f09a96268a6e5f9e8829c758d9e208a1b8bb97..a4cd4e9bce1b099e4ea70708d4c16f11bf141c56 100644 --- a/tangostationcontrol/pyproject.toml +++ b/tangostationcontrol/pyproject.toml @@ -1,3 +1,7 @@ [build-system] requires = ['setuptools>=62.6', 'wheel'] build-backend = 'setuptools.build_meta' +[tool.pytest.ini_options] +markers = [ + "timeout", +] diff --git a/tangostationcontrol/requirements.txt b/tangostationcontrol/requirements.txt index 9a398792a2ee6fd267337fe315c92e358d25a727..7b66147ed058c2a42f68c6daa4803d843b3d9ff7 100644 --- a/tangostationcontrol/requirements.txt +++ b/tangostationcontrol/requirements.txt @@ -2,17 +2,18 @@ # order of appearance. Changing the order has an impact on the overall # integration process, which may cause wedges in the gate later. -lofar-station-client[tango] >= 0.22.3 # Apache 2 +lofar-sid >= 1.0.11 # Apache 2 +lofar-lotus>=0.0.4 # Apache 2 PyTango>=10.0.0 # LGPL v3 numpy>=1.21.6 # BSD3 asyncua >= 0.9.90 # LGPLv3 psycopg2-binary >= 2.9.2 # LGPL -pyasn1 == 0.4.8 # BSD, pinned because https://github.com/pyasn1/pyasn1/issues/28 -pysnmplib >= 5.0.23 # BSD2 +pyasn1 >= 0.6.1 # BSD +pysnmp >= 7 # BSD2 +pysmi >= 1.5.11 # BSD2 h5py >= 3.1.0 # BSD jsonschema > 4.18 # MIT referencing > 0.30 # MIT -docker >= 5.0.3 # Apache 2 python-casacore >= 3.3.1 # LGPLv3 etrs-itrs@git+https://github.com/brentjens/etrs-itrs # Apache 2 lofarantpos >= 0.5.0 # Apache 2 diff --git a/tangostationcontrol/tangostationcontrol/clients/snmp/attribute_classes.py b/tangostationcontrol/tangostationcontrol/clients/snmp/attribute_classes.py index 7d2e60aded9aa7d26ae611e1f4d4df13af4b2524..ee73ed6c318d9788d4260a7c884086146141226d 100644 --- a/tangostationcontrol/tangostationcontrol/clients/snmp/attribute_classes.py +++ b/tangostationcontrol/tangostationcontrol/clients/snmp/attribute_classes.py @@ -1,6 +1,6 @@ import logging import numpy -from pysnmp import hlapi +import pysnmp.hlapi.v3arch.asyncio as hlapi logger = logging.getLogger() diff --git a/tangostationcontrol/tangostationcontrol/clients/snmp/snmp_client.py b/tangostationcontrol/tangostationcontrol/clients/snmp/snmp_client.py index da1805b113a05e5d8c59d480654307a86ce38d65..f779c3f1243f93c4574eb51e92e722e8db3f5879 100644 --- a/tangostationcontrol/tangostationcontrol/clients/snmp/snmp_client.py +++ b/tangostationcontrol/tangostationcontrol/clients/snmp/snmp_client.py @@ -1,10 +1,10 @@ # Copyright (C) 2022 ASTRON (Netherlands Institute for Radio Astronomy) # SPDX-License-Identifier: Apache-2.0 - +import asyncio import logging from os import path -from pysnmp import hlapi +import pysnmp.hlapi.v3arch.asyncio as hlapi from pysnmp.smi import builder, compiler from tangostationcontrol.clients.comms_client import CommClient @@ -28,7 +28,7 @@ class SNMPComm: self.port = port self.engine = hlapi.SnmpEngine() self.community = hlapi.CommunityData(community, mpModel=pysnmp_snmp_version) - self.transport = hlapi.UdpTransportTarget((host, port)) + self.transport = asyncio.run(hlapi.UdpTransportTarget.create((host, port))) # context data sets the version used. Default SNMPv2 self.ctx_data = hlapi.ContextData() @@ -152,28 +152,26 @@ class MIBLoader: f"file://{mib_dir}", ], ) - logger.debug(f"mib sources: {self.mibBuilder.getMibSources()}") + logger.debug(f"mib sources: {self.mibBuilder.get_mib_sources()}") def load_pymib(self, mib_name): - self.mibBuilder.loadModules(mib_name) + self.mibBuilder.load_modules(mib_name) -def test_SNMP_connection(community, host, port=161): +async def test_SNMP_connection(community, host, port=161): """ Attempts to read a single SNMP point with the given parameters sysUpTime is chosen because it is pretty much Ubiquitous point. """ - iterator = hlapi.getCmd( + errorIndication, errorStatus, errorIndex, _ = await hlapi.get_cmd( hlapi.SnmpEngine(), hlapi.CommunityData(community, mpModel=1), - hlapi.UdpTransportTarget((host, port), timeout=2, retries=1), + await hlapi.UdpTransportTarget.create((host, port), timeout=2, retries=1), hlapi.ContextData(), hlapi.ObjectType(hlapi.ObjectIdentity("SNMPv2-MIB", "sysUpTime", 0)), ) - errorIndication, errorStatus, errorIndex, _ = next(iterator) - if errorIndication or errorStatus or errorIndex: # if not (None, 0, 0) there has been some error logger.debug( diff --git a/tangostationcontrol/tangostationcontrol/common/antennas.py b/tangostationcontrol/tangostationcontrol/common/antennas.py index 7228944964ddd519b9aa738761d3073035b75e7a..b40cae96123bccdb778f8727aab00462aa38173f 100644 --- a/tangostationcontrol/tangostationcontrol/common/antennas.py +++ b/tangostationcontrol/tangostationcontrol/common/antennas.py @@ -4,7 +4,7 @@ import numpy from tango import Util -from lofar_station_client.common import CaseInsensitiveString +from lofar_lotus.dict import CaseInsensitiveString def antenna_set_to_mask( diff --git a/tangostationcontrol/tangostationcontrol/common/calibration.py b/tangostationcontrol/tangostationcontrol/common/calibration.py index b952b42f6ecc3ac66ce02b4da6d7724419dc9cf3..2fe724d4472e39eca8f8e738bc6e0c15ab082e28 100644 --- a/tangostationcontrol/tangostationcontrol/common/calibration.py +++ b/tangostationcontrol/tangostationcontrol/common/calibration.py @@ -7,7 +7,7 @@ from typing import Dict from urllib.parse import urlparse import numpy -from lofar_station_client.file_access import member, attribute, read_hdf5 +from lofar_lotus.file_access import member, attribute, read_hdf5 from minio import Minio from tango import DeviceProxy @@ -20,7 +20,7 @@ from tangostationcontrol.common.constants import ( ) from tangostationcontrol.common.sdp import complex_to_weights, are_subbands_decreasing from tangostationcontrol.common.type_checking import device_name_matches -from lofar_station_client.common import CaseInsensitiveString +from lofar_lotus.dict import CaseInsensitiveString logger = logging.getLogger() diff --git a/tangostationcontrol/tangostationcontrol/common/env_decorators.py b/tangostationcontrol/tangostationcontrol/common/env_decorators.py index a80fbc911a35ca5b7fb5057ffa045d5badaae0f5..d456fc3ccc1853bd2f9474e6f5f58e168820f44d 100644 --- a/tangostationcontrol/tangostationcontrol/common/env_decorators.py +++ b/tangostationcontrol/tangostationcontrol/common/env_decorators.py @@ -7,7 +7,7 @@ import logging import time from tango import DevFailed, DeviceProxy -from lofar_station_client.common import CaseInsensitiveString +from lofar_lotus.dict import CaseInsensitiveString logger = logging.getLogger() diff --git a/tangostationcontrol/tangostationcontrol/common/events/change_events.py b/tangostationcontrol/tangostationcontrol/common/events/change_events.py index 00eb0a8a6087f4753912bf2b71e41ece5ca861d1..eea33317c0b6353830a2a80c98081350457ca6b9 100644 --- a/tangostationcontrol/tangostationcontrol/common/events/change_events.py +++ b/tangostationcontrol/tangostationcontrol/common/events/change_events.py @@ -3,7 +3,7 @@ import numpy -from lofar_station_client.common import CaseInsensitiveString, CaseInsensitiveDict +from lofar_lotus.dict import CaseInsensitiveString, CaseInsensitiveDict from tango.server import Device diff --git a/tangostationcontrol/tangostationcontrol/common/events/subscriptions.py b/tangostationcontrol/tangostationcontrol/common/events/subscriptions.py index a8bd2ed22653b6bcaca49c42577ca01f2b99bf06..60cc6401b33fb9c610238224b70da18947a7f96f 100644 --- a/tangostationcontrol/tangostationcontrol/common/events/subscriptions.py +++ b/tangostationcontrol/tangostationcontrol/common/events/subscriptions.py @@ -15,7 +15,7 @@ from tangostationcontrol.common.lofar_logging import exception_to_str from tangostationcontrol.common.constants import ( DEFAULT_METRICS_POLLING_PERIOD_MS, ) -from lofar_station_client.common import CaseInsensitiveString +from lofar_lotus.dict import CaseInsensitiveString from tangostationcontrol.metrics import AttributeMetric logger = logging.getLogger() diff --git a/tangostationcontrol/tangostationcontrol/common/proxies/create_proxies.py b/tangostationcontrol/tangostationcontrol/common/proxies/create_proxies.py index 3a23f1734ef3a050442f6fecc3f464e590da26b9..ce7fb78d5828a6a542f02df4729e8e2dc563f1aa 100644 --- a/tangostationcontrol/tangostationcontrol/common/proxies/create_proxies.py +++ b/tangostationcontrol/tangostationcontrol/common/proxies/create_proxies.py @@ -6,7 +6,7 @@ import abc import tango -from lofar_station_client.common import CaseInsensitiveDict +from lofar_lotus.dict import CaseInsensitiveDict from tangostationcontrol.common.proxies.proxy import create_device_proxy from tangostationcontrol.common.types.device_config_types import ( diff --git a/tangostationcontrol/tangostationcontrol/common/types/device_config_types.py b/tangostationcontrol/tangostationcontrol/common/types/device_config_types.py index f12a42c22056a25e80d00aa5e44091cc0466dcc5..81bd86fb8fc98cf30cbf4fdad400750d6ae6cf0c 100644 --- a/tangostationcontrol/tangostationcontrol/common/types/device_config_types.py +++ b/tangostationcontrol/tangostationcontrol/common/types/device_config_types.py @@ -7,7 +7,7 @@ from typing import List, Union from tango import DeviceProxy -from lofar_station_client.common import CaseInsensitiveDict +from lofar_lotus.dict import CaseInsensitiveDict # Dictionary of device class keys with attribute name list device_config_type = CaseInsensitiveDict[str, List[str]] diff --git a/tangostationcontrol/tangostationcontrol/devices/base_device_classes/hierarchy_device.py b/tangostationcontrol/tangostationcontrol/devices/base_device_classes/hierarchy_device.py index 7e488828b6fe1f9ab4b65fd097ee6a1d61112296..786d9629492f7341bf9bf6561b9446374ffaf5e7 100644 --- a/tangostationcontrol/tangostationcontrol/devices/base_device_classes/hierarchy_device.py +++ b/tangostationcontrol/tangostationcontrol/devices/base_device_classes/hierarchy_device.py @@ -10,7 +10,7 @@ from typing import Dict, List, Optional, Callable, Union from tango import Database, DevState, DeviceProxy -from lofar_station_client.common import CaseInsensitiveDict, CaseInsensitiveString +from lofar_lotus.dict import CaseInsensitiveDict, CaseInsensitiveString from tangostationcontrol.common.type_checking import device_name_matches from tangostationcontrol.common.proxies.proxy import create_device_proxy diff --git a/tangostationcontrol/tangostationcontrol/devices/base_device_classes/lofar_device.py b/tangostationcontrol/tangostationcontrol/devices/base_device_classes/lofar_device.py index 67f4f72e418a31d31a480895f24e430a396231b2..84a4fd3a053d0be097d276d950ae6077ce3b7021 100644 --- a/tangostationcontrol/tangostationcontrol/devices/base_device_classes/lofar_device.py +++ b/tangostationcontrol/tangostationcontrol/devices/base_device_classes/lofar_device.py @@ -48,7 +48,7 @@ from tangostationcontrol.common.constants import ( DEFAULT_METRICS_POLLING_PERIOD_MS, DEFAULT_POLLING_PERIOD_MS, ) -from lofar_station_client.common import CaseInsensitiveDict +from lofar_lotus.dict import CaseInsensitiveDict from tangostationcontrol.common.events import EventSubscriptions, ChangeEvents from tangostationcontrol.common.json_encoder import JsonEncoder from tangostationcontrol.common.lofar_logging import ( diff --git a/tangostationcontrol/tangostationcontrol/devices/base_device_classes/snmp_device.py b/tangostationcontrol/tangostationcontrol/devices/base_device_classes/snmp_device.py index 37649c5350e2610d4e6aa10ada154a2e02a996c8..c5ef2988150b31383d26e18e6fbe848a7d440407 100644 --- a/tangostationcontrol/tangostationcontrol/devices/base_device_classes/snmp_device.py +++ b/tangostationcontrol/tangostationcontrol/devices/base_device_classes/snmp_device.py @@ -2,7 +2,7 @@ # SPDX-License-Identifier: Apache-2.0 """SNMP Device Server for LOFAR2.0""" - +import asyncio import logging import os @@ -10,7 +10,6 @@ try: from importlib.resources import files except ImportError: from importlib_resources import files # type: ignore -from pysmi import debug from tango.server import device_property, attribute from tangostationcontrol.clients.snmp.attribute_classes import SNMPAttribute @@ -66,18 +65,18 @@ class SNMPDevice(LOFARDevice): """ Test whether we can connect with the SNMP server """ - return test_SNMP_connection(self.SNMP_community, self.SNMP_host) + return asyncio.run(test_SNMP_connection(self.SNMP_community, self.SNMP_host)) def __init__(self, cl, name): # Super must be called after variable assignment due to executing init_device! super().__init__(cl, name) # Configure PySMI debug logging - debug.setLogger( - debug.Debug( - "searcher", "compiler", "borrower", "reader", loggerName="pysmi" - ) - ) + # debug.set_logger( + # debug.Debug( + # "searcher", "compiler", "borrower", "reader", loggerName="pysmi" + # ) + # ) def configure_for_initialise(self, simulator_class): if self.SNMP_use_simulators: diff --git a/tangostationcontrol/tangostationcontrol/devices/calibration.py b/tangostationcontrol/tangostationcontrol/devices/calibration.py index c78c328307a9be9d55f522063fd96c0e173de7d1..512ecd94f966029c397983dc636b72c2435e51f2 100644 --- a/tangostationcontrol/tangostationcontrol/devices/calibration.py +++ b/tangostationcontrol/tangostationcontrol/devices/calibration.py @@ -12,7 +12,7 @@ from tangostationcontrol.common.calibration import ( calibrate_RCU_attenuator_dB, calibrate_input_samples_delay, ) -from lofar_station_client.common import ( +from lofar_lotus.dict import ( CaseInsensitiveDict, CaseInsensitiveString, ) diff --git a/tangostationcontrol/tangostationcontrol/devices/metadata.py b/tangostationcontrol/tangostationcontrol/devices/metadata.py index 05d1aae7f3ac878accc4c0ad3cd61f1ae96d0494..d5a2601d4eb6545f2f20ed1ae7558a22bb21a3a2 100644 --- a/tangostationcontrol/tangostationcontrol/devices/metadata.py +++ b/tangostationcontrol/tangostationcontrol/devices/metadata.py @@ -13,8 +13,8 @@ from tango import DebugIt, DeviceProxy from tango.server import device_property, attribute, command # PyTango imports -from lofar_station_client.common import CaseInsensitiveDict -from lofar_station_client.zeromq.publisher import ZeroMQPublisher +from lofar_lotus.dict import CaseInsensitiveDict +from lofar_lotus.zeromq import ZeroMQPublisher from tangostationcontrol.asyncio import PeriodicTask from tangostationcontrol.common.device_decorators import only_in_states, log_exceptions @@ -203,7 +203,7 @@ class Metadata(LOFARDevice): if not self._publisher: self._publisher = ZeroMQPublisher( - ZeroMQPublisher.contstruct_bind_uri( + ZeroMQPublisher.construct_bind_uri( self.metadata_protocol, self.metadata_bind, self.metadata_port ), [self.metadata_topic], diff --git a/tangostationcontrol/tangostationcontrol/devices/protection_control.py b/tangostationcontrol/tangostationcontrol/devices/protection_control.py index 769c34b6269ae23758571805d7f66494fc46c848..929e4fc01ef5adc25ddf153e4e78380289ce8255 100644 --- a/tangostationcontrol/tangostationcontrol/devices/protection_control.py +++ b/tangostationcontrol/tangostationcontrol/devices/protection_control.py @@ -15,7 +15,7 @@ from tango.server import attribute, device_property from tango.server import command # Additional import -from lofar_station_client.common import CaseInsensitiveDict +from lofar_lotus.dict import CaseInsensitiveDict from tangostationcontrol.asyncio import PeriodicTask from tangostationcontrol.common.types.device_config_types import ( diff --git a/tangostationcontrol/tangostationcontrol/devices/sdp/statistics.py b/tangostationcontrol/tangostationcontrol/devices/sdp/statistics.py index bff5e860be1d67eb352d4b8d0be6cd701138c028..45deb68ec87cf425956b48b5a4aef59e1a24d430 100644 --- a/tangostationcontrol/tangostationcontrol/devices/sdp/statistics.py +++ b/tangostationcontrol/tangostationcontrol/devices/sdp/statistics.py @@ -16,7 +16,7 @@ from typing import Dict from prometheus_client import Counter, Gauge -from lofar_station_client.zeromq.subscriber import AsyncZeroMQSubscriber +from lofar_lotus.zeromq import AsyncZeroMQSubscriber # PyTango imports from tango.server import device_property, attribute diff --git a/tangostationcontrol/tangostationcontrol/metadata/metadata_organizer.py b/tangostationcontrol/tangostationcontrol/metadata/metadata_organizer.py index dfac39c6b50700ab006a46503a83f9c1b817997c..5384e322f2963160fa74797a9459bf0a455a3a7d 100644 --- a/tangostationcontrol/tangostationcontrol/metadata/metadata_organizer.py +++ b/tangostationcontrol/tangostationcontrol/metadata/metadata_organizer.py @@ -9,7 +9,7 @@ from typing import Any import numpy from tango import DeviceProxy -from lofar_station_client.common import CaseInsensitiveDict +from lofar_lotus.dict import CaseInsensitiveDict from tangostationcontrol.common.lofar_logging import exception_to_str from tangostationcontrol.common.proxies.create_proxies import ( create_proxies, diff --git a/tangostationcontrol/tangostationcontrol/protection/config_types.py b/tangostationcontrol/tangostationcontrol/protection/config_types.py index 62a4843d296e1ca38cdad500529dc32e99d384c1..d70bd68868d68e41a83ea096b8120cccd6d29cf3 100644 --- a/tangostationcontrol/tangostationcontrol/protection/config_types.py +++ b/tangostationcontrol/tangostationcontrol/protection/config_types.py @@ -5,7 +5,7 @@ import copy import logging import tango -from lofar_station_client.common import CaseInsensitiveDict +from lofar_lotus.dict import CaseInsensitiveDict from tango import DevFailed from tangostationcontrol.common.types.device_config_types import device_config_type diff --git a/tangostationcontrol/tangostationcontrol/protection/protection_manager.py b/tangostationcontrol/tangostationcontrol/protection/protection_manager.py index 3867a976d00996102be63c6470055c0ca6332649..629e2b122011159b986c73a3c9abfb5212b2901f 100644 --- a/tangostationcontrol/tangostationcontrol/protection/protection_manager.py +++ b/tangostationcontrol/tangostationcontrol/protection/protection_manager.py @@ -9,7 +9,7 @@ from concurrent.futures import ThreadPoolExecutor from typing import Any import tango -from lofar_station_client.common import CaseInsensitiveDict +from lofar_lotus.dict import CaseInsensitiveDict from tango import DevFailed from tangostationcontrol.common.atomic import Atomic diff --git a/tangostationcontrol/tangostationcontrol/rpc/messagehandler.py b/tangostationcontrol/tangostationcontrol/rpc/messagehandler.py index c5d738bb9f283d6ae0dfd51ac9bbb73dfb576672..08a9314d3a3244a1b11bda1a14d19d3ee49a8cf9 100644 --- a/tangostationcontrol/tangostationcontrol/rpc/messagehandler.py +++ b/tangostationcontrol/tangostationcontrol/rpc/messagehandler.py @@ -9,7 +9,7 @@ from typing import Callable, Dict from prometheus_client import Counter, Gauge import zmq -from lofar_station_client.zeromq.subscriber import ZeroMQSubscriber +from lofar_lotus.zeromq import ZeroMQSubscriber from tangostationcontrol.metrics import AttributeMetric import logging diff --git a/tangostationcontrol/tangostationcontrol/rpc/server.py b/tangostationcontrol/tangostationcontrol/rpc/server.py index 8d22deec7bb993b2712426074b40383f1c723515..4130b21e55f365b0369458c12c78dc3b7fb19d1b 100644 --- a/tangostationcontrol/tangostationcontrol/rpc/server.py +++ b/tangostationcontrol/tangostationcontrol/rpc/server.py @@ -78,11 +78,13 @@ def _create_parser(): parser.add_argument( "--port", default=50051, + type=int, help="HTTP port to listen on.", ) parser.add_argument( "--metrics-port", default=8001, + type=int, help="Prometheus metrics HTTP port.", ) parser.add_argument( diff --git a/tangostationcontrol/tangostationcontrol/toolkit/generate_caltable_from_lofar1.py b/tangostationcontrol/tangostationcontrol/toolkit/generate_caltable_from_lofar1.py index 3710e4b28f1a2afae0b4eba74dc13b8aafd77b91..fa58d936821bccd2778698fd0a4fce723487250c 100755 --- a/tangostationcontrol/tangostationcontrol/toolkit/generate_caltable_from_lofar1.py +++ b/tangostationcontrol/tangostationcontrol/toolkit/generate_caltable_from_lofar1.py @@ -6,7 +6,7 @@ from tangostationcontrol.toolkit.lofar1.caltable import LOFAR1CalTables import numpy -from lofar_station_client.file_access import create_hdf5 +from lofar_lotus.file_access import create_hdf5 from tangostationcontrol.common import calibration diff --git a/tangostationcontrol/test-requirements.txt b/tangostationcontrol/test-requirements.txt index bd14f1512a97338c4b0315e331fced966a12a6d2..a3026ac04573e70db5ed03c05389a03cd6259014 100644 --- a/tangostationcontrol/test-requirements.txt +++ b/tangostationcontrol/test-requirements.txt @@ -20,9 +20,9 @@ python-subunit<1.4.3,>=1.4.0 # Apache-2.0/BSD Pygments>=2.6.0 # BSD testscenarios>=0.5.0 # Apache-2.0/BSD testtools>=2.4.0 # MIT -timeout-decorator>=0.5.0 # MIT xenon>=0.8.0 # MIT prometheus_client # Apache-2.0 pytest>=7.3.0 # MIT pytest-forked>=1.6.0 # MIT pytest-cov >= 3.0.0 # MIT +pytest-timeout # MIT diff --git a/tangostationcontrol/test/clients/test_snmp_client.py b/tangostationcontrol/test/clients/test_snmp_client.py index 3812ffa46e539f6d81440654b124f7529ccf53fa..727c810a260e3b0f5452f56966ffa8314dc88b06 100644 --- a/tangostationcontrol/test/clients/test_snmp_client.py +++ b/tangostationcontrol/test/clients/test_snmp_client.py @@ -6,7 +6,7 @@ from unittest import mock from test import base import numpy -from pysnmp import hlapi +import pysnmp.hlapi.v3arch.asyncio as hlapi from pysnmp.smi import view, error from pysnmp.smi.rfc1902 import ObjectIdentity @@ -162,8 +162,8 @@ class TestSNMP(base.TestCase): with self.assertRaises(ValueError): client._process_annotation(annotation=i) - @mock.patch("pysnmp.hlapi.ObjectIdentity") - @mock.patch("pysnmp.hlapi.ObjectType") + @mock.patch("pysnmp.hlapi.v3arch.asyncio.ObjectIdentity") + @mock.patch("pysnmp.hlapi.v3arch.asyncio.ObjectType") @mock.patch("tangostationcontrol.clients.snmp.snmp_client.SNMPComm.getter") def test_snmp_obj_get(self, m_next, m_obj_T, m_obj_i): """ @@ -206,9 +206,9 @@ class TestSNMP(base.TestCase): f"During test {j} {i}; Expected: {checkval} of type {i}, got: {val} of type {type(val)}", ) - @mock.patch("pysnmp.hlapi.ObjectIdentity") - @mock.patch("pysnmp.hlapi.ObjectType") - @mock.patch("pysnmp.hlapi.setCmd") + @mock.patch("pysnmp.hlapi.v3arch.asyncio.ObjectIdentity") + @mock.patch("pysnmp.hlapi.v3arch.asyncio.ObjectType") + @mock.patch("pysnmp.hlapi.v3arch.asyncio.set_cmd") @mock.patch("tangostationcontrol.clients.snmp.snmp_client.SNMPComm.setter") def test_snmp_obj_set(self, m_next, m_nextCmd, m_obj_T, m_obj_ID): """ @@ -286,7 +286,7 @@ class TestSNMP(base.TestCase): [ ( None, - hlapi.Integer.withNamedValues(enable=1, disable=0)(1), + hlapi.Integer.with_named_values(enable=1, disable=0)(1), ) ] ] diff --git a/tangostationcontrol/test/common/events/test_register_subscriptions.py b/tangostationcontrol/test/common/events/test_register_subscriptions.py index 2421974c9d894c4de51b72edd5cf1e62c800032d..20aee763cb02d5de057018fb135e8a43b27bce93 100644 --- a/tangostationcontrol/test/common/events/test_register_subscriptions.py +++ b/tangostationcontrol/test/common/events/test_register_subscriptions.py @@ -6,7 +6,7 @@ from unittest import mock from unittest.mock import call import tango -from lofar_station_client.common import CaseInsensitiveDict +from lofar_lotus.dict import CaseInsensitiveDict from tango import DeviceProxy, DevFailed from tangostationcontrol.common.constants import DEFAULT_POLLING_PERIOD_METADATA_MS diff --git a/tangostationcontrol/test/common/proxy/test_create_proxies.py b/tangostationcontrol/test/common/proxy/test_create_proxies.py index cb532188f204ce02755ec238c64e3e55f28e22a7..a5c3222f25ea071b0d8c1a4c28686291360ee26d 100644 --- a/tangostationcontrol/test/common/proxy/test_create_proxies.py +++ b/tangostationcontrol/test/common/proxy/test_create_proxies.py @@ -5,7 +5,7 @@ import logging from unittest import mock import tango -from lofar_station_client.common import CaseInsensitiveDict +from lofar_lotus.dict import CaseInsensitiveDict from tangostationcontrol.common.types.device_config_types import ( device_config_type, diff --git a/tangostationcontrol/test/devices/base_device_classes/test_beam_device.py b/tangostationcontrol/test/devices/base_device_classes/test_beam_device.py index 07d83166810ca455fb4f8f09e67f3d8692e72c4e..0517460b5a25f0c46356bf179c8fc916e112a633 100644 --- a/tangostationcontrol/test/devices/base_device_classes/test_beam_device.py +++ b/tangostationcontrol/test/devices/base_device_classes/test_beam_device.py @@ -9,7 +9,7 @@ import logging import time import numpy -import timeout_decorator +import pytest from tango import DevFailed from tangostationcontrol.common.atomic import Atomic @@ -101,7 +101,7 @@ class TestBeamTracker(base.TestCase): ) time.sleep(step) - @timeout_decorator.timeout(5) + @pytest.mark.timeout(5) def test_beamtracker_start_stop(self): """Test repeatedly starting and stopping the beamtracking @@ -191,7 +191,7 @@ class TestBeamTracker(base.TestCase): self.beamtracker_base(interval, setup=setup, test=test) - @timeout_decorator.timeout(5) + @pytest.mark.timeout(5) def test_update_pointing_early(self): """Test that early updates sleep until the intended update time has passed""" @@ -216,7 +216,7 @@ class TestBeamTracker(base.TestCase): test=test, ) - @timeout_decorator.timeout(5) + @pytest.mark.timeout(5) def test_update_pointing_late(self): """Test that late updates do not cause any additional sleep""" @@ -241,7 +241,7 @@ class TestBeamTracker(base.TestCase): test=test, ) - @timeout_decorator.timeout(5) + @pytest.mark.timeout(5) def test_update_pointing_stale(self): """Test the :attr:`stale_pointing` functionality for beamtracking""" test_value = "update-pointing-stale" diff --git a/tangostationcontrol/test/devices/base_device_classes/test_opcua_device.py b/tangostationcontrol/test/devices/base_device_classes/test_opcua_device.py index 09d314780706aa39384f48417051b9520b4ea6fb..cb266b1b3f4a641963be0af737493636c4cb6845 100644 --- a/tangostationcontrol/test/devices/base_device_classes/test_opcua_device.py +++ b/tangostationcontrol/test/devices/base_device_classes/test_opcua_device.py @@ -5,10 +5,10 @@ import logging import numpy import time +import pytest from tango import DevFailed from tango.test_context import DeviceTestContext from attribute_wrapper.attribute_wrapper import AttributeWrapper -import timeout_decorator from tangostationcontrol.devices.base_device_classes import opcua_device @@ -34,11 +34,11 @@ class RunOPCUADevice(device_base.DeviceTestCase): self.test_device = opcua_device.OPCUADevice - @timeout_decorator.timeout(10) + # @pytest.mark.timeout(10) def test_connect(self): """Test if device connects to the OPC-UA server.""" - with RunOPCUAServer(12345, "http://lofar.eu") as opcua_server: + with RunOPCUAServer(12345, "http://lofar.eu"): with DeviceTestContext( self.TestDevice, properties=self.TestDevice.PROPERTIES, process=True ) as proxy: @@ -49,7 +49,7 @@ class RunOPCUADevice(device_base.DeviceTestCase): proxy.off() - @timeout_decorator.timeout(30) + @pytest.mark.timeout(30) def test_read_after_disconnect(self): """Test if reads fail after disconnecting from the OPC-UA server.""" @@ -66,21 +66,21 @@ class RunOPCUADevice(device_base.DeviceTestCase): with self.assertRaises(DevFailed): _ = proxy.float_R - @timeout_decorator.timeout(30) + @pytest.mark.timeout(30) def test_read_after_reconnect(self): """Test if reads succeeds after reconnecting to the OPC-UA server.""" with DeviceTestContext( self.TestDevice, properties=self.TestDevice.PROPERTIES, process=True ) as proxy: - with RunOPCUAServer(12345, "http://lofar.eu") as opcua_server: + with RunOPCUAServer(12345, "http://lofar.eu"): proxy.initialise() while proxy.connected_R: logger.debug("Sleeping to wait for disconnect") time.sleep(0.5) - with RunOPCUAServer(12345, "http://lofar.eu") as opcua_server: + with RunOPCUAServer(12345, "http://lofar.eu"): while not proxy.connected_R: logger.debug("Sleeping to wait for reconnect") time.sleep(0.5) diff --git a/tangostationcontrol/test/devices/test_station_manager_device.py b/tangostationcontrol/test/devices/test_station_manager_device.py index b831361f9c553e906506efdf20c1697bafa62e24..520e061573a2d07a4f8f049231ecc17507bad076 100644 --- a/tangostationcontrol/test/devices/test_station_manager_device.py +++ b/tangostationcontrol/test/devices/test_station_manager_device.py @@ -4,7 +4,7 @@ import asyncio import time -from timeout_decorator import timeout_decorator +import pytest from unittest import mock @@ -45,7 +45,7 @@ class TestStationManagerDevice(device_base.DeviceTestCase): ) self.off_to_hibernate = lambda: time.sleep(30) - @timeout_decorator.timeout(10) + @pytest.mark.timeout(10) def test_state_transition_timeout(self): timeout = 1 diff --git a/tangostationcontrol/test/metadata/test_metadata_organizer.py b/tangostationcontrol/test/metadata/test_metadata_organizer.py index a1d596ba1f96581b1b30d1d32976fd1ab5831223..7d737a2c4b926667db4e4f1d97cc555412334928 100644 --- a/tangostationcontrol/test/metadata/test_metadata_organizer.py +++ b/tangostationcontrol/test/metadata/test_metadata_organizer.py @@ -10,7 +10,7 @@ from unittest.mock import patch import numpy from tango import DevFailed -from lofar_station_client.common import CaseInsensitiveDict +from lofar_lotus.dict import CaseInsensitiveDict from tangostationcontrol.common.lofar_logging import exception_to_str from tangostationcontrol.common.proxies import create_proxies diff --git a/tangostationcontrol/test/opcua.py b/tangostationcontrol/test/opcua.py index 4172cbec89730f3efaa77531345070f405f74180..ec9cd20e9c6c99995337b7d67f352cbacc446426 100644 --- a/tangostationcontrol/test/opcua.py +++ b/tangostationcontrol/test/opcua.py @@ -1,5 +1,6 @@ import asyncio import asyncua +import asyncua.ua import time from tangostationcontrol.asyncio import EventLoopThread @@ -43,7 +44,7 @@ class RunOPCUAServer: self.future = None async def run_server(self): - async with await make_opcua_server(self.port, self.namespace) as opcua_server: + async with await make_opcua_server(self.port, self.namespace): self.running = True while not self.stopping: await asyncio.sleep(0.1) @@ -63,6 +64,10 @@ class RunOPCUAServer: def stop(self): self.stopping = True - _ = self.future.result() + try: + _ = self.future.result(2) + except TimeoutError: + print("The coroutine took too long, cancelling the task...") + self.future.cancel() self.event_loop_thread.stop() diff --git a/tangostationcontrol/test/protection/test_config_types.py b/tangostationcontrol/test/protection/test_config_types.py index 00889507551d6d823ac3983f82ac6eed14f3be9a..b2cb330774228ac400dd166f6d4292fa35760dca 100644 --- a/tangostationcontrol/test/protection/test_config_types.py +++ b/tangostationcontrol/test/protection/test_config_types.py @@ -4,7 +4,7 @@ import logging from unittest import mock -from lofar_station_client.common import CaseInsensitiveDict +from lofar_lotus.dict import CaseInsensitiveDict from tangostationcontrol.devices import ProtectionControl from tangostationcontrol.protection import config_types diff --git a/tangostationcontrol/test/protection/test_metrics.py b/tangostationcontrol/test/protection/test_metrics.py index 37a2e52208d00a06a898d971d1511a793e5d0507..b43389e1aef69c8f26e746c640a26a77be8604a8 100644 --- a/tangostationcontrol/test/protection/test_metrics.py +++ b/tangostationcontrol/test/protection/test_metrics.py @@ -4,7 +4,7 @@ import logging from unittest import mock -from lofar_station_client.common import CaseInsensitiveDict +from lofar_lotus.dict import CaseInsensitiveDict from tango import DeviceProxy, DevFailed from tangostationcontrol.protection.config_types import ( diff --git a/tangostationcontrol/test/protection/test_protection_manager.py b/tangostationcontrol/test/protection/test_protection_manager.py index 99622c7f6b187542ebc067b2a4f527b1dab3047f..eaeed73c8bfc99d97b216807474549e961871e17 100644 --- a/tangostationcontrol/test/protection/test_protection_manager.py +++ b/tangostationcontrol/test/protection/test_protection_manager.py @@ -6,9 +6,9 @@ from unittest import mock from unittest.mock import PropertyMock import tango -from lofar_station_client.common import CaseInsensitiveDict +from lofar_lotus.dict import CaseInsensitiveDict from tango import DevFailed -from timeout_decorator import timeout_decorator +import pytest from tangostationcontrol.common.constants import N_pn from tangostationcontrol.protection.threshold import NumberProtectionThreshold @@ -105,7 +105,7 @@ class TestProtectionManager(base.TestCase): t_manager.evaluate("sdpfirmware", "fpga_temp_r", [91.4] * N_pn) m_shutdown["mock"].assert_called_once() - @timeout_decorator.timeout(10) + @pytest.mark.timeout(10) def test_protective_shutdown_already_protected(self): """Test the iterative shutdown sequence""" @@ -123,7 +123,7 @@ class TestProtectionManager(base.TestCase): self.assertTrue(self.m_create_proxy["mock"].return_value.protection_lock_RW) - @timeout_decorator.timeout(10) + @pytest.mark.timeout(10) def test_protective_shutdown_transition_once(self): """Test having to transition once for protective shutdown""" m_transition_hibernate = mock.Mock() @@ -158,7 +158,7 @@ class TestProtectionManager(base.TestCase): m_transition_hibernate.assert_called_once() self.assertEqual(t_manager._state, ProtectionStateEnum.OFF) - @timeout_decorator.timeout(10) + @pytest.mark.timeout(10) def test_protective_shutdown_transition_await(self): """Test awaiting state transition completion""" m_transition_hibernate = mock.Mock() @@ -196,7 +196,7 @@ class TestProtectionManager(base.TestCase): m_time["mock"].assert_called_once() self.assertEqual(t_manager._state, ProtectionStateEnum.OFF) - @timeout_decorator.timeout(10) + @pytest.mark.timeout(10) def test_protective_shutdown_anticipate_transition(self): """Test protective shutdown anticipate ongoing transition""" diff --git a/tangostationcontrol/test/rpc/test_messagehandler.py b/tangostationcontrol/test/rpc/test_messagehandler.py index c4becbec480f7ee2082996aa8c0f90e31af4ddf0..21ff2229456ce8c092a62228b88a4478f4348f41 100644 --- a/tangostationcontrol/test/rpc/test_messagehandler.py +++ b/tangostationcontrol/test/rpc/test_messagehandler.py @@ -2,9 +2,9 @@ # SPDX-License-Identifier: Apache-2.0 import time +import pytest -from lofar_station_client.zeromq.publisher import ZeroMQPublisher -from timeout_decorator import timeout_decorator +from lofar_lotus.zeromq import ZeroMQPublisher from tangostationcontrol.rpc.messagehandler import MultiEndpointZMQMessageHandler @@ -15,7 +15,7 @@ class TestMultiEndpointZMQMessageHandler(base.TestCase): DEFAULT_PUBLISH_ADDRESS = "tcp://*:6001" DEFAULT_SUBSCRIBE_ADDRESS = "tcp://127.0.0.1:6001" - @timeout_decorator.timeout(2) + @pytest.mark.timeout(2) def test(self): t_msg = '{"foo": "bar"}' t_topic = "topic" diff --git a/tangostationcontrol/tox.ini b/tangostationcontrol/tox.ini index f1e8c83088557d0b671317420efd7ed41d916503..090286a2a5a32c2a804d3a619cd93ff2ee52274e 100644 --- a/tangostationcontrol/tox.ini +++ b/tangostationcontrol/tox.ini @@ -16,7 +16,7 @@ wheel_build_env = .pkg ; - lofar-station-client setenv = PYTHONWARNINGS=default::DeprecationWarning - PIP_EXTRA_INDEX_URL=https://git.astron.nl/api/v4/projects/395/packages/pypi/simple + PIP_EXTRA_INDEX_URL=https://git.astron.nl/api/v4/groups/36/-/packages/pypi/simple ; Share the same envdir with as many jobs as possible due to extensive time it ; takes to compile the pytango wheel, in addition to its large install size. ; should the environment change (such as the Python version) the environment @@ -47,7 +47,7 @@ passenv = setenv = VIRTUAL_ENV={envdir} TESTS_DIR=./integration_test/{env:TEST_MODULE:default} - PIP_EXTRA_INDEX_URL=https://git.astron.nl/api/v4/projects/395/packages/pypi/simple + PIP_EXTRA_INDEX_URL=https://git.astron.nl/api/v4/groups/36/-/packages/pypi/simple commands = echo "Integration test directory configured for{env:TESTS_DIR} ({env:TEST_MODULE:default})" {envpython} -m pytest --version @@ -62,7 +62,7 @@ runner = ignore_env_name_mismatch envdir = {toxworkdir}/coverage setenv = VIRTUAL_ENV={envdir} - PIP_EXTRA_INDEX_URL=https://git.astron.nl/api/v4/projects/395/packages/pypi/simple + PIP_EXTRA_INDEX_URL=https://git.astron.nl/api/v4/groups/36/-/packages/pypi/simple commands = {envpython} -m pytest --version {envpython} -m coverage --version