示例#1
0
    def test_state_machine_illegal_path(self):
        model_file = self.SIMPLE_MACHINE_DEF_FILE
        illegal_trigger_name = 'ILLEGAL_TRIGGER'

        sm, trigger_name, callback_routine = \
            self._setup_state_machine_for_execution(filename=model_file)

        steps = [
            PathStep(
                trigger=trigger_name,
                trigger_id=f'from_{sm.machine.initial}'),
            PathStep(
                trigger=illegal_trigger_name,
                trigger_id="ILLEGAL STEP")
        ]

        # Execute the state machine
        sm.execute_state_machine(input_data=steps)

        # Illegal path should cause duplication of last state since
        # transition was requested but action denied.
        expected_path = [sm.machine.initial, sm.state, sm.state]

        logging.info(f"EXPECTED PATH: {expected_path}")
        logging.info(f"ACTUAL PATH: {sm.path}")

        assert_true(isinstance(sm.path, list))
        assert_equals(expected_path, sm.path)
示例#2
0
    def test_add_data(self):

        # Verify data is added to PathStep correctly

        test_data = str(uuid4())
        step = PathStep(trigger=self.TRIGGER_NAME)
        step.add_data(data=test_data)

        assert_equals(step.trigger_data, test_data)
示例#3
0
    def test_add_id(self):

        # Verify ID is added to PathStep correctly

        test_id = str(uuid4())
        step = PathStep(trigger=self.TRIGGER_NAME)
        step.add_id(step_id=test_id)

        assert_equals(step.id, test_id)
示例#4
0
    def test__str__does_not_crash(self):
        test_id = str(uuid4())
        validation_ids = ['test']
        expectations = [False]

        step = PathStep(trigger=self.TRIGGER_NAME)
        step.add_id(step_id=test_id)
        self._add_and_validate_expectations(
            validation_ids=validation_ids, expectations=expectations)

        assert_true(isinstance(str(step), str))
示例#5
0
    def build_test_case(self, test_suite: str,
                        test_name: str) -> typing.List[PathStep]:
        """
        Get the test case definition for the specified test suite & test case

        Args:
            test_suite (str): Name of test suite (ConfigParser section)
            test_name (str): Name of test case (Config Parser section option)

        Returns:
            (list[dict]) Paths for state machine with execution
            and validation parameters

        """
        test_cases = self.get_possible_test_cases(test_suite)

        # Check if test case is defined...
        if test_name not in test_cases:
            logging.error(f"The test case '{test_name}' was not found in "
                          f"specified suite: '{test_suite}'")
            return []

        # Get test suite data, get the test case steps and return list
        ts_data = [x for x in self.data if test_suite in x][0][test_suite]

        test_case = []
        for tc in ts_data[test_name].get(YamlPathConsts.STEPS, []):
            step = PathStep(trigger=list(tc.keys())[0])

            # Record the trigger's unique id (if present)
            if YamlPathConsts.ID in tc[step.trigger]:
                step.add_id(tc[step.trigger][YamlPathConsts.ID])

            # Save validation expectations (id corresponds to specific
            # validation routine associated with step and result is the
            # expectation)
            if tc[step.trigger][YamlPathConsts.EXPECTATIONS] is not None:
                for v_id, exp in \
                        tc[step.trigger][YamlPathConsts.EXPECTATIONS].items():
                    step.add_expectation(v_id, exp)

            # Save the data to passed to the trigger if provided
            if (tc[step.trigger][YamlPathConsts.DATA] is not None
                    or tc[step.trigger][YamlPathConsts.DATA] != {}):
                step.add_data(tc[step.trigger][YamlPathConsts.DATA])

            test_case.append(step)

        self.test_case = test_case

        valid_path = ValidatePaths.validate_steps(steps=self.test_case)
        if not valid_path:
            logging.error("Errors found in the path definitions. "
                          "Returning an empty list of steps.")

        return self.test_case if valid_path else []
示例#6
0
    def _add_and_validate_expectations(
            self, validation_ids: List[str],
            expectations: List[bool]) -> NoReturn:

        # Add requested expectations
        step = PathStep(trigger=self.TRIGGER_NAME)
        for id_, expect in zip(validation_ids, expectations):
            step.add_expectation(
                validation_id=id_, expectation=expect)

        # Verify the expectations were added correctly (format and value)
        assert_equals(len(step.expectations), len(validation_ids))
        for index in range(len(validation_ids)):
            assert_equals(
                step.expectations[index][PathStep.ID],
                validation_ids[index])
            assert_equals(
                step.expectations[index][PathStep.EXPECTATION],
                expectations[index])
示例#7
0
    def test_get_expectations(self):

        # Verify requested expectation value is returned

        validation_ids = ['test_1', 'test_2']
        expectations = [False, True]
        target_index = choice(range(len(expectations)))

        logging.info(f"Selecting expectation element: {target_index}")

        # Add expectations
        step = PathStep(trigger=self.TRIGGER_NAME)
        for id_, expect in zip(validation_ids, expectations):
            step.add_expectation(
                validation_id=id_, expectation=expect)

        # Get randomly selected expectation (selected from expectations added)
        expectation = step.get_expectation(validation_ids[target_index])

        # Verify return value matches the expectation
        assert_equals(expectation, expectations[target_index])
示例#8
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
示例#9
0
    def test_state_machine_traversal_path(self):
        model_file = self.SIMPLE_MACHINE_DEF_FILE

        sm, trigger_name, callback_routine = \
            self._setup_state_machine_for_execution(filename=model_file)

        steps = [PathStep(
            trigger=trigger_name,
            trigger_id=f'from_{sm.machine.initial}')]

        sm.execute_state_machine(input_data=steps)

        expected_path = [sm.machine.initial, sm.state]

        logging.info(f"EXPECTED PATH: {expected_path}")
        logging.info(f"ACTUAL PATH: {sm.path}")

        assert_true(isinstance(sm.path, list))
        assert_equals(expected_path, sm.path)
示例#10
0
    def _setup_and_execute_state_machine(self) -> Tuple[StateMachine, str, str]:
        """
        Sets up and executes the model

        Returns:
            Tuple: state_machine (StateMachine), trigger_name (str), trigger_id (str)

        """
        model_file = self.SIMPLE_MACHINE_DEF_FILE

        sm, trigger_name, callback_routine = \
            self._setup_state_machine_for_execution(filename=model_file)

        trigger_id = f'from_{sm.machine.initial}'
        steps = [PathStep(
            trigger=trigger_name,
            trigger_id=trigger_id)]

        sm.execute_state_machine(input_data=steps)
        return sm, trigger_name, trigger_id
示例#11
0
    def _define_path_step(self,
                          trigger_name: str = None,
                          trigger_id: str = None) -> PathStep:
        """
        Builds a simple path step with a name, id, expectations,
        and data

        Args:
            trigger_name (str): Name of trigger/step
            trigger_id (str): Unique id for trigger/step

        Returns:
            Instantiated and populated PathStep object
        """

        trigger_name = trigger_name or self.TRIGGER_NAME
        trigger_id = trigger_id or self.TRIGGER_ID

        step = PathStep(trigger=trigger_name, trigger_id=trigger_id)
        step.add_data(self.STEP_DATA)
        for validation_id, expectation in self.EXPECTATIONS.items():
            step.add_expectation(validation_id, expectation)
        return step