Commit 221d47da authored by Gianluca Marotta's avatar Gianluca Marotta
Browse files

CT-215 First implementation of alignment of InitCommand and tests; unique...

CT-215 First implementation of alignment of InitCommand and tests; unique init_command_objects in CspLmcCommon
parent c3e22519
Loading
Loading
Loading
Loading
Loading
+100 −30
Original line number Diff line number Diff line
@@ -319,8 +319,73 @@ class CspSubarray(SKASubarray):
            apiutil = tango.ApiUtil.instance()
            apiutil.set_asynch_cb_sub_model(tango.cb_sub_model.PUSH_CALLBACK)
            self.logger.info(message)

            alignment_thr = threading.Thread(target=self.obs_state_alignment,
                                                    name="Thread-Initialization ObsState Alignment",
                                                    args=())
            alignment_thr.start()

            return (result_code, message)

        def obs_state_alignment(self):

            device = self.target
            # create a list with all the obs_states of sub-elements
            # !!! delete the logger !!!
            self.logger.info(f'obs state of CBF: {device._sc_subarray_obs_state[self.CbfSubarray].name}')

            obs_states_list = [device._sc_subarray_obs_state[fqdn].name for fqdn in
                               device._sc_subarray_fqdn]
            # obs_state of cbf_subarray
            #cbf_obs_state = device._sc_subarray_obs_state[self.CbfSubarray].name
            # allowed coupled states for different sub-elements
            allowed_coupled = {'RESOURCING': 'IDLE',
                              'RESOURCING': 'EMPTY',
                              'CONFIGURING': 'READY',
                              'SCANNING': 'READY',
                              'ABORTING': 'ABORTED',
                              'RESETTING': 'IDLE',
                              'RESTARTING': 'EMPTY'
                               }
            transitional_states = allowed_coupled.keys()
            timeout = 10 # seconds

            # CASE B: CBF is ON
            if device._sc_subarray_state[self.CbfSubarray] == DevState.ON:
                # start a loop in case of transitional states (CASE 2)
                starting_time = time.time()
                exit_loop = False
                while time.time() - starting_time < timeout or exit_loop:
                    # first creates an intersection list
                    transitional_present = set(transitional_states) & set(obs_states_list)
                    # CASE 1: Transitional states NOT present
                    if not transitional_present:
                        # CASE 1.1: All obsStates are EQUAL
                        if len(set(obs_states_list)) == 1:
                            self.state_model._update_obs_state(obs_states_list[0])
                            exit_loop = True
                        # CASE 1.1: obsStates are DIFFERENT
                        else:
                            self.state_model._update_obs_state('FAULT')
                            exit_loop = True
                    # CASE 2: Transitional states ARE present
                    else:
                        state = transitional_present[0]
                        for sub_elt_obs_state in obs_states_list:
                            # CASE 2.1: Other obs_states are NOT ALLOWED
                            if sub_elt_obs_state is not (state or allowed_coupled[state]):
                                self.state_model._update_obs_state('FAULT')
                                exit_loop = True
                                break
                            # CASE 2.2: Other obs_states are ALLOWED
                            else:
                                self.state_model._update_obs_state(state)
            # CASE A: CBF is OFF
            else:
                self.state_model._update_op_state('OFF')
                self.state_model._update_obs_state('EMPTY')


    class OnCommand(SKASubarray.OnCommand):
        def do(self):
            super().do()
