예제 #1
0
    def test_created_temporary_auth_token_is_correctly_scoped_to_user_who_ran_the_action(
            self):
        params = {
            'actionstr': 'bar',
            'mock_status': action_constants.LIVEACTION_STATUS_SUCCEEDED
        }

        global global_runner
        global_runner = None

        def mock_get_runner(*args, **kwargs):
            global global_runner
            runner = original_get_runner(*args, **kwargs)
            global_runner = runner
            return runner

        # user joe_1

        runner_container = get_runner_container()
        original_get_runner = runner_container._get_runner

        liveaction_db = self._get_failingaction_exec_db_model(params)
        liveaction_db = LiveAction.add_or_update(liveaction_db)
        liveaction_db.context = {'user': '******'}
        executions.create_execution_object(liveaction_db)

        runner_container._get_runner = mock_get_runner

        self.assertEqual(getattr(global_runner, 'auth_token', None), None)
        runner_container.dispatch(liveaction_db)
        self.assertEqual(global_runner.auth_token.user, 'user_joe_1')
        self.assertEqual(global_runner.auth_token.metadata['service'],
                         'actions_container')

        runner_container._get_runner = original_get_runner

        # user mark_1
        global_runner = None
        runner_container = get_runner_container()
        original_get_runner = runner_container._get_runner

        liveaction_db = self._get_failingaction_exec_db_model(params)
        liveaction_db = LiveAction.add_or_update(liveaction_db)
        liveaction_db.context = {'user': '******'}
        executions.create_execution_object(liveaction_db)
        original_get_runner = runner_container._get_runner

        runner_container._get_runner = mock_get_runner

        self.assertEqual(getattr(global_runner, 'auth_token', None), None)
        runner_container.dispatch(liveaction_db)
        self.assertEqual(global_runner.auth_token.user, 'user_mark_2')
        self.assertEqual(global_runner.auth_token.metadata['service'],
                         'actions_container')
예제 #2
0
    def test_created_temporary_auth_token_is_correctly_scoped_to_user_who_ran_the_action(self):
        params = {
            'actionstr': 'bar',
            'mock_status': action_constants.LIVEACTION_STATUS_SUCCEEDED
        }

        global global_runner
        global_runner = None

        def mock_get_runner(*args, **kwargs):
            global global_runner
            runner = original_get_runner(*args, **kwargs)
            global_runner = runner
            return runner

        # user joe_1

        runner_container = get_runner_container()
        original_get_runner = runner_container._get_runner

        liveaction_db = self._get_failingaction_exec_db_model(params)
        liveaction_db = LiveAction.add_or_update(liveaction_db)
        liveaction_db.context = {'user': '******'}
        executions.create_execution_object(liveaction_db)

        runner_container._get_runner = mock_get_runner

        self.assertEqual(getattr(global_runner, 'auth_token', None), None)
        runner_container.dispatch(liveaction_db)
        self.assertEqual(global_runner.auth_token.user, 'user_joe_1')
        self.assertEqual(global_runner.auth_token.metadata['service'], 'actions_container')

        runner_container._get_runner = original_get_runner

        # user mark_1
        global_runner = None
        runner_container = get_runner_container()
        original_get_runner = runner_container._get_runner

        liveaction_db = self._get_failingaction_exec_db_model(params)
        liveaction_db = LiveAction.add_or_update(liveaction_db)
        liveaction_db.context = {'user': '******'}
        executions.create_execution_object(liveaction_db)
        original_get_runner = runner_container._get_runner

        runner_container._get_runner = mock_get_runner

        self.assertEqual(getattr(global_runner, 'auth_token', None), None)
        runner_container.dispatch(liveaction_db)
        self.assertEqual(global_runner.auth_token.user, 'user_mark_2')
        self.assertEqual(global_runner.auth_token.metadata['service'], 'actions_container')
예제 #3
0
파일: inquiries.py 프로젝트: lyandut/st2
    def _mark_inquiry_complete(self, inquiry_id, result):
        """Mark Inquiry as completed

        This function updates the local LiveAction and Execution with a successful
        status as well as call the "post_run" function for the Inquirer runner so that
        the appropriate callback function is executed

        :param inquiry: The Inquiry for which the response is given
        :param requester_user: The user providing the response

        :rtype: bool - True if requester_user is able to respond. False if not.
        """

        # Update inquiry's execution result with a successful status and the validated response
        liveaction_db = action_utils.update_liveaction_status(
            status=action_constants.LIVEACTION_STATUS_SUCCEEDED,
            runner_info=system_info.get_process_info(),
            result=result,
            liveaction_id=inquiry_id)
        executions.update_execution(liveaction_db)

        # Call Inquiry runner's post_run to trigger callback to workflow
        runner_container = get_runner_container()
        action_db = get_action_by_ref(liveaction_db.action)
        runnertype_db = get_runnertype_by_name(action_db.runner_type['name'])
        runner = runner_container._get_runner(runnertype_db, action_db, liveaction_db)
        runner.post_run(status=action_constants.LIVEACTION_STATUS_SUCCEEDED, result=result)

        return liveaction_db
