def test_get_initial_state_is_none(self):
        _, model_cfg, model_def = setup_state_machine_definitions(
            self.MACHINE_DEFINITION_FILE)
        model_def.data[SMConsts.INITIAL_STATE] = None

        init_state = model_def.get_initial_state()
        assert_is_none(init_state)
Exemple #2
0
    def _test_image_generation(
            self, filename: str = None, path_only: bool = False) -> None:
        """
        Instantiate a state machine and generate an
        image of the state machine.

        Args:
            filename (str): Filespec of file to store image
            path_only (str): Only generate the current image path

        Returns:
            None
        """
        # Set up state machine configuration
        model_file = self.SIMPLE_MACHINE_DEF_FILE
        def_file, model_cfg, model_def = setup_state_machine_definitions(
            model_file)
        expected_model_name = get_model_name_from_raw_file(def_file)

        # Build state machine
        obj_model = ImportCheck()
        sm = StateMachine(data_model=model_def, object_model=obj_model)
        sm.configure_state_machine()

        # Generate image
        image_name = sm.generate_image(filename=filename, path_only=path_only)

        # Assure image filename is correct and file exists
        filename = filename or os.path.abspath(f"{expected_model_name}.png")
        assert_equals(filename, image_name)
        assert_true(os.path.exists(image_name))

        # Verify image is deleted
        os.remove(image_name)
        assert_false(os.path.exists(image_name))
 def test_get_transitions_for_valid_state(self):
     _, model_cfg, model_def = setup_state_machine_definitions(
         self.MACHINE_DEFINITION_FILE)
     transitions = model_def.get_transitions(self.VALID_TEST_STATE)
     assert_equals(len(transitions), self.NUMBER_OF_TRANSITIONS)
     assert_true(isinstance(transitions[0], dict))
     assert_in(self.VALID_TRANSITION_NAME,
               [x[SMConsts.TRIGGER_NAME] for x in transitions])
    def test_get_transition_info_by_name_invalid_state_and_name(self):
        cfg_file, model_cfg, model_def = setup_state_machine_definitions(
            self.MACHINE_DEFINITION_FILE)
        trigger_info = model_def.get_transition_info_by_name(
            state_name=self.INVALID_TEST_STATE,
            trigger_name=self.INVALID_TEST_STATE)

        assert_equals(trigger_info, {})
    def test_validate_multi_triggers(self):
        cfg_file, model_cfg, model_def = setup_state_machine_definitions(
            self.MACHINE_DEFINITION_FILE)
        triggers = model_def.get_multi_triggers()
        validated_triggers = model_def.validate_multi_triggers(triggers)

        assert_true(isinstance(validated_triggers, list))
        assert_true(validated_triggers)
    def test_get_state_definition_with_non_existing_state(self):
        _, model_cfg, model_def = setup_state_machine_definitions(
            self.MACHINE_DEFINITION_FILE)
        state_def = model_def.get_state_definition(
            state=self.INVALID_TEST_STATE)

        assert_true(isinstance(state_def, dict))
        assert_equals(state_def, {})
Exemple #7
0
    def test_validate_initial_state_with_invalid_state(self):
        model_file, model_cfg, model_def = setup_state_machine_definitions(
            self.MACHINE_DEFINITION_FILE)

        # Set initial state to an invalid state
        model_def.data[SMConsts.INITIAL_STATE] = self.INVALID_TEST_STATE

        # Validate the initial state, should return False
        assert_false(ValidateData(model_def).validate_initial_state())
Exemple #8
0
    def test_validate_all_transitions_with_no_states(self):
        model_file, model_cfg, model_def = setup_state_machine_definitions(
            self.MACHINE_DEFINITION_FILE)

        # Remove all states (and transitions)
        model_def.data[SMConsts.DEFINITION] = {}

        # Validate the transitions (there are none!), should return False
        assert_false(ValidateData(model_def).validate_all_transitions())