@@ -694,26 +759,26 @@ class CspSubarray(SKASubarray):
                self.logger.info("CspSubarray timeout flag:{}".format(target_device._timeout_expired))
                if target_device._abort_obs_event.is_set():
                    if target_device._timeout_expired or target_device._failure_raised:
                        return target_device.abort_cmd_obj.failed()
                        return target_device._abort_cmd_obj.failed()
                    self.logger.info("Abort configure ends with success!!")
                    if all(target_device._sc_subarray_obs_state[fqdn] == ObsState.ABORTED for fqdn in device_list):
                        return target_device.abort_cmd_obj.succeeded()
                    return target_device.abort_cmd_obj.abort_monitoring(device_list)
                        return target_device._abort_cmd_obj.succeeded()
                    return target_device._abort_cmd_obj.abort_monitoring(device_list)

                if target_device._timeout_expired or target_device._failure_raised:
                    # if failure/timeout found check if the CBF subarray is configured. In
                    # this case the CSP.LMC Subarray obsState is set to READY.
                    if target_device._sc_subarray_obs_state[target_device.CbfSubarray] == ObsState.READY:
                        return target_device.configure_cmd_obj.succeeded()
                        return target_device._configure_cmd_obj.succeeded()
                    self.logger.info("Configure ends with failure")
                    return target_device.configure_cmd_obj.failed()
                    return target_device._configure_cmd_obj.failed()
                if all(target_device._sc_subarray_obs_state[fqdn] == ObsState.READY for fqdn in device_list):
                    target_device._valid_scan_configuration = input_arg[1]
                    target_device._cmd_duration_measured[cmd_name] = time.time() - command_start_time
                    target_device._cmd_progress[cmd_name] = 100
                    target_device._last_executed_command = cmd_name
                    self.logger.info("Configure ends with success!!")
                    return target_device.configure_cmd_obj.succeeded()
                    return target_device._configure_cmd_obj.succeeded()

        def validate_scan_configuration(self, argin):
            """
@@ -848,9 +913,9 @@ class CspSubarray(SKASubarray):
                return
            if target_device._abort_obs_event.is_set():
                if target_device._failure_raised or target_device._timeout_expired:
                    return target_device.abort_cmd_obj.failed()
                    return target_device._abort_cmd_obj.failed()
                self.logger.info("Abort of scan command ends with success!")
                return target_device.abort_cmd_obj.succeeded()
                return target_device._abort_cmd_obj.succeeded()

    class EndScanCommand(SKASubarray.EndScanCommand):

@@ -902,7 +967,7 @@ class CspSubarray(SKASubarray):
                    if target_device._sc_subarray_obs_state[device] == ObsState.IDLE:
                        continue
                    if target_device._sc_subarray_obs_state[device] == ObsState.READY:
                        (result_code, msg) = target_device.gotoidle_cmd_obj.do()
                        (result_code, msg) = target_device._gotoidle_cmd_obj.do()
                return (result_code, msg)
            for device in devices_to_reset:
                try:
@@ -959,13 +1024,13 @@ class CspSubarray(SKASubarray):
            # end of the while loop
            # check for timeout/failure conditions on each sub-component
            if target_device._failure_raised or target_device._timeout_expired:
                return target_device.obsreset_cmd_obj.failed()
                return target_device._obsreset_cmd_obj.failed()

            if all(target_device._sc_subarray_obs_state[fqdn] == dev_successful_state for fqdn in device_list):
                target_device._cmd_progress[cmd_name] = 100
                target_device._last_executed_command = cmd_name
                self.logger.info("ObsReset ends with success")
                return target_device.obsreset_cmd_obj.succeeded()
                return target_device._obsreset_cmd_obj.succeeded()

    class AbortCommand(SKASubarray.AbortCommand):

@@ -1040,13 +1105,13 @@ class CspSubarray(SKASubarray):
            # end of the while loop
            # check for timeout/failure conditions on each sub-component
            if target_device._failure_raised or target_device._timeout_expired:
                return target_device.abort_cmd_obj.failed()
                return target_device._abort_cmd_obj.failed()

            if all(target_device._sc_subarray_obs_state[fqdn] == ObsState.ABORTED for fqdn in device_list):
                target_device._cmd_progress[cmd_name] = 100
                target_device._last_executed_command = cmd_name
                self.logger.info("Abort ends with success")
                return target_device.abort_cmd_obj.succeeded()
                return target_device._abort_cmd_obj.succeeded()

    class RestartCommand(SKASubarray.RestartCommand):

@@ -1123,13 +1188,13 @@ class CspSubarray(SKASubarray):
            # end of the while loop
            # check for timeout/failure conditions on each sub-component
            if target_device._failure_raised or target_device._timeout_expired:
                return target_device.restart_cmd_obj.failed()
                return target_device._restart_cmd_obj.failed()

            if all(target_device._sc_subarray_obs_state[fqdn] == ObsState.EMPTY for fqdn in device_list):
                target_device._cmd_progress[cmd_name] = 100
                target_device._last_executed_command = cmd_name
                self.logger.info("Restart ends with success")
                return target_device.restart_cmd_obj.succeeded()
                return target_device._restart_cmd_obj.succeeded()

    '''
    class GoToIdleCommand(ActionCommand):
@@ -1299,14 +1364,14 @@ class CspSubarray(SKASubarray):
            self.logger.info("1")
            target_device._sc_subarray_cmd_exec_state[device][cmd_name] = CmdExecState.IDLE
            if target_device._failure_raised or target_device._timeout_expired:
                return target_device.gotoidle_cmd_obj.failed()
                return target_device._gotoidle_cmd_obj.failed()
                
            self.logger.info("2")
            if all(target_device._sc_subarray_obs_state[fqdn] == dev_successful_state for fqdn in device_list):
                target_device._last_executed_command = cmd_name
                # reset the CSP Subarray command execution flag
                target_device._cmd_execution_state[cmd_name] = CmdExecState.IDLE
                return target_device.gotoidle_cmd_obj.succeeded()
                return target_device._gotoidle_cmd_obj.succeeded()

        def check_allowed(self):
            """