예제 #4
0
    def _mark_inquiry_complete(self, inquiry_id, result):
        """Mark Inquiry as completed

        This function updates the local LiveAction and Execution with a successful
        status as well as call the "post_run" function for the Inquirer runner so that
        the appropriate callback function is executed

        :param inquiry: The Inquiry for which the response is given
        :param requester_user: The user providing the response

        :rtype: bool - True if requester_user is able to respond. False if not.
        """

        # Update inquiry's execution result with a successful status and the validated response
        liveaction_db = action_utils.update_liveaction_status(
            status=action_constants.LIVEACTION_STATUS_SUCCEEDED,
            runner_info=system_info.get_process_info(),
            result=result,
            liveaction_id=inquiry_id)
        executions.update_execution(liveaction_db)

        # Call Inquiry runner's post_run to trigger callback to workflow
        runner_container = get_runner_container()
        action_db = get_action_by_ref(liveaction_db.action)
        runnertype_db = get_runnertype_by_name(action_db.runner_type['name'])
        runner = runner_container._get_runner(runnertype_db, action_db,
                                              liveaction_db)
        runner.post_run(status=action_constants.LIVEACTION_STATUS_SUCCEEDED,
                        result=result)

        return liveaction_db
예제 #5
0
    def test_state_db_created_for_polling_async_actions(self):
        runner_container = get_runner_container()

        params = {"actionstr": "foo", "actionint": 20, "async_test": True}

        liveaction_db = self._get_liveaction_model(
            RunnerContainerTest.polling_async_action_db, params)

        liveaction_db = LiveAction.add_or_update(liveaction_db)
        executions.create_execution_object(liveaction_db)

        # Assert that execution ran without exceptions.
        with mock.patch(
                "st2actions.container.base.get_runner",
                mock.Mock(return_value=polling_async_runner.get_runner()),
        ):
            runner_container.dispatch(liveaction_db)
        states = ActionExecutionState.get_all()
        found = [
            state for state in states if state.execution_id == liveaction_db.id
        ]

        self.assertTrue(len(found) > 0, "There should be a state db object.")
        self.assertTrue(
            len(found) == 1, "There should only be one state db object.")
        self.assertIsNotNone(found[0].query_context)
        self.assertIsNotNone(found[0].query_module)
예제 #6
0
파일: inquiry.py 프로젝트: st2sandbox/st2
def respond(inquiry, response, requester=None):
    # Set requester to system user is not provided.
    if not requester:
        requester = cfg.CONF.system_user.user

    # Retrieve the liveaction from the database.
    liveaction_db = lv_db_access.LiveAction.get_by_id(
        inquiry.liveaction.get("id"))

    # Resume the parent workflow first. If the action execution for the inquiry is updated first,
    # it triggers handling of the action execution completion which will interact with the paused
    # parent workflow. The resuming logic that is executed here will then race with the completion
    # of the inquiry action execution, which will randomly result in the parent workflow stuck in
    # paused state.
    if liveaction_db.context.get("parent"):
        LOG.debug('Resuming workflow parent(s) for inquiry "%s".' %
                  str(inquiry.id))

        # For action execution under Action Chain workflows, request the entire
        # workflow to resume. Orquesta handles resume differently and so does not require root
        # to resume. Orquesta allows for specifc branches to resume while other is paused. When
        # there is no other paused branches, the conductor will resume the rest of the workflow.
        resume_target = (
            action_service.get_parent_liveaction(liveaction_db)
            if workflow_service.is_action_execution_under_workflow_context(
                liveaction_db) else
            action_service.get_root_liveaction(liveaction_db))

        if resume_target.status in action_constants.LIVEACTION_PAUSE_STATES:
            action_service.request_resume(resume_target, requester)

    # Succeed the liveaction and update result with the inquiry response.
    LOG.debug('Updating response for inquiry "%s".' % str(inquiry.id))

    result = fast_deepcopy_dict(inquiry.result)
    result["response"] = response

    liveaction_db = action_utils.update_liveaction_status(
        status=action_constants.LIVEACTION_STATUS_SUCCEEDED,
        end_timestamp=date_utils.get_datetime_utc_now(),
        runner_info=sys_info_utils.get_process_info(),
        result=result,
        liveaction_id=str(liveaction_db.id),
    )

    # Sync the liveaction with the corresponding action execution.
    execution_service.update_execution(liveaction_db)

    # Invoke inquiry post run to trigger a callback to parent workflow.
    LOG.debug('Invoking post run for inquiry "%s".' % str(inquiry.id))
    runner_container = container.get_runner_container()
    action_db = action_utils.get_action_by_ref(liveaction_db.action)
    runnertype_db = action_utils.get_runnertype_by_name(
        action_db.runner_type["name"])
    runner = runner_container._get_runner(runnertype_db, action_db,
                                          liveaction_db)
    runner.post_run(status=action_constants.LIVEACTION_STATUS_SUCCEEDED,
                    result=result)

    return liveaction_db
