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
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
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__))
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
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
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