@@ -1603,12 +1668,12 @@ class CspSubarray(SKASubarray):
        # to determine the CSP health state.
        if self._sc_subarray_state[self.CbfSubarray] == DevState.OFF:
            if self._sc_subarray_obs_state[self.CbfSubarray] == ObsState.EMPTY:
                self.off_cmd_obj.succeeded()
                self._off_cmd_obj.succeeded()
        if self._sc_subarray_state[self.CbfSubarray] == DevState.ON:
            if self._sc_subarray_obs_state[self.CbfSubarray] == ObsState.EMPTY:
                self.on_cmd_obj.succeeded()
                self._on_cmd_obj.succeeded()
            if self._sc_subarray_obs_state[self.CbfSubarray] == ObsState.READY:
                self.configure_cmd_obj.succeeded()
                self._configure_cmd_obj.succeeded()
        #self.set_state(self._sc_subarray_state[self.CbfSubarray])
        #self.logger.info("Csp subarray state: {} obsState: {}".format(self.get_state(), self.state_model._obs_state))
        return True
@@ -1854,14 +1919,19 @@ class CspSubarray(SKASubarray):
        super().init_command_objects()

        args = (self, self.state_model, self.logger)
        self.configure_cmd_obj = self.ConfigureCommand(*args)
        self.off_cmd_obj = self.OffCommand(*args)
        self.on_cmd_obj = self.OnCommand(*args)
        self.scan_cmd_obj = self.ScanCommand(*args)
        self.gotoidle_cmd_obj = self.GoToIdleCommand(*args)
        self.obsreset_cmd_obj = self.ObsResetCommand(*args)
        self.abort_cmd_obj = self.AbortCommand(*args)
        self.restart_cmd_obj = self.RestartCommand(*args)
        self._configure_cmd_obj = self.ConfigureCommand(*args)
        self._off_cmd_obj = self.OffCommand(*args)
        self._on_cmd_obj = self.OnCommand(*args)
        self._scan_cmd_obj = self.ScanCommand(*args)
        self._gotoidle_cmd_obj = self.GoToIdleCommand(*args)
        self._obsreset_cmd_obj = self.ObsResetCommand(*args)
        self._abort_cmd_obj = self.AbortCommand(*args)
        self._restart_cmd_obj = self.RestartCommand(*args)
        self._assignresources_cmd_obj = self.AssignResourcesCommand(*args)
        self._releaseresources_cmd_obj = self.ReleaseResourcesCommand(*args)
        self.register_command_object("AssignResources", self.AssignResourcesCommand(*args))
        self.register_command_object("ReleaseResources", self.ReleaseResourcesCommand(*args))
        self.register_command_object("ReleaseAllResources", self.ReleaseAllResourcesCommand(*args))
        self.register_command_object("GoToIdle", self.GoToIdleCommand(*args))
        self.register_command_object("Configure", self.ConfigureCommand(*args))
        self.register_command_object("Scan", self.ScanCommand(*args))