예제 #7
0
    def test_state_db_created_for_polling_async_actions(self):
        runner_container = get_runner_container()

        params = {
            'actionstr': 'foo',
            'actionint': 20,
            'async_test': True
        }

        liveaction_db = self._get_liveaction_model(
            RunnerContainerTest.polling_async_action_db,
            params
        )

        liveaction_db = LiveAction.add_or_update(liveaction_db)
        executions.create_execution_object(liveaction_db)

        # Assert that execution ran without exceptions.
        runner_container.dispatch(liveaction_db)
        states = ActionExecutionState.get_all()
        found = [state for state in states if state.execution_id == liveaction_db.id]

        self.assertTrue(len(found) > 0, 'There should be a state db object.')
        self.assertTrue(len(found) == 1, 'There should only be one state db object.')
        self.assertTrue(found[0].query_context is not None)
        self.assertTrue(found[0].query_module is not None)
예제 #8
0
 def test_dispatch_runner_failure(self):
     runner_container = get_runner_container()
     params = {'actionstr': 'bar'}
     actionexec_db = self._get_failingaction_exec_db_model(params)
     actionexec_db = ActionExecution.add_or_update(actionexec_db)
     self.assertTrue(runner_container.dispatch(actionexec_db))
     # pickup updated actionexec_db
     actionexec_db = ActionExecution.get_by_id(actionexec_db.id)
     self.assertTrue('message' in actionexec_db.result)
     self.assertTrue('traceback' in actionexec_db.result)
예제 #9
0
파일: inquiry.py 프로젝트: nzlosh/st2
def respond(inquiry, response, requester=None):
    # Set requester to system user is not provided.
    if not requester:
        requester = cfg.CONF.system_user.user

    # Retrieve the liveaction from the database.
    liveaction_db = lv_db_access.LiveAction.get_by_id(inquiry.liveaction.get('id'))

    # Resume the parent workflow first. If the action execution for the inquiry is updated first,
    # it triggers handling of the action execution completion which will interact with the paused
    # parent workflow. The resuming logic that is executed here will then race with the completion
    # of the inquiry action execution, which will randomly result in the parent workflow stuck in
    # paused state.
    if liveaction_db.context.get('parent'):
        LOG.debug('Resuming workflow parent(s) for inquiry "%s".' % str(inquiry.id))

        # For action execution under Action Chain and Mistral workflows, request the entire
        # workflow to resume. Orquesta handles resume differently and so does not require root
        # to resume. Orquesta allows for specifc branches to resume while other is paused. When
        # there is no other paused branches, the conductor will resume the rest of the workflow.
        resume_target = (
            action_service.get_parent_liveaction(liveaction_db)
            if workflow_service.is_action_execution_under_workflow_context(liveaction_db)
            else action_service.get_root_liveaction(liveaction_db)
        )

        if resume_target.status in action_constants.LIVEACTION_PAUSE_STATES:
            action_service.request_resume(resume_target, requester)

    # Succeed the liveaction and update result with the inquiry response.
    LOG.debug('Updating response for inquiry "%s".' % str(inquiry.id))

    result = copy.deepcopy(inquiry.result)
    result['response'] = response

    liveaction_db = action_utils.update_liveaction_status(
        status=action_constants.LIVEACTION_STATUS_SUCCEEDED,
        end_timestamp=date_utils.get_datetime_utc_now(),
        runner_info=sys_info_utils.get_process_info(),
        result=result,
        liveaction_id=str(liveaction_db.id)
    )

    # Sync the liveaction with the corresponding action execution.
    execution_service.update_execution(liveaction_db)

    # Invoke inquiry post run to trigger a callback to parent workflow.
    LOG.debug('Invoking post run for inquiry "%s".' % str(inquiry.id))
    runner_container = container.get_runner_container()
    action_db = action_utils.get_action_by_ref(liveaction_db.action)
    runnertype_db = action_utils.get_runnertype_by_name(action_db.runner_type['name'])
    runner = runner_container._get_runner(runnertype_db, action_db, liveaction_db)
    runner.post_run(status=action_constants.LIVEACTION_STATUS_SUCCEEDED, result=result)

    return liveaction_db