Exemple #9
0
    def test__get_callback__does_not_exist(self):
        def_file, model_cfg, model_def = setup_state_machine_definitions(
            self.MACHINE_DEFINITION_FILE)

        obj_model = ImportCheck()

        sm = StateMachine(data_model=model_def, object_model=obj_model)

        # Should raise AttributeError since the method does not exist.
        sm._get_callback('object_model.undefined_test_routine')
    def test_get_all_triggers(self):
        cfg_file, model_cfg, model_def = setup_state_machine_definitions(
            self.MACHINE_DEFINITION_FILE)
        expected_triggers = get_triggers_from_raw_file(cfg_file)
        reported_triggers = model_def.get_all_triggers()

        logging.info(f"EXPECTED TRIGGERS: {expected_triggers}")
        logging.info(f"REPORTED TRIGGERS: {reported_triggers}")

        assert_equals(set(expected_triggers) ^ set(reported_triggers), set())
Exemple #11
0
    def test_validate_initial_state_with_none_value(self):
        model_file, model_cfg, model_def = setup_state_machine_definitions(
            self.MACHINE_DEFINITION_FILE)

        # Set the initial state to None (should be equivalent
        # to invalid state)
        model_def.data[SMConsts.INITIAL_STATE] = None

        # Validate the initial state, should return False
        assert_false(ValidateData(model_def).validate_initial_state())
    def test_get_state_validation_methods_valid_state(self):
        _, model_cfg, model_def = setup_state_machine_definitions(
            self.MACHINE_DEFINITION_FILE)
        validations = model_def.get_state_validation_methods(
            self.VALID_TEST_STATE)

        assert_true(isinstance(validations, list))
        assert_equals(len(validations), 2)
        assert_true(isinstance(validations[0], dict))
        assert_equals(validations[0][SMConsts.NAME],
                      self.VALID_TEST_STATE.lower())
Exemple #13
0
    def test_get_model_name(self):
        def_file, model_cfg, model_def = setup_state_machine_definitions(
            self.MACHINE_DEFINITION_FILE)

        sm = StateMachine(data_model=model_def, object_model=None)
        expected_model_name = get_model_name_from_raw_file(def_file)

        logging.info(f"Expected Model Name: {expected_model_name}")
        logging.info(f"Actual Model Name: {sm.name}")

        assert_equals(sm.name, expected_model_name)
Exemple #14
0
    def test_model(self):
        # This tests a large percentage of the configure_state_machine.
        # Testing all paths is dependent on the model definition, and
        # general_sample.yaml contains the necessary conditions/definitions
        # to traverse all logic conditions.
        def_file, model_cfg, model_def = setup_state_machine_definitions(
            self.MACHINE_DEFINITION_FILE)

        sm = StateMachine(data_model=model_def, object_model=None)
        sm.configure_state_machine()
        assert_true(isinstance(sm, StateMachine))
    def test_get_list_of_states(self):
        cfg_file, model_cfg, model_def = setup_state_machine_definitions(
            self.MACHINE_DEFINITION_FILE)

        expected_states = get_states_from_raw_file(yaml_file=cfg_file)
        returned_states = model_def.get_list_of_states()

        logging.info(f"Expected States: {expected_states}")
        logging.info(f"Returned States: {returned_states}")

        assert_equals(set(expected_states) ^ set(returned_states), set())
Exemple #16
0
    def test__set_execution_description_no_args(self):
        def_file, model_cfg, model_def = setup_state_machine_definitions(
            self.MACHINE_DEFINITION_FILE)

        expected_model_name = get_model_name_from_raw_file(def_file)

        obj_model = ImportCheck()

        sm = StateMachine(data_model=model_def, object_model=obj_model)
        sm.configure_state_machine()
        sm._set_execution_description()
        assert_equals(sm.description, expected_model_name)
    def test_get_transition_info_by_name_valid_state_and_name(self):
        cfg_file, model_cfg, model_def = setup_state_machine_definitions(
            self.MACHINE_DEFINITION_FILE)
        trigger_info = model_def.get_transition_info_by_name(
            state_name=self.VALID_TEST_STATE,
            trigger_name=self.VALID_TRANSITION_NAME)

        transitions = model_def.get_transitions(
            self.VALID_TEST_STATE)[self.VALID_TRANSITION_INDEX]
        for key, value in transitions.items():
            assert_true(key in trigger_info)
            assert_equals(value, trigger_info[key])
