Commit fe718958 authored by Elisabetta Giani's avatar Elisabetta Giani
Browse files

csp-skb-49:

Updated python-buildenv/runtime docker images to 9.3.3.1
Try to fix the problems for skb-26 (CspMaster On/StandyBy commands).
Try to fix bug skb-49.
Updated tests.
parent 21c4a477
Loading
Loading
Loading
Loading
Loading
+20 −11
Original line number Original line Diff line number Diff line
@@ -280,6 +280,8 @@ class CspMaster(SKAMaster):
        if all(value == CmdExecState.IDLE for value in self._cmd_execution_state.values()) or (not any(self._cmd_execution_state)):
        if all(value == CmdExecState.IDLE for value in self._cmd_execution_state.values()) or (not any(self._cmd_execution_state)):
            self.logger.debug("_cmd_execution_state:{}".format(self._cmd_execution_state.items()))
            self.logger.debug("_cmd_execution_state:{}".format(self._cmd_execution_state.items()))
            self.set_state(self._se_state[self.CspCbf])
            self.set_state(self._se_state[self.CspCbf])
            self.set_change_event('State', self._se_state[self.CspCbf])
            self.set_archive_event('State', self._se_state[self.CspCbf])
        if self._admin_mode in [AdminMode.OFFLINE, AdminMode.NOT_FITTED, AdminMode.RESERVED]:
        if self._admin_mode in [AdminMode.OFFLINE, AdminMode.NOT_FITTED, AdminMode.RESERVED]:
            self.set_state(tango.DevState.DISABLE)
            self.set_state(tango.DevState.DISABLE)
        self.logger.debug("CspState: {}".format(self.get_state()))
        self.logger.debug("CspState: {}".format(self.get_state()))
@@ -439,7 +441,7 @@ class CspMaster(SKAMaster):
        # tango_cmd_name: is the TANGO command name with the capital letter
        # tango_cmd_name: is the TANGO command name with the capital letter
        # In the dictionary keys, is generally used the command name in lower letters
        # In the dictionary keys, is generally used the command name in lower letters
        cmd_name = tango_cmd_name.lower()
        cmd_name = tango_cmd_name.lower()
        self.logger.debug("cmd_name: {} dev_state: {}".format(cmd_name,
        self.logger.info("cmd_name: {} dev_state: {}".format(cmd_name,
                                                  dev_successful_state))
                                                  dev_successful_state))
        num_of_failed_device = 0
        num_of_failed_device = 0
        self._num_dev_completed_task[cmd_name] = 0
        self._num_dev_completed_task[cmd_name] = 0
@@ -477,6 +479,8 @@ class CspMaster(SKAMaster):
                # IDLE and the thread exit. After it is received the callback message with the
                # IDLE and the thread exit. After it is received the callback message with the
                # error message generated by the CbfMaster but the 
                # error message generated by the CbfMaster but the 
                # self._cmd_execution_state results RUNNING and the device stucks 
                # self._cmd_execution_state results RUNNING and the device stucks 
                if device_proxy.state() == dev_successful_state:
                    continue
                device_proxy.command_inout_asynch(tango_cmd_name, self._cmd_ended_cb)
                device_proxy.command_inout_asynch(tango_cmd_name, self._cmd_ended_cb)
            except tango.DevFailed as df:
            except tango.DevFailed as df:
                # It should not happen! Verify
                # It should not happen! Verify
@@ -593,7 +597,7 @@ class CspMaster(SKAMaster):
        with self._cmd_exec_state_lock:
        with self._cmd_exec_state_lock:
            self._cmd_execution_state[cmd_name] = CmdExecState.IDLE
            self._cmd_execution_state[cmd_name] = CmdExecState.IDLE


    def _enable_subarrays(self, tango_cmd_name):
    def _switch_subarrays(self, tango_cmd_name):
        """
        """
        Helper method to execute the On[Off] command on the CSP subarrays.
        Helper method to execute the On[Off] command on the CSP subarrays.