예제 #10
0
 def test_dispatch(self):
     runner_container = get_runner_container()
     params = {'actionstr': 'bar'}
     actionexec_db = self._get_action_exec_db_model(params)
     actionexec_db = ActionExecution.add_or_update(actionexec_db)
     # Assert that execution ran successfully.
     self.assertTrue(runner_container.dispatch(actionexec_db))
     actionexec_db = ActionExecution.get_by_id(actionexec_db.id)
     result = actionexec_db.result
     self.assertTrue(result.get('action_params').get('actionint') == 10)
     self.assertTrue(result.get('action_params').get('actionstr') == 'bar')
예제 #11
0
 def test_dispatch_runner_failure(self):
     runner_container = get_runner_container()
     params = {'actionstr': 'bar'}
     liveaction_db = self._get_failingaction_exec_db_model(params)
     liveaction_db = LiveAction.add_or_update(liveaction_db)
     executions.create_execution_object(liveaction_db)
     runner_container.dispatch(liveaction_db)
     # pickup updated liveaction_db
     liveaction_db = LiveAction.get_by_id(liveaction_db.id)
     self.assertTrue('error' in liveaction_db.result)
     self.assertTrue('traceback' in liveaction_db.result)
예제 #12
0
 def test_dispatch_runner_failure(self):
     runner_container = get_runner_container()
     params = {"actionstr": "bar"}
     liveaction_db = self._get_failingaction_exec_db_model(params)
     liveaction_db = LiveAction.add_or_update(liveaction_db)
     executions.create_execution_object(liveaction_db)
     runner_container.dispatch(liveaction_db)
     # pickup updated liveaction_db
     liveaction_db = LiveAction.get_by_id(liveaction_db.id)
     self.assertTrue("message" in liveaction_db.result)
     self.assertTrue("traceback" in liveaction_db.result)
예제 #13
0
 def test_dispatch_override_default_action_params(self):
     runner_container = get_runner_container()
     params = {"actionstr": "foo", "actionint": 20}
     liveaction_db = self._get_action_exec_db_model(RunnerContainerTest.action_db, params)
     liveaction_db = LiveAction.add_or_update(liveaction_db)
     executions.create_execution_object(liveaction_db)
     # Assert that execution ran successfully.
     runner_container.dispatch(liveaction_db)
     liveaction_db = LiveAction.get_by_id(liveaction_db.id)
     result = liveaction_db.result
     self.assertTrue(result.get("action_params").get("actionint") == 20)
     self.assertTrue(result.get("action_params").get("actionstr") == "foo")
예제 #14
0
 def test_dispatch_runner_failure(self):
     runner_container = get_runner_container()
     params = {
         'actionstr': 'bar'
     }
     actionexec_db = self._get_failingaction_exec_db_model(params)
     actionexec_db = ActionExecution.add_or_update(actionexec_db)
     self.assertTrue(runner_container.dispatch(actionexec_db))
     # pickup updated actionexec_db
     actionexec_db = ActionExecution.get_by_id(actionexec_db.id)
     self.assertTrue('message' in actionexec_db.result)
     self.assertTrue('traceback' in actionexec_db.result)
예제 #15
0
    def test_dispatch_non_utf8_result(self):
        runner_container = get_runner_container()
        params = {"cmd": "python -c 'print \"\\x82\"'"}
        liveaction_db = self._get_liveaction_model(RunnerContainerTest.local_action_db, params)
        liveaction_db = LiveAction.add_or_update(liveaction_db)
        executions.create_execution_object(liveaction_db)

        try:
            runner_container.dispatch(liveaction_db)
            self.fail("Mongo won't handle non UTF-8 strings. Should have failed.")
        except InvalidStringData:
            pass
