예제 #1
0
    def _get_observer_in_state(self, observer_name, observer_type, for_state, **kwargs):
        """Return Observable object assigned to observer_name of given device"""
        # TODO: return observer object wrapped in decorator mocking it's start()
        available_observer_names = []
        if not for_state:
            for_state = self.current_state
        if observer_type == TextualDevice.cmds:
            available_observer_names = self._cmdnames_available_in_state[for_state]
        elif observer_type == TextualDevice.events:
            available_observer_names = self._eventnames_available_in_state[for_state]

        if observer_name in available_observer_names:
            observer_params = dict(kwargs, connection=self.io_connection.moler_connection)
            observer = create_instance_from_class_fullname(
                class_fullname=available_observer_names[observer_name],
                constructor_parameters=observer_params
            )
            return observer

        exc = DeviceFailure(
            device=self.__class__.__name__,
            message="Failed to create {}-object for '{}' {}. '{}' {} is unknown for state '{}' of device '{}'. Available names: {}".format(
                observer_type, observer_name, observer_type, observer_name, observer_type, for_state,
                self.__class__.__name__, available_observer_names))
        self._log(logging.ERROR, exc)
        raise exc
예제 #2
0
    def _trigger_change_state(self, next_state, timeout, rerun, send_enter_after_changed_state,
                              log_stacktrace_on_fail=True):
        self._log(logging.DEBUG, "'{}'. Changing state from '{}' into '{}'.".format(self.name, self.current_state,
                                                                                    next_state))
        change_state_method = None
        # all state triggers used by SM are methods with names starting from "GOTO_"
        # for e.g. GOTO_REMOTE, GOTO_CONNECTED
        for goto_method in self.goto_states_triggers:
            if "GOTO_{}".format(next_state) == goto_method:
                change_state_method = getattr(self, goto_method)

        if change_state_method:
            self._trigger_change_state_loop(rerun=rerun, next_state=next_state, change_state_method=change_state_method,
                                            timeout=timeout, log_stacktrace_on_fail=log_stacktrace_on_fail,
                                            send_enter_after_changed_state=send_enter_after_changed_state)
        else:
            exc = DeviceFailure(
                device=self.__class__.__name__,
                message="{}. Failed to change state from '{}' to '{}'. "
                        "Either target state does not exist in SM or there is no direct/indirect transition "
                        "towards target state. Try to change state machine definition. "
                        "Available states: {}".format(self.name, self.state, next_state, self.states))
            if log_stacktrace_on_fail:
                self._log(logging.ERROR, exc)
            raise exc
예제 #3
0
    def _get_observer_in_state(self, observer_name, observer_type, **kwargs):
        """Return Observable object assigned to obserber_name of given device"""
        # TODO: return observer object wrapped in decorator mocking it's start()
        # TODO:  to check it it is starting in correct state (do it on flag)
        available_observer_names = []

        if observer_type == TextualDevice.cmds:
            available_observer_names = self._cmdnames_available_in_state[
                self.current_state]
        elif observer_type == TextualDevice.events:
            available_observer_names = self._eventnames_available_in_state[
                self.current_state]

        if observer_name in available_observer_names:
            # TODO: GL refactor to instance_loader
            observer_splited = available_observer_names[observer_name].split(
                '.')
            observer_module_name = ".".join(observer_splited[:-1])
            observer_class_name = observer_splited[-1]

            observer_module = importlib.import_module(observer_module_name)
            observer_class = getattr(observer_module, observer_class_name)
            observer = observer_class(
                connection=self.io_connection.moler_connection, **kwargs)

            return observer

        raise DeviceFailure(
            device=self.__class__.__name__,
            message=
            "Failed to create {}-object for '{}' {}. '{}' {} is unknown for state '{}' of device '{}'."
            .format(observer_type, observer_name, observer_type, observer_name,
                    observer_type, self.current_state,
                    self.__class__.__name__))
예제 #4
0
    def _trigger_change_state(self, next_state, timeout, rerun,
                              send_enter_after_changed_state):
        self._log(
            logging.DEBUG, "Changing state from '%s' into '%s'" %
            (self.current_state, next_state))
        change_state_method = None
        entered_state = False
        retrying = 0
        # all state triggers used by SM are methods with names starting from "GOTO_"
        # for e.g. GOTO_REMOTE, GOTO_CONNECTED
        for goto_method in self.goto_states_triggers:
            if "GOTO_{}".format(next_state) == goto_method:
                change_state_method = getattr(self, goto_method)

        if change_state_method:
            while (retrying <= rerun) and (not entered_state) and (
                    self.current_state is not next_state):
                try:
                    change_state_method(self.current_state,
                                        next_state,
                                        timeout=timeout)
                    entered_state = True
                except Exception as ex:
                    if retrying == rerun:
                        ex_traceback = traceback.format_exc()
                        exc = DeviceChangeStateFailure(
                            device=self.__class__.__name__,
                            exception=ex_traceback)
                        self._log(logging.ERROR, exc)
                        raise exc
                    else:
                        retrying += 1
                        self._log(
                            logging.DEBUG, "Cannot change state into '{}'. "
                            "Retrying '{}' of '{}' times.".format(
                                next_state, retrying, rerun))
                        if send_enter_after_changed_state:
                            self._send_enter_after_changed_state()
            self.io_connection.moler_connection.change_newline_seq(
                self._get_newline(state=next_state))
            if send_enter_after_changed_state:
                self._send_enter_after_changed_state()
            self._log(logging.DEBUG,
                      "Successfully enter state '{}'".format(next_state))
        else:
            exc = DeviceFailure(
                device=self.__class__.__name__,
                message="Failed to change state to '{}'. "
                "Either target state does not exist in SM or there is no direct/indirect transition "
                "towards target state. Try to change state machine definition. "
                "Available states: {}".format(next_state, self.states))
            self._log(logging.ERROR, exc)
            raise exc
예제 #5
0
    def _validate_device_configuration(self):
        exception_message = ""
        configuration = self._configurations[TextualDevice.connection_hops]

        for source_state in configuration.keys():
            for dest_state in configuration[source_state].keys():
                if "required_command_params" in configuration[source_state][dest_state].keys():
                    for required_command_param in configuration[source_state][dest_state]["required_command_params"]:
                        if required_command_param not in configuration[source_state][dest_state]["command_params"]:
                            exception_message += "\n'{}' in 'command_params' in transition from '{}' to '{}'".format(
                                required_command_param, source_state, dest_state)

        if exception_message:
            exc = DeviceFailure(device=self.__class__.__name__,
                                message="Missing required parameter(s). There is no required parameter(s):{}".format(
                                    exception_message))
            self._log(logging.ERROR, exc)
            raise exc
예제 #6
0
    def _validate_prompts_uniqueness(self):
        prompts = dict()
        error_message = ""

        for state in self._state_prompts.keys():
            prompt = self._state_prompts[state]

            if prompt not in prompts.keys():
                prompts[prompt] = state
            else:
                error_message += "\n'{}' -> '{}', '{}'".format(prompt, prompts[prompt], state)

        if error_message:
            exc = DeviceFailure(device=self.__class__.__name__,
                                message="Incorrect device configuration. The same prompts for states: {}.".format(
                                    error_message))
            self._log(logging.ERROR, exc)
            raise exc