Exemple #18
0
    def test_validate_initial_state_that_does_not_have_transitions(self):
        model_file, model_cfg, model_def = setup_state_machine_definitions(
            self.MACHINE_DEFINITION_FILE)
        model_def.data[SMConsts.INITIAL_STATE] = self.VALID_TEST_STATE

        # Remove all transitions from initial_state definition
        state_def = model_def.data[SMConsts.DEFINITION][
            self.VALID_TEST_STATE_INDEX]
        state_def[self.VALID_TEST_STATE][SMConsts.TRANSITIONS] = []

        # Validate the initial state, should return False
        assert_false(ValidateData(model_def).validate_initial_state())
    def test_get_transition_info_for_valid_state(self):
        cfg_file, model_cfg, model_def = setup_state_machine_definitions(
            self.MACHINE_DEFINITION_FILE)
        transitions = model_def.get_transitions(self.VALID_TEST_STATE)
        trans_tuple = (t_name, t_dest, t_method) = \
            model_def.get_transition_info(transitions[0])
        logging.info(f"Expected transition Data (not in order): "
                     f"{set(list(transitions[0].values()))}")
        logging.info(f"Received transition Data tuple: {set(trans_tuple)}")

        assert_equals(t_name, transitions[0][SMConsts.TRIGGER_NAME])
        assert_equals(t_dest, transitions[0][SMConsts.DESTINATION_STATE])
        assert_equals(t_method, transitions[0][SMConsts.CHANGE_STATE_ROUTINE])
    def test_get_state_definition_with_existing_state(self):
        _, model_cfg, model_def = setup_state_machine_definitions(
            self.MACHINE_DEFINITION_FILE)
        state_def = model_def.get_state_definition(state=self.VALID_TEST_STATE)

        logging.info(f"STATE NAME: {self.VALID_TEST_STATE}")
        logging.info(f"EXPECTED STATE DESCRIPTION: "
                     f"{self.VALID_TEST_STATE_DESCRIPTION}")
        logging.info(state_def)

        assert_true(isinstance(state_def, dict))
        assert_equals(state_def[SMConsts.DESCRIPTION],
                      self.VALID_TEST_STATE_DESCRIPTION)
    def test_get_multi_triggers(self):
        expected_trigger_names = [
            'multi_trigger_test_from_all',
            'multi_trigger_test_from_select_states']

        cfg_file, model_cfg, model_def = setup_state_machine_definitions(
            self.MACHINE_DEFINITION_FILE)
        triggers = model_def.get_multi_triggers()
        trigger_names = [x.get(SMConsts.TRIGGER_NAME) for x in triggers]

        assert_true(isinstance(triggers, list))
        assert_true(triggers)
        assert_equals(expected_trigger_names, trigger_names)
Exemple #22
0
    def test__get_callback__exists(self):
        def_file, model_cfg, model_def = setup_state_machine_definitions(
            self.SIMPLE_MACHINE_DEF_FILE)

        obj_model = ImportCheck()

        sm = StateMachine(data_model=model_def, object_model=obj_model)
        api = sm._get_callback('object_model.test_routine')

        # Verify the routine returned a Callable reference.
        assert_true(callable(api))

        # Execute the API. It should return the default value, which is False
        assert_equals(api(), ImportCheck.DEFAULT_RESPONSE)
    def test_get_transition_info_for_undefined_transition(self):
        error_msg = 'Not Found'

        cfg_file, model_cfg, model_def = setup_state_machine_definitions(
            self.MACHINE_DEFINITION_FILE)
        transitions = model_def.get_transitions(self.VALID_TEST_STATE)
        transitions[0] = {}

        trans_tuple = model_def.get_transition_info(transitions[0])
        logging.info(f"Expected transition Data (not in order): "
                     f"{[error_msg for _ in range(3)]}")
        logging.info(f"Received transition Data tuple: {set(trans_tuple)}")

        for msg in trans_tuple:
            assert_equals(msg, error_msg)