예제 #16
0
 def test_dispatch_override_default_action_params(self):
     runner_container = get_runner_container()
     params = {'actionstr': 'foo', 'actionint': 20}
     liveaction_db = self._get_liveaction_model(
         RunnerContainerTest.action_db, params)
     liveaction_db = LiveAction.add_or_update(liveaction_db)
     executions.create_execution_object(liveaction_db)
     # Assert that execution ran successfully.
     runner_container.dispatch(liveaction_db)
     liveaction_db = LiveAction.get_by_id(liveaction_db.id)
     result = liveaction_db.result
     self.assertTrue(result.get('action_params').get('actionint') == 20)
     self.assertTrue(result.get('action_params').get('actionstr') == 'foo')
예제 #17
0
    def test_dispatch_override_default_action_params(self):
        runner_container = get_runner_container()
        params = {'actionstr': 'foo', 'actionint': 20}
        actionexec_db = self._get_action_exec_db_model(params)
        actionexec_db = ActionExecution.add_or_update(actionexec_db)

        # Assert that execution ran successfully.
        result = runner_container.dispatch(actionexec_db)
        self.assertTrue(result)
        actionexec_db = ActionExecution.get_by_id(actionexec_db.id)
        result = actionexec_db.result
        self.assertTrue(result.get('action_params').get('actionint') == 20)
        self.assertTrue(result.get('action_params').get('actionstr') == 'foo')
예제 #18
0
 def test_dispatch(self):
     runner_container = get_runner_container()
     params = {
         'actionstr': 'bar'
     }
     actionexec_db = self._get_action_exec_db_model(params)
     actionexec_db = ActionExecution.add_or_update(actionexec_db)
     # Assert that execution ran successfully.
     self.assertTrue(runner_container.dispatch(actionexec_db))
     actionexec_db = ActionExecution.get_by_id(actionexec_db.id)
     result = actionexec_db.result
     self.assertTrue(result.get('action_params').get('actionint') == 10)
     self.assertTrue(result.get('action_params').get('actionstr') == 'bar')
예제 #19
0
    def test_dispatch_non_utf8_result(self):
        runner_container = get_runner_container()
        params = {'cmd': "python -c 'print \"\\x82\"'"}
        liveaction_db = self._get_liveaction_model(
            RunnerContainerTest.local_action_db, params)
        liveaction_db = LiveAction.add_or_update(liveaction_db)
        executions.create_execution_object(liveaction_db)

        try:
            runner_container.dispatch(liveaction_db)
            self.fail(
                'Mongo won\'t handle non UTF-8 strings. Should have failed.')
        except InvalidStringData:
            pass
예제 #20
0
    def test_dispatch_unsupported_status(self):
        runner_container = get_runner_container()
        params = {'actionstr': 'bar'}
        liveaction_db = self._get_liveaction_model(
            RunnerContainerTest.action_db, params)
        liveaction_db = LiveAction.add_or_update(liveaction_db)
        executions.create_execution_object(liveaction_db)

        # Manually set the liveaction_db to some unsupported status.
        liveaction_db.status = action_constants.LIVEACTION_STATUS_CANCELED

        # Assert exception is raised on dispatch.
        self.assertRaises(ActionRunnerDispatchError, runner_container.dispatch,
                          liveaction_db)
예제 #21
0
    def test_dispatch_unsupported_status(self):
        runner_container = get_runner_container()
        params = {'actionstr': 'bar'}
        liveaction_db = self._get_liveaction_model(RunnerContainerTest.action_db, params)
        liveaction_db = LiveAction.add_or_update(liveaction_db)
        executions.create_execution_object(liveaction_db)

        # Manually set the liveaction_db to some unsupported status.
        liveaction_db.status = action_constants.LIVEACTION_STATUS_CANCELED

        # Assert exception is raised on dispatch.
        self.assertRaises(
            ActionRunnerDispatchError,
            runner_container.dispatch,
            liveaction_db
        )
예제 #22
0
    def test_dispatch_override_default_action_params(self):
        runner_container = get_runner_container()
        params = {
            'actionstr': 'foo',
            'actionint': 20
        }
        actionexec_db = self._get_action_exec_db_model(params)
        actionexec_db = ActionExecution.add_or_update(actionexec_db)

        # Assert that execution ran successfully.
        result = runner_container.dispatch(actionexec_db)
        self.assertTrue(result)
        actionexec_db = ActionExecution.get_by_id(actionexec_db.id)
        result = actionexec_db.result
        self.assertTrue(result.get('action_params').get('actionint') == 20)
        self.assertTrue(result.get('action_params').get('actionstr') == 'foo')