@@ -605,10 +609,6 @@ class CspMaster(SKAMaster):
        if subarray_action not in ['on', 'off']:
        if subarray_action not in ['on', 'off']:
            self.logger.warning(f"Invalid command {subarray_action} to issue on CSP subarray")
            self.logger.warning(f"Invalid command {subarray_action} to issue on CSP subarray")
            return
            return
        master_state = self.get_state()
        if (subarray_action, master_state) not in [('on', tango.DevState.ON), ('off', tango.DevState.STANDBY)]:
            self.logger.warning("CSPMaster is not in the proper state ({})".format(self.get_state()))
            return
        try:
        try:
            subarray_group = tango.Group("CSPSubarray")
            subarray_group = tango.Group("CSPSubarray")
            for subarray in self.CspSubarrays:
            for subarray in self.CspSubarrays:
@@ -635,6 +635,12 @@ class CspMaster(SKAMaster):
        except Exception:
        except Exception:
            self.logger.error("command {} failed on subarray".format(subarray_action))
            self.logger.error("command {} failed on subarray".format(subarray_action))
    
    
    def _enable_subarrays(self):
        return self._switch_subarrays('On')

    def _disable_subarrays(self):
        return self._switch_subarrays('Off')

    def _se_write_adminMode(self, value, device_fqdn):
    def _se_write_adminMode(self, value, device_fqdn):
        """
        """
        *Class method.*
        *Class method.*
@@ -1224,6 +1230,8 @@ class CspMaster(SKAMaster):
        # property '__value'
        # property '__value'
        #attribute_properties = csp_tango_db.get_device_attribute_property(self.get_name(),
        #attribute_properties = csp_tango_db.get_device_attribute_property(self.get_name(),
        #                                                                  {'adminMode': ['__value']})
        #                                                                  {'adminMode': ['__value']})
        self.set_change_event("state", True, True)
        self.set_archive_event("state", True, True)
        # set init values for the CSP Element and Sub-element SCM states
        # set init values for the CSP Element and Sub-element SCM states
        self.set_state(tango.DevState.INIT)
        self.set_state(tango.DevState.INIT)
        self._health_state = HealthState.OK
        self._health_state = HealthState.OK