Exemple #24
0
    def _setup_state_machine_for_execution(filename):
        def_file, model_cfg, model_def = setup_state_machine_definitions(
            filename)
        obj_model = ImportCheck()
        sm = StateMachine(data_model=model_def, object_model=obj_model)
        sm.configure_state_machine()

        # Get data about transition configuration
        trans_data = model_def.get_transitions(sm.machine.initial)[0]
        callback_routine = trans_data[SMConsts.CHANGE_STATE_ROUTINE]

        # Setup state machine to execute transition
        trigger_name = trans_data[SMConsts.TRIGGER_NAME]
        sm.current_step = PathStep(
            trigger=trigger_name,
            trigger_id=f'from_{sm.machine.initial}')
        return sm, trigger_name, callback_routine
    def test_get_state_definitions(self):
        _, model_cfg, model_def = setup_state_machine_definitions(
            self.MACHINE_DEFINITION_FILE)
        defs = model_def.get_state_definitions()

        # Get all of the states (but remove the entries prefixed with
        # the StateMachineConstants.NON_STATE_PREFIX)
        test_model = model_cfg.data[SMConsts.DEFINITION]
        test_model = [x for x in test_model if
                      not list(x.keys())[0].startswith(
                          SMConsts.NON_STATE_PREFIX)]

        num_states = len(test_model)
        logging.debug(f"\nExpected Number of States: {num_states}:\n"
                      f"{test_model}")
        logging.debug(f"Received: {len(defs)}:\n{defs}")

        assert_true(defs, isinstance(defs, list))
        assert_equals(len(defs), num_states)
Exemple #26
0
    def test_validate_all_transitions_with_an_invalid_transition(self):
        bogus_transition = {
            SMConsts.CHANGE_STATE_ROUTINE: 'object_model.unlock_server',
            SMConsts.DESTINATION_STATE: self.INVALID_TEST_STATE,
            SMConsts.TRIGGER_NAME: 'BOGUS'
        }

        # Not pretty, but to meet PEP-8 line length, save to a tuple,
        # and then assign vars based on the tuple
        model_tuple = setup_state_machine_definitions(
            self.MACHINE_DEFINITION_FILE)
        (model_file, model_cfg, model_def) = model_tuple

        # Add a transition (to any state) that points to an
        # unknown/undefined state
        state_def = model_def.data[SMConsts.DEFINITION][
            self.VALID_TEST_STATE_INDEX]
        state_def[self.VALID_TEST_STATE][SMConsts.TRANSITIONS].append(
            bogus_transition)

        # Validate the transitions, should return False
        assert_false(ValidateData(model_def).validate_all_transitions())
 def test_get_initial_state(self):
     _, model_cfg, model_def = setup_state_machine_definitions(
         self.MACHINE_DEFINITION_FILE)
     init_state = model_def.get_initial_state()
     assert_equals(init_state, model_cfg.data[SMConsts.INITIAL_STATE])
    def test_get_model_name(self):
        _, model_cfg, model_def = setup_state_machine_definitions(
            self.MACHINE_DEFINITION_FILE)

        model_name = model_def.get_model_name()
        assert_equals(model_name, model_cfg.data[SMConsts.MODEL_NAME])
 def test_validate_path_with_invalid_path(self):
     cfg_file, model_cfg, model_def = setup_state_machine_definitions(
         self.MACHINE_DEFINITION_FILE)
     path = get_states_from_raw_file(yaml_file=cfg_file)
     assert_false(model_def.validate_path(path))
 def test_get_transition_info_for_invalid_state(self):
     cfg_file, model_cfg, model_def = setup_state_machine_definitions(
         self.MACHINE_DEFINITION_FILE)
     transitions = model_def.get_transitions(self.INVALID_TEST_STATE)
     assert_equals(transitions, [])