예제 #23
0
    def test_dispatch(self):
        runner_container = get_runner_container()
        params = {"actionstr": "bar"}
        liveaction_db = self._get_action_exec_db_model(RunnerContainerTest.action_db, params)
        liveaction_db = LiveAction.add_or_update(liveaction_db)
        executions.create_execution_object(liveaction_db)
        # Assert that execution ran successfully.
        runner_container.dispatch(liveaction_db)
        liveaction_db = LiveAction.get_by_id(liveaction_db.id)
        result = liveaction_db.result
        self.assertTrue(result.get("action_params").get("actionint") == 10)
        self.assertTrue(result.get("action_params").get("actionstr") == "bar")

        # Assert that context is written correctly.
        context = {"user": "******", "third_party_system": {"ref_id": "1234"}}

        self.assertDictEqual(liveaction_db.context, context)
예제 #24
0
    def test_state_db_creation_async_actions(self):
        runner_container = get_runner_container()
        params = {"actionstr": "foo", "actionint": 20, "async_test": True}
        liveaction_db = self._get_action_exec_db_model(RunnerContainerTest.async_action_db, params)
        liveaction_db = LiveAction.add_or_update(liveaction_db)
        executions.create_execution_object(liveaction_db)
        # Assert that execution ran without exceptions.
        runner_container.dispatch(liveaction_db)
        states = ActionExecutionState.get_all()

        found = None
        for state in states:
            if state.execution_id == liveaction_db.id:
                found = state
        self.assertTrue(found is not None, "There should be a state db object.")
        self.assertTrue(found.query_context is not None)
        self.assertTrue(found.query_module is not None)
예제 #25
0
    def test_dispatch(self):
        runner_container = get_runner_container()
        params = {'actionstr': 'bar'}
        liveaction_db = self._get_liveaction_model(
            RunnerContainerTest.action_db, params)
        liveaction_db = LiveAction.add_or_update(liveaction_db)
        executions.create_execution_object(liveaction_db)
        # Assert that execution ran successfully.
        runner_container.dispatch(liveaction_db)
        liveaction_db = LiveAction.get_by_id(liveaction_db.id)
        result = liveaction_db.result
        self.assertTrue(result.get('action_params').get('actionint') == 10)
        self.assertTrue(result.get('action_params').get('actionstr') == 'bar')

        # Assert that context is written correctly.
        context = {'user': '******', 'third_party_system': {'ref_id': '1234'}}

        self.assertDictEqual(liveaction_db.context, context)
예제 #26
0
    def test_dispatch(self):
        runner_container = get_runner_container()
        params = {"actionstr": "bar"}
        liveaction_db = self._get_liveaction_model(
            RunnerContainerTest.action_db, params)
        liveaction_db = LiveAction.add_or_update(liveaction_db)
        executions.create_execution_object(liveaction_db)
        # Assert that execution ran successfully.
        runner_container.dispatch(liveaction_db)
        liveaction_db = LiveAction.get_by_id(liveaction_db.id)
        result = liveaction_db.result
        self.assertTrue(result.get("action_params").get("actionint") == 10)
        self.assertTrue(result.get("action_params").get("actionstr") == "bar")

        # Assert that context is written correctly.
        context = {"user": "******", "third_party_system": {"ref_id": "1234"}}

        self.assertDictEqual(liveaction_db.context, context)
예제 #27
0
    def test_state_db_not_created_for_async_actions(self):
        runner_container = get_runner_container()

        params = {"actionstr": "foo", "actionint": 20, "async_test": True}

        liveaction_db = self._get_liveaction_model(
            RunnerContainerTest.async_action_db, params)

        liveaction_db = LiveAction.add_or_update(liveaction_db)
        executions.create_execution_object(liveaction_db)

        # Assert that execution ran without exceptions.
        runner_container.dispatch(liveaction_db)
        states = ActionExecutionState.get_all()
        found = [
            state for state in states if state.execution_id == liveaction_db.id
        ]

        self.assertTrue(
            len(found) == 0, "There should not be a state db object.")
예제 #28
0
    def test_state_db_creation_async_actions(self):
        runner_container = get_runner_container()
        params = {
            'actionstr': 'foo',
            'actionint': 20,
            'async_test': True
        }
        actionexec_db = self._get_action_exec_db_model(RunnerContainerTest.async_action_db, params)
        actionexec_db = ActionExecution.add_or_update(actionexec_db)

        # Assert that execution ran without exceptions.
        runner_container.dispatch(actionexec_db)
        states = ActionExecutionState.get_all()

        found = None
        for state in states:
            if state.execution_id == actionexec_db.id:
                found = state
        self.assertTrue(found is not None, 'There should be a state db object.')
        self.assertTrue(found.query_context is not None)
        self.assertTrue(found.query_module is not None)