@@ -1886,18 +1894,19 @@ class CspMaster(SKAMaster):
        try:
        try:
            # start the thread
            # start the thread
            # set the  CSP command execution running flag
            # set the  CSP command execution running flag
            self.logger.debug("self._cmd_execution_state: {}".format(self._cmd_execution_state.items()))
            self.logger.info("self._cmd_execution_state: {}".format(self._cmd_execution_state.items()))
            with self._cmd_exec_state_lock:
            with self._cmd_exec_state_lock:
                self._cmd_execution_state['on'] = CmdExecState.RUNNING
                self._cmd_execution_state['on'] = CmdExecState.RUNNING
            self._command_thread['on'].start()
            self._command_thread['on'].start()
            self.logger.debug("self._cmd_execution_state: {}".format(self._cmd_execution_state.items()))
            self.logger.debug("self._cmd_execution_state: {}".format(self._cmd_execution_state.items()))
            # To temporarily solve SKB-26 -> join the thread to synchronize the command
            # To temporarily solve SKB-26 -> join the thread to synchronize the command
            self._command_thread['on'].join()
            self._command_thread['on'].join()
            self._enable_subarrays()
            self._update_csp_state()
            self._update_csp_state()
            self.logger.info("CSP State:{}".format(self.get_state()))
            self.logger.info("CSP State:{}".format(self.get_state()))
            self._enable_subarrays('On')
        except Exception as e:
        except Exception:
            # reset the sub-element command exec state
            # reset the sub-element command exec state
            self.logger.error(f"Received error {e}")
            self._se_cmd_execution_state.clear()
            self._se_cmd_execution_state.clear()
            self._cmd_execution_state['on'] = CmdExecState.IDLE
            self._cmd_execution_state['on'] = CmdExecState.IDLE
            tango.Except.throw_exception("Command failed",
            tango.Except.throw_exception("Command failed",
@@ -2063,12 +2072,12 @@ class CspMaster(SKAMaster):
                self._cmd_execution_state['standby'] = CmdExecState.RUNNING
                self._cmd_execution_state['standby'] = CmdExecState.RUNNING
            # start the thread
            # start the thread
            self._command_thread['standby'].start()
            self._command_thread['standby'].start()
            self.logger.debug("self._cmd_execution_state: {}".format(self._cmd_execution_state.items()))
            self.logger.info("self._cmd_execution_state: {}".format(self._cmd_execution_state.items()))
            # To temprarily solve the SKB-26 -> join the thread to synchronize the command
            # To temprarily solve the SKB-26 -> join the thread to synchronize the command
            self._command_thread['standby'].join()
            self._command_thread['standby'].join()
            self._update_csp_state()
            self._update_csp_state()
            self.logger.info("CSP State:{}".format(self.get_state()))
            self.logger.info("CSP State:{}".format(self.get_state()))
            self._enable_subarrays('Off')
            self._disable_subarrays()
        except Exception:
        except Exception:
            # reset the sub-element command exec state
            # reset the sub-element command exec state
            self._se_cmd_execution_state.clear()
            self._se_cmd_execution_state.clear()
+19 −22
Original line number Original line Diff line number Diff line
@@ -332,7 +332,7 @@ class CspSubarray(SKASubarray):
            # Implemented as a nested default dictionary
            # Implemented as a nested default dictionary
            # keys: FQDN
            # keys: FQDN
            # values: default dictionary (keys: command name, values: the duration (in sec))
            # values: default dictionary (keys: command name, values: the duration (in sec))
            device._sc_subarray_cmd_duration_expected = defaultdict(lambda: defaultdict(lambda: 5))
            device._sc_subarray_cmd_duration_expected = defaultdict(lambda: defaultdict(lambda: 10))
            
            
            # _sc_subarray_scan_configuration: report the scan configuration
            # _sc_subarray_scan_configuration: report the scan configuration
            # for each sub-array sub-component (CBF, PSS subarray, PSTBeams) 
            # for each sub-array sub-component (CBF, PSS subarray, PSTBeams) 
@@ -435,7 +435,8 @@ class CspSubarray(SKASubarray):
                    device.connect_to_subarray_subcomponent(device.PssSubarray)
                    device.connect_to_subarray_subcomponent(device.PssSubarray)
                    # put the device to OFF/EMPTY: no transition is allowed from INIT state
                    # put the device to OFF/EMPTY: no transition is allowed from INIT state
                    self.succeeded()
                    self.succeeded()
                    if device._sc_subarray_state[device.CbfSubarray] is not DevState.ON:
                    subarray_state = device._sc_subarray_state[device.CbfSubarray]
                    if subarray_state is not DevState.ON:
                        return
                        return
                    # put the device to ON/EMPTY
                    # put the device to ON/EMPTY
                    on_handler.succeeded()
                    on_handler.succeeded()
@@ -457,7 +458,7 @@ class CspSubarray(SKASubarray):
            """
            """
            Helper method to monitor the CSP Subarray observing state at re-initialization if
            Helper method to monitor the CSP Subarray observing state at re-initialization if
            the observing state is in a transitional state.
            the observing state is in a transitional state.
            NOTE: Currently onlt the SCANNING obsState is handled.
            NOTE: Currently only the SCANNING obsState is handled.


            :param csp_obs_state: the CSP.LMC Subarray observing state.
            :param csp_obs_state: the CSP.LMC Subarray observing state.
            :type csp_obs_state: string
            :type csp_obs_state: string
@@ -546,6 +547,7 @@ class CspSubarray(SKASubarray):
        def do(self):
        def do(self):
            super().do()
            super().do()
            device = self.target
            device = self.target
            device_in_error = 0
            self.logger.info("Call On Command")
            self.logger.info("Call On Command")
            for fqdn in device._sc_subarray_fqdn:
            for fqdn in device._sc_subarray_fqdn:
                try:
                try:
@@ -560,10 +562,12 @@ class CspSubarray(SKASubarray):
                            device._health_state = HealthState.DEGRADED
                            device._health_state = HealthState.DEGRADED
                            continue
                            continue
                        else:
                        else:
                            return (ResultCode.FAILED, message)
                            device_in_error += 1
                except tango.DevFailed as tango_err:
                except tango.DevFailed as tango_err:
                    message = str(tango_err.args[0].desc)
                    message = str(tango_err.args[0].desc)
                    return (ResultCode.FAILED, message)
                    device_in_error += 1
            if device_in_error:
                return (ResultCode.FAILED, "Command On failed")
            message = "On command completed OK"
            message = "On command completed OK"
            self.logger.info(message)
            self.logger.info(message)
            return (ResultCode.OK, message)
            return (ResultCode.OK, message)
@@ -671,7 +675,7 @@ class CspSubarray(SKASubarray):
           
           
            # the dictionary with the scan configuration
            # the dictionary with the scan configuration


            self.logger.info("ConfigureCommand at {}".format(time.time()))
            self.logger.info(f"ConfigureCommand at {time.time()}")
            target_device = self.target
            target_device = self.target
            try:
            try:
                # if the stored configuration attribute is not empty, check
                # if the stored configuration attribute is not empty, check
@@ -703,6 +707,8 @@ class CspSubarray(SKASubarray):
            for device in target_device._sc_subarray_assigned_fqdn:
            for device in target_device._sc_subarray_assigned_fqdn:
                # reset the command progress counter for each
                # reset the command progress counter for each
                # sub-array component
                # sub-array component
                self.logger.info(f"ConfigureCommand exec_state {target_device._sc_subarray_cmd_exec_state[device]['configurescan']}")
                target_device._sc_subarray_cmd_exec_state[device]['configurescan'] = CmdExecState.IDLE
                if target_device._sc_subarray_obs_state[device] == ObsState.READY:
                if target_device._sc_subarray_obs_state[device] == ObsState.READY:
                    target_device._reconfiguring = True
                    target_device._reconfiguring = True
                target_device._sc_subarray_cmd_progress[device]['configurescan'] = 0
                target_device._sc_subarray_cmd_progress[device]['configurescan'] = 0
@@ -735,20 +741,14 @@ class CspSubarray(SKASubarray):
                # NOTE: CBF/PSS sub-array checks for the validity of its
                # NOTE: CBF/PSS sub-array checks for the validity of its
                # configuration. Failure in configuration throws an exception that is
                # configuration. Failure in configuration throws an exception that is
                # caught via the _cmd_ended_cb callback
                # caught via the _cmd_ended_cb callback
                """
                try:
                    # read the timeout configured for the operation on the device
                    self._sc_subarray_cmd_duration_expected[device]['configurescan'] = proxy.configureDelayExpected
                except AttributeError as attr_err:
                    self.logger.info("No attribute {} on device {}".format(str(attr_err), device))
                """

                try:
                try:
                    # read the timeout configured for the operation on the device
                    # read the timeout configured for the operation on the device
                    target_device._sc_subarray_cmd_duration_expected[device]['configurescan'] = target_device._get_expected_delay(proxy, "configureDelayExpected")
                    target_device._sc_subarray_cmd_duration_expected[device]['configurescan'] = target_device._get_expected_delay(proxy, "configureDelayExpected")
                    #self.logger.info("config delay: {}".format(target_device._sc_subarray_cmd_duration_expected[device]['configurescan']))
                except tango.DevFailed as tango_err:
                except tango.DevFailed as tango_err:
                    self.logger.info("No attribute {} on device {}".format(tango_err.args[0].desc, device))
                    self.logger.info("No attribute {} on device {}. Use default value {}".format(tango_err.args[0].desc, device,
                                                      target_device._sc_subarray_cmd_duration_expected[device]['configurescan'))
                if target_device._sc_subarray_cmd_duration_expected[device]['configurescan'] >  target_device._config_delay_expected:
                    target_device._config_delay_expected = target_device._sc_subarray_cmd_duration_expected[device]['configurescan'] 
                try:
                try:
                    target_device._timeout_expired = False
                    target_device._timeout_expired = False
                    target_device._failure_raised = False
                    target_device._failure_raised = False
@@ -774,11 +774,6 @@ class CspSubarray(SKASubarray):
                self.logger.debug("configure starting time: {}".format(target_device._sc_subarray_cmd_starting_time[device]))
                self.logger.debug("configure starting time: {}".format(target_device._sc_subarray_cmd_starting_time[device]))
            # end for loop on devices
            # end for loop on devices


            # TODO: evaluate the global timeout as the max of the single sub-element
            # timeouts
            # configure the timeout for the operation
            if target_device._config_delay_expected > 0:
                target_device._cmd_duration_expected['configurescan'] = target_device._config_delay_expected
            self.logger.debug("_config_delay_expected :{}".format(target_device._config_delay_expected))
            self.logger.debug("_config_delay_expected :{}".format(target_device._config_delay_expected))
            # invoke the constructor for the command thread
            # invoke the constructor for the command thread
            thread_args = [target_device._sc_subarray_assigned_fqdn, argin]
            thread_args = [target_device._sc_subarray_assigned_fqdn, argin]
@@ -1400,6 +1395,8 @@ class CspSubarray(SKASubarray):
                self.logger.info("Creating group for Reset {}".format(device_list))
                self.logger.info("Creating group for Reset {}".format(device_list))
                sc_group = tango.Group("ResetGroup")
                sc_group = tango.Group("ResetGroup")
                for device in device_list:
                for device in device_list:
                    if target_device._sc_subarray_state[device] != tango.DevState.FAULT:
                        continue
                    sc_group.add(device)
                    sc_group.add(device)
            except Exception:
            except Exception:
                self.logger.error("TANGO Group command failed")
                self.logger.error("TANGO Group command failed")
@@ -1717,7 +1714,7 @@ class CspSubarray(SKASubarray):
    def _get_expected_delay(self, proxy,attr_name):
    def _get_expected_delay(self, proxy,attr_name):
        try:
        try:
            attr_value = proxy.read_attribute(attr_name)
            attr_value = proxy.read_attribute(attr_name)
            return attr_value.value()
            return attr_value.value
        except AttributeError as attr_err:
        except AttributeError as attr_err:
            self.logger.info("No attribute {} on device {}".format(str(attr_err), proxy))
            self.logger.info("No attribute {} on device {}".format(str(attr_err), proxy))
            tango.Except.throw_exception("Attribute Error", str(attr_err), "", tango.ErrSeverity.ERR)
            tango.Except.throw_exception("Attribute Error", str(attr_err), "", tango.ErrSeverity.ERR)
+2 −2
Original line number Original line Diff line number Diff line
FROM nexus.engageska-portugal.pt/ska-docker/ska-python-buildenv:9.3.2 AS buildenv
FROM nexus.engageska-portugal.pt/ska-docker/ska-python-buildenv:9.3.3.1 AS buildenv
FROM nexus.engageska-portugal.pt/ska-docker/ska-python-runtime:9.3.2 AS runtime
FROM nexus.engageska-portugal.pt/ska-docker/ska-python-runtime:9.3.3.1 AS runtime


# create ipython profile to so that itango doesn't fail if ipython hasn't run yet
# create ipython profile to so that itango doesn't fail if ipython hasn't run yet
RUN ipython profile create
RUN ipython profile create
+0 −4
Original line number Original line Diff line number Diff line
@@ -262,10 +262,6 @@
                            "polled_attr": [
                            "polled_attr": [
				"healthstate",
				"healthstate",
				"1000",
				"1000",
                                "adminmode", 
                                "1000", 
				"state",
				"1000",
                                "csppssadminmode", 
                                "csppssadminmode", 
                                "1000", 
                                "1000", 
                                "csppstadminmode", 
                                "csppstadminmode", 
+13 −15
Original line number Original line Diff line number Diff line
@@ -14,7 +14,6 @@ import sys
import os
import os
import time
import time
import logging
import logging
import unittest
import numpy as np
import numpy as np
# Tango imports
# Tango imports
import tango
import tango
@@ -40,7 +39,7 @@ LOGGER = logging.getLogger(__name__)
# Device test case
# Device test case


@pytest.mark.usefixtures("midcsp_master", "midcsp_subarray01", "cbf_master")
@pytest.mark.usefixtures("midcsp_master", "midcsp_subarray01", "cbf_master")
class TestBase(unittest.TestCase):
class TestBase(object):
    fixture_names = ()
    fixture_names = ()


    @pytest.fixture(autouse=True)
    @pytest.fixture(autouse=True)
@@ -69,8 +68,7 @@ class TestCspMaster(TestBase):
        if state == DevState.STANDBY:
        if state == DevState.STANDBY:
            argin = ["mid_csp_cbf/sub_elt/master",]
            argin = ["mid_csp_cbf/sub_elt/master",]
            self.midcsp_master.On(argin)
            self.midcsp_master.On(argin)
            prober_state = Probe(self.midcsp_master, "State", DevState.ON, f"CSP Master not ON")
        state = self.midcsp_master.State()
            Poller(3, 0.1).check(prober_state)
        if state == DevState.ON:
        if state == DevState.ON:
            return
            return


@@ -79,8 +77,6 @@ class TestCspMaster(TestBase):
        Test for execution of On command when the CbfMaster is in the right state
        Test for execution of On command when the CbfMaster is in the right state
        """
        """
        self._setup_master()
        self._setup_master()
        prober_subarray_state = Probe(self.midcsp_subarray01, "State", DevState.ON, f"CSPSubarray not ON")
        Poller(4, 0.2).check(prober_subarray_state)
        assert self.midcsp_subarray01.state() == DevState.ON
        assert self.midcsp_subarray01.state() == DevState.ON


    def test_Standby_valid_state(self):
    def test_Standby_valid_state(self):
@@ -91,24 +87,26 @@ class TestCspMaster(TestBase):
        assert self.midcsp_master.state() == DevState.ON
        assert self.midcsp_master.state() == DevState.ON
        argin = ["mid_csp_cbf/sub_elt/master",]
        argin = ["mid_csp_cbf/sub_elt/master",]
        self.midcsp_master.Standby(argin)
        self.midcsp_master.Standby(argin)
        prober_state = Probe(self.midcsp_master, "State", DevState.STANDBY, 
        assert self.midcsp_master.state() == DevState.STANDBY
                             f"CSP Master not STANDBY")
        Poller(4, 0.2).check(prober_state)


    def test_issue_Standby_AFTER_On_command(self):
    @pytest.mark.sequence
    @pytest.mark.parametrize('execution_number', range(3))
    def test_sequence_ON_STABDBY_commands(self, execution_number):
        """
        """
        Issue the Standby command just after the On command, without waiting
        Issue the Standby command just after the On command, without waiting
        on the State value.
        on the State value.
        To solve SKB-26 bug, the power commands are now executed in
        To solve SKB-26 bug, the power commands are now executed in
        synch way.
        synch way.
        Repeat the test a number times = execution_number
        """
        """
        self._setup_master()
        self._setup_master()
        argin = ["mid_csp_cbf/sub_elt/master",]
        argin = ["mid_csp_cbf/sub_elt/master",]
        self.midcsp_master.On(argin)
        self.midcsp_master.Standby(argin)
        self.midcsp_master.Standby(argin)
        prober_state = Probe(self.midcsp_master, "State", DevState.STANDBY, 
        assert self.midcsp_subarray01.state() == DevState.OFF
                             f"CSP Master not STANDBY")
        assert self.midcsp_master.state() == DevState.STANDBY
        Poller(4, 0.2).check(prober_state)
        self.midcsp_master.On(argin)
        assert self.midcsp_subarray01.state() == DevState.ON
        assert self.midcsp_master.state() == DevState.ON


    '''
    '''
    def test_cspmaster_state_WHEN_adminmode_is_offline(self):
    def test_cspmaster_state_WHEN_adminmode_is_offline(self):
Loading