+84 −9
Original line number Diff line number Diff line
@@ -21,28 +21,103 @@ def test_cspsubarray_state_and_obstate_value_after_initialization():
    """
    device_under_test = CspSubarray
    cbf_subarray_fqdn = 'mid_csp_cbf/sub_elt/subarray_01'
    cbf_subarray_state_attr = 'State'
    pss_subarray_fqdn = 'mid_csp_pss/sub_elt/subarray_01'
    pst_subarray_fqdn = 'mid_csp_pst/sub_elt/subarray_01'

    state_attr = 'State'
    dut_properties = {
            'CspMaster': 'mid_csp/elt/master',
            'CbfSubarray': cbf_subarray_fqdn,
            'PssSubarray': 'mid_csp_pss/sub_elt/subarray_01',
            'PstSubarray': 'mid_csp_pst/sub_elt/subarray_01',
            'PssSubarray': pss_subarray_fqdn,
            'PstSubarray': pst_subarray_fqdn
    }
    event_subscription_map = {}
    cbf_subarray_device_proxy_mock = Mock()
    pss_subarray_device_proxy_mock = Mock()
    pst_subarray_device_proxy_mock = Mock()

    event_subscription_map_cbf= {}
    cbf_subarray_device_proxy_mock.subscribe_event.side_effect = (
       lambda attr_name, event_type, callback, *args, **kwargs: event_subscription_map.update({attr_name: callback}))
       lambda attr_name, event_type, callback, *args, **kwargs: event_subscription_map_cbf.update({attr_name: callback}))

    event_subscription_map_pss = {}
    cbf_subarray_device_proxy_mock.subscribe_event.side_effect = (
        lambda attr_name, event_type, callback, *args, **kwargs: event_subscription_map_pss.update(
            {attr_name: callback}))

    event_subscription_map_pst = {}
    cbf_subarray_device_proxy_mock.subscribe_event.side_effect = (
        lambda attr_name, event_type, callback, *args, **kwargs: event_subscription_map_pst.update(
            {attr_name: callback}))

    proxies_to_mock = {
        cbf_subarray_fqdn: cbf_subarray_device_proxy_mock
        cbf_subarray_fqdn: cbf_subarray_device_proxy_mock,
        pss_subarray_fqdn: pss_subarray_device_proxy_mock,
        pst_subarray_fqdn: pst_subarray_device_proxy_mock
    }

    # CASE A: CBF is OFF
    with fake_tango_system(device_under_test, initial_dut_properties=dut_properties, proxies_to_mock=proxies_to_mock) as tango_context:
        dummy_event = create_dummy_event(cbf_subarray_fqdn, DevState.OFF)
        event_subscription_map[cbf_subarray_state_attr](dummy_event)
        event_subscription_map_cbf[state_attr](dummy_event)
        assert tango_context.device.State() == DevState.OFF
        assert tango_context.device.obsState == ObsState.EMPTY

    # CASE B: CBF is ON
    #
    #   CASE 1.1 ObsState are EQUAL
    with fake_tango_system(device_under_test, initial_dut_properties=dut_properties, proxies_to_mock=proxies_to_mock) as tango_context:
        dummy_event_cbf = create_dummy_obs_event(cbf_subarray_fqdn, ObsState.READY)
        dummy_event_pss = create_dummy_obs_event(cbf_subarray_fqdn, ObsState.READY)
        dummy_event_pst = create_dummy_obs_event(cbf_subarray_fqdn, ObsState.READY)

        event_subscription_map_cbf[state_attr](dummy_event_cbf)
        event_subscription_map_pss[state_attr](dummy_event_pss)
        event_subscription_map_pst[state_attr](dummy_event_pst)

        assert tango_context.device.State() == DevState.ON
        assert tango_context.device.obsState == ObsState.READY
    #
    #   CASE 1.2 ObsState are DIFFERENT
    with fake_tango_system(device_under_test, initial_dut_properties=dut_properties, proxies_to_mock=proxies_to_mock) as tango_context:
        dummy_event_cbf = create_dummy_obs_event(cbf_subarray_fqdn, ObsState.READY)
        dummy_event_pss = create_dummy_obs_event(cbf_subarray_fqdn, ObsState.FAULT)
        dummy_event_pst = create_dummy_obs_event(cbf_subarray_fqdn, ObsState.READY)

        event_subscription_map_cbf[state_attr](dummy_event_cbf)
        event_subscription_map_pss[state_attr](dummy_event_pss)
        event_subscription_map_pst[state_attr](dummy_event_pst)

        assert tango_context.device.State() == DevState.ON
        assert tango_context.device.obsState == ObsState.FAULT
    #
    #   CASE 2.1 Transitional states ALLOWED
    with fake_tango_system(device_under_test, initial_dut_properties=dut_properties, proxies_to_mock=proxies_to_mock) as tango_context:
        dummy_event_cbf = create_dummy_obs_event(cbf_subarray_fqdn, ObsState.CONFIGURING)
        dummy_event_pss = create_dummy_obs_event(cbf_subarray_fqdn, ObsState.READY)
        dummy_event_pst = create_dummy_obs_event(cbf_subarray_fqdn, ObsState.READY)

        event_subscription_map_cbf[state_attr](dummy_event_cbf)
        event_subscription_map_pss[state_attr](dummy_event_pss)
        event_subscription_map_pst[state_attr](dummy_event_pst)

        assert tango_context.device.State() == DevState.ON
        assert tango_context.device.obsState == ObsState.CONFIGURING

        dummy_event_cbf = create_dummy_obs_event(cbf_subarray_fqdn, ObsState.READY)
        assert tango_context.device.obsState == ObsState.READY
    #
    #   CASE 2.1 Transitional states NOT ALLOWED
    with fake_tango_system(device_under_test, initial_dut_properties=dut_properties, proxies_to_mock=proxies_to_mock) as tango_context:
        dummy_event_cbf = create_dummy_obs_event(cbf_subarray_fqdn, ObsState.CONFIGURING)
        dummy_event_pss = create_dummy_obs_event(cbf_subarray_fqdn, ObsState.READY)
        dummy_event_pst = create_dummy_obs_event(cbf_subarray_fqdn, ObsState.FAULT)

        event_subscription_map_cbf[state_attr](dummy_event_cbf)
        event_subscription_map_pss[state_attr](dummy_event_pss)
        event_subscription_map_pst[state_attr](dummy_event_pst)

        assert tango_context.device.State() == DevState.ON
        assert tango_context.device.obsState == ObsState.FAULT

def test_cspsbarray_state_after_On_WITH_exception_raised_by_subelement_subarray():
    """
    Test the behavior of the CspSubarray when one of the sub-element subarray
+0 −14
Original line number Diff line number Diff line
@@ -645,20 +645,6 @@ class MidCspSubarrayBase(CspSubarray):
    #def Configure(self, argin):
    #    CspSubarray.Configure(self, argin)

    def init_command_objects(self):
        """
        Sets up the command objects
        """
        super().init_command_objects()
        args = (self, self.state_model, self.logger)

        self._assignresources_cmd_obj = self.AssignResourcesCommand(*args)
        self._releaseresources_cmd_obj = self.ReleaseResourcesCommand(*args)
        self.register_command_object("AssignResources", self.AssignResourcesCommand(*args))
        self.register_command_object("ReleaseResources", self.ReleaseResourcesCommand(*args))
        self.register_command_object("ReleaseAllResources", self.ReleaseAllResourcesCommand(*args))

    
    # PROTECTED REGION END #    //  MidCspSubarrayBase.private_methods
    # ----------------
    # Class Properties