예제 #29
0
    def test_dispatch(self):
        runner_container = get_runner_container()
        params = {
            'actionstr': 'bar'
        }
        liveaction_db = self._get_action_exec_db_model(RunnerContainerTest.action_db, params)
        liveaction_db = LiveAction.add_or_update(liveaction_db)
        executions.create_execution_object(liveaction_db)
        # Assert that execution ran successfully.
        runner_container.dispatch(liveaction_db)
        liveaction_db = LiveAction.get_by_id(liveaction_db.id)
        result = liveaction_db.result
        self.assertTrue(result.get('action_params').get('actionint') == 10)
        self.assertTrue(result.get('action_params').get('actionstr') == 'bar')

        # Assert that context is written correctly.
        context = {
            'user': '******',
            'third_party_system': {
                'ref_id': '1234'
            }
        }

        self.assertDictEqual(liveaction_db.context, context)
예제 #30
0
    def test_post_run_is_always_called_after_run(self):
        # 1. post_run should be called on success, failure, etc.
        runner_container = get_runner_container()
        params = {
            'actionstr': 'bar',
            'mock_status': action_constants.LIVEACTION_STATUS_SUCCEEDED
        }
        liveaction_db = self._get_failingaction_exec_db_model(params)
        liveaction_db = LiveAction.add_or_update(liveaction_db)
        executions.create_execution_object(liveaction_db)

        global global_runner
        global_runner = None
        original_get_runner = runner_container._get_runner

        def mock_get_runner(*args, **kwargs):
            global global_runner
            runner = original_get_runner(*args, **kwargs)
            global_runner = runner
            return runner

        runner_container._get_runner = mock_get_runner

        # Note: We can't assert here that post_run hasn't been called yet because runner instance
        # is only instantiated later inside dispatch method
        runner_container.dispatch(liveaction_db)
        self.assertTrue(global_runner.post_run_called)

        # 2. Verify post_run is called if run() throws
        runner_container = get_runner_container()
        params = {'actionstr': 'bar', 'raise': True}
        liveaction_db = self._get_failingaction_exec_db_model(params)
        liveaction_db = LiveAction.add_or_update(liveaction_db)
        executions.create_execution_object(liveaction_db)

        global_runner = None
        original_get_runner = runner_container._get_runner

        def mock_get_runner(*args, **kwargs):
            global global_runner
            runner = original_get_runner(*args, **kwargs)
            global_runner = runner
            return runner

        runner_container._get_runner = mock_get_runner

        # Note: We can't assert here that post_run hasn't been called yet because runner instance
        # is only instantiated later inside dispatch method
        runner_container.dispatch(liveaction_db)
        self.assertTrue(global_runner.post_run_called)

        # 2. Verify post_run is also called if _delete_auth_token throws
        runner_container = get_runner_container()
        runner_container._delete_auth_token = mock.Mock(
            side_effect=ValueError('throw'))
        params = {
            'actionstr': 'bar',
            'mock_status': action_constants.LIVEACTION_STATUS_SUCCEEDED
        }
        liveaction_db = self._get_failingaction_exec_db_model(params)
        liveaction_db = LiveAction.add_or_update(liveaction_db)
        executions.create_execution_object(liveaction_db)

        global_runner = None
        original_get_runner = runner_container._get_runner

        def mock_get_runner(*args, **kwargs):
            global global_runner
            runner = original_get_runner(*args, **kwargs)
            global_runner = runner
            return runner

        runner_container._get_runner = mock_get_runner

        # Note: We can't assert here that post_run hasn't been called yet because runner instance
        # is only instantiated later inside dispatch method
        runner_container.dispatch(liveaction_db)
        self.assertTrue(global_runner.post_run_called)
예제 #31
0
파일: inquiries.py 프로젝트: mz-techops/st2
def purge_inquiries(logger):
    """Purge Inquiries that have exceeded their configured TTL

    At the moment, Inquiries do not have their own database model, so this function effectively
    is another, more specialized GC for executions. It will look for executions with a 'pending'
    status that use the 'inquirer' runner, which is the current definition for an Inquiry.

    Then it will mark those that have a nonzero TTL have existed longer than their TTL as
    "timed out". It will then request that the parent workflow(s) resume, where the failure
    can be handled as the user desires.
    """

    # Get all existing Inquiries
    filters = {'runner__name': 'inquirer', 'status': action_constants.LIVEACTION_STATUS_PENDING}
    inquiries = list(ActionExecution.query(**filters))

    gc_count = 0

    # Inspect each Inquiry, and determine if TTL is expired
    for inquiry in inquiries:

        ttl = int(inquiry.result.get('ttl'))
        if ttl <= 0:
            logger.debug("Inquiry %s has a TTL of %s. Skipping." % (inquiry.id, ttl))
            continue

        min_since_creation = int(
            (get_datetime_utc_now() - inquiry.start_timestamp).total_seconds() / 60
        )

        logger.debug("Inquiry %s has a TTL of %s and was started %s minute(s) ago" % (
                     inquiry.id, ttl, min_since_creation))

        if min_since_creation > ttl:

            gc_count += 1
            logger.info("TTL expired for Inquiry %s. Marking as timed out." % inquiry.id)

            liveaction_db = action_utils.update_liveaction_status(
                status=action_constants.LIVEACTION_STATUS_TIMED_OUT,
                result=inquiry.result,
                liveaction_id=inquiry.liveaction.get('id'))
            executions.update_execution(liveaction_db)

            # Call Inquiry runner's post_run to trigger callback to workflow
            runner_container = get_runner_container()
            action_db = get_action_by_ref(liveaction_db.action)
            runnertype_db = get_runnertype_by_name(action_db.runner_type['name'])
            runner = runner_container._get_runner(runnertype_db, action_db, liveaction_db)
            runner.post_run(status=action_constants.LIVEACTION_STATUS_TIMED_OUT,
                            result=inquiry.result)

            if liveaction_db.context.get("parent"):

                # Request that root workflow resumes
                root_liveaction = action_service.get_root_liveaction(liveaction_db)
                action_service.request_resume(
                    root_liveaction,
                    UserDB(cfg.CONF.system_user.user)
                )

    logger.info('Marked %s ttl-expired Inquiries as "timed out".' % (gc_count))
예제 #32
0
    def test_post_run_is_always_called_after_run(self):
        # 1. post_run should be called on success, failure, etc.
        runner_container = get_runner_container()
        params = {
            'actionstr': 'bar',
            'mock_status': action_constants.LIVEACTION_STATUS_SUCCEEDED
        }
        liveaction_db = self._get_failingaction_exec_db_model(params)
        liveaction_db = LiveAction.add_or_update(liveaction_db)
        executions.create_execution_object(liveaction_db)

        global global_runner
        global_runner = None
        original_get_runner = runner_container._get_runner

        def mock_get_runner(*args, **kwargs):
            global global_runner
            runner = original_get_runner(*args, **kwargs)
            global_runner = runner
            return runner
        runner_container._get_runner = mock_get_runner

        # Note: We can't assert here that post_run hasn't been called yet because runner instance
        # is only instantiated later inside dispatch method
        runner_container.dispatch(liveaction_db)
        self.assertTrue(global_runner.post_run_called)

        # 2. Verify post_run is called if run() throws
        runner_container = get_runner_container()
        params = {
            'actionstr': 'bar',
            'raise': True
        }
        liveaction_db = self._get_failingaction_exec_db_model(params)
        liveaction_db = LiveAction.add_or_update(liveaction_db)
        executions.create_execution_object(liveaction_db)

        global_runner = None
        original_get_runner = runner_container._get_runner

        def mock_get_runner(*args, **kwargs):
            global global_runner
            runner = original_get_runner(*args, **kwargs)
            global_runner = runner
            return runner
        runner_container._get_runner = mock_get_runner

        # Note: We can't assert here that post_run hasn't been called yet because runner instance
        # is only instantiated later inside dispatch method
        runner_container.dispatch(liveaction_db)
        self.assertTrue(global_runner.post_run_called)

        # 2. Verify post_run is also called if _delete_auth_token throws
        runner_container = get_runner_container()
        runner_container._delete_auth_token = mock.Mock(side_effect=ValueError('throw'))
        params = {
            'actionstr': 'bar',
            'mock_status': action_constants.LIVEACTION_STATUS_SUCCEEDED
        }
        liveaction_db = self._get_failingaction_exec_db_model(params)
        liveaction_db = LiveAction.add_or_update(liveaction_db)
        executions.create_execution_object(liveaction_db)

        global_runner = None
        original_get_runner = runner_container._get_runner

        def mock_get_runner(*args, **kwargs):
            global global_runner
            runner = original_get_runner(*args, **kwargs)
            global_runner = runner
            return runner
        runner_container._get_runner = mock_get_runner

        # Note: We can't assert here that post_run hasn't been called yet because runner instance
        # is only instantiated later inside dispatch method
        runner_container.dispatch(liveaction_db)
        self.assertTrue(global_runner.post_run_called)